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