X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/23035521721c540a7aa92408ec72387a3d931b24..79cb759dc8580da2e82e880cd94a08cd38bb814e:/src/msw/window.cpp diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 3702df9b6c..0caca386a9 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -183,12 +183,6 @@ extern wxMenu *wxCurrentPopupMenu; #endif -#ifdef __WXWINCE__ -extern wxChar *wxCanvasClassName; -#else -extern const wxChar *wxCanvasClassName; -#endif - // true if we had already created the std colour map, used by // wxGetStdColourMap() and wxWindow::OnSysColourChanged() (FIXME-MT) static bool gs_hasStdCmap = false; @@ -281,12 +275,11 @@ static void EnsureParentHasControlParentStyle(wxWindow *parent) */ while ( parent && !parent->IsTopLevel() ) { - LONG exStyle = ::GetWindowLong(GetHwndOf(parent), GWL_EXSTYLE); + LONG exStyle = wxGetWindowExStyle(parent); if ( !(exStyle & WS_EX_CONTROLPARENT) ) { // force the parent to have this style - ::SetWindowLong(GetHwndOf(parent), GWL_EXSTYLE, - exStyle | WS_EX_CONTROLPARENT); + wxSetWindowExStyle(parent, exStyle | WS_EX_CONTROLPARENT); } parent = parent->GetParent(); @@ -525,7 +518,6 @@ bool wxWindowMSW::MSWCommand(WXUINT WXUNUSED(param), WXWORD WXUNUSED(id)) void wxWindowMSW::Init() { // MSW specific - m_isBeingDeleted = false; m_oldWndProc = NULL; m_mouseInWindow = false; m_lastKeydownProcessed = false; @@ -547,7 +539,7 @@ void wxWindowMSW::Init() // Destructor wxWindowMSW::~wxWindowMSW() { - m_isBeingDeleted = true; + SendDestroyEvent(); #ifndef __WXUNIVERSAL__ // VS: make sure there's no wxFrame with last focus set to us: @@ -590,6 +582,12 @@ wxWindowMSW::~wxWindowMSW() } +/* static */ +const wxChar *wxWindowMSW::MSWGetRegisteredClassName() +{ + return wxApp::GetRegisteredClassName(_T("wxWindow"), COLOR_BTNFACE); +} + // real construction (Init() must have been called before!) bool wxWindowMSW::Create(wxWindow *parent, wxWindowID id, @@ -622,7 +620,8 @@ bool wxWindowMSW::Create(wxWindow *parent, msflags |= WS_VISIBLE; } - if ( !MSWCreate(wxCanvasClassName, NULL, pos, size, msflags, exstyle) ) + if ( !MSWCreate(MSWGetRegisteredClassName(), + NULL, pos, size, msflags, exstyle) ) return false; InheritAttributes(); @@ -755,6 +754,11 @@ wxWindowMSW::MSWShowWithEffect(bool show, if ( !s_pfnAnimateWindow ) return Show(show); + // Show() has a side effect of sending a WM_SIZE to the window, which helps + // ensuring that it's laid out correctly, but AnimateWindow() doesn't do + // this so send the event ourselves + SendSizeEvent(); + // prepare to use AnimateWindow() if ( !timeout ) @@ -871,7 +875,11 @@ bool wxWindowMSW::SetFont(const wxFont& font) HWND hWnd = GetHwnd(); if ( hWnd != 0 ) { - WXHANDLE hFont = m_font.GetResourceHandle(); + // note the use of GetFont() instead of m_font: our own font could have + // just been reset and in this case we need to change the font used by + // the native window to the default for this class, i.e. exactly what + // GetFont() returns + WXHANDLE hFont = GetFont().GetResourceHandle(); wxASSERT_MSG( hFont, wxT("should have valid font") ); @@ -954,6 +962,9 @@ void wxWindowMSW::MSWUpdateUIState(int action, int state) // scrolling stuff // --------------------------------------------------------------------------- +namespace +{ + inline int GetScrollPosition(HWND hWnd, int wOrient) { #ifdef __WXMICROWIN__ @@ -969,12 +980,19 @@ inline int GetScrollPosition(HWND hWnd, int wOrient) #endif } +inline UINT WXOrientToSB(int orient) +{ + return orient == wxHORIZONTAL ? SB_HORZ : SB_VERT; +} + +} // anonymous namespace + int wxWindowMSW::GetScrollPos(int orient) const { HWND hWnd = GetHwnd(); wxCHECK_MSG( hWnd, 0, _T("no HWND in GetScrollPos") ); - return GetScrollPosition(hWnd, orient == wxHORIZONTAL ? SB_HORZ : SB_VERT); + return GetScrollPosition(hWnd, WXOrientToSB(orient)); } // This now returns the whole range, not just the number @@ -985,15 +1003,9 @@ int wxWindowMSW::GetScrollRange(int orient) const HWND hWnd = GetHwnd(); if ( !hWnd ) return 0; -#if 0 - ::GetScrollRange(hWnd, orient == wxHORIZONTAL ? SB_HORZ : SB_VERT, - &minPos, &maxPos); -#endif WinStruct scrollInfo; scrollInfo.fMask = SIF_RANGE; - if ( !::GetScrollInfo(hWnd, - orient == wxHORIZONTAL ? SB_HORZ : SB_VERT, - &scrollInfo) ) + if ( !::GetScrollInfo(hWnd, WXOrientToSB(orient), &scrollInfo) ) { // Most of the time this is not really an error, since the return // value can also be zero when there is no scrollbar yet. @@ -1026,8 +1038,7 @@ void wxWindowMSW::SetScrollPos(int orient, int pos, bool refresh) info.fMask |= SIF_DISABLENOSCROLL; } - ::SetScrollInfo(hWnd, orient == wxHORIZONTAL ? SB_HORZ : SB_VERT, - &info, refresh); + ::SetScrollInfo(hWnd, WXOrientToSB(orient), &info, refresh); } // New function that will replace some of the above. @@ -1037,28 +1048,37 @@ void wxWindowMSW::SetScrollbar(int orient, int range, bool refresh) { + // We have to set the variables here to make them valid in events + // triggered by ::SetScrollInfo() + *(orient == wxHORIZONTAL ? &m_xThumbSize : &m_yThumbSize) = pageSize; + + HWND hwnd = GetHwnd(); + if ( !hwnd ) + return; + WinStruct info; - info.nPage = pageSize; - info.nMin = 0; // range is nMax - nMin + 1 - info.nMax = range - 1; // as both nMax and nMax are inclusive - info.nPos = pos; + if ( range != -1 ) + { + info.nPage = pageSize; + info.nMin = 0; // range is nMax - nMin + 1 + info.nMax = range - 1; // as both nMax and nMax are inclusive + info.nPos = pos; + + // enable the scrollbar if it had been disabled before by specifying + // SIF_DISABLENOSCROLL below: as we can't know whether this had been + // done or not just do it always + ::EnableScrollBar(hwnd, WXOrientToSB(orient), ESB_ENABLE_BOTH); + } + //else: leave all the fields to be 0 + info.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; - if ( HasFlag(wxALWAYS_SHOW_SB) ) + if ( HasFlag(wxALWAYS_SHOW_SB) || range == -1 ) { // disable scrollbar instead of removing it then info.fMask |= SIF_DISABLENOSCROLL; } - HWND hWnd = GetHwnd(); - if ( hWnd ) - { - // We have to set the variables here to make them valid in events - // triggered by ::SetScrollInfo() - *(orient == wxHORIZONTAL ? &m_xThumbSize : &m_yThumbSize) = pageSize; - - ::SetScrollInfo(hWnd, orient == wxHORIZONTAL ? SB_HORZ : SB_VERT, - &info, refresh); - } + ::SetScrollInfo(hwnd, WXOrientToSB(orient), &info, refresh); } void wxWindowMSW::ScrollWindow(int dx, int dy, const wxRect *prect) @@ -1133,10 +1153,10 @@ void wxWindowMSW::SetLayoutDirection(wxLayoutDirection dir) #ifdef __WXWINCE__ wxUnusedVar(dir); #else - const HWND hwnd = GetHwnd(); - wxCHECK_RET( hwnd, _T("layout direction must be set after window creation") ); + wxCHECK_RET( GetHwnd(), + _T("layout direction must be set after window creation") ); - LONG styleOld = ::GetWindowLong(hwnd, GWL_EXSTYLE); + LONG styleOld = wxGetWindowExStyle(this); LONG styleNew = styleOld; switch ( dir ) @@ -1156,7 +1176,7 @@ void wxWindowMSW::SetLayoutDirection(wxLayoutDirection dir) if ( styleNew != styleOld ) { - ::SetWindowLong(hwnd, GWL_EXSTYLE, styleNew); + wxSetWindowExStyle(this, styleNew); } #endif } @@ -1166,12 +1186,10 @@ wxLayoutDirection wxWindowMSW::GetLayoutDirection() const #ifdef __WXWINCE__ return wxLayout_Default; #else - const HWND hwnd = GetHwnd(); - wxCHECK_MSG( hwnd, wxLayout_Default, _T("invalid window") ); + wxCHECK_MSG( GetHwnd(), wxLayout_Default, _T("invalid window") ); - return ::GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_LAYOUTRTL - ? wxLayout_RightToLeft - : wxLayout_LeftToRight; + return wxHasWindowExStyle(this, WS_EX_LAYOUTRTL) ? wxLayout_RightToLeft + : wxLayout_LeftToRight; #endif } @@ -1270,36 +1288,12 @@ void wxWindowMSW::DissociateHandle() bool wxCheckWindowWndProc(WXHWND hWnd, WXFARPROC WXUNUSED(wndProc)) { -// TODO: This list of window class names should be factored out so they can be -// managed in one place and then accessed from here and other places, such as -// wxApp::RegisterWindowClasses() and wxApp::UnregisterWindowClasses() + const wxString str(wxGetWindowClass(hWnd)); -#ifdef __WXWINCE__ - extern wxChar *wxCanvasClassName; - extern wxChar *wxCanvasClassNameNR; -#else - extern const wxChar *wxCanvasClassName; - extern const wxChar *wxCanvasClassNameNR; -#endif - extern const wxChar *wxMDIFrameClassName; - extern const wxChar *wxMDIFrameClassNameNoRedraw; - extern const wxChar *wxMDIChildFrameClassName; - extern const wxChar *wxMDIChildFrameClassNameNoRedraw; - wxString str(wxGetWindowClass(hWnd)); - if (str == wxCanvasClassName || - str == wxCanvasClassNameNR || -#if wxUSE_GLCANVAS - str == _T("wxGLCanvasClass") || - str == _T("wxGLCanvasClassNR") || -#endif // wxUSE_GLCANVAS - str == wxMDIFrameClassName || - str == wxMDIFrameClassNameNoRedraw || - str == wxMDIChildFrameClassName || - str == wxMDIChildFrameClassNameNoRedraw || - str == _T("wxTLWHiddenParent")) - return true; // Effectively means don't subclass - else - return false; + // TODO: get rid of wxTLWHiddenParent special case (currently it's not + // registered by wxApp but using ad hoc code in msw/toplevel.cpp); + // there is also a hidden window class used by sockets &c + return wxApp::IsRegisteredClassName(str) || str == _T("wxTLWHiddenParent"); } // ---------------------------------------------------------------------------- @@ -1382,14 +1376,14 @@ void wxWindowMSW::MSWUpdateStyle(long flagsOld, long exflagsOld) } // and the extended style - long exstyleReal = ::GetWindowLong(GetHwnd(), GWL_EXSTYLE); + long exstyleReal = wxGetWindowExStyle(this); if ( exstyle != exstyleOld ) { exstyleReal &= ~exstyleOld; exstyleReal |= exstyle; - ::SetWindowLong(GetHwnd(), GWL_EXSTYLE, exstyleReal); + wxSetWindowExStyle(this, exstyleReal); // ex style changes don't take effect without calling SetWindowPos callSWP = true; @@ -1597,7 +1591,7 @@ bool wxWindowMSW::Reparent(wxWindowBase *parent) ::SetParent(hWndChild, hWndParent); #ifndef __WXWINCE__ - if ( ::GetWindowLong(hWndChild, GWL_EXSTYLE) & WS_EX_CONTROLPARENT ) + if ( wxHasWindowExStyle(this, WS_EX_CONTROLPARENT) ) { EnsureParentHasControlParentStyle(GetParent()); } @@ -1981,6 +1975,11 @@ void wxWindowMSW::DoMoveWindow(int x, int y, int width, int height) #if USE_DEFERRED_SIZING m_pendingPosition = wxPoint(x, y); m_pendingSize = wxSize(width, height); + } + else // window was moved immediately, without deferring it + { + m_pendingPosition = wxDefaultPosition; + m_pendingSize = wxDefaultSize; #endif // USE_DEFERRED_SIZING } } @@ -2008,6 +2007,12 @@ void wxWindowMSW::DoSetSize(int x, int y, int width, int height, int sizeFlags) width == currentW && height == currentH && !(sizeFlags & wxSIZE_FORCE) ) { + if (sizeFlags & wxSIZE_FORCE_EVENT) + { + wxSizeEvent event( wxSize(width,height), GetId() ); + event.SetEventObject( this ); + HandleWindowEvent( event ); + } return; } @@ -2541,8 +2546,7 @@ bool wxWindowMSW::MSWShouldPreProcessMessage(WXMSG* msg) { wxWindow * const win = node->GetData(); if ( win->CanAcceptFocus() && - !(::GetWindowLong(GetHwndOf(win), GWL_EXSTYLE) & - WS_EX_CONTROLPARENT) ) + !wxHasWindowExStyle(win, WS_EX_CONTROLPARENT) ) { // it shouldn't hang... canSafelyCallIsDlgMsg = true; @@ -3413,12 +3417,12 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l rc.result = MSWDefWindowProc(message, wParam, lParam); processed = true; - // now alter the client size making room for drawing a themed border - NCCALCSIZE_PARAMS *csparam = NULL; + // now alter the client size making room for drawing a + // themed border RECT *rect; if ( wParam ) { - csparam = (NCCALCSIZE_PARAMS *)lParam; + NCCALCSIZE_PARAMS *csparam = (NCCALCSIZE_PARAMS *)lParam; rect = &csparam->rgrc[0]; } else @@ -3675,6 +3679,11 @@ bool wxWindowMSW::MSWCreate(const wxChar *wclass, // especially for wxTLWs wxCHECK_MSG( !m_hWnd, true, "window can't be recreated" ); + // this can happen if this function is called using the return value of + // wxApp::GetRegisteredClassName() which failed + wxCHECK_MSG( wclass, false, "failed to register window class?" ); + + // choose the position/size for the new window int x, y, w, h; (void)MSWGetCreateWindowCoords(pos, size, x, y, w, h); @@ -3689,7 +3698,7 @@ bool wxWindowMSW::MSWCreate(const wxChar *wclass, wxString className(wclass); if ( !HasFlag(wxFULL_REPAINT_ON_RESIZE) ) { - className += wxT("NR"); + className += wxApp::GetNoRedrawClassSuffix(); } // do create the window @@ -3840,8 +3849,7 @@ bool wxWindowMSW::HandleTooltipNotify(WXUINT code, // if we got TTN_NEEDTEXTW in Unicode build: in this case we just have // to copy the string we have into the buffer static wxChar buf[513]; - wxStrncpy(buf, ttip.c_str(), WXSIZEOF(buf) - 1); - buf[WXSIZEOF(buf) - 1] = _T('\0'); + wxStrlcpy(buf, ttip.c_str(), WXSIZEOF(buf)); ttText->lpszText = buf; } @@ -3946,8 +3954,6 @@ bool wxWindowMSW::HandleCreate(WXLPCREATESTRUCT WXUNUSED_IN_WINCE(cs), bool wxWindowMSW::HandleDestroy() { - SendDestroyEvent(); - // delete our drop target if we've got one #if wxUSE_DRAG_AND_DROP if ( m_dropTarget != NULL ) @@ -4097,7 +4103,6 @@ bool wxWindowMSW::HandleDropFiles(WXWPARAM wParam) ::DragQueryFile(hFilesInfo, wIndex, wxStringBuffer(files[wIndex], len), len); } - DragFinish (hFilesInfo); wxDropFilesEvent event(wxEVT_DROP_FILES, gwFilesDropped, files); event.SetEventObject(this); @@ -4107,6 +4112,8 @@ bool wxWindowMSW::HandleDropFiles(WXWPARAM wParam) event.m_pos.x = dropPoint.x; event.m_pos.y = dropPoint.y; + DragFinish(hFilesInfo); + return HandleWindowEvent(event); #endif } @@ -4257,17 +4264,33 @@ bool wxWindowMSW::HandlePower(WXWPARAM WXUNUSED_IN_WINCE(wParam), bool wxWindowMSW::IsDoubleBuffered() const { - for ( const wxWindowMSW *wnd = this; - wnd && !wnd->IsTopLevel(); wnd = - wnd->GetParent() ) + for ( const wxWindowMSW *win = this; win; win = win->GetParent() ) { - if ( ::GetWindowLong(GetHwndOf(wnd), GWL_EXSTYLE) & WS_EX_COMPOSITED ) + if ( wxHasWindowExStyle(win, WS_EX_COMPOSITED) ) return true; + + if ( win->IsTopLevel() ) + break; } return false; } +void wxWindowMSW::SetDoubleBuffered(bool on) +{ + // Get the current extended style bits + long exstyle = wxGetWindowExStyle(this); + + // Twiddle the bit as needed + if ( on ) + exstyle |= WS_EX_COMPOSITED; + else + exstyle &= ~WS_EX_COMPOSITED; + + // put it back + wxSetWindowExStyle(this, exstyle); +} + // --------------------------------------------------------------------------- // owner drawn stuff // --------------------------------------------------------------------------- @@ -5078,12 +5101,8 @@ bool wxWindowMSW::HandleCommand(WXWORD id_, WXWORD cmd, WXHWND control) // 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); + wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, id); event.SetEventObject(this); - event.SetId(id); event.SetInt(id); return HandleWindowEvent(event); @@ -5284,20 +5303,16 @@ bool wxWindowMSW::HandleMouseMove(int x, int y, WXUINT flags) static bool s_initDone = false; if ( !s_initDone ) { - wxLogNull noLog; - - wxDynamicLibrary dllComCtl32(_T("comctl32.dll"), wxDL_VERBATIM); + // see comment in wxApp::GetComCtl32Version() explaining the + // use of wxLoadedDLL + wxLoadedDLL dllComCtl32(_T("comctl32.dll")); if ( dllComCtl32.IsLoaded() ) { s_pfn_TrackMouseEvent = (_TrackMouseEvent_t) - dllComCtl32.GetSymbol(_T("_TrackMouseEvent")); + dllComCtl32.RawGetSymbol(_T("_TrackMouseEvent")); } s_initDone = true; - - // notice that it's ok to unload comctl32.dll here as it won't - // be really unloaded, being still in use because we link to it - // statically too } if ( s_pfn_TrackMouseEvent ) @@ -5620,18 +5635,19 @@ int wxWindowMSW::HandleMenuChar(int WXUNUSED_IN_WINCE(chAccel), return wxNOT_FOUND; } -bool wxWindowMSW::HandleClipboardEvent( WXUINT nMsg ) +#endif // wxUSE_MENUS + +bool wxWindowMSW::HandleClipboardEvent(WXUINT nMsg) { - const wxEventType type = ( nMsg == WM_CUT ) ? wxEVT_COMMAND_TEXT_CUT : - ( nMsg == WM_COPY ) ? wxEVT_COMMAND_TEXT_COPY : - /*( nMsg == WM_PASTE ) ? */ wxEVT_COMMAND_TEXT_PASTE; + const wxEventType type = nMsg == WM_CUT ? wxEVT_COMMAND_TEXT_CUT + : nMsg == WM_COPY ? wxEVT_COMMAND_TEXT_COPY + : /* nMsg == WM_PASTE */ wxEVT_COMMAND_TEXT_PASTE; wxClipboardTextEvent evt(type, GetId()); evt.SetEventObject(this); return HandleWindowEvent(evt); } -#endif // wxUSE_MENUS // --------------------------------------------------------------------------- // joystick @@ -5782,8 +5798,7 @@ bool wxWindowMSW::MSWOnScroll(int orientation, WXWORD wParam, scrollInfo.fMask = SIF_TRACKPOS; if ( !::GetScrollInfo(GetHwnd(), - orientation == wxHORIZONTAL ? SB_HORZ - : SB_VERT, + WXOrientToSB(orientation), &scrollInfo) ) { // Not necessarily an error, if there are no scrollbars yet. @@ -6214,7 +6229,7 @@ extern wxWindow *wxGetWindowFromHWND(WXHWND 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; + wxWindow *win = NULL; if ( hwnd ) { win = wxFindWinFromHandle(hwnd);