toplevel fixes to deal with base class fixes. Create interface change to support...
[wxWidgets.git] / src / os2 / toplevel.cpp
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"
38 #endif //WX_PRECOMP
39
40 #include "wx/os2/private.h"
41
42 // ----------------------------------------------------------------------------
43 // stubs for missing functions under MicroWindows
44 // ----------------------------------------------------------------------------
45
46
47 // ----------------------------------------------------------------------------
48 // globals
49 // ----------------------------------------------------------------------------
50
51 // list of all frames and modeless dialogs
52 wxWindowList wxModelessWindows;
53
54 // the name of the default wxWindows class
55 extern const wxChar* wxCanvasClassName;
56 extern const wxChar* wxFrameClassName;
57 extern void wxAssociateWinWithHandle( HWND hWnd
58 ,wxWindowOS2* pWin
59 );
60
61 // ============================================================================
62 // wxTopLevelWindowMSW implementation
63 // ============================================================================
64
65 // Dialog window proc
66 MRESULT EXPENTRY wxDlgProc( HWND WXUNUSED(hWnd)
67 ,UINT uMessage
68 ,MPARAM WXUNUSED(wParam)
69 ,MPARAM WXUNUSED(lParam)
70 )
71 {
72 if (uMessage == WM_INITDLG)
73 {
74 //
75 // For this message, returning TRUE tells system to set focus to the
76 // first control in the dialog box.
77 //
78 return (MRESULT)TRUE;
79 }
80 else
81 {
82 //
83 // For all the other ones, FALSE means that we didn't process the
84 // message
85 //
86 return (MRESULT)FALSE;
87 }
88 } // end of wxDlgProc
89
90 // ----------------------------------------------------------------------------
91 // wxTopLevelWindowOS2 creation
92 // ----------------------------------------------------------------------------
93
94 void wxTopLevelWindowOS2::Init()
95 {
96 m_bIconized = m_bMaximizeOnShow = FALSE;
97
98 //
99 // Unlike (almost?) all other windows, frames are created hidden
100 //
101 m_isShown = FALSE;
102
103 //
104 // Data to save/restore when calling ShowFullScreen
105 m_lFsStyle = 0;
106 m_lFsOldWindowStyle = 0;
107 m_bFsIsMaximized = FALSE;
108 m_bFsIsShowing = FALSE;
109
110 m_hFrame = NULLHANDLE;
111 memset(&m_vSwp, 0, sizeof(SWP));
112 memset(&m_vSwpClient, 0, sizeof(SWP));
113 } // end of wxTopLevelWindowIOS2::Init
114
115 long wxTopLevelWindowOS2::OS2GetCreateWindowFlags(
116 long* plExflags
117 ) const
118 {
119 long lStyle = GetWindowStyle();
120 long lMsflags = 0;
121
122 if (lStyle == wxDEFAULT_FRAME_STYLE)
123 lMsflags = FCF_SIZEBORDER | FCF_TITLEBAR | FCF_SYSMENU |
124 FCF_MINMAX | FCF_TASKLIST;
125 else
126 {
127 if ((lStyle & wxCAPTION) == wxCAPTION)
128 lMsflags = FCF_TASKLIST;
129 else
130 lMsflags = FCF_NOMOVEWITHOWNER;
131
132 if ((lStyle & wxVSCROLL) == wxVSCROLL)
133 lMsflags |= FCF_VERTSCROLL;
134 if ((lStyle & wxHSCROLL) == wxHSCROLL)
135 lMsflags |= FCF_HORZSCROLL;
136 if (lStyle & wxMINIMIZE_BOX)
137 lMsflags |= FCF_MINBUTTON;
138 if (lStyle & wxMAXIMIZE_BOX)
139 lMsflags |= FCF_MAXBUTTON;
140 if (lStyle & wxTHICK_FRAME)
141 lMsflags |= FCF_DLGBORDER;
142 if (lStyle & wxSYSTEM_MENU)
143 lMsflags |= FCF_SYSMENU;
144 if (lStyle & wxCAPTION)
145 lMsflags |= FCF_TASKLIST;
146 if (lStyle & wxCLIP_CHILDREN)
147 {
148 // Invalid for frame windows under PM
149 }
150
151 if (lStyle & wxTINY_CAPTION_VERT)
152 lMsflags |= FCF_TASKLIST;
153 if (lStyle & wxTINY_CAPTION_HORIZ)
154 lMsflags |= FCF_TASKLIST;
155
156 if ((lStyle & wxTHICK_FRAME) == 0)
157 lMsflags |= FCF_BORDER;
158 if (lStyle & wxFRAME_TOOL_WINDOW)
159 *plExflags = kFrameToolWindow;
160
161 if (lStyle & wxSTAY_ON_TOP)
162 lMsflags |= FCF_SYSMODAL;
163 }
164 return lMsflags;
165 } // end of wxTopLevelWindowOS2::OS2GetCreateWindowFlags
166
167 bool wxTopLevelWindowOS2::CreateDialog(
168 ULONG ulDlgTemplate
169 , const wxString& rsTitle
170 , const wxPoint& rPos
171 , const wxSize& rSize
172 )
173 {
174 wxWindow* pParent = GetParent();
175
176 //
177 // For the dialogs without wxDIALOG_NO_PARENT style, use the top level
178 // app window as parent - this avoids creating modal dialogs without
179 // parent
180 //
181 if (!pParent && !(GetWindowStyleFlag() & wxDIALOG_NO_PARENT))
182 {
183 pParent = wxTheApp->GetTopWindow();
184
185 if (pParent)
186 {
187 //
188 // Don't use transient windows as parents, this is dangerous as it
189 // can lead to a crash if the parent is destroyed before the child
190 //
191 // also don't use the window which is currently hidden as then the
192 // dialog would be hidden as well
193 if ((pParent->GetExtraStyle() & wxWS_EX_TRANSIENT) ||
194 !pParent->IsShown())
195 {
196 pParent = NULL;
197 }
198 }
199 }
200
201 HWND hWndDlg;
202 HWND hWndParent;
203
204 if (pParent)
205 hWndParent = GetHwndOf(pParent);
206 else
207 hWndParent = HWND_DESKTOP;
208
209 hWndDlg = ::WinLoadDlg( hWndParent
210 ,hWndParent
211 ,(PFNWP)wxDlgProc
212 ,NULL
213 ,(ULONG)ulDlgTemplate
214 ,(PVOID)this
215 );
216
217 m_hWnd = (WXHWND) hWndDlg;
218
219 if ( !m_hWnd )
220 {
221 wxFAIL_MSG(_("Did you forget to include wx/os2/wx.rc in your resources?"));
222
223 wxLogSysError(_("Can't create dialog using template '%ul'"), ulDlgTemplate);
224
225 return FALSE;
226 }
227
228 //
229 // Move the dialog to its initial position without forcing repainting
230 //
231 int nX;
232 int nY;
233 int nWidth;
234 int nHeight;
235
236 if (!OS2GetCreateWindowCoords( rPos
237 ,rSize
238 ,nX
239 ,nY
240 ,nWidth
241 ,nHeight
242 ))
243 {
244 nX = nWidth = (int)CW_USEDEFAULT;
245 }
246
247 //
248 // We can't use CW_USEDEFAULT here as we're not calling CreateWindow()
249 // and passing CW_USEDEFAULT to MoveWindow() results in resizing the
250 // window to (0, 0) size which breaks quite a lot of things, e.g. the
251 // sizer calculation in wxSizer::Fit()
252 //
253 if (nWidth == (int)CW_USEDEFAULT)
254 {
255 //
256 // The exact number doesn't matter, the dialog will be resized
257 // again soon anyhow but it should be big enough to allow
258 // calculation relying on "totalSize - clientSize > 0" work, i.e.
259 // at least greater than the title bar height
260 //
261 nWidth = nHeight = 100;
262 }
263 if (nX == (int)CW_USEDEFAULT)
264 {
265 //
266 // Centre it on the screen - what else can we do?
267 //
268 wxSize vSizeDpy = wxGetDisplaySize();
269
270 nX = (vSizeDpy.x - nWidth) / 2;
271 nY = (vSizeDpy.y - nHeight) / 2;
272 }
273 ::WinSetWindowPos( GetHwnd()
274 ,HWND_TOP
275 ,nX
276 ,nY
277 ,nWidth
278 ,nHeight
279 ,SWP_MOVE | SWP_SIZE | SWP_ZORDER | SWP_SHOW
280 );
281 if (!rsTitle.IsNull())
282 {
283 ::WinSetWindowText(GetHwnd(), rsTitle.c_str());
284 }
285 SubclassWin(m_hWnd);
286 return TRUE;
287 } // end of wxTopLevelWindowOS2::CreateDialog
288
289 bool wxTopLevelWindowOS2::CreateFrame(
290 const wxString& rsTitle
291 , const wxPoint& rPos
292 , const wxSize& rSize
293 )
294 {
295 long lExflags;
296 long lFlags = OS2GetCreateWindowFlags(&lExflags);
297 long lStyle = GetWindowStyleFlag();
298 int nX = rPos.x;
299 int nY = rPos.y;
300 int nWidth = rSize.x;
301 int nHeight = rSize.y;
302 ULONG ulStyleFlags = 0L;
303 ERRORID vError;
304 wxString sError;
305 wxWindow* pParent = GetParent();
306 HWND hParent;
307 HWND hFrame;
308 HWND hClient;
309
310 if (pParent)
311 hParent = GetHwndOf(pParent);
312 else
313 hParent = HWND_DESKTOP;
314
315 if ((lStyle & wxMINIMIZE) || (lStyle & wxICONIZE))
316 ulStyleFlags |= WS_MINIMIZED;
317 if (lStyle & wxMAXIMIZE)
318 ulStyleFlags |= WS_MAXIMIZED;
319
320 //
321 // Clear the visible flag, we always call show
322 //
323 ulStyleFlags &= (unsigned long)~WS_VISIBLE;
324 m_bIconized = FALSE;
325
326 //
327 // Create the frame window: We break ranks with other ports now
328 // and instead of calling down into the base wxWindow class' OS2Create
329 // we do all our own stuff here. We will set the needed pieces
330 // of wxWindow manually, here.
331 //
332
333 hFrame = ::WinCreateStdWindow( hParent
334 ,ulStyleFlags // frame-window style
335 ,(PULONG)&lFlags // window style
336 ,(PSZ)wxFrameClassName // class name
337 ,(PSZ)rsTitle.c_str() // window title
338 ,0L // default client style
339 ,NULLHANDLE // resource in executable file
340 ,0 // resource id
341 ,&hClient // receives client window handle
342 );
343 if (!hFrame)
344 {
345 vError = ::WinGetLastError(vHabmain);
346 sError = wxPMErrorToStr(vError);
347 wxLogError("Error creating frame. Error: %s\n", sError);
348 return FALSE;
349 }
350
351 //
352 // wxWindow class' m_hWnd set here and needed associations
353 //
354 m_hFrame = hFrame;
355 m_hWnd = hClient;
356 wxAssociateWinWithHandle(m_hWnd, this);
357 wxAssociateWinWithHandle(m_hFrame, this);
358
359 m_backgroundColour.Set(wxString("GREY"));
360
361 LONG lColor = (LONG)m_backgroundColour.GetPixel();
362
363 if (!::WinSetPresParam( m_hWnd
364 ,PP_BACKGROUNDCOLOR
365 ,sizeof(LONG)
366 ,(PVOID)&lColor
367 ))
368 {
369 vError = ::WinGetLastError(vHabmain);
370 sError = wxPMErrorToStr(vError);
371 wxLogError("Error creating frame. Error: %s\n", sError);
372 return FALSE;
373 }
374
375 //
376 // Now need to subclass window. Instead of calling the SubClassWin in wxWindow
377 // we manually subclass here because we don't want to use the main wxWndProc
378 // by default
379 //
380 m_fnOldWndProc = (WXFARPROC) ::WinSubclassWindow(m_hFrame, (PFNWP)wxFrameMainWndProc);
381
382 //
383 // Now size everything. If adding a menu the client will need to be resized.
384 //
385
386 if (pParent)
387 {
388 nY = pParent->GetSize().y - (nY + nHeight);
389 }
390 else
391 {
392 RECTL vRect;
393
394 ::WinQueryWindowRect(HWND_DESKTOP, &vRect);
395 nY = vRect.yTop - (nY + nHeight);
396 }
397 if (!::WinSetWindowPos( m_hFrame
398 ,HWND_TOP
399 ,nX
400 ,nY
401 ,nWidth
402 ,nHeight
403 ,SWP_SIZE | SWP_MOVE | SWP_ACTIVATE | SWP_ZORDER
404 ))
405 {
406 vError = ::WinGetLastError(vHabmain);
407 sError = wxPMErrorToStr(vError);
408 wxLogError("Error sizing frame. Error: %s\n", sError);
409 return FALSE;
410 }
411 return TRUE;
412 } // end of wxTopLevelWindowOS2::CreateFrame
413
414 bool wxTopLevelWindowOS2::Create(
415 wxWindow* pParent
416 , wxWindowID vId
417 , const wxString& rsTitle
418 , const wxPoint& rPos
419 , const wxSize& rSize
420 , long lStyle
421 , const wxString& rsName
422 )
423 {
424 //
425 // Init our fields
426 //
427 Init();
428 m_windowStyle = lStyle;
429 SetName(rsName);
430 m_windowId = vId == -1 ? NewControlId() : vId;
431 wxTopLevelWindows.Append(this);
432 if (pParent)
433 pParent->AddChild(this);
434
435 if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG)
436 {
437 //
438 // We have different dialog templates to allows creation of dialogs
439 // with & without captions under OS2indows, resizeable or not (but a
440 // resizeable dialog always has caption - otherwise it would look too
441 // strange)
442 //
443 ULONG ulDlgTemplate;
444
445 if (lStyle & wxRESIZE_BORDER)
446 ulDlgTemplate = (ULONG)kResizeableDialog;
447 else if (lStyle & wxCAPTION)
448 ulDlgTemplate = (ULONG)kCaptionDialog;
449 else
450 ulDlgTemplate = (ULONG)kNoCaptionDialog;
451 return CreateDialog( ulDlgTemplate
452 ,rsTitle
453 ,rPos
454 ,rSize
455 );
456 }
457 else // !dialog
458 {
459 return CreateFrame( rsTitle
460 ,rPos
461 ,rSize
462 );
463 }
464 } // end of wxTopLevelWindowOS2::Create
465
466 wxTopLevelWindowOS2::~wxTopLevelWindowOS2()
467 {
468 wxTopLevelWindows.DeleteObject(this);
469
470 if (wxModelessWindows.Find(this))
471 wxModelessWindows.DeleteObject(this);
472
473 //
474 // If this is the last top-level window, exit.
475 //
476 if (wxTheApp && (wxTopLevelWindows.Number() == 0))
477 {
478 wxTheApp->SetTopWindow(NULL);
479 if ( wxTheApp->GetExitOnFrameDelete() )
480 {
481 ::WinPostMsg(NULL, WM_QUIT, 0, 0);
482 }
483 }
484 } // end of wxTopLevelWindowOS2::~wxTopLevelWindowOS2
485
486 //
487 // IF we have child controls in the Frame's client we need to alter
488 // the y position, because, OS/2 controls are positioned relative to
489 // wxWindows orgin (top left) not the OS/2 origin (bottom left)
490 //
491 void wxTopLevelWindowOS2::AlterChildPos()
492 {
493 //
494 // OS/2 is the only OS concerned about this
495 //
496 wxWindow* pChild = NULL;
497 wxControl* pCtrl = NULL;
498 RECTL vRect;
499 SWP vSwp;
500
501 ::WinQueryWindowRect(GetHwnd(), &vRect);
502 for (wxWindowList::Node* pNode = GetChildren().GetFirst();
503 pNode;
504 pNode = pNode->GetNext())
505 {
506 wxWindow* pChild = pNode->GetData();
507
508 ::WinQueryWindowPos(pChild->GetHWND(), &vSwp);
509 vSwp.y += (vRect.yTop - m_vSwpClient.cy);
510 if (pChild->IsKindOf(CLASSINFO(wxControl)))
511 {
512 pCtrl = wxDynamicCast(pChild, wxControl);
513 //
514 // Must deal with controls that have margins like ENTRYFIELD. The SWP
515 // struct of such a control will have and origin offset from its intended
516 // position by the width of the margins.
517 //
518 vSwp.y -= pCtrl->GetYComp();
519 vSwp.x -= pCtrl->GetXComp();
520 }
521 ::WinSetWindowPos( pChild->GetHWND()
522 ,HWND_TOP
523 ,vSwp.x
524 ,vSwp.y
525 ,vSwp.cx
526 ,vSwp.cy
527 ,SWP_MOVE
528 );
529 ::WinQueryWindowPos(pChild->GetHWND(), &vSwp);
530 pChild = NULL;
531 }
532 ::WinQueryWindowPos(GetHwnd(), &m_vSwpClient);
533 } // end of wxTopLevelWindowOS2::AlterChildPos
534
535 void wxTopLevelWindowOS2::UpdateInternalSize(
536 wxWindow* pChild
537 , int nHeight
538 )
539 {
540 pChild->MoveChildren(m_vSwpClient.cy - nHeight);
541 ::WinQueryWindowPos(GetHwnd(), &m_vSwpClient);
542 } // end of wxTopLevelWindowOS2::UpdateInternalSize
543
544 // ----------------------------------------------------------------------------
545 // wxTopLevelWindowOS2 client size
546 // ----------------------------------------------------------------------------
547
548 void wxTopLevelWindowOS2::DoSetClientSize(
549 int nWidth
550 , int nHeight
551 )
552 {
553 //
554 // Call GetClientAreaOrigin() to take the toolbar into account
555 //
556 wxPoint vPt = GetClientAreaOrigin();
557
558 nWidth += vPt.x;
559 nHeight += vPt.y;
560
561 wxWindow::DoSetClientSize( nWidth
562 ,nHeight
563 );
564 } // end of wxTopLevelWindowOS2::DoSetClientSize
565
566 void wxTopLevelWindowOS2::DoGetClientSize(
567 int* pnX
568 , int* pnY
569 ) const
570 {
571 wxWindow::DoGetClientSize( pnX
572 ,pnY
573 );
574
575 wxPoint vPt = GetClientAreaOrigin();
576
577 if (pnX)
578 *pnX -= vPt.x;
579
580 if (pnY)
581 *pnY += vPt.y;
582 } // end of wxTopLevelWindowOS2::DoGetClientSize
583
584 // ----------------------------------------------------------------------------
585 // wxTopLevelWindowOS2 showing
586 // ----------------------------------------------------------------------------
587
588 void wxTopLevelWindowOS2::DoShowWindow(
589 int nShowCmd
590 )
591 {
592 ::WinShowWindow(m_hFrame, (BOOL)nShowCmd);
593 m_bIconized = nShowCmd == SWP_MINIMIZE;
594 } // end of wxTopLevelWindowOS2::DoShowWindow
595
596 bool wxTopLevelWindowOS2::Show(
597 bool bShow
598 )
599 {
600 int nShowCmd;
601 SWP vSwp;
602 RECTL vRect;
603
604 if (bShow)
605 {
606 if (m_bMaximizeOnShow)
607 {
608 nShowCmd = SWP_SHOW;
609 m_bMaximizeOnShow = FALSE;
610 }
611 else
612 {
613 nShowCmd = SWP_HIDE;
614 }
615 }
616 else // hide
617 {
618 nShowCmd = SWP_HIDE;
619 }
620 DoShowWindow(nShowCmd);
621
622 if (bShow)
623 {
624 wxActivateEvent vEvent(wxEVT_ACTIVATE, TRUE, m_windowId);
625
626 ::WinQueryWindowPos(m_hFrame, &vSwp);
627 m_bIconized = vSwp.fl & SWP_MINIMIZE;
628 ::WinQueryWindowPos(m_hWnd, &m_vSwpClient);
629 ::WinSendMsg(m_hFrame, WM_UPDATEFRAME, (MPARAM)~0, 0);
630 ::WinEnableWindow(m_hFrame, TRUE);
631 vEvent.SetEventObject(this);
632 GetEventHandler()->ProcessEvent(vEvent);
633 }
634 else
635 {
636 //
637 // Try to highlight the correct window (the parent)
638 //
639 if (GetParent())
640 {
641 HWND hWndParent = GetHwndOf(GetParent());
642
643 ::WinQueryWindowPos(hWndParent, &vSwp);
644 m_bIconized = vSwp.fl & SWP_MINIMIZE;
645 if (hWndParent)
646 ::WinSetWindowPos( hWndParent
647 ,HWND_TOP
648 ,vSwp.x
649 ,vSwp.y
650 ,vSwp.cx
651 ,vSwp.cy
652 ,SWP_ZORDER | SWP_ACTIVATE | SWP_SHOW | SWP_MOVE
653 );
654 ::WinEnableWindow(hWndParent, TRUE);
655 }
656 }
657 return TRUE;
658 } // end of wxTopLevelWindowOS2::Show
659
660 // ----------------------------------------------------------------------------
661 // wxTopLevelWindowOS2 maximize/minimize
662 // ----------------------------------------------------------------------------
663
664 void wxTopLevelWindowOS2::Maximize(
665 bool bMaximize
666 )
667 {
668 if (IsShown())
669 {
670 //
671 // Just maximize it directly
672 //
673 DoShowWindow(bMaximize ? SWP_MAXIMIZE : SWP_RESTORE);
674 }
675 else // hidden
676 {
677 //
678 // We can't maximize the hidden frame because it shows it as well, so
679 // just remember that we should do it later in this case
680 //
681 m_bMaximizeOnShow = TRUE;
682 }
683 } // end of wxTopLevelWindowOS2::Maximize
684
685 bool wxTopLevelWindowOS2::IsMaximized() const
686 {
687 bool bIconic;
688
689 ::WinQueryWindowPos(m_hFrame, (PSWP)&m_vSwp);
690 return (m_vSwp.fl & SWP_MAXIMIZE);
691 } // end of wxTopLevelWindowOS2::IsMaximized
692
693 void wxTopLevelWindowOS2::Iconize(
694 bool bIconize
695 )
696 {
697 DoShowWindow(bIconize ? SWP_MINIMIZE : SWP_RESTORE);
698 } // end of wxTopLevelWindowOS2::Iconize
699
700 bool wxTopLevelWindowOS2::IsIconized() const
701 {
702 // also update the current state
703 ::WinQueryWindowPos(m_hFrame, (PSWP)&m_vSwp);
704 if (m_vSwp.fl & SWP_MINIMIZE)
705 ((wxTopLevelWindow*)this)->m_bIconized = TRUE;
706 else
707 ((wxTopLevelWindow*)this)->m_bIconized = FALSE;
708 return m_bIconized;
709 } // end of wxTopLevelWindowOS2::IsIconized
710
711 void wxTopLevelWindowOS2::Restore()
712 {
713 DoShowWindow(SWP_RESTORE);
714 } // end of wxTopLevelWindowOS2::Restore
715
716 // ----------------------------------------------------------------------------
717 // wxTopLevelWindowOS2 fullscreen
718 // ----------------------------------------------------------------------------
719
720 bool wxTopLevelWindowOS2::ShowFullScreen(
721 bool bShow
722 , long lStyle
723 )
724 {
725 if (bShow)
726 {
727 if (IsFullScreen())
728 return FALSE;
729
730 m_bFsIsShowing = TRUE;
731 m_lFsStyle = lStyle;
732
733 //
734 // Zap the frame borders
735 //
736
737 //
738 // Save the 'normal' window lStyle
739 //
740 m_lFsOldWindowStyle = ::WinQueryWindowULong( (HWND)GetHWND()
741 ,QWL_STYLE
742 );
743
744 //
745 // Save the old position, width & height, maximize state
746 //
747 m_vFsOldSize = GetRect();
748 m_bFsIsMaximized = IsMaximized();
749
750 //
751 // Decide which window lStyle flags to turn off
752 //
753 LONG lNewStyle = m_lFsOldWindowStyle;
754 LONG lOffFlags = 0;
755
756 if (lStyle & wxFULLSCREEN_NOBORDER)
757 lOffFlags |= FCF_BORDER;
758 if (lStyle & wxFULLSCREEN_NOCAPTION)
759 lOffFlags |= (FCF_TASKLIST | FCF_SYSMENU);
760
761 lNewStyle &= (~lOffFlags);
762
763 //
764 // Change our window style to be compatible with full-screen mode
765 //
766 ::WinSetWindowULong( (HWND)GetHWND()
767 ,QWL_STYLE
768 ,lNewStyle
769 );
770
771 //
772 // Resize to the size of the desktop
773 //
774 int nWidth;
775 int nHeight;
776 RECTL vRect = wxGetWindowRect(HWND_DESKTOP);
777
778 nWidth = vRect.xRight - vRect.xLeft;
779 nHeight = vRect.yTop - vRect.yBottom;
780
781 SetSize( nWidth
782 ,nHeight
783 );
784
785 //
786 // Now flush the window style cache and actually go full-screen
787 //
788 ::WinSetWindowPos( m_hFrame
789 ,HWND_TOP
790 ,0
791 ,0
792 ,nWidth
793 ,nHeight
794 ,SWP_SIZE | SWP_MOVE
795 );
796
797 wxSizeEvent vEvent( wxSize( nWidth
798 ,nHeight
799 )
800 ,GetId()
801 );
802
803 GetEventHandler()->ProcessEvent(vEvent);
804 return TRUE;
805 }
806 else
807 {
808 if (!IsFullScreen())
809 return FALSE;
810
811 m_bFsIsShowing = FALSE;
812 Maximize(m_bFsIsMaximized);
813 ::WinSetWindowULong( (HWND)GetHWND()
814 ,QWL_STYLE
815 ,m_lFsOldWindowStyle
816 );
817 ::WinSetWindowPos( m_hFrame
818 ,HWND_TOP
819 ,m_vFsOldSize.x
820 ,m_vFsOldSize.y
821 ,m_vFsOldSize.width
822 ,m_vFsOldSize.height
823 ,SWP_SIZE | SWP_MOVE
824 );
825 return TRUE;
826 }
827 } // end of wxTopLevelWindowOS2::ShowFullScreen
828
829 // ----------------------------------------------------------------------------
830 // wxTopLevelWindowOS2 misc
831 // ----------------------------------------------------------------------------
832
833 void wxTopLevelWindowOS2::SetIcon(
834 const wxIcon& rIcon
835 )
836 {
837 //
838 // This sets m_icon
839 //
840 wxTopLevelWindowBase::SetIcon(rIcon);
841
842 if (m_icon.Ok())
843 {
844 ::WinSendMsg( m_hFrame
845 ,WM_SETICON
846 ,(MPARAM)((HPOINTER)m_icon.GetHICON())
847 ,NULL
848 );
849 ::WinSendMsg( m_hFrame
850 ,WM_UPDATEFRAME
851 ,(MPARAM)FCF_ICON
852 ,(MPARAM)0
853 );
854 }
855 } // end of wxTopLevelWindowOS2::SetIcon
856
857 bool wxTopLevelWindowOS2::EnableCloseButton(
858 bool bEnable
859 )
860 {
861 //
862 // Get system (a.k.a. window) menu
863 //
864 HMENU hMenu = ::WinWindowFromID(m_hFrame, FID_SYSMENU);
865
866 if (!hMenu)
867 {
868 wxLogLastError(_T("GetSystemMenu"));
869 return FALSE;
870 }
871
872 //
873 // Enabling/disabling the close item from it also automatically
874 // disables/enables the close title bar button
875 //
876 if (bEnable)
877 (void)::WinSendMsg( hMenu
878 ,MM_SETITEMATTR
879 ,MPFROM2SHORT(SC_CLOSE, FALSE)
880 ,MPFROM2SHORT(MIA_DISABLED, FALSE)
881 );
882 else
883 (void)::WinSendMsg( hMenu
884 ,MM_SETITEMATTR
885 ,MPFROM2SHORT(SC_CLOSE, FALSE)
886 ,MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED)
887 );
888
889 //
890 // Update appearance immediately
891 //
892 ::WinSendMsg( m_hFrame
893 ,WM_UPDATEFRAME
894 ,(MPARAM)FCF_MENU
895 ,(MPARAM)0
896 );
897 return TRUE;
898 } // end of wxTopLevelWindowOS2::EnableCloseButton
899