X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/79099b80ad442cb93b2f7df716bf3d1dd80b446f..c263eb03846c1b1439bf67d1d831255024278adf:/src/msw/window.cpp diff --git a/src/msw/window.cpp b/src/msw/window.cpp index fec6a59d91..bcba0c04c8 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -155,11 +155,6 @@ void wxRemoveHandleAssociation(wxWindowMSW *win); extern void wxAssociateWinWithHandle(HWND hWnd, wxWindowMSW *win); wxWindow *wxFindWinFromHandle(WXHWND hWnd); -// this magical function is used to translate VK_APPS key presses to right -// mouse clicks -static void TranslateKbdEventToMouse(wxWindowMSW *win, - int *x, int *y, WPARAM *flags); - // get the text metrics for the current font static TEXTMETRIC wxGetTextMetrics(const wxWindowMSW *win); @@ -264,7 +259,7 @@ wxBEGIN_FLAGS( wxWindowStyle ) wxFLAGS_MEMBER(wxBORDER_RAISED) wxFLAGS_MEMBER(wxBORDER_STATIC) wxFLAGS_MEMBER(wxBORDER_NONE) - + // old style border flags wxFLAGS_MEMBER(wxSIMPLE_BORDER) wxFLAGS_MEMBER(wxSUNKEN_BORDER) @@ -586,7 +581,7 @@ void wxWindowMSW::SetFocusFromKbd() } // Get the window with the focus -wxWindow *wxWindowBase::FindFocus() +wxWindow *wxWindowBase::DoFindFocus() { HWND hWnd = ::GetFocus(); if ( hWnd ) @@ -1005,7 +1000,7 @@ void wxWindowMSW::UnsubclassWin() HWND hwnd = GetHwnd(); if ( hwnd ) { - m_hWnd = 0; + SetHWND(0); wxCHECK_RET( ::IsWindow(hwnd), wxT("invalid HWND in UnsubclassWin") ); @@ -1021,6 +1016,27 @@ void wxWindowMSW::UnsubclassWin() } } +void wxWindowMSW::AssociateHandle(WXWidget handle) +{ + if ( m_hWnd ) + { + if ( !::DestroyWindow(GetHwnd()) ) + wxLogLastError(wxT("DestroyWindow")); + } + + WXHWND wxhwnd = (WXHWND)handle; + + SetHWND(wxhwnd); + SubclassWin(wxhwnd); +} + +void wxWindowMSW::DissociateHandle() +{ + // this also calls SetHWND(0) for us + UnsubclassWin(); +} + + bool wxCheckWindowWndProc(WXHWND hWnd, WXFARPROC wndProc) { // Unicows note: the code below works, but only because WNDCLASS contains @@ -1383,6 +1399,8 @@ void wxWindowMSW::DragAcceptFiles(bool accept) HWND hWnd = GetHwnd(); if ( hWnd ) ::DragAcceptFiles(hWnd, (BOOL)accept); +#else + wxUnusedVar(accept); #endif } @@ -1735,7 +1753,7 @@ bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y) menu->SetInvokingWindow(this); menu->UpdateUI(); - if ( x == -1 && y == -1 ) + if ( x == wxDefaultCoord && y == wxDefaultCoord ) { wxPoint mouse = ScreenToClient(wxGetMousePosition()); x = mouse.x; y = mouse.y; @@ -2262,31 +2280,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l #endif case WM_SIZE: - switch ( wParam ) - { - case SIZE_MAXHIDE: - case SIZE_MAXSHOW: - // we're not interested in these messages at all - break; - - case SIZE_MINIMIZED: - // we shouldn't send sizev events for these messages as the - // client size may be negative which breaks existing code - // - // OTOH we might send another (wxMinimizedEvent?) one or - // add an additional parameter to wxSizeEvent if this is - // useful to anybody - break; - - default: - wxFAIL_MSG( _T("unexpected WM_SIZE parameter") ); - // fall through nevertheless - - case SIZE_MAXIMIZED: - case SIZE_RESTORED: - processed = HandleSize(LOWORD(lParam), HIWORD(lParam), - wParam); - } + processed = HandleSize(LOWORD(lParam), HIWORD(lParam), wParam); break; #if !defined(__WXWINCE__) @@ -2396,18 +2390,18 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l 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. + // 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 + // 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() ) { m_mouseInWindow = false; - // Unfortunately no mouse state is passed with a WM_MOUSE_LEAVE + // Unfortunately no mouse state is passed with a WM_MOUSE_LEAVE int state = 0; if ( wxIsShiftDown() ) state |= MK_SHIFT; @@ -2446,7 +2440,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l break; #endif // __WXWINCE__ - + #if wxUSE_MOUSEWHEEL case WM_MOUSEWHEEL: processed = HandleMouseWheel(wParam, lParam); @@ -2504,19 +2498,23 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l // this should never happen wxCHECK_MSG( win, 0, _T("FindWindowForMouseEvent() returned NULL") ); + } + processed = win->HandleMouseEvent(message, x, y, wParam); + + // if the app didn't eat the event, handle it in the default + // way, that is by giving this window the focus + if ( !processed ) + { // for the standard classes their WndProc sets the focus to // them anyhow and doing it from here results in some weird - // problems, but for our windows we want them to acquire - // focus when clicked + // problems, so don't do it for them (unnecessary anyhow) if ( !win->IsOfStandardClass() ) { if ( message == WM_LBUTTONDOWN && win->AcceptsFocus() ) win->SetFocus(); } } - - processed = win->HandleMouseEvent(message, x, y, wParam); } break; @@ -2663,13 +2661,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l // special case of VK_APPS: treat it the same as right mouse // click because both usually pop up a context menu case VK_APPS: - { - WPARAM flags; - int x, y; - - TranslateKbdEventToMouse(this, &x, &y, &flags); - processed = HandleMouseEvent(WM_RBUTTONDOWN, x, y, flags); - } + processed = HandleMouseEvent(WM_RBUTTONDOWN, -1, -1, 0); break; #endif // VK_APPS @@ -2688,11 +2680,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l // 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); + processed = HandleMouseEvent(WM_RBUTTONUP, -1, -1, 0); } else #endif // VK_APPS @@ -3047,7 +3035,7 @@ bool wxWindowMSW::MSWGetCreateWindowCoords(const wxPoint& pos, already has - so no WM_SIZE would be sent. */ - + // we don't use CW_USEDEFAULT here for several reasons: // // 1. it results in huge frames on modern screens (1000*800 is not @@ -3384,6 +3372,8 @@ 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 @@ -3438,7 +3428,7 @@ bool wxWindowMSW::HandleSetFocus(WXHWND hwnd) { return false; } - + // notify the parent keeping track of focus for the kbd navigation // purposes that we got it wxChildFocusEvent eventFocus((wxWindow *)this); @@ -3529,6 +3519,7 @@ bool wxWindowMSW::HandleInitDialog(WXHWND WXUNUSED(hWndFocus)) bool wxWindowMSW::HandleDropFiles(WXWPARAM wParam) { #if defined (__WXMICROWIN__) || defined(__WXWINCE__) + wxUnusedVar(wParam); return false; #else // __WXMICROWIN__ HDROP hFilesInfo = (HDROP) wParam; @@ -3675,7 +3666,8 @@ wxWindowMSW::MSWOnDrawItem(int WXUNUSED_UNLESS_ODRAWN(id), { wxMenuItem *pMenuItem = (wxMenuItem *)(pDrawStruct->itemData); - wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), false ); + wxCHECK_MSG( pMenuItem && pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), + false, _T("MSWOnDrawItem: bad wxMenuItem pointer") ); // prepare to call OnDrawItem(): notice using of wxDCTemp to prevent // the DC from being released @@ -3703,7 +3695,7 @@ wxWindowMSW::MSWOnDrawItem(int WXUNUSED_UNLESS_ODRAWN(id), #else // !wxUSE_OWNER_DRAWN // we may still have owner-drawn buttons internally because we have to make // them owner-drawn to support colour change - wxControl *item = + wxControl *item = # if wxUSE_BUTTON wxDynamicCast(FindItem(id), wxButton) # else @@ -3723,9 +3715,7 @@ wxWindowMSW::MSWOnDrawItem(int WXUNUSED_UNLESS_ODRAWN(id), } bool -wxWindowMSW::MSWOnMeasureItem(int WXUNUSED_UNLESS_ODRAWN(id), - WXMEASUREITEMSTRUCT * - WXUNUSED_UNLESS_ODRAWN(itemStruct)) +wxWindowMSW::MSWOnMeasureItem(int id, WXMEASUREITEMSTRUCT *itemStruct) { #if wxUSE_OWNER_DRAWN && wxUSE_MENUS_NATIVE // is it a menu item? @@ -3734,7 +3724,8 @@ wxWindowMSW::MSWOnMeasureItem(int WXUNUSED_UNLESS_ODRAWN(id), { wxMenuItem *pMenuItem = (wxMenuItem *)(pMeasureStruct->itemData); - wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), false ); + wxCHECK_MSG( pMenuItem && pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), + false, _T("MSWOnMeasureItem: bad wxMenuItem pointer") ); size_t w, h; bool rc = pMenuItem->OnMeasureItem(&w, &h); @@ -3750,7 +3741,10 @@ wxWindowMSW::MSWOnMeasureItem(int WXUNUSED_UNLESS_ODRAWN(id), { return item->MSWOnMeasure(itemStruct); } -#endif // wxUSE_OWNER_DRAWN +#else + wxUnusedVar(id); + wxUnusedVar(itemStruct); +#endif // wxUSE_OWNER_DRAWN && wxUSE_MENUS_NATIVE return false; } @@ -4011,7 +4005,7 @@ extern wxCOLORMAP *wxGetStdColourMap() bool wxWindowMSW::HandlePaint() { // if (GetExtraStyle() & wxWS_EX_THEMED_BACKGROUND) -// return FALSE; +// return false; HRGN hRegion = ::CreateRectRgn(0, 0, 0, 0); // Dummy call to get a handle if ( !hRegion ) @@ -4101,7 +4095,7 @@ void wxWindowMSW::OnEraseBackground(wxEraseEvent& event) { RECT rect; ::GetClientRect(GetHwnd(), &rect); - + wxColour backgroundColour( GetBackgroundColour()); COLORREF ref = PALETTERGB(backgroundColour.Red(), backgroundColour.Green(), @@ -4146,7 +4140,8 @@ bool wxWindowMSW::HandleMaximize() bool wxWindowMSW::HandleMove(int x, int y) { - wxMoveEvent event(wxPoint(x, y), m_windowId); + wxPoint point(x,y); + wxMoveEvent event(point, m_windowId); event.SetEventObject(this); return GetEventHandler()->ProcessEvent(event); @@ -4163,16 +4158,40 @@ bool wxWindowMSW::HandleMoving(wxRect& rect) return rc; } -bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), - WXUINT WXUNUSED(flag)) +bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam) { - // don't use w and h parameters as they specify the client size while - // according to the docs EVT_SIZE handler is supposed to receive the total - // size - wxSizeEvent event(GetSize(), m_windowId); - event.SetEventObject(this); + bool processed = false; - return GetEventHandler()->ProcessEvent(event); + switch ( wParam ) + { + default: + wxFAIL_MSG( _T("unexpected WM_SIZE parameter") ); + // fall through nevertheless + + case SIZE_MAXHIDE: + case SIZE_MAXSHOW: + // we're not interested in these messages at all + break; + + case SIZE_MINIMIZED: + processed = HandleMinimize(); + break; + + case SIZE_MAXIMIZED: + /* processed = */ HandleMaximize(); + // fall through to send a normal size event as well + + case SIZE_RESTORED: + // don't use w and h parameters as they specify the client size + // while according to the docs EVT_SIZE handler is supposed to + // receive the total size + wxSizeEvent event(GetSize(), m_windowId); + event.SetEventObject(this); + + processed = GetEventHandler()->ProcessEvent(event); + } + + return processed; } bool wxWindowMSW::HandleSizing(wxRect& rect) @@ -4401,7 +4420,7 @@ static wxWindowMSW *FindWindowForMouseEvent(wxWindowMSW *win, int *x, int *y) // bool wxWindowMSW::HandleMouseEvent(WXUINT msg, int x, int y, WXUINT flags) { // the mouse events take consecutive IDs from WM_MOUSEFIRST to - // WM_MOUSELAST, so it's enough to substract WM_MOUSEMOVE == WM_MOUSEFIRST + // WM_MOUSELAST, so it's enough to subtract WM_MOUSEMOVE == WM_MOUSEFIRST // from the message id and take the value in the table to get wxWin event // id static const wxEventType eventsMouse[] = @@ -4445,7 +4464,7 @@ bool wxWindowMSW::HandleMouseMove(int x, int y, WXUINT flags) trackinfo.hwndTrack = GetHwnd(); //Use the commctrl.h _TrackMouseEvent, which will call the // appropriate TrackMouseEvent or emulate it ( win95 ) - // else we need _WIN32_WINNT >= 0x0400 + // else we need _WIN32_WINNT >= 0x0400 _TrackMouseEvent(&trackinfo); #endif #endif @@ -4532,7 +4551,7 @@ wxKeyEvent wxWindowMSW::CreateKeyEvent(wxEventType evType, event.m_eventObject = (wxWindow *)this; // const_cast event.m_keyCode = id; #if wxUSE_UNICODE - event.m_uniChar = wParam; + event.m_uniChar = (wxChar) wParam; #endif event.m_rawCode = (wxUint32) wParam; event.m_rawFlags = (wxUint32) lParam; @@ -4696,7 +4715,7 @@ int wxWindowMSW::HandleMenuChar(int chAccel, WXLPARAM lParam) // FIXME-UNICODE: this comparison doesn't risk to work // for non ASCII accelerator characters I'm afraid, but // what can we do? - if ( wxToupper(*p) == chAccel ) + if ( (wchar_t)wxToupper(*p) == (wchar_t)chAccel ) { return i; } @@ -4821,7 +4840,7 @@ bool wxWindowMSW::HandleJoystickEvent(WXUINT msg, int x, int y, WXUINT flags) bool wxWindowMSW::MSWOnScroll(int orientation, WXWORD wParam, WXWORD pos, WXHWND control) -{ +{ if ( control && control != m_hWnd ) // Prevent infinite recursion { wxWindow *child = wxFindWinFromHandle(control); @@ -4904,13 +4923,13 @@ void wxGetCharSize(WXHWND wnd, int *x, int *y, const wxFont& the_font) TEXTMETRIC tm; HDC dc = ::GetDC((HWND) wnd); HFONT was = 0; - + // the_font.UseResource(); // the_font.RealizeResource(); HFONT fnt = (HFONT)the_font.GetResourceHandle(); // const_cast if ( fnt ) was = (HFONT) SelectObject(dc,fnt); - + GetTextMetrics(dc, &tm); if ( fnt && was ) { @@ -5032,10 +5051,10 @@ int wxCharCodeMSWToWX(int keySym, WXLPARAM lParam) return id; } -int wxCharCodeWXToMSW(int id, bool *isVirtual) +WXWORD wxCharCodeWXToMSW(int id, bool *isVirtual) { *isVirtual = true; - int keySym; + WXWORD keySym; switch (id) { case WXK_CANCEL: keySym = VK_CANCEL; break; @@ -5104,7 +5123,7 @@ int wxCharCodeWXToMSW(int id, bool *isVirtual) default: { *isVirtual = false; - keySym = id; + keySym = (WORD)id; break; } } @@ -5114,25 +5133,32 @@ int wxCharCodeWXToMSW(int id, bool *isVirtual) bool wxGetKeyState(wxKeyCode key) { bool bVirtual; - int vkey = wxCharCodeWXToMSW(key, &bVirtual); - SHORT state; - switch (key) +//High order with GetAsyncKeyState only available on WIN32 +#ifdef __WIN32__ + //If the requested key is a LED key, return + //true if the led is pressed + if (key == WXK_NUMLOCK || + key == WXK_CAPITAL || + key == WXK_SCROLL) { - case WXK_NUMLOCK: - case WXK_CAPITAL: - case WXK_SCROLL: - // get the toggle state of the special key - state = GetKeyState(vkey); - break; - - default: - // Get the current state of the physical key - state = GetAsyncKeyState(vkey); - break; +#endif + //low order bit means LED is highlighted, + //high order means key is down + //Here, for compat with other ports we want both + return GetKeyState( wxCharCodeWXToMSW(key, &bVirtual) ) != 0; + +#ifdef __WIN32__ + } + else + { + //normal key + //low order bit means key pressed since last call + //high order means key is down + //We want only the high order bit - the key may not be down if only low order + return ( GetAsyncKeyState( wxCharCodeWXToMSW(key, &bVirtual) ) & (1<<15) ) != 0; } - // if the most significant bit is set then the key is down - return ( state & 0x0001 ) != 0; +#endif } wxWindow *wxGetActiveWindow() @@ -5689,26 +5715,6 @@ const char *wxGetMessageName(int message) } #endif //__WXDEBUG__ -static void TranslateKbdEventToMouse(wxWindowMSW *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); -} - static TEXTMETRIC wxGetTextMetrics(const wxWindowMSW *win) { // prepare the DC @@ -5904,7 +5910,7 @@ static void wxAdjustZOrder(wxWindow* parent) // Set the z-order correctly SetWindowPos((HWND) parent->GetHWND(), HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); } - + wxWindowList::compatibility_iterator current = parent->GetChildren().GetFirst(); while (current) { @@ -5922,7 +5928,7 @@ void wxWindowMSW::OnInitDialog( wxInitDialogEvent& event ) #if wxUSE_STATBOX wxAdjustZOrder(this); #endif - + event.Skip(); } #endif