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