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