X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/63da7df70114ff2c535d6cdeec5d0aca83ce97f3..656fc51cda91ea40154358a6adcd85ded506812a:/src/msw/window.cpp diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 6aa913b6b2..f58179b4c3 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -71,6 +71,10 @@ #include "wx/caret.h" #endif // wxUSE_CARET +#if wxUSE_SPINCTRL + #include "wx/spinctrl.h" +#endif // wxUSE_SPINCTRL + #include "wx/intl.h" #include "wx/log.h" @@ -316,6 +320,8 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id, msflags |= WS_CHILD | WS_VISIBLE; if ( style & wxCLIP_CHILDREN ) msflags |= WS_CLIPCHILDREN; + if ( style & wxCLIP_SIBLINGS ) + msflags |= WS_CLIPSIBLINGS; bool want3D; WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D); @@ -865,7 +871,8 @@ WXDWORD wxWindow::MakeExtendedStyle(long style, bool eliminateBorders) exStyle |= WS_EX_DLGMODALFRAME; #if defined(__WIN95__) if ( style & wxRAISED_BORDER ) - exStyle |= WS_EX_WINDOWEDGE; + // It seems that WS_EX_WINDOWEDGE doesn't work, but WS_EX_DLGMODALFRAME does + exStyle |= WS_EX_DLGMODALFRAME; /* WS_EX_WINDOWEDGE */; if ( style & wxSTATIC_BORDER ) exStyle |= WS_EX_STATICEDGE; #endif @@ -1144,11 +1151,14 @@ void wxWindow::DoGetPosition(int *x, int *y) const ::ScreenToClient(hParentWnd, &point); } - // 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; + if ( parent ) + { + // 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; + } } if ( x ) @@ -1460,7 +1470,7 @@ bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y) ::ClientToScreen(hWnd, &point); wxCurrentPopupMenu = menu; ::TrackPopupMenu(hMenu, TPM_RIGHTBUTTON, point.x, point.y, 0, hWnd, NULL); - wxYield(); + wxYieldIfNeeded(); wxCurrentPopupMenu = NULL; menu->SetInvokingWindow(NULL); @@ -1555,7 +1565,18 @@ bool wxWindow::MSWProcessMessage(WXMSG* pMsg) } else if ( lDlgCode & DLGC_BUTTON ) { - // buttons want process Enter themselevs + // let IsDialogMessage() handle this for all + // buttons except the owner-drawn ones which it + // just seems to ignore + long style = ::GetWindowLong(msg->hwnd, GWL_STYLE); + if ( (style & BS_OWNERDRAW) == BS_OWNERDRAW ) + { + // emulate the button click + wxWindow *btn = wxFindWinFromHandle((WXHWND)msg->hwnd); + if ( btn ) + btn->MSWCommand(BN_CLICKED, 0 /* unused */); + } + bProcess = FALSE; } else @@ -1844,7 +1865,7 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) break; case WM_MOVE: - processed = HandleMove(LOWORD(lParam), HIWORD(lParam)); + processed = HandleMove(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); break; case WM_SIZE: @@ -1885,17 +1906,15 @@ 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; + processed = HandleMouseMove(GET_X_LPARAM(lParam), + GET_Y_LPARAM(lParam), + wParam); + break; case WM_LBUTTONDOWN: // set focus to this window - SetFocus(); + if (AcceptsFocus()) + SetFocus(); // fall through @@ -1907,12 +1926,10 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) case WM_MBUTTONDOWN: case WM_MBUTTONUP: case WM_MBUTTONDBLCLK: - { - short x = LOWORD(lParam); - short y = HIWORD(lParam); - - processed = HandleMouseEvent(message, x, y, wParam); - } + processed = HandleMouseEvent(message, + GET_X_LPARAM(lParam), + GET_Y_LPARAM(lParam), + wParam); break; case MM_JOY1MOVE: @@ -1923,12 +1940,10 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) case MM_JOY2BUTTONDOWN: case MM_JOY1BUTTONUP: case MM_JOY2BUTTONUP: - { - int x = LOWORD(lParam); - int y = HIWORD(lParam); - - processed = HandleJoystickEvent(message, x, y, wParam); - } + processed = HandleJoystickEvent(message, + GET_X_LPARAM(lParam), + GET_Y_LPARAM(lParam), + wParam); break; case WM_SYSCOMMAND: @@ -2168,6 +2183,36 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) rc.result = TRUE; } break; +#ifdef __WIN32__ + case WM_HELP: + { + HELPINFO* info = (HELPINFO*) lParam; + // Don't yet process menu help events, just windows + if (info->iContextType == HELPINFO_WINDOW) + { + wxWindow* subjectOfHelp = this; + bool eventProcessed = FALSE; + while (subjectOfHelp && !eventProcessed) + { + wxHelpEvent helpEvent(wxEVT_HELP, subjectOfHelp->GetId(), wxPoint(info->MousePos.x, info->MousePos.y) ) ; // info->iCtrlId); + helpEvent.SetEventObject(this); + eventProcessed = GetEventHandler()->ProcessEvent(helpEvent); + + // Go up the window hierarchy until the event is handled (or not) + subjectOfHelp = subjectOfHelp->GetParent(); + } + processed = eventProcessed; + } + else if (info->iContextType == HELPINFO_MENUITEM) + { + wxHelpEvent helpEvent(wxEVT_HELP, info->iCtrlId) ; + helpEvent.SetEventObject(this); + processed = GetEventHandler()->ProcessEvent(helpEvent); + } + else processed = FALSE; + break; + } +#endif } if ( !processed ) @@ -2260,24 +2305,25 @@ void wxWindow::MSWDetachWindowMenu() { if ( m_hMenu ) { + wxChar buf[1024]; HMENU hMenu = (HMENU)m_hMenu; int N = ::GetMenuItemCount(hMenu); - int i; - for (i = 0; i < N; i++) + for ( int i = 0; i < N; i++ ) { - wxChar buf[100]; - int chars = GetMenuString(hMenu, i, buf, 100, MF_BYPOSITION); - if ( !chars ) + if ( !::GetMenuString(hMenu, i, buf, WXSIZEOF(buf), MF_BYPOSITION) ) { wxLogLastError(wxT("GetMenuString")); continue; } - if ( wxStrcmp(buf, wxT("&Window")) == 0 ) + if ( wxStrcmp(buf, _("&Window")) == 0 ) { - RemoveMenu(hMenu, i, MF_BYPOSITION); + if ( !::RemoveMenu(hMenu, i, MF_BYPOSITION) ) + { + wxLogLastError(wxT("RemoveMenu")); + } break; } @@ -2314,10 +2360,14 @@ bool wxWindow::MSWCreate(int id, height1 = parent_rect.bottom - parent_rect.top; } - if ( x > -1 ) x1 = x; - if ( y > -1 ) y1 = y; - if ( width > -1 ) width1 = width; - if ( height > -1 ) height1 = height; + if ( x != -1 ) + x1 = x; + if ( y != -1 ) + y1 = y; + if ( width != -1 ) + width1 = width; + if ( height != -1 ) + height1 = height; // unfortunately, setting WS_EX_CONTROLPARENT only for some windows in the // hierarchy with several embedded panels (and not all of them) causes the @@ -2333,14 +2383,22 @@ bool wxWindow::MSWCreate(int id, } #endif // 0 - HWND hParent = (HWND)NULL; - if ( parent ) - hParent = (HWND) parent->GetHWND(); + HWND hParent = parent ? GetHwndOf(parent) : NULL; wxWndHook = this; if ( dialog_template ) { + // for the dialogs without wxDIALOG_NO_PARENT style, use the top level + // app window as parent - this avoids creating modal dialogs without + // parent + if ( !hParent && !(GetWindowStyleFlag() & wxDIALOG_NO_PARENT) ) + { + wxWindow *winTop = wxTheApp->GetTopWindow(); + if ( winTop ) + hParent = GetHwndOf(winTop); + } + m_hWnd = (WXHWND)::CreateDialog(wxGetInstance(), dialog_template, hParent, @@ -2348,11 +2406,44 @@ bool wxWindow::MSWCreate(int id, if ( m_hWnd == 0 ) { - wxLogError(_("Can't find dummy dialog template!\nCheck resource include path for finding wx.rc.")); + wxLogError(_("Can't find dialog template '%s'!\nCheck resource include path for finding wx.rc."), + dialog_template); return FALSE; } + if ( extendedStyle != 0 ) + { + ::SetWindowLong(GetHwnd(), GWL_EXSTYLE, extendedStyle); + ::SetWindowPos(GetHwnd(), NULL, 0, 0, 0, 0, + SWP_NOSIZE | + SWP_NOMOVE | + SWP_NOZORDER | + SWP_NOACTIVATE); + } + +#if defined(__WIN95__) + // For some reason, the system menu is activated when we use the + // WS_EX_CONTEXTHELP style, so let's set a reasonable icon + if (extendedStyle & WS_EX_CONTEXTHELP) + { + wxFrame *winTop = wxDynamicCast(wxTheApp->GetTopWindow(), wxFrame); + if ( winTop ) + { + wxIcon icon = winTop->GetIcon(); + if ( icon.Ok() ) + { + ::SendMessage(GetHwnd(), WM_SETICON, + (WPARAM)TRUE, + (LPARAM)GetHiconOf(icon)); + } + } + } +#endif // __WIN95__ + + + // JACS: is the following still necessary? The above seems to work. + // ::SetWindowLong(GWL_EXSTYLE) doesn't work for the dialogs, so try // to take care of (at least some) extended style flags ourselves if ( extendedStyle & WS_EX_TOPMOST ) @@ -2370,7 +2461,7 @@ bool wxWindow::MSWCreate(int id, wxLogLastError(wxT("MoveWindow")); } } - else + else // creating a normal window, not a dialog { int controlId = 0; if ( style & WS_CHILD ) @@ -2406,6 +2497,7 @@ bool wxWindow::MSWCreate(int id, } wxWndHook = NULL; + #ifdef __WXDEBUG__ wxNode* node = wxWinHandleList->Member(this); if (node) @@ -2416,7 +2508,8 @@ bool wxWindow::MSWCreate(int id, wxLogError(wxT("A second HWND association is being added for the same window!")); } } -#endif +#endif // Debug + wxAssociateWinWithHandle((HWND) m_hWnd, this); return TRUE; @@ -2766,11 +2859,9 @@ bool wxWindow::HandleSetCursor(WXHWND hWnd, // cursor set, stop here return TRUE; } - else - { - // pass up the window chain - return FALSE; - } + + // pass up the window chain + return FALSE; } // --------------------------------------------------------------------------- @@ -3076,6 +3167,7 @@ bool wxWindow::HandleGetMinMaxInfo(void *mmInfo) } // generate an artificial resize event +/* FUNCTION IS NOW A MEMBER OF wxFrame - gt void wxWindow::SendSizeEvent() { RECT r; @@ -3091,6 +3183,7 @@ void wxWindow::SendSizeEvent() (void)::PostMessage(GetHwnd(), WM_SIZE, SIZE_RESTORED, MAKELPARAM(r.right - r.left, r.bottom - r.top)); } +*/ // --------------------------------------------------------------------------- // command messages @@ -3141,6 +3234,17 @@ bool wxWindow::HandleCommand(WXWORD id, WXWORD cmd, WXHWND control) return GetEventHandler()->ProcessEvent(event); } +#if wxUSE_SPINCTRL + else + { + // 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 return FALSE; } @@ -3173,6 +3277,7 @@ void wxWindow::InitMouseEvent(wxMouseEvent& event, int x, int y, WXUINT flags) 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; event.SetTimestamp(s_currentMsg.time); event.m_eventObject = this; @@ -4330,3 +4435,38 @@ static TEXTMETRIC wxGetTextMetrics(const wxWindow *win) return tm; } + +// Find the wxWindow at the current mouse position, returning the mouse +// position. +wxWindow* wxFindWindowAtPointer(wxPoint& pt) +{ + return wxFindWindowAtPoint(wxGetMousePosition()); +} + +wxWindow* wxFindWindowAtPoint(const wxPoint& pt) +{ + POINT pt2; + pt2.x = pt.x; + pt2.y = pt.y; + HWND hWndHit = ::WindowFromPoint(pt2); + + wxWindow* win = wxFindWinFromHandle((WXHWND) hWndHit) ; + HWND hWnd = hWndHit; + + // Try to find a window with a wxWindow associated with it + while (!win && (hWnd != 0)) + { + hWnd = ::GetParent(hWnd); + win = wxFindWinFromHandle((WXHWND) hWnd) ; + } + return win; +} + +// Get the current mouse position. +wxPoint wxGetMousePosition() +{ + POINT pt; + GetCursorPos( & pt ); + return wxPoint(pt.x, pt.y); +} +