X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/1f916a19f14ce4f8d172f81344dd2b978dd29340..00421206821da3373ddc075d63149826b3be38af:/src/msw/window.cpp diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 569dec2dd6..7149e45154 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -49,10 +49,18 @@ #include "wx/menuitem.h" #include "wx/log.h" + +#if wxUSE_TOOLTIPS #include "wx/tooltip.h" +#endif + +#include "wx/intl.h" +#include "wx/log.h" #include "wx/msw/private.h" +#include "wx/textctrl.h" + #include #ifndef __GNUWIN32__ @@ -225,13 +233,15 @@ void wxWindow::SetHWND(WXHWND hWnd) void wxWindow::Init() { + m_isWindow = TRUE; + // Generic +// m_windowCursor = * wxSTANDARD_CURSOR; m_windowId = 0; m_isShown = TRUE; m_windowStyle = 0; m_windowParent = NULL; m_windowEventHandler = this; - m_windowCursor = *wxSTANDARD_CURSOR; m_children = new wxList; m_doubleClickAllowed = 0 ; m_winCaptured = FALSE; @@ -302,14 +312,6 @@ wxWindow::wxWindow() // Destructor wxWindow::~wxWindow() { - // Remove potential dangling pointer - if (GetParent() && GetParent()->IsKindOf(CLASSINFO(wxPanel))) - { - wxPanel* panel = (wxPanel*) GetParent(); - if (panel->GetLastFocus() == this) - panel->SetLastFocus((wxWindow*) NULL); - } - m_isBeingDeleted = TRUE; // first of all, delete the things on which nothing else depends @@ -672,12 +674,12 @@ void wxWindow::GetClientSize(int *x, int *y) const { HWND hWnd = (HWND) GetHWND(); RECT rect; - GetClientRect(hWnd, &rect); + ::GetClientRect(hWnd, &rect); *x = rect.right; *y = rect.bottom; } -void wxWindow::SetSize(int x, int y, int width, int height, int sizeFlags) +void wxWindow::DoSetSize(int x, int y, int width, int height, int sizeFlags) { int currentX, currentY; GetPosition(¤tX, ¤tY); @@ -708,14 +710,16 @@ void wxWindow::SetSize(int x, int y, int width, int height, int sizeFlags) MoveWindow(hWnd, actualX, actualY, actualWidth, actualHeight, (BOOL)TRUE); } -void wxWindow::SetClientSize(int width, int height) +void wxWindow::DoSetClientSize(int width, int height) { wxWindow *parent = GetParent(); HWND hWnd = (HWND) GetHWND(); - HWND hParentWnd = (HWND) (HWND) parent->GetHWND(); + HWND hParentWnd = (HWND) 0; + if (parent) + hParentWnd = (HWND) parent->GetHWND(); RECT rect; - GetClientRect(hWnd, &rect); + ::GetClientRect(hWnd, &rect); RECT rect2; GetWindowRect(hWnd, &rect2); @@ -764,13 +768,14 @@ void wxWindow::AdjustForParentClientOrigin(int& x, int& y, int sizeFlags) bool wxWindow::Show(bool show) { + m_isShown = show; HWND hWnd = (HWND) GetHWND(); int cshow; if (show) cshow = SW_SHOW; else cshow = SW_HIDE; - ShowWindow(hWnd, (BOOL)cshow); + ShowWindow(hWnd, cshow); if (show) { BringWindowToTop(hWnd); @@ -782,7 +787,11 @@ bool wxWindow::Show(bool show) bool wxWindow::IsShown(void) const { - return (::IsWindowVisible((HWND) GetHWND()) != 0); + // Can't rely on IsWindowVisible, since it will return FALSE + // if the parent is not visible. + return m_isShown; +// int ret = ::IsWindowVisible((HWND) GetHWND()) ; +// return (ret != 0); } int wxWindow::GetCharHeight(void) const @@ -932,7 +941,7 @@ LRESULT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA #define DIMENSION_TYPE int #endif -// Main Windows 3 window proc +// Main Windows window proc long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) { wxASSERT( m_lastMsg == message && @@ -1170,6 +1179,7 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) return MSWOnSysCommand(wParam, lParam); break; } + case WM_COMMAND: { #ifdef __WIN32__ @@ -1221,48 +1231,81 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) return MSWOnMeasureItem((int)wParam, (WXMEASUREITEMSTRUCT *)lParam); break; } - case WM_KEYDOWN: - MSWOnKeyDown((WORD) wParam, lParam); - // we consider these message "not interesting" + // If this has been processed by an event handler, + // return 0 now (we've handled it). + if ( MSWOnKeyDown((WORD) wParam, lParam) ) + break; + + // we consider these message "not interesting" to OnChar if ( wParam == VK_SHIFT || wParam == VK_CONTROL ) + { return Default(); + } - // Avoid duplicate messages to OnChar for these special keys switch ( wParam ) { + // avoid duplicate messages to OnChar for these ASCII keys: they + // will be translated by TranslateMessage() and received in WM_CHAR case VK_ESCAPE: case VK_SPACE: case VK_RETURN: case VK_BACK: case VK_TAB: + return Default(); + +#ifdef VK_APPS + + // normally these macros would be defined in windows.h +#ifndef GET_X_LPARAM + #define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp)) + #define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp)) +#endif + + // special case of VK_APPS: treat it the same as right mouse 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); + MSWOnRButtonDown(x, y, fwKeys); + } + break; +#endif // VK_APPS + case VK_LEFT: case VK_RIGHT: case VK_DOWN: case VK_UP: - if ( ::GetKeyState(VK_CONTROL) & 0x100 ) - MSWOnChar((WORD)wParam, lParam); - break; - default: - MSWOnChar((WORD)wParam, lParam); - if ( ::GetKeyState(VK_CONTROL) & 0x100 ) + if ( !MSWOnChar((WORD)wParam, lParam) ) + { return Default(); + } break; } - break; case WM_KEYUP: - { - MSWOnKeyUp((WORD) wParam, lParam); + if ( !MSWOnKeyUp((WORD) wParam, lParam) ) + return Default(); break; - } + case WM_CHAR: // Always an ASCII character - { - MSWOnChar((WORD)wParam, lParam, TRUE); - break; - } + if ( !MSWOnChar((WORD)wParam, lParam, TRUE) ) + return Default(); + break; case WM_HSCROLL: { @@ -1441,7 +1484,6 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) return 1L; break; } - case WM_GETMINMAXINFO: { MINMAXINFO *info = (MINMAXINFO *)lParam; @@ -1456,9 +1498,64 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) return MSWDefWindowProc(message, wParam, lParam ); break; } - case WM_GETDLGCODE: - return MSWGetDlgCode(); + { + return MSWGetDlgCode(); + } + case WM_SETCURSOR: + { + // don't set cursor for other windows, only for this one: this + // prevents children of this window from gettign the same cursor + // as the parent has (don't forget that this message is propagated + // by default up the window parent-child hierarchy) + if ( (HWND)wParam == hWnd ) + { + // don't set cursor when the mouse is not in the client part + short nHitTest = LOWORD(lParam); + if ( nHitTest == HTCLIENT || nHitTest == HTERROR ) + { + HCURSOR hcursor = 0; + if ( wxIsBusy() ) + { + // from msw\utils.cpp + extern HCURSOR gs_wxBusyCursor; + + hcursor = gs_wxBusyCursor; + } + else + { + wxCursor *cursor = NULL; + + if ( m_windowCursor.Ok() ) + { + cursor = &m_windowCursor; + } + else + { + // from msw\data.cpp + extern wxCursor *g_globalCursor; + + if ( g_globalCursor && g_globalCursor->Ok() ) + cursor = g_globalCursor; + } + + if ( cursor ) + hcursor = (HCURSOR)cursor->GetHCURSOR(); + } + + if ( hcursor ) + { + ::SetCursor(hcursor); + + // returning TRUE stops the DefWindowProc() from + // further processing this message - exactly what we + // need because we've just set the cursor. + return TRUE; + } + } + } + } + return MSWDefWindowProc(message, wParam, lParam ); default: return MSWDefWindowProc(message, wParam, lParam ); @@ -1700,7 +1797,7 @@ long wxWindow::MSWOnNotify(WXWPARAM wParam, WXLPARAM lParam) #endif // Win95 // not processed - return FALSE; + return Default(); } void wxWindow::MSWOnMenuHighlight(WXWORD WXUNUSED(item), WXWORD WXUNUSED(flags), WXHMENU WXUNUSED(sysmenu)) @@ -1734,7 +1831,7 @@ bool wxWindow::MSWOnSetFocus(WXHWND WXUNUSED(hwnd)) wxWindow *parent = GetParent(); if ( parent && parent->IsKindOf(CLASSINFO(wxPanel)) ) { - ((wxPanel *)parent)->SetLastFocus(this); + ((wxPanel *)parent)->SetLastFocus(GetId()); } wxFocusEvent event(wxEVT_SET_FOCUS, m_windowId); @@ -1941,21 +2038,23 @@ long wxWindow::MSWDefWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) long wxWindow::Default() { - // Ignore 'fake' events (perhaps generated as a result of a separate real event) - if (m_lastMsg == 0) + // Ignore 'fake' events (perhaps generated as a result of a separate real + // event) + if ( m_lastMsg == 0 ) return 0; #ifdef __WXDEBUG__ wxLogTrace(wxTraceMessages, "Forwarding %s to DefWindowProc.", - wxGetMessageName(m_lastMsg)); + wxGetMessageName(m_lastMsg)); #endif // __WXDEBUG__ - return this->MSWDefWindowProc(m_lastMsg, m_lastWParam, m_lastLParam); + return MSWDefWindowProc(m_lastMsg, m_lastWParam, m_lastLParam); } bool wxWindow::MSWProcessMessage(WXMSG* pMsg) { - if ( m_hWnd != 0 && (GetWindowStyleFlag() & wxTAB_TRAVERSAL) ) { + if ( m_hWnd != 0 && (GetWindowStyleFlag() & wxTAB_TRAVERSAL) ) + { // intercept dialog navigation keys MSG *msg = (MSG *)pMsg; bool bProcess = TRUE; @@ -2017,7 +2116,7 @@ bool wxWindow::MSWProcessMessage(WXMSG* pMsg) // it return FALSE; } - +#ifndef __WIN16__ wxButton *btnDefault = GetDefaultItem(); if ( btnDefault && !bCtrlDown ) { @@ -2030,6 +2129,7 @@ bool wxWindow::MSWProcessMessage(WXMSG* pMsg) // else: but if there is not it makes sense to make it // work like a TAB - and that's what we do. // Note that Ctrl-Enter always works this way. +#endif } break; @@ -2052,6 +2152,7 @@ bool wxWindow::MSWProcessMessage(WXMSG* pMsg) if ( ::IsDialogMessage((HWND)GetHWND(), msg) ) return TRUE; } + #if wxUSE_TOOLTIPS if ( m_tooltip ) { @@ -2062,6 +2163,19 @@ bool wxWindow::MSWProcessMessage(WXMSG* pMsg) } #endif // wxUSE_TOOLTIPS +/* This code manages to disable character input completely. Nice one! + * Probably because the dialog is requesting all char input. Or, + * it gets called by non-dialog windows. + + // In case we don't have wxTAB_TRAVERSAL style on. + // If we don't call this, we may never process Enter correctly. + if ( m_hWnd != 0 && (GetWindowStyleFlag() & wxTAB_TRAVERSAL) == 0 ) + { + MSG *msg = (MSG *)pMsg; + if ( ::IsDialogMessage((HWND)GetHWND(), msg) ) + return TRUE; + } +*/ return FALSE; } @@ -2171,7 +2285,7 @@ bool wxWindow::MSWOnCommand(WXWORD id, WXWORD cmd, WXHWND control) long wxWindow::MSWOnSysCommand(WXWPARAM wParam, WXLPARAM lParam) { - switch (wParam) + switch (wParam & 0xFFFFFFF0) { case SC_MAXIMIZE: { @@ -2373,11 +2487,6 @@ void wxWindow::MSWOnRButtonDClick(int x, int y, WXUINT flags) void wxWindow::MSWOnMouseMove(int x, int y, WXUINT flags) { // 'normal' move event... - // Set cursor, but only if we're not in 'busy' mode - - // Trouble with this is that it sets the cursor for controls too :-( - if (m_windowCursor.Ok() && !wxIsBusy()) - ::SetCursor((HCURSOR) m_windowCursor.GetHCURSOR()); if (!m_mouseInWindow) { @@ -2456,7 +2565,9 @@ void wxWindow::MSWOnMouseLeave(int x, int y, WXUINT flags) GetEventHandler()->ProcessEvent(event); } -void wxWindow::MSWOnChar(WXWORD wParam, WXLPARAM lParam, bool isASCII) +// isASCII is TRUE only when we're called from WM_CHAR handler and not from +// WM_KEYDOWN one +bool wxWindow::MSWOnChar(WXWORD wParam, WXLPARAM lParam, bool isASCII) { int id; bool tempControlDown = FALSE; @@ -2518,12 +2629,16 @@ void wxWindow::MSWOnChar(WXWORD wParam, WXLPARAM lParam, bool isASCII) event.m_x = pt.x; event.m_y = pt.y; - if (!GetEventHandler()->ProcessEvent(event)) - Default(); + if (GetEventHandler()->ProcessEvent(event)) + return TRUE; + else + return FALSE; } + else + return FALSE; } -void wxWindow::MSWOnKeyDown(WXWORD wParam, WXLPARAM lParam, bool isASCII) +bool wxWindow::MSWOnKeyDown(WXWORD wParam, WXLPARAM lParam) { int id; @@ -2552,12 +2667,19 @@ void wxWindow::MSWOnKeyDown(WXWORD wParam, WXLPARAM lParam, bool isASCII) event.m_x = pt.x; event.m_y = pt.y; - if (!GetEventHandler()->ProcessEvent(event)) - Default(); + if (GetEventHandler()->ProcessEvent(event)) + { + return TRUE; + } + else return FALSE; + } + else + { + return FALSE; } } -void wxWindow::MSWOnKeyUp(WXWORD wParam, WXLPARAM lParam, bool isASCII) +bool wxWindow::MSWOnKeyUp(WXWORD wParam, WXLPARAM lParam) { int id; @@ -2586,9 +2708,13 @@ void wxWindow::MSWOnKeyUp(WXWORD wParam, WXLPARAM lParam, bool isASCII) event.m_x = pt.x; event.m_y = pt.y; - if (!GetEventHandler()->ProcessEvent(event)) - Default(); + if (GetEventHandler()->ProcessEvent(event)) + return TRUE; + else + return FALSE; } + else + return FALSE; } void wxWindow::MSWOnJoyDown(int joystick, int x, int y, WXUINT flags) @@ -3660,14 +3786,22 @@ WXDWORD wxWindow::Determine3DEffects(WXDWORD defaultBorderStyle, bool *want3D) void wxWindow::OnChar(wxKeyEvent& event) { - bool isVirtual; - int id = wxCharCodeWXToMSW((int)event.KeyCode(), &isVirtual); + event.Skip(); +} - if ( id == -1 ) - id= m_lastWParam; +void wxWindow::OnKeyDown(wxKeyEvent& event) +{ + Default(); +} - if ( !event.ControlDown() ) - (void) MSWDefWindowProc(m_lastMsg, (WPARAM) id, m_lastLParam); +void wxWindow::OnKeyUp(wxKeyEvent& event) +{ + Default(); +} + +void wxWindow::OnPaint(wxPaintEvent& event) +{ + Default(); } bool wxWindow::IsEnabled(void) const