Finish basic dialog support and some scrolling fixes.
[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
60 // ============================================================================
61 // wxTopLevelWindowMSW implementation
62 // ============================================================================
63
64 // Dialog window proc
65 MRESULT EXPENTRY wxDlgProc( HWND WXUNUSED(hWnd)
66 ,UINT uMessage
67 ,MPARAM WXUNUSED(wParam)
68 ,MPARAM WXUNUSED(lParam)
69 )
70 {
71 if (uMessage == WM_INITDLG)
72 {
73 //
74 // For this message, returning TRUE tells system to set focus to the
75 // first control in the dialog box.
76 //
77 return (MRESULT)TRUE;
78 }
79 else
80 {
81 //
82 // For all the other ones, FALSE means that we didn't process the
83 // message
84 //
85 return (MRESULT)FALSE;
86 }
87 } // end of wxDlgProc
88
89 // ----------------------------------------------------------------------------
90 // wxTopLevelWindowOS2 creation
91 // ----------------------------------------------------------------------------
92
93 void wxTopLevelWindowOS2::Init()
94 {
95 m_bIconized = m_bMaximizeOnShow = FALSE;
96
97 //
98 // Unlike (almost?) all other windows, frames are created hidden
99 //
100 m_isShown = FALSE;
101
102 //
103 // Data to save/restore when calling ShowFullScreen
104 m_lFsStyle = 0;
105 m_lFsOldWindowStyle = 0;
106 m_bFsIsMaximized = FALSE;
107 m_bFsIsShowing = FALSE;
108
109 m_hFrame = NULLHANDLE;
110 memset(&m_vSwp, 0, sizeof(SWP));
111 memset(&m_vSwpClient, 0, sizeof(SWP));
112 } // end of wxTopLevelWindowIOS2::Init
113
114 long wxTopLevelWindowOS2::OS2GetCreateWindowFlags(
115 long* plExflags
116 ) const
117 {
118 long lStyle = GetWindowStyle();
119 long lMsflags = 0;
120
121 if (lStyle == wxDEFAULT_FRAME_STYLE)
122 lMsflags = FCF_SIZEBORDER | FCF_TITLEBAR | FCF_SYSMENU |
123 FCF_MINMAX | FCF_TASKLIST;
124 else
125 {
126 if ((lStyle & wxCAPTION) == wxCAPTION)
127 lMsflags = FCF_TASKLIST;
128 else
129 lMsflags = FCF_NOMOVEWITHOWNER;
130
131 if ((lStyle & wxVSCROLL) == wxVSCROLL)
132 lMsflags |= FCF_VERTSCROLL;
133 if ((lStyle & wxHSCROLL) == wxHSCROLL)
134 lMsflags |= FCF_HORZSCROLL;
135 if (lStyle & wxMINIMIZE_BOX)
136 lMsflags |= FCF_MINBUTTON;
137 if (lStyle & wxMAXIMIZE_BOX)
138 lMsflags |= FCF_MAXBUTTON;
139 if (lStyle & wxTHICK_FRAME)
140 lMsflags |= FCF_DLGBORDER;
141 if (lStyle & wxSYSTEM_MENU)
142 lMsflags |= FCF_SYSMENU;
143 if (lStyle & wxCAPTION)
144 lMsflags |= FCF_TASKLIST;
145 if (lStyle & wxCLIP_CHILDREN)
146 {
147 // Invalid for frame windows under PM
148 }
149
150 if (lStyle & wxTINY_CAPTION_VERT)
151 lMsflags |= FCF_TASKLIST;
152 if (lStyle & wxTINY_CAPTION_HORIZ)
153 lMsflags |= FCF_TASKLIST;
154
155 if ((lStyle & wxTHICK_FRAME) == 0)
156 lMsflags |= FCF_BORDER;
157 if (lStyle & wxFRAME_TOOL_WINDOW)
158 *plExflags = kFrameToolWindow;
159
160 if (lStyle & wxSTAY_ON_TOP)
161 lMsflags |= FCF_SYSMODAL;
162 }
163 return lMsflags;
164 } // end of wxTopLevelWindowOS2::OS2GetCreateWindowFlags
165
166 bool wxTopLevelWindowOS2::CreateDialog(
167 ULONG ulDlgTemplate
168 , const wxString& rsTitle
169 , const wxPoint& rPos
170 , const wxSize& rSize
171 )
172 {
173 wxWindow* pParent = GetParent();
174
175 //
176 // For the dialogs without wxDIALOG_NO_PARENT style, use the top level
177 // app window as parent - this avoids creating modal dialogs without
178 // parent
179 //
180 if (!pParent && !(GetWindowStyleFlag() & wxDIALOG_NO_PARENT))
181 {
182 pParent = wxTheApp->GetTopWindow();
183
184 if (pParent)
185 {
186 //
187 // Don't use transient windows as parents, this is dangerous as it
188 // can lead to a crash if the parent is destroyed before the child
189 //
190 // also don't use the window which is currently hidden as then the
191 // dialog would be hidden as well
192 if ((pParent->GetExtraStyle() & wxWS_EX_TRANSIENT) ||
193 !pParent->IsShown())
194 {
195 pParent = NULL;
196 }
197 }
198 }
199
200 HWND hWndDlg;
201 HWND hWndOwner;
202
203 if (pParent)
204 hWndOwner = GetHwndOf(pParent);
205 else
206 hWndOwner = HWND_DESKTOP;
207
208 hWndDlg = ::WinLoadDlg( HWND_DESKTOP
209 ,hWndOwner
210 ,(PFNWP)wxDlgProc
211 ,NULL
212 ,(ULONG)ulDlgTemplate
213 ,(PVOID)this
214 );
215
216 m_hWnd = (WXHWND) hWndDlg;
217
218 if ( !m_hWnd )
219 {
220 wxFAIL_MSG(_("Did you forget to include wx/os2/wx.rc in your resources?"));
221
222 wxLogSysError(_("Can't create dialog using template '%ul'"), ulDlgTemplate);
223
224 return FALSE;
225 }
226
227 //
228 // Move the dialog to its initial position without forcing repainting
229 //
230 int nX;
231 int nY;
232 int nWidth;
233 int nHeight;
234
235 if (!OS2GetCreateWindowCoords( rPos
236 ,rSize
237 ,nX
238 ,nY
239 ,nWidth
240 ,nHeight
241 ))
242 {
243 nX = nWidth = (int)CW_USEDEFAULT;
244 }
245
246 //
247 // We can't use CW_USEDEFAULT here as we're not calling CreateWindow()
248 // and passing CW_USEDEFAULT to MoveWindow() results in resizing the
249 // window to (0, 0) size which breaks quite a lot of things, e.g. the
250 // sizer calculation in wxSizer::Fit()
251 //
252 if (nWidth == (int)CW_USEDEFAULT)
253 {
254 //
255 // The exact number doesn't matter, the dialog will be resized
256 // again soon anyhow but it should be big enough to allow
257 // calculation relying on "totalSize - clientSize > 0" work, i.e.
258 // at least greater than the title bar height
259 //
260 nWidth = nHeight = 100;
261 }
262 if (nX == (int)CW_USEDEFAULT)
263 {
264 //
265 // Centre it on the screen - what else can we do?
266 //
267 wxSize vSizeDpy = wxGetDisplaySize();
268
269 nX = (vSizeDpy.x - nWidth) / 2;
270 nY = (vSizeDpy.y - nHeight) / 2;
271 }
272 m_backgroundColour.Set(wxString("LIGHT GREY"));
273
274 LONG lColor = (LONG)m_backgroundColour.GetPixel();
275
276 if (!::WinSetPresParam( m_hWnd
277 ,PP_BACKGROUNDCOLOR
278 ,sizeof(LONG)
279 ,(PVOID)&lColor
280 ))
281 {
282 return FALSE;
283 }
284 ::WinSetWindowPos( GetHwnd()
285 ,HWND_TOP
286 ,nX
287 ,nY
288 ,nWidth
289 ,nHeight
290 ,SWP_MOVE | SWP_SIZE | SWP_ZORDER | SWP_SHOW
291 );
292 //
293 // Set the m_hFrame to m_hWnd for Dialogs
294 //
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 // IF we have child controls in the Frame's client we need to alter
507 // the y position, because, OS/2 controls are positioned relative to
508 // wxWindows orgin (top left) not the OS/2 origin (bottom left)
509 //
510 void wxTopLevelWindowOS2::AlterChildPos()
511 {
512 //
513 // OS/2 is the only OS concerned about this
514 //
515 wxWindow* pChild = NULL;
516 wxControl* pCtrl = NULL;
517 RECTL vRect;
518 SWP vSwp;
519
520 ::WinQueryWindowRect(GetHwnd(), &vRect);
521 for (wxWindowList::Node* pNode = GetChildren().GetFirst();
522 pNode;
523 pNode = pNode->GetNext())
524 {
525 wxWindow* pChild = pNode->GetData();
526
527 ::WinQueryWindowPos(pChild->GetHWND(), &vSwp);
528 vSwp.y += (vRect.yTop - m_vSwpClient.cy);
529 if (pChild->IsKindOf(CLASSINFO(wxControl)))
530 {
531 pCtrl = wxDynamicCast(pChild, wxControl);
532 //
533 // Must deal with controls that have margins like ENTRYFIELD. The SWP
534 // struct of such a control will have and origin offset from its intended
535 // position by the width of the margins.
536 //
537 vSwp.y -= pCtrl->GetYComp();
538 vSwp.x -= pCtrl->GetXComp();
539 }
540 ::WinSetWindowPos( pChild->GetHWND()
541 ,HWND_TOP
542 ,vSwp.x
543 ,vSwp.y
544 ,vSwp.cx
545 ,vSwp.cy
546 ,SWP_MOVE
547 );
548 ::WinQueryWindowPos(pChild->GetHWND(), &vSwp);
549 pChild = NULL;
550 }
551 ::WinQueryWindowPos(GetHwnd(), &m_vSwpClient);
552 } // end of wxTopLevelWindowOS2::AlterChildPos
553
554 void wxTopLevelWindowOS2::UpdateInternalSize(
555 wxWindow* pChild
556 , int nHeight
557 )
558 {
559 pChild->MoveChildren(m_vSwpClient.cy - nHeight);
560 ::WinQueryWindowPos(GetHwnd(), &m_vSwpClient);
561 } // end of wxTopLevelWindowOS2::UpdateInternalSize
562
563 // ----------------------------------------------------------------------------
564 // wxTopLevelWindowOS2 client size
565 // ----------------------------------------------------------------------------
566
567 void wxTopLevelWindowOS2::DoSetClientSize(
568 int nWidth
569 , int nHeight
570 )
571 {
572 //
573 // Call GetClientAreaOrigin() to take the toolbar into account
574 //
575 wxPoint vPt = GetClientAreaOrigin();
576
577 nWidth += vPt.x;
578 nHeight += vPt.y;
579
580 wxWindow::DoSetClientSize( nWidth
581 ,nHeight
582 );
583 } // end of wxTopLevelWindowOS2::DoSetClientSize
584
585 void wxTopLevelWindowOS2::DoGetClientSize(
586 int* pnX
587 , int* pnY
588 ) const
589 {
590 wxWindow::DoGetClientSize( pnX
591 ,pnY
592 );
593
594 wxPoint vPt = GetClientAreaOrigin();
595
596 if (pnX)
597 *pnX -= vPt.x;
598
599 if (pnY)
600 *pnY += vPt.y;
601 } // end of wxTopLevelWindowOS2::DoGetClientSize
602
603 // ----------------------------------------------------------------------------
604 // wxTopLevelWindowOS2 showing
605 // ----------------------------------------------------------------------------
606
607 void wxTopLevelWindowOS2::DoShowWindow(
608 int nShowCmd
609 )
610 {
611 ::WinShowWindow(m_hFrame, (BOOL)(nShowCmd & SWP_SHOW));
612
613 //
614 // Need to artificially send a size event as wxApps often expect to do some
615 // final child control sizing
616 SendSizeEvent();
617 m_bIconized = nShowCmd == SWP_MINIMIZE;
618 } // end of wxTopLevelWindowOS2::DoShowWindow
619
620 bool wxTopLevelWindowOS2::Show(
621 bool bShow
622 )
623 {
624 int nShowCmd;
625 SWP vSwp;
626 RECTL vRect;
627
628 if (bShow)
629 {
630 if (m_bMaximizeOnShow)
631 {
632 nShowCmd = SWP_MAXIMIZE;
633 m_bMaximizeOnShow = FALSE;
634 }
635 else
636 {
637 nShowCmd = SWP_SHOW;
638 }
639 }
640 else // hide
641 {
642 nShowCmd = SWP_HIDE;
643 }
644 DoShowWindow(nShowCmd);
645
646 if (bShow)
647 {
648 wxActivateEvent vEvent(wxEVT_ACTIVATE, TRUE, m_windowId);
649
650 ::WinQueryWindowPos(m_hFrame, &vSwp);
651 m_bIconized = vSwp.fl & SWP_MINIMIZE;
652 ::WinQueryWindowPos(m_hWnd, &m_vSwpClient);
653 ::WinSendMsg(m_hFrame, WM_UPDATEFRAME, (MPARAM)~0, 0);
654 ::WinEnableWindow(m_hFrame, TRUE);
655 vEvent.SetEventObject(this);
656 GetEventHandler()->ProcessEvent(vEvent);
657 }
658 else
659 {
660 //
661 // Try to highlight the correct window (the parent)
662 //
663 if (GetParent())
664 {
665 HWND hWndParent = GetHwndOf(GetParent());
666
667 ::WinQueryWindowPos(hWndParent, &vSwp);
668 m_bIconized = vSwp.fl & SWP_MINIMIZE;
669 if (hWndParent)
670 ::WinSetWindowPos( hWndParent
671 ,HWND_TOP
672 ,vSwp.x
673 ,vSwp.y
674 ,vSwp.cx
675 ,vSwp.cy
676 ,SWP_ZORDER | SWP_ACTIVATE | SWP_SHOW | SWP_MOVE
677 );
678 ::WinEnableWindow(hWndParent, TRUE);
679 }
680 }
681 return TRUE;
682 } // end of wxTopLevelWindowOS2::Show
683
684 // ----------------------------------------------------------------------------
685 // wxTopLevelWindowOS2 maximize/minimize
686 // ----------------------------------------------------------------------------
687
688 void wxTopLevelWindowOS2::Maximize(
689 bool bMaximize
690 )
691 {
692 if (IsShown())
693 {
694 //
695 // Just maximize it directly
696 //
697 DoShowWindow(bMaximize ? SWP_MAXIMIZE : SWP_RESTORE);
698 }
699 else // hidden
700 {
701 //
702 // We can't maximize the hidden frame because it shows it as well, so
703 // just remember that we should do it later in this case
704 //
705 m_bMaximizeOnShow = TRUE;
706 }
707 } // end of wxTopLevelWindowOS2::Maximize
708
709 bool wxTopLevelWindowOS2::IsMaximized() const
710 {
711 bool bIconic;
712
713 ::WinQueryWindowPos(m_hFrame, (PSWP)&m_vSwp);
714 return (m_vSwp.fl & SWP_MAXIMIZE);
715 } // end of wxTopLevelWindowOS2::IsMaximized
716
717 void wxTopLevelWindowOS2::Iconize(
718 bool bIconize
719 )
720 {
721 DoShowWindow(bIconize ? SWP_MINIMIZE : SWP_RESTORE);
722 } // end of wxTopLevelWindowOS2::Iconize
723
724 bool wxTopLevelWindowOS2::IsIconized() const
725 {
726 // also update the current state
727 ::WinQueryWindowPos(m_hFrame, (PSWP)&m_vSwp);
728 if (m_vSwp.fl & SWP_MINIMIZE)
729 ((wxTopLevelWindow*)this)->m_bIconized = TRUE;
730 else
731 ((wxTopLevelWindow*)this)->m_bIconized = FALSE;
732 return m_bIconized;
733 } // end of wxTopLevelWindowOS2::IsIconized
734
735 void wxTopLevelWindowOS2::Restore()
736 {
737 DoShowWindow(SWP_RESTORE);
738 } // end of wxTopLevelWindowOS2::Restore
739
740 // generate an artificial resize event
741 void wxTopLevelWindowOS2::SendSizeEvent()
742 {
743 if (!m_bIconized)
744 {
745 RECTL vRect = wxGetWindowRect(GetHwnd());
746
747 (void)::WinPostMsg( m_hFrame
748 ,WM_SIZE
749 ,MPFROM2SHORT(vRect.xRight - vRect.xLeft, vRect.yTop - vRect.yBottom)
750 ,MPFROM2SHORT(vRect.xRight - vRect.xLeft, vRect.yTop - vRect.yBottom)
751 );
752 }
753 } // end of wxTopLevelWindowOS2::SendSizeEvent
754
755 // ----------------------------------------------------------------------------
756 // wxTopLevelWindowOS2 fullscreen
757 // ----------------------------------------------------------------------------
758
759 bool wxTopLevelWindowOS2::ShowFullScreen(
760 bool bShow
761 , long lStyle
762 )
763 {
764 if (bShow)
765 {
766 if (IsFullScreen())
767 return FALSE;
768
769 m_bFsIsShowing = TRUE;
770 m_lFsStyle = lStyle;
771
772 //
773 // Zap the frame borders
774 //
775
776 //
777 // Save the 'normal' window lStyle
778 //
779 m_lFsOldWindowStyle = ::WinQueryWindowULong( (HWND)GetHWND()
780 ,QWL_STYLE
781 );
782
783 //
784 // Save the old position, width & height, maximize state
785 //
786 m_vFsOldSize = GetRect();
787 m_bFsIsMaximized = IsMaximized();
788
789 //
790 // Decide which window lStyle flags to turn off
791 //
792 LONG lNewStyle = m_lFsOldWindowStyle;
793 LONG lOffFlags = 0;
794
795 if (lStyle & wxFULLSCREEN_NOBORDER)
796 lOffFlags |= FCF_BORDER;
797 if (lStyle & wxFULLSCREEN_NOCAPTION)
798 lOffFlags |= (FCF_TASKLIST | FCF_SYSMENU);
799
800 lNewStyle &= (~lOffFlags);
801
802 //
803 // Change our window style to be compatible with full-screen mode
804 //
805 ::WinSetWindowULong( (HWND)GetHWND()
806 ,QWL_STYLE
807 ,lNewStyle
808 );
809
810 //
811 // Resize to the size of the desktop
812 //
813 int nWidth;
814 int nHeight;
815 RECTL vRect = wxGetWindowRect(HWND_DESKTOP);
816
817 nWidth = vRect.xRight - vRect.xLeft;
818 nHeight = vRect.yTop - vRect.yBottom;
819
820 SetSize( nWidth
821 ,nHeight
822 );
823
824 //
825 // Now flush the window style cache and actually go full-screen
826 //
827 ::WinSetWindowPos( m_hFrame
828 ,HWND_TOP
829 ,0
830 ,0
831 ,nWidth
832 ,nHeight
833 ,SWP_SIZE | SWP_MOVE
834 );
835
836 wxSizeEvent vEvent( wxSize( nWidth
837 ,nHeight
838 )
839 ,GetId()
840 );
841
842 GetEventHandler()->ProcessEvent(vEvent);
843 return TRUE;
844 }
845 else
846 {
847 if (!IsFullScreen())
848 return FALSE;
849
850 m_bFsIsShowing = FALSE;
851 Maximize(m_bFsIsMaximized);
852 ::WinSetWindowULong( (HWND)GetHWND()
853 ,QWL_STYLE
854 ,m_lFsOldWindowStyle
855 );
856 ::WinSetWindowPos( m_hFrame
857 ,HWND_TOP
858 ,m_vFsOldSize.x
859 ,m_vFsOldSize.y
860 ,m_vFsOldSize.width
861 ,m_vFsOldSize.height
862 ,SWP_SIZE | SWP_MOVE
863 );
864 return TRUE;
865 }
866 } // end of wxTopLevelWindowOS2::ShowFullScreen
867
868 // ----------------------------------------------------------------------------
869 // wxTopLevelWindowOS2 misc
870 // ----------------------------------------------------------------------------
871
872 void wxTopLevelWindowOS2::SetIcon(
873 const wxIcon& rIcon
874 )
875 {
876 //
877 // This sets m_icon
878 //
879 wxTopLevelWindowBase::SetIcon(rIcon);
880
881 if (m_icon.Ok())
882 {
883 ::WinSendMsg( m_hFrame
884 ,WM_SETICON
885 ,(MPARAM)((HPOINTER)m_icon.GetHICON())
886 ,NULL
887 );
888 ::WinSendMsg( m_hFrame
889 ,WM_UPDATEFRAME
890 ,(MPARAM)FCF_ICON
891 ,(MPARAM)0
892 );
893 }
894 } // end of wxTopLevelWindowOS2::SetIcon
895
896 bool wxTopLevelWindowOS2::EnableCloseButton(
897 bool bEnable
898 )
899 {
900 //
901 // Get system (a.k.a. window) menu
902 //
903 HMENU hMenu = ::WinWindowFromID(m_hFrame, FID_SYSMENU);
904
905 if (!hMenu)
906 {
907 wxLogLastError(_T("GetSystemMenu"));
908 return FALSE;
909 }
910
911 //
912 // Enabling/disabling the close item from it also automatically
913 // disables/enables the close title bar button
914 //
915 if (bEnable)
916 (void)::WinSendMsg( hMenu
917 ,MM_SETITEMATTR
918 ,MPFROM2SHORT(SC_CLOSE, FALSE)
919 ,MPFROM2SHORT(MIA_DISABLED, FALSE)
920 );
921 else
922 (void)::WinSendMsg( hMenu
923 ,MM_SETITEMATTR
924 ,MPFROM2SHORT(SC_CLOSE, FALSE)
925 ,MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED)
926 );
927
928 //
929 // Update appearance immediately
930 //
931 ::WinSendMsg( m_hFrame
932 ,WM_UPDATEFRAME
933 ,(MPARAM)FCF_MENU
934 ,(MPARAM)0
935 );
936 return TRUE;
937 } // end of wxTopLevelWindowOS2::EnableCloseButton
938