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