X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2690830ea0c100902aa85eb98a56506a5a98ce0d..2035e10e83324c6925d12725b842768f6e2b00a2:/src/msw/window.cpp diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 4cd05cfd2f..9e92ac4db2 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -54,9 +54,8 @@ #include "wx/ownerdrw.h" #endif -#if wxUSE_DRAG_AND_DROP - #include "wx/dataobj.h" - #include "wx/msw/ole/droptgt.h" +#if wxUSE_DRAG_AND_DROP + #include "wx/dnd.h" #endif #include "wx/menuitem.h" @@ -75,12 +74,12 @@ #include "wx/intl.h" #include "wx/log.h" - #include "wx/textctrl.h" +#include "wx/notebook.h" #include -#if !defined(__GNUWIN32__)|| defined(wxUSE_NORLANDER_HEADERS) +#ifndef __GNUWIN32_OLD__ #include #include #endif @@ -89,28 +88,16 @@ #include #endif -#if ( defined(__WIN95__) && !defined(__GNUWIN32__)) || defined(__TWIN32__ ) || defined(wxUSE_NORLANDER_HEADERS) - #include -#endif - -#ifndef __TWIN32__ - #ifdef __GNUWIN32__ - #ifndef wxUSE_NORLANDER_HEADERS - #include - #endif +#if !defined(__GNUWIN32_OLD__) && !defined(__TWIN32__) + #ifdef __WIN95__ + #include + #endif +#else // broken compiler + #ifndef __TWIN32__ + #include "wx/msw/gnuwin32/extra.h" #endif #endif -// --------------------------------------------------------------------------- -// macros -// --------------------------------------------------------------------------- - -// standard macros missing from some compilers headers -#ifndef GET_X_LPARAM - #define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp)) - #define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp)) -#endif // GET_X_LPARAM - // --------------------------------------------------------------------------- // global variables // --------------------------------------------------------------------------- @@ -120,14 +107,14 @@ extern MSG s_currentMsg; wxMenu *wxCurrentPopupMenu = NULL; extern wxList WXDLLEXPORT wxPendingDelete; -extern wxChar wxCanvasClassName[]; +extern const wxChar *wxCanvasClassName; // --------------------------------------------------------------------------- // private functions // --------------------------------------------------------------------------- // the window proc for all our windows -LRESULT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, +LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); #ifdef __WXDEBUG__ @@ -138,19 +125,22 @@ void wxRemoveHandleAssociation(wxWindow *win); void wxAssociateWinWithHandle(HWND hWnd, wxWindow *win); wxWindow *wxFindWinFromHandle(WXHWND hWnd); +// this magical function is used to translate VK_APPS key presses to right +// mouse clicks +static void TranslateKbdEventToMouse(wxWindow *win, int *x, int *y, WPARAM *flags); + // --------------------------------------------------------------------------- // event tables // --------------------------------------------------------------------------- -#if !USE_SHARED_LIBRARY - IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase) -#endif +IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase) BEGIN_EVENT_TABLE(wxWindow, wxWindowBase) EVT_ERASE_BACKGROUND(wxWindow::OnEraseBackground) EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged) EVT_INIT_DIALOG(wxWindow::OnInitDialog) EVT_IDLE(wxWindow::OnIdle) + EVT_SET_FOCUS(wxWindow::OnSetFocus) END_EVENT_TABLE() // =========================================================================== @@ -164,6 +154,17 @@ END_EVENT_TABLE() // Find an item given the MS Windows id wxWindow *wxWindow::FindItem(long id) const { + wxControl *item = wxDynamicCast(this, wxControl); + if ( item ) + { + // i it we or one of our "internal" children? + if ( item->GetId() == id || + (item->GetSubcontrols().Index(id) != wxNOT_FOUND) ) + { + return item; + } + } + wxWindowList::Node *current = GetChildren().GetFirst(); while (current) { @@ -173,19 +174,6 @@ wxWindow *wxWindow::FindItem(long id) const if ( wnd ) return wnd; - if ( childWin->IsKindOf(CLASSINFO(wxControl)) ) - { - wxControl *item = (wxControl *)childWin; - if ( item->GetId() == id ) - return item; - else - { - // In case it's a 'virtual' control (e.g. radiobox) - if ( item->GetSubcontrols().Member((wxObject *)id) ) - return item; - } - } - current = current->GetNext(); } @@ -282,8 +270,12 @@ wxWindow::~wxWindow() if ( m_hWnd ) { - if ( !::DestroyWindow(GetHwnd()) ) - wxLogLastError("DestroyWindow"); + // VZ: test temp removed to understand what really happens here + //if (::IsWindow(GetHwnd())) + { + if ( !::DestroyWindow(GetHwnd()) ) + wxLogLastError("DestroyWindow"); + } // remove hWnd <-> wxWindow association wxRemoveHandleAssociation(this); @@ -297,7 +289,7 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id, long style, const wxString& name) { - wxCHECK_MSG( parent, FALSE, T("can't create wxWindow without parent") ); + wxCHECK_MSG( parent, FALSE, wxT("can't create wxWindow without parent") ); if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) ) return FALSE; @@ -373,6 +365,20 @@ bool wxWindow::Enable(bool enable) if ( hWnd ) ::EnableWindow(hWnd, (BOOL)enable); + // VZ: no, this is a bad idea: imagine that you have a dialog with some + // disabled controls and disable it - you really wouldn't like the + // disabled controls eb reenabled too when you reenable the dialog! +#if 0 + wxWindowList::Node *node = GetChildren().GetFirst(); + while ( node ) + { + wxWindow *child = node->GetData(); + child->Enable(enable); + + node = node->GetNext(); + } +#endif // 0 + return TRUE; } @@ -448,7 +454,7 @@ bool wxWindow::SetFont(const wxFont& font) { WXHANDLE hFont = m_font.GetResourceHandle(); - wxASSERT_MSG( hFont, T("should have valid font") ); + wxASSERT_MSG( hFont, wxT("should have valid font") ); ::SendMessage(hWnd, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0)); } @@ -464,7 +470,7 @@ bool wxWindow::SetCursor(const wxCursor& cursor) } wxASSERT_MSG( m_cursor.Ok(), - T("cursor must be valid after call to the base version")); + wxT("cursor must be valid after call to the base version")); HWND hWnd = GetHwnd(); @@ -476,7 +482,7 @@ bool wxWindow::SetCursor(const wxCursor& cursor) ::GetWindowRect(hWnd, &rect); if ( ::PtInRect(&rect, point) && !wxIsBusy() ) - ::SetCursor((HCURSOR)m_cursor.GetHCURSOR()); + ::SetCursor(GetHcursorOf(m_cursor)); return TRUE; } @@ -801,10 +807,10 @@ void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect) void wxWindow::SubclassWin(WXHWND hWnd) { - wxASSERT_MSG( !m_oldWndProc, T("subclassing window twice?") ); + wxASSERT_MSG( !m_oldWndProc, wxT("subclassing window twice?") ); HWND hwnd = (HWND)hWnd; - wxCHECK_RET( ::IsWindow(hwnd), T("invalid HWND in SubclassWin") ); + wxCHECK_RET( ::IsWindow(hwnd), wxT("invalid HWND in SubclassWin") ); wxAssociateWinWithHandle(hwnd, this); @@ -822,7 +828,7 @@ void wxWindow::UnsubclassWin() { m_hWnd = 0; - wxCHECK_RET( ::IsWindow(hwnd), T("invalid HWND in UnsubclassWin") ); + wxCHECK_RET( ::IsWindow(hwnd), wxT("invalid HWND in UnsubclassWin") ); FARPROC farProc = (FARPROC) GetWindowLong(hwnd, GWL_WNDPROC); if ( (m_oldWndProc != 0) && (farProc != (FARPROC) m_oldWndProc) ) @@ -969,9 +975,9 @@ void wxWindow::OnIdle(wxIdleEvent& event) // by the time the OnIdle function is called, so 'state' may be // meaningless. int state = 0; - if ( ::GetKeyState(VK_SHIFT) != 0 ) + if ( wxIsShiftDown() ) state |= MK_SHIFT; - if ( ::GetKeyState(VK_CONTROL) != 0 ) + if ( wxIsCtrlDown() ) state |= MK_CONTROL; wxMouseEvent event(wxEVT_LEAVE_WINDOW); @@ -1174,6 +1180,14 @@ void wxWindow::DoGetClientSize(int *x, int *y) const *y = rect.bottom; } +void wxWindow::DoMoveWindow(int x, int y, int width, int height) +{ + if ( !::MoveWindow(GetHwnd(), x, y, width, height, TRUE) ) + { + wxLogLastError("MoveWindow"); + } +} + // set the size of the window: if the dimensions are positive, just use them, // but if any of them is equal to -1, it means that we must find the value for // it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in @@ -1197,9 +1211,9 @@ void wxWindow::DoSetSize(int x, int y, int width, int height, int sizeFlags) return; } - if ( x == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE) ) + if ( x == -1 && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) ) x = currentX; - if ( y == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE) ) + if ( y == -1 && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) ) y = currentY; AdjustForParentClientOrigin(x, y, sizeFlags); @@ -1207,7 +1221,7 @@ void wxWindow::DoSetSize(int x, int y, int width, int height, int sizeFlags) wxSize size(-1, -1); if ( width == -1 ) { - if ( sizeFlags && wxSIZE_AUTO_WIDTH ) + if ( sizeFlags & wxSIZE_AUTO_WIDTH ) { size = DoGetBestSize(); width = size.x; @@ -1221,11 +1235,11 @@ void wxWindow::DoSetSize(int x, int y, int width, int height, int sizeFlags) if ( height == -1 ) { - if ( sizeFlags && wxSIZE_AUTO_HEIGHT ) + if ( sizeFlags & wxSIZE_AUTO_HEIGHT ) { if ( size.x == -1 ) { - size= DoGetBestSize(); + size = DoGetBestSize(); } //else: already called DoGetBestSize() above @@ -1238,16 +1252,7 @@ void wxWindow::DoSetSize(int x, int y, int width, int height, int sizeFlags) } } - if ( !::MoveWindow(GetHwnd(), x, y, width, height, TRUE) ) - { - wxLogLastError("MoveWindow"); - } -} - -// for a generic window there is no natural best size - just use the current one -wxSize wxWindow::DoGetBestSize() -{ - return GetSize(); + DoMoveWindow(x, y, width, height); } void wxWindow::DoSetClientSize(int width, int height) @@ -1281,7 +1286,7 @@ void wxWindow::DoSetClientSize(int width, int height) ::ScreenToClient(hParentWnd, &point); } - MoveWindow(hWnd, point.x, point.y, actual_width, actual_height, (BOOL)TRUE); + DoMoveWindow(point.x, point.y, actual_width, actual_height); wxSizeEvent event(wxSize(width, height), m_windowId); event.SetEventObject(this); @@ -1466,6 +1471,10 @@ bool wxWindow::MSWProcessMessage(WXMSG* pMsg) { // intercept dialog navigation keys MSG *msg = (MSG *)pMsg; + + // here we try to do all the job which ::IsDialogMessage() usually does + // internally +#if 1 bool bProcess = TRUE; if ( msg->message != WM_KEYDOWN ) bProcess = FALSE; @@ -1475,8 +1484,8 @@ bool wxWindow::MSWProcessMessage(WXMSG* pMsg) if ( bProcess ) { - bool bCtrlDown = (::GetKeyState(VK_CONTROL) & 0x100) != 0; - bool bShiftDown = (::GetKeyState(VK_SHIFT) & 0x100) != 0; + bool bCtrlDown = wxIsCtrlDown(); + bool bShiftDown = wxIsShiftDown(); // WM_GETDLGCODE: ask the control if it wants the key for itself, // don't process it if it's the case (except for Ctrl-Tab/Enter @@ -1583,6 +1592,35 @@ bool wxWindow::MSWProcessMessage(WXMSG* pMsg) } } } +#else + // let ::IsDialogMessage() do almost everything and handle just the + // things it doesn't here: Ctrl-TAB for switching notebook pages + if ( msg->message == WM_KEYDOWN ) + { + // don't process system keys here + if ( !(HIWORD(msg->lParam) & KF_ALTDOWN) ) + { + if ( (msg->wParam == VK_TAB) && wxIsCtrlDown() ) + { + // find the first notebook parent and change its page + wxWindow *win = this; + wxNotebook *nbook = NULL; + while ( win && !nbook ) + { + nbook = wxDynamicCast(win, wxNotebook); + win = win->GetParent(); + } + + if ( nbook ) + { + bool forward = !wxIsShiftDown(); + + nbook->AdvanceSelection(forward); + } + } + } + } +#endif // 0 if ( ::IsDialogMessage(GetHwnd(), msg) ) return TRUE; @@ -1705,11 +1743,11 @@ void wxWindow::UnpackMenuSelect(WXWPARAM wParam, WXLPARAM lParam, wxWindow *wxWndHook = NULL; // Main window proc -LRESULT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { // trace all messages - useful for the debugging #ifdef __WXDEBUG__ - wxLogTrace(wxTraceMessages, T("Processing %s(wParam=%8lx, lParam=%8lx)"), + wxLogTrace(wxTraceMessages, wxT("Processing %s(wParam=%8lx, lParam=%8lx)"), wxGetMessageName(message), wParam, lParam); #endif // __WXDEBUG__ @@ -1829,7 +1867,20 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) break; case WM_MOUSEMOVE: + { + short x = LOWORD(lParam); + short y = HIWORD(lParam); + + processed = HandleMouseMove(x, y, wParam); + } + break; + case WM_LBUTTONDOWN: + // set focus to this window + SetFocus(); + + // fall through + case WM_LBUTTONUP: case WM_LBUTTONDBLCLK: case WM_RBUTTONDOWN: @@ -1912,6 +1963,7 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) //else: get the dlg code from the DefWindowProc() break; + case WM_SYSKEYDOWN: case WM_KEYDOWN: // If this has been processed by an event handler, // return 0 now (we've handled it). @@ -1939,6 +1991,8 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) case VK_RETURN: case VK_BACK: case VK_TAB: + case VK_ADD: + case VK_SUBTRACT: // but set processed to FALSE, not TRUE to still pass them to // the control's default window proc - otherwise built-in // keyboard handling won't work @@ -1951,20 +2005,11 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) // click because both usually pop up a context menu case VK_APPS: { - // construct the key mask - WPARAM fwKeys = MK_RBUTTON; - if ( (::GetKeyState(VK_CONTROL) & 0x100) != 0 ) - fwKeys |= MK_CONTROL; - if ( (::GetKeyState(VK_SHIFT) & 0x100) != 0 ) - fwKeys |= MK_SHIFT; - - // simulate right mouse button click - DWORD dwPos = ::GetMessagePos(); - int x = GET_X_LPARAM(dwPos), - y = GET_Y_LPARAM(dwPos); - - ScreenToClient(&x, &y); - processed = HandleMouseEvent(WM_RBUTTONDOWN, x, y, fwKeys); + WPARAM flags; + int x, y; + + TranslateKbdEventToMouse(this, &x, &y, &flags); + processed = HandleMouseEvent(WM_RBUTTONDOWN, x, y, flags); } break; #endif // VK_APPS @@ -1978,10 +2023,26 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) } break; + case WM_SYSKEYUP: case WM_KEYUP: - processed = HandleKeyUp((WORD) wParam, lParam); +#ifdef VK_APPS + // special case of VK_APPS: treat it the same as right mouse button + if ( wParam == VK_APPS ) + { + WPARAM flags; + int x, y; + + TranslateKbdEventToMouse(this, &x, &y, &flags); + processed = HandleMouseEvent(WM_RBUTTONUP, x, y, flags); + } + else +#endif // VK_APPS + { + processed = HandleKeyUp((WORD) wParam, lParam); + } break; + case WM_SYSCHAR: case WM_CHAR: // Always an ASCII character processed = HandleChar((WORD)wParam, lParam, TRUE); break; @@ -2094,7 +2155,7 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) if ( !processed ) { #ifdef __WXDEBUG__ - wxLogTrace(wxTraceMessages, T("Forwarding %s to DefWindowProc."), + wxLogTrace(wxTraceMessages, wxT("Forwarding %s to DefWindowProc."), wxGetMessageName(message)); #endif // __WXDEBUG__ rc.result = MSWDefWindowProc(message, wParam, lParam); @@ -2139,14 +2200,14 @@ void wxAssociateWinWithHandle(HWND hWnd, wxWindow *win) // adding NULL hWnd is (first) surely a result of an error and // (secondly) breaks menu command processing wxCHECK_RET( hWnd != (HWND)NULL, - T("attempt to add a NULL hWnd to window list ignored") ); + wxT("attempt to add a NULL hWnd to window list ignored") ); wxWindow *oldWin = wxFindWinFromHandle((WXHWND) hWnd); if ( oldWin && (oldWin != win) ) { wxString str(win->GetClassInfo()->GetClassName()); - wxLogError("Bug! Found existing HWND %X for new window of class %s", (int) hWnd, (const char*) str); + wxLogError(wxT("Bug! Found existing HWND %X for new window of class %s"), (int) hWnd, (const wxChar*) str); } else if (!oldWin) { @@ -2191,12 +2252,12 @@ void wxWindow::MSWDetachWindowMenu() int chars = GetMenuString(hMenu, i, buf, 100, MF_BYPOSITION); if ( !chars ) { - wxLogLastError(T("GetMenuString")); + wxLogLastError(wxT("GetMenuString")); continue; } - if ( wxStrcmp(buf, T("&Window")) == 0 ) + if ( wxStrcmp(buf, wxT("&Window")) == 0 ) { RemoveMenu(hMenu, i, MF_BYPOSITION); @@ -2240,6 +2301,17 @@ bool wxWindow::MSWCreate(int id, if ( width > -1 ) width1 = width; if ( height > -1 ) height1 = height; + // Unfortunately this won't work in WIN16. Unless perhaps + // we define WS_EX_CONTROLPARENT ourselves? +#ifndef __WIN16__ + // if we have wxTAB_TRAVERSAL style, we want WS_EX_CONTROLPARENT or + // IsDialogMessage() won't work for us + if ( GetWindowStyleFlag() & wxTAB_TRAVERSAL ) + { + extendedStyle |= WS_EX_CONTROLPARENT; + } +#endif + HWND hParent = (HWND)NULL; if ( parent ) hParent = (HWND) parent->GetHWND(); @@ -2268,14 +2340,14 @@ bool wxWindow::MSWCreate(int id, if ( !::SetWindowPos(GetHwnd(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE) ) { - wxLogLastError(T("SetWindowPos")); + wxLogLastError(wxT("SetWindowPos")); } } // move the dialog to its initial position without forcing repainting if ( !::MoveWindow(GetHwnd(), x1, y1, width1, height1, FALSE) ) { - wxLogLastError(T("MoveWindow")); + wxLogLastError(wxT("MoveWindow")); } } else @@ -2287,12 +2359,12 @@ bool wxWindow::MSWCreate(int id, wxString className(wclass); if ( GetWindowStyleFlag() & wxNO_FULL_REPAINT_ON_RESIZE ) { - className += T("NR"); + className += wxT("NR"); } m_hWnd = (WXHWND)CreateWindowEx(extendedStyle, - wclass, - title ? title : T(""), + className, + title ? title : wxT(""), style, x1, y1, width1, height1, @@ -2318,7 +2390,7 @@ bool wxWindow::MSWCreate(int id, HWND hWnd = (HWND) node->GetKeyInteger(); if (hWnd != (HWND) m_hWnd) { - wxLogError("A second HWND association is being added for the same window!"); + wxLogError(wxT("A second HWND association is being added for the same window!")); } } #endif @@ -2374,7 +2446,7 @@ bool wxWindow::MSWOnNotify(int WXUNUSED(idCtrl), { #if wxUSE_TOOLTIPS NMHDR* hdr = (NMHDR *)lParam; - if ( hdr->code == TTN_NEEDTEXT && m_tooltip ) + if ( (int)hdr->code == TTN_NEEDTEXT && m_tooltip ) { TOOLTIPTEXT *ttt = (TOOLTIPTEXT *)lParam; ttt->lpszText = (wxChar *)m_tooltip->GetTip().c_str(); @@ -2397,7 +2469,7 @@ bool wxWindow::HandleQueryEndSession(long logOff, bool *mayEnd) wxCloseEvent event(wxEVT_QUERY_END_SESSION, -1); event.SetEventObject(wxTheApp); event.SetCanVeto(TRUE); - event.SetLoggingOff(logOff == ENDSESSION_LOGOFF); + event.SetLoggingOff(logOff == (long)ENDSESSION_LOGOFF); bool rc = wxTheApp->ProcessEvent(event); @@ -2420,7 +2492,7 @@ bool wxWindow::HandleEndSession(bool endSession, long logOff) wxCloseEvent event(wxEVT_END_SESSION, -1); event.SetEventObject(wxTheApp); event.SetCanVeto(FALSE); - event.SetLoggingOff( (logOff == ENDSESSION_LOGOFF) ); + event.SetLoggingOff( (logOff == (long)ENDSESSION_LOGOFF) ); if ( (this == wxTheApp->GetTopWindow()) && // Only send once wxTheApp->ProcessEvent(event)) { @@ -2467,6 +2539,33 @@ bool wxWindow::HandleDestroy() // activation/focus // --------------------------------------------------------------------------- +void wxWindow::OnSetFocus(wxFocusEvent& event) +{ + // panel wants to track the window which was the last to have focus in it, + // so we want to set ourselves as the window which last had focus + // + // notice that it's also important to do it upwards the tree becaus + // otherwise when the top level panel gets focus, it won't set it back to + // us, but to some other sibling + wxWindow *win = this; + while ( win ) + { + wxWindow *parent = win->GetParent(); + wxPanel *panel = wxDynamicCast(parent, wxPanel); + if ( panel ) + { + panel->SetLastFocus(win); + } + + win = parent; + } + + wxLogTrace(_T("focus"), _T("%s (0x%08x) gets focus"), + GetClassInfo()->GetClassName(), GetHandle()); + + event.Skip(); +} + bool wxWindow::HandleActivate(int state, bool WXUNUSED(minimized), WXHWND WXUNUSED(activate)) @@ -2489,13 +2588,6 @@ bool wxWindow::HandleSetFocus(WXHWND WXUNUSED(hwnd)) } #endif // wxUSE_CARET - // panel wants to track the window which was the last to have focus in it - wxPanel *panel = wxDynamicCast(GetParent(), wxPanel); - if ( panel ) - { - panel->SetLastFocus(this); - } - wxFocusEvent event(wxEVT_SET_FOCUS, m_windowId); event.SetEventObject(this); @@ -2574,54 +2666,46 @@ bool wxWindow::HandleSetCursor(WXHWND hWnd, short nHitTest, int WXUNUSED(mouseMsg)) { - // don't set cursor for other windows, only for this one: this prevents - // children of this window from getting the same cursor as the parent has - // (don't forget that this message is propagated by default up the window - // parent-child hierarchy) - if ( GetHWND() == hWnd ) - { - // don't set cursor when the mouse is not in the client part - if ( nHitTest == HTCLIENT || nHitTest == HTERROR ) - { - HCURSOR hcursor = 0; - if ( wxIsBusy() ) - { - // from msw\utils.cpp - extern HCURSOR gs_wxBusyCursor; + // the logic is as follows: + // 1. if we have the cursor set it unless wxIsBusy() + // 2. if we're a top level window, set some cursor anyhow + // 3. if wxIsBusy(), set the busy cursor, otherwise the global one - hcursor = gs_wxBusyCursor; - } - else - { - wxCursor *cursor = NULL; - - if ( m_cursor.Ok() ) - { - cursor = &m_cursor; - } - else - { - // from msw\data.cpp - extern wxCursor *g_globalCursor; - - if ( g_globalCursor && g_globalCursor->Ok() ) - cursor = g_globalCursor; - } - - if ( cursor ) - hcursor = (HCURSOR)cursor->GetHCURSOR(); - } + HCURSOR hcursor = 0; + bool isBusy = wxIsBusy(); + if ( m_cursor.Ok() ) + { + hcursor = GetHcursorOf(m_cursor); + } - if ( hcursor ) + if ( !GetParent() ) + { + if ( isBusy ) + { + hcursor = wxGetCurrentBusyCursor(); + } + else if ( !hcursor ) + { + const wxCursor *cursor = wxGetGlobalCursor(); + if ( cursor && cursor->Ok() ) { - ::SetCursor(hcursor); - - return TRUE; + hcursor = GetHcursorOf(*cursor); } } } - return FALSE; + if ( hcursor ) + { + ::SetCursor(hcursor); + + // cursor set, stop here + return TRUE; + } + else + { + // pass up the window chain + return FALSE; + } } // --------------------------------------------------------------------------- @@ -2659,10 +2743,9 @@ bool wxWindow::MSWOnDrawItem(int id, WXDRAWITEMSTRUCT *itemStruct) { return ((wxControl *)item)->MSWOnDraw(itemStruct); } - else -#endif - return FALSE; +#endif // USE_OWNER_DRAWN + return FALSE; } bool wxWindow::MSWOnMeasureItem(int id, WXMEASUREITEMSTRUCT *itemStruct) @@ -2931,14 +3014,41 @@ bool wxWindow::HandleCommand(WXWORD id, WXWORD cmd, WXHWND control) return popupMenu->MSWCommand(cmd, id); } - wxWindow *win = FindItem(id); - if ( !win ) + wxWindow *win = (wxWindow*) NULL; + if ( cmd == 0 || cmd == 1 ) // menu or accel - use id { + // must cast to a signed type before comparing with other ids! + win = FindItem((signed short)id); + } + + if (!win && control) + { + // find it from HWND - this works even with the broken programs using + // the same ids for different controls win = wxFindWinFromHandle(control); } if ( win ) + { return win->MSWCommand(cmd, id); + } + + // the messages sent from the in-place edit control used by the treectrl + // for label editing have id == 0, but they should _not_ be treated as menu + // messages (they are EN_XXX ones, in fact) so don't translate anything + // coming from a control to wxEVT_COMMAND_MENU_SELECTED + if ( !control ) + { + // If no child window, it may be an accelerator, e.g. for a popup menu + // command + + wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED); + event.SetEventObject(this); + event.SetId(id); + event.SetInt(id); + + return GetEventHandler()->ProcessEvent(event); + } return FALSE; } @@ -3043,12 +3153,43 @@ bool wxWindow::HandleMouseMove(int x, int y, WXUINT flags) // keyboard handling // --------------------------------------------------------------------------- +// create the key event of the given type for the given key - used by +// HandleChar and HandleKeyDown/Up +wxKeyEvent wxWindow::CreateKeyEvent(wxEventType evType, + int id, + WXLPARAM lParam) const +{ + wxKeyEvent event(evType); + event.SetId(GetId()); + event.m_shiftDown = wxIsShiftDown(); + event.m_controlDown = wxIsCtrlDown(); + event.m_altDown = (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN; + + event.m_eventObject = (wxWindow *)this; // const_cast + event.m_keyCode = id; + event.SetTimestamp(s_currentMsg.time); + + // translate the position to client coords + POINT pt; + GetCursorPos(&pt); + RECT rect; + GetWindowRect(GetHwnd(),&rect); + pt.x -= rect.left; + pt.y -= rect.top; + + event.m_x = pt.x; + event.m_y = pt.y; + + return event; +} + // isASCII is TRUE only when we're called from WM_CHAR handler and not from // WM_KEYDOWN one bool wxWindow::HandleChar(WXWORD wParam, WXLPARAM lParam, bool isASCII) { + bool ctrlDown = FALSE; + int id; - bool tempControlDown = FALSE; if ( isASCII ) { // If 1 -> 26, translate to CTRL plus a letter. @@ -3057,142 +3198,86 @@ bool wxWindow::HandleChar(WXWORD wParam, WXLPARAM lParam, bool isASCII) { switch (id) { - case 13: - { + case 13: id = WXK_RETURN; break; - } - case 8: - { + + case 8: id = WXK_BACK; break; - } - case 9: - { + + case 9: id = WXK_TAB; break; - } - default: - { - tempControlDown = TRUE; + + default: + ctrlDown = TRUE; id = id + 96; - } } } } - else if ( (id = wxCharCodeMSWToWX(wParam)) == 0 ) { + else if ( (id = wxCharCodeMSWToWX(wParam)) == 0 ) + { // it's ASCII and will be processed here only when called from - // WM_CHAR (i.e. when isASCII = TRUE) + // WM_CHAR (i.e. when isASCII = TRUE), don't process it now id = -1; } if ( id != -1 ) { - wxKeyEvent event(wxEVT_CHAR); - event.m_shiftDown = (::GetKeyState(VK_SHIFT)&0x100?TRUE:FALSE); - event.m_controlDown = (::GetKeyState(VK_CONTROL)&0x100?TRUE:FALSE); - if ( (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN ) - event.m_altDown = TRUE; - - event.m_eventObject = this; - event.m_keyCode = id; - event.SetTimestamp(s_currentMsg.time); - - POINT pt; - GetCursorPos(&pt); - RECT rect; - GetWindowRect(GetHwnd(),&rect); - pt.x -= rect.left; - pt.y -= rect.top; - - event.m_x = pt.x; event.m_y = pt.y; + wxKeyEvent event(CreateKeyEvent(wxEVT_CHAR, id, lParam)); + if ( ctrlDown ) + { + event.m_controlDown = TRUE; + } if ( GetEventHandler()->ProcessEvent(event) ) return TRUE; - else - return FALSE; } - else - return FALSE; + + return FALSE; } bool wxWindow::HandleKeyDown(WXWORD wParam, WXLPARAM lParam) { - int id; + int id = wxCharCodeMSWToWX(wParam); - if ( (id = wxCharCodeMSWToWX(wParam)) == 0 ) { + if ( !id ) + { + // normal ASCII char id = wParam; } - if ( id != -1 ) + if ( id != -1 ) // VZ: does this ever happen (FIXME)? { - wxKeyEvent event(wxEVT_KEY_DOWN); - event.m_shiftDown = (::GetKeyState(VK_SHIFT)&0x100?TRUE:FALSE); - event.m_controlDown = (::GetKeyState(VK_CONTROL)&0x100?TRUE:FALSE); - if ( (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN ) - event.m_altDown = TRUE; - - event.m_eventObject = this; - event.m_keyCode = id; - event.SetTimestamp(s_currentMsg.time); - - POINT pt; - GetCursorPos(&pt); - RECT rect; - GetWindowRect(GetHwnd(),&rect); - pt.x -= rect.left; - pt.y -= rect.top; - - event.m_x = pt.x; event.m_y = pt.y; - + wxKeyEvent event(CreateKeyEvent(wxEVT_KEY_DOWN, id, lParam)); if ( GetEventHandler()->ProcessEvent(event) ) { return TRUE; } - else return FALSE; - } - else - { - return FALSE; } + + return FALSE; } bool wxWindow::HandleKeyUp(WXWORD wParam, WXLPARAM lParam) { - int id; + int id = wxCharCodeMSWToWX(wParam); - if ( (id = wxCharCodeMSWToWX(wParam)) == 0 ) { + if ( !id ) + { + // normal ASCII char id = wParam; } - if ( id != -1 ) + if ( id != -1 ) // VZ: does this ever happen (FIXME)? { - wxKeyEvent event(wxEVT_KEY_UP); - event.m_shiftDown = (::GetKeyState(VK_SHIFT)&0x100?TRUE:FALSE); - event.m_controlDown = (::GetKeyState(VK_CONTROL)&0x100?TRUE:FALSE); - if ( (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN ) - event.m_altDown = TRUE; - - event.m_eventObject = this; - event.m_keyCode = id; - event.SetTimestamp(s_currentMsg.time); - - POINT pt; - GetCursorPos(&pt); - RECT rect; - GetWindowRect(GetHwnd(),&rect); - pt.x -= rect.left; - pt.y -= rect.top; - - event.m_x = pt.x; event.m_y = pt.y; - + wxKeyEvent event(CreateKeyEvent(wxEVT_KEY_UP, id, lParam)); if ( GetEventHandler()->ProcessEvent(event) ) return TRUE; - else - return FALSE; } - else - return FALSE; + + return FALSE; } // --------------------------------------------------------------------------- @@ -3267,7 +3352,7 @@ bool wxWindow::HandleJoystickEvent(WXUINT msg, int x, int y, WXUINT flags) break; default: - wxFAIL_MSG(T("no such joystick event")); + wxFAIL_MSG(wxT("no such joystick event")); return FALSE; } @@ -3324,8 +3409,11 @@ bool wxWindow::MSWOnScroll(int orientation, WXWORD wParam, event.m_eventType = wxEVT_SCROLLWIN_PAGEDOWN; break; - case SB_THUMBTRACK: case SB_THUMBPOSITION: + event.m_eventType = wxEVT_SCROLLWIN_THUMBRELEASE; + break; + + case SB_THUMBTRACK: event.m_eventType = wxEVT_SCROLLWIN_THUMBTRACK; break; @@ -3340,7 +3428,7 @@ bool wxWindow::MSWOnScroll(int orientation, WXWORD wParam, // global functions // =========================================================================== -void wxGetCharSize(WXHWND wnd, int *x, int *y,wxFont *the_font) +void wxGetCharSize(WXHWND wnd, int *x, int *y, const wxFont *the_font) { TEXTMETRIC tm; HDC dc = ::GetDC((HWND) wnd); @@ -3350,7 +3438,7 @@ void wxGetCharSize(WXHWND wnd, int *x, int *y,wxFont *the_font) { // the_font->UseResource(); // the_font->RealizeResource(); - fnt = (HFONT)the_font->GetResourceHandle(); + fnt = (HFONT)((wxFont *)the_font)->GetResourceHandle(); // const_cast if ( fnt ) was = (HFONT) SelectObject(dc,fnt); } @@ -3538,6 +3626,48 @@ wxWindow *wxGetActiveWindow() return NULL; } +extern wxWindow *wxGetWindowFromHWND(WXHWND hWnd) +{ + HWND hwnd = (HWND)hWnd; + + // For a radiobutton, we get the radiobox from GWL_USERDATA (which is set + // by code in msw/radiobox.cpp), for all the others we just search up the + // window hierarchy + wxWindow *win = (wxWindow *)NULL; + if ( hwnd ) + { + win = wxFindWinFromHandle((WXHWND)hwnd); + if ( !win ) + { + // the radiobox pointer is stored in GWL_USERDATA only under Win32 +#ifdef __WIN32__ + // native radiobuttons return DLGC_RADIOBUTTON here and for any + // wxWindow class which overrides WM_GETDLGCODE processing to + // do it as well, win would be already non NULL + if ( ::SendMessage((HWND)hwnd, WM_GETDLGCODE, + 0, 0) & DLGC_RADIOBUTTON ) + { + win = (wxWindow *)::GetWindowLong(hwnd, GWL_USERDATA); + } + else +#endif // Win32 + { + // hwnd is not a wxWindow, try its parent next below + hwnd = ::GetParent(hwnd); + } + } + //else: it's a wxRadioButton, not a radiobutton from wxRadioBox + } + + while ( hwnd && !win ) + { + win = wxFindWinFromHandle((WXHWND)hwnd); + hwnd = ::GetParent(hwnd); + } + + return win; +} + // Windows keyboard hook. Allows interception of e.g. F1, ESCAPE // in active frames and dialogs, regardless of where the focus is. static HHOOK wxTheKeyboardHook = 0; @@ -3553,16 +3683,21 @@ void wxSetKeyboardHook(bool doIt) wxTheKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC) wxTheKeyboardHookProc, wxGetInstance(), #if defined(__WIN32__) && !defined(__TWIN32__) - GetCurrentThreadId()); + GetCurrentThreadId() // (DWORD)GetCurrentProcess()); // This is another possibility. Which is right? #else - GetCurrentTask()); + GetCurrentTask() #endif + ); } else { UnhookWindowsHookEx(wxTheKeyboardHook); + // avoids mingw warning about statement with no effect (FreeProcInstance + // doesn't do anything under Win32) +#ifndef __GNUC__ FreeProcInstance(wxTheKeyboardHookProc); +#endif } } @@ -3572,8 +3707,8 @@ wxKeyboardHook(int nCode, WORD wParam, DWORD lParam) DWORD hiWord = HIWORD(lParam); if ( nCode != HC_NOREMOVE && ((hiWord & KF_UP) == 0) ) { - int id; - if ( (id = wxCharCodeMSWToWX(wParam)) != 0 ) + int id = wxCharCodeMSWToWX(wParam); + if ( id != 0 ) { wxKeyEvent event(wxEVT_CHAR_HOOK); if ( (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN ) @@ -3581,25 +3716,31 @@ wxKeyboardHook(int nCode, WORD wParam, DWORD lParam) event.m_eventObject = NULL; event.m_keyCode = id; - /* begin Albert's fix for control and shift key 26.5 */ - event.m_shiftDown = (::GetKeyState(VK_SHIFT)&0x100?TRUE:FALSE); - event.m_controlDown = (::GetKeyState(VK_CONTROL)&0x100?TRUE:FALSE); - /* end Albert's fix for control and shift key 26.5 */ + event.m_shiftDown = wxIsShiftDown(); + event.m_controlDown = wxIsCtrlDown(); event.SetTimestamp(s_currentMsg.time); wxWindow *win = wxGetActiveWindow(); + wxEvtHandler *handler; if ( win ) { - if ( win->GetEventHandler()->ProcessEvent(event) ) - return 1; + handler = win->GetEventHandler(); + event.SetId(win->GetId()); } else { - if ( wxTheApp && wxTheApp->ProcessEvent(event) ) - return 1; + handler = wxTheApp; + event.SetId(-1); + } + + if ( handler && handler->ProcessEvent(event) ) + { + // processed + return 1; } } } + return (int)CallNextHookEx(wxTheKeyboardHook, nCode, wParam, lParam); } @@ -3618,13 +3759,13 @@ const char *wxGetMessageName(int message) 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 0x000C: return "WM_SETTEXT"; + case 0x000D: return "WM_GETTEXT"; case 0x000E: return "WM_GETTEXTLENGTH"; - case 0x000F: return "WM_PAINT("; + case 0x000F: return "WM_PAINT"; case 0x0010: return "WM_CLOSE"; case 0x0011: return "WM_QUERYENDSESSION"; - case 0x0012: return "WM_QUIT("; + case 0x0012: return "WM_QUIT"; case 0x0013: return "WM_QUERYOPEN"; case 0x0014: return "WM_ERASEBKGND"; case 0x0015: return "WM_SYSCOLORCHANGE"; @@ -3652,8 +3793,8 @@ const char *wxGetMessageName(int message) 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 0x0030: return "WM_SETFONT"; + case 0x0031: return "WM_GETFONT"; case 0x0037: return "WM_QUERYDRAGICON"; case 0x0039: return "WM_COMPAREITEM"; case 0x0041: return "WM_COMPACTING"; @@ -3666,12 +3807,12 @@ const char *wxGetMessageName(int message) case 0x004A: return "WM_COPYDATA"; case 0x004B: return "WM_CANCELJOURNAL"; case 0x004E: return "WM_NOTIFY"; - case 0x0050: return "WM_INPUTLANGCHANGEREQUEST("; + 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 0x0055: return "WM_NOTIFYFORMAT"; case 0x007B: return "WM_CONTEXTMENU"; case 0x007C: return "WM_STYLECHANGING"; case 0x007D: return "WM_STYLECHANGED"; @@ -3683,8 +3824,8 @@ const char *wxGetMessageName(int message) 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 0x0084: return "WM_NCHITTEST"; + case 0x0085: return "WM_NCPAINT"; case 0x0086: return "WM_NCACTIVATE"; case 0x0087: return "WM_GETDLGCODE"; case 0x00A0: return "WM_NCMOUSEMOVE"; @@ -3705,7 +3846,7 @@ const char *wxGetMessageName(int message) case 0x0105: return "WM_SYSKEYUP"; case 0x0106: return "WM_SYSCHAR"; case 0x0107: return "WM_SYSDEADCHAR"; - case 0x0108: return "WM_KEYLAST("; + case 0x0108: return "WM_KEYLAST"; #ifdef __WIN32__ case 0x010D: return "WM_IME_STARTCOMPOSITION"; @@ -3721,7 +3862,7 @@ const char *wxGetMessageName(int message) case 0x0115: return "WM_VSCROLL"; case 0x0116: return "WM_INITMENU"; case 0x0117: return "WM_INITMENUPOPUP"; - case 0x011F: return "WM_MENUSELECT("; + case 0x011F: return "WM_MENUSELECT"; case 0x0120: return "WM_MENUCHAR"; case 0x0121: return "WM_ENTERIDLE"; case 0x0200: return "WM_MOUSEMOVE"; @@ -3743,7 +3884,7 @@ const char *wxGetMessageName(int message) case 0x0214: return "WM_SIZING"; case 0x0215: return "WM_CAPTURECHANGED"; case 0x0216: return "WM_MOVING"; - case 0x0218: return "WM_POWERBROADCAST("; + case 0x0218: return "WM_POWERBROADCAST"; case 0x0219: return "WM_DEVICECHANGE"; #endif //WIN32 @@ -3751,7 +3892,7 @@ const char *wxGetMessageName(int message) case 0x0221: return "WM_MDIDESTROY"; case 0x0222: return "WM_MDIACTIVATE"; case 0x0223: return "WM_MDIRESTORE"; - case 0x0224: return "WM_MDINEXT("; + case 0x0224: return "WM_MDINEXT"; case 0x0225: return "WM_MDIMAXIMIZE"; case 0x0226: return "WM_MDITILE"; case 0x0227: return "WM_MDICASCADE"; @@ -3761,22 +3902,22 @@ const char *wxGetMessageName(int message) case 0x0233: return "WM_DROPFILES"; #ifdef __WIN32__ - case 0x0281: return "WM_IME_SETCONTEXT("; + 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 0x0285: return "WM_IME_SELECT"; case 0x0286: return "WM_IME_CHAR"; case 0x0290: return "WM_IME_KEYDOWN"; case 0x0291: return "WM_IME_KEYUP"; #endif //WIN32 - case 0x0300: return "WM_CUT("; + 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 0x0305: return "WM_RENDERFORMAT"; case 0x0306: return "WM_RENDERALLFORMATS"; case 0x0307: return "WM_DESTROYCLIPBOARD"; case 0x0308: return "WM_DRAWCLIPBOARD"; @@ -3797,9 +3938,9 @@ const char *wxGetMessageName(int message) // 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 + 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"; @@ -3813,12 +3954,12 @@ const char *wxGetMessageName(int message) 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 + 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 + 18: return "LVM_HITTEST"; case 0x1000 + 19: return "LVM_ENSUREVISIBLE"; case 0x1000 + 20: return "LVM_SCROLL"; case 0x1000 + 21: return "LVM_REDRAWITEMS"; @@ -3837,7 +3978,7 @@ const char *wxGetMessageName(int message) 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 + 34: return "LVM_GETVIEWRECT"; case 0x1000 + 35: return "LVM_GETTEXTCOLOR"; case 0x1000 + 36: return "LVM_SETTEXTCOLOR"; case 0x1000 + 37: return "LVM_GETTEXTBKCOLOR"; @@ -3852,25 +3993,25 @@ const char *wxGetMessageName(int message) 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 + 47: return "LVM_SETITEMCOUNT"; case 0x1000 + 48: return "LVM_SORTITEMS"; case 0x1000 + 49: return "LVM_SETITEMPOSITION32"; - case 0x1000 + 50: return "LVM_GETSELECTEDCOUNT("; + 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 + 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 + 64: return "LVM_APPROXIMATEVIEWRECT"; case 0x1000 + 65: return "LVM_SETWORKAREA"; // tree view @@ -3878,12 +4019,12 @@ const char *wxGetMessageName(int message) 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 + 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"; @@ -3893,8 +4034,8 @@ const char *wxGetMessageName(int message) 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 + 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"; @@ -3906,7 +4047,7 @@ const char *wxGetMessageName(int message) case 0x1100 + 25: return "TVM_GETTOOLTIPS"; // header - case 0x1200 + 0: return "HDM_GETITEMCOUNT("; + case 0x1200 + 0: return "HDM_GETITEMCOUNT"; case 0x1200 + 1: return "HDM_INSERTITEMA"; case 0x1200 + 10: return "HDM_INSERTITEMW"; case 0x1200 + 2: return "HDM_DELETEITEM"; @@ -3914,11 +4055,11 @@ const char *wxGetMessageName(int message) 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 + 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"; @@ -3926,9 +4067,9 @@ const char *wxGetMessageName(int message) case 0x1200 + 19: return "HDM_SETHOTDIVIDER"; // tab control - case 0x1300 + 2: return "TCM_GETIMAGELIST("; - case 0x1300 + 3: return "TCM_SETIMAGELIST("; - case 0x1300 + 4: return "TCM_GETITEMCOUNT("; + 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"; @@ -3937,16 +4078,16 @@ const char *wxGetMessageName(int message) 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 + 10: return "TCM_GETITEMRECT"; case 0x1300 + 11: return "TCM_GETCURSEL"; case 0x1300 + 12: return "TCM_SETCURSEL"; - case 0x1300 + 13: return "TCM_HITTEST("; + case 0x1300 + 13: return "TCM_HITTEST"; case 0x1300 + 14: return "TCM_SETITEMEXTRA"; - case 0x1300 + 40: return "TCM_ADJUSTRECT("; + 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 + 44: return "TCM_GETROWCOUNT"; case 0x1300 + 45: return "TCM_GETTOOLTIPS"; case 0x1300 + 46: return "TCM_SETTOOLTIPS"; case 0x1300 + 47: return "TCM_GETCURFOCUS"; @@ -3972,21 +4113,21 @@ const char *wxGetMessageName(int message) 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+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+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+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"; @@ -3995,15 +4136,15 @@ const char *wxGetMessageName(int message) 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+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+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"; @@ -4021,3 +4162,22 @@ const char *wxGetMessageName(int message) } } #endif //__WXDEBUG__ + +static void TranslateKbdEventToMouse(wxWindow *win, int *x, int *y, WPARAM *flags) +{ + // construct the key mask + WPARAM& fwKeys = *flags; + + fwKeys = MK_RBUTTON; + if ( wxIsCtrlDown() ) + fwKeys |= MK_CONTROL; + if ( wxIsShiftDown() ) + fwKeys |= MK_SHIFT; + + // simulate right mouse button click + DWORD dwPos = ::GetMessagePos(); + *x = GET_X_LPARAM(dwPos); + *y = GET_Y_LPARAM(dwPos); + + win->ScreenToClient(x, y); +}