X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/c43e86bda666dd2df9907493c8a7aaf0fee9fa0f..807a903e6807ae3e49928bda488a04bc0d832149:/src/msw/window.cpp diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 014c0747bb..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" @@ -867,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 @@ -1146,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 ) @@ -1462,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); @@ -1557,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 @@ -1846,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: @@ -1887,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 @@ -1909,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: @@ -1925,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: @@ -2292,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; } @@ -2346,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 @@ -2365,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, @@ -2380,17 +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) + + if ( extendedStyle != 0 ) { ::SetWindowLong(GetHwnd(), GWL_EXSTYLE, extendedStyle); ::SetWindowPos(GetHwnd(), NULL, 0, 0, 0, 0, - SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); + 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 ) @@ -2408,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 ) @@ -2444,6 +2497,7 @@ bool wxWindow::MSWCreate(int id, } wxWndHook = NULL; + #ifdef __WXDEBUG__ wxNode* node = wxWinHandleList->Member(this); if (node) @@ -2454,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; @@ -3112,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; @@ -3127,6 +3183,7 @@ void wxWindow::SendSizeEvent() (void)::PostMessage(GetHwnd(), WM_SIZE, SIZE_RESTORED, MAKELPARAM(r.right - r.left, r.bottom - r.top)); } +*/ // --------------------------------------------------------------------------- // command messages @@ -3177,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; } @@ -4367,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); +} +