+
+ // unlike (almost?) all other windows, frames are created hidden
+ m_isShown = FALSE;
+
+ // Data to save/restore when calling ShowFullScreen
+ m_fsStyle = 0;
+ m_fsOldWindowStyle = 0;
+ m_fsIsMaximized = FALSE;
+ m_fsIsShowing = FALSE;
+
+ m_winLastFocused = (wxWindow *)NULL;
+}
+
+WXDWORD wxTopLevelWindowMSW::MSWGetStyle(long style, WXDWORD *exflags) const
+{
+ // let the base class deal with the common styles but fix the ones which
+ // don't make sense for us (we also deal with the borders ourselves)
+ WXDWORD msflags = wxWindow::MSWGetStyle
+ (
+ (style & ~wxBORDER_MASK) | wxBORDER_NONE, exflags
+ ) & ~WS_CHILD;
+
+ // first select the kind of window being created
+ //
+ // note that if we don't set WS_POPUP, Windows assumes WS_OVERLAPPED and
+ // creates a window with both caption and border, hence we also test it
+ // below in some other cases
+ if ( style & wxFRAME_TOOL_WINDOW )
+ msflags |= WS_POPUP;
+ else
+ msflags |= WS_OVERLAPPED;
+
+ // border and caption styles
+ if ( style & wxRESIZE_BORDER )
+ msflags |= WS_THICKFRAME;
+ else if ( !(style & wxBORDER_NONE) )
+ msflags |= WS_BORDER;
+ else
+ msflags |= WS_POPUP;
+
+ if ( style & wxCAPTION )
+ msflags |= WS_CAPTION;
+ 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 & wxSYSTEM_MENU )
+ msflags |= WS_SYSMENU;
+ if ( style & wxMINIMIZE )
+ msflags |= WS_MINIMIZE;
+ if ( style & wxMAXIMIZE )
+ msflags |= WS_MAXIMIZE;
+
+ // 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 )
+ {
+#if !defined(__WIN16__) && !defined(__SC__)
+ if ( !(GetExtraStyle() & wxTOPLEVEL_EX_DIALOG) )
+ {
+ if ( style & wxFRAME_TOOL_WINDOW )
+ {
+ // create the palette-like window
+ *exflags |= WS_EX_TOOLWINDOW;
+ }
+
+ // We have to solve 2 different problems here:
+ //
+ // 1. frames with wxFRAME_NO_TASKBAR flag shouldn't appear in the
+ // taskbar even if they don't have a parent
+ //
+ // 2. frames without this style should appear in the taskbar even
+ // if they're owned (Windows only puts non owned windows into
+ // the taskbar normally)
+ //
+ // The second one is solved here by using WS_EX_APPWINDOW flag, the
+ // first one is dealt with in our MSWGetParent() method
+ // implementation
+ if ( !(style & wxFRAME_NO_TASKBAR) && GetParent() )
+ {
+ // need to force the frame to appear in the taskbar
+ *exflags |= WS_EX_APPWINDOW;
+ }
+ //else: nothing to do [here]
+ }
+#endif // !Win16
+
+ if ( style & wxSTAY_ON_TOP )
+ *exflags |= WS_EX_TOPMOST;
+
+#ifdef __WIN32__
+ if ( GetExtraStyle() & wxFRAME_EX_CONTEXTHELP )
+ *exflags |= WS_EX_CONTEXTHELP;
+#endif // __WIN32__
+ }
+
+ return msflags;
+}
+
+WXHWND wxTopLevelWindowMSW::MSWGetParent() const
+{
+ // for the frames without wxFRAME_FLOAT_ON_PARENT style we should use 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
+ // wxFRAME_FLOAT_ON_PARENT flag)
+ wxWindow *parent;
+ if ( HasFlag(wxFRAME_FLOAT_ON_PARENT) )
+ {
+ parent = GetParent();
+
+ // this flag doesn't make sense then and will be ignored
+ wxASSERT_MSG( parent,
+ _T("wxFRAME_FLOAT_ON_PARENT but no parent?") );
+ }
+ else // don't float on parent, must not be owned
+ {
+ parent = NULL;
+ }
+
+ // now deal with the 2nd taskbar-related problem (see comments above in
+ // MSWGetStyle())
+ if ( HasFlag(wxFRAME_NO_TASKBAR) && !parent )
+ {
+ if ( !ms_hiddenParent )
+ {
+ ms_hiddenParent = new wxTopLevelWindowMSW(NULL, -1, _T(""));
+
+ // we shouldn't leave it in wxTopLevelWindows or we wouldn't
+ // terminate the app when the last user-created frame is deleted --
+ // see ~wxTopLevelWindowMSW
+ wxTopLevelWindows.DeleteObject(ms_hiddenParent);
+ }
+
+ parent = ms_hiddenParent;
+ }
+
+ return parent ? parent->GetHWND() : WXHWND(NULL);
+}
+
+bool wxTopLevelWindowMSW::CreateDialog(const void *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();
+
+ if ( parent )
+ {
+ // don't use transient windows as parents, this is dangerous as it
+ // can lead to a crash if the parent is destroyed before the child
+ //
+ // also don't use the window which is currently hidden as then the
+ // dialog would be hidden as well
+ if ( (parent->GetExtraStyle() & wxWS_EX_TRANSIENT) ||
+ !parent->IsShown() )
+ {
+ parent = NULL;
+ }
+ }
+ }
+
+ m_hWnd = (WXHWND)::CreateDialogIndirect
+ (
+ wxGetInstance(),
+ (DLGTEMPLATE*)dlgTemplate,
+ parent ? GetHwndOf(parent) : NULL,
+ (DLGPROC)wxDlgProc
+ );
+
+ if ( !m_hWnd )
+ {
+ wxFAIL_MSG(_("Failed to create dialog. Incorrect DLGTEMPLATE?"));
+
+ wxLogSysError(_("Can't create dialog using memory template"));
+
+ return FALSE;
+ }
+
+ WXDWORD 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) )
+ {
+ x =
+ w = (int)CW_USEDEFAULT;
+ }
+
+ // we can't use CW_USEDEFAULT here as we're not calling CreateWindow()
+ // and passing CW_USEDEFAULT to MoveWindow() results in resizing the
+ // window to (0, 0) size which breaks quite a lot of things, e.g. the
+ // sizer calculation in wxSizer::Fit()
+ if ( w == (int)CW_USEDEFAULT )
+ {
+ // the exact number doesn't matter, the dialog will be resized
+ // again soon anyhow but it should be big enough to allow
+ // calculation relying on "totalSize - clientSize > 0" work, i.e.
+ // at least greater than the title bar height
+ w =
+ h = 100;
+ }
+
+ if ( x == (int)CW_USEDEFAULT )
+ {
+ // centre it on the screen - what else can we do?
+ wxSize sizeDpy = wxGetDisplaySize();
+
+ x = (sizeDpy.x - w) / 2;
+ y = (sizeDpy.y - h) / 2;
+ }
+
+ if ( !::MoveWindow(GetHwnd(), x, y, w, h, FALSE) )
+ {
+ wxLogLastError(wxT("MoveWindow"));
+ }
+
+ 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)
+{
+ WXDWORD exflags;
+ WXDWORD flags = MSWGetCreateWindowFlags(&exflags);
+
+ return MSWCreate(wxCanvasClassName, title, pos, size, flags, exflags);