#include "wx/ownerdrw.h"
#endif
-#if wxUSE_DRAG_AND_DROP
- #include "wx/dataobj.h"
- #include "wx/msw/ole/droptgt.h"
+#if wxUSE_DRAG_AND_DROP
+ #include "wx/dnd.h"
#endif
#include "wx/menuitem.h"
#include "wx/intl.h"
#include "wx/log.h"
-
#include "wx/textctrl.h"
+#include "wx/notebook.h"
#include <string.h>
#ifndef __TWIN32__
#ifdef __GNUWIN32__
#ifndef wxUSE_NORLANDER_HEADERS
- #include <wx/msw/gnuwin32/extra.h>
+ #include "wx/msw/gnuwin32/extra.h"
#endif
#endif
#endif
wxMenu *wxCurrentPopupMenu = NULL;
extern wxList WXDLLEXPORT wxPendingDelete;
-extern wxChar wxCanvasClassName[];
+extern const wxChar *wxCanvasClassName;
// ---------------------------------------------------------------------------
// private functions
// ---------------------------------------------------------------------------
// the window proc for all our windows
-LRESULT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message,
+LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam);
#ifdef __WXDEBUG__
// event tables
// ---------------------------------------------------------------------------
-#if !USE_SHARED_LIBRARY
IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase)
-#endif
BEGIN_EVENT_TABLE(wxWindow, wxWindowBase)
EVT_ERASE_BACKGROUND(wxWindow::OnEraseBackground)
// ---------------------------------------------------------------------------
// Find an item given the MS Windows id
-wxWindow *wxWindow::FindItem(int id) const
+wxWindow *wxWindow::FindItem(long id) const
{
+ wxControl *item = wxDynamicCast(this, wxControl);
+ if ( item )
+ {
+ // i it we or one of our "internal" children?
+ if ( item->GetId() == id ||
+ (item->GetSubcontrols().Index(id) != wxNOT_FOUND) )
+ {
+ return item;
+ }
+ }
+
wxWindowList::Node *current = GetChildren().GetFirst();
while (current)
{
if ( wnd )
return wnd;
- if ( childWin->IsKindOf(CLASSINFO(wxControl)) )
- {
- wxControl *item = (wxControl *)childWin;
- if ( item->GetId() == id )
- return item;
- else
- {
- // In case it's a 'virtual' control (e.g. radiobox)
- if ( item->GetSubcontrols().Member((wxObject *)id) )
- return item;
- }
- }
-
current = current->GetNext();
}
long style,
const wxString& name)
{
- wxCHECK_MSG( parent, FALSE, _T("can't create wxWindow without parent") );
+ wxCHECK_MSG( parent, FALSE, wxT("can't create wxWindow without parent") );
if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) )
return FALSE;
if ( hWnd )
::EnableWindow(hWnd, (BOOL)enable);
+ wxWindowList::Node *node = GetChildren().GetFirst();
+ while ( node )
+ {
+ wxWindow *child = node->GetData();
+ child->Enable(enable);
+
+ node = node->GetNext();
+ }
+
return TRUE;
}
{
WXHANDLE hFont = m_font.GetResourceHandle();
- wxASSERT_MSG( hFont, _T("should have valid font") );
+ wxASSERT_MSG( hFont, wxT("should have valid font") );
::SendMessage(hWnd, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0));
}
}
wxASSERT_MSG( m_cursor.Ok(),
- _T("cursor must be valid after call to the base version"));
+ wxT("cursor must be valid after call to the base version"));
HWND hWnd = GetHwnd();
void wxWindow::SubclassWin(WXHWND hWnd)
{
- wxASSERT_MSG( !m_oldWndProc, _T("subclassing window twice?") );
+ wxASSERT_MSG( !m_oldWndProc, wxT("subclassing window twice?") );
HWND hwnd = (HWND)hWnd;
- wxCHECK_RET( ::IsWindow(hwnd), _T("invalid HWND in SubclassWin") );
+ wxCHECK_RET( ::IsWindow(hwnd), wxT("invalid HWND in SubclassWin") );
wxAssociateWinWithHandle(hwnd, this);
{
m_hWnd = 0;
- wxCHECK_RET( ::IsWindow(hwnd), _T("invalid HWND in SubclassWin") );
+ wxCHECK_RET( ::IsWindow(hwnd), wxT("invalid HWND in UnsubclassWin") );
FARPROC farProc = (FARPROC) GetWindowLong(hwnd, GWL_WNDPROC);
if ( (m_oldWndProc != 0) && (farProc != (FARPROC) m_oldWndProc) )
*y = rect.bottom;
}
+void wxWindow::DoMoveWindow(int x, int y, int width, int height)
+{
+ if ( !::MoveWindow(GetHwnd(), x, y, width, height, TRUE) )
+ {
+ wxLogLastError("MoveWindow");
+ }
+}
+
// set the size of the window: if the dimensions are positive, just use them,
// but if any of them is equal to -1, it means that we must find the value for
// it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
return;
}
- if ( x == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
+ if ( x == -1 && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
x = currentX;
- if ( y == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
+ if ( y == -1 && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
y = currentY;
AdjustForParentClientOrigin(x, y, sizeFlags);
wxSize size(-1, -1);
if ( width == -1 )
{
- if ( sizeFlags && wxSIZE_AUTO_WIDTH )
+ if ( sizeFlags & wxSIZE_AUTO_WIDTH )
{
size = DoGetBestSize();
width = size.x;
if ( height == -1 )
{
- if ( sizeFlags && wxSIZE_AUTO_HEIGHT )
+ if ( sizeFlags & wxSIZE_AUTO_HEIGHT )
{
if ( size.x == -1 )
{
- size= DoGetBestSize();
+ size = DoGetBestSize();
}
//else: already called DoGetBestSize() above
}
}
- if ( !::MoveWindow(GetHwnd(), x, y, width, height, TRUE) )
- {
- wxLogLastError("MoveWindow");
- }
-}
-
-// for a generic window there is no natural best size - just use the current one
-wxSize wxWindow::DoGetBestSize()
-{
- return GetSize();
+ DoMoveWindow(x, y, width, height);
}
void wxWindow::DoSetClientSize(int width, int height)
::ScreenToClient(hParentWnd, &point);
}
- MoveWindow(hWnd, point.x, point.y, actual_width, actual_height, (BOOL)TRUE);
+ DoMoveWindow(point.x, point.y, actual_width, actual_height);
wxSizeEvent event(wxSize(width, height), m_windowId);
event.SetEventObject(this);
{
// intercept dialog navigation keys
MSG *msg = (MSG *)pMsg;
+
+ // here we try to do all the job which ::IsDialogMessage() usually does
+ // internally
+#if 0
bool bProcess = TRUE;
if ( msg->message != WM_KEYDOWN )
bProcess = FALSE;
}
}
}
+#else
+ // let ::IsDialogMessage() do almost everything and handle just the
+ // things it doesn't here: Ctrl-TAB for switching notebook pages
+ if ( msg->message == WM_KEYDOWN )
+ {
+ // don't process system keys here
+ if ( !(HIWORD(msg->lParam) & KF_ALTDOWN) )
+ {
+ if ( (msg->wParam == VK_TAB) &&
+ (::GetKeyState(VK_CONTROL) & 0x100) != 0 )
+ {
+ // find the first notebook parent and change its page
+ wxWindow *win = this;
+ wxNotebook *nbook = NULL;
+ while ( win && !nbook )
+ {
+ nbook = wxDynamicCast(win, wxNotebook);
+ win = win->GetParent();
+ }
+
+ if ( nbook )
+ {
+ bool forward = !(::GetKeyState(VK_SHIFT) & 0x100);
+
+ nbook->AdvanceSelection(forward);
+ }
+ }
+ }
+ }
+#endif // 0
if ( ::IsDialogMessage(GetHwnd(), msg) )
return TRUE;
wxWindow *wxWndHook = NULL;
// Main window proc
-LRESULT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
// trace all messages - useful for the debugging
#ifdef __WXDEBUG__
- wxLogTrace(wxTraceMessages, _T("Processing %s(wParam=%8lx, lParam=%8lx)"),
+ wxLogTrace(wxTraceMessages, wxT("Processing %s(wParam=%8lx, lParam=%8lx)"),
wxGetMessageName(message), wParam, lParam);
#endif // __WXDEBUG__
// it with wxWindow stored in wxWndHook
if ( !wnd && wxWndHook )
{
+#if 0 // def __WXDEBUG__
+ char buf[512];
+ ::GetClassNameA((HWND) hWnd, buf, 512);
+ wxString className(buf);
+#endif
+
wxAssociateWinWithHandle(hWnd, wxWndHook);
wnd = wxWndHook;
wxWndHook = NULL;
break;
case WM_MOUSEMOVE:
+ {
+ short x = LOWORD(lParam);
+ short y = HIWORD(lParam);
+
+ processed = HandleMouseMove(x, y, wParam);
+ }
+ break;
+
case WM_LBUTTONDOWN:
+ // set focus to this window
+ SetFocus();
+
+ // fall through
+
case WM_LBUTTONUP:
case WM_LBUTTONDBLCLK:
case WM_RBUTTONDOWN:
case VK_RETURN:
case VK_BACK:
case VK_TAB:
+ case VK_ADD:
+ case VK_SUBTRACT:
// but set processed to FALSE, not TRUE to still pass them to
// the control's default window proc - otherwise built-in
// keyboard handling won't work
if ( !processed )
{
#ifdef __WXDEBUG__
- wxLogTrace(wxTraceMessages, _T("Forwarding %s to DefWindowProc."),
+ wxLogTrace(wxTraceMessages, wxT("Forwarding %s to DefWindowProc."),
wxGetMessageName(message));
#endif // __WXDEBUG__
rc.result = MSWDefWindowProc(message, wParam, lParam);
return (wxWindow *)node->Data();
}
+#if 0 // def __WXDEBUG__
+static int gs_AssociationCount = 0;
+#endif
+
void wxAssociateWinWithHandle(HWND hWnd, wxWindow *win)
{
// adding NULL hWnd is (first) surely a result of an error and
// (secondly) breaks menu command processing
wxCHECK_RET( hWnd != (HWND)NULL,
- _T("attempt to add a NULL hWnd to window list ignored") );
+ wxT("attempt to add a NULL hWnd to window list ignored") );
+
+
+ wxWindow *oldWin = wxFindWinFromHandle((WXHWND) hWnd);
+ if ( oldWin && (oldWin != win) )
+ {
+ wxString str(win->GetClassInfo()->GetClassName());
+ wxLogError(wxT("Bug! Found existing HWND %X for new window of class %s"), (int) hWnd, (const wxChar*) str);
+ }
+ else if (!oldWin)
+ {
+#if 0 // def __WXDEBUG__
+ gs_AssociationCount ++;
+ wxLogDebug("+ Association %d", gs_AssociationCount);
+#endif
- if ( !wxWinHandleList->Find((long)hWnd) )
wxWinHandleList->Append((long)hWnd, win);
+ }
}
void wxRemoveHandleAssociation(wxWindow *win)
{
+#if 0 // def __WXDEBUG__
+ if (wxWinHandleList->Member(win))
+ {
+ wxLogDebug("- Association %d", gs_AssociationCount);
+ gs_AssociationCount --;
+ }
+#endif
wxWinHandleList->DeleteObject(win);
}
int chars = GetMenuString(hMenu, i, buf, 100, MF_BYPOSITION);
if ( !chars )
{
- wxLogLastError(_T("GetMenuString"));
+ wxLogLastError(wxT("GetMenuString"));
continue;
}
- if ( wxStrcmp(buf, _T("&Window")) == 0 )
+ if ( wxStrcmp(buf, wxT("&Window")) == 0 )
{
RemoveMenu(hMenu, i, MF_BYPOSITION);
if ( width > -1 ) width1 = width;
if ( height > -1 ) height1 = height;
-#ifdef __WXWINE__
HWND hParent = (HWND)NULL;
-#else
- HWND hParent = NULL;
-#endif
if ( parent )
hParent = (HWND) parent->GetHWND();
if ( !::SetWindowPos(GetHwnd(), HWND_TOPMOST, 0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE) )
{
- wxLogLastError(_T("SetWindowPos"));
+ wxLogLastError(wxT("SetWindowPos"));
}
}
// move the dialog to its initial position without forcing repainting
if ( !::MoveWindow(GetHwnd(), x1, y1, width1, height1, FALSE) )
{
- wxLogLastError(_T("MoveWindow"));
+ wxLogLastError(wxT("MoveWindow"));
}
}
else
wxString className(wclass);
if ( GetWindowStyleFlag() & wxNO_FULL_REPAINT_ON_RESIZE )
{
- className += _T("NR");
+ className += wxT("NR");
}
m_hWnd = (WXHWND)CreateWindowEx(extendedStyle,
- wclass,
- title ? title : _T(""),
+ className,
+ title ? title : wxT(""),
style,
x1, y1,
width1, height1,
}
wxWndHook = NULL;
- wxWinHandleList->Append((long)m_hWnd, this);
+#ifdef __WXDEBUG__
+ wxNode* node = wxWinHandleList->Member(this);
+ if (node)
+ {
+ HWND hWnd = (HWND) node->GetKeyInteger();
+ if (hWnd != (HWND) m_hWnd)
+ {
+ wxLogError(wxT("A second HWND association is being added for the same window!"));
+ }
+ }
+#endif
+ wxAssociateWinWithHandle((HWND) m_hWnd, this);
return TRUE;
}
{
#if wxUSE_TOOLTIPS
NMHDR* hdr = (NMHDR *)lParam;
- if ( hdr->code == TTN_NEEDTEXT && m_tooltip )
+ if ( (int)hdr->code == TTN_NEEDTEXT && m_tooltip )
{
TOOLTIPTEXT *ttt = (TOOLTIPTEXT *)lParam;
ttt->lpszText = (wxChar *)m_tooltip->GetTip().c_str();
wxCloseEvent event(wxEVT_QUERY_END_SESSION, -1);
event.SetEventObject(wxTheApp);
event.SetCanVeto(TRUE);
- event.SetLoggingOff(logOff == ENDSESSION_LOGOFF);
+ event.SetLoggingOff(logOff == (long)ENDSESSION_LOGOFF);
bool rc = wxTheApp->ProcessEvent(event);
wxCloseEvent event(wxEVT_END_SESSION, -1);
event.SetEventObject(wxTheApp);
event.SetCanVeto(FALSE);
- event.SetLoggingOff( (logOff == ENDSESSION_LOGOFF) );
+ event.SetLoggingOff( (logOff == (long)ENDSESSION_LOGOFF) );
if ( (this == wxTheApp->GetTopWindow()) && // Only send once
wxTheApp->ProcessEvent(event))
{
{
return ((wxControl *)item)->MSWOnDraw(itemStruct);
}
- else
-#endif
- return FALSE;
+#endif // USE_OWNER_DRAWN
+ return FALSE;
}
bool wxWindow::MSWOnMeasureItem(int id, WXMEASUREITEMSTRUCT *itemStruct)
return popupMenu->MSWCommand(cmd, id);
}
- wxWindow *win = FindItem(id);
- if ( !win )
+ wxWindow *win;
+ if ( cmd == 0 || cmd == 1 ) // menu or accel - use id
{
+ // must cast to a signed type before comparing with other ids!
+ win = FindItem((signed short)id);
+ }
+ else
+ {
+ // find it from HWND - this works even with the broken programs using
+ // the same ids for different controls
win = wxFindWinFromHandle(control);
}
if ( win )
return win->MSWCommand(cmd, id);
+ else
+ {
+ // If no child window, it may be an accelerator, e.g. for
+ // a popup menu command.
+
+ wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED);
+ event.SetEventObject(this);
+ event.SetId(id);
+ event.SetInt(id);
+ return ProcessEvent(event);
+ }
return FALSE;
}
break;
default:
- wxFAIL_MSG(_T("no such joystick event"));
+ wxFAIL_MSG(wxT("no such joystick event"));
return FALSE;
}
event.m_eventType = wxEVT_SCROLLWIN_PAGEDOWN;
break;
- case SB_THUMBTRACK:
case SB_THUMBPOSITION:
+ event.m_isScrolling = FALSE;
+ /* fall-through */
+
+ case SB_THUMBTRACK:
event.m_eventType = wxEVT_SCROLLWIN_THUMBTRACK;
break;
// global functions
// ===========================================================================
-void wxGetCharSize(WXHWND wnd, int *x, int *y,wxFont *the_font)
+void wxGetCharSize(WXHWND wnd, int *x, int *y, const wxFont *the_font)
{
TEXTMETRIC tm;
HDC dc = ::GetDC((HWND) wnd);
{
// the_font->UseResource();
// the_font->RealizeResource();
- fnt = (HFONT)the_font->GetResourceHandle();
+ fnt = (HFONT)((wxFont *)the_font)->GetResourceHandle(); // const_cast
if ( fnt )
was = (HFONT) SelectObject(dc,fnt);
}
{
wxTheKeyboardHookProc = MakeProcInstance((FARPROC) wxKeyboardHook, wxGetInstance());
wxTheKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC) wxTheKeyboardHookProc, wxGetInstance(),
+
#if defined(__WIN32__) && !defined(__TWIN32__)
GetCurrentThreadId());
// (DWORD)GetCurrentProcess()); // This is another possibility. Which is right?
#else
- GetCurrentTask());
+ GetCurrentTask());
#endif
}
else
{
UnhookWindowsHookEx(wxTheKeyboardHook);
+ // avoids mingw warning about statement with no effect (FreeProcInstance
+ // doesn't do anything under Win32)
+#ifndef __GNUWIN32__
FreeProcInstance(wxTheKeyboardHookProc);
+#endif
}
}