X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b8f434e731d0f6153a87988777baa4c2fbe629c6..950905affdfa9041316f82308e1a11e82c783070:/src/msw/window.cpp diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 7d80f8dd6b..d83eac47ee 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -57,6 +57,7 @@ #include "wx/ownerdrw.h" #endif +#include "wx/hashmap.h" #include "wx/evtloop.h" #include "wx/power.h" #include "wx/sysopt.h" @@ -172,6 +173,13 @@ static struct MouseEventInfoDummy } gs_lastMouseEvent; #endif // wxUSE_MOUSEEVENT_HACK +// hash containing the registered handlers for the custom messages +WX_DECLARE_HASH_MAP(int, wxWindow::MSWMessageHandler, + wxIntegerHash, wxIntegerEqual, + MSWMessageHandlers); + +static MSWMessageHandlers gs_messageHandlers; + // --------------------------------------------------------------------------- // private functions // --------------------------------------------------------------------------- @@ -484,7 +492,6 @@ void wxWindowMSW::Init() m_mouseInWindow = false; m_lastKeydownProcessed = false; - m_childrenDisabled = NULL; m_frozenness = 0; m_hWnd = 0; @@ -545,8 +552,6 @@ wxWindowMSW::~wxWindowMSW() wxRemoveHandleAssociation(this); } - delete m_childrenDisabled; - } // real construction (Init() must have been called before!) @@ -648,69 +653,11 @@ wxWindow *wxWindowBase::DoFindFocus() return NULL; } -bool wxWindowMSW::Enable(bool enable) +void wxWindowMSW::DoEnable( bool enable ) { - if ( !wxWindowBase::Enable(enable) ) - return false; - HWND hWnd = GetHwnd(); if ( hWnd ) ::EnableWindow(hWnd, (BOOL)enable); - - // the logic below doesn't apply to the top level windows -- otherwise - // showing a modal dialog would result in total greying out (and ungreying - // out later) of everything which would be really ugly - if ( IsTopLevel() ) - return true; - - // when the parent is disabled, all of its children should be disabled as - // well but when it is enabled back, only those of the children which - // hadn't been already disabled in the beginning should be enabled again, - // so we have to keep the list of those children - for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); - node; - node = node->GetNext() ) - { - wxWindow *child = node->GetData(); - if ( child->IsTopLevel() ) - { - // the logic below doesn't apply to top level children - continue; - } - - if ( enable ) - { - // re-enable the child unless it had been disabled before us - if ( !m_childrenDisabled || !m_childrenDisabled->Find(child) ) - child->Enable(); - } - else // we're being disabled - { - if ( child->IsEnabled() ) - { - // disable it as children shouldn't stay enabled while the - // parent is not - child->Disable(); - } - else // child already disabled, remember it - { - // have we created the list of disabled children already? - if ( !m_childrenDisabled ) - m_childrenDisabled = new wxWindowList; - - m_childrenDisabled->Append(child); - } - } - } - - if ( enable && m_childrenDisabled ) - { - // we don't need this list any more, don't keep unused memory - delete m_childrenDisabled; - m_childrenDisabled = NULL; - } - - return true; } bool wxWindowMSW::Show(bool show) @@ -979,10 +926,7 @@ void wxWindowMSW::ScrollWindow(int dx, int dy, const wxRect *prect) RECT *pr; if ( prect ) { - rect.left = prect->x; - rect.top = prect->y; - rect.right = prect->x + prect->width; - rect.bottom = prect->y + prect->height; + wxCopyRectToRECT(*prect, rect); pr = ▭ } else @@ -1520,11 +1464,7 @@ void wxWindowMSW::Refresh(bool eraseBack, const wxRect *rect) const RECT *pRect; if ( rect ) { - mswRect.left = rect->x; - mswRect.top = rect->y; - mswRect.right = rect->x + rect->width; - mswRect.bottom = rect->y + rect->height; - + wxCopyRectToRECT(*rect, mswRect); pRect = &mswRect; } else @@ -2039,7 +1979,7 @@ void wxWindowMSW::GetTextExtent(const wxString& string, SIZE sizeRect; TEXTMETRIC tm; - ::GetTextExtentPoint32(hdc, string, string.length(), &sizeRect); + ::GetTextExtentPoint32(hdc, string.wx_str(), string.length(), &sizeRect); GetTextMetrics(hdc, &tm); if ( x ) @@ -2104,10 +2044,22 @@ bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y) ::ClientToScreen(hWnd, &point); wxCurrentPopupMenu = menu; #if defined(__WXWINCE__) - UINT flags = 0; -#else - UINT flags = TPM_RIGHTBUTTON | TPM_RECURSE; -#endif + static const UINT flags = 0; +#else // !__WXWINCE__ + UINT flags = TPM_RIGHTBUTTON; + // NT4 doesn't support TPM_RECURSE and simply doesn't show the menu at all + // when it's use, I'm not sure about Win95/98 but prefer to err on the safe + // side and not to use it there neither -- modify the test if it does work + // on these systems + if ( wxGetWinVersion() >= wxWinVersion_5 ) + { + // using TPM_RECURSE allows us to show a popup menu while another menu + // is opened which can be useful and is supported by the other + // platforms, so allow it under Windows too + flags |= TPM_RECURSE; + } +#endif // __WXWINCE__/!__WXWINCE__ + ::TrackPopupMenu(hMenu, flags, point.x, point.y, 0, hWnd, NULL); // we need to do it right now as otherwise the events are never going to be @@ -2380,7 +2332,7 @@ bool wxWindowMSW::MSWShouldPreProcessMessage(WXMSG* msg) node = node->GetNext() ) { wxWindow * const win = node->GetData(); - if ( win->AcceptsFocus() && + if ( win->CanAcceptFocus() && !(::GetWindowLong(GetHwndOf(win), GWL_EXSTYLE) & WS_EX_CONTROLPARENT) ) { @@ -2512,7 +2464,7 @@ LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM w LRESULT rc; - if ( wnd && wxEventLoop::AllowProcessing(wnd) ) + if ( wnd && wxGUIEventLoop::AllowProcessing(wnd) ) rc = wnd->MSWWindowProc(message, wParam, lParam); else rc = ::DefWindowProc(hWnd, message, wParam, lParam); @@ -2790,7 +2742,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l // problems, so don't do it for them (unnecessary anyhow) if ( !win->IsOfStandardClass() ) { - if ( message == WM_LBUTTONDOWN && win->AcceptsFocus() ) + if ( message == WM_LBUTTONDOWN && win->CanAcceptFocus() ) win->SetFocus(); } } @@ -3222,6 +3174,15 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l } break; #endif // __WXWINCE__ + + default: + // try a custom message handler + const MSWMessageHandlers::const_iterator + i = gs_messageHandlers.find(message); + if ( i != gs_messageHandlers.end() ) + { + processed = (*i->second)(this, message, wParam, lParam); + } } if ( !processed ) @@ -3408,8 +3369,8 @@ bool wxWindowMSW::MSWCreate(const wxChar *wclass, m_hWnd = (WXHWND)::CreateWindowEx ( extendedStyle, - className, - title ? title : m_windowName.c_str(), + className.wx_str(), + title ? title : m_windowName.wx_str(), style, x, y, w, h, (HWND)MSWGetParent(), @@ -3529,7 +3490,7 @@ bool wxWindowMSW::HandleTooltipNotify(WXUINT code, ( CP_ACP, 0, // no flags - ttip, + ttip.wx_str(), tipLength, buf, WXSIZEOF(buf) - 1 @@ -5268,7 +5229,7 @@ int wxWindowMSW::HandleMenuChar(int WXUNUSED_IN_WINCE(chAccel), // menu creation code wxMenuItem *item = (wxMenuItem*)mii.dwItemData; - const wxChar *p = wxStrchr(item->GetText(), _T('&')); + const wxChar *p = wxStrchr(item->GetText().wx_str(), _T('&')); while ( p++ ) { if ( *p == _T('&') ) @@ -5488,6 +5449,30 @@ bool wxWindowMSW::MSWOnScroll(int orientation, WXWORD wParam, return GetEventHandler()->ProcessEvent(event); } +// ---------------------------------------------------------------------------- +// custom message handlers +// ---------------------------------------------------------------------------- + +/* static */ bool +wxWindowMSW::MSWRegisterMessageHandler(int msg, MSWMessageHandler handler) +{ + wxCHECK_MSG( gs_messageHandlers.find(msg) == gs_messageHandlers.end(), + false, _T("registering handler for the same message twice") ); + + gs_messageHandlers[msg] = handler; + return true; +} + +/* static */ void +wxWindowMSW::MSWUnregisterMessageHandler(int msg, MSWMessageHandler handler) +{ + const MSWMessageHandlers::iterator i = gs_messageHandlers.find(msg); + wxCHECK_RET( i != gs_messageHandlers.end() && i->second == handler, + _T("unregistering non-registered handler?") ); + + gs_messageHandlers.erase(i); +} + // =========================================================================== // global functions // =========================================================================== @@ -5779,7 +5764,7 @@ static inline bool wxIsKeyDown(WXWORD vk) switch (vk) { case VK_LBUTTON: - if (GetSystemMetrics(SM_SWAPBUTTON)) vk = VK_RBUTTON; + if (GetSystemMetrics(SM_SWAPBUTTON)) vk = VK_RBUTTON; break; case VK_RBUTTON: if (GetSystemMetrics(SM_SWAPBUTTON)) vk = VK_LBUTTON; @@ -6073,6 +6058,46 @@ const wxChar *wxGetMessageName(int message) case 0x00A7: return wxT("WM_NCMBUTTONDOWN"); case 0x00A8: return wxT("WM_NCMBUTTONUP"); case 0x00A9: return wxT("WM_NCMBUTTONDBLCLK"); + + case 0x00B0: return wxT("EM_GETSEL"); + case 0x00B1: return wxT("EM_SETSEL"); + case 0x00B2: return wxT("EM_GETRECT"); + case 0x00B3: return wxT("EM_SETRECT"); + case 0x00B4: return wxT("EM_SETRECTNP"); + case 0x00B5: return wxT("EM_SCROLL"); + case 0x00B6: return wxT("EM_LINESCROLL"); + case 0x00B7: return wxT("EM_SCROLLCARET"); + case 0x00B8: return wxT("EM_GETMODIFY"); + case 0x00B9: return wxT("EM_SETMODIFY"); + case 0x00BA: return wxT("EM_GETLINECOUNT"); + case 0x00BB: return wxT("EM_LINEINDEX"); + case 0x00BC: return wxT("EM_SETHANDLE"); + case 0x00BD: return wxT("EM_GETHANDLE"); + case 0x00BE: return wxT("EM_GETTHUMB"); + case 0x00C1: return wxT("EM_LINELENGTH"); + case 0x00C2: return wxT("EM_REPLACESEL"); + case 0x00C4: return wxT("EM_GETLINE"); + case 0x00C5: return wxT("EM_LIMITTEXT/EM_SETLIMITTEXT"); /* ;win40 Name change */ + case 0x00C6: return wxT("EM_CANUNDO"); + case 0x00C7: return wxT("EM_UNDO"); + case 0x00C8: return wxT("EM_FMTLINES"); + case 0x00C9: return wxT("EM_LINEFROMCHAR"); + case 0x00CB: return wxT("EM_SETTABSTOPS"); + case 0x00CC: return wxT("EM_SETPASSWORDCHAR"); + case 0x00CD: return wxT("EM_EMPTYUNDOBUFFER"); + case 0x00CE: return wxT("EM_GETFIRSTVISIBLELINE"); + case 0x00CF: return wxT("EM_SETREADONLY"); + case 0x00D0: return wxT("EM_SETWORDBREAKPROC"); + case 0x00D1: return wxT("EM_GETWORDBREAKPROC"); + case 0x00D2: return wxT("EM_GETPASSWORDCHAR"); + case 0x00D3: return wxT("EM_SETMARGINS"); + case 0x00D4: return wxT("EM_GETMARGINS"); + case 0x00D5: return wxT("EM_GETLIMITTEXT"); + case 0x00D6: return wxT("EM_POSFROMCHAR"); + case 0x00D7: return wxT("EM_CHARFROMPOS"); + case 0x00D8: return wxT("EM_SETIMESTATUS"); + case 0x00D9: return wxT("EM_GETIMESTATUS"); + case 0x0100: return wxT("WM_KEYDOWN"); case 0x0101: return wxT("WM_KEYUP"); case 0x0102: return wxT("WM_CHAR"); @@ -6098,6 +6123,16 @@ const wxChar *wxGetMessageName(int message) case 0x011F: return wxT("WM_MENUSELECT"); case 0x0120: return wxT("WM_MENUCHAR"); case 0x0121: return wxT("WM_ENTERIDLE"); + + case 0x0132: return wxT("WM_CTLCOLORMSGBOX"); + case 0x0133: return wxT("WM_CTLCOLOREDIT"); + case 0x0134: return wxT("WM_CTLCOLORLISTBOX"); + case 0x0135: return wxT("WM_CTLCOLORBTN"); + case 0x0136: return wxT("WM_CTLCOLORDLG"); + case 0x0137: return wxT("WM_CTLCOLORSCROLLBAR"); + case 0x0138: return wxT("WM_CTLCOLORSTATIC"); + case 0x01E1: return wxT("MN_GETHMENU"); + case 0x0200: return wxT("WM_MOUSEMOVE"); case 0x0201: return wxT("WM_LBUTTONDOWN"); case 0x0202: return wxT("WM_LBUTTONUP"); @@ -6142,6 +6177,11 @@ const wxChar *wxGetMessageName(int message) case 0x0290: return wxT("WM_IME_KEYDOWN"); case 0x0291: return wxT("WM_IME_KEYUP"); + case 0x02A0: return wxT("WM_NCMOUSEHOVER"); + case 0x02A1: return wxT("WM_MOUSEHOVER"); + case 0x02A2: return wxT("WM_NCMOUSELEAVE"); + case 0x02A3: return wxT("WM_MOUSELEAVE"); + case 0x0300: return wxT("WM_CUT"); case 0x0301: return wxT("WM_COPY"); case 0x0302: return wxT("WM_PASTE"); @@ -6160,9 +6200,10 @@ const wxChar *wxGetMessageName(int message) case 0x030F: return wxT("WM_QUERYNEWPALETTE"); case 0x0310: return wxT("WM_PALETTEISCHANGING"); case 0x0311: return wxT("WM_PALETTECHANGED"); -#if wxUSE_HOTKEY case 0x0312: return wxT("WM_HOTKEY"); -#endif + + case 0x0317: return wxT("WM_PRINT"); + case 0x0318: return wxT("WM_PRINTCLIENT"); // common controls messages - although they're not strictly speaking // standard, it's nice to decode them nevertheless @@ -6593,7 +6634,7 @@ public: } return CallNextHookEx(ms_hMsgHookProc, nCode, wParam, lParam); - }; + } private: static HHOOK ms_hMsgHookProc;