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