From b225f65995e9eccefe9b502568b1b8e40629cd1a Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 7 Oct 2001 22:17:24 +0000 Subject: [PATCH] changed/centralized window creation code to allow wxTLW work in wxUniv git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@11880 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/msw/control.h | 23 ++- include/wx/msw/frame.h | 4 - include/wx/msw/private.h | 4 +- include/wx/msw/setup0.h | 136 ++++--------- include/wx/msw/toplevel.h | 18 ++ include/wx/msw/window.h | 38 +++- include/wx/msw/winundef.h | 18 ++ include/wx/window.h | 2 +- src/msw/control.cpp | 2 +- src/msw/dialog.cpp | 78 +------ src/msw/frame.cpp | 102 ---------- src/msw/glcanvas.cpp | 180 ++++++++-------- src/msw/mdi.cpp | 53 ++--- src/msw/nativdlg.cpp | 8 +- src/msw/notebook.cpp | 4 +- src/msw/toplevel.cpp | 225 +++++++++++++++++++- src/msw/window.cpp | 418 ++++++++++++++++---------------------- src/univ/topluniv.cpp | 11 +- 18 files changed, 619 insertions(+), 705 deletions(-) diff --git a/include/wx/msw/control.h b/include/wx/msw/control.h index 1c984d20b0..dc66995be7 100644 --- a/include/wx/msw/control.h +++ b/include/wx/msw/control.h @@ -92,20 +92,21 @@ protected: virtual wxSize DoGetBestSize() const; - // create the control of the given class with the given style, returns FALSE - // if creation failed + // create the control of the given class with the given style (combination + // of WS_XXX flags, i.e. Windows style, not wxWindows one), returns + // FALSE if creation failed // // All parameters except classname and style are optional, if the - // size/position are not given, they should be set later with SetSize() and, - // label (the title of the window), of course, is left empty. The extended - // style is determined from the style and the app 3D settings automatically - // if it's not specified explicitly. + // size/position are not given, they should be set later with SetSize() + // and, label (the title of the window), of course, is left empty. The + // extended style is determined from the style and the app 3D settings + // automatically if it's not specified explicitly. bool MSWCreateControl(const wxChar *classname, - WXDWORD style, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - const wxString& label = wxEmptyString, - WXDWORD exstyle = (WXDWORD)-1); + WXDWORD style, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + const wxString& label = wxEmptyString, + WXDWORD exstyle = (WXDWORD)-1); // determine the extended styles combination for this window (may slightly // modify style parameter, this is why it's non const) diff --git a/include/wx/msw/frame.h b/include/wx/msw/frame.h index a6215ab037..2b63cc5149 100644 --- a/include/wx/msw/frame.h +++ b/include/wx/msw/frame.h @@ -93,10 +93,6 @@ public: bool HandleCommand(WXWORD id, WXWORD cmd, WXHWND control); bool HandleMenuSelect(WXWORD nItem, WXWORD nFlags, WXHMENU hMenu); - bool MSWCreate(int id, wxWindow *parent, const wxChar *wclass, - wxWindow *wx_win, const wxChar *title, - int x, int y, int width, int height, long style); - // tooltip management #if wxUSE_TOOLTIPS WXHWND GetToolTipCtrl() const { return m_hwndToolTip; } diff --git a/include/wx/msw/private.h b/include/wx/msw/private.h index 176aebd123..dffa2e32af 100644 --- a/include/wx/msw/private.h +++ b/include/wx/msw/private.h @@ -21,8 +21,8 @@ #include #ifdef __WXMICROWIN__ -/* Extra prototypes and symbols not defined by MicroWindows */ -#include "wx/msw/microwin.h" + // Extra prototypes and symbols not defined by MicroWindows + #include "wx/msw/microwin.h" #endif // undefine conflicting symbols which were defined in windows.h diff --git a/include/wx/msw/setup0.h b/include/wx/msw/setup0.h index 0021a80906..640a8fc72e 100644 --- a/include/wx/msw/setup0.h +++ b/include/wx/msw/setup0.h @@ -36,22 +36,6 @@ // so there is little advantage to setting it to 1. #define WXWIN_COMPATIBILITY 0 -// This setting determines the compatibility with 2.0 API: set it to 1 to -// enable it -// -// Default is 0. -// -// Recommended setting: 0 (please update your code instead!) -#define WXWIN_COMPATIBILITY_2 0 - -// This setting determines the compatibility with 2.0 API: set it to 1 to -// enable it -// -// Default is 0. -// -// Recommended setting: 0 (please update your code instead!) -#define WXWIN_COMPATIBILITY_2_2 0 - // in wxMSW version 2.1.11 and earlier, wxIcon always derives from wxBitmap, // but this is very dangerous because you can mistakenly pass an icon instead // of a bitmap to a function taking "const wxBitmap&" - which will *not* work @@ -104,7 +88,7 @@ // Default is 1. // // Recommended setting: 1 but see comment above -#define wxUSE_DEBUG_CONTEXT 1 +#define wxUSE_DEBUG_CONTEXT 0 // If 1, enables debugging versions of wxObject::new and wxObject::delete *IF* // __WXDEBUG__ is also defined. @@ -115,7 +99,7 @@ // Default is 1 // // Recommended setting: 1 but see comment in the beginning of this section -#define wxUSE_MEMORY_TRACING 1 +#define wxUSE_MEMORY_TRACING 0 // In debug mode, cause new and delete to be redefined globally. // If this causes problems (e.g. link errors), set this to 0. @@ -124,7 +108,7 @@ // Default is 1 // // Recommended setting: 1 but see comment in the beginning of this section -#define wxUSE_GLOBAL_MEMORY_OPERATORS 1 +#define wxUSE_GLOBAL_MEMORY_OPERATORS 0 // In debug mode, causes new to be defined to be WXDEBUG_NEW (see object.h). If // this causes problems (e.g. link errors), set this to 0. You may need to set @@ -134,7 +118,7 @@ // Default is 1 // // Recommended setting: 1 but see comment in the beginning of this section -#define wxUSE_DEBUG_NEW_ALWAYS 1 +#define wxUSE_DEBUG_NEW_ALWAYS 0 // wxHandleFatalExceptions() may be used to catch the program faults at run // time and, instead of terminating the program with a usual GPF message box, @@ -193,20 +177,12 @@ // Recommended setting: 1 (always) #define wxUSE_LOG 1 -// Support for command line parsing using wxCmdLineParser class. -// -// Default is 1 -// -// Recommended setting: 1 (can be set to 0 if you don't use the cmd line) -#define wxUSE_CMDLINE_PARSER 1 - -// Recommended setting: 1 #define wxUSE_LOGWINDOW 1 -// Recommended setting: 1 +// Recommended setting: 1 (always) #define wxUSE_LOGGUI 1 -// Recommended setting: 1 +// Recommended setting: 1 (always) #define wxUSE_LOG_DIALOG 1 // Support for multithreaded applications: if 1, compile in thread classes @@ -264,7 +240,7 @@ // i18n support: _() macro, wxLocale class. Requires wxTextFile. #define wxUSE_INTL 1 -// Set wxUSE_DATETIME to 1 to compile the wxDateTime and related classes which +// Set wxUSE_TIMEDATE to 1 to compile the wxDateTime and related classes which // allow to manipulate dates, times and time intervals. wxDateTime replaces the // old wxTime and wxDate classes which are still provided for backwards // compatibility (and implemented in terms of wxDateTime). @@ -276,20 +252,9 @@ // // Requires: wxUSE_LONGLONG // -// Default is 1 -// // Recommended setting: 1 #define wxUSE_DATETIME 1 -// wxUSE_TIMEDATE enables compilation of the old wxDate and wxTime classes (not -// the same as wxDateTime!). These classes are obsolete and shouldn't be used -// in new code -// -// Default is 0 -// -// Recommended setting: 0 unless you have legacy code which uses these classes -#define wxUSE_TIMEDATE 0 - // Set wxUSE_TIMER to 1 to compile wxTimer class // // Default is 1 @@ -365,6 +330,8 @@ // wxUSE_LIBPNG. #define wxUSE_ZLIB 1 +#define wxUSE_REGEX 1 + // If enabled, the code written by Apple will be used to write, in a portable // way, float on the disk. See extended.c for the license which is different // from wxWindows one. @@ -383,22 +350,6 @@ // wxMimeTypesManager class #define wxUSE_MIMETYPE 1 -// wxSystemOptions class -#define wxUSE_SYSTEM_OPTIONS 1 - -// Support for regular expression matching via wxRegEx class: enable this to -// use POSIX regular expressions in your code. You need to compile regex -// library from src/regex to use it under Windows. -// -// Default is 0 -// -// Recommended setting: 1 if your compiler supports it, if it doesn't please -// contribute us a makefile for src/regex for it -#define wxUSE_REGEX 0 - -// wxWave class -#define wxUSE_WAVE 1 - // ---------------------------------------------------------------------------- // Individual GUI controls // ---------------------------------------------------------------------------- @@ -576,9 +527,6 @@ // wxValidator class and related methods #define wxUSE_VALIDATORS 1 -// wxDC cacheing implementation -#define wxUSE_DC_CACHEING 1 - // ---------------------------------------------------------------------------- // common dialogs // ---------------------------------------------------------------------------- @@ -601,29 +549,6 @@ // Recommended setting: 1 (unless it really doesn't work) #define wxUSE_COMMON_DIALOGS 1 -// wxBusyInfo displays window with message when app is busy. Works in same way -// as wxBusyCursor -#define wxUSE_BUSYINFO 1 - -// Use single/multiple choice dialogs. -// -// Default is 1 -// -// Recommended setting: 1 (used in the library itself) -#define wxUSE_CHOICEDLG 1 - -// Use colour picker dialog -// -// Default is 1 -// -// Recommended setting: 1 -#define wxUSE_COLOURDLG 1 - -// wxDirDlg class for getting a directory name from user -#define wxUSE_DIRDLG 1 - -// TODO: setting to choose the generic or native one - // Use file open/save dialogs. // // Default is 1 @@ -631,11 +556,6 @@ // Recommended setting: 1 (used in many places in the library itself) #define wxUSE_FILEDLG 1 -// Use find/replace dialogs. -// -// Default is 1 -// -// Recommended setting: 1 (but may be safely set to 0) #define wxUSE_FINDREPLDLG 1 // Use font picker dialog @@ -652,22 +572,38 @@ // Recommended setting: 1 (used in the library itself) #define wxUSE_MSGDLG 1 -// progress dialog class for lengthy operations -#define wxUSE_PROGRESSDLG 1 +// Use single/multiple choice dialogs. +// +// Default is 1 +// +// Recommended setting: 1 (used in the library itself) +#define wxUSE_CHOICEDLG 1 -// support for startup tips (wxShowTip &c) -#define wxUSE_STARTUP_TIPS 1 +// Use colour picker dialog +// +// Default is 1 +// +// Recommended setting: 1 +#define wxUSE_COLOURDLG 1 // text entry dialog and wxGetTextFromUser function #define wxUSE_TEXTDLG 1 -// number entry dialog #define wxUSE_NUMBERDLG 1 -// splash screen class -#define wxUSE_SPLASH 1 +// progress dialog class for lengthy operations +#define wxUSE_PROGRESSDLG 1 + +// wxBusyInfo displays window with message when app is busy. Works in same way +// as wxBusyCursor +#define wxUSE_BUSYINFO 1 + +// wxDirDlg class for getting a directory name from user +#define wxUSE_DIRDLG 1 + +// support for startup tips (wxShowTip &c) +#define wxUSE_STARTUP_TIPS 1 -// wizards #define wxUSE_WIZARDDLG 1 // ---------------------------------------------------------------------------- @@ -768,10 +704,7 @@ // 0 for no help facility #define wxUSE_MS_HTML_HELP 0 // 0 for no MS HTML Help - -// Use wxHTML-based help controller? #define wxUSE_WXHTML_HELP 1 - #define wxUSE_RESOURCES 1 // 0 for no wxGetResource/wxWriteResource #define wxUSE_CONSTRAINTS 1 @@ -890,7 +823,6 @@ // Set to 1 for XPM format support #define wxUSE_XPM 1 -// Set to 1 to compile in wxPalette class #define wxUSE_PALETTE 1 // ---------------------------------------------------------------------------- @@ -1176,7 +1108,7 @@ // you need to modify setup.h and rebuild everything // ---------------------------------------------------------------------------- -#if wxUSE_DATETIME && !wxUSE_LONGLONG +#if wxUSE_TIMEDATE && !wxUSE_LONGLONG #error wxDateTime requires wxLongLong #endif diff --git a/include/wx/msw/toplevel.h b/include/wx/msw/toplevel.h index ce10f8e628..98ae4f2594 100644 --- a/include/wx/msw/toplevel.h +++ b/include/wx/msw/toplevel.h @@ -70,12 +70,30 @@ protected: // common part of all ctors void Init(); + // create a new frame, return FALSE if it couldn't be created + bool CreateFrame(const wxString& title, + const wxPoint& pos, + const wxSize& size); + + // create a new dialog using the given dialog template from resources, + // return FALSE if it couldn't be created + bool CreateDialog(const wxChar *dlgTemplate, + const wxString& title, + const wxPoint& pos, + const wxSize& size); + // common part of Iconize(), Maximize() and Restore() void DoShowWindow(int nShowCmd); // implement the geometry-related methods for a top level window virtual void DoSetClientSize(int width, int height); + // get the MSW window flags corresponding to wxWindows ones + // + // the functions returns the flags (WS_XXX) directly and puts the ext + // (WS_EX_XXX) flags into the provided pointer if not NULL + long MSWGetCreateWindowFlags(long *exflags) const; + // is the frame currently iconized? bool m_iconized; diff --git a/include/wx/msw/window.h b/include/wx/msw/window.h index 65fd4641b6..4e9bc75585 100644 --- a/include/wx/msw/window.h +++ b/include/wx/msw/window.h @@ -217,16 +217,26 @@ public: // MSW only: TRUE if this control is part of the main control virtual bool ContainsHWND(WXHWND WXUNUSED(hWnd)) const { return FALSE; }; - // returns TRUE if the window has been created - bool MSWCreate(int id, - wxWindow *parent, - const wxChar *wclass, - wxWindow *wx_win, - const wxChar *title, - int x, int y, int width, int height, - WXDWORD style, - const wxChar *dialog_template = NULL, + // translate wxWindows coords into Windows ones suitable to be passed to + // ::CreateWindow() + // + // returns TRUE if non default coords are returned, FALSE otherwise + bool MSWGetCreateWindowCoords(const wxPoint& pos, + const wxSize& size, + int& x, int& y, + int& w, int& h) const; + + // creates the window of specified Windows class with given style, extended + // style, title and geometry (default values + // + // returns TRUE if the window has been created, FALSE if creation failed + bool MSWCreate(const wxChar *wclass, + const wxChar *title = NULL, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + WXDWORD style = 0, WXDWORD exendedStyle = 0); + virtual bool MSWCommand(WXUINT param, WXWORD id); #if WXWIN_COMPATIBILITY @@ -463,5 +473,15 @@ private: WXDLLEXPORT int wxCharCodeMSWToWX(int keySym); WXDLLEXPORT int wxCharCodeWXToMSW(int id, bool *IsVirtual); +// window creation helper class: before creating a new HWND, instantiate an +// object of this class on stack - this allows to process the messages sent to +// the window even before CreateWindow() returns +class wxWindowCreationHook +{ +public: + wxWindowCreationHook(wxWindowMSW *winBeingCreated); + ~wxWindowCreationHook(); +}; + #endif // _WX_WINDOW_H_ diff --git a/include/wx/msw/winundef.h b/include/wx/msw/winundef.h index 3e6653c834..87c9c72f53 100644 --- a/include/wx/msw/winundef.h +++ b/include/wx/msw/winundef.h @@ -25,6 +25,24 @@ // elsewhere because the functions, unlike the macros, respect the scope. // ---------------------------------------------------------------------------- +// CreateDialog + +#ifdef CreateDialog + #undef CreateDialog + + inline HWND CreateDialog(HINSTANCE hInstance, + LPCTSTR pTemplate, + HWND hwndParent, + DLGPROC pDlgProc) + { + #ifdef _UNICODE + return CreateDialogW(hInstance, pTemplate, hwndParent, pDlgProc); + #else + return CreateDialogA(hInstance, pTemplate, hwndParent, pDlgProc); + #endif + } +#endif + // GetCharWidth #ifdef GetCharWidth diff --git a/include/wx/window.h b/include/wx/window.h index 734e518ca7..9f43aa71c9 100644 --- a/include/wx/window.h +++ b/include/wx/window.h @@ -975,7 +975,7 @@ protected: virtual void DoSetClientData( void *data ); virtual void *DoGetClientData() const; - + // Makes an adjustment to the window position (for example, a frame that has // a toolbar that it manages itself). virtual void AdjustForParentClientOrigin(int& x, int& y, int sizeFlags); diff --git a/src/msw/control.cpp b/src/msw/control.cpp index 4ba67fba6e..8400508235 100644 --- a/src/msw/control.cpp +++ b/src/msw/control.cpp @@ -128,7 +128,7 @@ bool wxControl::MSWCreateControl(const wxChar *classname, } #endif // wxUSE_CTL3D - // subclass again for purposes of dialog editing mode + // install wxWindows window proc for this window SubclassWin(m_hWnd); // controls use the same font and colours as their parent dialog by default diff --git a/src/msw/dialog.cpp b/src/msw/dialog.cpp index d612844e9c..5f70961052 100644 --- a/src/msw/dialog.cpp +++ b/src/msw/dialog.cpp @@ -113,86 +113,14 @@ bool wxDialog::Create(wxWindow *parent, SetExtraStyle(GetExtraStyle() | wxTOPLEVEL_EX_DIALOG); - if ( !wxTopLevelWindow::Create(parent, id, title, pos, size, style, name) ) - return FALSE; - + // save focus before doing anything which can potentially change it m_oldFocus = FindFocus(); - int x = pos.x; - int y = pos.y; - int width = size.x; - int height = size.y; - - if (x < 0) - x = wxDIALOG_DEFAULT_X; - if (y < 0) - y = wxDIALOG_DEFAULT_Y; - - if (width < 0) - width = wxDIALOG_DEFAULT_WIDTH; - if (height < 0) - height = wxDIALOG_DEFAULT_HEIGHT; - // All dialogs should really have this style - m_windowStyle |= wxTAB_TRAVERSAL; - - WXDWORD extendedStyle = MakeExtendedStyle(m_windowStyle); - if (m_windowStyle & wxSTAY_ON_TOP) - extendedStyle |= WS_EX_TOPMOST; - -#ifndef __WIN16__ - if (m_exStyle & wxDIALOG_EX_CONTEXTHELP) - extendedStyle |= WS_EX_CONTEXTHELP; -#endif - - // Allows creation of dialogs with & without captions under MSWindows, - // resizeable or not (but a resizeable dialog always has caption - - // otherwise it would look too strange) - const wxChar *dlg; - if ( style & wxRESIZE_BORDER ) - dlg = wxT("wxResizeableDialog"); - else if ( style & wxCAPTION ) - dlg = wxT("wxCaptionDialog"); - else - dlg = wxT("wxNoCaptionDialog"); - -#ifdef __WXMICROWIN__ - extern const wxChar *wxFrameClassName; - - int msflags = WS_OVERLAPPED|WS_POPUP; - if (style & wxCAPTION) - msflags |= WS_CAPTION; - if (style & wxCLIP_CHILDREN) - msflags |= WS_CLIPCHILDREN; - if ((style & wxTHICK_FRAME) == 0) - msflags |= WS_BORDER; - MSWCreate(m_windowId, parent, wxFrameClassName, this, NULL, - x, y, width, height, - msflags, - NULL, - extendedStyle); - -#else - MSWCreate(m_windowId, parent, NULL, this, NULL, - x, y, width, height, - 0, // style is not used if we have dlg template - dlg, - extendedStyle); -#endif - HWND hwnd = (HWND)GetHWND(); - - if ( !hwnd ) - { - wxFAIL_MSG(_("Failed to create dialog. You probably forgot to include wx/msw/wx.rc in your resources.")); + style |= wxTAB_TRAVERSAL; + if ( !wxTopLevelWindow::Create(parent, id, title, pos, size, style, name) ) return FALSE; - } - -#ifndef __WXMICROWIN__ - SubclassWin(GetHWND()); -#endif - - SetWindowText(hwnd, title); return TRUE; } diff --git a/src/msw/frame.cpp b/src/msw/frame.cpp index 13946cb04e..abb54f3ef5 100644 --- a/src/msw/frame.cpp +++ b/src/msw/frame.cpp @@ -119,9 +119,6 @@ void wxFrameMSW::Init() m_fsIsShowing = FALSE; m_winLastFocused = (wxWindow *)NULL; - - // unlike (almost?) all other windows, frames are created hidden - m_isShown = FALSE; } bool wxFrameMSW::Create(wxWindow *parent, @@ -135,13 +132,6 @@ bool wxFrameMSW::Create(wxWindow *parent, if ( !wxTopLevelWindow::Create(parent, id, title, pos, size, style, name) ) return FALSE; - // the frame must have NULL parent HWND or it would be always on top of its - // parent which is not what we usually want (in fact, we only want it for - // frames with the special wxFRAME_TOOL_WINDOW style handled elsewhere) - if ( !MSWCreate(m_windowId, NULL, wxFrameClassName, this, title, - pos.x, pos.y, size.x, size.y, style) ) - return FALSE; - SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE)); wxModelessWindows.Append(this); @@ -469,98 +459,6 @@ bool wxFrameMSW::ShowFullScreen(bool show, long style) } } -/* - * Frame window - * - */ - -bool wxFrameMSW::MSWCreate(int id, wxWindow *parent, const wxChar *wclass, wxWindow *wx_win, const wxChar *title, - int x, int y, int width, int height, long style) - -{ - // If child windows aren't properly drawn initially, WS_CLIPCHILDREN - // could be the culprit. But without it, you can get a lot of flicker. - - DWORD msflags = 0; - if ( style & wxCAPTION ) - { - if ( style & wxFRAME_TOOL_WINDOW ) - msflags |= WS_POPUPWINDOW; - else - msflags |= WS_OVERLAPPED; - } - else - { - msflags |= WS_POPUP; - } - - if (style & wxMINIMIZE_BOX) - msflags |= WS_MINIMIZEBOX; - if (style & wxMAXIMIZE_BOX) - msflags |= WS_MAXIMIZEBOX; - if (style & wxTHICK_FRAME) - msflags |= WS_THICKFRAME; - if (style & wxSYSTEM_MENU) - msflags |= WS_SYSMENU; - if ( style & wxMINIMIZE ) - msflags |= WS_MINIMIZE; - if (style & wxMAXIMIZE) - msflags |= WS_MAXIMIZE; - if (style & wxCAPTION) - msflags |= WS_CAPTION; - if (style & wxCLIP_CHILDREN) - msflags |= WS_CLIPCHILDREN; - - // Keep this in wxFrameMSW because it saves recoding this function - // in wxTinyFrame -#if wxUSE_ITSY_BITSY && !defined(__WIN32__) - if (style & wxTINY_CAPTION_VERT) - msflags |= IBS_VERTCAPTION; - if (style & wxTINY_CAPTION_HORIZ) - msflags |= IBS_HORZCAPTION; -#else - if (style & wxTINY_CAPTION_VERT) - msflags |= WS_CAPTION; - if (style & wxTINY_CAPTION_HORIZ) - msflags |= WS_CAPTION; -#endif - if ((style & wxTHICK_FRAME) == 0) - msflags |= WS_BORDER; - - WXDWORD extendedStyle = MakeExtendedStyle(style); - - // make all frames appear in the win9x shell taskbar unless - // wxFRAME_TOOL_WINDOW or wxFRAME_NO_TASKBAR is given - without giving them - // WS_EX_APPWINDOW style, the child (i.e. owned) frames wouldn't appear in it -#if !defined(__WIN16__) && !defined(__SC__) - if ( (style & wxFRAME_TOOL_WINDOW) || - (style & wxFRAME_NO_TASKBAR) ) - extendedStyle |= WS_EX_TOOLWINDOW; - else if ( !(style & wxFRAME_NO_TASKBAR) ) - extendedStyle |= WS_EX_APPWINDOW; -#endif - - if (style & wxSTAY_ON_TOP) - extendedStyle |= WS_EX_TOPMOST; - -#ifndef __WIN16__ - if (m_exStyle & wxFRAME_EX_CONTEXTHELP) - extendedStyle |= WS_EX_CONTEXTHELP; -#endif - - m_iconized = FALSE; - if ( !wxWindow::MSWCreate(id, parent, wclass, wx_win, title, x, y, width, height, - msflags, NULL, extendedStyle) ) - return FALSE; - - // Seems to be necessary if we use WS_POPUP - // style instead of WS_OVERLAPPED - if (width > -1 && height > -1) - ::PostMessage(GetHwnd(), WM_SIZE, SIZE_RESTORED, MAKELPARAM(width, height)); - - return TRUE; -} - // Default activation behaviour - set the focus for the first child // subwindow found. void wxFrameMSW::OnActivate(wxActivateEvent& event) diff --git a/src/msw/glcanvas.cpp b/src/msw/glcanvas.cpp index 6439927730..e73a9a9181 100644 --- a/src/msw/glcanvas.cpp +++ b/src/msw/glcanvas.cpp @@ -6,7 +6,7 @@ // Created: 04/01/98 // RCS-ID: $Id$ // Copyright: (c) Julian Smart -// Licence: wxWindows licence +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// #ifdef __GNUG__ @@ -33,7 +33,8 @@ #include -wxChar wxGLCanvasClassName[] = wxT("wxGLCanvasClass"); +static const wxChar *wxGLCanvasClassName = wxT("wxGLCanvasClass"); +static const wxChar *wxGLCanvasClassNameNoRedraw = wxT("wxGLCanvasClassNR"); LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); @@ -213,25 +214,16 @@ wxGLCanvas::~wxGLCanvas() ::ReleaseDC((HWND) GetHWND(), (HDC) m_hDC); } -// Replaces wxWindow::Create functionality, since we need to use a different window class -bool wxGLCanvas::Create(wxWindow *parent, wxWindowID id, - const wxPoint& pos, const wxSize& size, long style, const wxString& name) +// Replaces wxWindow::Create functionality, since we need to use a different +// window class +bool wxGLCanvas::Create(wxWindow *parent, + wxWindowID id, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString& name) { - /* - Suggestion from Kelly Brock (not yet implemented): - - OpenGL corruption fix is simple assuming it doesn't screw anything else - up. Add the following line to the top of the create function: - - wxSize parentSize = GetClientSize(); - - All locations within the function that use 'size' are changed to - 'parentSize'. - The above corrects the initial display corruption with the GeForce and - TNT2, not sure about other NVidia cards yet. - */ - - static bool registeredGLCanvasClass = FALSE; + static bool s_registeredGLCanvasClass = FALSE; // We have to register a special window class because we need // the CS_OWNDC style for GLCanvas. @@ -253,12 +245,10 @@ bool wxGLCanvas::Create(wxWindow *parent, wxWindowID id, only way to prevent this, the only reliable means, is to set CS_OWNDC." */ - if (!registeredGLCanvasClass) + if (!s_registeredGLCanvasClass) { WNDCLASS wndclass; - static const long styleNormal = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC; - // the fields which are common to all classes wndclass.lpfnWndProc = (WNDPROC)wxWndProc; wndclass.cbClsExtra = 0; @@ -271,15 +261,29 @@ bool wxGLCanvas::Create(wxWindow *parent, wxWindowID id, // Register the GLCanvas class name wndclass.hbrBackground = (HBRUSH)NULL; wndclass.lpszClassName = wxGLCanvasClassName; - wndclass.style = styleNormal; + wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC; - if ( !RegisterClass(&wndclass) ) + if ( !::RegisterClass(&wndclass) ) { wxLogLastError(wxT("RegisterClass(wxGLCanvasClass)")); return FALSE; } - registeredGLCanvasClass = TRUE; + // Register the GLCanvas class name for windows which don't do full repaint + // on resize + wndclass.lpszClassName = wxGLCanvasClassNameNoRedraw; + wndclass.style &= ~(CS_HREDRAW | CS_VREDRAW); + + if ( !::RegisterClass(&wndclass) ) + { + wxLogLastError(wxT("RegisterClass(wxGLCanvasClassNameNoRedraw)")); + + ::UnregisterClass(wxGLCanvasClass, wxhInstance()); + + return FALSE; + } + + s_registeredGLCanvasClass = TRUE; } wxCHECK_MSG( parent, FALSE, wxT("can't create wxWindow without parent") ); @@ -302,10 +306,7 @@ bool wxGLCanvas::Create(wxWindow *parent, wxWindowID id, books that contain the wgl function descriptions. */ - msflags |= WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS; - // if ( style & wxCLIP_CHILDREN ) - // msflags |= WS_CLIPCHILDREN; - msflags |= WS_CLIPCHILDREN; + msflags |= WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN; bool want3D; WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D); @@ -326,12 +327,7 @@ bool wxGLCanvas::Create(wxWindow *parent, wxWindowID id, DLGC_WANTTAB | DLGC_WANTMESSAGE; } - MSWCreate(m_windowId, parent, wxGLCanvasClassName, this, NULL, - pos.x, pos.y, - WidthDefault(size.x), HeightDefault(size.y), - msflags, NULL, exStyle); - - return TRUE; + return MSWCreate(wxGLCanvasClassName, NULL, pos, size, msflags, exStyle); } static void AdjustPFDForAttributes(PIXELFORMATDESCRIPTOR& pfd, int *attribList) @@ -341,7 +337,7 @@ static void AdjustPFDForAttributes(PIXELFORMATDESCRIPTOR& pfd, int *attribList) pfd.iPixelType = PFD_TYPE_COLORINDEX; pfd.cColorBits = 0; int arg=0; - + while( (attribList[arg]!=0) ) { switch( attribList[arg++] ) @@ -385,10 +381,10 @@ static void AdjustPFDForAttributes(PIXELFORMATDESCRIPTOR& pfd, int *attribList) // doesn't count in cColorBits pfd.cAlphaBits = attribList[arg++]; break; - case WX_GL_DEPTH_SIZE: + case WX_GL_DEPTH_SIZE: pfd.cDepthBits = attribList[arg++]; break; - case WX_GL_STENCIL_SIZE: + case WX_GL_STENCIL_SIZE: pfd.cStencilBits = attribList[arg++]; break; case WX_GL_MIN_ACCUM_RED: @@ -414,25 +410,25 @@ void wxGLCanvas::SetupPixelFormat(int *attribList) // (HDC hDC) { int pixelFormat; PIXELFORMATDESCRIPTOR pfd = { - sizeof(PIXELFORMATDESCRIPTOR), /* size */ - 1, /* version */ - PFD_SUPPORT_OPENGL | - PFD_DRAW_TO_WINDOW | - PFD_DOUBLEBUFFER, /* support double-buffering */ - PFD_TYPE_RGBA, /* color type */ - 16, /* prefered color depth */ - 0, 0, 0, 0, 0, 0, /* color bits (ignored) */ - 0, /* no alpha buffer */ - 0, /* alpha bits (ignored) */ - 0, /* no accumulation buffer */ - 0, 0, 0, 0, /* accum bits (ignored) */ - 16, /* depth buffer */ - 0, /* no stencil buffer */ - 0, /* no auxiliary buffers */ - PFD_MAIN_PLANE, /* main layer */ - 0, /* reserved */ - 0, 0, 0, /* no layer, visible, damage masks */ - }; + sizeof(PIXELFORMATDESCRIPTOR), /* size */ + 1, /* version */ + PFD_SUPPORT_OPENGL | + PFD_DRAW_TO_WINDOW | + PFD_DOUBLEBUFFER, /* support double-buffering */ + PFD_TYPE_RGBA, /* color type */ + 16, /* prefered color depth */ + 0, 0, 0, 0, 0, 0, /* color bits (ignored) */ + 0, /* no alpha buffer */ + 0, /* alpha bits (ignored) */ + 0, /* no accumulation buffer */ + 0, 0, 0, 0, /* accum bits (ignored) */ + 16, /* depth buffer */ + 0, /* no stencil buffer */ + 0, /* no auxiliary buffers */ + PFD_MAIN_PLANE, /* main layer */ + 0, /* reserved */ + 0, 0, 0, /* no layer, visible, damage masks */ + }; AdjustPFDForAttributes(pfd, attribList); @@ -459,7 +455,7 @@ void wxGLCanvas::SetupPalette(const wxPalette& palette) } else { - return; + return; } m_palette = palette; @@ -493,20 +489,20 @@ wxPalette wxGLCanvas::CreateDefaultPalette() /* build a simple RGB color palette */ { - int redMask = (1 << pfd.cRedBits) - 1; - int greenMask = (1 << pfd.cGreenBits) - 1; - int blueMask = (1 << pfd.cBlueBits) - 1; - int i; - - for (i=0; ipalPalEntry[i].peRed = - (((i >> pfd.cRedShift) & redMask) * 255) / redMask; - pPal->palPalEntry[i].peGreen = - (((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask; - pPal->palPalEntry[i].peBlue = - (((i >> pfd.cBlueShift) & blueMask) * 255) / blueMask; - pPal->palPalEntry[i].peFlags = 0; - } + int redMask = (1 << pfd.cRedBits) - 1; + int greenMask = (1 << pfd.cGreenBits) - 1; + int blueMask = (1 << pfd.cBlueBits) - 1; + int i; + + for (i=0; ipalPalEntry[i].peRed = + (((i >> pfd.cRedShift) & redMask) * 255) / redMask; + pPal->palPalEntry[i].peGreen = + (((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask; + pPal->palPalEntry[i].peBlue = + (((i >> pfd.cBlueShift) & blueMask) * 255) / blueMask; + pPal->palPalEntry[i].peFlags = 0; + } } HPALETTE hPalette = CreatePalette(pPal); @@ -727,25 +723,25 @@ bool wxGLApp::InitGLVisual(int *attribList) { int pixelFormat; PIXELFORMATDESCRIPTOR pfd = { - sizeof(PIXELFORMATDESCRIPTOR), /* size */ - 1, /* version */ - PFD_SUPPORT_OPENGL | - PFD_DRAW_TO_WINDOW | - PFD_DOUBLEBUFFER, /* support double-buffering */ - PFD_TYPE_RGBA, /* color type */ - 16, /* prefered color depth */ - 0, 0, 0, 0, 0, 0, /* color bits (ignored) */ - 0, /* no alpha buffer */ - 0, /* alpha bits (ignored) */ - 0, /* no accumulation buffer */ - 0, 0, 0, 0, /* accum bits (ignored) */ - 16, /* depth buffer */ - 0, /* no stencil buffer */ - 0, /* no auxiliary buffers */ - PFD_MAIN_PLANE, /* main layer */ - 0, /* reserved */ - 0, 0, 0, /* no layer, visible, damage masks */ - }; + sizeof(PIXELFORMATDESCRIPTOR), /* size */ + 1, /* version */ + PFD_SUPPORT_OPENGL | + PFD_DRAW_TO_WINDOW | + PFD_DOUBLEBUFFER, /* support double-buffering */ + PFD_TYPE_RGBA, /* color type */ + 16, /* prefered color depth */ + 0, 0, 0, 0, 0, 0, /* color bits (ignored) */ + 0, /* no alpha buffer */ + 0, /* alpha bits (ignored) */ + 0, /* no accumulation buffer */ + 0, 0, 0, 0, /* accum bits (ignored) */ + 16, /* depth buffer */ + 0, /* no stencil buffer */ + 0, /* no auxiliary buffers */ + PFD_MAIN_PLANE, /* main layer */ + 0, /* reserved */ + 0, 0, 0, /* no layer, visible, damage masks */ + }; AdjustPFDForAttributes(pfd, attribList); diff --git a/src/msw/mdi.cpp b/src/msw/mdi.cpp index c71a0a8d37..9edbdbf703 100644 --- a/src/msw/mdi.cpp +++ b/src/msw/mdi.cpp @@ -67,8 +67,6 @@ extern const wxChar *wxMDIFrameClassName; // from app.cpp extern const wxChar *wxMDIChildFrameClassName; extern const wxChar *wxMDIChildFrameClassNameNoRedraw; -extern wxWindow *wxWndHook; // from window.cpp - extern void wxAssociateWinWithHandle(HWND hWnd, wxWindow *win); extern void wxRemoveHandleAssociation(wxWindow *win); @@ -192,44 +190,22 @@ bool wxMDIParentFrame::Create(wxWindow *parent, SetName(name); m_windowStyle = style; - if (parent) parent->AddChild(this); + if ( parent ) + parent->AddChild(this); if ( id > -1 ) m_windowId = id; else - m_windowId = (int)NewControlId(); + m_windowId = NewControlId(); - int x = pos.x; - int y = pos.y; - int width = size.x; - int height = size.y; + long exflags; + long msflags = MSWGetCreateWindowFlags(&exflags); - DWORD msflags = WS_OVERLAPPED; - if (style & wxMINIMIZE_BOX) - msflags |= WS_MINIMIZEBOX; - if (style & wxMAXIMIZE_BOX) - msflags |= WS_MAXIMIZEBOX; - if (style & wxTHICK_FRAME) - msflags |= WS_THICKFRAME; - if (style & wxSYSTEM_MENU) - msflags |= WS_SYSMENU; - if ((style & wxMINIMIZE) || (style & wxICONIZE)) - msflags |= WS_MINIMIZE; - if (style & wxMAXIMIZE) - msflags |= WS_MAXIMIZE; - if (style & wxCAPTION) - msflags |= WS_CAPTION; - - if (style & wxCLIP_CHILDREN) - msflags |= WS_CLIPCHILDREN; - - if ( !wxWindow::MSWCreate(m_windowId, - parent, - wxMDIFrameClassName, - this, + if ( !wxWindow::MSWCreate(wxMDIFrameClassName, title, - x, y, width, height, - msflags) ) + pos, size, + msflags, + exflags) ) { return FALSE; } @@ -662,8 +638,6 @@ bool wxMDIChildFrame::Create(wxMDIParentFrame *parent, parent->AddChild(this); } - wxWndHook = this; - int x = pos.x; int y = pos.y; int width = size.x; @@ -716,15 +690,13 @@ bool wxMDIChildFrame::Create(wxMDIParentFrame *parent, mcs.lParam = 0; + wxWindowCreationHook hook(this); + m_hWnd = (WXHWND)::SendMessage(GetWinHwnd(parent->GetClientWindow()), WM_MDICREATE, 0, (LONG)(LPSTR)&mcs); - wxWndHook = NULL; wxAssociateWinWithHandle((HWND) GetHWND(), this); - // VZ: what's this? an act of piracy? - //SetWindowLong(GetHwnd(), 0, (long)this); - wxModelessWindows.Append(this); return TRUE; @@ -1195,7 +1167,7 @@ bool wxMDIClientWindow::CreateClient(wxMDIParentFrame *parent, long style) DWORD exStyle = 0; #endif - wxWndHook = this; + wxWindowCreationHook hook(this); m_hWnd = (WXHWND)::CreateWindowEx ( exStyle, @@ -1215,7 +1187,6 @@ bool wxMDIClientWindow::CreateClient(wxMDIParentFrame *parent, long style) } SubclassWin(m_hWnd); - wxWndHook = NULL; return TRUE; } diff --git a/src/msw/nativdlg.cpp b/src/msw/nativdlg.cpp index d77267951f..85a7920b99 100644 --- a/src/msw/nativdlg.cpp +++ b/src/msw/nativdlg.cpp @@ -43,7 +43,6 @@ // global functions // --------------------------------------------------------------------------- -extern wxWindow *wxWndHook; extern LONG APIENTRY _EXPORT wxDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); @@ -54,12 +53,12 @@ extern LONG APIENTRY _EXPORT wxDlgProc(HWND hWnd, UINT message, bool wxWindow::LoadNativeDialog(wxWindow* parent, wxWindowID& id) { m_windowId = id; - wxWndHook = this; + + wxWindowCreationHook hook(this); m_hWnd = (WXHWND)::CreateDialog((HINSTANCE)wxGetInstance(), MAKEINTRESOURCE(id), parent ? (HWND)parent->GetHWND() : 0, (DLGPROC) wxDlgProc); - wxWndHook = NULL; if ( !m_hWnd ) return FALSE; @@ -93,12 +92,11 @@ bool wxWindow::LoadNativeDialog(wxWindow* parent, const wxString& name) { SetName(name); - wxWndHook = this; + wxWindowCreationHook hook(this); m_hWnd = (WXHWND)::CreateDialog((HINSTANCE) wxGetInstance(), name.c_str(), parent ? (HWND)parent->GetHWND() : 0, (DLGPROC)wxDlgProc); - wxWndHook = NULL; if ( !m_hWnd ) return FALSE; diff --git a/src/msw/notebook.cpp b/src/msw/notebook.cpp index 2022f361f9..a20bd933dd 100644 --- a/src/msw/notebook.cpp +++ b/src/msw/notebook.cpp @@ -172,9 +172,7 @@ bool wxNotebook::Create(wxWindow *parent, tabStyle |= TCS_VERTICAL|TCS_RIGHT; - if ( !MSWCreate(GetId(), GetParent(), WC_TABCONTROL, - this, NULL, pos.x, pos.y, size.x, size.y, - tabStyle, NULL, 0) ) + if ( !MSWCreateControl(WC_TABCONTROL, tabStyle, pos, size) ) { return FALSE; } diff --git a/src/msw/toplevel.cpp b/src/msw/toplevel.cpp index 7b2c2b569c..6724b8d4a6 100644 --- a/src/msw/toplevel.cpp +++ b/src/msw/toplevel.cpp @@ -56,10 +56,31 @@ static inline bool IsZoomed(HWND WXUNUSED(hwnd)) { return FALSE; } // list of all frames and modeless dialogs wxWindowList wxModelessWindows; +// the name of the default wxWindows class +extern const wxChar *wxCanvasClassName; + // ============================================================================ // wxTopLevelWindowMSW implementation // ============================================================================ +// Dialog window proc +LONG APIENTRY _EXPORT +wxDlgProc(HWND WXUNUSED(hWnd), UINT message, WPARAM WXUNUSED(wParam), LPARAM WXUNUSED(lParam)) +{ + if ( message == WM_INITDIALOG ) + { + // for this message, returning TRUE tells system to set focus to the + // first control in the dialog box + return TRUE; + } + else + { + // for all the other ones, FALSE means that we didn't process the + // message + return FALSE; + } +} + // ---------------------------------------------------------------------------- // wxTopLevelWindowMSW creation // ---------------------------------------------------------------------------- @@ -68,6 +89,180 @@ void wxTopLevelWindowMSW::Init() { m_iconized = m_maximizeOnShow = FALSE; + + // unlike (almost?) all other windows, frames are created hidden + m_isShown = FALSE; +} + +long wxTopLevelWindowMSW::MSWGetCreateWindowFlags(long *exflags) const +{ + long style = GetWindowStyle(); + long msflags = 0; + + // first select the kind of window being created + if ( style & wxCAPTION ) + { + if ( style & wxFRAME_TOOL_WINDOW ) + msflags |= WS_POPUPWINDOW; + else + msflags |= WS_OVERLAPPED; + } + else + { + msflags |= WS_POPUP; + } + + // next translate the individual flags + if ( style & wxMINIMIZE_BOX ) + msflags |= WS_MINIMIZEBOX; + if ( style & wxMAXIMIZE_BOX ) + msflags |= WS_MAXIMIZEBOX; + if ( style & wxTHICK_FRAME ) + msflags |= WS_THICKFRAME; + if ( style & wxSYSTEM_MENU ) + msflags |= WS_SYSMENU; + if ( style & wxMINIMIZE ) + msflags |= WS_MINIMIZE; + if ( style & wxMAXIMIZE ) + msflags |= WS_MAXIMIZE; + if ( style & wxCAPTION ) + msflags |= WS_CAPTION; + if ( style & wxCLIP_CHILDREN ) + msflags |= WS_CLIPCHILDREN; + + // Keep this here because it saves recoding this function in wxTinyFrame +#if wxUSE_ITSY_BITSY && !defined(__WIN32__) + if ( style & wxTINY_CAPTION_VERT ) + msflags |= IBS_VERTCAPTION; + if ( style & wxTINY_CAPTION_HORIZ ) + msflags |= IBS_HORZCAPTION; +#else + if ( style & (wxTINY_CAPTION_VERT | wxTINY_CAPTION_HORIZ) ) + msflags |= WS_CAPTION; +#endif + + if ( exflags ) + { + *exflags = MakeExtendedStyle(style); + + // make all frames appear in the win9x shell taskbar unless + // wxFRAME_TOOL_WINDOW or wxFRAME_NO_TASKBAR is given - without giving + // them WS_EX_APPWINDOW style, the child (i.e. owned) frames wouldn't + // appear in it +#if !defined(__WIN16__) && !defined(__SC__) + if ( (style & wxFRAME_TOOL_WINDOW) || (style & wxFRAME_NO_TASKBAR) ) + *exflags |= WS_EX_TOOLWINDOW; + else if ( !(style & wxFRAME_NO_TASKBAR) ) + *exflags |= WS_EX_APPWINDOW; +#endif + + if ( style & wxSTAY_ON_TOP ) + *exflags |= WS_EX_TOPMOST; + +#ifdef __WIN32__ + if ( m_exStyle & wxFRAME_EX_CONTEXTHELP ) + *exflags |= WS_EX_CONTEXTHELP; +#endif // __WIN32__ + } + + return msflags; +} + +bool wxTopLevelWindowMSW::CreateDialog(const wxChar *dlgTemplate, + const wxString& title, + const wxPoint& pos, + const wxSize& size) +{ +#ifdef __WXMICROWIN__ + // no dialogs support under MicroWin yet + return CreateFrame(title, pos, size); +#else // !__WXMICROWIN__ + wxWindow *parent = GetParent(); + + // for the dialogs without wxDIALOG_NO_PARENT style, use the top level + // app window as parent - this avoids creating modal dialogs without + // parent + if ( !parent && !(GetWindowStyleFlag() & wxDIALOG_NO_PARENT) ) + { + parent = wxTheApp->GetTopWindow(); + } + + m_hWnd = (WXHWND)::CreateDialog(wxGetInstance(), + dlgTemplate, + parent ? GetHwndOf(parent) : NULL, + (DLGPROC)wxDlgProc); + + if ( !m_hWnd ) + { + wxFAIL_MSG(_("Did you forget to include wx/msw/wx.rc in your resources?")); + + wxLogSysError(_("Can't create dialog using template '%s'"), dlgTemplate); + + return FALSE; + } + + long exflags; + (void)MSWGetCreateWindowFlags(&exflags); + + if ( exflags ) + { + ::SetWindowLong(GetHwnd(), GWL_EXSTYLE, exflags); + ::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 ( exflags & 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__ + + // move the dialog to its initial position without forcing repainting + int x, y, w, h; + if ( MSWGetCreateWindowCoords(pos, size, x, y, w, h) ) + { + if ( !::MoveWindow(GetHwnd(), x, y, w, h, FALSE) ) + { + wxLogLastError(wxT("MoveWindow")); + } + } + //else: leave it at default position + + if ( !title.empty() ) + { + ::SetWindowText(GetHwnd(), title); + } + + SubclassWin(m_hWnd); + + return TRUE; +#endif // __WXMICROWIN__/!__WXMICROWIN__ +} + +bool wxTopLevelWindowMSW::CreateFrame(const wxString& title, + const wxPoint& pos, + const wxSize& size) +{ + long exflags; + long flags = MSWGetCreateWindowFlags(&exflags); + + return MSWCreate(wxCanvasClassName, title, pos, size, flags, exflags); } bool wxTopLevelWindowMSW::Create(wxWindow *parent, @@ -92,7 +287,35 @@ bool wxTopLevelWindowMSW::Create(wxWindow *parent, if ( parent ) parent->AddChild(this); - return TRUE; + if ( GetExtraStyle() & wxTOPLEVEL_EX_DIALOG ) + { + // TODO: it would be better to construct the dialog template in memory + // during run-time than to rely on the limited number of + // templates in wx.rc because: + // a) you wouldn't have to include wx.rc in all wxWin programs + // (and the number of complaints about it would dtop) + // b) we'd be able to provide more templates simply, i.e. + // we could generate the templates for all style + // combinations + + // we have different dialog templates to allows creation of dialogs + // with & without captions under MSWindows, resizeable or not (but a + // resizeable dialog always has caption - otherwise it would look too + // strange) + const wxChar *dlgTemplate; + if ( style & wxRESIZE_BORDER ) + dlgTemplate = wxT("wxResizeableDialog"); + else if ( style & wxCAPTION ) + dlgTemplate = wxT("wxCaptionDialog"); + else + dlgTemplate = wxT("wxNoCaptionDialog"); + + return CreateDialog(dlgTemplate, title, pos, size); + } + else // !dialog + { + return CreateFrame(title, pos, size); + } } wxTopLevelWindowMSW::~wxTopLevelWindowMSW() diff --git a/src/msw/window.cpp b/src/msw/window.cpp index aa47fded24..5630b738c6 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -433,11 +433,7 @@ bool wxWindowMSW::Create(wxWindow *parent, m_isShown = FALSE; } - return MSWCreate(m_windowId, parent, wxCanvasClassName, - (wxWindow *)this, NULL, - pos.x, pos.y, - WidthDefault(size.x), HeightDefault(size.y), - msflags, NULL, exStyle); + return MSWCreate(wxCanvasClassName, NULL, pos, size, msflags, exStyle); } // --------------------------------------------------------------------------- @@ -986,11 +982,19 @@ void wxWindowMSW::SubclassWin(WXHWND hWnd) wxAssociateWinWithHandle(hwnd, this); - m_oldWndProc = (WXFARPROC) GetWindowLong(hwnd, GWL_WNDPROC); + m_oldWndProc = (WXFARPROC)::GetWindowLong(hwnd, GWL_WNDPROC); - wxASSERT( (WXFARPROC) m_oldWndProc != (WXFARPROC) wxWndProc ); - - SetWindowLong(hwnd, GWL_WNDPROC, (LONG) wxWndProc); + // we don't need to subclass the window of our own class (in the Windows + // sense of the word) + if ( (WXFARPROC) m_oldWndProc != (WXFARPROC) wxWndProc ) + { + ::SetWindowLong(hwnd, GWL_WNDPROC, (LONG) wxWndProc); + } + else + { + // don't bother restoring it neither + m_oldWndProc = NULL; + } } void wxWindowMSW::UnsubclassWin() @@ -1005,11 +1009,15 @@ void wxWindowMSW::UnsubclassWin() wxCHECK_RET( ::IsWindow(hwnd), wxT("invalid HWND in UnsubclassWin") ); - FARPROC farProc = (FARPROC) GetWindowLong(hwnd, GWL_WNDPROC); - if ( (m_oldWndProc != 0) && (farProc != (FARPROC) m_oldWndProc) ) + if ( m_oldWndProc ) { - SetWindowLong(hwnd, GWL_WNDPROC, (LONG) m_oldWndProc); - m_oldWndProc = 0; + FARPROC wndProc = (FARPROC)::GetWindowLong(hwnd, GWL_WNDPROC); + if ( wndProc != (FARPROC) m_oldWndProc ) + { + ::SetWindowLong(hwnd, GWL_WNDPROC, (LONG) m_oldWndProc); + } + + m_oldWndProc = NULL; } } } @@ -1035,6 +1043,7 @@ WXDWORD wxWindowMSW::MakeExtendedStyle(long style, bool eliminateBorders) exStyle |= WS_EX_STATICEDGE; #endif } + return exStyle; } @@ -1042,7 +1051,7 @@ WXDWORD wxWindowMSW::MakeExtendedStyle(long style, bool eliminateBorders) // applying a default border style if required, and returning an extended // style to pass to CreateWindowEx. WXDWORD wxWindowMSW::Determine3DEffects(WXDWORD defaultBorderStyle, - bool *want3D) const + bool *want3D) const { // If matches certain criteria, then assume no 3D effects // unless specifically requested (dealt with in MakeExtendedStyle) @@ -1053,7 +1062,7 @@ WXDWORD wxWindowMSW::Determine3DEffects(WXDWORD defaultBorderStyle, || (m_windowStyle & wxNO_BORDER) ) { *want3D = FALSE; - return MakeExtendedStyle(m_windowStyle, FALSE); + return MakeExtendedStyle(m_windowStyle); } // Determine whether we should be using 3D effects or not. @@ -2007,7 +2016,19 @@ void wxWindowMSW::UnpackMenuSelect(WXWPARAM wParam, WXLPARAM lParam, // Hook for new window just as it's being created, when the window isn't yet // associated with the handle -wxWindowMSW *wxWndHook = NULL; +static wxWindowMSW *gs_winBeingCreated = NULL; + +// implementation of wxWindowCreationHook class: it just sets gs_winBeingCreated to the +// window being created and insures that it's always unset back later +wxWindowCreationHook::wxWindowCreationHook(wxWindowMSW *winBeingCreated) +{ + gs_winBeingCreated = winBeingCreated; +} + +wxWindowCreationHook::~wxWindowCreationHook() +{ + gs_winBeingCreated = NULL; +} // Main window proc LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) @@ -2021,38 +2042,21 @@ LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM w wxWindowMSW *wnd = wxFindWinFromHandle((WXHWND) hWnd); // when we get the first message for the HWND we just created, we associate - // it with wxWindow stored in wxWndHook - if ( !wnd && wxWndHook ) + // it with wxWindow stored in gs_winBeingCreated + if ( !wnd && gs_winBeingCreated ) { -#if 0 // def __WXDEBUG__ - char buf[512]; - ::GetClassNameA((HWND) hWnd, buf, 512); - wxString className(buf); -#endif - - wxAssociateWinWithHandle(hWnd, wxWndHook); - wnd = wxWndHook; - wxWndHook = NULL; + wxAssociateWinWithHandle(hWnd, gs_winBeingCreated); + wnd = gs_winBeingCreated; + gs_winBeingCreated = NULL; wnd->SetHWND((WXHWND)hWnd); } LRESULT rc; - // Stop right here if we don't have a valid handle in our wxWindow object. - if ( wnd && !wnd->GetHWND() ) - { - // FIXME: why do we do this? - wnd->SetHWND((WXHWND) hWnd); - rc = wnd->MSWDefWindowProc(message, wParam, lParam ); - wnd->SetHWND(0); - } + if ( wnd ) + rc = wnd->MSWWindowProc(message, wParam, lParam); else - { - if ( wnd ) - rc = wnd->MSWWindowProc(message, wParam, lParam); - else - rc = DefWindowProc( hWnd, message, wParam, lParam ); - } + rc = ::DefWindowProc(hWnd, message, wParam, lParam); return rc; } @@ -2583,25 +2587,12 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam return rc.result; } -// Dialog window proc -LONG APIENTRY _EXPORT -wxDlgProc(HWND WXUNUSED(hWnd), UINT message, WPARAM WXUNUSED(wParam), LPARAM WXUNUSED(lParam)) -{ - if ( message == WM_INITDIALOG ) - { - // for this message, returning TRUE tells system to set focus to the - // first control in the dialog box - return TRUE; - } - else - { - // for all the other ones, FALSE means that we didn't process the - // message - return 0; - } -} +// ---------------------------------------------------------------------------- +// wxWindow <-> HWND map +// ---------------------------------------------------------------------------- wxList *wxWinHandleList = NULL; + wxWindow *wxFindWinFromHandle(WXHWND hWnd) { wxNode *node = wxWinHandleList->Find((long)hWnd); @@ -2610,10 +2601,6 @@ wxWindow *wxFindWinFromHandle(WXHWND hWnd) return (wxWindow *)node->Data(); } -#if 0 // def __WXDEBUG__ -static int gs_AssociationCount = 0; -#endif - void wxAssociateWinWithHandle(HWND hWnd, wxWindowMSW *win) { // adding NULL hWnd is (first) surely a result of an error and @@ -2621,36 +2608,30 @@ void wxAssociateWinWithHandle(HWND hWnd, wxWindowMSW *win) wxCHECK_RET( hWnd != (HWND)NULL, wxT("attempt to add a NULL hWnd to window list ignored") ); - wxWindow *oldWin = wxFindWinFromHandle((WXHWND) hWnd); +#ifdef __WXDEBUG__ if ( oldWin && (oldWin != win) ) { - wxString str(win->GetClassInfo()->GetClassName()); - wxLogError(wxT("Bug! Found existing HWND %X for new window of class %s"), (int) hWnd, (const wxChar*) str); + wxLogDebug(wxT("HWND %X already associated with another window (%s)"), + hWnd, win->GetClassInfo()->GetClassName()); } - else if (!oldWin) + else +#endif // __WXDEBUG__ + if (!oldWin) { -#if 0 // def __WXDEBUG__ - gs_AssociationCount ++; - wxLogDebug("+ Association %d", gs_AssociationCount); -#endif - wxWinHandleList->Append((long)hWnd, win); } } void wxRemoveHandleAssociation(wxWindowMSW *win) { -#if 0 // def __WXDEBUG__ - if (wxWinHandleList->Member(win)) - { - wxLogDebug("- Association %d", gs_AssociationCount); - gs_AssociationCount --; - } -#endif wxWinHandleList->DeleteObject(win); } +// ---------------------------------------------------------------------------- +// various MSW speciic class dependent functions +// ---------------------------------------------------------------------------- + // Default destroyer - override if you destroy it in some other way // (e.g. with MDI child windows) void wxWindowMSW::MSWDestroyWindow() @@ -2686,209 +2667,154 @@ void wxWindowMSW::MSWDetachWindowMenu() } } } -#endif +#endif // __WXUNIVERSAL__ } -bool wxWindowMSW::MSWCreate(int id, - wxWindow *parent, - const wxChar *wclass, - wxWindow * WXUNUSED(wx_win), - const wxChar *title, - int x, - int y, - int width, - int height, - WXDWORD style, - const wxChar *dialog_template, - WXDWORD extendedStyle) +bool wxWindowMSW::MSWGetCreateWindowCoords(const wxPoint& pos, + const wxSize& size, + int& x, int& y, + int& w, int& h) const { - int x1 = CW_USEDEFAULT; - int y1 = 0; - int width1 = CW_USEDEFAULT; - int height1 = 100; - - // Find parent's size, if it exists, to set up a possible default - // panel size the size of the parent window - RECT rectParent; - if ( parent ) - { - ::GetClientRect(GetHwndOf(parent), &rectParent); - - width1 = rectParent.right - rectParent.left; - height1 = rectParent.bottom - rectParent.top; - } - - 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 - // program to hang during the next call to IsDialogMessage() due to the bug - // in this function (at least in Windows NT 4.0, it seems to work ok in - // Win2K) -#if 0 - // if we have wxTAB_TRAVERSAL style, we want WS_EX_CONTROLPARENT or - // IsDialogMessage() won't work for us - if ( GetWindowStyleFlag() & wxTAB_TRAVERSAL ) - { - extendedStyle |= WS_EX_CONTROLPARENT; - } -#endif // 0 + bool nonDefault = FALSE; - HWND hParent; - if ( GetWindowStyleFlag() & wxPOPUP_WINDOW ) - { - // popup windows should have desktop as parent because they shouldn't - // be limited to the parents client area as child windows usually are - hParent = ::GetDesktopWindow(); - } - else if ( parent ) + if ( pos.x == -1 ) { - hParent = GetHwndOf(parent); + // if set x to CW_USEDEFAULT, y parameter is ignored anyhow so we can + // just as well set it to CW_USEDEFAULT as well + x = + y = CW_USEDEFAULT; } else { - // top level window - hParent = NULL; - } + x = pos.x; + y = pos.y == -1 ? CW_USEDEFAULT : pos.y; - wxWndHook = this; + nonDefault = TRUE; + } -#ifndef __WXMICROWIN__ - if ( dialog_template ) + if ( size.x == -1 || size.y == -1 ) { - // 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, - (DLGPROC)wxDlgProc); - - if ( m_hWnd == 0 ) + // Find parent's size, if it exists, to set up a possible default panel + // size the size of the parent window + wxWindow *parent = GetParent(); + if ( parent ) { - wxLogError(_("Can't find dialog template '%s'!\nCheck resource include path for finding wx.rc."), - dialog_template); + RECT rectParent; + ::GetClientRect(GetHwndOf(parent), &rectParent); - return FALSE; + w = size.x == -1 ? rectParent.right - rectParent.left : size.x; + h = size.y == -1 ? rectParent.bottom - rectParent.top : size.y; } - - if ( extendedStyle != 0 ) + else { - ::SetWindowLong(GetHwnd(), GWL_EXSTYLE, extendedStyle); - ::SetWindowPos(GetHwnd(), NULL, 0, 0, 0, 0, - SWP_NOSIZE | - SWP_NOMOVE | - SWP_NOZORDER | - SWP_NOACTIVATE); + w = + h = CW_USEDEFAULT; } + } + else + { + w = size.x; + h = size.y; -#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__ + nonDefault = TRUE; + } + return nonDefault; +} - // JACS: is the following still necessary? The above seems to work. +bool wxWindowMSW::MSWCreate(const wxChar *wclass, + const wxChar *title, + const wxPoint& pos, + const wxSize& size, + WXDWORD style, + WXDWORD extendedStyle) +{ + // choose the position/size for the new window + int x, y, w, h; + (void)MSWGetCreateWindowCoords(pos, size, x, y, w, h); - // ::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 ) + // find the correct parent HWND + wxWindow *parent = GetParent(); + bool isChild = (style & WS_CHILD) != 0; + HWND hParent; + if ( GetWindowStyleFlag() & wxPOPUP_WINDOW ) + { + // popup windows should have desktop as parent because they shouldn't + // be limited to the parents client area as child windows usually are + hParent = ::GetDesktopWindow(); + } + else // !popup + { + if ( (isChild || (style & WS_POPUPWINDOW)) && parent ) { - if ( !::SetWindowPos(GetHwnd(), HWND_TOPMOST, 0, 0, 0, 0, - SWP_NOSIZE | SWP_NOMOVE) ) - { - wxLogLastError(wxT("SetWindowPos")); - } + // this is either a normal child window or a top level window with + // wxFRAME_TOOL_WINDOW style (see below) + hParent = GetHwndOf(parent); } - - // move the dialog to its initial position without forcing repainting - if ( !::MoveWindow(GetHwnd(), x1, y1, width1, height1, FALSE) ) + else { - wxLogLastError(wxT("MoveWindow")); + // this is either a window for which no parent was specified (not + // much we can do then) or a frame without wxFRAME_TOOL_WINDOW + // style: we should use NULL parent HWND for it or it would be + // always on top of its parent which is not what we usually want + // (in fact, we only want it for frames with the special + // wxFRAME_TOOL_WINDOW style translated into WS_POPUPWINDOW we test + // against above) + hParent = NULL; } } - else // creating a normal window, not a dialog -#endif // !__WXMICROWIN__ - { - int controlId = 0; - if ( style & WS_CHILD ) - { - controlId = id; - if ( GetWindowStyleFlag() & wxCLIP_SIBLINGS ) - { - style |= WS_CLIPSIBLINGS; - } - } - - wxString className(wclass); - if ( GetWindowStyleFlag() & wxNO_FULL_REPAINT_ON_RESIZE ) - { - className += wxT("NR"); - } + // controlId is menu handle for the top level windows, so set it to 0 + // unless we're creating a child window + int controlId; + if ( isChild ) + { + controlId = GetId(); - m_hWnd = (WXHWND)CreateWindowEx(extendedStyle, - className, - title ? title : wxT(""), - style, - x1, y1, - width1, height1, - hParent, (HMENU)controlId, - wxGetInstance(), - NULL); - - if ( !m_hWnd ) + if ( GetWindowStyleFlag() & wxCLIP_SIBLINGS ) { - wxLogSysError(_("Can't create window of class %s"), wclass); - - return FALSE; + style |= WS_CLIPSIBLINGS; } } + else // !child + { + controlId = 0; + } - wxWndHook = NULL; - -#ifdef __WXDEBUG__ - wxNode* node = wxWinHandleList->Member(this); - if (node) + // for each class "Foo" we have we also have "FooNR" ("no repaint") class + // which is the same but without CS_[HV]REDRAW class styles so using it + // ensures that the window is not fully repainted on each resize + wxString className(wclass); + if ( GetWindowStyleFlag() & wxNO_FULL_REPAINT_ON_RESIZE ) { - HWND hWnd = (HWND) node->GetKeyInteger(); - if (hWnd != (HWND) m_hWnd) - { - wxLogError(wxT("A second HWND association is being added for the same window!")); - } + className += wxT("NR"); + } + + // do create the window + wxWindowCreationHook hook(this); + + m_hWnd = (WXHWND)::CreateWindowEx + ( + extendedStyle, + className, + title ? title : wxT(""), + style, + x, y, w, h, + hParent, + (HMENU)controlId, + wxGetInstance(), + NULL // no extra data + ); + + if ( !m_hWnd ) + { + wxLogSysError(_("Can't create window of class %s"), wclass); + + return FALSE; } -#endif // Debug - wxAssociateWinWithHandle((HWND) m_hWnd, this); + SubclassWin(m_hWnd); SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT)); diff --git a/src/univ/topluniv.cpp b/src/univ/topluniv.cpp index f17795f547..fff2e484cd 100644 --- a/src/univ/topluniv.cpp +++ b/src/univ/topluniv.cpp @@ -75,9 +75,9 @@ bool wxTopLevelWindow::Create(wxWindow *parent, long styleOrig = 0, exstyleOrig = 0; + // FIXME -- wxUniv should provide a way to force non-native decorations! if ( ms_drawDecorations == -1 ) ms_drawDecorations = !wxSystemSettings::HasFrameDecorations(); - // FIXME -- wxUniv should provide a way to force non-native decorations! if ( ms_drawDecorations ) { @@ -97,15 +97,6 @@ bool wxTopLevelWindow::Create(wxWindow *parent, size, style, name) ) return FALSE; - // FIXME: to be removed as soon as wxTLW/wxFrame/wxDialog creation code in - // wxMSW is rationalized -#ifdef __WXMSW__ - extern const wxChar *wxFrameClassName; - if ( !MSWCreate(id, NULL, wxFrameClassName, this, title, - pos.x, pos.y, size.x, size.y, style) ) - return FALSE; -#endif // __WXMSW__ - if ( ms_drawDecorations ) { m_windowStyle = styleOrig; -- 2.45.2