]> git.saurik.com Git - wxWidgets.git/blame - src/os2/toplevel.cpp
Applied patch [ 603104 ] wxX11 wxClientDC, wxPaintDC fix
[wxWidgets.git] / src / os2 / toplevel.cpp
CommitLineData
f45e4fad
DW
1///////////////////////////////////////////////////////////////////////////////
2// Name: msw/toplevel.cpp
3// Purpose: implements wxTopLevelWindow for MSW
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 30.12.01
7// RCS-ID: $Id$
8// Copyright: (c) 2001 SciTech Software, Inc. (www.scitechsoft.com)
9// License: wxWindows license
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20#ifdef __GNUG__
21 #pragma implementation "toplevel.h"
22#endif
23
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
27#ifdef __BORLANDC__
28 #pragma hdrstop
29#endif
30
31#ifndef WX_PRECOMP
32 #include "wx/app.h"
33 #include "wx/toplevel.h"
34 #include "wx/string.h"
35 #include "wx/log.h"
36 #include "wx/intl.h"
37 #include "wx/frame.h"
a4a16252 38 #include "wx/control.h"
272ebf16 39 #include "wx/containr.h" // wxSetFocusToChild()
f45e4fad
DW
40#endif //WX_PRECOMP
41
42#include "wx/os2/private.h"
43
44// ----------------------------------------------------------------------------
45// stubs for missing functions under MicroWindows
46// ----------------------------------------------------------------------------
47
48
49// ----------------------------------------------------------------------------
50// globals
51// ----------------------------------------------------------------------------
52
53// list of all frames and modeless dialogs
54wxWindowList wxModelessWindows;
55
56// the name of the default wxWindows class
793c7f9b
DW
57extern void wxAssociateWinWithHandle( HWND hWnd
58 ,wxWindowOS2* pWin
59 );
45e0dc94 60bool wxTopLevelWindowOS2::m_sbInitialized = FALSE;
6ed98c6a 61wxWindow* wxTopLevelWindowOS2::m_spHiddenParent = NULL;
f45e4fad 62
47df2b8c
DW
63// ============================================================================
64// wxTopLevelWindowOS2 implementation
65// ============================================================================
66
67BEGIN_EVENT_TABLE(wxTopLevelWindowOS2, wxTopLevelWindowBase)
68 EVT_ACTIVATE(wxTopLevelWindowOS2::OnActivate)
69END_EVENT_TABLE()
70
f45e4fad
DW
71// ============================================================================
72// wxTopLevelWindowMSW implementation
73// ============================================================================
74
75// Dialog window proc
76MRESULT EXPENTRY wxDlgProc( HWND WXUNUSED(hWnd)
77 ,UINT uMessage
78 ,MPARAM WXUNUSED(wParam)
79 ,MPARAM WXUNUSED(lParam)
80 )
81{
47df2b8c 82 switch(uMessage)
f45e4fad 83 {
47df2b8c
DW
84 case WM_INITDLG:
85 //
86 // For this message, returning TRUE tells system to set focus to
0256cfeb
DW
87 // the first control in the dialog box, but we set the focus
88 // ourselves, however in OS/2 we must return true to enable the dialog
47df2b8c 89 //
0256cfeb 90 return (MRESULT)TRUE;
47df2b8c
DW
91 default:
92 //
93 // For all the other ones, FALSE means that we didn't process the
94 // message
95 //
96 return (MRESULT)FALSE;
f45e4fad
DW
97 }
98} // end of wxDlgProc
99
100// ----------------------------------------------------------------------------
101// wxTopLevelWindowOS2 creation
102// ----------------------------------------------------------------------------
103
104void wxTopLevelWindowOS2::Init()
105{
106 m_bIconized = m_bMaximizeOnShow = FALSE;
107
108 //
109 // Unlike (almost?) all other windows, frames are created hidden
110 //
111 m_isShown = FALSE;
112
113 //
114 // Data to save/restore when calling ShowFullScreen
115 m_lFsStyle = 0;
116 m_lFsOldWindowStyle = 0;
117 m_bFsIsMaximized = FALSE;
118 m_bFsIsShowing = FALSE;
119
120 m_hFrame = NULLHANDLE;
121 memset(&m_vSwp, 0, sizeof(SWP));
122 memset(&m_vSwpClient, 0, sizeof(SWP));
47df2b8c 123 m_pWinLastFocused = (wxWindow *)NULL;
f45e4fad
DW
124} // end of wxTopLevelWindowIOS2::Init
125
47df2b8c
DW
126void wxTopLevelWindowOS2::OnActivate(
127 wxActivateEvent& rEvent
128)
129{
130 if (rEvent.GetActive())
131 {
132 //
133 // Restore focus to the child which was last focused
134 //
135 wxLogTrace(_T("focus"), _T("wxTLW %08x activated."), m_hWnd);
136
137 wxWindow* pParent = m_pWinLastFocused ? m_pWinLastFocused->GetParent()
138 : NULL;
139 if (!pParent)
140 {
141 pParent = this;
142 }
143
144 wxSetFocusToChild( pParent
145 ,&m_pWinLastFocused
146 );
147 }
148 else // deactivating
149 {
150 //
151 // Remember the last focused child if it is our child
152 //
153 m_pWinLastFocused = FindFocus();
154
155 //
156 // So we NULL it out if it's a child from some other frame
157 //
158 wxWindow* pWin = m_pWinLastFocused;
159
160 while (pWin)
161 {
162 if (pWin->IsTopLevel())
163 {
164 if (pWin != this)
165 {
166 m_pWinLastFocused = NULL;
167 }
168 break;
169 }
170 pWin = pWin->GetParent();
171 }
172
173 wxLogTrace(_T("focus"),
174 _T("wxTLW %08x deactivated, last focused: %08x."),
175 m_hWnd,
176 m_pWinLastFocused ? GetHwndOf(m_pWinLastFocused)
177 : NULL);
178 rEvent.Skip();
179 }
180} // end of wxTopLevelWindowOS2::OnActivate
181
b9b1d6c8
DW
182WXDWORD wxTopLevelWindowOS2::OS2GetStyle(
183 long lStyle
184, WXDWORD* pdwExflags
f45e4fad
DW
185) const
186{
b9b1d6c8
DW
187 long lMsflags = wxWindow::OS2GetStyle( (lStyle & ~wxBORDER_MASK) | wxBORDER_NONE
188 ,pdwExflags
189 );
f45e4fad
DW
190
191 if (lStyle == wxDEFAULT_FRAME_STYLE)
b9b1d6c8
DW
192 lMsflags |= FCF_SIZEBORDER | FCF_TITLEBAR | FCF_SYSMENU |
193 FCF_MINMAX | FCF_TASKLIST;
f45e4fad
DW
194 else
195 {
196 if ((lStyle & wxCAPTION) == wxCAPTION)
b9b1d6c8 197 lMsflags |= FCF_TASKLIST;
f45e4fad 198 else
b9b1d6c8 199 lMsflags |= FCF_NOMOVEWITHOWNER;
f45e4fad
DW
200
201 if ((lStyle & wxVSCROLL) == wxVSCROLL)
202 lMsflags |= FCF_VERTSCROLL;
203 if ((lStyle & wxHSCROLL) == wxHSCROLL)
204 lMsflags |= FCF_HORZSCROLL;
205 if (lStyle & wxMINIMIZE_BOX)
206 lMsflags |= FCF_MINBUTTON;
207 if (lStyle & wxMAXIMIZE_BOX)
208 lMsflags |= FCF_MAXBUTTON;
209 if (lStyle & wxTHICK_FRAME)
210 lMsflags |= FCF_DLGBORDER;
211 if (lStyle & wxSYSTEM_MENU)
212 lMsflags |= FCF_SYSMENU;
213 if (lStyle & wxCAPTION)
214 lMsflags |= FCF_TASKLIST;
215 if (lStyle & wxCLIP_CHILDREN)
216 {
217 // Invalid for frame windows under PM
218 }
219
220 if (lStyle & wxTINY_CAPTION_VERT)
221 lMsflags |= FCF_TASKLIST;
222 if (lStyle & wxTINY_CAPTION_HORIZ)
223 lMsflags |= FCF_TASKLIST;
224
225 if ((lStyle & wxTHICK_FRAME) == 0)
226 lMsflags |= FCF_BORDER;
227 if (lStyle & wxFRAME_TOOL_WINDOW)
b9b1d6c8 228 *pdwExflags = kFrameToolWindow;
f45e4fad
DW
229
230 if (lStyle & wxSTAY_ON_TOP)
231 lMsflags |= FCF_SYSMODAL;
232 }
233 return lMsflags;
234} // end of wxTopLevelWindowOS2::OS2GetCreateWindowFlags
235
6ed98c6a
DW
236WXHWND wxTopLevelWindowOS2::OS2GetParent() const
237{
238 //
239 // For the frames without wxFRAME_FLOAT_ON_PARENT style we should use NULL
240 // parent HWND or it would be always on top of its parent which is not what
241 // we usually want (in fact, we only want it for frames with the
242 // wxFRAME_FLOAT_ON_PARENT flag)
243 //
244 wxWindow* pParent;
245
246 if (HasFlag(wxFRAME_FLOAT_ON_PARENT) )
247 {
248 pParent = GetParent();
249
250 // this flag doesn't make sense then and will be ignored
251 wxASSERT_MSG( pParent,
252 _T("wxFRAME_FLOAT_ON_PARENT but no parent?") );
253 }
254 else // don't float on parent, must not be owned
255 {
256 pParent = NULL;
257 }
258 if (HasFlag(wxFRAME_NO_TASKBAR) && !pParent)
259 {
260 if (!m_spHiddenParent)
261 {
262 m_spHiddenParent = new wxTopLevelWindowOS2(NULL, -1, _T(""));
263
264 //
265 // We shouldn't leave it in wxTopLevelWindows or we wouldn't
266 // terminate the app when the last user-created frame is deleted --
267 // see ~wxTopLevelWindowMSW
268 //
269 wxTopLevelWindows.DeleteObject(m_spHiddenParent);
270 }
271 pParent = m_spHiddenParent;
272 }
273 return pParent ? pParent->GetHWND() : NULL;
274} // end of wxTopLevelWindowOS2::OS2GetParent
275
f45e4fad
DW
276bool wxTopLevelWindowOS2::CreateDialog(
277 ULONG ulDlgTemplate
278, const wxString& rsTitle
279, const wxPoint& rPos
280, const wxSize& rSize
281)
282{
283 wxWindow* pParent = GetParent();
284
285 //
286 // For the dialogs without wxDIALOG_NO_PARENT style, use the top level
287 // app window as parent - this avoids creating modal dialogs without
288 // parent
289 //
290 if (!pParent && !(GetWindowStyleFlag() & wxDIALOG_NO_PARENT))
291 {
292 pParent = wxTheApp->GetTopWindow();
293
294 if (pParent)
295 {
296 //
297 // Don't use transient windows as parents, this is dangerous as it
298 // can lead to a crash if the parent is destroyed before the child
299 //
300 // also don't use the window which is currently hidden as then the
301 // dialog would be hidden as well
302 if ((pParent->GetExtraStyle() & wxWS_EX_TRANSIENT) ||
303 !pParent->IsShown())
304 {
305 pParent = NULL;
306 }
307 }
308 }
309
310 HWND hWndDlg;
1b086de1 311 HWND hWndOwner;
f45e4fad
DW
312
313 if (pParent)
1b086de1 314 hWndOwner = GetHwndOf(pParent);
f45e4fad 315 else
1b086de1 316 hWndOwner = HWND_DESKTOP;
f45e4fad 317
1b086de1
DW
318 hWndDlg = ::WinLoadDlg( HWND_DESKTOP
319 ,hWndOwner
f45e4fad
DW
320 ,(PFNWP)wxDlgProc
321 ,NULL
322 ,(ULONG)ulDlgTemplate
323 ,(PVOID)this
324 );
325
326 m_hWnd = (WXHWND) hWndDlg;
327
328 if ( !m_hWnd )
329 {
330 wxFAIL_MSG(_("Did you forget to include wx/os2/wx.rc in your resources?"));
331
332 wxLogSysError(_("Can't create dialog using template '%ul'"), ulDlgTemplate);
333
334 return FALSE;
335 }
336
337 //
338 // Move the dialog to its initial position without forcing repainting
339 //
340 int nX;
341 int nY;
342 int nWidth;
343 int nHeight;
344
345 if (!OS2GetCreateWindowCoords( rPos
346 ,rSize
347 ,nX
348 ,nY
349 ,nWidth
350 ,nHeight
351 ))
352 {
353 nX = nWidth = (int)CW_USEDEFAULT;
354 }
355
356 //
357 // We can't use CW_USEDEFAULT here as we're not calling CreateWindow()
358 // and passing CW_USEDEFAULT to MoveWindow() results in resizing the
359 // window to (0, 0) size which breaks quite a lot of things, e.g. the
360 // sizer calculation in wxSizer::Fit()
361 //
362 if (nWidth == (int)CW_USEDEFAULT)
363 {
364 //
365 // The exact number doesn't matter, the dialog will be resized
366 // again soon anyhow but it should be big enough to allow
367 // calculation relying on "totalSize - clientSize > 0" work, i.e.
368 // at least greater than the title bar height
369 //
370 nWidth = nHeight = 100;
371 }
372 if (nX == (int)CW_USEDEFAULT)
373 {
374 //
375 // Centre it on the screen - what else can we do?
376 //
377 wxSize vSizeDpy = wxGetDisplaySize();
378
379 nX = (vSizeDpy.x - nWidth) / 2;
380 nY = (vSizeDpy.y - nHeight) / 2;
381 }
626af800
DW
382 m_backgroundColour.Set(wxString("LIGHT GREY"));
383
384 LONG lColor = (LONG)m_backgroundColour.GetPixel();
385
386 if (!::WinSetPresParam( m_hWnd
387 ,PP_BACKGROUNDCOLOR
388 ,sizeof(LONG)
389 ,(PVOID)&lColor
390 ))
391 {
392 return FALSE;
393 }
b3260bce 394
f45e4fad
DW
395 ::WinSetWindowPos( GetHwnd()
396 ,HWND_TOP
397 ,nX
398 ,nY
399 ,nWidth
400 ,nHeight
0256cfeb 401 ,SWP_MOVE | SWP_SIZE | SWP_ZORDER | SWP_SHOW | SWP_ACTIVATE
f45e4fad 402 );
859e65de 403 ::WinQueryWindowPos(GetHwnd(), GetSwp());
626af800 404 m_hFrame = m_hWnd;
f45e4fad
DW
405 SubclassWin(m_hWnd);
406 return TRUE;
407} // end of wxTopLevelWindowOS2::CreateDialog
408
409bool wxTopLevelWindowOS2::CreateFrame(
410 const wxString& rsTitle
411, const wxPoint& rPos
412, const wxSize& rSize
413)
414{
b9b1d6c8
DW
415 WXDWORD lExflags;
416 WXDWORD lFlags = OS2GetCreateWindowFlags(&lExflags);
f45e4fad
DW
417 long lStyle = GetWindowStyleFlag();
418 int nX = rPos.x;
419 int nY = rPos.y;
420 int nWidth = rSize.x;
421 int nHeight = rSize.y;
422 ULONG ulStyleFlags = 0L;
423 ERRORID vError;
424 wxString sError;
425 wxWindow* pParent = GetParent();
426 HWND hParent;
427 HWND hFrame;
428 HWND hClient;
429
430 if (pParent)
431 hParent = GetHwndOf(pParent);
432 else
433 hParent = HWND_DESKTOP;
434
435 if ((lStyle & wxMINIMIZE) || (lStyle & wxICONIZE))
436 ulStyleFlags |= WS_MINIMIZED;
437 if (lStyle & wxMAXIMIZE)
438 ulStyleFlags |= WS_MAXIMIZED;
439
440 //
441 // Clear the visible flag, we always call show
442 //
443 ulStyleFlags &= (unsigned long)~WS_VISIBLE;
444 m_bIconized = FALSE;
445
446 //
447 // Create the frame window: We break ranks with other ports now
448 // and instead of calling down into the base wxWindow class' OS2Create
449 // we do all our own stuff here. We will set the needed pieces
450 // of wxWindow manually, here.
451 //
452
453 hFrame = ::WinCreateStdWindow( hParent
454 ,ulStyleFlags // frame-window style
455 ,(PULONG)&lFlags // window style
456 ,(PSZ)wxFrameClassName // class name
457 ,(PSZ)rsTitle.c_str() // window title
458 ,0L // default client style
459 ,NULLHANDLE // resource in executable file
460 ,0 // resource id
461 ,&hClient // receives client window handle
462 );
463 if (!hFrame)
464 {
465 vError = ::WinGetLastError(vHabmain);
466 sError = wxPMErrorToStr(vError);
467 wxLogError("Error creating frame. Error: %s\n", sError);
468 return FALSE;
469 }
470
471 //
472 // wxWindow class' m_hWnd set here and needed associations
473 //
474 m_hFrame = hFrame;
475 m_hWnd = hClient;
476 wxAssociateWinWithHandle(m_hWnd, this);
477 wxAssociateWinWithHandle(m_hFrame, this);
478
e58dab20 479 m_backgroundColour.Set(wxString("MEDIUM GREY"));
f45e4fad
DW
480
481 LONG lColor = (LONG)m_backgroundColour.GetPixel();
482
483 if (!::WinSetPresParam( m_hWnd
484 ,PP_BACKGROUNDCOLOR
485 ,sizeof(LONG)
486 ,(PVOID)&lColor
487 ))
488 {
489 vError = ::WinGetLastError(vHabmain);
490 sError = wxPMErrorToStr(vError);
491 wxLogError("Error creating frame. Error: %s\n", sError);
492 return FALSE;
493 }
494
495 //
496 // Now need to subclass window. Instead of calling the SubClassWin in wxWindow
497 // we manually subclass here because we don't want to use the main wxWndProc
498 // by default
499 //
500 m_fnOldWndProc = (WXFARPROC) ::WinSubclassWindow(m_hFrame, (PFNWP)wxFrameMainWndProc);
501
502 //
503 // Now size everything. If adding a menu the client will need to be resized.
504 //
505
506 if (pParent)
507 {
508 nY = pParent->GetSize().y - (nY + nHeight);
509 }
510 else
511 {
512 RECTL vRect;
513
514 ::WinQueryWindowRect(HWND_DESKTOP, &vRect);
515 nY = vRect.yTop - (nY + nHeight);
516 }
517 if (!::WinSetWindowPos( m_hFrame
518 ,HWND_TOP
519 ,nX
520 ,nY
521 ,nWidth
522 ,nHeight
523 ,SWP_SIZE | SWP_MOVE | SWP_ACTIVATE | SWP_ZORDER
524 ))
525 {
526 vError = ::WinGetLastError(vHabmain);
527 sError = wxPMErrorToStr(vError);
528 wxLogError("Error sizing frame. Error: %s\n", sError);
529 return FALSE;
530 }
54ffa107
DW
531 lStyle = ::WinQueryWindowULong( m_hWnd
532 ,QWL_STYLE
533 );
534 lStyle |= WS_CLIPCHILDREN;
535 ::WinSetWindowULong( m_hWnd
536 ,QWL_STYLE
537 ,lStyle
538 );
f45e4fad
DW
539 return TRUE;
540} // end of wxTopLevelWindowOS2::CreateFrame
541
542bool wxTopLevelWindowOS2::Create(
543 wxWindow* pParent
544, wxWindowID vId
545, const wxString& rsTitle
546, const wxPoint& rPos
547, const wxSize& rSize
548, long lStyle
549, const wxString& rsName
550)
551{
552 //
553 // Init our fields
554 //
555 Init();
556 m_windowStyle = lStyle;
557 SetName(rsName);
558 m_windowId = vId == -1 ? NewControlId() : vId;
559 wxTopLevelWindows.Append(this);
560 if (pParent)
561 pParent->AddChild(this);
562
563 if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG)
564 {
565 //
566 // We have different dialog templates to allows creation of dialogs
567 // with & without captions under OS2indows, resizeable or not (but a
568 // resizeable dialog always has caption - otherwise it would look too
569 // strange)
570 //
571 ULONG ulDlgTemplate;
572
573 if (lStyle & wxRESIZE_BORDER)
574 ulDlgTemplate = (ULONG)kResizeableDialog;
575 else if (lStyle & wxCAPTION)
576 ulDlgTemplate = (ULONG)kCaptionDialog;
577 else
578 ulDlgTemplate = (ULONG)kNoCaptionDialog;
579 return CreateDialog( ulDlgTemplate
580 ,rsTitle
581 ,rPos
582 ,rSize
583 );
584 }
585 else // !dialog
586 {
587 return CreateFrame( rsTitle
588 ,rPos
589 ,rSize
590 );
591 }
592} // end of wxTopLevelWindowOS2::Create
593
594wxTopLevelWindowOS2::~wxTopLevelWindowOS2()
595{
a23692f0
DW
596 if (this == m_spHiddenParent)
597 {
598 //
599 // Stop [infinite] recursion which would otherwise happen when we do
600 // "delete ms_hiddenParent" below -- and we're not interested in doing
601 // anything of the rest below for that window because the rest of
602 // wxWindows doesn't even know about it
603 //
604 return;
605 }
f45e4fad
DW
606
607 if (wxModelessWindows.Find(this))
608 wxModelessWindows.DeleteObject(this);
609
610 //
a23692f0
DW
611 // After destroying an owned window, Windows activates the next top level
612 // window in Z order but it may be different from our owner (to reproduce
613 // this simply Alt-TAB to another application and back before closing the
614 // owned frame) whereas we always want to yield activation to our parent
615 //
616 if (HasFlag(wxFRAME_FLOAT_ON_PARENT))
617 {
618 wxWindow* pParent = GetParent();
619
620 if (pParent)
621 {
622 ::WinSetWindowPos( GetHwndOf(pParent)
623 ,HWND_TOP
624 ,0, 0, 0, 0
625 ,SWP_ZORDER
626 );
627 }
628 }
629
630 //
631 // If this is the last top-level window, we're going to exit and we should
632 // delete ms_hiddenParent now to avoid leaking it
f45e4fad 633 //
a23692f0 634 if (IsLastBeforeExit())
f45e4fad 635 {
a23692f0 636 if (m_spHiddenParent)
f45e4fad 637 {
a23692f0
DW
638 delete m_spHiddenParent;
639 m_spHiddenParent = NULL;
f45e4fad
DW
640 }
641 }
642} // end of wxTopLevelWindowOS2::~wxTopLevelWindowOS2
643
f45e4fad
DW
644// ----------------------------------------------------------------------------
645// wxTopLevelWindowOS2 client size
646// ----------------------------------------------------------------------------
647
648void wxTopLevelWindowOS2::DoSetClientSize(
649 int nWidth
650, int nHeight
651)
652{
653 //
654 // Call GetClientAreaOrigin() to take the toolbar into account
655 //
656 wxPoint vPt = GetClientAreaOrigin();
657
658 nWidth += vPt.x;
659 nHeight += vPt.y;
660
661 wxWindow::DoSetClientSize( nWidth
662 ,nHeight
663 );
664} // end of wxTopLevelWindowOS2::DoSetClientSize
665
666void wxTopLevelWindowOS2::DoGetClientSize(
667 int* pnX
668, int* pnY
669) const
670{
671 wxWindow::DoGetClientSize( pnX
672 ,pnY
673 );
674
675 wxPoint vPt = GetClientAreaOrigin();
676
677 if (pnX)
678 *pnX -= vPt.x;
679
680 if (pnY)
681 *pnY += vPt.y;
682} // end of wxTopLevelWindowOS2::DoGetClientSize
683
684// ----------------------------------------------------------------------------
685// wxTopLevelWindowOS2 showing
686// ----------------------------------------------------------------------------
687
688void wxTopLevelWindowOS2::DoShowWindow(
689 int nShowCmd
690)
691{
54ffa107 692 ::WinShowWindow(m_hFrame, (BOOL)(nShowCmd & SWP_SHOW));
239c2e96
DW
693
694 //
695 // Need to artificially send a size event as wxApps often expect to do some
696 // final child control sizing
697 SendSizeEvent();
f45e4fad
DW
698 m_bIconized = nShowCmd == SWP_MINIMIZE;
699} // end of wxTopLevelWindowOS2::DoShowWindow
700
701bool wxTopLevelWindowOS2::Show(
702 bool bShow
703)
704{
705 int nShowCmd;
706 SWP vSwp;
707 RECTL vRect;
708
709 if (bShow)
710 {
711 if (m_bMaximizeOnShow)
712 {
54ffa107 713 nShowCmd = SWP_MAXIMIZE;
f45e4fad
DW
714 m_bMaximizeOnShow = FALSE;
715 }
716 else
717 {
54ffa107 718 nShowCmd = SWP_SHOW;
f45e4fad
DW
719 }
720 }
721 else // hide
722 {
723 nShowCmd = SWP_HIDE;
724 }
725 DoShowWindow(nShowCmd);
726
727 if (bShow)
728 {
729 wxActivateEvent vEvent(wxEVT_ACTIVATE, TRUE, m_windowId);
730
731 ::WinQueryWindowPos(m_hFrame, &vSwp);
732 m_bIconized = vSwp.fl & SWP_MINIMIZE;
733 ::WinQueryWindowPos(m_hWnd, &m_vSwpClient);
734 ::WinSendMsg(m_hFrame, WM_UPDATEFRAME, (MPARAM)~0, 0);
4a46a5df 735 ::WinQueryWindowPos(m_hWnd, &vSwp);
f45e4fad 736 ::WinEnableWindow(m_hFrame, TRUE);
859e65de
DW
737
738 //
739 // Deal with children
740 //
741 MoveChildren(m_vSwpClient.cy - vSwp.cy);
f45e4fad
DW
742 vEvent.SetEventObject(this);
743 GetEventHandler()->ProcessEvent(vEvent);
744 }
745 else
746 {
747 //
748 // Try to highlight the correct window (the parent)
749 //
750 if (GetParent())
751 {
752 HWND hWndParent = GetHwndOf(GetParent());
753
754 ::WinQueryWindowPos(hWndParent, &vSwp);
755 m_bIconized = vSwp.fl & SWP_MINIMIZE;
f45e4fad
DW
756 ::WinEnableWindow(hWndParent, TRUE);
757 }
758 }
759 return TRUE;
760} // end of wxTopLevelWindowOS2::Show
761
762// ----------------------------------------------------------------------------
763// wxTopLevelWindowOS2 maximize/minimize
764// ----------------------------------------------------------------------------
765
766void wxTopLevelWindowOS2::Maximize(
767 bool bMaximize
768)
769{
770 if (IsShown())
771 {
772 //
773 // Just maximize it directly
774 //
775 DoShowWindow(bMaximize ? SWP_MAXIMIZE : SWP_RESTORE);
776 }
777 else // hidden
778 {
779 //
780 // We can't maximize the hidden frame because it shows it as well, so
781 // just remember that we should do it later in this case
782 //
783 m_bMaximizeOnShow = TRUE;
784 }
785} // end of wxTopLevelWindowOS2::Maximize
786
787bool wxTopLevelWindowOS2::IsMaximized() const
788{
789 bool bIconic;
790
791 ::WinQueryWindowPos(m_hFrame, (PSWP)&m_vSwp);
792 return (m_vSwp.fl & SWP_MAXIMIZE);
793} // end of wxTopLevelWindowOS2::IsMaximized
794
795void wxTopLevelWindowOS2::Iconize(
796 bool bIconize
797)
798{
799 DoShowWindow(bIconize ? SWP_MINIMIZE : SWP_RESTORE);
800} // end of wxTopLevelWindowOS2::Iconize
801
802bool wxTopLevelWindowOS2::IsIconized() const
803{
804 // also update the current state
805 ::WinQueryWindowPos(m_hFrame, (PSWP)&m_vSwp);
806 if (m_vSwp.fl & SWP_MINIMIZE)
807 ((wxTopLevelWindow*)this)->m_bIconized = TRUE;
808 else
809 ((wxTopLevelWindow*)this)->m_bIconized = FALSE;
810 return m_bIconized;
811} // end of wxTopLevelWindowOS2::IsIconized
812
813void wxTopLevelWindowOS2::Restore()
814{
815 DoShowWindow(SWP_RESTORE);
816} // end of wxTopLevelWindowOS2::Restore
817
239c2e96
DW
818// generate an artificial resize event
819void wxTopLevelWindowOS2::SendSizeEvent()
820{
821 if (!m_bIconized)
822 {
823 RECTL vRect = wxGetWindowRect(GetHwnd());
824
825 (void)::WinPostMsg( m_hFrame
826 ,WM_SIZE
827 ,MPFROM2SHORT(vRect.xRight - vRect.xLeft, vRect.yTop - vRect.yBottom)
828 ,MPFROM2SHORT(vRect.xRight - vRect.xLeft, vRect.yTop - vRect.yBottom)
829 );
830 }
831} // end of wxTopLevelWindowOS2::SendSizeEvent
832
f45e4fad
DW
833// ----------------------------------------------------------------------------
834// wxTopLevelWindowOS2 fullscreen
835// ----------------------------------------------------------------------------
836
837bool wxTopLevelWindowOS2::ShowFullScreen(
838 bool bShow
839, long lStyle
840)
841{
842 if (bShow)
843 {
844 if (IsFullScreen())
845 return FALSE;
846
847 m_bFsIsShowing = TRUE;
848 m_lFsStyle = lStyle;
849
850 //
851 // Zap the frame borders
852 //
853
854 //
855 // Save the 'normal' window lStyle
856 //
857 m_lFsOldWindowStyle = ::WinQueryWindowULong( (HWND)GetHWND()
858 ,QWL_STYLE
859 );
860
861 //
862 // Save the old position, width & height, maximize state
863 //
864 m_vFsOldSize = GetRect();
865 m_bFsIsMaximized = IsMaximized();
866
867 //
868 // Decide which window lStyle flags to turn off
869 //
870 LONG lNewStyle = m_lFsOldWindowStyle;
871 LONG lOffFlags = 0;
872
873 if (lStyle & wxFULLSCREEN_NOBORDER)
874 lOffFlags |= FCF_BORDER;
875 if (lStyle & wxFULLSCREEN_NOCAPTION)
876 lOffFlags |= (FCF_TASKLIST | FCF_SYSMENU);
877
878 lNewStyle &= (~lOffFlags);
879
880 //
881 // Change our window style to be compatible with full-screen mode
882 //
883 ::WinSetWindowULong( (HWND)GetHWND()
884 ,QWL_STYLE
885 ,lNewStyle
886 );
887
888 //
889 // Resize to the size of the desktop
890 //
891 int nWidth;
892 int nHeight;
893 RECTL vRect = wxGetWindowRect(HWND_DESKTOP);
894
895 nWidth = vRect.xRight - vRect.xLeft;
896 nHeight = vRect.yTop - vRect.yBottom;
897
898 SetSize( nWidth
899 ,nHeight
900 );
901
902 //
903 // Now flush the window style cache and actually go full-screen
904 //
905 ::WinSetWindowPos( m_hFrame
906 ,HWND_TOP
907 ,0
908 ,0
909 ,nWidth
910 ,nHeight
911 ,SWP_SIZE | SWP_MOVE
912 );
913
914 wxSizeEvent vEvent( wxSize( nWidth
915 ,nHeight
916 )
917 ,GetId()
918 );
919
920 GetEventHandler()->ProcessEvent(vEvent);
921 return TRUE;
922 }
923 else
924 {
925 if (!IsFullScreen())
926 return FALSE;
927
928 m_bFsIsShowing = FALSE;
929 Maximize(m_bFsIsMaximized);
930 ::WinSetWindowULong( (HWND)GetHWND()
931 ,QWL_STYLE
932 ,m_lFsOldWindowStyle
933 );
934 ::WinSetWindowPos( m_hFrame
935 ,HWND_TOP
936 ,m_vFsOldSize.x
937 ,m_vFsOldSize.y
938 ,m_vFsOldSize.width
939 ,m_vFsOldSize.height
940 ,SWP_SIZE | SWP_MOVE
941 );
942 return TRUE;
943 }
944} // end of wxTopLevelWindowOS2::ShowFullScreen
945
946// ----------------------------------------------------------------------------
947// wxTopLevelWindowOS2 misc
948// ----------------------------------------------------------------------------
949
950void wxTopLevelWindowOS2::SetIcon(
951 const wxIcon& rIcon
952)
3437f881
DW
953{
954 SetIcons(wxIconBundle(rIcon));
955} // end of wxTopLevelWindowOS2::SetIcon
956
957void wxTopLevelWindowOS2::SetIcons(
958 const wxIconBundle& rIcons
959)
f45e4fad
DW
960{
961 //
962 // This sets m_icon
963 //
3437f881
DW
964 wxTopLevelWindowBase::SetIcons(rIcons);
965
966 const wxIcon& vIcon = rIcons.GetIcon(wxSize(32, 32));
f45e4fad 967
3437f881 968 if (vIcon.Ok() && vIcon.GetWidth() == 32 && vIcon.GetHeight() == 32)
f45e4fad
DW
969 {
970 ::WinSendMsg( m_hFrame
971 ,WM_SETICON
3437f881 972 ,(MPARAM)((HPOINTER)vIcon.GetHICON())
f45e4fad
DW
973 ,NULL
974 );
975 ::WinSendMsg( m_hFrame
976 ,WM_UPDATEFRAME
977 ,(MPARAM)FCF_ICON
978 ,(MPARAM)0
979 );
980 }
981} // end of wxTopLevelWindowOS2::SetIcon
982
983bool wxTopLevelWindowOS2::EnableCloseButton(
984 bool bEnable
985)
986{
987 //
988 // Get system (a.k.a. window) menu
989 //
990 HMENU hMenu = ::WinWindowFromID(m_hFrame, FID_SYSMENU);
991
992 if (!hMenu)
993 {
994 wxLogLastError(_T("GetSystemMenu"));
995 return FALSE;
996 }
997
998 //
999 // Enabling/disabling the close item from it also automatically
1000 // disables/enables the close title bar button
1001 //
1002 if (bEnable)
1003 (void)::WinSendMsg( hMenu
1004 ,MM_SETITEMATTR
1005 ,MPFROM2SHORT(SC_CLOSE, FALSE)
1006 ,MPFROM2SHORT(MIA_DISABLED, FALSE)
1007 );
1008 else
1009 (void)::WinSendMsg( hMenu
1010 ,MM_SETITEMATTR
1011 ,MPFROM2SHORT(SC_CLOSE, FALSE)
1012 ,MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED)
1013 );
1014
1015 //
1016 // Update appearance immediately
1017 //
1018 ::WinSendMsg( m_hFrame
1019 ,WM_UPDATEFRAME
1020 ,(MPARAM)FCF_MENU
1021 ,(MPARAM)0
1022 );
1023 return TRUE;
1024} // end of wxTopLevelWindowOS2::EnableCloseButton
1025