New positioning code, eliminating a lot of extra, unnecessary methods
[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 #include "wx/control.h"
39 #endif //WX_PRECOMP
40
41 #include "wx/os2/private.h"
42
43 // ----------------------------------------------------------------------------
44 // stubs for missing functions under MicroWindows
45 // ----------------------------------------------------------------------------
46
47
48 // ----------------------------------------------------------------------------
49 // globals
50 // ----------------------------------------------------------------------------
51
52 // list of all frames and modeless dialogs
53 wxWindowList wxModelessWindows;
54
55 // the name of the default wxWindows class
56 extern void wxAssociateWinWithHandle( HWND hWnd
57 ,wxWindowOS2* pWin
58 );
59 bool wxTopLevelWindowOS2::m_sbInitialized = FALSE;
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 hWndOwner;
203
204 if (pParent)
205 hWndOwner = GetHwndOf(pParent);
206 else
207 hWndOwner = HWND_DESKTOP;
208
209 hWndDlg = ::WinLoadDlg( HWND_DESKTOP
210 ,hWndOwner
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 m_backgroundColour.Set(wxString("LIGHT GREY"));
274
275 LONG lColor = (LONG)m_backgroundColour.GetPixel();
276
277 if (!::WinSetPresParam( m_hWnd
278 ,PP_BACKGROUNDCOLOR
279 ,sizeof(LONG)
280 ,(PVOID)&lColor
281 ))
282 {
283 return FALSE;
284 }
285
286 ::WinSetWindowPos( GetHwnd()
287 ,HWND_TOP
288 ,nX
289 ,nY
290 ,nWidth
291 ,nHeight
292 ,SWP_MOVE | SWP_SIZE | SWP_ZORDER | SWP_SHOW
293 );
294 ::WinQueryWindowPos(GetHwnd(), GetSwp());
295 m_hFrame = m_hWnd;
296 SubclassWin(m_hWnd);
297 return TRUE;
298 } // end of wxTopLevelWindowOS2::CreateDialog
299
300 bool wxTopLevelWindowOS2::CreateFrame(
301 const wxString& rsTitle
302 , const wxPoint& rPos
303 , const wxSize& rSize
304 )
305 {
306 long lExflags;
307 long lFlags = OS2GetCreateWindowFlags(&lExflags);
308 long lStyle = GetWindowStyleFlag();
309 int nX = rPos.x;
310 int nY = rPos.y;
311 int nWidth = rSize.x;
312 int nHeight = rSize.y;
313 ULONG ulStyleFlags = 0L;
314 ERRORID vError;
315 wxString sError;
316 wxWindow* pParent = GetParent();
317 HWND hParent;
318 HWND hFrame;
319 HWND hClient;
320
321 if (pParent)
322 hParent = GetHwndOf(pParent);
323 else
324 hParent = HWND_DESKTOP;
325
326 if ((lStyle & wxMINIMIZE) || (lStyle & wxICONIZE))
327 ulStyleFlags |= WS_MINIMIZED;
328 if (lStyle & wxMAXIMIZE)
329 ulStyleFlags |= WS_MAXIMIZED;
330
331 //
332 // Clear the visible flag, we always call show
333 //
334 ulStyleFlags &= (unsigned long)~WS_VISIBLE;
335 m_bIconized = FALSE;
336
337 //
338 // Create the frame window: We break ranks with other ports now
339 // and instead of calling down into the base wxWindow class' OS2Create
340 // we do all our own stuff here. We will set the needed pieces
341 // of wxWindow manually, here.
342 //
343
344 hFrame = ::WinCreateStdWindow( hParent
345 ,ulStyleFlags // frame-window style
346 ,(PULONG)&lFlags // window style
347 ,(PSZ)wxFrameClassName // class name
348 ,(PSZ)rsTitle.c_str() // window title
349 ,0L // default client style
350 ,NULLHANDLE // resource in executable file
351 ,0 // resource id
352 ,&hClient // receives client window handle
353 );
354 if (!hFrame)
355 {
356 vError = ::WinGetLastError(vHabmain);
357 sError = wxPMErrorToStr(vError);
358 wxLogError("Error creating frame. Error: %s\n", sError);
359 return FALSE;
360 }
361
362 //
363 // wxWindow class' m_hWnd set here and needed associations
364 //
365 m_hFrame = hFrame;
366 m_hWnd = hClient;
367 wxAssociateWinWithHandle(m_hWnd, this);
368 wxAssociateWinWithHandle(m_hFrame, this);
369
370 m_backgroundColour.Set(wxString("MEDIUM GREY"));
371
372 LONG lColor = (LONG)m_backgroundColour.GetPixel();
373
374 if (!::WinSetPresParam( m_hWnd
375 ,PP_BACKGROUNDCOLOR
376 ,sizeof(LONG)
377 ,(PVOID)&lColor
378 ))
379 {
380 vError = ::WinGetLastError(vHabmain);
381 sError = wxPMErrorToStr(vError);
382 wxLogError("Error creating frame. Error: %s\n", sError);
383 return FALSE;
384 }
385
386 //
387 // Now need to subclass window. Instead of calling the SubClassWin in wxWindow
388 // we manually subclass here because we don't want to use the main wxWndProc
389 // by default
390 //
391 m_fnOldWndProc = (WXFARPROC) ::WinSubclassWindow(m_hFrame, (PFNWP)wxFrameMainWndProc);
392
393 //
394 // Now size everything. If adding a menu the client will need to be resized.
395 //
396
397 if (pParent)
398 {
399 nY = pParent->GetSize().y - (nY + nHeight);
400 }
401 else
402 {
403 RECTL vRect;
404
405 ::WinQueryWindowRect(HWND_DESKTOP, &vRect);
406 nY = vRect.yTop - (nY + nHeight);
407 }
408 if (!::WinSetWindowPos( m_hFrame
409 ,HWND_TOP
410 ,nX
411 ,nY
412 ,nWidth
413 ,nHeight
414 ,SWP_SIZE | SWP_MOVE | SWP_ACTIVATE | SWP_ZORDER
415 ))
416 {
417 vError = ::WinGetLastError(vHabmain);
418 sError = wxPMErrorToStr(vError);
419 wxLogError("Error sizing frame. Error: %s\n", sError);
420 return FALSE;
421 }
422 lStyle = ::WinQueryWindowULong( m_hWnd
423 ,QWL_STYLE
424 );
425 lStyle |= WS_CLIPCHILDREN;
426 ::WinSetWindowULong( m_hWnd
427 ,QWL_STYLE
428 ,lStyle
429 );
430 return TRUE;
431 } // end of wxTopLevelWindowOS2::CreateFrame
432
433 bool wxTopLevelWindowOS2::Create(
434 wxWindow* pParent
435 , wxWindowID vId
436 , const wxString& rsTitle
437 , const wxPoint& rPos
438 , const wxSize& rSize
439 , long lStyle
440 , const wxString& rsName
441 )
442 {
443 //
444 // Init our fields
445 //
446 Init();
447 m_windowStyle = lStyle;
448 SetName(rsName);
449 m_windowId = vId == -1 ? NewControlId() : vId;
450 wxTopLevelWindows.Append(this);
451 if (pParent)
452 pParent->AddChild(this);
453
454 if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG)
455 {
456 //
457 // We have different dialog templates to allows creation of dialogs
458 // with & without captions under OS2indows, resizeable or not (but a
459 // resizeable dialog always has caption - otherwise it would look too
460 // strange)
461 //
462 ULONG ulDlgTemplate;
463
464 if (lStyle & wxRESIZE_BORDER)
465 ulDlgTemplate = (ULONG)kResizeableDialog;
466 else if (lStyle & wxCAPTION)
467 ulDlgTemplate = (ULONG)kCaptionDialog;
468 else
469 ulDlgTemplate = (ULONG)kNoCaptionDialog;
470 return CreateDialog( ulDlgTemplate
471 ,rsTitle
472 ,rPos
473 ,rSize
474 );
475 }
476 else // !dialog
477 {
478 return CreateFrame( rsTitle
479 ,rPos
480 ,rSize
481 );
482 }
483 } // end of wxTopLevelWindowOS2::Create
484
485 wxTopLevelWindowOS2::~wxTopLevelWindowOS2()
486 {
487 wxTopLevelWindows.DeleteObject(this);
488
489 if (wxModelessWindows.Find(this))
490 wxModelessWindows.DeleteObject(this);
491
492 //
493 // If this is the last top-level window, exit.
494 //
495 if (wxTheApp && (wxTopLevelWindows.Number() == 0))
496 {
497 wxTheApp->SetTopWindow(NULL);
498 if ( wxTheApp->GetExitOnFrameDelete() )
499 {
500 ::WinPostMsg(NULL, WM_QUIT, 0, 0);
501 }
502 }
503 } // end of wxTopLevelWindowOS2::~wxTopLevelWindowOS2
504
505 // ----------------------------------------------------------------------------
506 // wxTopLevelWindowOS2 client size
507 // ----------------------------------------------------------------------------
508
509 void wxTopLevelWindowOS2::DoSetClientSize(
510 int nWidth
511 , int nHeight
512 )
513 {
514 //
515 // Call GetClientAreaOrigin() to take the toolbar into account
516 //
517 wxPoint vPt = GetClientAreaOrigin();
518
519 nWidth += vPt.x;
520 nHeight += vPt.y;
521
522 wxWindow::DoSetClientSize( nWidth
523 ,nHeight
524 );
525 } // end of wxTopLevelWindowOS2::DoSetClientSize
526
527 void wxTopLevelWindowOS2::DoGetClientSize(
528 int* pnX
529 , int* pnY
530 ) const
531 {
532 wxWindow::DoGetClientSize( pnX
533 ,pnY
534 );
535
536 wxPoint vPt = GetClientAreaOrigin();
537
538 if (pnX)
539 *pnX -= vPt.x;
540
541 if (pnY)
542 *pnY += vPt.y;
543 } // end of wxTopLevelWindowOS2::DoGetClientSize
544
545 // ----------------------------------------------------------------------------
546 // wxTopLevelWindowOS2 showing
547 // ----------------------------------------------------------------------------
548
549 void wxTopLevelWindowOS2::DoShowWindow(
550 int nShowCmd
551 )
552 {
553 ::WinShowWindow(m_hFrame, (BOOL)(nShowCmd & SWP_SHOW));
554
555 //
556 // Need to artificially send a size event as wxApps often expect to do some
557 // final child control sizing
558 SendSizeEvent();
559 m_bIconized = nShowCmd == SWP_MINIMIZE;
560 } // end of wxTopLevelWindowOS2::DoShowWindow
561
562 bool wxTopLevelWindowOS2::Show(
563 bool bShow
564 )
565 {
566 int nShowCmd;
567 SWP vSwp;
568 RECTL vRect;
569
570 if (bShow)
571 {
572 if (m_bMaximizeOnShow)
573 {
574 nShowCmd = SWP_MAXIMIZE;
575 m_bMaximizeOnShow = FALSE;
576 }
577 else
578 {
579 nShowCmd = SWP_SHOW;
580 }
581 }
582 else // hide
583 {
584 nShowCmd = SWP_HIDE;
585 }
586 DoShowWindow(nShowCmd);
587
588 if (bShow)
589 {
590 wxActivateEvent vEvent(wxEVT_ACTIVATE, TRUE, m_windowId);
591
592 ::WinQueryWindowPos(m_hFrame, &vSwp);
593 m_bIconized = vSwp.fl & SWP_MINIMIZE;
594 ::WinQueryWindowPos(m_hWnd, &m_vSwpClient);
595 ::WinSendMsg(m_hFrame, WM_UPDATEFRAME, (MPARAM)~0, 0);
596 ::WinEnableWindow(m_hFrame, TRUE);
597
598 //
599 // Deal with children
600 //
601 MoveChildren(m_vSwpClient.cy - vSwp.cy);
602
603
604 //
605 // Need to handle the case of a single child that not a control
606 // as this is probably a panel with its own children
607 //
608 if (GetChildren().GetCount() > 0)
609 {
610 for (wxWindowList::Node* pNode = GetChildren().GetFirst();
611 pNode;
612 pNode = pNode->GetNext())
613 {
614 wxWindow* pChild = pNode->GetData();
615
616 if ( GetChildren().GetCount() == 1 &&
617 !pChild->IsKindOf(CLASSINFO(wxControl))
618 )
619 pChild->MoveChildren(m_vSwpClient.cy - vSwp.cy);
620 pChild->Refresh();
621 pChild = NULL;
622 }
623 }
624
625 vEvent.SetEventObject(this);
626 GetEventHandler()->ProcessEvent(vEvent);
627 }
628 else
629 {
630 //
631 // Try to highlight the correct window (the parent)
632 //
633 if (GetParent())
634 {
635 HWND hWndParent = GetHwndOf(GetParent());
636
637 ::WinQueryWindowPos(hWndParent, &vSwp);
638 m_bIconized = vSwp.fl & SWP_MINIMIZE;
639 if (hWndParent)
640 ::WinSetWindowPos( hWndParent
641 ,HWND_TOP
642 ,vSwp.x
643 ,vSwp.y
644 ,vSwp.cx
645 ,vSwp.cy
646 ,SWP_ZORDER | SWP_ACTIVATE | SWP_SHOW | SWP_MOVE
647 );
648 ::WinEnableWindow(hWndParent, TRUE);
649 }
650 }
651 return TRUE;
652 } // end of wxTopLevelWindowOS2::Show
653
654 // ----------------------------------------------------------------------------
655 // wxTopLevelWindowOS2 maximize/minimize
656 // ----------------------------------------------------------------------------
657
658 void wxTopLevelWindowOS2::Maximize(
659 bool bMaximize
660 )
661 {
662 if (IsShown())
663 {
664 //
665 // Just maximize it directly
666 //
667 DoShowWindow(bMaximize ? SWP_MAXIMIZE : SWP_RESTORE);
668 }
669 else // hidden
670 {
671 //
672 // We can't maximize the hidden frame because it shows it as well, so
673 // just remember that we should do it later in this case
674 //
675 m_bMaximizeOnShow = TRUE;
676 }
677 } // end of wxTopLevelWindowOS2::Maximize
678
679 bool wxTopLevelWindowOS2::IsMaximized() const
680 {
681 bool bIconic;
682
683 ::WinQueryWindowPos(m_hFrame, (PSWP)&m_vSwp);
684 return (m_vSwp.fl & SWP_MAXIMIZE);
685 } // end of wxTopLevelWindowOS2::IsMaximized
686
687 void wxTopLevelWindowOS2::Iconize(
688 bool bIconize
689 )
690 {
691 DoShowWindow(bIconize ? SWP_MINIMIZE : SWP_RESTORE);
692 } // end of wxTopLevelWindowOS2::Iconize
693
694 bool wxTopLevelWindowOS2::IsIconized() const
695 {
696 // also update the current state
697 ::WinQueryWindowPos(m_hFrame, (PSWP)&m_vSwp);
698 if (m_vSwp.fl & SWP_MINIMIZE)
699 ((wxTopLevelWindow*)this)->m_bIconized = TRUE;
700 else
701 ((wxTopLevelWindow*)this)->m_bIconized = FALSE;
702 return m_bIconized;
703 } // end of wxTopLevelWindowOS2::IsIconized
704
705 void wxTopLevelWindowOS2::Restore()
706 {
707 DoShowWindow(SWP_RESTORE);
708 } // end of wxTopLevelWindowOS2::Restore
709
710 // generate an artificial resize event
711 void wxTopLevelWindowOS2::SendSizeEvent()
712 {
713 if (!m_bIconized)
714 {
715 RECTL vRect = wxGetWindowRect(GetHwnd());
716
717 (void)::WinPostMsg( m_hFrame
718 ,WM_SIZE
719 ,MPFROM2SHORT(vRect.xRight - vRect.xLeft, vRect.yTop - vRect.yBottom)
720 ,MPFROM2SHORT(vRect.xRight - vRect.xLeft, vRect.yTop - vRect.yBottom)
721 );
722 }
723 } // end of wxTopLevelWindowOS2::SendSizeEvent
724
725 // ----------------------------------------------------------------------------
726 // wxTopLevelWindowOS2 fullscreen
727 // ----------------------------------------------------------------------------
728
729 bool wxTopLevelWindowOS2::ShowFullScreen(
730 bool bShow
731 , long lStyle
732 )
733 {
734 if (bShow)
735 {
736 if (IsFullScreen())
737 return FALSE;
738
739 m_bFsIsShowing = TRUE;
740 m_lFsStyle = lStyle;
741
742 //
743 // Zap the frame borders
744 //
745
746 //
747 // Save the 'normal' window lStyle
748 //
749 m_lFsOldWindowStyle = ::WinQueryWindowULong( (HWND)GetHWND()
750 ,QWL_STYLE
751 );
752
753 //
754 // Save the old position, width & height, maximize state
755 //
756 m_vFsOldSize = GetRect();
757 m_bFsIsMaximized = IsMaximized();
758
759 //
760 // Decide which window lStyle flags to turn off
761 //
762 LONG lNewStyle = m_lFsOldWindowStyle;
763 LONG lOffFlags = 0;
764
765 if (lStyle & wxFULLSCREEN_NOBORDER)
766 lOffFlags |= FCF_BORDER;
767 if (lStyle & wxFULLSCREEN_NOCAPTION)
768 lOffFlags |= (FCF_TASKLIST | FCF_SYSMENU);
769
770 lNewStyle &= (~lOffFlags);
771
772 //
773 // Change our window style to be compatible with full-screen mode
774 //
775 ::WinSetWindowULong( (HWND)GetHWND()
776 ,QWL_STYLE
777 ,lNewStyle
778 );
779
780 //
781 // Resize to the size of the desktop
782 //
783 int nWidth;
784 int nHeight;
785 RECTL vRect = wxGetWindowRect(HWND_DESKTOP);
786
787 nWidth = vRect.xRight - vRect.xLeft;
788 nHeight = vRect.yTop - vRect.yBottom;
789
790 SetSize( nWidth
791 ,nHeight
792 );
793
794 //
795 // Now flush the window style cache and actually go full-screen
796 //
797 ::WinSetWindowPos( m_hFrame
798 ,HWND_TOP
799 ,0
800 ,0
801 ,nWidth
802 ,nHeight
803 ,SWP_SIZE | SWP_MOVE
804 );
805
806 wxSizeEvent vEvent( wxSize( nWidth
807 ,nHeight
808 )
809 ,GetId()
810 );
811
812 GetEventHandler()->ProcessEvent(vEvent);
813 return TRUE;
814 }
815 else
816 {
817 if (!IsFullScreen())
818 return FALSE;
819
820 m_bFsIsShowing = FALSE;
821 Maximize(m_bFsIsMaximized);
822 ::WinSetWindowULong( (HWND)GetHWND()
823 ,QWL_STYLE
824 ,m_lFsOldWindowStyle
825 );
826 ::WinSetWindowPos( m_hFrame
827 ,HWND_TOP
828 ,m_vFsOldSize.x
829 ,m_vFsOldSize.y
830 ,m_vFsOldSize.width
831 ,m_vFsOldSize.height
832 ,SWP_SIZE | SWP_MOVE
833 );
834 return TRUE;
835 }
836 } // end of wxTopLevelWindowOS2::ShowFullScreen
837
838 // ----------------------------------------------------------------------------
839 // wxTopLevelWindowOS2 misc
840 // ----------------------------------------------------------------------------
841
842 void wxTopLevelWindowOS2::SetIcon(
843 const wxIcon& rIcon
844 )
845 {
846 //
847 // This sets m_icon
848 //
849 wxTopLevelWindowBase::SetIcon(rIcon);
850
851 if (m_icon.Ok())
852 {
853 ::WinSendMsg( m_hFrame
854 ,WM_SETICON
855 ,(MPARAM)((HPOINTER)m_icon.GetHICON())
856 ,NULL
857 );
858 ::WinSendMsg( m_hFrame
859 ,WM_UPDATEFRAME
860 ,(MPARAM)FCF_ICON
861 ,(MPARAM)0
862 );
863 }
864 } // end of wxTopLevelWindowOS2::SetIcon
865
866 bool wxTopLevelWindowOS2::EnableCloseButton(
867 bool bEnable
868 )
869 {
870 //
871 // Get system (a.k.a. window) menu
872 //
873 HMENU hMenu = ::WinWindowFromID(m_hFrame, FID_SYSMENU);
874
875 if (!hMenu)
876 {
877 wxLogLastError(_T("GetSystemMenu"));
878 return FALSE;
879 }
880
881 //
882 // Enabling/disabling the close item from it also automatically
883 // disables/enables the close title bar button
884 //
885 if (bEnable)
886 (void)::WinSendMsg( hMenu
887 ,MM_SETITEMATTR
888 ,MPFROM2SHORT(SC_CLOSE, FALSE)
889 ,MPFROM2SHORT(MIA_DISABLED, FALSE)
890 );
891 else
892 (void)::WinSendMsg( hMenu
893 ,MM_SETITEMATTR
894 ,MPFROM2SHORT(SC_CLOSE, FALSE)
895 ,MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED)
896 );
897
898 //
899 // Update appearance immediately
900 //
901 ::WinSendMsg( m_hFrame
902 ,WM_UPDATEFRAME
903 ,(MPARAM)FCF_MENU
904 ,(MPARAM)0
905 );
906 return TRUE;
907 } // end of wxTopLevelWindowOS2::EnableCloseButton
908