]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/os2/frame.cpp
Added wxStudio module.
[wxWidgets.git] / src / os2 / frame.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: frame.cpp
3// Purpose: wxFrame
4// Author: David Webster
5// Modified by:
6// Created: 10/27/99
7// RCS-ID: $Id$
8// Copyright: (c) David Webster
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
15#ifndef WX_PRECOMP
16 #include "wx/setup.h"
17 #include "wx/frame.h"
18 #include "wx/menu.h"
19 #include "wx/app.h"
20 #include "wx/utils.h"
21 #include "wx/dialog.h"
22 #include "wx/settings.h"
23 #include "wx/dcclient.h"
24#endif // WX_PRECOMP
25
26#include "wx/os2/private.h"
27
28#if wxUSE_STATUSBAR
29 #include "wx/statusbr.h"
30 #include "wx/generic/statusbr.h"
31#endif // wxUSE_STATUSBAR
32
33#if wxUSE_TOOLBAR
34 #include "wx/toolbar.h"
35#endif // wxUSE_TOOLBAR
36
37#include "wx/menuitem.h"
38#include "wx/log.h"
39
40// ----------------------------------------------------------------------------
41// globals
42// ----------------------------------------------------------------------------
43
44extern wxWindowList wxModelessWindows;
45extern wxList WXDLLEXPORT wxPendingDelete;
46extern wxChar wxFrameClassName[];
47extern wxMenu *wxCurrentPopupMenu;
48
49// ----------------------------------------------------------------------------
50// event tables
51// ----------------------------------------------------------------------------
52
53BEGIN_EVENT_TABLE(wxFrame, wxFrameBase)
54 EVT_ACTIVATE(wxFrame::OnActivate)
55 EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged)
56END_EVENT_TABLE()
57
58IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxWindow)
59
60// ============================================================================
61// implementation
62// ============================================================================
63
64// ----------------------------------------------------------------------------
65// static class members
66// ----------------------------------------------------------------------------
67
68#if wxUSE_NATIVE_STATUSBAR
69 bool wxFrame::m_bUseNativeStatusBar = TRUE;
70#else
71 bool wxFrame::m_bUseNativeStatusBar = FALSE;
72#endif
73
74// ----------------------------------------------------------------------------
75// creation/destruction
76// ----------------------------------------------------------------------------
77
78void wxFrame::Init()
79{
80 m_bIconized = FALSE;
81
82#if wxUSE_TOOLTIPS
83 m_hWndToolTip = 0;
84#endif
85 // Data to save/restore when calling ShowFullScreen
86 m_lFsStyle = 0L;
87 m_lFsOldWindowStyle = 0L;
88 m_nFsStatusBarFields = 0;
89 m_nFsStatusBarHeight = 0;
90 m_nFsToolBarHeight = 0;
91 m_bFsIsMaximized = FALSE;
92 m_bFsIsShowing = FALSE;
93
94 //
95 // Initialize SWP's
96 //
97 memset(&m_vSwp, 0, sizeof(SWP));
98 memset(&m_vSwpClient, 0, sizeof(SWP));
99 memset(&m_vSwpTitleBar, 0, sizeof(SWP));
100 memset(&m_vSwpMenuBar, 0, sizeof(SWP));
101 memset(&m_vSwpHScroll, 0, sizeof(SWP));
102 memset(&m_vSwpVScroll, 0, sizeof(SWP));
103 memset(&m_vSwpStatusBar, 0, sizeof(SWP));
104 memset(&m_vSwpToolBar, 0, sizeof(SWP));
105} // end of wxFrame::Init
106
107bool wxFrame::Create(
108 wxWindow* pParent
109, wxWindowID vId
110, const wxString& rsTitle
111, const wxPoint& rPos
112, const wxSize& rSize
113, long lulStyle
114, const wxString& rsName
115)
116{
117 int nX = rPos.x;
118 int nY = rPos.y;
119 int nWidth = rSize.x;
120 int nHeight = rSize.y;
121
122 SetName(rsName);
123 m_windowStyle = lulStyle;
124 m_frameMenuBar = NULL;
125 m_frameToolBar = NULL;
126 m_frameStatusBar = NULL;
127
128 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE));
129
130 if (vId > -1 )
131 m_windowId = vId;
132 else
133 m_windowId = (int)NewControlId();
134
135 if (pParent)
136 pParent->AddChild(this);
137
138 m_bIconized = FALSE;
139
140 if ((m_windowStyle & wxFRAME_FLOAT_ON_PARENT) == 0)
141 pParent = NULL;
142
143 if (!pParent)
144 wxTopLevelWindows.Append(this);
145
146 OS2Create( m_windowId
147 ,pParent
148 ,wxFrameClassName
149 ,this
150 ,rsTitle
151 ,nX
152 ,nY
153 ,nWidth
154 ,nHeight
155 ,lulStyle
156 );
157
158 wxModelessWindows.Append(this);
159 return TRUE;
160} // end of wxFrame::Create
161
162wxFrame::~wxFrame()
163{
164 m_isBeingDeleted = TRUE;
165 wxTopLevelWindows.DeleteObject(this);
166
167 DeleteAllBars();
168
169 if (wxTheApp && (wxTopLevelWindows.Number() == 0))
170 {
171 wxTheApp->SetTopWindow(NULL);
172
173 if (wxTheApp->GetExitOnFrameDelete())
174 {
175 ::WinPostMsg(m_hFrame, WM_QUIT, 0, 0);
176 }
177 }
178 wxModelessWindows.DeleteObject(this);
179
180 //
181 // For some reason, wxWindows can activate another task altogether
182 // when a frame is destroyed after a modal dialog has been invoked.
183 // Try to bring the parent to the top.
184 //
185 // MT:Only do this if this frame is currently the active window, else weird
186 // things start to happen.
187 //
188 if (wxGetActiveWindow() == this)
189 {
190 if (GetParent() && GetParent()->GetHWND())
191 {
192 ::WinSetWindowPos( (HWND) GetParent()->GetHWND()
193 ,HWND_TOP
194 ,0
195 ,0
196 ,0
197 ,0
198 ,SWP_ZORDER
199 );
200 }
201 }
202} // end of wxFrame::~wxFrame
203
204//
205// Get size *available for subwindows* i.e. excluding menu bar, toolbar etc.
206//
207void wxFrame::DoGetClientSize(
208 int* pX
209, int* pY
210) const
211{
212 //
213 // OS/2 PM's coordinates go from bottom-left not
214 // top-left thus the += instead of the -=
215 //
216 RECTL vRect;
217
218 //
219 // PM has no GetClientRect that inherantly knows about the client window
220 // We have to explicitly go fetch it!
221 //
222 ::WinQueryWindowRect(GetHwnd(), &vRect);
223
224#if wxUSE_STATUSBAR
225 if ( GetStatusBar() )
226 {
227 int nStatusX;
228 int nStatusY;
229
230 GetStatusBar()->GetClientSize( &nStatusX
231 ,&nStatusY
232 );
233 vRect.yBottom += nStatusY;
234 }
235#endif // wxUSE_STATUSBAR
236
237 wxPoint vPoint(GetClientAreaOrigin());
238
239 vRect.yBottom += vPoint.y;
240 vRect.xRight -= vPoint.x;
241
242 if (pX)
243 *pX = vRect.xRight;
244 if (pY)
245 *pY = vRect.yBottom;
246} // end of wxFrame::DoGetClientSize
247
248//
249// Set the client size (i.e. leave the calculation of borders etc.
250// to wxWindows)
251//
252void wxFrame::DoSetClientSize(
253 int nWidth
254, int nHeight
255)
256{
257 HWND hWnd = GetHwnd();
258 RECTL vRect;
259 RECTL vRect2;
260
261 ::WinQueryWindowRect(GetHwnd(), &vRect);
262
263 ::WinQueryWindowRect(m_hFrame, &vRect2);
264
265 //
266 // Find the difference between the entire window (title bar and all)
267 // and the client area; add this to the new client size to move the
268 // window. Remember OS/2's backwards y coord system!
269 //
270 int nActualWidth = vRect2.xRight - vRect2.xLeft - vRect.xRight + nWidth;
271 int nActualHeight = vRect2.yTop + vRect2.yTop - vRect.yTop + nHeight;
272
273#if wxUSE_STATUSBAR
274 if ( GetStatusBar() )
275 {
276 int nStatusX;
277 int nStatusY;
278
279 GetStatusBar()->GetClientSize( &nStatusX
280 ,&nStatusY
281 );
282 nActualHeight += nStatusY;
283 }
284#endif // wxUSE_STATUSBAR
285
286 wxPoint vPoint(GetClientAreaOrigin());
287 nActualWidth += vPoint.y;
288 nActualHeight += vPoint.x;
289
290 POINTL vPointl;
291
292 vPointl.x = vRect2.xLeft;
293 vPoint.y = vRect2.yTop;
294
295 ::WinSetWindowPos( m_hFrame
296 ,HWND_TOP
297 ,vPointl.x
298 ,vPointl.y
299 ,nActualWidth
300 ,nActualHeight
301 ,SWP_MOVE | SWP_SIZE | SWP_SHOW
302 );
303
304 wxSizeEvent vEvent( wxSize( nWidth
305 ,nHeight
306 )
307 ,m_windowId
308 );
309 vEvent.SetEventObject(this);
310 GetEventHandler()->ProcessEvent(vEvent);
311} // end of wxFrame::DoSetClientSize
312
313void wxFrame::DoGetSize(
314 int* pWidth
315, int* pHeight
316) const
317{
318 RECTL vRect;
319
320 ::WinQueryWindowRect(m_hFrame, &vRect);
321 *pWidth = vRect.xRight - vRect.xLeft;
322 *pHeight = vRect.yTop - vRect.yBottom;
323} // end of wxFrame::DoGetSize
324
325void wxFrame::DoGetPosition(
326 int* pX
327, int* pY
328) const
329{
330 RECTL vRect;
331 POINTL vPoint;
332
333 ::WinQueryWindowRect(m_hFrame, &vRect);
334 vPoint.x = vRect.xLeft;
335
336 //
337 // OS/2 is backwards [WIN32 it is vRect.yTop]
338 //
339 vPoint.y = vRect.yBottom;
340
341 *pX = vPoint.x;
342 *pY = vPoint.y;
343} // end of wxFrame::DoGetPosition
344
345// ----------------------------------------------------------------------------
346// variations around ::ShowWindow()
347// ----------------------------------------------------------------------------
348
349void wxFrame::DoShowWindow(
350 int bShowCmd
351)
352{
353 HWND hClient = NULLHANDLE;
354 SWP vSwp;
355
356 //
357 // Reset the window position
358 //
359 WinQueryWindowPos(m_hFrame, &vSwp);
360 WinSetWindowPos( GetHwnd()
361 ,HWND_TOP
362 ,vSwp.x
363 ,vSwp.y
364 ,vSwp.cx
365 ,vSwp.cy
366 ,SWP_SIZE | SWP_MOVE | SWP_ACTIVATE
367 );
368 ::WinShowWindow(m_hFrame, (BOOL)bShowCmd);
369 ::WinShowWindow(GetHwnd(), (BOOL)bShowCmd);
370} // end of wxFrame::DoShowWindow
371
372bool wxFrame::Show(
373 bool bShow
374)
375{
376 SWP vSwp;
377
378 DoShowWindow((int)bShow);
379
380 if (bShow)
381 {
382 wxActivateEvent vEvent(wxEVT_ACTIVATE, TRUE, m_windowId);
383
384 ::WinQueryWindowPos(m_hFrame, &vSwp);
385 m_bIconized = vSwp.fl & SWP_MINIMIZE;
386 ::WinEnableWindow(m_hFrame, TRUE);
387 vEvent.SetEventObject(this);
388 GetEventHandler()->ProcessEvent(vEvent);
389 }
390 else
391 {
392 //
393 // Try to highlight the correct window (the parent)
394 //
395 if (GetParent())
396 {
397 HWND hWndParent = GetHwndOf(GetParent());
398
399 ::WinQueryWindowPos(hWndParent, &vSwp);
400 m_bIconized = vSwp.fl & SWP_MINIMIZE;
401 if (hWndParent)
402 ::WinSetWindowPos( hWndParent
403 ,HWND_TOP
404 ,vSwp.x
405 ,vSwp.y
406 ,vSwp.cx
407 ,vSwp.cy
408 ,SWP_ZORDER | SWP_ACTIVATE | SWP_SHOW | SWP_MOVE
409 );
410 ::WinEnableWindow(hWndParent, TRUE);
411 }
412 }
413 return TRUE;
414} // end of wxFrame::Show
415
416void wxFrame::Iconize(
417 bool bIconize
418)
419{
420 DoShowWindow(bIconize ? SWP_MINIMIZE : SWP_RESTORE);
421} // end of wxFrame::Iconize
422
423void wxFrame::Maximize(
424 bool bMaximize)
425{
426 DoShowWindow(bMaximize ? SWP_MAXIMIZE : SWP_RESTORE);
427} // end of wxFrame::Maximize
428
429void wxFrame::Restore()
430{
431 DoShowWindow(SWP_RESTORE);
432} // end of wxFrame::Restore
433
434bool wxFrame::IsIconized() const
435{
436 SWP vSwp;
437 bool bIconic;
438
439 ::WinQueryWindowPos(GetHwnd(), &vSwp);
440
441 if (vSwp.fl & SWP_MINIMIZE)
442 ((wxFrame*)this)->m_bIconized = TRUE;
443 else
444 ((wxFrame*)this)->m_bIconized = FALSE;
445 return m_bIconized;
446} // end of wxFrame::IsIconized
447
448// Is it maximized?
449bool wxFrame::IsMaximized() const
450{
451 SWP vSwp;
452 bool bIconic;
453
454 ::WinQueryWindowPos(m_hFrame, &vSwp);
455 return (vSwp.fl & SWP_MAXIMIZE);
456} // end of wxFrame::IsMaximized
457
458void wxFrame::SetIcon(
459 const wxIcon& rIcon
460)
461{
462 wxFrameBase::SetIcon(rIcon);
463
464 if ((m_icon.GetHICON()) != NULLHANDLE)
465 {
466 ::WinSendMsg( m_hFrame
467 ,WM_SETICON
468 ,(MPARAM)((HPOINTER)m_icon.GetHICON())
469 ,NULL
470 );
471 ::WinSendMsg( m_hFrame
472 ,WM_UPDATEFRAME
473 ,(MPARAM)FCF_ICON
474 ,(MPARAM)0
475 );
476 }
477} // end of wxFrame::SetIcon
478
479#if wxUSE_STATUSBAR
480wxStatusBar* wxFrame::OnCreateStatusBar(
481 int nNumber
482, long lulStyle
483, wxWindowID vId
484, const wxString& rName
485)
486{
487 wxStatusBar* pStatusBar = NULL;
488
489 pStatusBar = wxFrameBase::OnCreateStatusBar( nNumber
490 ,lulStyle
491 ,vId
492 ,rName
493 );
494 return pStatusBar;
495} // end of wxFrame::OnCreateStatusBar
496
497void wxFrame::PositionStatusBar()
498{
499 //
500 // Native status bar positions itself
501 //
502 if (m_frameStatusBar)
503 {
504 int nWidth;
505 int nHeight;
506 int nStatbarWidth;
507 int nStatbarHeight;
508 HWND hWndClient;
509 RECTL vRect;
510
511 ::WinQueryWindowRect(GetHwnd(), &vRect);
512 nWidth = vRect.xRight - vRect.xLeft;
513 nHeight = vRect.yTop - vRect.yBottom;
514
515 m_frameStatusBar->GetSize( &nStatbarWidth
516 ,&nStatbarHeight
517 );
518
519 //
520 // Since we wish the status bar to be directly under the client area,
521 // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.
522 //
523 m_frameStatusBar->SetSize( 0
524 ,nHeight
525 ,nWidth
526 ,nStatbarHeight
527 );
528 }
529} // end of wxFrame::PositionStatusBar
530#endif // wxUSE_STATUSBAR
531
532void wxFrame::DetachMenuBar()
533{
534 if (m_frameMenuBar)
535 {
536 m_frameMenuBar->Detach();
537 m_frameMenuBar = NULL;
538 }
539} // end of wxFrame::DetachMenuBar
540
541void wxFrame::SetMenuBar(
542 wxMenuBar* pMenuBar
543)
544{
545 ERRORID vError;
546 wxString sError;
547 HWND hClient = NULLHANDLE;
548 HWND hFrame = NULLHANDLE;
549 HWND hTitlebar = NULLHANDLE;
550 HWND hHScroll = NULLHANDLE;
551 HWND hVScroll = NULLHANDLE;
552 HWND hMenuBar = NULLHANDLE;
553 SWP vSwp;
554 SWP vSwpTitlebar;
555 SWP vSwpVScroll;
556 SWP vSwpHScroll;
557 SWP vSwpMenu;
558
559 if (!pMenuBar)
560 {
561 DetachMenuBar();
562 return;
563 }
564
565 m_frameMenuBar = NULL;
566
567 // Can set a menubar several times.
568 // TODO: how to prevent a memory leak if you have a currently-unattached
569 // menubar? wxWindows assumes that the frame will delete the menu (otherwise
570 // there are problems for MDI).
571 if (pMenuBar->GetHMenu())
572 {
573 m_hMenu = pMenuBar->GetHMenu();
574 }
575 else
576 {
577 pMenuBar->Detach();
578
579 m_hMenu = pMenuBar->Create();
580
581 if (!m_hMenu)
582 return;
583 }
584
585 //
586 // Set the parent and owner of the menubar to be the frame
587 //
588 if (!::WinSetParent(m_hMenu, m_hFrame, FALSE))
589 {
590 vError = ::WinGetLastError(vHabmain);
591 sError = wxPMErrorToStr(vError);
592 wxLogError("Error setting parent for submenu. Error: %s\n", sError);
593 }
594
595 if (!::WinSetOwner(m_hMenu, m_hFrame))
596 {
597 vError = ::WinGetLastError(vHabmain);
598 sError = wxPMErrorToStr(vError);
599 wxLogError("Error setting parent for submenu. Error: %s\n", sError);
600 }
601 InternalSetMenuBar();
602
603 m_frameMenuBar = pMenuBar;
604 pMenuBar->Attach(this);
605
606 //
607 // Now resize the client to fit the new frame
608 //
609 WinQueryWindowPos(m_hFrame, &vSwp);
610 hTitlebar = WinWindowFromID(m_hFrame, FID_TITLEBAR);
611 WinQueryWindowPos(hTitlebar, &vSwpTitlebar);
612 hHScroll = WinWindowFromID(m_hFrame, FID_HORZSCROLL);
613 WinQueryWindowPos(hHScroll, &vSwpHScroll);
614 hVScroll = WinWindowFromID(m_hFrame, FID_VERTSCROLL);
615 WinQueryWindowPos(hVScroll, &vSwpVScroll);
616 hMenuBar = WinWindowFromID(m_hFrame, FID_MENU);
617 WinQueryWindowPos(hMenuBar, &vSwpMenu);
618 WinSetWindowPos( GetHwnd()
619 ,HWND_TOP
620 ,SV_CXSIZEBORDER/2
621 ,(SV_CYSIZEBORDER/2) + vSwpHScroll.cy/2
622 ,vSwp.cx - ((SV_CXSIZEBORDER + 1) + vSwpVScroll.cx)
623 ,vSwp.cy - ((SV_CYSIZEBORDER + 1) + vSwpTitlebar.cy + vSwpMenu.cy + vSwpHScroll.cy/2)
624 ,SWP_SIZE | SWP_MOVE
625 );
626} // end of wxFrame::SetMenuBar
627
628void wxFrame::InternalSetMenuBar()
629{
630 WinSendMsg((HWND)m_hFrame, WM_UPDATEFRAME, (MPARAM)FCF_MENU, (MPARAM)0);
631} // end of wxFrame::InternalSetMenuBar
632
633//
634// Responds to colour changes, and passes event on to children
635//
636void wxFrame::OnSysColourChanged(
637 wxSysColourChangedEvent& rEvent
638)
639{
640 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE));
641 Refresh();
642
643 if (m_frameStatusBar)
644 {
645 wxSysColourChangedEvent vEvent2;
646
647 vEvent2.SetEventObject(m_frameStatusBar);
648 m_frameStatusBar->GetEventHandler()->ProcessEvent(vEvent2);
649 }
650
651 //
652 // Propagate the event to the non-top-level children
653 //
654 wxWindow::OnSysColourChanged(rEvent);
655} // end of wxFrame::OnSysColourChanged
656
657// Pass TRUE to show full screen, FALSE to restore.
658bool wxFrame::ShowFullScreen(
659 bool bShow
660, long lStyle
661)
662{
663 /*
664 // TODO
665 if (show)
666 {
667 if (IsFullScreen())
668 return FALSE;
669
670 m_fsIsShowing = TRUE;
671 m_fsStyle = style;
672
673 wxToolBar *theToolBar = GetToolBar();
674 wxStatusBar *theStatusBar = GetStatusBar();
675
676 int dummyWidth;
677
678 if (theToolBar)
679 theToolBar->GetSize(&dummyWidth, &m_fsToolBarHeight);
680 if (theStatusBar)
681 theStatusBar->GetSize(&dummyWidth, &m_fsStatusBarHeight);
682
683 // zap the toolbar, menubar, and statusbar
684
685 if ((style & wxFULLSCREEN_NOTOOLBAR) && theToolBar)
686 {
687 theToolBar->SetSize(-1,0);
688 theToolBar->Show(FALSE);
689 }
690
691 if (style & wxFULLSCREEN_NOMENUBAR)
692 SetMenu((HWND)GetHWND(), (HMENU) NULL);
693
694 // Save the number of fields in the statusbar
695 if ((style & wxFULLSCREEN_NOSTATUSBAR) && theStatusBar)
696 {
697 m_fsStatusBarFields = theStatusBar->GetFieldsCount();
698 SetStatusBar((wxStatusBar*) NULL);
699 delete theStatusBar;
700 }
701 else
702 m_fsStatusBarFields = 0;
703
704 // zap the frame borders
705
706 // save the 'normal' window style
707 m_fsOldWindowStyle = GetWindowLong((HWND)GetHWND(), GWL_STYLE);
708
709 // save the old position, width & height, maximize state
710 m_fsOldSize = GetRect();
711 m_fsIsMaximized = IsMaximized();
712
713 // decide which window style flags to turn off
714 LONG newStyle = m_fsOldWindowStyle;
715 LONG offFlags = 0;
716
717 if (style & wxFULLSCREEN_NOBORDER)
718 offFlags |= WS_BORDER;
719 if (style & wxFULLSCREEN_NOCAPTION)
720 offFlags |= (WS_CAPTION | WS_SYSMENU);
721
722 newStyle &= (~offFlags);
723
724 // change our window style to be compatible with full-screen mode
725 SetWindowLong((HWND)GetHWND(), GWL_STYLE, newStyle);
726
727 // resize to the size of the desktop
728 int width, height;
729
730 RECT rect;
731 ::GetWindowRect(GetDesktopWindow(), &rect);
732 width = rect.right - rect.left;
733 height = rect.bottom - rect.top;
734
735 SetSize(width, height);
736
737 // now flush the window style cache and actually go full-screen
738 SetWindowPos((HWND)GetHWND(), HWND_TOP, 0, 0, width, height, SWP_FRAMECHANGED);
739
740 wxSizeEvent event(wxSize(width, height), GetId());
741 GetEventHandler()->ProcessEvent(event);
742
743 return TRUE;
744 }
745 else
746 {
747 if (!IsFullScreen())
748 return FALSE;
749
750 m_fsIsShowing = FALSE;
751
752 wxToolBar *theToolBar = GetToolBar();
753
754 // restore the toolbar, menubar, and statusbar
755 if (theToolBar && (m_fsStyle & wxFULLSCREEN_NOTOOLBAR))
756 {
757 theToolBar->SetSize(-1, m_fsToolBarHeight);
758 theToolBar->Show(TRUE);
759 }
760
761 if ((m_fsStyle & wxFULLSCREEN_NOSTATUSBAR) && (m_fsStatusBarFields > 0))
762 {
763 CreateStatusBar(m_fsStatusBarFields);
764 PositionStatusBar();
765 }
766
767 if ((m_fsStyle & wxFULLSCREEN_NOMENUBAR) && (m_hMenu != 0))
768 SetMenu((HWND)GetHWND(), (HMENU)m_hMenu);
769
770 Maximize(m_fsIsMaximized);
771 SetWindowLong((HWND)GetHWND(),GWL_STYLE, m_fsOldWindowStyle);
772 SetWindowPos((HWND)GetHWND(),HWND_TOP,m_fsOldSize.x, m_fsOldSize.y,
773 m_fsOldSize.width, m_fsOldSize.height, SWP_FRAMECHANGED);
774
775 return TRUE;
776 }
777*/
778 return TRUE;
779} // end of wxFrame::ShowFullScreen
780
781//
782// Frame window
783//
784bool wxFrame::OS2Create(
785 int nId
786, wxWindow* pParent
787, const wxChar* zWclass
788, wxWindow* pWxWin
789, const wxChar* zTitle
790, int nX
791, int nY
792, int nWidth
793, int nHeight
794, long ulStyle
795)
796{
797 ULONG ulCreateFlags = 0L;
798 ULONG ulStyleFlags = 0L;
799 ULONG ulExtraFlags = 0L;
800 FRAMECDATA vFrameCtlData;
801 HWND hParent = NULLHANDLE;
802 HWND hClient = NULLHANDLE;
803 HWND hFrame = NULLHANDLE;
804 HWND hTitlebar = NULLHANDLE;
805 HWND hHScroll = NULLHANDLE;
806 HWND hVScroll = NULLHANDLE;
807 SWP vSwp[10];
808 RECTL vRect[10];
809 USHORT uCtlCount;
810
811 m_hDefaultIcon = (WXHICON) (wxSTD_FRAME_ICON ? wxSTD_FRAME_ICON : wxDEFAULT_FRAME_ICON);
812
813 if (pParent)
814 hParent = GetWinHwnd(pParent);
815 else
816 hParent = HWND_DESKTOP;
817
818 if (ulStyle == wxDEFAULT_FRAME_STYLE)
819 ulCreateFlags = FCF_SIZEBORDER | FCF_TITLEBAR | FCF_SYSMENU |
820 FCF_MINMAX | FCF_VERTSCROLL | FCF_HORZSCROLL | FCF_TASKLIST;
821 else
822 {
823 if ((ulStyle & wxCAPTION) == wxCAPTION)
824 ulCreateFlags = FCF_TASKLIST;
825 else
826 ulCreateFlags = FCF_NOMOVEWITHOWNER;
827
828 if (ulStyle & wxMINIMIZE_BOX)
829 ulCreateFlags |= FCF_MINBUTTON;
830 if (ulStyle & wxMAXIMIZE_BOX)
831 ulCreateFlags |= FCF_MAXBUTTON;
832 if (ulStyle & wxTHICK_FRAME)
833 ulCreateFlags |= FCF_DLGBORDER;
834 if (ulStyle & wxSYSTEM_MENU)
835 ulCreateFlags |= FCF_SYSMENU;
836 if (ulStyle & wxCAPTION)
837 ulCreateFlags |= FCF_TASKLIST;
838 if (ulStyle & wxCLIP_CHILDREN)
839 {
840 // Invalid for frame windows under PM
841 }
842
843 if (ulStyle & wxTINY_CAPTION_VERT)
844 ulCreateFlags |= FCF_TASKLIST;
845 if (ulStyle & wxTINY_CAPTION_HORIZ)
846 ulCreateFlags |= FCF_TASKLIST;
847
848 if ((ulStyle & wxTHICK_FRAME) == 0)
849 ulCreateFlags |= FCF_BORDER;
850 if (ulStyle & wxFRAME_TOOL_WINDOW)
851 ulExtraFlags = kFrameToolWindow;
852
853 if (ulStyle & wxSTAY_ON_TOP)
854 ulCreateFlags |= FCF_SYSMODAL;
855 }
856 if ((ulStyle & wxMINIMIZE) || (ulStyle & wxICONIZE))
857 ulStyleFlags |= WS_MINIMIZED;
858 if (ulStyle & wxMAXIMIZE)
859 ulStyleFlags |= WS_MAXIMIZED;
860
861 //
862 // Clear the visible flag, we always call show
863 //
864 ulStyleFlags &= (unsigned long)~WS_VISIBLE;
865 m_bIconized = FALSE;
866
867 //
868 // Set the frame control block
869 //
870 vFrameCtlData.cb = sizeof(vFrameCtlData);
871 vFrameCtlData.flCreateFlags = ulCreateFlags;
872 vFrameCtlData.hmodResources = 0L;
873 vFrameCtlData.idResources = 0;
874
875 //
876 // Create the frame window
877 //
878 if ((m_hFrame = ::WinCreateWindow( hParent // Frame is parent
879 ,WC_FRAME // standard frame class
880 ,(PSZ)zTitle // Window title
881 ,0 // No styles
882 ,0, 0, 0, 0 // Window position
883 ,NULLHANDLE // Owner
884 ,HWND_TOP // Sibling
885 ,(ULONG)nId // ID
886 ,(PVOID)&vFrameCtlData // Creation data
887 ,NULL // Window Pres Params
888 )) == 0L)
889 {
890 return FALSE;
891 }
892
893 if (!wxWindow::OS2Create( m_hFrame
894 ,wxFrameClassName
895 ,NULL
896 ,0L
897 ,0L
898 ,0L
899 ,0L
900 ,0L
901 ,NULLHANDLE
902 ,HWND_TOP
903 ,(unsigned long)FID_CLIENT
904 ,NULL
905 ,NULL
906 ))
907 {
908 return FALSE;
909 }
910
911 //
912 // Now size everything. If adding a menu the client will need to be resized.
913 //
914 if (!::WinSetWindowPos( m_hFrame
915 ,HWND_TOP
916 ,nX
917 ,nY
918 ,nWidth
919 ,nHeight
920 ,SWP_SIZE | SWP_MOVE | SWP_ACTIVATE
921 ))
922 return FALSE;
923
924 uCtlCount = SHORT1FROMMP(::WinSendMsg(m_hFrame, WM_FORMATFRAME, (MPARAM)vSwp, (MPARAM)vRect));
925 for (int i = 0; i < uCtlCount; i++)
926 {
927 if (vSwp[i].hwnd == m_hFrame)
928 memcpy(&m_vSwp, &vSwp[i], sizeof(SWP));
929 else if (vSwp[i].hwnd == m_hVScroll)
930 memcpy(&m_vSwpVScroll, &vSwp[i], sizeof(SWP));
931 else if (vSwp[i].hwnd == m_hHScroll)
932 memcpy(&m_vSwpVScroll, &vSwp[i], sizeof(SWP));
933 else if (vSwp[i].hwnd == m_hTitleBar)
934 memcpy(&m_vSwpTitleBar, &vSwp[i], sizeof(SWP));
935 }
936
937 //
938 // Now set the size of the client
939 //
940 WinSetWindowPos( hClient
941 ,HWND_TOP
942 ,SV_CXSIZEBORDER/2
943 ,(SV_CYSIZEBORDER/2) + m_vSwpHScroll.cy/2
944 ,m_vSwp.cx - ((SV_CXSIZEBORDER + 1) + m_vSwpVScroll.cx)
945 ,m_vSwp.cy - ((SV_CYSIZEBORDER + 1) + m_vSwpTitleBar.cy + m_vSwpHScroll.cy/2)
946 ,SWP_SIZE | SWP_MOVE
947 );
948
949 //
950 // Set the client window's background, otherwise it is transparent!
951 //
952 return TRUE;
953} // end of wxFrame::OS2Create
954
955//
956// Default activation behaviour - set the focus for the first child
957// subwindow found.
958//
959void wxFrame::OnActivate(
960 wxActivateEvent& rEvent
961)
962{
963 for (wxWindowList::Node* pNode = GetChildren().GetFirst();
964 pNode;
965 pNode = pNode->GetNext())
966 {
967 // FIXME all this is totally bogus - we need to do the same as wxPanel,
968 // but how to do it without duplicating the code?
969
970 // restore focus
971 wxWindow* pChild = pNode->GetData();
972
973 if (!pChild->IsTopLevel()
974#if wxUSE_TOOLBAR
975 && !wxDynamicCast(pChild, wxToolBar)
976#endif // wxUSE_TOOLBAR
977#if wxUSE_STATUSBAR
978 && !wxDynamicCast(pChild, wxStatusBar)
979#endif // wxUSE_STATUSBAR
980 )
981 {
982 pChild->SetFocus();
983 return;
984 }
985 }
986} // end of wxFrame::OnActivate
987
988// ----------------------------------------------------------------------------
989// wxFrame size management: we exclude the areas taken by menu/status/toolbars
990// from the client area, so the client area is what's really available for the
991// frame contents
992// ----------------------------------------------------------------------------
993
994// Checks if there is a toolbar, and returns the first free client position
995wxPoint wxFrame::GetClientAreaOrigin() const
996{
997 wxPoint vPoint(0, 0);
998
999 if (GetToolBar())
1000 {
1001 int nWidth;
1002 int nHeight;
1003
1004 GetToolBar()->GetSize( &nWidth
1005 ,&nHeight
1006 );
1007
1008 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL)
1009 {
1010 vPoint.x += nWidth;
1011 }
1012 else
1013 {
1014 // PM is backwards from windows
1015 vPoint.y += nHeight;
1016 }
1017 }
1018 return vPoint;
1019} // end of wxFrame::GetClientAreaOrigin
1020
1021// ----------------------------------------------------------------------------
1022// tool/status bar stuff
1023// ----------------------------------------------------------------------------
1024
1025#if wxUSE_TOOLBAR
1026
1027wxToolBar* wxFrame::CreateToolBar(
1028 long lStyle
1029, wxWindowID vId
1030, const wxString& rName
1031)
1032{
1033 if (wxFrameBase::CreateToolBar( lStyle
1034 ,vId
1035 ,rName
1036 ))
1037 {
1038 PositionToolBar();
1039 }
1040 return m_frameToolBar;
1041} // end of wxFrame::CreateToolBar
1042
1043void wxFrame::PositionToolBar()
1044{
1045 HWND hWndClient;
1046 RECTL vRect;
1047
1048 ::WinQueryWindowRect(GetHwnd(), &vRect);
1049
1050#if wxUSE_STATUSBAR
1051 if (GetStatusBar())
1052 {
1053 int nStatusX;
1054 int nStatusY;
1055
1056 GetStatusBar()->GetClientSize( &nStatusX
1057 ,&nStatusY
1058 );
1059 // PM is backwards from windows
1060 vRect.yBottom += nStatusY;
1061 }
1062#endif // wxUSE_STATUSBAR
1063
1064 if ( GetToolBar() )
1065 {
1066 int nToolbarWidth;
1067 int nToolbarHeight;
1068
1069 GetToolBar()->GetSize( &nToolbarWidth
1070 ,&nToolbarHeight
1071 );
1072
1073 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL)
1074 {
1075 nToolbarHeight = vRect.yBottom;
1076 }
1077 else
1078 {
1079 nToolbarWidth = vRect.xRight;
1080 }
1081
1082 //
1083 // Use the 'real' PM position here
1084 //
1085 GetToolBar()->SetSize( 0
1086 ,0
1087 ,nToolbarWidth
1088 ,nToolbarHeight
1089 ,wxSIZE_NO_ADJUSTMENTS
1090 );
1091 }
1092} // end of wxFrame::PositionToolBar
1093#endif // wxUSE_TOOLBAR
1094
1095// ----------------------------------------------------------------------------
1096// frame state (iconized/maximized/...)
1097// ----------------------------------------------------------------------------
1098
1099//
1100// propagate our state change to all child frames: this allows us to emulate X
1101// Windows behaviour where child frames float independently of the parent one
1102// on the desktop, but are iconized/restored with it
1103//
1104void wxFrame::IconizeChildFrames(
1105 bool bIconize
1106)
1107{
1108 for (wxWindowList::Node* pNode = GetChildren().GetFirst();
1109 pNode;
1110 pNode = pNode->GetNext() )
1111 {
1112 wxWindow* pWin = pNode->GetData();
1113
1114 if (pWin->IsKindOf(CLASSINFO(wxFrame)) )
1115 {
1116 ((wxFrame *)pWin)->Iconize(bIconize);
1117 }
1118 }
1119} // end of wxFrame::IconizeChildFrames
1120
1121// ===========================================================================
1122// message processing
1123// ===========================================================================
1124
1125// ---------------------------------------------------------------------------
1126// preprocessing
1127// ---------------------------------------------------------------------------
1128bool wxFrame::OS2TranslateMessage(
1129 WXMSG* pMsg
1130)
1131{
1132 if (wxWindow::OS2TranslateMessage(pMsg))
1133 return TRUE;
1134 //
1135 // try the menu bar accels
1136 //
1137 wxMenuBar* pMenuBar = GetMenuBar();
1138
1139 if (!pMenuBar )
1140 return FALSE;
1141
1142 const wxAcceleratorTable& rAcceleratorTable = pMenuBar->GetAccelTable();
1143 return rAcceleratorTable.Translate(this, pMsg);
1144} // end of wxFrame::OS2TranslateMessage
1145
1146// ---------------------------------------------------------------------------
1147// our private (non virtual) message handlers
1148// ---------------------------------------------------------------------------
1149bool wxFrame::HandlePaint()
1150{
1151 RECTL vRect;
1152
1153 if (::WinQueryUpdateRect(m_hFrame, &vRect))
1154 {
1155 if (m_bIconized)
1156 {
1157 //
1158 // Icons in PM are the same as "pointers"
1159 //
1160 HPOINTER hIcon;
1161
1162 if (m_icon.Ok())
1163 hIcon = (HPOINTER)::WinSendMsg(m_hFrame, WM_QUERYICON, 0L, 0L);
1164 else
1165 hIcon = (HPOINTER)m_hDefaultIcon;
1166
1167 //
1168 // Hold a pointer to the dc so long as the OnPaint() message
1169 // is being processed
1170 //
1171 RECTL vRect2;
1172 HPS hPs = ::WinBeginPaint(m_hFrame, NULLHANDLE, &vRect2);
1173
1174 //
1175 // Erase background before painting or we get white background
1176 //
1177 OS2DefWindowProc(WM_ERASEBACKGROUND, (MPARAM)hPs, (MPARAM)&vRect2);
1178
1179 if (hIcon)
1180 {
1181 HWND hWndClient;
1182 RECTL vRect3;
1183
1184 ::WinQueryWindowRect(GetHwnd(), &vRect3);
1185
1186 static const int nIconWidth = 32;
1187 static const int nIconHeight = 32;
1188 int nIconX = (int)((vRect3.xRight - nIconWidth)/2);
1189 int nIconY = (int)((vRect3.yBottom + nIconHeight)/2);
1190
1191 ::WinDrawPointer(hPs, nIconX, nIconY, hIcon, DP_NORMAL);
1192 }
1193 ::WinEndPaint(hPs);
1194 return TRUE;
1195 }
1196 else
1197 {
1198 return wxWindow::HandlePaint();
1199 }
1200 }
1201 else
1202 {
1203 // nothing to paint - processed
1204 return TRUE;
1205 }
1206 return FALSE;
1207} // end of wxFrame::HandlePaint
1208
1209bool wxFrame::HandleSize(
1210 int nX
1211, int nY
1212, WXUINT nId
1213)
1214{
1215 bool bProcessed = FALSE;
1216
1217 switch (nId)
1218 {
1219 case kSizeNormal:
1220 //
1221 // Only do it it if we were iconized before, otherwise resizing the
1222 // parent frame has a curious side effect of bringing it under it's
1223 // children
1224 if (!m_bIconized )
1225 break;
1226
1227 //
1228 // restore all child frames too
1229 //
1230 IconizeChildFrames(FALSE);
1231
1232 //
1233 // fall through
1234 //
1235
1236 case kSizeMax:
1237 m_bIconized = FALSE;
1238 break;
1239
1240 case kSizeMin:
1241 //
1242 // Iconize all child frames too
1243 //
1244 IconizeChildFrames(TRUE);
1245 m_bIconized = TRUE;
1246 break;
1247 }
1248
1249 if (!m_bIconized)
1250 {
1251 //
1252 // forward WM_SIZE to status bar control
1253 //
1254#if wxUSE_NATIVE_STATUSBAR
1255 if (m_frameStatusBar && m_frameStatusBar->IsKindOf(CLASSINFO(wxStatusBar95)))
1256 {
1257 wxSizeEvent vEvent( wxSize( nX
1258 ,nY
1259 )
1260 ,m_frameStatusBar->GetId()
1261 );
1262
1263 vEvent.SetEventObject(m_frameStatusBar);
1264 m_frameStatusBar->OnSize(vEvent);
1265 }
1266#endif // wxUSE_NATIVE_STATUSBAR
1267
1268 PositionStatusBar();
1269 PositionToolBar();
1270 wxSizeEvent vEvent( wxSize( nX
1271 ,nY
1272 )
1273 ,m_windowId
1274 );
1275
1276 vEvent.SetEventObject(this);
1277 bProcessed = GetEventHandler()->ProcessEvent(vEvent);
1278 }
1279 return bProcessed;
1280} // end of wxFrame::HandleSize
1281
1282bool wxFrame::HandleCommand(
1283 WXWORD nId
1284, WXWORD nCmd
1285, WXHWND hControl
1286)
1287{
1288 if (hControl)
1289 {
1290 //
1291 // In case it's e.g. a toolbar.
1292 //
1293 wxWindow* pWin = wxFindWinFromHandle(hControl);
1294
1295 if (pWin)
1296 return pWin->OS2Command( nCmd
1297 ,nId
1298 );
1299 }
1300
1301 //
1302 // Handle here commands from menus and accelerators
1303 //
1304 if (nCmd == 0 || nCmd == 1)
1305 {
1306 if (wxCurrentPopupMenu)
1307 {
1308 wxMenu* pPopupMenu = wxCurrentPopupMenu;
1309
1310 wxCurrentPopupMenu = NULL;
1311
1312 return pPopupMenu->OS2Command( nCmd
1313 ,nId
1314 );
1315 }
1316
1317 if (ProcessCommand(nId))
1318 {
1319 return TRUE;
1320 }
1321 }
1322 return FALSE;
1323} // end of wxFrame::HandleCommand
1324
1325bool wxFrame::HandleMenuSelect(
1326 WXWORD nItem
1327, WXWORD nFlags
1328, WXHMENU hMenu
1329)
1330{
1331 int nMenuItem;
1332
1333 if (nFlags == 0xFFFF && hMenu == 0)
1334 {
1335 //
1336 // Menu was removed from screen
1337 //
1338 nMenuItem = -1;
1339 }
1340 else if (!(nFlags & MIS_SUBMENU) && !(nFlags & MIS_SEPARATOR))
1341 {
1342 nMenuItem = nItem;
1343 }
1344 else
1345 {
1346 //
1347 // Don't give hints for separators (doesn't make sense) nor for the
1348 // items opening popup menus (they don't have them anyhow)
1349 //
1350 return FALSE;
1351 }
1352 wxMenuEvent vEvent(wxEVT_MENU_HIGHLIGHT, nMenuItem);
1353
1354 vEvent.SetEventObject(this);
1355 return GetEventHandler()->ProcessEvent(vEvent);
1356} // end of wxFrame::HandleMenuSelect
1357
1358// ---------------------------------------------------------------------------
1359// the window proc for wxFrame
1360// ---------------------------------------------------------------------------
1361
1362MRESULT wxFrame::OS2WindowProc(
1363 WXUINT uMessage
1364, WXWPARAM wParam
1365, WXLPARAM lParam
1366)
1367{
1368 MRESULT mRc = 0L;
1369 bool bProcessed = FALSE;
1370
1371 switch (uMessage)
1372 {
1373 case WM_CLOSE:
1374 //
1375 // If we can't close, tell the system that we processed the
1376 // message - otherwise it would close us
1377 //
1378 bProcessed = !Close();
1379 break;
1380
1381 case WM_COMMAND:
1382 {
1383 WORD wId;
1384 WORD wCmd;
1385 WXHWND hWnd;
1386
1387 UnpackCommand( (WXWPARAM)wParam
1388 ,(WXLPARAM)lParam
1389 ,&wId
1390 ,&hWnd
1391 ,&wCmd
1392 );
1393 bProcessed = HandleCommand( wId
1394 ,wCmd
1395 ,(WXHWND)hWnd
1396 );
1397 }
1398 break;
1399
1400 case WM_MENUSELECT:
1401 {
1402 WXWORD wItem;
1403 WXWORD wFlags;
1404 WXHMENU hMenu;
1405
1406 UnpackMenuSelect( wParam
1407 ,lParam
1408 ,&wItem
1409 ,&wFlags
1410 ,&hMenu
1411 );
1412 bProcessed = HandleMenuSelect( wItem
1413 ,wFlags
1414 ,hMenu
1415 );
1416 }
1417 break;
1418
1419 case WM_PAINT:
1420 bProcessed = HandlePaint();
1421 break;
1422
1423 case WM_ERASEBACKGROUND:
1424 //
1425 // Return TRUE to request PM to paint the window background
1426 // in SYSCLR_WINDOW.
1427 //
1428 bProcessed = TRUE;
1429 mRc = (MRESULT)(TRUE);
1430 break;
1431
1432 case CM_QUERYDRAGIMAGE:
1433 {
1434 HPOINTER hIcon;
1435
1436 if (m_icon.Ok())
1437 hIcon = (HPOINTER)::WinSendMsg(m_hFrame, WM_QUERYICON, 0L, 0L);
1438 else
1439 hIcon = (HPOINTER)m_hDefaultIcon;
1440 mRc = (MRESULT)hIcon;
1441 bProcessed = mRc != 0;
1442 }
1443 break;
1444
1445 case WM_SIZE:
1446 bProcessed = HandleSize(LOWORD(lParam), HIWORD(lParam), (WXUINT)wParam);
1447 break;
1448 }
1449
1450 if (!bProcessed )
1451 mRc = wxWindow::OS2WindowProc( uMessage
1452 ,wParam
1453 ,lParam
1454 );
1455 return (MRESULT)0;
1456} // wxFrame::OS2WindowProc
1457