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