#include "wx/string.h"
#include "wx/log.h"
#include "wx/intl.h"
+ #include "wx/frame.h"
#endif //WX_PRECOMP
#include "wx/msw/private.h"
#ifdef __WXMICROWIN__
-static inline bool IsIconic(HWND WXUNUSED(hwnd)) { return FALSE; }
+// static inline bool IsIconic(HWND WXUNUSED(hwnd)) { return FALSE; }
static inline bool IsZoomed(HWND WXUNUSED(hwnd)) { return FALSE; }
#endif // __WXMICROWIN__
// 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;
}
long wxTopLevelWindowMSW::MSWGetCreateWindowFlags(long *exflags) const
{
*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 ( !(GetExtraStyle() & wxTOPLEVEL_EX_DIALOG) )
+ {
+ // 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 ( (style & wxFRAME_TOOL_WINDOW) || (style & wxFRAME_NO_TASKBAR) )
+ *exflags |= WS_EX_TOOLWINDOW;
+ else if ( !(style & wxFRAME_NO_TASKBAR) )
+ *exflags |= WS_EX_APPWINDOW;
+ }
+#endif // !Win16
if ( style & wxSTAY_ON_TOP )
*exflags |= WS_EX_TOPMOST;
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)::CreateDialog(wxGetInstance(),
// move the dialog to its initial position without forcing repainting
int x, y, w, h;
- if ( MSWGetCreateWindowCoords(pos, size, x, y, w, h) )
+ if ( !MSWGetCreateWindowCoords(pos, size, x, y, w, h) )
{
- if ( !::MoveWindow(GetHwnd(), x, y, w, h, FALSE) )
- {
- wxLogLastError(wxT("MoveWindow"));
- }
+ 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"));
}
- //else: leave it at default position
if ( !title.empty() )
{
}
// ----------------------------------------------------------------------------
-// wxTopLevelWindowMSW geometry
+// wxTopLevelWindowMSW client size
// ----------------------------------------------------------------------------
void wxTopLevelWindowMSW::DoSetClientSize(int width, int height)
{
- HWND hWnd = GetHwnd();
-
- RECT rectClient;
- ::GetClientRect(hWnd, &rectClient);
+ // call GetClientAreaOrigin() to take the toolbar into account
+ wxPoint pt = GetClientAreaOrigin();
+ width += pt.x;
+ height += pt.y;
- RECT rectTotal;
- ::GetWindowRect(hWnd, &rectTotal);
+ wxWindow::DoSetClientSize(width, height);
+}
- // Find the difference between the entire window (title bar and all)
- // and the client area; add this to the new client size to move the
- // window
- width += rectTotal.right - rectTotal.left - rectClient.right;
- height += rectTotal.bottom - rectTotal.top - rectClient.bottom;
+void wxTopLevelWindowMSW::DoGetClientSize(int *x, int *y) const
+{
+ wxWindow::DoGetClientSize(x, y);
- // note that calling GetClientAreaOrigin() takes the toolbar into account
wxPoint pt = GetClientAreaOrigin();
- width += pt.x;
- height += pt.y;
- if ( !::MoveWindow(hWnd, rectTotal.left, rectTotal.top,
- width, height, TRUE /* redraw */) )
- {
- wxLogLastError(_T("MoveWindow"));
- }
+ if ( x )
+ *x -= pt.x;
- wxSizeEvent event(wxSize(width, height), m_windowId);
- event.SetEventObject(this);
- (void)GetEventHandler()->ProcessEvent(event);
+ if ( y )
+ *y -= pt.y;
}
// ----------------------------------------------------------------------------
DoShowWindow(SW_RESTORE);
}
+// ----------------------------------------------------------------------------
+// wxTopLevelWindowMSW fullscreen
+// ----------------------------------------------------------------------------
+
+bool wxTopLevelWindowMSW::ShowFullScreen(bool show, long style)
+{
+ if (show)
+ {
+ if (IsFullScreen())
+ return FALSE;
+
+ m_fsIsShowing = TRUE;
+ m_fsStyle = style;
+
+ // zap the frame borders
+
+ // save the 'normal' window style
+ m_fsOldWindowStyle = GetWindowLong((HWND)GetHWND(), GWL_STYLE);
+
+ // save the old position, width & height, maximize state
+ m_fsOldSize = GetRect();
+ m_fsIsMaximized = IsMaximized();
+
+ // decide which window style flags to turn off
+ LONG newStyle = m_fsOldWindowStyle;
+ LONG offFlags = 0;
+
+ if (style & wxFULLSCREEN_NOBORDER)
+ offFlags |= WS_BORDER | WS_THICKFRAME;
+ if (style & wxFULLSCREEN_NOCAPTION)
+ offFlags |= (WS_CAPTION | WS_SYSMENU);
+
+ newStyle &= (~offFlags);
+
+ // change our window style to be compatible with full-screen mode
+ ::SetWindowLong((HWND)GetHWND(), GWL_STYLE, newStyle);
+
+ // resize to the size of the desktop
+ int width, height;
+
+ RECT rect = wxGetWindowRect(::GetDesktopWindow());
+ width = rect.right - rect.left;
+ height = rect.bottom - rect.top;
+
+ SetSize(width, height);
+
+ // now flush the window style cache and actually go full-screen
+ SetWindowPos((HWND)GetHWND(), HWND_TOP, 0, 0, width, height, SWP_FRAMECHANGED);
+
+ wxSizeEvent event(wxSize(width, height), GetId());
+ GetEventHandler()->ProcessEvent(event);
+
+ return TRUE;
+ }
+ else
+ {
+ if (!IsFullScreen())
+ return FALSE;
+
+ m_fsIsShowing = FALSE;
+
+ Maximize(m_fsIsMaximized);
+ SetWindowLong((HWND)GetHWND(),GWL_STYLE, m_fsOldWindowStyle);
+ SetWindowPos((HWND)GetHWND(),HWND_TOP,m_fsOldSize.x, m_fsOldSize.y,
+ m_fsOldSize.width, m_fsOldSize.height, SWP_FRAMECHANGED);
+
+ return TRUE;
+ }
+}
+
// ----------------------------------------------------------------------------
// wxTopLevelWindowMSW misc
// ----------------------------------------------------------------------------
}
#endif // __WIN95__
}
+
+bool wxTopLevelWindowMSW::EnableCloseButton(bool enable)
+{
+#ifndef __WXMICROWIN__
+ // get system (a.k.a. window) menu
+ HMENU hmenu = ::GetSystemMenu(GetHwnd(), FALSE /* get it */);
+ if ( !hmenu )
+ {
+ wxLogLastError(_T("GetSystemMenu"));
+
+ return FALSE;
+ }
+
+ // enabling/disabling the close item from it also automatically
+ // disables/enables the close title bar button
+ if ( ::EnableMenuItem(hmenu, SC_CLOSE,
+ MF_BYCOMMAND |
+ (enable ? MF_ENABLED : MF_GRAYED)) == -1 )
+ {
+ wxLogLastError(_T("EnableMenuItem(SC_CLOSE)"));
+
+ return FALSE;
+ }
+
+ // update appearance immediately
+ if ( !::DrawMenuBar(GetHwnd()) )
+ {
+ wxLogLastError(_T("DrawMenuBar"));
+ }
+#endif // !__WXMICROWIN__
+
+ return TRUE;
+}
+