X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e4d03677b9e48e581604511e1a4e2cb16dccb619..4a10ea8b13fd0851e71e6fa5ebbe5b93933be11e:/src/msw/window.cpp diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 706f6740be..66fcdf4355 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -17,10 +17,6 @@ // headers // --------------------------------------------------------------------------- -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) - #pragma implementation "window.h" -#endif - // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" @@ -47,13 +43,16 @@ #include "wx/msgdlg.h" #include "wx/settings.h" #include "wx/statbox.h" + #include "wx/sizer.h" #endif #if wxUSE_OWNER_DRAWN && !defined(__WXUNIVERSAL__) #include "wx/ownerdrw.h" #endif +#include "wx/evtloop.h" #include "wx/module.h" +#include "wx/sysopt.h" #if wxUSE_DRAG_AND_DROP #include "wx/dnd.h" @@ -106,18 +105,30 @@ #include #endif -#if (!defined(__GNUWIN32_OLD__) && !defined(__WXMICROWIN__) /* && !defined(__WXWINCE__) */ ) || defined(__CYGWIN10__) - #ifdef __WIN95__ - #include - #endif -#elif !defined(__WXMICROWIN__) && !defined(__WXWINCE__) // broken compiler - #include "wx/msw/gnuwin32/extra.h" -#endif +#include #include "wx/msw/missing.h" #if defined(__WXWINCE__) -#include "wx/msw/wince/missing.h" + #include "wx/msw/wince/missing.h" +#endif + +#if defined(TME_LEAVE) && defined(WM_MOUSELEAVE) + #define HAVE_TRACKMOUSEEVENT +#endif // everything needed for TrackMouseEvent() + +// if this is set to 1, we use deferred window sizing to reduce flicker when +// resizing complicated window hierarchies, but this can in theory result in +// different behaviour than the old code so we keep the possibility to use it +// by setting this to 0 (in the future this should be removed completely) +#define USE_DEFERRED_SIZING 1 + +// set this to 1 to filter out duplicate mouse events, e.g. mouse move events +// when mouse position didnd't change +#ifdef __WXWINCE__ + #define wxUSE_MOUSEEVENT_HACK 0 +#else + #define wxUSE_MOUSEEVENT_HACK 1 #endif // --------------------------------------------------------------------------- @@ -138,6 +149,18 @@ extern const wxChar *wxCanvasClassName; // wxGetStdColourMap() and wxWindow::OnSysColourChanged() (FIXME-MT) static bool gs_hasStdCmap = false; +// last mouse event information we need to filter out the duplicates +#if wxUSE_MOUSEEVENT_HACK +static struct MouseEventInfoDummy +{ + // mouse position (in screen coordinates) + wxPoint pos; + + // last mouse event type + wxEventType type; +} gs_lastMouseEvent; +#endif // wxUSE_MOUSEEVENT_HACK + // --------------------------------------------------------------------------- // private functions // --------------------------------------------------------------------------- @@ -148,7 +171,7 @@ LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, #ifdef __WXDEBUG__ - const char *wxGetMessageName(int message); + const wxChar *wxGetMessageName(int message); #endif //__WXDEBUG__ void wxRemoveHandleAssociation(wxWindowMSW *win); @@ -158,8 +181,10 @@ wxWindow *wxFindWinFromHandle(WXHWND hWnd); // get the text metrics for the current font static TEXTMETRIC wxGetTextMetrics(const wxWindowMSW *win); +#ifdef __WXWINCE__ // find the window for the mouse event at the specified position -static wxWindowMSW *FindWindowForMouseEvent(wxWindowMSW *win, int *x, int *y); //TW:REQ:Univ +static wxWindowMSW *FindWindowForMouseEvent(wxWindowMSW *win, int *x, int *y); +#endif // __WXWINCE__ // wrapper around BringWindowToTop() API static inline void wxBringWindowToTop(HWND hwnd) @@ -213,6 +238,21 @@ static void EnsureParentHasControlParentStyle(wxWindow *parent) #endif // !__WXWINCE__ +#ifdef __WXWINCE__ +// On Windows CE, GetCursorPos can return an error, so use this function +// instead +bool GetCursorPosWinCE(POINT* pt) +{ + if (!GetCursorPos(pt)) + { + DWORD pos = GetMessagePos(); + pt->x = LOWORD(pos); + pt->y = HIWORD(pos); + } + return true; +} +#endif + // --------------------------------------------------------------------------- // event tables // --------------------------------------------------------------------------- @@ -287,7 +327,7 @@ wxBEGIN_PROPERTIES_TABLE(wxWindow) // Always constructor Properties first wxREADONLY_PROPERTY( Parent,wxWindow*, GetParent, EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) - wxPROPERTY( Id,wxWindowID, SetId, GetId, wxID_ANY, 0 /*flags*/ , wxT("Helpstring") , wxT("group") ) + wxPROPERTY( Id,wxWindowID, SetId, GetId, -1 /*wxID_ANY*/ , 0 /*flags*/ , wxT("Helpstring") , wxT("group") ) wxPROPERTY( Position,wxPoint, SetPosition , GetPosition, wxDefaultPosition , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // pos wxPROPERTY( Size,wxSize, SetSize, GetSize, wxDefaultSize , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // size wxPROPERTY( WindowStyle , long , SetWindowStyleFlag , GetWindowStyleFlag , EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style @@ -305,9 +345,9 @@ wxBEGIN_PROPERTIES_TABLE(wxWindow) wxPROPERTY( Shown , bool , Show , IsShown , wxxVariant((bool)true) , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) #if 0 // possible property candidates (not in xrc) or not valid in all subclasses - wxPROPERTY( Title,wxString, SetTitle, GetTitle, wxT("") ) + wxPROPERTY( Title,wxString, SetTitle, GetTitle, wxEmptyString ) wxPROPERTY( Font , wxFont , SetFont , GetWindowFont , ) - wxPROPERTY( Label,wxString, SetLabel, GetLabel, wxT("") ) + wxPROPERTY( Label,wxString, SetLabel, GetLabel, wxEmptyString ) // MaxHeight, Width , MinHeight , Width // TODO switch label to control and title to toplevels @@ -442,11 +482,8 @@ void wxWindowMSW::Init() m_xThumbSize = 0; m_yThumbSize = 0; -#if wxUSE_MOUSEEVENT_HACK - m_lastMouseX = - m_lastMouseY = -1; - m_lastMouseEvent = -1; -#endif // wxUSE_MOUSEEVENT_HACK + m_pendingPosition = wxDefaultPosition; + m_pendingSize = wxDefaultSize; } // Destructor @@ -465,7 +502,12 @@ wxWindowMSW::~wxWindowMSW() { frame->SetLastFocus(NULL); } - break; + + // apparently sometimes we can end up with our grand parent + // pointing to us as well: this is surely a bug in focus handling + // code but it's not clear where it happens so for now just try to + // fix it here by not breaking out of the loop + //break; } } #endif // __WXUNIVERSAL__ @@ -489,6 +531,7 @@ wxWindowMSW::~wxWindowMSW() } delete m_childrenDisabled; + } // real construction (Init() must have been called before!) @@ -661,12 +704,23 @@ bool wxWindowMSW::Show(bool show) return false; HWND hWnd = GetHwnd(); - int cshow = show ? SW_SHOW : SW_HIDE; - ::ShowWindow(hWnd, cshow); - if ( show && IsTopLevel() ) + // we could be called before the underlying window is created (this is + // actually useful to prevent it from being initially shown), e.g. + // + // wxFoo *foo = new wxFoo; + // foo->Hide(); + // foo->Create(parent, ...); + // + // should work without errors + if ( hWnd ) { - wxBringWindowToTop(hWnd); + ::ShowWindow(hWnd, show ? SW_SHOW : SW_HIDE); + + if ( show && IsTopLevel() ) + { + wxBringWindowToTop(hWnd); + } } return true; @@ -752,7 +806,11 @@ bool wxWindowMSW::SetCursor(const wxCursor& cursor) // Change the cursor NOW if we're within the correct window POINT point; +#ifdef __WXWINCE__ + ::GetCursorPosWinCE(&point); +#else ::GetCursorPos(&point); +#endif RECT rect = wxGetWindowRect(hWnd); @@ -763,7 +821,7 @@ bool wxWindowMSW::SetCursor(const wxCursor& cursor) return true; } -void wxWindowMSW::WarpPointer (int x, int y) +void wxWindowMSW::WarpPointer(int x, int y) { ClientToScreen(&x, &y); @@ -773,16 +831,32 @@ void wxWindowMSW::WarpPointer (int x, int y) } } +void wxWindowMSW::MSWUpdateUIState(int action) +{ + // WM_UPDATEUISTATE only appeared in Windows 2000 so it can do us no good + // to use it on older systems -- and could possibly do some harm + static int s_needToUpdate = -1; + if ( s_needToUpdate == -1 ) + { + int verMaj, verMin; + s_needToUpdate = wxGetOsVersion(&verMaj, &verMin) == wxWINDOWS_NT && + verMaj >= 5; + } + + if ( s_needToUpdate ) + { + // NB: it doesn't seem to matter what we put in wParam, whether we + // include just one UISF_XXX or both, both are affected, no idea + // why + ::SendMessage(GetHwnd(), WM_UPDATEUISTATE, + MAKEWPARAM(action, UISF_HIDEFOCUS | UISF_HIDEACCEL), 0); + } +} + // --------------------------------------------------------------------------- // scrolling stuff // --------------------------------------------------------------------------- -// convert wxHORIZONTAL/wxVERTICAL to SB_HORZ/SB_VERT -static inline int wxDirToWinStyle(int orient) -{ - return orient == wxHORIZONTAL ? SB_HORZ : SB_VERT; -} - inline int GetScrollPosition(HWND hWnd, int wOrient) { #ifdef __WXMICROWIN__ @@ -795,7 +869,7 @@ inline int GetScrollPosition(HWND hWnd, int wOrient) wOrient, &scrollInfo) ) { - // Not neccessarily an error, if there are no scrollbars yet. + // Not necessarily an error, if there are no scrollbars yet. // wxLogLastError(_T("GetScrollInfo")); } return scrollInfo.nPos; @@ -1035,7 +1109,8 @@ void wxWindowMSW::DissociateHandle() } -bool wxCheckWindowWndProc(WXHWND hWnd, WXFARPROC wndProc) +bool wxCheckWindowWndProc(WXHWND hWnd, + WXFARPROC WXUNUSED_IN_WINCE(wndProc)) { // Unicows note: the code below works, but only because WNDCLASS contains // original window handler rather that the unicows fake one. This may not @@ -1121,7 +1196,7 @@ void wxWindowMSW::SetWindowStyleFlag(long flags) ::SetWindowLong(GetHwnd(), GWL_EXSTYLE, exstyleReal); - // we must call SetWindowPos() to flash the cached extended style and + // we must call SetWindowPos() to flush the cached extended style and // also to make the change to wxSTAY_ON_TOP style take effect: just // setting the style simply doesn't work if ( !::SetWindowPos(GetHwnd(), @@ -1145,8 +1220,12 @@ WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const // using this flag results in very significant reduction in flicker, // especially with controls inside the static boxes (as the interior of the - // box is not redrawn twice) - style |= WS_CLIPCHILDREN; + // box is not redrawn twice).but sometimes results in redraw problems, so + // optionally allow the old code to continue to use it provided a special + // system option is turned on + if ( !wxSystemOptions::GetOptionInt(wxT("msw.window.no-clip-children")) + || (flags & wxCLIP_CHILDREN) ) + style |= WS_CLIPCHILDREN; // it doesn't seem useful to use WS_CLIPSIBLINGS here as we officially // don't support overlapping windows and it only makes sense for them and, @@ -1230,7 +1309,11 @@ bool wxWindowMSW::IsMouseInWindow() const { // get the mouse position POINT pt; +#ifdef __WXWINCE__ + ::GetCursorPosWinCE(&pt); +#else ::GetCursorPos(&pt); +#endif // find the window which currently has the cursor and go up the window // chain until we find this window - or exhaust it @@ -1243,6 +1326,7 @@ bool wxWindowMSW::IsMouseInWindow() const void wxWindowMSW::OnInternalIdle() { +#ifndef HAVE_TRACKMOUSEEVENT // Check if we need to send a LEAVE event if ( m_mouseInWindow ) { @@ -1250,44 +1334,10 @@ void wxWindowMSW::OnInternalIdle() // or doesn't have mouse capture if ( !IsMouseInWindow() ) { - // Generate a LEAVE event - m_mouseInWindow = false; - - // Unfortunately the mouse button and keyboard state may have - // changed by the time the OnInternalIdle function is called, so 'state' - // may be meaningless. - int state = 0; - if ( wxIsShiftDown() ) - state |= MK_SHIFT; - if ( wxIsCtrlDown() ) - state |= MK_CONTROL; - - // Only the high-order bit should be tested - if ( GetKeyState( VK_LBUTTON ) & (1<<15) ) - state |= MK_LBUTTON; - if ( GetKeyState( VK_MBUTTON ) & (1<<15) ) - state |= MK_MBUTTON; - if ( GetKeyState( VK_RBUTTON ) & (1<<15) ) - state |= MK_RBUTTON; - - POINT pt; - if ( !::GetCursorPos(&pt) ) - { - wxLogLastError(_T("GetCursorPos")); - } - - // we need to have client coordinates here for symmetry with - // wxEVT_ENTER_WINDOW - RECT rect = wxGetWindowRect(GetHwnd()); - pt.x -= rect.left; - pt.y -= rect.top; - - wxMouseEvent event2(wxEVT_LEAVE_WINDOW); - InitMouseEvent(event2, pt.x, pt.y, state); - - (void)GetEventHandler()->ProcessEvent(event2); + GenerateMouseLeave(); } } +#endif // !HAVE_TRACKMOUSEEVENT if (wxUpdateUIEvent::CanUpdate(this)) UpdateWindowUI(wxUPDATE_UI_FROMIDLE); @@ -1325,7 +1375,8 @@ void wxWindowMSW::Freeze() { if ( !m_frozenness++ ) { - SendSetRedraw(GetHwnd(), false); + if ( IsShown() ) + SendSetRedraw(GetHwnd(), false); } } @@ -1335,11 +1386,14 @@ void wxWindowMSW::Thaw() if ( !--m_frozenness ) { - SendSetRedraw(GetHwnd(), true); + if ( IsShown() ) + { + SendSetRedraw(GetHwnd(), true); - // we need to refresh everything or otherwise he invalidated area is not - // repainted - Refresh(); + // we need to refresh everything or otherwise the invalidated area + // is not going to be repainted + Refresh(); + } } } @@ -1348,18 +1402,32 @@ void wxWindowMSW::Refresh(bool eraseBack, const wxRect *rect) HWND hWnd = GetHwnd(); if ( hWnd ) { + RECT mswRect; + const RECT *pRect; if ( rect ) { - RECT mswRect; mswRect.left = rect->x; mswRect.top = rect->y; mswRect.right = rect->x + rect->width; mswRect.bottom = rect->y + rect->height; - ::InvalidateRect(hWnd, &mswRect, eraseBack); + pRect = &mswRect; } else - ::InvalidateRect(hWnd, NULL, eraseBack); + { + pRect = NULL; + } + + // RedrawWindow not available on SmartPhone or eVC++ 3 +#if !defined(__SMARTPHONE__) && !(defined(_WIN32_WCE) && _WIN32_WCE < 400) + UINT flags = RDW_INVALIDATE | RDW_ALLCHILDREN; + if ( eraseBack ) + flags |= RDW_ERASE; + + ::RedrawWindow(hWnd, pRect, NULL, flags); +#else + ::InvalidateRect(hWnd, pRect, eraseBack); +#endif } } @@ -1398,14 +1466,12 @@ void wxWindowMSW::SetDropTarget(wxDropTarget *pDropTarget) // old style file-manager drag&drop support: we retain the old-style // DragAcceptFiles in parallel with SetDropTarget. -void wxWindowMSW::DragAcceptFiles(bool accept) +void wxWindowMSW::DragAcceptFiles(bool WXUNUSED_IN_WINCE(accept)) { -#if !defined(__WXWINCE__) +#ifndef __WXWINCE__ HWND hWnd = GetHwnd(); if ( hWnd ) ::DragAcceptFiles(hWnd, (BOOL)accept); -#else - wxUnusedVar(accept); #endif } @@ -1429,20 +1495,46 @@ void wxWindowMSW::DoSetToolTip(wxToolTip *tooltip) // moving and resizing // --------------------------------------------------------------------------- +bool wxWindowMSW::IsSizeDeferred() const +{ +#if USE_DEFERRED_SIZING + if ( m_pendingPosition != wxDefaultPosition || + m_pendingSize != wxDefaultSize ) + return true; +#endif // USE_DEFERRED_SIZING + + return false; +} + // Get total size void wxWindowMSW::DoGetSize(int *x, int *y) const { - RECT rect = wxGetWindowRect(GetHwnd()); + // if SetSize() had been called at wx level but not realized at Windows + // level yet (i.e. EndDeferWindowPos() not called), we still should return + // the new and not the old position to the other wx code + if ( m_pendingSize != wxDefaultSize ) + { + if ( x ) + *x = m_pendingSize.x; + if ( y ) + *y = m_pendingSize.y; + } + else // use current size + { + RECT rect = wxGetWindowRect(GetHwnd()); - if ( x ) - *x = rect.right - rect.left; - if ( y ) - *y = rect.bottom - rect.top; + if ( x ) + *x = rect.right - rect.left; + if ( y ) + *y = rect.bottom - rect.top; + } } // Get size *available for subwindows* i.e. excluding menu bar etc. void wxWindowMSW::DoGetClientSize(int *x, int *y) const { + // this is only for top level windows whose resizing is never deferred, so + // we can safely use the current size here RECT rect = wxGetClientRect(GetHwnd()); if ( x ) @@ -1453,42 +1545,50 @@ void wxWindowMSW::DoGetClientSize(int *x, int *y) const void wxWindowMSW::DoGetPosition(int *x, int *y) const { - RECT rect = wxGetWindowRect(GetHwnd()); - - POINT point; - point.x = rect.left; - point.y = rect.top; + wxWindow * const parent = GetParent(); - // we do the adjustments with respect to the parent only for the "real" - // children, not for the dialogs/frames - if ( !IsTopLevel() ) + wxPoint pos; + if ( m_pendingPosition != wxDefaultPosition ) { - HWND hParentWnd = 0; - wxWindow *parent = GetParent(); - if ( parent ) - hParentWnd = GetWinHwnd(parent); + pos = m_pendingPosition; + } + else // use current position + { + RECT rect = wxGetWindowRect(GetHwnd()); - // Since we now have the absolute screen coords, if there's a parent we - // must subtract its top left corner - if ( hParentWnd ) - { - ::ScreenToClient(hParentWnd, &point); - } + POINT point; + point.x = rect.left; + point.y = rect.top; - if ( parent ) + // we do the adjustments with respect to the parent only for the "real" + // children, not for the dialogs/frames + if ( !IsTopLevel() ) { - // We may be faking the client origin. So a window that's really at (0, - // 30) may appear (to wxWin apps) to be at (0, 0). - wxPoint pt(parent->GetClientAreaOrigin()); - point.x -= pt.x; - point.y -= pt.y; + // Since we now have the absolute screen coords, if there's a + // parent we must subtract its top left corner + if ( parent ) + { + ::ScreenToClient(GetHwndOf(parent), &point); + } } + + pos.x = point.x; + pos.y = point.y; + } + + // we also must adjust by the client area offset: a control which is just + // under a toolbar could be at (0, 30) in Windows but at (0, 0) in wx + if ( parent && !IsTopLevel() ) + { + const wxPoint pt(parent->GetClientAreaOrigin()); + pos.x -= pt.x; + pos.y -= pt.y; } if ( x ) - *x = point.x; + *x = pos.x; if ( y ) - *y = point.y; + *y = pos.y; } void wxWindowMSW::DoScreenToClient(int *x, int *y) const @@ -1523,39 +1623,65 @@ void wxWindowMSW::DoClientToScreen(int *x, int *y) const *y = pt.y; } -void wxWindowMSW::DoMoveWindow(int x, int y, int width, int height) +bool +wxWindowMSW::DoMoveSibling(WXHWND hwnd, int x, int y, int width, int height) { - // TODO: is this consistent with other platforms? - // Still, negative width or height shouldn't be allowed - if (width < 0) - width = 0; - if (height < 0) - height = 0; +#if USE_DEFERRED_SIZING + // if our parent had prepared a defer window handle for us, use it (unless + // we are a top level window) + wxWindowMSW * const parent = IsTopLevel() ? NULL : GetParent(); - // if our parent had prepared a defer window handle for us, use it - wxWindowMSW *parent = GetParent(); HDWP hdwp = parent ? (HDWP)parent->m_hDWP : NULL; if ( hdwp ) { - hdwp = ::DeferWindowPos(hdwp, GetHwnd(), NULL, - x, y, width, height, + hdwp = ::DeferWindowPos(hdwp, (HWND)hwnd, NULL, x, y, width, height, SWP_NOZORDER); if ( !hdwp ) { wxLogLastError(_T("DeferWindowPos")); } + } + if ( parent ) + { // hdwp must be updated as it may have been changed parent->m_hDWP = (WXHANDLE)hdwp; } + if ( hdwp ) + { + // did deferred move, remember new coordinates of the window as they're + // different from what Windows would return for it + return true; + } + // otherwise (or if deferring failed) move the window in place immediately - if ( !hdwp ) +#endif // USE_DEFERRED_SIZING + if ( !::MoveWindow((HWND)hwnd, x, y, width, height, IsShown()) ) { - if ( !::MoveWindow(GetHwnd(), x, y, width, height, TRUE) ) - { - wxLogLastError(wxT("MoveWindow")); - } + wxLogLastError(wxT("MoveWindow")); + } + + // if USE_DEFERRED_SIZING, indicates that we didn't use deferred move, + // ignored otherwise + return false; +} + +void wxWindowMSW::DoMoveWindow(int x, int y, int width, int height) +{ + // TODO: is this consistent with other platforms? + // Still, negative width or height shouldn't be allowed + if (width < 0) + width = 0; + if (height < 0) + height = 0; + + if ( DoMoveSibling(m_hWnd, x, y, width, height) ) + { +#if USE_DEFERRED_SIZING + m_pendingPosition = wxPoint(x, y); + m_pendingSize = wxSize(width, height); +#endif // USE_DEFERRED_SIZING } } @@ -1571,13 +1697,16 @@ void wxWindowMSW::DoSetSize(int x, int y, int width, int height, int sizeFlags) { // get the current size and position... int currentX, currentY; + int currentW, currentH; + GetPosition(¤tX, ¤tY); - int currentW,currentH; GetSize(¤tW, ¤tH); - // ... and don't do anything (avoiding flicker) if it's already ok + // ... and don't do anything (avoiding flicker) if it's already ok unless + // we're forced to resize the window if ( x == currentX && y == currentY && - width == currentW && height == currentH ) + width == currentW && height == currentH && + !(sizeFlags & wxSIZE_FORCE) ) { return; } @@ -1645,28 +1774,21 @@ void wxWindowMSW::DoSetClientSize(int width, int height) RECT rectClient; ::GetClientRect(GetHwnd(), &rectClient); - // if the size is already ok, stop here (rectClient.left = top = 0) + // if the size is already ok, stop here (NB: rectClient.left = top = 0) if ( (rectClient.right == width || width == wxDefaultCoord) && (rectClient.bottom == height || height == wxDefaultCoord) ) { break; } - int widthClient = width, - heightClient = height; - // Find the difference between the entire window (title bar and all) // and the client area; add this to the new client size to move the // window RECT rectWin; ::GetWindowRect(GetHwnd(), &rectWin); - widthClient += rectWin.right - rectWin.left - rectClient.right; - heightClient += rectWin.bottom - rectWin.top - rectClient.bottom; - - POINT point; - point.x = rectWin.left; - point.y = rectWin.top; + const int widthWin = rectWin.right - rectWin.left, + heightWin = rectWin.bottom - rectWin.top; // MoveWindow positions the child windows relative to the parent, so // adjust if necessary @@ -1675,21 +1797,24 @@ void wxWindowMSW::DoSetClientSize(int width, int height) wxWindow *parent = GetParent(); if ( parent ) { - ::ScreenToClient(GetHwndOf(parent), &point); + ::ScreenToClient(GetHwndOf(parent), (POINT *)&rectWin); } } - DoMoveWindow(point.x, point.y, widthClient, heightClient); + // don't call DoMoveWindow() because we want to move window immediately + // and not defer it here + if ( !::MoveWindow(GetHwnd(), + rectWin.left, + rectWin.top, + width + widthWin - rectClient.right, + height + heightWin - rectClient.bottom, + TRUE) ) + { + wxLogLastError(_T("MoveWindow")); + } } } -// For implementation purposes - sometimes decorations make the client area -// smaller -wxPoint wxWindowMSW::GetClientAreaOrigin() const -{ - return wxPoint(0, 0); -} - // --------------------------------------------------------------------------- // text metrics // --------------------------------------------------------------------------- @@ -1729,7 +1854,7 @@ void wxWindowMSW::GetTextExtent(const wxString& string, SIZE sizeRect; TEXTMETRIC tm; - GetTextExtentPoint(hdc, string, string.length(), &sizeRect); + ::GetTextExtentPoint32(hdc, string, string.length(), &sizeRect); GetTextMetrics(hdc, &tm); if ( x ) @@ -1864,7 +1989,8 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg) } bool bForward = true, - bWindowChange = false; + bWindowChange = false, + bFromTab = false; // should we process this message specially? bool bProcess = true; @@ -1878,6 +2004,7 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg) // Ctrl-Tab cycles thru notebook pages bWindowChange = bCtrlDown; bForward = !bShiftDown; + bFromTab = true; } break; @@ -1895,38 +2022,6 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg) bProcess = false; break; - case VK_ESCAPE: - { -#if wxUSE_BUTTON - wxButton *btn = wxDynamicCast(FindWindow(wxID_CANCEL),wxButton); - - // our own wxLogDialog should react to Esc - // without Cancel button but this is a private class - // so let's try recognize it by content - #if wxUSE_LOG_DIALOG - if ( !btn && - wxDynamicCast(this,wxDialog) && - FindWindow(wxID_MORE) && - FindWindow(wxID_OK) && - !FindWindow(wxID_CANCEL) && - GetTitle().MakeLower().StartsWith(wxTheApp->GetAppName().c_str()) - ) - btn = wxDynamicCast(FindWindow(wxID_OK),wxButton); - #endif // wxUSE_LOG_DIALOG - if ( btn && btn->IsEnabled() ) - { - // if we do have a cancel button, do press it - btn->MSWCommand(BN_CLICKED, 0 /* unused */); - - // we consumed the message - return true; - } -#endif // wxUSE_BUTTON - - bProcess = false; - } - break; - case VK_RETURN: { if ( (lDlgCode & DLGC_WANTMESSAGE) && !bCtrlDown ) @@ -1936,7 +2031,10 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg) // it return false; } - else if ( lDlgCode & DLGC_BUTTON ) + + // currently active button should get enter press even + // if there is a default button elsewhere + if ( lDlgCode & DLGC_DEFPUSHBUTTON ) { // let IsDialogMessage() handle this for all // buttons except the owner-drawn ones which it @@ -1945,16 +2043,15 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg) if ( (style & BS_OWNERDRAW) == BS_OWNERDRAW ) { // emulate the button click - wxWindow *btn = wxFindWinFromHandle((WXHWND)msg->hwnd); + wxWindow * + btn = wxFindWinFromHandle((WXHWND)msg->hwnd); if ( btn ) btn->MSWCommand(BN_CLICKED, 0 /* unused */); } bProcess = false; } - // FIXME: this should be handled by - // wxNavigationKeyEvent handler and not here! - else + else // not a button itself { #if wxUSE_BUTTON wxButton *btn = wxDynamicCast(GetDefaultItem(), @@ -2002,10 +2099,17 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg) wxNavigationKeyEvent event; event.SetDirection(bForward); event.SetWindowChange(bWindowChange); + event.SetFromTab(bFromTab); event.SetEventObject(this); if ( GetEventHandler()->ProcessEvent(event) ) { + // as we don't call IsDialogMessage(), which would take of + // this by default, we need to manually send this message + // so that controls could change their appearance + // appropriately + MSWUpdateUIState(UIS_CLEAR); + return true; } } @@ -2215,7 +2319,7 @@ LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM w LRESULT rc; - if ( wnd ) + if ( wnd && wxEventLoop::AllowProcessing(wnd) ) rc = wnd->MSWWindowProc(message, wParam, lParam); else rc = ::DefWindowProc(hWnd, message, wParam, lParam); @@ -2233,7 +2337,6 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l { bool allow; WXLRESULT result; - WXHICON hIcon; WXHBRUSH hBrush; } rc; @@ -2262,49 +2365,6 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l (void)HandleDestroy(); break; -#ifndef __SMARTPHONE__ // or wxWinCE in general ? - case WM_WINDOWPOSCHANGING: - { - WINDOWPOS *wp = wx_reinterpret_cast(WINDOWPOS *, lParam); - - if ( wp->flags & SWP_NOSIZE ) - break; - - // when we resize this window, its children are probably going - // to be repositioned as well, prepare to use DeferWindowPos() - // for them - const int numChildren = GetChildren().GetCount(); - if ( numChildren > 1 ) - { - m_hDWP = (WXHANDLE)::BeginDeferWindowPos(numChildren); - if ( !m_hDWP ) - { - wxLogLastError(_T("BeginDeferWindowPos")); - } - } - } - break; - - case WM_WINDOWPOSCHANGED: - // first let DefWindowProc() handle the message: it will generate - // WM_MOVE and WM_SIZE as needed - processed = MSWDefWindowProc(message, wParam, lParam) == 0; - - // then change the positions of all child windows at once - if ( m_hDWP ) - { - HDWP hDWP = (HDWP)m_hDWP; - m_hDWP = NULL; - - // put all child controls in place at once now - if ( !::EndDeferWindowPos(hDWP) ) - { - wxLogLastError(_T("EndDeferWindowPos")); - } - } - break; -#endif // __SMARTPHONE__ - case WM_SIZE: processed = HandleSize(LOWORD(lParam), HIWORD(lParam), wParam); break; @@ -2314,7 +2374,6 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l break; #if !defined(__WXWINCE__) - // TODO: move those in WM_WINDOWPOSCHANGING case above case WM_MOVING: { LPRECT pRect = (LPRECT)lParam; @@ -2352,8 +2411,31 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l break; #endif // !__WXWINCE__ +#if !(defined(_WIN32_WCE) && _WIN32_WCE < 400) + case WM_WINDOWPOSCHANGED: + { + WINDOWPOS *lpPos = (WINDOWPOS *)lParam; + + if ( !(lpPos->flags & SWP_NOSIZE) ) + { + RECT rc; + ::GetClientRect(GetHwnd(), &rc); + + AutoHRGN hrgnClient(::CreateRectRgnIndirect(&rc)); + AutoHRGN hrgnNew(::CreateRectRgn(lpPos->x, lpPos->y, + lpPos->cx, lpPos->cy)); + + // we need to invalidate any new exposed areas here + // to force them to repaint + if ( ::CombineRgn(hrgnNew, hrgnNew, hrgnClient, RGN_DIFF) != NULLREGION ) + ::InvalidateRgn(GetHwnd(), hrgnNew, TRUE); + } + } + break; +#endif #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__) case WM_ACTIVATEAPP: + // This implicitly sends a wxEVT_ACTIVATE_APP event wxTheApp->SetActive(wParam != 0, FindFocus()); break; #endif @@ -2376,52 +2458,34 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l processed = HandleKillFocus((WXHWND)(HWND)wParam); break; + case WM_PRINTCLIENT: + processed = HandlePrintClient((WXHDC)wParam); + break; + case WM_PAINT: + if ( wParam ) { - if ( wParam ) - { - // cast to wxWindow is needed for wxUniv - wxPaintDCEx dc((wxWindow *)this, (WXHDC)wParam); - processed = HandlePaint(); - } - else - { - processed = HandlePaint(); - } - break; - } + wxPaintDCEx dc((wxWindow *)this, (WXHDC)wParam); -#ifndef __WXWINCE__ - case WM_PRINT: + processed = HandlePaint(); + } + else // no DC given { -#if wxUSE_LISTCTRL - // Don't call the wx handlers in this case - if ( wxIsKindOf(this, wxListCtrl) ) - break; -#endif - - if ( lParam & PRF_ERASEBKGND ) - HandleEraseBkgnd((WXHDC)(HDC)wParam); - - wxPaintDCEx dc((wxWindow *)this, (WXHDC)wParam); processed = HandlePaint(); } break; -#endif case WM_CLOSE: #ifdef __WXUNIVERSAL__ // Universal uses its own wxFrame/wxDialog, so we don't receive // close events unless we have this. Close(); - processed = true; - rc.result = TRUE; -#else +#endif // __WXUNIVERSAL__ + // don't let the DefWindowProc() destroy our window - we'll do it // ourselves in ~wxWindow processed = true; rc.result = TRUE; -#endif break; case WM_SHOWWINDOW: @@ -2434,61 +2498,20 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l wParam); break; - // Seems to be broken currently -#if 0 // ndef __WXWINCE__ +#ifdef HAVE_TRACKMOUSEEVENT case WM_MOUSELEAVE: - { - wxASSERT_MSG( !m_mouseInWindow, wxT("the mouse should be in a window to generate this event!") ); - - // only process this message if the mouse is not in the window, - // This can also check for children in composite windows. - // however, this may mean the the wxEVT_LEAVE_WINDOW is never sent - // if the mouse does not enter the window from it's child before - // leaving the scope of the window. ( perhaps this can be picked - // up in the OnIdle code as before, for this special case ) - if ( /*IsComposite() && */ !IsMouseInWindow() ) + // filter out excess WM_MOUSELEAVE events sent after PopupMenu() (on XP at least) + if ( m_mouseInWindow ) { - m_mouseInWindow = false; - - // Unfortunately no mouse state is passed with a WM_MOUSE_LEAVE - int state = 0; - if ( wxIsShiftDown() ) - state |= MK_SHIFT; - if ( wxIsCtrlDown() ) - state |= MK_CONTROL; - if ( GetKeyState( VK_LBUTTON ) ) - state |= MK_LBUTTON; - if ( GetKeyState( VK_MBUTTON ) ) - state |= MK_MBUTTON; - if ( GetKeyState( VK_RBUTTON ) ) - state |= MK_RBUTTON; - - POINT pt; - if ( !::GetCursorPos(&pt) ) - { - wxLogLastError(_T("GetCursorPos")); - } - - // we need to have client coordinates here for symmetry with - // wxEVT_ENTER_WINDOW - RECT rect = wxGetWindowRect(GetHwnd()); - pt.x -= rect.left; - pt.y -= rect.top; - - wxMouseEvent event2(wxEVT_LEAVE_WINDOW); - InitMouseEvent(event2, pt.x, pt.y, state); - - (void)GetEventHandler()->ProcessEvent(event2); + GenerateMouseLeave(); } + // always pass processed back as false, this allows the window - // manager to process the message too. This is needed to ensure - // windows XP themes work properly as the mouse moves over widgets - // like buttons. - processed = false; - } - break; -#endif - // __WXWINCE__ + // manager to process the message too. This is needed to + // ensure windows XP themes work properly as the mouse moves + // over widgets like buttons. So don't set processed to true here. + break; +#endif // HAVE_TRACKMOUSEEVENT #if wxUSE_MOUSEWHEEL case WM_MOUSEWHEEL: @@ -2531,8 +2554,10 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l int x = GET_X_LPARAM(lParam), y = GET_Y_LPARAM(lParam); +#ifdef __WXWINCE__ // redirect the event to a static control if necessary by - // finding one under mouse + // finding one under mouse because under CE the static controls + // don't generate mouse events (even with SS_NOTIFY) wxWindowMSW *win; if ( GetCapture() == this ) { @@ -2548,6 +2573,9 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l wxCHECK_MSG( win, 0, _T("FindWindowForMouseEvent() returned NULL") ); } +#else // !__WXWINCE__ + wxWindowMSW *win = this; +#endif // __WXWINCE__/!__WXWINCE__ processed = win->HandleMouseEvent(message, x, y, wParam); @@ -2900,7 +2928,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l wxHelpEvent helpEvent(wxEVT_HELP, subjectOfHelp->GetId(), #ifdef __WXWINCE__ - wxPoint(0, 0) + wxPoint(0,0) #else wxPoint(info->MousePos.x, info->MousePos.y) #endif @@ -3153,42 +3181,22 @@ bool wxWindowMSW::MSWCreate(const wxChar *wclass, // do create the window wxWindowCreationHook hook(this); - // VZ: anyone care to explain why this is done for CE? -#ifdef __WXWINCE__ - if (extendedStyle == 0) - { - m_hWnd = (WXHWND)::CreateWindow - ( - className, - title ? title : wxEmptyString, - style, - x, y, w, h, - (HWND)MSWGetParent(), - (HMENU)controlId, - wxGetInstance(), - NULL // no extra data - ); - } - else -#endif // __WXWINCE__ - { - m_hWnd = (WXHWND)::CreateWindowEx - ( - extendedStyle, - className, - title ? title : wxEmptyString, - style, - x, y, w, h, - (HWND)MSWGetParent(), - (HMENU)controlId, - wxGetInstance(), - NULL // no extra data - ); - } + m_hWnd = (WXHWND)::CreateWindowEx + ( + extendedStyle, + className, + title ? title : m_windowName.c_str(), + style, + x, y, w, h, + (HWND)MSWGetParent(), + (HMENU)controlId, + wxGetInstance(), + NULL // no extra data + ); if ( !m_hWnd ) { - wxLogSysError(_("Can't create window of class %s"), wclass); + wxLogSysError(_("Can't create window of class %s"), className.c_str()); return false; } @@ -3359,7 +3367,7 @@ bool wxWindowMSW::MSWOnNotify(int WXUNUSED(idCtrl), bool wxWindowMSW::HandleQueryEndSession(long logOff, bool *mayEnd) { -#ifndef __WXWINCE__ +#ifdef ENDSESSION_LOGOFF wxCloseEvent event(wxEVT_QUERY_END_SESSION, wxID_ANY); event.SetEventObject(wxTheApp); event.SetCanVeto(true); @@ -3376,13 +3384,15 @@ bool wxWindowMSW::HandleQueryEndSession(long logOff, bool *mayEnd) return rc; #else + wxUnusedVar(logOff); + wxUnusedVar(mayEnd); return false; #endif } bool wxWindowMSW::HandleEndSession(bool endSession, long logOff) { -#ifndef __WXWINCE__ +#ifdef ENDSESSION_LOGOFF // do nothing if the session isn't ending if ( !endSession ) return false; @@ -3398,6 +3408,8 @@ bool wxWindowMSW::HandleEndSession(bool endSession, long logOff) return wxTheApp->ProcessEvent(event); #else + wxUnusedVar(endSession); + wxUnusedVar(logOff); return false; #endif } @@ -3406,7 +3418,8 @@ bool wxWindowMSW::HandleEndSession(bool endSession, long logOff) // window creation/destruction // --------------------------------------------------------------------------- -bool wxWindowMSW::HandleCreate(WXLPCREATESTRUCT cs, bool *mayCreate) +bool wxWindowMSW::HandleCreate(WXLPCREATESTRUCT WXUNUSED_IN_WINCE(cs), + bool *mayCreate) { // VZ: why is this commented out for WinCE? If it doesn't support // WS_EX_CONTROLPARENT at all it should be somehow handled globally, @@ -3414,8 +3427,6 @@ bool wxWindowMSW::HandleCreate(WXLPCREATESTRUCT cs, bool *mayCreate) #ifndef __WXWINCE__ if ( ((CREATESTRUCT *)cs)->dwExStyle & WS_EX_CONTROLPARENT ) EnsureParentHasControlParentStyle(GetParent()); -#else - wxUnusedVar(cs); #endif // !__WXWINCE__ // TODO: should generate this event from WM_NCCREATE @@ -3545,7 +3556,7 @@ bool wxWindowMSW::HandleKillFocus(WXHWND hwnd) bool wxWindowMSW::HandleShow(bool show, int WXUNUSED(status)) { wxShowEvent event(GetId(), show); - event.m_eventObject = this; + event.SetEventObject(this); return GetEventHandler()->ProcessEvent(event); } @@ -3553,7 +3564,7 @@ bool wxWindowMSW::HandleShow(bool show, int WXUNUSED(status)) bool wxWindowMSW::HandleInitDialog(WXHWND WXUNUSED(hWndFocus)) { wxInitDialogEvent event(GetId()); - event.m_eventObject = this; + event.SetEventObject(this); return GetEventHandler()->ProcessEvent(event); } @@ -3588,7 +3599,7 @@ bool wxWindowMSW::HandleDropFiles(WXWPARAM wParam) DragFinish (hFilesInfo); wxDropFilesEvent event(wxEVT_DROP_FILES, gwFilesDropped, files); - event.m_eventObject = this; + event.SetEventObject(this); POINT dropPoint; DragQueryPoint(hFilesInfo, (LPPOINT) &dropPoint); @@ -3623,7 +3634,11 @@ bool wxWindowMSW::HandleSetCursor(WXHWND WXUNUSED(hWnd), // first ask the user code - it may wish to set the cursor in some very // specific way (for example, depending on the current position) POINT pt; +#ifdef __WXWINCE__ + if ( !::GetCursorPosWinCE(&pt)) +#else if ( !::GetCursorPos(&pt) ) +#endif { wxLogLastError(wxT("GetCursorPos")); } @@ -3708,7 +3723,11 @@ wxWindowMSW::MSWOnDrawItem(int WXUNUSED_UNLESS_ODRAWN(id), { wxMenuItem *pMenuItem = (wxMenuItem *)(pDrawStruct->itemData); - wxCHECK_MSG( pMenuItem && pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), + // see comment before the same test in MSWOnMeasureItem() below + if ( !pMenuItem ) + return false; + + wxCHECK_MSG( wxDynamicCast(pMenuItem, wxMenuItem), false, _T("MSWOnDrawItem: bad wxMenuItem pointer") ); // prepare to call OnDrawItem(): notice using of wxDCTemp to prevent @@ -3766,7 +3785,15 @@ wxWindowMSW::MSWOnMeasureItem(int id, WXMEASUREITEMSTRUCT *itemStruct) { wxMenuItem *pMenuItem = (wxMenuItem *)(pMeasureStruct->itemData); - wxCHECK_MSG( pMenuItem && pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), + // according to Carsten Fuchs the pointer may be NULL under XP if an + // MDI child frame is initially maximized, see this for more info: + // http://article.gmane.org/gmane.comp.lib.wxwidgets.general/27745 + // + // so silently ignore it instead of asserting + if ( !pMenuItem ) + return false; + + wxCHECK_MSG( wxDynamicCast(pMenuItem, wxMenuItem), false, _T("MSWOnMeasureItem: bad wxMenuItem pointer") ); size_t w, h; @@ -3817,12 +3844,16 @@ bool wxWindowMSW::HandleDisplayChange() #ifndef __WXMICROWIN__ -bool wxWindowMSW::HandleCtlColor(WXHBRUSH *brush, WXHDC pDC, WXHWND pWnd) +bool wxWindowMSW::HandleCtlColor(WXHBRUSH *brush, WXHDC hDC, WXHWND hWnd) { -#if wxUSE_CONTROLS - wxWindow *item = FindItemByHWND(pWnd, true); +#if !wxUSE_CONTROLS || defined(__WXUNIVERSAL__) + wxUnusedVar(hDC); + wxUnusedVar(hWnd); +#else + wxControl *item = wxDynamicCast(FindItemByHWND(hWnd, true), wxControl); + if ( item ) - *brush = item->MSWControlColor(pDC); + *brush = item->MSWControlColor(hDC, hWnd); else #endif // wxUSE_CONTROLS *brush = NULL; @@ -3832,11 +3863,6 @@ bool wxWindowMSW::HandleCtlColor(WXHBRUSH *brush, WXHDC pDC, WXHWND pWnd) #endif // __WXMICROWIN__ -WXHBRUSH wxWindowMSW::MSWControlColor(WXHDC WXUNUSED(hDC)) -{ - return (WXHBRUSH)0; -} - bool wxWindowMSW::HandlePaletteChanged(WXHWND hWndPalChange) { #if wxUSE_PALETTE @@ -3966,6 +3992,7 @@ extern wxCOLORMAP *wxGetStdColourMap() // we want to avoid Windows' "help" and for this we need to have a // reference bitmap which can tell us what the RGB values change // to. + wxLogNull logNo; // suppress error if we couldn't load the bitmap wxBitmap stdColourBitmap(_T("wxBITMAP_STD_COLOURS")); if ( stdColourBitmap.Ok() ) { @@ -4098,87 +4125,107 @@ void wxWindowMSW::OnEraseBackground(wxEraseEvent& event) // do default background painting - if ( !DoEraseBackground(*event.GetDC()) ) + if ( !DoEraseBackground(GetHdcOf(*event.GetDC())) ) { // let the system paint the background event.Skip(); } } -bool wxWindowMSW::DoEraseBackground(wxDC& dc) +bool wxWindowMSW::DoEraseBackground(WXHDC hDC) { - HBRUSH hBrush = (HBRUSH)MSWGetBgBrush(dc.GetHDC()); - if ( !hBrush ) + HBRUSH hbr = (HBRUSH)MSWGetBgBrush(hDC); + if ( !hbr ) return false; - RECT rc; - ::GetClientRect(GetHwnd(), &rc); - ::FillRect(GetHdcOf(dc), &rc, hBrush); + wxFillRect(GetHwnd(), (HDC)hDC, hbr); return true; } -WXHBRUSH wxWindowMSW::MSWGetSolidBgBrushForChild(wxWindow *child) -{ - wxColour col = MSWGetBgColourForChild(child); - if ( col.Ok() ) - { - // draw children with the same colour as the parent - wxBrush *brush = wxTheBrushList->FindOrCreateBrush(col, wxSOLID); - - return (WXHBRUSH)brush->GetResourceHandle(); - } - - return 0; -} - -wxColour wxWindowMSW::MSWGetBgColourForChild(wxWindow *child) +WXHBRUSH +wxWindowMSW::MSWGetBgBrushForChild(WXHDC WXUNUSED(hDC), WXHWND hWnd) { if ( m_hasBgCol ) { // our background colour applies to: // 1. this window itself, always // 2. all children unless the colour is "not inheritable" - // 3. immediate transparent children which should show the same - // background as we do, but not for transparent grandchildren - // which use the background of their immediate parent instead - if ( m_inheritBgCol || - child == this || - (child->HasTransparentBackground() && - child->GetParent() == this) ) + // 3. even if it is not inheritable, our immediate transparent + // children should still inherit it -- but not any transparent + // children because it would look wrong if a child of non + // transparent child would show our bg colour when the child itself + // does not + wxWindow *win = wxFindWinFromHandle(hWnd); + if ( win == this || + m_inheritBgCol || + (win && win->HasTransparentBackground() && + win->GetParent() == this) ) { - return GetBackgroundColour(); + // draw children with the same colour as the parent + wxBrush * + brush = wxTheBrushList->FindOrCreateBrush(GetBackgroundColour()); + + return (WXHBRUSH)GetHbrushOf(*brush); } } - return wxNullColour; + return 0; } -WXHBRUSH wxWindowMSW::MSWGetBgBrushForSelf(wxWindow *parent, WXHDC hDC) +WXHBRUSH wxWindowMSW::MSWGetBgBrush(WXHDC hDC, WXHWND hWndToPaint) { - return parent->MSWGetBgBrushForChild(hDC, (wxWindow *)this); -} + if ( !hWndToPaint ) + hWndToPaint = GetHWND(); -WXHBRUSH wxWindowMSW::MSWGetBgBrush(WXHDC hDC) -{ - for ( wxWindow *win = (wxWindow *)this; win; win = win->GetParent() ) + for ( wxWindowMSW *win = this; win; win = win->GetParent() ) { - WXHBRUSH hBrush = MSWGetBgBrushForSelf(win, hDC); + WXHBRUSH hBrush = win->MSWGetBgBrushForChild(hDC, hWndToPaint); if ( hBrush ) return hBrush; - // background is not inherited beyond the windows which have their own - // fixed background such as top level windows and notebooks and for - // windows for which a custom colour had been explicitly set with - // SetOwnBackgroundColour() and so shouldn't affect its children - if ( win->ProvidesBackground() || - (win->m_hasBgCol && !win->m_inheritBgCol) ) + // background is not inherited beyond top level windows + if ( win->IsTopLevel() ) break; } return 0; } +bool wxWindowMSW::HandlePrintClient(WXHDC hDC) +{ + // we receive this message when DrawThemeParentBackground() is + // called from def window proc of several controls under XP and we + // must draw properly themed background here + // + // note that naively I'd expect filling the client rect with the + // brush returned by MSWGetBgBrush() work -- but for some reason it + // doesn't and we have to call parents MSWPrintChild() which is + // supposed to call DrawThemeBackground() with appropriate params + // + // also note that in this case lParam == PRF_CLIENT but we're + // clearly expected to paint the background and nothing else! + + if ( IsTopLevel() || InheritsBackgroundColour() ) + return false; + + // sometimes we don't want the parent to handle it at all, instead + // return whatever value this window wants + if ( !MSWShouldPropagatePrintChild() ) + return MSWPrintChild(hDC, (wxWindow *)this); + + for ( wxWindow *win = GetParent(); win; win = win->GetParent() ) + { + if ( win->MSWPrintChild(hDC, (wxWindow *)this) ) + return true; + + if ( win->IsTopLevel() || win->InheritsBackgroundColour() ) + break; + } + + return false; +} + // --------------------------------------------------------------------------- // moving and resizing // --------------------------------------------------------------------------- @@ -4221,8 +4268,37 @@ bool wxWindowMSW::HandleMoving(wxRect& rect) bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam) { - bool processed = false; +#if USE_DEFERRED_SIZING + // when we resize this window, its children are probably going to be + // repositioned as well, prepare to use DeferWindowPos() for them + int numChildren = 0; + for ( HWND child = ::GetWindow(GetHwndOf(this), GW_CHILD); + child; + child = ::GetWindow(child, GW_HWNDNEXT) ) + { + numChildren ++; + } + + // Protect against valid m_hDWP being overwritten + bool useDefer = false; + + if ( numChildren > 1 ) + { + if (!m_hDWP) + { + m_hDWP = (WXHANDLE)::BeginDeferWindowPos(numChildren); + if ( !m_hDWP ) + { + wxLogLastError(_T("BeginDeferWindowPos")); + } + if (m_hDWP) + useDefer = true; + } + } +#endif // USE_DEFERRED_SIZING + // update this window size + bool processed = false; switch ( wParam ) { default: @@ -4252,6 +4328,35 @@ bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam) processed = GetEventHandler()->ProcessEvent(event); } +#if USE_DEFERRED_SIZING + // and finally change the positions of all child windows at once + if ( useDefer && m_hDWP ) + { + // reset m_hDWP to NULL so that child windows don't try to use our + // m_hDWP after we call EndDeferWindowPos() on it (this shouldn't + // happen anyhow normally but who knows what weird flow of control we + // may have depending on what the users EVT_SIZE handler does...) + HDWP hDWP = (HDWP)m_hDWP; + m_hDWP = NULL; + + // do put all child controls in place at once + if ( !::EndDeferWindowPos(hDWP) ) + { + wxLogLastError(_T("EndDeferWindowPos")); + } + + // Reset our children's pending pos/size values. + for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); + node; + node = node->GetNext() ) + { + wxWindowMSW *child = node->GetData(); + child->m_pendingPosition = wxDefaultPosition; + child->m_pendingSize = wxDefaultSize; + } + } +#endif // USE_DEFERRED_SIZING + return processed; } @@ -4266,10 +4371,9 @@ bool wxWindowMSW::HandleSizing(wxRect& rect) return rc; } -bool wxWindowMSW::HandleGetMinMaxInfo(void *mmInfo) +bool wxWindowMSW::HandleGetMinMaxInfo(void *WXUNUSED_IN_WINCE(mmInfo)) { #ifdef __WXWINCE__ - wxUnusedVar(mmInfo); return false; #else MINMAXINFO *info = (MINMAXINFO *)mmInfo; @@ -4362,18 +4466,27 @@ bool wxWindowMSW::HandleCommand(WXWORD id, WXWORD cmd, WXHWND control) return GetEventHandler()->ProcessEvent(event); } -#if wxUSE_SPINCTRL && !defined(__WXUNIVERSAL__) else { +#if wxUSE_SPINCTRL && !defined(__WXUNIVERSAL__) // the text ctrl which is logically part of wxSpinCtrl sends WM_COMMAND // notifications to its parent which we want to reflect back to // wxSpinCtrl wxSpinCtrl *spin = wxSpinCtrl::GetSpinForTextCtrl(control); if ( spin && spin->ProcessTextCommand(cmd, id) ) return true; - } #endif // wxUSE_SPINCTRL +#if wxUSE_CHOICE && defined(__SMARTPHONE__) + // the listbox ctrl which is logically part of wxChoice sends WM_COMMAND + // notifications to its parent which we want to reflect back to + // wxChoice + wxChoice *choice = wxChoice::GetChoiceForListBox(control); + if ( choice && choice->MSWCommand(cmd, id) ) + return true; +#endif + } + return false; } @@ -4395,25 +4508,22 @@ void wxWindowMSW::InitMouseEvent(wxMouseEvent& event, event.m_leftDown = (flags & MK_LBUTTON) != 0; event.m_middleDown = (flags & MK_MBUTTON) != 0; event.m_rightDown = (flags & MK_RBUTTON) != 0; - // event.m_altDown = (::GetKeyState(VK_MENU) & 0x80000000) != 0; - // Returns different negative values on WinME and WinNT, - // so simply test for negative value. event.m_altDown = ::GetKeyState(VK_MENU) < 0; #ifndef __WXWINCE__ event.SetTimestamp(::GetMessageTime()); #endif - event.m_eventObject = this; + event.SetEventObject(this); event.SetId(GetId()); #if wxUSE_MOUSEEVENT_HACK - m_lastMouseX = x; - m_lastMouseY = y; - m_lastMouseEvent = event.GetEventType(); + gs_lastMouseEvent.pos = ClientToScreen(wxPoint(x, y)); + gs_lastMouseEvent.type = event.GetEventType(); #endif // wxUSE_MOUSEEVENT_HACK } +#ifdef __WXWINCE__ // Windows doesn't send the mouse events to the static controls (which are // transparent in the sense that their WM_NCHITTEST handler returns // HTTRANSPARENT) at all but we want all controls to receive the mouse events @@ -4424,7 +4534,7 @@ void wxWindowMSW::InitMouseEvent(wxMouseEvent& event, // Notice that this is not done for the mouse move events because this could // (would?) be too slow, but only for clicks which means that the static texts // still don't get move, enter nor leave events. -static wxWindowMSW *FindWindowForMouseEvent(wxWindowMSW *win, int *x, int *y) //TW:REQ:Univ +static wxWindowMSW *FindWindowForMouseEvent(wxWindowMSW *win, int *x, int *y) { wxCHECK_MSG( x && y, win, _T("NULL pointer in FindWindowForMouseEvent") ); @@ -4477,6 +4587,7 @@ static wxWindowMSW *FindWindowForMouseEvent(wxWindowMSW *win, int *x, int *y) // return win; } +#endif // __WXWINCE__ bool wxWindowMSW::HandleMouseEvent(WXUINT msg, int x, int y, WXUINT flags) { @@ -4516,38 +4627,54 @@ bool wxWindowMSW::HandleMouseMove(int x, int y, WXUINT flags) { // Generate an ENTER event m_mouseInWindow = true; -#if _WIN32_WINNT >= 0x0400 -#ifndef __WXWINCE__ - TRACKMOUSEEVENT trackinfo; - trackinfo.cbSize = sizeof(trackinfo); +#ifdef HAVE_TRACKMOUSEEVENT + WinStruct trackinfo; + trackinfo.dwFlags = TME_LEAVE; trackinfo.hwndTrack = GetHwnd(); - //Use the commctrl.h _TrackMouseEvent, which will call the - // appropriate TrackMouseEvent or emulate it ( win95 ) - // else we need _WIN32_WINNT >= 0x0400 + + // Use the commctrl.h _TrackMouseEvent(), which will call the real + // TrackMouseEvent() if available or emulate it _TrackMouseEvent(&trackinfo); -#endif -#endif +#endif // HAVE_TRACKMOUSEEVENT + wxMouseEvent event(wxEVT_ENTER_WINDOW); InitMouseEvent(event, x, y, flags); (void)GetEventHandler()->ProcessEvent(event); } } +#ifdef HAVE_TRACKMOUSEEVENT + else + { + // Check if we need to send a LEAVE event + // Windows doesn't send WM_MOUSELEAVE if the mouse has been captured so + // send it here if we are using native mouse leave tracking + if ( HasCapture() && !IsMouseInWindow() ) + { + GenerateMouseLeave(); + } + } +#endif // HAVE_TRACKMOUSEEVENT #if wxUSE_MOUSEEVENT_HACK - // Window gets a click down message followed by a mouse move message even - // if position isn't changed! We want to discard the trailing move event - // if x and y are the same. - if ( (m_lastMouseEvent == wxEVT_RIGHT_DOWN || - m_lastMouseEvent == wxEVT_LEFT_DOWN || - m_lastMouseEvent == wxEVT_MIDDLE_DOWN) && - (m_lastMouseX == x && m_lastMouseY == y) ) - { - m_lastMouseEvent = wxEVT_MOTION; + // Windows often generates mouse events even if mouse position hasn't + // changed (http://article.gmane.org/gmane.comp.lib.wxwidgets.devel/66576) + // + // Filter this out as it can result in unexpected behaviour compared to + // other platforms + if ( gs_lastMouseEvent.type == wxEVT_RIGHT_DOWN || + gs_lastMouseEvent.type == wxEVT_LEFT_DOWN || + gs_lastMouseEvent.type == wxEVT_MIDDLE_DOWN || + gs_lastMouseEvent.type == wxEVT_MOTION ) + { + if ( ClientToScreen(wxPoint(x, y)) == gs_lastMouseEvent.pos ) + { + gs_lastMouseEvent.type = wxEVT_MOTION; - return false; + return false; + } } #endif // wxUSE_MOUSEEVENT_HACK @@ -4558,11 +4685,14 @@ bool wxWindowMSW::HandleMouseMove(int x, int y, WXUINT flags) bool wxWindowMSW::HandleMouseWheel(WXWPARAM wParam, WXLPARAM lParam) { #if wxUSE_MOUSEWHEEL + // notice that WM_MOUSEWHEEL position is in screen coords (as it's + // forwarded up to the parent by DefWindowProc()) and not in the client + // ones as all the other messages, translate them to the client coords for + // consistency + const wxPoint + pt = ScreenToClient(wxPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); wxMouseEvent event(wxEVT_MOUSEWHEEL); - InitMouseEvent(event, - GET_X_LPARAM(lParam), - GET_Y_LPARAM(lParam), - LOWORD(wParam)); + InitMouseEvent(event, pt.x, pt.y, LOWORD(wParam)); event.m_wheelRotation = (short)HIWORD(wParam); event.m_wheelDelta = WHEEL_DELTA; @@ -4583,14 +4713,53 @@ bool wxWindowMSW::HandleMouseWheel(WXWPARAM wParam, WXLPARAM lParam) event.m_linesPerAction = s_linesPerRotation; return GetEventHandler()->ProcessEvent(event); -#else - (void) wParam; - (void) lParam; +#else // !wxUSE_MOUSEWHEEL + wxUnusedVar(wParam); + wxUnusedVar(lParam); return false; -#endif +#endif // wxUSE_MOUSEWHEEL/!wxUSE_MOUSEWHEEL } +void wxWindowMSW::GenerateMouseLeave() +{ + m_mouseInWindow = false; + + int state = 0; + if ( wxIsShiftDown() ) + state |= MK_SHIFT; + if ( wxIsCtrlDown() ) + state |= MK_CONTROL; + + // Only the high-order bit should be tested + if ( GetKeyState( VK_LBUTTON ) & (1<<15) ) + state |= MK_LBUTTON; + if ( GetKeyState( VK_MBUTTON ) & (1<<15) ) + state |= MK_MBUTTON; + if ( GetKeyState( VK_RBUTTON ) & (1<<15) ) + state |= MK_RBUTTON; + + POINT pt; +#ifdef __WXWINCE__ + if ( !::GetCursorPosWinCE(&pt) ) +#else + if ( !::GetCursorPos(&pt) ) +#endif + { + wxLogLastError(_T("GetCursorPos")); + } + + // we need to have client coordinates here for symmetry with + // wxEVT_ENTER_WINDOW + RECT rect = wxGetWindowRect(GetHwnd()); + pt.x -= rect.left; + pt.y -= rect.top; + + wxMouseEvent event(wxEVT_LEAVE_WINDOW); + InitMouseEvent(event, pt.x, pt.y, state); + + (void)GetEventHandler()->ProcessEvent(event); +} // --------------------------------------------------------------------------- // keyboard handling @@ -4609,7 +4778,7 @@ wxKeyEvent wxWindowMSW::CreateKeyEvent(wxEventType evType, event.m_controlDown = wxIsCtrlDown(); event.m_altDown = (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN; - event.m_eventObject = (wxWindow *)this; // const_cast + event.SetEventObject((wxWindow *)this); // const_cast event.m_keyCode = id; #if wxUSE_UNICODE event.m_uniChar = (wxChar) wParam; @@ -4622,7 +4791,11 @@ wxKeyEvent wxWindowMSW::CreateKeyEvent(wxEventType evType, // translate the position to client coords POINT pt; +#ifdef __WXWINCE__ + GetCursorPosWinCE(&pt); +#else GetCursorPos(&pt); +#endif RECT rect; GetWindowRect(GetHwnd(),&rect); pt.x -= rect.left; @@ -4738,7 +4911,8 @@ bool wxWindowMSW::HandleKeyUp(WXWPARAM wParam, WXLPARAM lParam) return false; } -int wxWindowMSW::HandleMenuChar(int chAccel, WXLPARAM lParam) +int wxWindowMSW::HandleMenuChar(int WXUNUSED_IN_WINCE(chAccel), + WXLPARAM WXUNUSED_IN_WINCE(lParam)) { // FIXME: implement GetMenuItemCount for WinCE, possibly // in terms of GetMenuItemInfo @@ -4796,9 +4970,6 @@ int wxWindowMSW::HandleMenuChar(int chAccel, WXLPARAM lParam) wxLogLastError(_T("GetMenuItemInfo")); } } -#else - wxUnusedVar(chAccel); - wxUnusedVar(lParam); #endif return wxNOT_FOUND; } @@ -4912,32 +5083,32 @@ bool wxWindowMSW::MSWOnScroll(int orientation, WXWORD wParam, wxScrollWinEvent event; event.SetPosition(pos); event.SetOrientation(orientation); - event.m_eventObject = this; + event.SetEventObject(this); switch ( wParam ) { case SB_TOP: - event.m_eventType = wxEVT_SCROLLWIN_TOP; + event.SetEventType(wxEVT_SCROLLWIN_TOP); break; case SB_BOTTOM: - event.m_eventType = wxEVT_SCROLLWIN_BOTTOM; + event.SetEventType(wxEVT_SCROLLWIN_BOTTOM); break; case SB_LINEUP: - event.m_eventType = wxEVT_SCROLLWIN_LINEUP; + event.SetEventType(wxEVT_SCROLLWIN_LINEUP); break; case SB_LINEDOWN: - event.m_eventType = wxEVT_SCROLLWIN_LINEDOWN; + event.SetEventType(wxEVT_SCROLLWIN_LINEDOWN); break; case SB_PAGEUP: - event.m_eventType = wxEVT_SCROLLWIN_PAGEUP; + event.SetEventType(wxEVT_SCROLLWIN_PAGEUP); break; case SB_PAGEDOWN: - event.m_eventType = wxEVT_SCROLLWIN_PAGEDOWN; + event.SetEventType(wxEVT_SCROLLWIN_PAGEDOWN); break; case SB_THUMBPOSITION: @@ -4956,16 +5127,16 @@ bool wxWindowMSW::MSWOnScroll(int orientation, WXWORD wParam, : SB_VERT, &scrollInfo) ) { - // Not neccessarily an error, if there are no scrollbars yet. + // Not necessarily an error, if there are no scrollbars yet. // wxLogLastError(_T("GetScrollInfo")); } event.SetPosition(scrollInfo.nTrackPos); } - event.m_eventType = wParam == SB_THUMBPOSITION + event.SetEventType( wParam == SB_THUMBPOSITION ? wxEVT_SCROLLWIN_THUMBRELEASE - : wxEVT_SCROLLWIN_THUMBTRACK; + : wxEVT_SCROLLWIN_THUMBTRACK ); break; default: @@ -5019,7 +5190,7 @@ int wxCharCodeMSWToWX(int keySym, WXLPARAM lParam) case VK_CLEAR: id = WXK_CLEAR; break; case VK_SHIFT: id = WXK_SHIFT; break; case VK_CONTROL: id = WXK_CONTROL; break; - case VK_MENU : id = WXK_MENU; break; + case VK_MENU : id = WXK_ALT; break; case VK_PAUSE: id = WXK_PAUSE; break; case VK_CAPITAL: id = WXK_CAPITAL; break; case VK_SPACE: id = WXK_SPACE; break; @@ -5125,7 +5296,6 @@ WXWORD wxCharCodeWXToMSW(int id, bool *isVirtual) case WXK_SHIFT: keySym = VK_SHIFT; break; case WXK_CONTROL: keySym = VK_CONTROL; break; case WXK_ALT: keySym = VK_MENU; break; - case WXK_MENU : keySym = VK_MENU; break; case WXK_PAUSE: keySym = VK_PAUSE; break; case WXK_CAPITAL: keySym = VK_CAPITAL; break; case WXK_PRIOR: keySym = VK_PRIOR; break; @@ -5197,6 +5367,9 @@ bool wxGetKeyState(wxKeyCode key) { bool bVirtual; + wxASSERT_MSG(key != WXK_LBUTTON && key != WXK_RBUTTON && key != + WXK_MBUTTON, wxT("can't use wxGetKeyState() for mouse buttons")); + //High order with GetAsyncKeyState only available on WIN32 #ifdef __WIN32__ //If the requested key is a LED key, return @@ -5333,7 +5506,7 @@ wxKeyboardHook(int nCode, WORD wParam, DWORD lParam) if ( (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN ) event.m_altDown = true; - event.m_eventObject = NULL; + event.SetEventObject(NULL); event.m_keyCode = id; event.m_shiftDown = wxIsShiftDown(); event.m_controlDown = wxIsCtrlDown(); @@ -5367,413 +5540,413 @@ wxKeyboardHook(int nCode, WORD wParam, DWORD lParam) #endif // !__WXMICROWIN__ #ifdef __WXDEBUG__ -const char *wxGetMessageName(int message) +const wxChar *wxGetMessageName(int message) { switch ( message ) { - case 0x0000: return "WM_NULL"; - case 0x0001: return "WM_CREATE"; - case 0x0002: return "WM_DESTROY"; - case 0x0003: return "WM_MOVE"; - case 0x0005: return "WM_SIZE"; - case 0x0006: return "WM_ACTIVATE"; - case 0x0007: return "WM_SETFOCUS"; - case 0x0008: return "WM_KILLFOCUS"; - case 0x000A: return "WM_ENABLE"; - case 0x000B: return "WM_SETREDRAW"; - case 0x000C: return "WM_SETTEXT"; - case 0x000D: return "WM_GETTEXT"; - case 0x000E: return "WM_GETTEXTLENGTH"; - case 0x000F: return "WM_PAINT"; - case 0x0010: return "WM_CLOSE"; - case 0x0011: return "WM_QUERYENDSESSION"; - case 0x0012: return "WM_QUIT"; - case 0x0013: return "WM_QUERYOPEN"; - case 0x0014: return "WM_ERASEBKGND"; - case 0x0015: return "WM_SYSCOLORCHANGE"; - case 0x0016: return "WM_ENDSESSION"; - case 0x0017: return "WM_SYSTEMERROR"; - case 0x0018: return "WM_SHOWWINDOW"; - case 0x0019: return "WM_CTLCOLOR"; - case 0x001A: return "WM_WININICHANGE"; - case 0x001B: return "WM_DEVMODECHANGE"; - case 0x001C: return "WM_ACTIVATEAPP"; - case 0x001D: return "WM_FONTCHANGE"; - case 0x001E: return "WM_TIMECHANGE"; - case 0x001F: return "WM_CANCELMODE"; - case 0x0020: return "WM_SETCURSOR"; - case 0x0021: return "WM_MOUSEACTIVATE"; - case 0x0022: return "WM_CHILDACTIVATE"; - case 0x0023: return "WM_QUEUESYNC"; - case 0x0024: return "WM_GETMINMAXINFO"; - case 0x0026: return "WM_PAINTICON"; - case 0x0027: return "WM_ICONERASEBKGND"; - case 0x0028: return "WM_NEXTDLGCTL"; - case 0x002A: return "WM_SPOOLERSTATUS"; - case 0x002B: return "WM_DRAWITEM"; - case 0x002C: return "WM_MEASUREITEM"; - case 0x002D: return "WM_DELETEITEM"; - case 0x002E: return "WM_VKEYTOITEM"; - case 0x002F: return "WM_CHARTOITEM"; - case 0x0030: return "WM_SETFONT"; - case 0x0031: return "WM_GETFONT"; - case 0x0037: return "WM_QUERYDRAGICON"; - case 0x0039: return "WM_COMPAREITEM"; - case 0x0041: return "WM_COMPACTING"; - case 0x0044: return "WM_COMMNOTIFY"; - case 0x0046: return "WM_WINDOWPOSCHANGING"; - case 0x0047: return "WM_WINDOWPOSCHANGED"; - case 0x0048: return "WM_POWER"; - - case 0x004A: return "WM_COPYDATA"; - case 0x004B: return "WM_CANCELJOURNAL"; - case 0x004E: return "WM_NOTIFY"; - case 0x0050: return "WM_INPUTLANGCHANGEREQUEST"; - case 0x0051: return "WM_INPUTLANGCHANGE"; - case 0x0052: return "WM_TCARD"; - case 0x0053: return "WM_HELP"; - case 0x0054: return "WM_USERCHANGED"; - case 0x0055: return "WM_NOTIFYFORMAT"; - case 0x007B: return "WM_CONTEXTMENU"; - case 0x007C: return "WM_STYLECHANGING"; - case 0x007D: return "WM_STYLECHANGED"; - case 0x007E: return "WM_DISPLAYCHANGE"; - case 0x007F: return "WM_GETICON"; - case 0x0080: return "WM_SETICON"; - - case 0x0081: return "WM_NCCREATE"; - case 0x0082: return "WM_NCDESTROY"; - case 0x0083: return "WM_NCCALCSIZE"; - case 0x0084: return "WM_NCHITTEST"; - case 0x0085: return "WM_NCPAINT"; - case 0x0086: return "WM_NCACTIVATE"; - case 0x0087: return "WM_GETDLGCODE"; - case 0x00A0: return "WM_NCMOUSEMOVE"; - case 0x00A1: return "WM_NCLBUTTONDOWN"; - case 0x00A2: return "WM_NCLBUTTONUP"; - case 0x00A3: return "WM_NCLBUTTONDBLCLK"; - case 0x00A4: return "WM_NCRBUTTONDOWN"; - case 0x00A5: return "WM_NCRBUTTONUP"; - case 0x00A6: return "WM_NCRBUTTONDBLCLK"; - case 0x00A7: return "WM_NCMBUTTONDOWN"; - case 0x00A8: return "WM_NCMBUTTONUP"; - case 0x00A9: return "WM_NCMBUTTONDBLCLK"; - case 0x0100: return "WM_KEYDOWN"; - case 0x0101: return "WM_KEYUP"; - case 0x0102: return "WM_CHAR"; - case 0x0103: return "WM_DEADCHAR"; - case 0x0104: return "WM_SYSKEYDOWN"; - case 0x0105: return "WM_SYSKEYUP"; - case 0x0106: return "WM_SYSCHAR"; - case 0x0107: return "WM_SYSDEADCHAR"; - case 0x0108: return "WM_KEYLAST"; - - case 0x010D: return "WM_IME_STARTCOMPOSITION"; - case 0x010E: return "WM_IME_ENDCOMPOSITION"; - case 0x010F: return "WM_IME_COMPOSITION"; - - case 0x0110: return "WM_INITDIALOG"; - case 0x0111: return "WM_COMMAND"; - case 0x0112: return "WM_SYSCOMMAND"; - case 0x0113: return "WM_TIMER"; - case 0x0114: return "WM_HSCROLL"; - case 0x0115: return "WM_VSCROLL"; - case 0x0116: return "WM_INITMENU"; - case 0x0117: return "WM_INITMENUPOPUP"; - case 0x011F: return "WM_MENUSELECT"; - case 0x0120: return "WM_MENUCHAR"; - case 0x0121: return "WM_ENTERIDLE"; - case 0x0200: return "WM_MOUSEMOVE"; - case 0x0201: return "WM_LBUTTONDOWN"; - case 0x0202: return "WM_LBUTTONUP"; - case 0x0203: return "WM_LBUTTONDBLCLK"; - case 0x0204: return "WM_RBUTTONDOWN"; - case 0x0205: return "WM_RBUTTONUP"; - case 0x0206: return "WM_RBUTTONDBLCLK"; - case 0x0207: return "WM_MBUTTONDOWN"; - case 0x0208: return "WM_MBUTTONUP"; - case 0x0209: return "WM_MBUTTONDBLCLK"; - case 0x020A: return "WM_MOUSEWHEEL"; - case 0x0210: return "WM_PARENTNOTIFY"; - case 0x0211: return "WM_ENTERMENULOOP"; - case 0x0212: return "WM_EXITMENULOOP"; - - case 0x0213: return "WM_NEXTMENU"; - case 0x0214: return "WM_SIZING"; - case 0x0215: return "WM_CAPTURECHANGED"; - case 0x0216: return "WM_MOVING"; - case 0x0218: return "WM_POWERBROADCAST"; - case 0x0219: return "WM_DEVICECHANGE"; - - case 0x0220: return "WM_MDICREATE"; - case 0x0221: return "WM_MDIDESTROY"; - case 0x0222: return "WM_MDIACTIVATE"; - case 0x0223: return "WM_MDIRESTORE"; - case 0x0224: return "WM_MDINEXT"; - case 0x0225: return "WM_MDIMAXIMIZE"; - case 0x0226: return "WM_MDITILE"; - case 0x0227: return "WM_MDICASCADE"; - case 0x0228: return "WM_MDIICONARRANGE"; - case 0x0229: return "WM_MDIGETACTIVE"; - case 0x0230: return "WM_MDISETMENU"; - case 0x0233: return "WM_DROPFILES"; - - case 0x0281: return "WM_IME_SETCONTEXT"; - case 0x0282: return "WM_IME_NOTIFY"; - case 0x0283: return "WM_IME_CONTROL"; - case 0x0284: return "WM_IME_COMPOSITIONFULL"; - case 0x0285: return "WM_IME_SELECT"; - case 0x0286: return "WM_IME_CHAR"; - case 0x0290: return "WM_IME_KEYDOWN"; - case 0x0291: return "WM_IME_KEYUP"; - - case 0x0300: return "WM_CUT"; - case 0x0301: return "WM_COPY"; - case 0x0302: return "WM_PASTE"; - case 0x0303: return "WM_CLEAR"; - case 0x0304: return "WM_UNDO"; - case 0x0305: return "WM_RENDERFORMAT"; - case 0x0306: return "WM_RENDERALLFORMATS"; - case 0x0307: return "WM_DESTROYCLIPBOARD"; - case 0x0308: return "WM_DRAWCLIPBOARD"; - case 0x0309: return "WM_PAINTCLIPBOARD"; - case 0x030A: return "WM_VSCROLLCLIPBOARD"; - case 0x030B: return "WM_SIZECLIPBOARD"; - case 0x030C: return "WM_ASKCBFORMATNAME"; - case 0x030D: return "WM_CHANGECBCHAIN"; - case 0x030E: return "WM_HSCROLLCLIPBOARD"; - case 0x030F: return "WM_QUERYNEWPALETTE"; - case 0x0310: return "WM_PALETTEISCHANGING"; - case 0x0311: return "WM_PALETTECHANGED"; + case 0x0000: return wxT("WM_NULL"); + case 0x0001: return wxT("WM_CREATE"); + case 0x0002: return wxT("WM_DESTROY"); + case 0x0003: return wxT("WM_MOVE"); + case 0x0005: return wxT("WM_SIZE"); + case 0x0006: return wxT("WM_ACTIVATE"); + case 0x0007: return wxT("WM_SETFOCUS"); + case 0x0008: return wxT("WM_KILLFOCUS"); + case 0x000A: return wxT("WM_ENABLE"); + case 0x000B: return wxT("WM_SETREDRAW"); + case 0x000C: return wxT("WM_SETTEXT"); + case 0x000D: return wxT("WM_GETTEXT"); + case 0x000E: return wxT("WM_GETTEXTLENGTH"); + case 0x000F: return wxT("WM_PAINT"); + case 0x0010: return wxT("WM_CLOSE"); + case 0x0011: return wxT("WM_QUERYENDSESSION"); + case 0x0012: return wxT("WM_QUIT"); + case 0x0013: return wxT("WM_QUERYOPEN"); + case 0x0014: return wxT("WM_ERASEBKGND"); + case 0x0015: return wxT("WM_SYSCOLORCHANGE"); + case 0x0016: return wxT("WM_ENDSESSION"); + case 0x0017: return wxT("WM_SYSTEMERROR"); + case 0x0018: return wxT("WM_SHOWWINDOW"); + case 0x0019: return wxT("WM_CTLCOLOR"); + case 0x001A: return wxT("WM_WININICHANGE"); + case 0x001B: return wxT("WM_DEVMODECHANGE"); + case 0x001C: return wxT("WM_ACTIVATEAPP"); + case 0x001D: return wxT("WM_FONTCHANGE"); + case 0x001E: return wxT("WM_TIMECHANGE"); + case 0x001F: return wxT("WM_CANCELMODE"); + case 0x0020: return wxT("WM_SETCURSOR"); + case 0x0021: return wxT("WM_MOUSEACTIVATE"); + case 0x0022: return wxT("WM_CHILDACTIVATE"); + case 0x0023: return wxT("WM_QUEUESYNC"); + case 0x0024: return wxT("WM_GETMINMAXINFO"); + case 0x0026: return wxT("WM_PAINTICON"); + case 0x0027: return wxT("WM_ICONERASEBKGND"); + case 0x0028: return wxT("WM_NEXTDLGCTL"); + case 0x002A: return wxT("WM_SPOOLERSTATUS"); + case 0x002B: return wxT("WM_DRAWITEM"); + case 0x002C: return wxT("WM_MEASUREITEM"); + case 0x002D: return wxT("WM_DELETEITEM"); + case 0x002E: return wxT("WM_VKEYTOITEM"); + case 0x002F: return wxT("WM_CHARTOITEM"); + case 0x0030: return wxT("WM_SETFONT"); + case 0x0031: return wxT("WM_GETFONT"); + case 0x0037: return wxT("WM_QUERYDRAGICON"); + case 0x0039: return wxT("WM_COMPAREITEM"); + case 0x0041: return wxT("WM_COMPACTING"); + case 0x0044: return wxT("WM_COMMNOTIFY"); + case 0x0046: return wxT("WM_WINDOWPOSCHANGING"); + case 0x0047: return wxT("WM_WINDOWPOSCHANGED"); + case 0x0048: return wxT("WM_POWER"); + + case 0x004A: return wxT("WM_COPYDATA"); + case 0x004B: return wxT("WM_CANCELJOURNAL"); + case 0x004E: return wxT("WM_NOTIFY"); + case 0x0050: return wxT("WM_INPUTLANGCHANGEREQUEST"); + case 0x0051: return wxT("WM_INPUTLANGCHANGE"); + case 0x0052: return wxT("WM_TCARD"); + case 0x0053: return wxT("WM_HELP"); + case 0x0054: return wxT("WM_USERCHANGED"); + case 0x0055: return wxT("WM_NOTIFYFORMAT"); + case 0x007B: return wxT("WM_CONTEXTMENU"); + case 0x007C: return wxT("WM_STYLECHANGING"); + case 0x007D: return wxT("WM_STYLECHANGED"); + case 0x007E: return wxT("WM_DISPLAYCHANGE"); + case 0x007F: return wxT("WM_GETICON"); + case 0x0080: return wxT("WM_SETICON"); + + case 0x0081: return wxT("WM_NCCREATE"); + case 0x0082: return wxT("WM_NCDESTROY"); + case 0x0083: return wxT("WM_NCCALCSIZE"); + case 0x0084: return wxT("WM_NCHITTEST"); + case 0x0085: return wxT("WM_NCPAINT"); + case 0x0086: return wxT("WM_NCACTIVATE"); + case 0x0087: return wxT("WM_GETDLGCODE"); + case 0x00A0: return wxT("WM_NCMOUSEMOVE"); + case 0x00A1: return wxT("WM_NCLBUTTONDOWN"); + case 0x00A2: return wxT("WM_NCLBUTTONUP"); + case 0x00A3: return wxT("WM_NCLBUTTONDBLCLK"); + case 0x00A4: return wxT("WM_NCRBUTTONDOWN"); + case 0x00A5: return wxT("WM_NCRBUTTONUP"); + case 0x00A6: return wxT("WM_NCRBUTTONDBLCLK"); + case 0x00A7: return wxT("WM_NCMBUTTONDOWN"); + case 0x00A8: return wxT("WM_NCMBUTTONUP"); + case 0x00A9: return wxT("WM_NCMBUTTONDBLCLK"); + case 0x0100: return wxT("WM_KEYDOWN"); + case 0x0101: return wxT("WM_KEYUP"); + case 0x0102: return wxT("WM_CHAR"); + case 0x0103: return wxT("WM_DEADCHAR"); + case 0x0104: return wxT("WM_SYSKEYDOWN"); + case 0x0105: return wxT("WM_SYSKEYUP"); + case 0x0106: return wxT("WM_SYSCHAR"); + case 0x0107: return wxT("WM_SYSDEADCHAR"); + case 0x0108: return wxT("WM_KEYLAST"); + + case 0x010D: return wxT("WM_IME_STARTCOMPOSITION"); + case 0x010E: return wxT("WM_IME_ENDCOMPOSITION"); + case 0x010F: return wxT("WM_IME_COMPOSITION"); + + case 0x0110: return wxT("WM_INITDIALOG"); + case 0x0111: return wxT("WM_COMMAND"); + case 0x0112: return wxT("WM_SYSCOMMAND"); + case 0x0113: return wxT("WM_TIMER"); + case 0x0114: return wxT("WM_HSCROLL"); + case 0x0115: return wxT("WM_VSCROLL"); + case 0x0116: return wxT("WM_INITMENU"); + case 0x0117: return wxT("WM_INITMENUPOPUP"); + case 0x011F: return wxT("WM_MENUSELECT"); + case 0x0120: return wxT("WM_MENUCHAR"); + case 0x0121: return wxT("WM_ENTERIDLE"); + case 0x0200: return wxT("WM_MOUSEMOVE"); + case 0x0201: return wxT("WM_LBUTTONDOWN"); + case 0x0202: return wxT("WM_LBUTTONUP"); + case 0x0203: return wxT("WM_LBUTTONDBLCLK"); + case 0x0204: return wxT("WM_RBUTTONDOWN"); + case 0x0205: return wxT("WM_RBUTTONUP"); + case 0x0206: return wxT("WM_RBUTTONDBLCLK"); + case 0x0207: return wxT("WM_MBUTTONDOWN"); + case 0x0208: return wxT("WM_MBUTTONUP"); + case 0x0209: return wxT("WM_MBUTTONDBLCLK"); + case 0x020A: return wxT("WM_MOUSEWHEEL"); + case 0x0210: return wxT("WM_PARENTNOTIFY"); + case 0x0211: return wxT("WM_ENTERMENULOOP"); + case 0x0212: return wxT("WM_EXITMENULOOP"); + + case 0x0213: return wxT("WM_NEXTMENU"); + case 0x0214: return wxT("WM_SIZING"); + case 0x0215: return wxT("WM_CAPTURECHANGED"); + case 0x0216: return wxT("WM_MOVING"); + case 0x0218: return wxT("WM_POWERBROADCAST"); + case 0x0219: return wxT("WM_DEVICECHANGE"); + + case 0x0220: return wxT("WM_MDICREATE"); + case 0x0221: return wxT("WM_MDIDESTROY"); + case 0x0222: return wxT("WM_MDIACTIVATE"); + case 0x0223: return wxT("WM_MDIRESTORE"); + case 0x0224: return wxT("WM_MDINEXT"); + case 0x0225: return wxT("WM_MDIMAXIMIZE"); + case 0x0226: return wxT("WM_MDITILE"); + case 0x0227: return wxT("WM_MDICASCADE"); + case 0x0228: return wxT("WM_MDIICONARRANGE"); + case 0x0229: return wxT("WM_MDIGETACTIVE"); + case 0x0230: return wxT("WM_MDISETMENU"); + case 0x0233: return wxT("WM_DROPFILES"); + + case 0x0281: return wxT("WM_IME_SETCONTEXT"); + case 0x0282: return wxT("WM_IME_NOTIFY"); + case 0x0283: return wxT("WM_IME_CONTROL"); + case 0x0284: return wxT("WM_IME_COMPOSITIONFULL"); + case 0x0285: return wxT("WM_IME_SELECT"); + case 0x0286: return wxT("WM_IME_CHAR"); + case 0x0290: return wxT("WM_IME_KEYDOWN"); + case 0x0291: return wxT("WM_IME_KEYUP"); + + case 0x0300: return wxT("WM_CUT"); + case 0x0301: return wxT("WM_COPY"); + case 0x0302: return wxT("WM_PASTE"); + case 0x0303: return wxT("WM_CLEAR"); + case 0x0304: return wxT("WM_UNDO"); + case 0x0305: return wxT("WM_RENDERFORMAT"); + case 0x0306: return wxT("WM_RENDERALLFORMATS"); + case 0x0307: return wxT("WM_DESTROYCLIPBOARD"); + case 0x0308: return wxT("WM_DRAWCLIPBOARD"); + case 0x0309: return wxT("WM_PAINTCLIPBOARD"); + case 0x030A: return wxT("WM_VSCROLLCLIPBOARD"); + case 0x030B: return wxT("WM_SIZECLIPBOARD"); + case 0x030C: return wxT("WM_ASKCBFORMATNAME"); + case 0x030D: return wxT("WM_CHANGECBCHAIN"); + case 0x030E: return wxT("WM_HSCROLLCLIPBOARD"); + case 0x030F: return wxT("WM_QUERYNEWPALETTE"); + case 0x0310: return wxT("WM_PALETTEISCHANGING"); + case 0x0311: return wxT("WM_PALETTECHANGED"); #if wxUSE_HOTKEY - case 0x0312: return "WM_HOTKEY"; + case 0x0312: return wxT("WM_HOTKEY"); #endif // common controls messages - although they're not strictly speaking // standard, it's nice to decode them nevertheless // listview - case 0x1000 + 0: return "LVM_GETBKCOLOR"; - case 0x1000 + 1: return "LVM_SETBKCOLOR"; - case 0x1000 + 2: return "LVM_GETIMAGELIST"; - case 0x1000 + 3: return "LVM_SETIMAGELIST"; - case 0x1000 + 4: return "LVM_GETITEMCOUNT"; - case 0x1000 + 5: return "LVM_GETITEMA"; - case 0x1000 + 75: return "LVM_GETITEMW"; - case 0x1000 + 6: return "LVM_SETITEMA"; - case 0x1000 + 76: return "LVM_SETITEMW"; - case 0x1000 + 7: return "LVM_INSERTITEMA"; - case 0x1000 + 77: return "LVM_INSERTITEMW"; - case 0x1000 + 8: return "LVM_DELETEITEM"; - case 0x1000 + 9: return "LVM_DELETEALLITEMS"; - case 0x1000 + 10: return "LVM_GETCALLBACKMASK"; - case 0x1000 + 11: return "LVM_SETCALLBACKMASK"; - case 0x1000 + 12: return "LVM_GETNEXTITEM"; - case 0x1000 + 13: return "LVM_FINDITEMA"; - case 0x1000 + 83: return "LVM_FINDITEMW"; - case 0x1000 + 14: return "LVM_GETITEMRECT"; - case 0x1000 + 15: return "LVM_SETITEMPOSITION"; - case 0x1000 + 16: return "LVM_GETITEMPOSITION"; - case 0x1000 + 17: return "LVM_GETSTRINGWIDTHA"; - case 0x1000 + 87: return "LVM_GETSTRINGWIDTHW"; - case 0x1000 + 18: return "LVM_HITTEST"; - case 0x1000 + 19: return "LVM_ENSUREVISIBLE"; - case 0x1000 + 20: return "LVM_SCROLL"; - case 0x1000 + 21: return "LVM_REDRAWITEMS"; - case 0x1000 + 22: return "LVM_ARRANGE"; - case 0x1000 + 23: return "LVM_EDITLABELA"; - case 0x1000 + 118: return "LVM_EDITLABELW"; - case 0x1000 + 24: return "LVM_GETEDITCONTROL"; - case 0x1000 + 25: return "LVM_GETCOLUMNA"; - case 0x1000 + 95: return "LVM_GETCOLUMNW"; - case 0x1000 + 26: return "LVM_SETCOLUMNA"; - case 0x1000 + 96: return "LVM_SETCOLUMNW"; - case 0x1000 + 27: return "LVM_INSERTCOLUMNA"; - case 0x1000 + 97: return "LVM_INSERTCOLUMNW"; - case 0x1000 + 28: return "LVM_DELETECOLUMN"; - case 0x1000 + 29: return "LVM_GETCOLUMNWIDTH"; - case 0x1000 + 30: return "LVM_SETCOLUMNWIDTH"; - case 0x1000 + 31: return "LVM_GETHEADER"; - case 0x1000 + 33: return "LVM_CREATEDRAGIMAGE"; - case 0x1000 + 34: return "LVM_GETVIEWRECT"; - case 0x1000 + 35: return "LVM_GETTEXTCOLOR"; - case 0x1000 + 36: return "LVM_SETTEXTCOLOR"; - case 0x1000 + 37: return "LVM_GETTEXTBKCOLOR"; - case 0x1000 + 38: return "LVM_SETTEXTBKCOLOR"; - case 0x1000 + 39: return "LVM_GETTOPINDEX"; - case 0x1000 + 40: return "LVM_GETCOUNTPERPAGE"; - case 0x1000 + 41: return "LVM_GETORIGIN"; - case 0x1000 + 42: return "LVM_UPDATE"; - case 0x1000 + 43: return "LVM_SETITEMSTATE"; - case 0x1000 + 44: return "LVM_GETITEMSTATE"; - case 0x1000 + 45: return "LVM_GETITEMTEXTA"; - case 0x1000 + 115: return "LVM_GETITEMTEXTW"; - case 0x1000 + 46: return "LVM_SETITEMTEXTA"; - case 0x1000 + 116: return "LVM_SETITEMTEXTW"; - case 0x1000 + 47: return "LVM_SETITEMCOUNT"; - case 0x1000 + 48: return "LVM_SORTITEMS"; - case 0x1000 + 49: return "LVM_SETITEMPOSITION32"; - case 0x1000 + 50: return "LVM_GETSELECTEDCOUNT"; - case 0x1000 + 51: return "LVM_GETITEMSPACING"; - case 0x1000 + 52: return "LVM_GETISEARCHSTRINGA"; - case 0x1000 + 117: return "LVM_GETISEARCHSTRINGW"; - case 0x1000 + 53: return "LVM_SETICONSPACING"; - case 0x1000 + 54: return "LVM_SETEXTENDEDLISTVIEWSTYLE"; - case 0x1000 + 55: return "LVM_GETEXTENDEDLISTVIEWSTYLE"; - case 0x1000 + 56: return "LVM_GETSUBITEMRECT"; - case 0x1000 + 57: return "LVM_SUBITEMHITTEST"; - case 0x1000 + 58: return "LVM_SETCOLUMNORDERARRAY"; - case 0x1000 + 59: return "LVM_GETCOLUMNORDERARRAY"; - case 0x1000 + 60: return "LVM_SETHOTITEM"; - case 0x1000 + 61: return "LVM_GETHOTITEM"; - case 0x1000 + 62: return "LVM_SETHOTCURSOR"; - case 0x1000 + 63: return "LVM_GETHOTCURSOR"; - case 0x1000 + 64: return "LVM_APPROXIMATEVIEWRECT"; - case 0x1000 + 65: return "LVM_SETWORKAREA"; + case 0x1000 + 0: return wxT("LVM_GETBKCOLOR"); + case 0x1000 + 1: return wxT("LVM_SETBKCOLOR"); + case 0x1000 + 2: return wxT("LVM_GETIMAGELIST"); + case 0x1000 + 3: return wxT("LVM_SETIMAGELIST"); + case 0x1000 + 4: return wxT("LVM_GETITEMCOUNT"); + case 0x1000 + 5: return wxT("LVM_GETITEMA"); + case 0x1000 + 75: return wxT("LVM_GETITEMW"); + case 0x1000 + 6: return wxT("LVM_SETITEMA"); + case 0x1000 + 76: return wxT("LVM_SETITEMW"); + case 0x1000 + 7: return wxT("LVM_INSERTITEMA"); + case 0x1000 + 77: return wxT("LVM_INSERTITEMW"); + case 0x1000 + 8: return wxT("LVM_DELETEITEM"); + case 0x1000 + 9: return wxT("LVM_DELETEALLITEMS"); + case 0x1000 + 10: return wxT("LVM_GETCALLBACKMASK"); + case 0x1000 + 11: return wxT("LVM_SETCALLBACKMASK"); + case 0x1000 + 12: return wxT("LVM_GETNEXTITEM"); + case 0x1000 + 13: return wxT("LVM_FINDITEMA"); + case 0x1000 + 83: return wxT("LVM_FINDITEMW"); + case 0x1000 + 14: return wxT("LVM_GETITEMRECT"); + case 0x1000 + 15: return wxT("LVM_SETITEMPOSITION"); + case 0x1000 + 16: return wxT("LVM_GETITEMPOSITION"); + case 0x1000 + 17: return wxT("LVM_GETSTRINGWIDTHA"); + case 0x1000 + 87: return wxT("LVM_GETSTRINGWIDTHW"); + case 0x1000 + 18: return wxT("LVM_HITTEST"); + case 0x1000 + 19: return wxT("LVM_ENSUREVISIBLE"); + case 0x1000 + 20: return wxT("LVM_SCROLL"); + case 0x1000 + 21: return wxT("LVM_REDRAWITEMS"); + case 0x1000 + 22: return wxT("LVM_ARRANGE"); + case 0x1000 + 23: return wxT("LVM_EDITLABELA"); + case 0x1000 + 118: return wxT("LVM_EDITLABELW"); + case 0x1000 + 24: return wxT("LVM_GETEDITCONTROL"); + case 0x1000 + 25: return wxT("LVM_GETCOLUMNA"); + case 0x1000 + 95: return wxT("LVM_GETCOLUMNW"); + case 0x1000 + 26: return wxT("LVM_SETCOLUMNA"); + case 0x1000 + 96: return wxT("LVM_SETCOLUMNW"); + case 0x1000 + 27: return wxT("LVM_INSERTCOLUMNA"); + case 0x1000 + 97: return wxT("LVM_INSERTCOLUMNW"); + case 0x1000 + 28: return wxT("LVM_DELETECOLUMN"); + case 0x1000 + 29: return wxT("LVM_GETCOLUMNWIDTH"); + case 0x1000 + 30: return wxT("LVM_SETCOLUMNWIDTH"); + case 0x1000 + 31: return wxT("LVM_GETHEADER"); + case 0x1000 + 33: return wxT("LVM_CREATEDRAGIMAGE"); + case 0x1000 + 34: return wxT("LVM_GETVIEWRECT"); + case 0x1000 + 35: return wxT("LVM_GETTEXTCOLOR"); + case 0x1000 + 36: return wxT("LVM_SETTEXTCOLOR"); + case 0x1000 + 37: return wxT("LVM_GETTEXTBKCOLOR"); + case 0x1000 + 38: return wxT("LVM_SETTEXTBKCOLOR"); + case 0x1000 + 39: return wxT("LVM_GETTOPINDEX"); + case 0x1000 + 40: return wxT("LVM_GETCOUNTPERPAGE"); + case 0x1000 + 41: return wxT("LVM_GETORIGIN"); + case 0x1000 + 42: return wxT("LVM_UPDATE"); + case 0x1000 + 43: return wxT("LVM_SETITEMSTATE"); + case 0x1000 + 44: return wxT("LVM_GETITEMSTATE"); + case 0x1000 + 45: return wxT("LVM_GETITEMTEXTA"); + case 0x1000 + 115: return wxT("LVM_GETITEMTEXTW"); + case 0x1000 + 46: return wxT("LVM_SETITEMTEXTA"); + case 0x1000 + 116: return wxT("LVM_SETITEMTEXTW"); + case 0x1000 + 47: return wxT("LVM_SETITEMCOUNT"); + case 0x1000 + 48: return wxT("LVM_SORTITEMS"); + case 0x1000 + 49: return wxT("LVM_SETITEMPOSITION32"); + case 0x1000 + 50: return wxT("LVM_GETSELECTEDCOUNT"); + case 0x1000 + 51: return wxT("LVM_GETITEMSPACING"); + case 0x1000 + 52: return wxT("LVM_GETISEARCHSTRINGA"); + case 0x1000 + 117: return wxT("LVM_GETISEARCHSTRINGW"); + case 0x1000 + 53: return wxT("LVM_SETICONSPACING"); + case 0x1000 + 54: return wxT("LVM_SETEXTENDEDLISTVIEWSTYLE"); + case 0x1000 + 55: return wxT("LVM_GETEXTENDEDLISTVIEWSTYLE"); + case 0x1000 + 56: return wxT("LVM_GETSUBITEMRECT"); + case 0x1000 + 57: return wxT("LVM_SUBITEMHITTEST"); + case 0x1000 + 58: return wxT("LVM_SETCOLUMNORDERARRAY"); + case 0x1000 + 59: return wxT("LVM_GETCOLUMNORDERARRAY"); + case 0x1000 + 60: return wxT("LVM_SETHOTITEM"); + case 0x1000 + 61: return wxT("LVM_GETHOTITEM"); + case 0x1000 + 62: return wxT("LVM_SETHOTCURSOR"); + case 0x1000 + 63: return wxT("LVM_GETHOTCURSOR"); + case 0x1000 + 64: return wxT("LVM_APPROXIMATEVIEWRECT"); + case 0x1000 + 65: return wxT("LVM_SETWORKAREA"); // tree view - case 0x1100 + 0: return "TVM_INSERTITEMA"; - case 0x1100 + 50: return "TVM_INSERTITEMW"; - case 0x1100 + 1: return "TVM_DELETEITEM"; - case 0x1100 + 2: return "TVM_EXPAND"; - case 0x1100 + 4: return "TVM_GETITEMRECT"; - case 0x1100 + 5: return "TVM_GETCOUNT"; - case 0x1100 + 6: return "TVM_GETINDENT"; - case 0x1100 + 7: return "TVM_SETINDENT"; - case 0x1100 + 8: return "TVM_GETIMAGELIST"; - case 0x1100 + 9: return "TVM_SETIMAGELIST"; - case 0x1100 + 10: return "TVM_GETNEXTITEM"; - case 0x1100 + 11: return "TVM_SELECTITEM"; - case 0x1100 + 12: return "TVM_GETITEMA"; - case 0x1100 + 62: return "TVM_GETITEMW"; - case 0x1100 + 13: return "TVM_SETITEMA"; - case 0x1100 + 63: return "TVM_SETITEMW"; - case 0x1100 + 14: return "TVM_EDITLABELA"; - case 0x1100 + 65: return "TVM_EDITLABELW"; - case 0x1100 + 15: return "TVM_GETEDITCONTROL"; - case 0x1100 + 16: return "TVM_GETVISIBLECOUNT"; - case 0x1100 + 17: return "TVM_HITTEST"; - case 0x1100 + 18: return "TVM_CREATEDRAGIMAGE"; - case 0x1100 + 19: return "TVM_SORTCHILDREN"; - case 0x1100 + 20: return "TVM_ENSUREVISIBLE"; - case 0x1100 + 21: return "TVM_SORTCHILDRENCB"; - case 0x1100 + 22: return "TVM_ENDEDITLABELNOW"; - case 0x1100 + 23: return "TVM_GETISEARCHSTRINGA"; - case 0x1100 + 64: return "TVM_GETISEARCHSTRINGW"; - case 0x1100 + 24: return "TVM_SETTOOLTIPS"; - case 0x1100 + 25: return "TVM_GETTOOLTIPS"; + case 0x1100 + 0: return wxT("TVM_INSERTITEMA"); + case 0x1100 + 50: return wxT("TVM_INSERTITEMW"); + case 0x1100 + 1: return wxT("TVM_DELETEITEM"); + case 0x1100 + 2: return wxT("TVM_EXPAND"); + case 0x1100 + 4: return wxT("TVM_GETITEMRECT"); + case 0x1100 + 5: return wxT("TVM_GETCOUNT"); + case 0x1100 + 6: return wxT("TVM_GETINDENT"); + case 0x1100 + 7: return wxT("TVM_SETINDENT"); + case 0x1100 + 8: return wxT("TVM_GETIMAGELIST"); + case 0x1100 + 9: return wxT("TVM_SETIMAGELIST"); + case 0x1100 + 10: return wxT("TVM_GETNEXTITEM"); + case 0x1100 + 11: return wxT("TVM_SELECTITEM"); + case 0x1100 + 12: return wxT("TVM_GETITEMA"); + case 0x1100 + 62: return wxT("TVM_GETITEMW"); + case 0x1100 + 13: return wxT("TVM_SETITEMA"); + case 0x1100 + 63: return wxT("TVM_SETITEMW"); + case 0x1100 + 14: return wxT("TVM_EDITLABELA"); + case 0x1100 + 65: return wxT("TVM_EDITLABELW"); + case 0x1100 + 15: return wxT("TVM_GETEDITCONTROL"); + case 0x1100 + 16: return wxT("TVM_GETVISIBLECOUNT"); + case 0x1100 + 17: return wxT("TVM_HITTEST"); + case 0x1100 + 18: return wxT("TVM_CREATEDRAGIMAGE"); + case 0x1100 + 19: return wxT("TVM_SORTCHILDREN"); + case 0x1100 + 20: return wxT("TVM_ENSUREVISIBLE"); + case 0x1100 + 21: return wxT("TVM_SORTCHILDRENCB"); + case 0x1100 + 22: return wxT("TVM_ENDEDITLABELNOW"); + case 0x1100 + 23: return wxT("TVM_GETISEARCHSTRINGA"); + case 0x1100 + 64: return wxT("TVM_GETISEARCHSTRINGW"); + case 0x1100 + 24: return wxT("TVM_SETTOOLTIPS"); + case 0x1100 + 25: return wxT("TVM_GETTOOLTIPS"); // header - case 0x1200 + 0: return "HDM_GETITEMCOUNT"; - case 0x1200 + 1: return "HDM_INSERTITEMA"; - case 0x1200 + 10: return "HDM_INSERTITEMW"; - case 0x1200 + 2: return "HDM_DELETEITEM"; - case 0x1200 + 3: return "HDM_GETITEMA"; - case 0x1200 + 11: return "HDM_GETITEMW"; - case 0x1200 + 4: return "HDM_SETITEMA"; - case 0x1200 + 12: return "HDM_SETITEMW"; - case 0x1200 + 5: return "HDM_LAYOUT"; - case 0x1200 + 6: return "HDM_HITTEST"; - case 0x1200 + 7: return "HDM_GETITEMRECT"; - case 0x1200 + 8: return "HDM_SETIMAGELIST"; - case 0x1200 + 9: return "HDM_GETIMAGELIST"; - case 0x1200 + 15: return "HDM_ORDERTOINDEX"; - case 0x1200 + 16: return "HDM_CREATEDRAGIMAGE"; - case 0x1200 + 17: return "HDM_GETORDERARRAY"; - case 0x1200 + 18: return "HDM_SETORDERARRAY"; - case 0x1200 + 19: return "HDM_SETHOTDIVIDER"; + case 0x1200 + 0: return wxT("HDM_GETITEMCOUNT"); + case 0x1200 + 1: return wxT("HDM_INSERTITEMA"); + case 0x1200 + 10: return wxT("HDM_INSERTITEMW"); + case 0x1200 + 2: return wxT("HDM_DELETEITEM"); + case 0x1200 + 3: return wxT("HDM_GETITEMA"); + case 0x1200 + 11: return wxT("HDM_GETITEMW"); + case 0x1200 + 4: return wxT("HDM_SETITEMA"); + case 0x1200 + 12: return wxT("HDM_SETITEMW"); + case 0x1200 + 5: return wxT("HDM_LAYOUT"); + case 0x1200 + 6: return wxT("HDM_HITTEST"); + case 0x1200 + 7: return wxT("HDM_GETITEMRECT"); + case 0x1200 + 8: return wxT("HDM_SETIMAGELIST"); + case 0x1200 + 9: return wxT("HDM_GETIMAGELIST"); + case 0x1200 + 15: return wxT("HDM_ORDERTOINDEX"); + case 0x1200 + 16: return wxT("HDM_CREATEDRAGIMAGE"); + case 0x1200 + 17: return wxT("HDM_GETORDERARRAY"); + case 0x1200 + 18: return wxT("HDM_SETORDERARRAY"); + case 0x1200 + 19: return wxT("HDM_SETHOTDIVIDER"); // tab control - case 0x1300 + 2: return "TCM_GETIMAGELIST"; - case 0x1300 + 3: return "TCM_SETIMAGELIST"; - case 0x1300 + 4: return "TCM_GETITEMCOUNT"; - case 0x1300 + 5: return "TCM_GETITEMA"; - case 0x1300 + 60: return "TCM_GETITEMW"; - case 0x1300 + 6: return "TCM_SETITEMA"; - case 0x1300 + 61: return "TCM_SETITEMW"; - case 0x1300 + 7: return "TCM_INSERTITEMA"; - case 0x1300 + 62: return "TCM_INSERTITEMW"; - case 0x1300 + 8: return "TCM_DELETEITEM"; - case 0x1300 + 9: return "TCM_DELETEALLITEMS"; - case 0x1300 + 10: return "TCM_GETITEMRECT"; - case 0x1300 + 11: return "TCM_GETCURSEL"; - case 0x1300 + 12: return "TCM_SETCURSEL"; - case 0x1300 + 13: return "TCM_HITTEST"; - case 0x1300 + 14: return "TCM_SETITEMEXTRA"; - case 0x1300 + 40: return "TCM_ADJUSTRECT"; - case 0x1300 + 41: return "TCM_SETITEMSIZE"; - case 0x1300 + 42: return "TCM_REMOVEIMAGE"; - case 0x1300 + 43: return "TCM_SETPADDING"; - case 0x1300 + 44: return "TCM_GETROWCOUNT"; - case 0x1300 + 45: return "TCM_GETTOOLTIPS"; - case 0x1300 + 46: return "TCM_SETTOOLTIPS"; - case 0x1300 + 47: return "TCM_GETCURFOCUS"; - case 0x1300 + 48: return "TCM_SETCURFOCUS"; - case 0x1300 + 49: return "TCM_SETMINTABWIDTH"; - case 0x1300 + 50: return "TCM_DESELECTALL"; + case 0x1300 + 2: return wxT("TCM_GETIMAGELIST"); + case 0x1300 + 3: return wxT("TCM_SETIMAGELIST"); + case 0x1300 + 4: return wxT("TCM_GETITEMCOUNT"); + case 0x1300 + 5: return wxT("TCM_GETITEMA"); + case 0x1300 + 60: return wxT("TCM_GETITEMW"); + case 0x1300 + 6: return wxT("TCM_SETITEMA"); + case 0x1300 + 61: return wxT("TCM_SETITEMW"); + case 0x1300 + 7: return wxT("TCM_INSERTITEMA"); + case 0x1300 + 62: return wxT("TCM_INSERTITEMW"); + case 0x1300 + 8: return wxT("TCM_DELETEITEM"); + case 0x1300 + 9: return wxT("TCM_DELETEALLITEMS"); + case 0x1300 + 10: return wxT("TCM_GETITEMRECT"); + case 0x1300 + 11: return wxT("TCM_GETCURSEL"); + case 0x1300 + 12: return wxT("TCM_SETCURSEL"); + case 0x1300 + 13: return wxT("TCM_HITTEST"); + case 0x1300 + 14: return wxT("TCM_SETITEMEXTRA"); + case 0x1300 + 40: return wxT("TCM_ADJUSTRECT"); + case 0x1300 + 41: return wxT("TCM_SETITEMSIZE"); + case 0x1300 + 42: return wxT("TCM_REMOVEIMAGE"); + case 0x1300 + 43: return wxT("TCM_SETPADDING"); + case 0x1300 + 44: return wxT("TCM_GETROWCOUNT"); + case 0x1300 + 45: return wxT("TCM_GETTOOLTIPS"); + case 0x1300 + 46: return wxT("TCM_SETTOOLTIPS"); + case 0x1300 + 47: return wxT("TCM_GETCURFOCUS"); + case 0x1300 + 48: return wxT("TCM_SETCURFOCUS"); + case 0x1300 + 49: return wxT("TCM_SETMINTABWIDTH"); + case 0x1300 + 50: return wxT("TCM_DESELECTALL"); // toolbar - case WM_USER+1: return "TB_ENABLEBUTTON"; - case WM_USER+2: return "TB_CHECKBUTTON"; - case WM_USER+3: return "TB_PRESSBUTTON"; - case WM_USER+4: return "TB_HIDEBUTTON"; - case WM_USER+5: return "TB_INDETERMINATE"; - case WM_USER+9: return "TB_ISBUTTONENABLED"; - case WM_USER+10: return "TB_ISBUTTONCHECKED"; - case WM_USER+11: return "TB_ISBUTTONPRESSED"; - case WM_USER+12: return "TB_ISBUTTONHIDDEN"; - case WM_USER+13: return "TB_ISBUTTONINDETERMINATE"; - case WM_USER+17: return "TB_SETSTATE"; - case WM_USER+18: return "TB_GETSTATE"; - case WM_USER+19: return "TB_ADDBITMAP"; - case WM_USER+20: return "TB_ADDBUTTONS"; - case WM_USER+21: return "TB_INSERTBUTTON"; - case WM_USER+22: return "TB_DELETEBUTTON"; - case WM_USER+23: return "TB_GETBUTTON"; - case WM_USER+24: return "TB_BUTTONCOUNT"; - case WM_USER+25: return "TB_COMMANDTOINDEX"; - case WM_USER+26: return "TB_SAVERESTOREA"; - case WM_USER+76: return "TB_SAVERESTOREW"; - case WM_USER+27: return "TB_CUSTOMIZE"; - case WM_USER+28: return "TB_ADDSTRINGA"; - case WM_USER+77: return "TB_ADDSTRINGW"; - case WM_USER+29: return "TB_GETITEMRECT"; - case WM_USER+30: return "TB_BUTTONSTRUCTSIZE"; - case WM_USER+31: return "TB_SETBUTTONSIZE"; - case WM_USER+32: return "TB_SETBITMAPSIZE"; - case WM_USER+33: return "TB_AUTOSIZE"; - case WM_USER+35: return "TB_GETTOOLTIPS"; - case WM_USER+36: return "TB_SETTOOLTIPS"; - case WM_USER+37: return "TB_SETPARENT"; - case WM_USER+39: return "TB_SETROWS"; - case WM_USER+40: return "TB_GETROWS"; - case WM_USER+42: return "TB_SETCMDID"; - case WM_USER+43: return "TB_CHANGEBITMAP"; - case WM_USER+44: return "TB_GETBITMAP"; - case WM_USER+45: return "TB_GETBUTTONTEXTA"; - case WM_USER+75: return "TB_GETBUTTONTEXTW"; - case WM_USER+46: return "TB_REPLACEBITMAP"; - case WM_USER+47: return "TB_SETINDENT"; - case WM_USER+48: return "TB_SETIMAGELIST"; - case WM_USER+49: return "TB_GETIMAGELIST"; - case WM_USER+50: return "TB_LOADIMAGES"; - case WM_USER+51: return "TB_GETRECT"; - case WM_USER+52: return "TB_SETHOTIMAGELIST"; - case WM_USER+53: return "TB_GETHOTIMAGELIST"; - case WM_USER+54: return "TB_SETDISABLEDIMAGELIST"; - case WM_USER+55: return "TB_GETDISABLEDIMAGELIST"; - case WM_USER+56: return "TB_SETSTYLE"; - case WM_USER+57: return "TB_GETSTYLE"; - case WM_USER+58: return "TB_GETBUTTONSIZE"; - case WM_USER+59: return "TB_SETBUTTONWIDTH"; - case WM_USER+60: return "TB_SETMAXTEXTROWS"; - case WM_USER+61: return "TB_GETTEXTROWS"; - case WM_USER+41: return "TB_GETBITMAPFLAGS"; + case WM_USER+1: return wxT("TB_ENABLEBUTTON"); + case WM_USER+2: return wxT("TB_CHECKBUTTON"); + case WM_USER+3: return wxT("TB_PRESSBUTTON"); + case WM_USER+4: return wxT("TB_HIDEBUTTON"); + case WM_USER+5: return wxT("TB_INDETERMINATE"); + case WM_USER+9: return wxT("TB_ISBUTTONENABLED"); + case WM_USER+10: return wxT("TB_ISBUTTONCHECKED"); + case WM_USER+11: return wxT("TB_ISBUTTONPRESSED"); + case WM_USER+12: return wxT("TB_ISBUTTONHIDDEN"); + case WM_USER+13: return wxT("TB_ISBUTTONINDETERMINATE"); + case WM_USER+17: return wxT("TB_SETSTATE"); + case WM_USER+18: return wxT("TB_GETSTATE"); + case WM_USER+19: return wxT("TB_ADDBITMAP"); + case WM_USER+20: return wxT("TB_ADDBUTTONS"); + case WM_USER+21: return wxT("TB_INSERTBUTTON"); + case WM_USER+22: return wxT("TB_DELETEBUTTON"); + case WM_USER+23: return wxT("TB_GETBUTTON"); + case WM_USER+24: return wxT("TB_BUTTONCOUNT"); + case WM_USER+25: return wxT("TB_COMMANDTOINDEX"); + case WM_USER+26: return wxT("TB_SAVERESTOREA"); + case WM_USER+76: return wxT("TB_SAVERESTOREW"); + case WM_USER+27: return wxT("TB_CUSTOMIZE"); + case WM_USER+28: return wxT("TB_ADDSTRINGA"); + case WM_USER+77: return wxT("TB_ADDSTRINGW"); + case WM_USER+29: return wxT("TB_GETITEMRECT"); + case WM_USER+30: return wxT("TB_BUTTONSTRUCTSIZE"); + case WM_USER+31: return wxT("TB_SETBUTTONSIZE"); + case WM_USER+32: return wxT("TB_SETBITMAPSIZE"); + case WM_USER+33: return wxT("TB_AUTOSIZE"); + case WM_USER+35: return wxT("TB_GETTOOLTIPS"); + case WM_USER+36: return wxT("TB_SETTOOLTIPS"); + case WM_USER+37: return wxT("TB_SETPARENT"); + case WM_USER+39: return wxT("TB_SETROWS"); + case WM_USER+40: return wxT("TB_GETROWS"); + case WM_USER+42: return wxT("TB_SETCMDID"); + case WM_USER+43: return wxT("TB_CHANGEBITMAP"); + case WM_USER+44: return wxT("TB_GETBITMAP"); + case WM_USER+45: return wxT("TB_GETBUTTONTEXTA"); + case WM_USER+75: return wxT("TB_GETBUTTONTEXTW"); + case WM_USER+46: return wxT("TB_REPLACEBITMAP"); + case WM_USER+47: return wxT("TB_SETINDENT"); + case WM_USER+48: return wxT("TB_SETIMAGELIST"); + case WM_USER+49: return wxT("TB_GETIMAGELIST"); + case WM_USER+50: return wxT("TB_LOADIMAGES"); + case WM_USER+51: return wxT("TB_GETRECT"); + case WM_USER+52: return wxT("TB_SETHOTIMAGELIST"); + case WM_USER+53: return wxT("TB_GETHOTIMAGELIST"); + case WM_USER+54: return wxT("TB_SETDISABLEDIMAGELIST"); + case WM_USER+55: return wxT("TB_GETDISABLEDIMAGELIST"); + case WM_USER+56: return wxT("TB_SETSTYLE"); + case WM_USER+57: return wxT("TB_GETSTYLE"); + case WM_USER+58: return wxT("TB_GETBUTTONSIZE"); + case WM_USER+59: return wxT("TB_SETBUTTONWIDTH"); + case WM_USER+60: return wxT("TB_SETMAXTEXTROWS"); + case WM_USER+61: return wxT("TB_GETTEXTROWS"); + case WM_USER+41: return wxT("TB_GETBITMAPFLAGS"); default: - static char s_szBuf[128]; - sprintf(s_szBuf, "", message); - return s_szBuf; + static wxString s_szBuf; + s_szBuf.Printf(wxT(""), message); + return s_szBuf.c_str(); } } #endif //__WXDEBUG__ @@ -5841,13 +6014,36 @@ wxWindow* wxFindWindowAtPoint(const wxPoint& pt) wxPoint wxGetMousePosition() { POINT pt; +#ifdef __WXWINCE__ + GetCursorPosWinCE(&pt); +#else GetCursorPos( & pt ); +#endif return wxPoint(pt.x, pt.y); } #if wxUSE_HOTKEY +#if defined(__SMARTPHONE__) || defined(__POCKETPC__) +static void WinCEUnregisterHotKey(int modifiers, int id) +{ + // Register hotkeys for the hardware buttons + HINSTANCE hCoreDll; + typedef BOOL (WINAPI *UnregisterFunc1Proc)(UINT, UINT); + + UnregisterFunc1Proc procUnregisterFunc; + hCoreDll = LoadLibrary(_T("coredll.dll")); + if (hCoreDll) + { + procUnregisterFunc = (UnregisterFunc1Proc)GetProcAddress(hCoreDll, _T("UnregisterFunc1")); + if (procUnregisterFunc) + procUnregisterFunc(modifiers, id); + FreeLibrary(hCoreDll); + } +} +#endif + bool wxWindowMSW::RegisterHotKey(int hotkeyId, int modifiers, int keycode) { UINT win_modifiers=0; @@ -5860,6 +6056,12 @@ bool wxWindowMSW::RegisterHotKey(int hotkeyId, int modifiers, int keycode) if ( modifiers & wxMOD_WIN ) win_modifiers |= MOD_WIN; +#if defined(__SMARTPHONE__) || defined(__POCKETPC__) + // Required for PPC and Smartphone hardware buttons + if (keycode >= WXK_SPECIAL1 && keycode <= WXK_SPECIAL20) + WinCEUnregisterHotKey(win_modifiers, hotkeyId); +#endif + if ( !::RegisterHotKey(GetHwnd(), hotkeyId, win_modifiers, keycode) ) { wxLogLastError(_T("RegisterHotKey")); @@ -5872,6 +6074,10 @@ bool wxWindowMSW::RegisterHotKey(int hotkeyId, int modifiers, int keycode) bool wxWindowMSW::UnregisterHotKey(int hotkeyId) { +#if defined(__SMARTPHONE__) || defined(__POCKETPC__) + WinCEUnregisterHotKey(MOD_WIN, hotkeyId); +#endif + if ( !::UnregisterHotKey(GetHwnd(), hotkeyId) ) { wxLogLastError(_T("UnregisterHotKey"));