no message
[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;
346
347 hClient = ::WinWindowFromID(GetHwnd(), FID_CLIENT);
348 ::WinShowWindow(GetHwnd(), (BOOL)bShowCmd);
349 ::WinShowWindow(hClient, (BOOL)bShowCmd);
350 } // end of wxFrame::DoShowWindow
351
352 bool wxFrame::Show(
353 bool bShow
354 )
355 {
356 SWP vSwp;
357
358 DoShowWindow((int)bShow);
359
360 if (bShow)
361 {
362 wxActivateEvent vEvent(wxEVT_ACTIVATE, TRUE, m_windowId);
363
364 ::WinQueryWindowPos(GetHwnd(), &vSwp);
365 m_bIconized = vSwp.fl & SWP_MINIMIZE;
366 ::WinSetWindowPos( (HWND) GetHWND()
367 ,HWND_TOP
368 ,vSwp.x
369 ,vSwp.y
370 ,vSwp.cx
371 ,vSwp.cy
372 ,SWP_ZORDER | SWP_ACTIVATE | SWP_SHOW | SWP_MOVE
373 );
374 vEvent.SetEventObject(this);
375 GetEventHandler()->ProcessEvent(vEvent);
376 }
377 else
378 {
379 //
380 // Try to highlight the correct window (the parent)
381 //
382 if (GetParent())
383 {
384 HWND hWndParent = GetHwndOf(GetParent());
385
386 ::WinQueryWindowPos(hWndParent, &vSwp);
387 m_bIconized = vSwp.fl & SWP_MINIMIZE;
388 if (hWndParent)
389 ::WinSetWindowPos( hWndParent
390 ,HWND_TOP
391 ,vSwp.x
392 ,vSwp.y
393 ,vSwp.cx
394 ,vSwp.cy
395 ,SWP_ZORDER | SWP_ACTIVATE | SWP_SHOW | SWP_MOVE
396 );
397 }
398 }
399 return TRUE;
400 } // end of wxFrame::Show
401
402 void wxFrame::Iconize(
403 bool bIconize
404 )
405 {
406 DoShowWindow(bIconize ? SWP_MINIMIZE : SWP_RESTORE);
407 } // end of wxFrame::Iconize
408
409 void wxFrame::Maximize(
410 bool bMaximize)
411 {
412 DoShowWindow(bMaximize ? SWP_MAXIMIZE : SWP_RESTORE);
413 } // end of wxFrame::Maximize
414
415 void wxFrame::Restore()
416 {
417 DoShowWindow(SWP_RESTORE);
418 } // end of wxFrame::Restore
419
420 bool wxFrame::IsIconized() const
421 {
422 SWP vSwp;
423 bool bIconic;
424
425 ::WinQueryWindowPos(GetHwnd(), &vSwp);
426
427 if (vSwp.fl & SWP_MINIMIZE)
428 ((wxFrame*)this)->m_bIconized = TRUE;
429 else
430 ((wxFrame*)this)->m_bIconized = FALSE;
431 return m_bIconized;
432 } // end of wxFrame::IsIconized
433
434 // Is it maximized?
435 bool wxFrame::IsMaximized() const
436 {
437 SWP vSwp;
438 bool bIconic;
439
440 ::WinQueryWindowPos(GetHwnd(), &vSwp);
441 return (vSwp.fl & SWP_MAXIMIZE);
442 } // end of wxFrame::IsMaximized
443
444 void wxFrame::SetIcon(
445 const wxIcon& rIcon
446 )
447 {
448 wxFrameBase::SetIcon(rIcon);
449
450 if ((m_icon.GetHICON()) != NULLHANDLE)
451 {
452 ::WinSendMsg( GetHwnd()
453 ,WM_SETICON
454 ,(MPARAM)((HPOINTER)m_icon.GetHICON())
455 ,NULL
456 );
457 ::WinSendMsg( GetHwnd()
458 ,WM_UPDATEFRAME
459 ,(MPARAM)FCF_ICON
460 ,(MPARAM)0
461 );
462 }
463 } // end of wxFrame::SetIcon
464
465 #if wxUSE_STATUSBAR
466 wxStatusBar* wxFrame::OnCreateStatusBar(
467 int nNumber
468 , long lulStyle
469 , wxWindowID vId
470 , const wxString& rName
471 )
472 {
473 wxStatusBar* pStatusBar = NULL;
474
475 pStatusBar = wxFrameBase::OnCreateStatusBar( nNumber
476 ,lulStyle
477 ,vId
478 ,rName
479 );
480 return pStatusBar;
481 } // end of wxFrame::OnCreateStatusBar
482
483 void wxFrame::PositionStatusBar()
484 {
485 //
486 // Native status bar positions itself
487 //
488 if (m_frameStatusBar)
489 {
490 int nWidth;
491 int nHeight;
492 int nStatbarWidth;
493 int nStatbarHeight;
494 HWND hWndClient;
495 RECTL vRect;
496
497 hWndClient = ::WinWindowFromID(GetHwnd(), FID_CLIENT);
498 ::WinQueryWindowRect(hWndClient, &vRect);
499 nWidth = vRect.xRight - vRect.xLeft;
500 nHeight = vRect.yTop - vRect.yBottom;
501
502 m_frameStatusBar->GetSize( &nStatbarWidth
503 ,&nStatbarHeight
504 );
505
506 //
507 // Since we wish the status bar to be directly under the client area,
508 // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.
509 //
510 m_frameStatusBar->SetSize( 0
511 ,nHeight
512 ,nWidth
513 ,nStatbarHeight
514 );
515 }
516 } // end of wxFrame::PositionStatusBar
517 #endif // wxUSE_STATUSBAR
518
519 void wxFrame::DetachMenuBar()
520 {
521 if (m_frameMenuBar)
522 {
523 m_frameMenuBar->Detach();
524 m_frameMenuBar = NULL;
525 }
526 } // end of wxFrame::DetachMenuBar
527
528 void wxFrame::SetMenuBar(
529 wxMenuBar* pMenuBar
530 )
531 {
532 if (!pMenuBar)
533 {
534 DetachMenuBar();
535 return;
536 }
537
538 m_frameMenuBar = NULL;
539
540 // Can set a menubar several times.
541 // TODO: how to prevent a memory leak if you have a currently-unattached
542 // menubar? wxWindows assumes that the frame will delete the menu (otherwise
543 // there are problems for MDI).
544 if (pMenuBar->GetHMenu())
545 {
546 m_hMenu = pMenuBar->GetHMenu();
547 }
548 else
549 {
550 pMenuBar->Detach();
551
552 m_hMenu = pMenuBar->Create();
553
554 if (!m_hMenu)
555 return;
556 }
557
558 InternalSetMenuBar();
559
560 m_frameMenuBar = pMenuBar;
561 pMenuBar->Attach(this);
562 } // end of wxFrame::SetMenuBar
563
564 void wxFrame::InternalSetMenuBar()
565 {
566 WinSendMsg((HWND)GetHwnd(), WM_UPDATEFRAME, (MPARAM)FCF_MENU, (MPARAM)0);
567 } // end of wxFrame::InternalSetMenuBar
568
569 //
570 // Responds to colour changes, and passes event on to children
571 //
572 void wxFrame::OnSysColourChanged(
573 wxSysColourChangedEvent& rEvent
574 )
575 {
576 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE));
577 Refresh();
578
579 if (m_frameStatusBar)
580 {
581 wxSysColourChangedEvent vEvent2;
582
583 vEvent2.SetEventObject(m_frameStatusBar);
584 m_frameStatusBar->GetEventHandler()->ProcessEvent(vEvent2);
585 }
586
587 //
588 // Propagate the event to the non-top-level children
589 //
590 wxWindow::OnSysColourChanged(rEvent);
591 } // end of wxFrame::OnSysColourChanged
592
593 // Pass TRUE to show full screen, FALSE to restore.
594 bool wxFrame::ShowFullScreen(
595 bool bShow
596 , long lStyle
597 )
598 {
599 /*
600 // TODO
601 if (show)
602 {
603 if (IsFullScreen())
604 return FALSE;
605
606 m_fsIsShowing = TRUE;
607 m_fsStyle = style;
608
609 wxToolBar *theToolBar = GetToolBar();
610 wxStatusBar *theStatusBar = GetStatusBar();
611
612 int dummyWidth;
613
614 if (theToolBar)
615 theToolBar->GetSize(&dummyWidth, &m_fsToolBarHeight);
616 if (theStatusBar)
617 theStatusBar->GetSize(&dummyWidth, &m_fsStatusBarHeight);
618
619 // zap the toolbar, menubar, and statusbar
620
621 if ((style & wxFULLSCREEN_NOTOOLBAR) && theToolBar)
622 {
623 theToolBar->SetSize(-1,0);
624 theToolBar->Show(FALSE);
625 }
626
627 if (style & wxFULLSCREEN_NOMENUBAR)
628 SetMenu((HWND)GetHWND(), (HMENU) NULL);
629
630 // Save the number of fields in the statusbar
631 if ((style & wxFULLSCREEN_NOSTATUSBAR) && theStatusBar)
632 {
633 m_fsStatusBarFields = theStatusBar->GetFieldsCount();
634 SetStatusBar((wxStatusBar*) NULL);
635 delete theStatusBar;
636 }
637 else
638 m_fsStatusBarFields = 0;
639
640 // zap the frame borders
641
642 // save the 'normal' window style
643 m_fsOldWindowStyle = GetWindowLong((HWND)GetHWND(), GWL_STYLE);
644
645 // save the old position, width & height, maximize state
646 m_fsOldSize = GetRect();
647 m_fsIsMaximized = IsMaximized();
648
649 // decide which window style flags to turn off
650 LONG newStyle = m_fsOldWindowStyle;
651 LONG offFlags = 0;
652
653 if (style & wxFULLSCREEN_NOBORDER)
654 offFlags |= WS_BORDER;
655 if (style & wxFULLSCREEN_NOCAPTION)
656 offFlags |= (WS_CAPTION | WS_SYSMENU);
657
658 newStyle &= (~offFlags);
659
660 // change our window style to be compatible with full-screen mode
661 SetWindowLong((HWND)GetHWND(), GWL_STYLE, newStyle);
662
663 // resize to the size of the desktop
664 int width, height;
665
666 RECT rect;
667 ::GetWindowRect(GetDesktopWindow(), &rect);
668 width = rect.right - rect.left;
669 height = rect.bottom - rect.top;
670
671 SetSize(width, height);
672
673 // now flush the window style cache and actually go full-screen
674 SetWindowPos((HWND)GetHWND(), HWND_TOP, 0, 0, width, height, SWP_FRAMECHANGED);
675
676 wxSizeEvent event(wxSize(width, height), GetId());
677 GetEventHandler()->ProcessEvent(event);
678
679 return TRUE;
680 }
681 else
682 {
683 if (!IsFullScreen())
684 return FALSE;
685
686 m_fsIsShowing = FALSE;
687
688 wxToolBar *theToolBar = GetToolBar();
689
690 // restore the toolbar, menubar, and statusbar
691 if (theToolBar && (m_fsStyle & wxFULLSCREEN_NOTOOLBAR))
692 {
693 theToolBar->SetSize(-1, m_fsToolBarHeight);
694 theToolBar->Show(TRUE);
695 }
696
697 if ((m_fsStyle & wxFULLSCREEN_NOSTATUSBAR) && (m_fsStatusBarFields > 0))
698 {
699 CreateStatusBar(m_fsStatusBarFields);
700 PositionStatusBar();
701 }
702
703 if ((m_fsStyle & wxFULLSCREEN_NOMENUBAR) && (m_hMenu != 0))
704 SetMenu((HWND)GetHWND(), (HMENU)m_hMenu);
705
706 Maximize(m_fsIsMaximized);
707 SetWindowLong((HWND)GetHWND(),GWL_STYLE, m_fsOldWindowStyle);
708 SetWindowPos((HWND)GetHWND(),HWND_TOP,m_fsOldSize.x, m_fsOldSize.y,
709 m_fsOldSize.width, m_fsOldSize.height, SWP_FRAMECHANGED);
710
711 return TRUE;
712 }
713 */
714 return TRUE;
715 } // end of wxFrame::ShowFullScreen
716
717 //
718 // Frame window
719 //
720 bool wxFrame::OS2Create(
721 int nId
722 , wxWindow* pParent
723 , const wxChar* zWclass
724 , wxWindow* pWxWin
725 , const wxChar* zTitle
726 , int nX
727 , int nY
728 , int nWidth
729 , int nHeight
730 , long ulStyle
731 )
732 {
733 ULONG ulCreateFlags = 0L;
734 ULONG ulStyleFlags = 0L;
735 ULONG ulExtraFlags = 0L;
736 FRAMECDATA vFrameCtlData;
737 HWND hParent = NULLHANDLE;
738 HWND hClient = NULLHANDLE;
739 HWND hTitlebar = NULLHANDLE;
740 HWND hHScroll = NULLHANDLE;
741 HWND hVScroll = NULLHANDLE;
742 SWP vSwp;
743 SWP vSwpTitlebar;
744 SWP vSwpVScroll;
745 SWP vSwpHScroll;
746
747 m_hDefaultIcon = (WXHICON) (wxSTD_FRAME_ICON ? wxSTD_FRAME_ICON : wxDEFAULT_FRAME_ICON);
748 memset(&vSwp, '\0', sizeof(SWP));
749 memset(&vSwpTitlebar, '\0', sizeof(SWP));
750 memset(&vSwpVScroll, '\0', sizeof(SWP));
751 memset(&vSwpHScroll, '\0', sizeof(SWP));
752 if (pParent)
753 hParent = GetWinHwnd(pParent);
754 else
755 hParent = HWND_DESKTOP;
756
757 if (ulStyle == wxDEFAULT_FRAME_STYLE)
758 ulCreateFlags = FCF_SIZEBORDER | FCF_TITLEBAR | FCF_SYSMENU |
759 FCF_MINMAX | FCF_VERTSCROLL | FCF_HORZSCROLL | FCF_TASKLIST;
760 else
761 {
762 if ((ulStyle & wxCAPTION) == wxCAPTION)
763 ulCreateFlags = FCF_TASKLIST;
764 else
765 ulCreateFlags = FCF_NOMOVEWITHOWNER;
766
767 if (ulStyle & wxMINIMIZE_BOX)
768 ulCreateFlags |= FCF_MINBUTTON;
769 if (ulStyle & wxMAXIMIZE_BOX)
770 ulCreateFlags |= FCF_MAXBUTTON;
771 if (ulStyle & wxTHICK_FRAME)
772 ulCreateFlags |= FCF_DLGBORDER;
773 if (ulStyle & wxSYSTEM_MENU)
774 ulCreateFlags |= FCF_SYSMENU;
775 if (ulStyle & wxCAPTION)
776 ulCreateFlags |= FCF_TASKLIST;
777 if (ulStyle & wxCLIP_CHILDREN)
778 {
779 // Invalid for frame windows under PM
780 }
781
782 if (ulStyle & wxTINY_CAPTION_VERT)
783 ulCreateFlags |= FCF_TASKLIST;
784 if (ulStyle & wxTINY_CAPTION_HORIZ)
785 ulCreateFlags |= FCF_TASKLIST;
786
787 if ((ulStyle & wxTHICK_FRAME) == 0)
788 ulCreateFlags |= FCF_BORDER;
789 if (ulStyle & wxFRAME_TOOL_WINDOW)
790 ulExtraFlags = kFrameToolWindow;
791
792 if (ulStyle & wxSTAY_ON_TOP)
793 ulCreateFlags |= FCF_SYSMODAL;
794 }
795 if ((ulStyle & wxMINIMIZE) || (ulStyle & wxICONIZE))
796 ulStyleFlags |= WS_MINIMIZED;
797 if (ulStyle & wxMAXIMIZE)
798 ulStyleFlags |= WS_MAXIMIZED;
799
800 //
801 // Clear the visible flag, we always call show
802 //
803 ulStyleFlags &= (unsigned long)~WS_VISIBLE;
804 m_bIconized = FALSE;
805
806 //
807 // Set the frame control block
808 //
809 vFrameCtlData.cb = sizeof(vFrameCtlData);
810 vFrameCtlData.flCreateFlags = ulCreateFlags;
811 vFrameCtlData.hmodResources = 0L;
812 vFrameCtlData.idResources = 0;
813
814 //
815 // Create the frame window
816 //
817 if (!wxWindow::OS2Create( hParent
818 ,WC_FRAME
819 ,zTitle
820 ,ulStyleFlags
821 ,(long)nX
822 ,(long)nY
823 ,(long)nWidth
824 ,(long)nHeight
825 ,NULLHANDLE
826 ,HWND_TOP
827 ,(long)nId
828 ,(void*)&vFrameCtlData
829 ,NULL
830 ))
831 {
832 return FALSE;
833 }
834
835 //
836 // Create the client window. We must call the API from here rather than
837 // the static base class create because we need a separate handle
838 //
839 if ((hClient = ::WinCreateWindow( GetHwnd() // Frame is parent
840 ,zWclass // Custom client class
841 ,NULL // Window title
842 ,0 // No styles
843 ,0, 0, 0, 0 // Window position
844 ,NULLHANDLE // Owner
845 ,HWND_TOP // Sibling
846 ,FID_CLIENT // standard client ID
847 ,NULL // Creation data
848 ,NULL // Window Pres Params
849 )) == 0L)
850 {
851 return FALSE;
852 }
853 //
854 // Send anything to initialize the frame
855 //
856 ::WinSendMsg( GetHwnd()
857 ,WM_UPDATEFRAME
858 ,(MPARAM)FCF_TASKLIST
859 ,(MPARAM)0
860 );
861
862 //
863 // Now size everything. If adding a menu the client will need to be resized.
864 //
865 if (!::WinSetWindowPos( GetHwnd()
866 ,HWND_TOP
867 ,nX
868 ,nY
869 ,nWidth
870 ,nHeight
871 ,SWP_SIZE | SWP_MOVE | SWP_ACTIVATE
872 ))
873 return FALSE;
874
875 WinQueryWindowPos(GetHwnd(), &vSwp);
876
877 if (ulCreateFlags & FCF_TITLEBAR)
878 {
879 hTitlebar = WinWindowFromID(GetHwnd(), FID_TITLEBAR);
880 WinQueryWindowPos(hTitlebar, &vSwpTitlebar);
881 }
882 if (ulCreateFlags & FCF_HORZSCROLL)
883 {
884 hHScroll = WinWindowFromID(GetHwnd(), FID_HORZSCROLL);
885 WinQueryWindowPos(hHScroll, &vSwpHScroll);
886 }
887 if (ulCreateFlags & FCF_VERTSCROLL)
888 {
889 hVScroll = WinWindowFromID(GetHwnd(), FID_VERTSCROLL);
890 WinQueryWindowPos(hVScroll, &vSwpVScroll);
891 }
892 if (!::WinSetWindowPos( hClient
893 ,HWND_TOP
894 ,SV_CXSIZEBORDER
895 ,(SV_CYSIZEBORDER - 1) + vSwpHScroll.cy
896 ,vSwp.cx - ((SV_CXSIZEBORDER * 2) + vSwpVScroll.cx)
897 ,vSwp.cy - ((SV_CYSIZEBORDER * 2) + 1 + vSwpTitlebar.cy + vSwpHScroll.cy)
898 ,SWP_SIZE | SWP_MOVE
899 ))
900 return FALSE;
901 return TRUE;
902 } // end of wxFrame::OS2Create
903
904 //
905 // Default activation behaviour - set the focus for the first child
906 // subwindow found.
907 //
908 void wxFrame::OnActivate(
909 wxActivateEvent& rEvent
910 )
911 {
912 for (wxWindowList::Node* pNode = GetChildren().GetFirst();
913 pNode;
914 pNode = pNode->GetNext())
915 {
916 // FIXME all this is totally bogus - we need to do the same as wxPanel,
917 // but how to do it without duplicating the code?
918
919 // restore focus
920 wxWindow* pChild = pNode->GetData();
921
922 if (!pChild->IsTopLevel()
923 #if wxUSE_TOOLBAR
924 && !wxDynamicCast(pChild, wxToolBar)
925 #endif // wxUSE_TOOLBAR
926 #if wxUSE_STATUSBAR
927 && !wxDynamicCast(pChild, wxStatusBar)
928 #endif // wxUSE_STATUSBAR
929 )
930 {
931 pChild->SetFocus();
932 return;
933 }
934 }
935 } // end of wxFrame::OnActivate
936
937 // ----------------------------------------------------------------------------
938 // wxFrame size management: we exclude the areas taken by menu/status/toolbars
939 // from the client area, so the client area is what's really available for the
940 // frame contents
941 // ----------------------------------------------------------------------------
942
943 // Checks if there is a toolbar, and returns the first free client position
944 wxPoint wxFrame::GetClientAreaOrigin() const
945 {
946 wxPoint vPoint(0, 0);
947
948 if (GetToolBar())
949 {
950 int nWidth;
951 int nHeight;
952
953 GetToolBar()->GetSize( &nWidth
954 ,&nHeight
955 );
956
957 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL)
958 {
959 vPoint.x += nWidth;
960 }
961 else
962 {
963 // PM is backwards from windows
964 vPoint.y += nHeight;
965 }
966 }
967 return vPoint;
968 } // end of wxFrame::GetClientAreaOrigin
969
970 // ----------------------------------------------------------------------------
971 // tool/status bar stuff
972 // ----------------------------------------------------------------------------
973
974 #if wxUSE_TOOLBAR
975
976 wxToolBar* wxFrame::CreateToolBar(
977 long lStyle
978 , wxWindowID vId
979 , const wxString& rName
980 )
981 {
982 if (wxFrameBase::CreateToolBar( lStyle
983 ,vId
984 ,rName
985 ))
986 {
987 PositionToolBar();
988 }
989 return m_frameToolBar;
990 } // end of wxFrame::CreateToolBar
991
992 void wxFrame::PositionToolBar()
993 {
994 HWND hWndClient;
995 RECTL vRect;
996
997 hWndClient = ::WinWindowFromID(GetHwnd(), FID_CLIENT);
998 ::WinQueryWindowRect(hWndClient, &vRect);
999
1000 #if wxUSE_STATUSBAR
1001 if (GetStatusBar())
1002 {
1003 int nStatusX;
1004 int nStatusY;
1005
1006 GetStatusBar()->GetClientSize( &nStatusX
1007 ,&nStatusY
1008 );
1009 // PM is backwards from windows
1010 vRect.yBottom += nStatusY;
1011 }
1012 #endif // wxUSE_STATUSBAR
1013
1014 if ( GetToolBar() )
1015 {
1016 int nToolbarWidth;
1017 int nToolbarHeight;
1018
1019 GetToolBar()->GetSize( &nToolbarWidth
1020 ,&nToolbarHeight
1021 );
1022
1023 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL)
1024 {
1025 nToolbarHeight = vRect.yBottom;
1026 }
1027 else
1028 {
1029 nToolbarWidth = vRect.xRight;
1030 }
1031
1032 //
1033 // Use the 'real' PM position here
1034 //
1035 GetToolBar()->SetSize( 0
1036 ,0
1037 ,nToolbarWidth
1038 ,nToolbarHeight
1039 ,wxSIZE_NO_ADJUSTMENTS
1040 );
1041 }
1042 } // end of wxFrame::PositionToolBar
1043 #endif // wxUSE_TOOLBAR
1044
1045 // ----------------------------------------------------------------------------
1046 // frame state (iconized/maximized/...)
1047 // ----------------------------------------------------------------------------
1048
1049 //
1050 // propagate our state change to all child frames: this allows us to emulate X
1051 // Windows behaviour where child frames float independently of the parent one
1052 // on the desktop, but are iconized/restored with it
1053 //
1054 void wxFrame::IconizeChildFrames(
1055 bool bIconize
1056 )
1057 {
1058 for (wxWindowList::Node* pNode = GetChildren().GetFirst();
1059 pNode;
1060 pNode = pNode->GetNext() )
1061 {
1062 wxWindow* pWin = pNode->GetData();
1063
1064 if (pWin->IsKindOf(CLASSINFO(wxFrame)) )
1065 {
1066 ((wxFrame *)pWin)->Iconize(bIconize);
1067 }
1068 }
1069 } // end of wxFrame::IconizeChildFrames
1070
1071 // ===========================================================================
1072 // message processing
1073 // ===========================================================================
1074
1075 // ---------------------------------------------------------------------------
1076 // preprocessing
1077 // ---------------------------------------------------------------------------
1078 bool wxFrame::OS2TranslateMessage(
1079 WXMSG* pMsg
1080 )
1081 {
1082 if (wxWindow::OS2TranslateMessage(pMsg))
1083 return TRUE;
1084 //
1085 // try the menu bar accels
1086 //
1087 wxMenuBar* pMenuBar = GetMenuBar();
1088
1089 if (!pMenuBar )
1090 return FALSE;
1091
1092 const wxAcceleratorTable& rAcceleratorTable = pMenuBar->GetAccelTable();
1093 return rAcceleratorTable.Translate(this, pMsg);
1094 } // end of wxFrame::OS2TranslateMessage
1095
1096 // ---------------------------------------------------------------------------
1097 // our private (non virtual) message handlers
1098 // ---------------------------------------------------------------------------
1099 bool wxFrame::HandlePaint()
1100 {
1101 RECTL vRect;
1102
1103 if (::WinQueryUpdateRect(GetHwnd(), &vRect))
1104 {
1105 if (m_bIconized)
1106 {
1107 //
1108 // Icons in PM are the same as "pointers"
1109 //
1110 HPOINTER hIcon;
1111
1112 if (m_icon.Ok())
1113 hIcon = (HPOINTER)::WinSendMsg(GetHwnd(), WM_QUERYICON, 0L, 0L);
1114 else
1115 hIcon = (HPOINTER)m_hDefaultIcon;
1116
1117 //
1118 // Hold a pointer to the dc so long as the OnPaint() message
1119 // is being processed
1120 //
1121 RECTL vRect2;
1122 HPS hPs = ::WinBeginPaint(GetHwnd(), NULLHANDLE, &vRect2);
1123
1124 //
1125 // Erase background before painting or we get white background
1126 //
1127 OS2DefWindowProc(WM_ERASEBACKGROUND, (MPARAM)hPs, (MPARAM)&vRect2);
1128
1129 if (hIcon)
1130 {
1131 HWND hWndClient;
1132 RECTL vRect3;
1133
1134 hWndClient = ::WinWindowFromID(GetHwnd(), FID_CLIENT);
1135 ::WinQueryWindowRect(hWndClient, &vRect3);
1136
1137 static const int nIconWidth = 32;
1138 static const int nIconHeight = 32;
1139 int nIconX = (int)((vRect3.xRight - nIconWidth)/2);
1140 int nIconY = (int)((vRect3.yBottom + nIconHeight)/2);
1141
1142 ::WinDrawPointer(hPs, nIconX, nIconY, hIcon, DP_NORMAL);
1143 }
1144 ::WinEndPaint(hPs);
1145 return TRUE;
1146 }
1147 else
1148 {
1149 return wxWindow::HandlePaint();
1150 }
1151 }
1152 else
1153 {
1154 // nothing to paint - processed
1155 return TRUE;
1156 }
1157 return FALSE;
1158 } // end of wxFrame::HandlePaint
1159
1160 bool wxFrame::HandleSize(
1161 int nX
1162 , int nY
1163 , WXUINT nId
1164 )
1165 {
1166 bool bProcessed = FALSE;
1167
1168 switch (nId)
1169 {
1170 case kSizeNormal:
1171 //
1172 // Only do it it if we were iconized before, otherwise resizing the
1173 // parent frame has a curious side effect of bringing it under it's
1174 // children
1175 if (!m_bIconized )
1176 break;
1177
1178 //
1179 // restore all child frames too
1180 //
1181 IconizeChildFrames(FALSE);
1182
1183 //
1184 // fall through
1185 //
1186
1187 case kSizeMax:
1188 m_bIconized = FALSE;
1189 break;
1190
1191 case kSizeMin:
1192 //
1193 // Iconize all child frames too
1194 //
1195 IconizeChildFrames(TRUE);
1196 m_bIconized = TRUE;
1197 break;
1198 }
1199
1200 if (!m_bIconized)
1201 {
1202 //
1203 // forward WM_SIZE to status bar control
1204 //
1205 #if wxUSE_NATIVE_STATUSBAR
1206 if (m_frameStatusBar && m_frameStatusBar->IsKindOf(CLASSINFO(wxStatusBar95)))
1207 {
1208 wxSizeEvent vEvent( wxSize( nX
1209 ,nY
1210 )
1211 ,m_frameStatusBar->GetId()
1212 );
1213
1214 vEvent.SetEventObject(m_frameStatusBar);
1215 m_frameStatusBar->OnSize(vEvent);
1216 }
1217 #endif // wxUSE_NATIVE_STATUSBAR
1218
1219 PositionStatusBar();
1220 PositionToolBar();
1221 wxSizeEvent vEvent( wxSize( nX
1222 ,nY
1223 )
1224 ,m_windowId
1225 );
1226
1227 vEvent.SetEventObject(this);
1228 bProcessed = GetEventHandler()->ProcessEvent(vEvent);
1229 }
1230 return bProcessed;
1231 } // end of wxFrame::HandleSize
1232
1233 bool wxFrame::HandleCommand(
1234 WXWORD nId
1235 , WXWORD nCmd
1236 , WXHWND hControl
1237 )
1238 {
1239 if (hControl)
1240 {
1241 //
1242 // In case it's e.g. a toolbar.
1243 //
1244 wxWindow* pWin = wxFindWinFromHandle(hControl);
1245
1246 if (pWin)
1247 return pWin->OS2Command( nCmd
1248 ,nId
1249 );
1250 }
1251
1252 //
1253 // Handle here commands from menus and accelerators
1254 //
1255 if (nCmd == 0 || nCmd == 1)
1256 {
1257 if (wxCurrentPopupMenu)
1258 {
1259 wxMenu* pPopupMenu = wxCurrentPopupMenu;
1260
1261 wxCurrentPopupMenu = NULL;
1262
1263 return pPopupMenu->OS2Command( nCmd
1264 ,nId
1265 );
1266 }
1267
1268 if (ProcessCommand(nId))
1269 {
1270 return TRUE;
1271 }
1272 }
1273 return FALSE;
1274 } // end of wxFrame::HandleCommand
1275
1276 bool wxFrame::HandleMenuSelect(
1277 WXWORD nItem
1278 , WXWORD nFlags
1279 , WXHMENU hMenu
1280 )
1281 {
1282 int nMenuItem;
1283
1284 if (nFlags == 0xFFFF && hMenu == 0)
1285 {
1286 //
1287 // Menu was removed from screen
1288 //
1289 nMenuItem = -1;
1290 }
1291 else if (!(nFlags & MIS_SUBMENU) && !(nFlags & MIS_SEPARATOR))
1292 {
1293 nMenuItem = nItem;
1294 }
1295 else
1296 {
1297 //
1298 // Don't give hints for separators (doesn't make sense) nor for the
1299 // items opening popup menus (they don't have them anyhow)
1300 //
1301 return FALSE;
1302 }
1303 wxMenuEvent vEvent(wxEVT_MENU_HIGHLIGHT, nMenuItem);
1304
1305 vEvent.SetEventObject(this);
1306 return GetEventHandler()->ProcessEvent(vEvent);
1307 } // end of wxFrame::HandleMenuSelect
1308
1309 // ---------------------------------------------------------------------------
1310 // the window proc for wxFrame
1311 // ---------------------------------------------------------------------------
1312
1313 MRESULT wxFrame::OS2WindowProc(
1314 WXUINT uMessage
1315 , WXWPARAM wParam
1316 , WXLPARAM lParam
1317 )
1318 {
1319 MRESULT mRc = 0L;
1320 bool bProcessed = FALSE;
1321
1322 switch (uMessage)
1323 {
1324 case WM_CLOSE:
1325 //
1326 // If we can't close, tell the system that we processed the
1327 // message - otherwise it would close us
1328 //
1329 bProcessed = !Close();
1330 break;
1331
1332 case WM_COMMAND:
1333 {
1334 WORD wId;
1335 WORD wCmd;
1336 WXHWND hWnd;
1337
1338 UnpackCommand( (WXWPARAM)wParam
1339 ,(WXLPARAM)lParam
1340 ,&wId
1341 ,&hWnd
1342 ,&wCmd
1343 );
1344 bProcessed = HandleCommand( wId
1345 ,wCmd
1346 ,(WXHWND)hWnd
1347 );
1348 }
1349 break;
1350
1351 case WM_MENUSELECT:
1352 {
1353 WXWORD wItem;
1354 WXWORD wFlags;
1355 WXHMENU hMenu;
1356
1357 UnpackMenuSelect( wParam
1358 ,lParam
1359 ,&wItem
1360 ,&wFlags
1361 ,&hMenu
1362 );
1363 bProcessed = HandleMenuSelect( wItem
1364 ,wFlags
1365 ,hMenu
1366 );
1367 }
1368 break;
1369
1370 case WM_PAINT:
1371 bProcessed = HandlePaint();
1372 break;
1373
1374 case CM_QUERYDRAGIMAGE:
1375 {
1376 HPOINTER hIcon;
1377
1378 if (m_icon.Ok())
1379 hIcon = (HPOINTER)::WinSendMsg(GetHwnd(), WM_QUERYICON, 0L, 0L);
1380 else
1381 hIcon = (HPOINTER)m_hDefaultIcon;
1382 mRc = (MRESULT)hIcon;
1383 bProcessed = mRc != 0;
1384 }
1385 break;
1386
1387 case WM_SIZE:
1388 bProcessed = HandleSize(LOWORD(lParam), HIWORD(lParam), (WXUINT)wParam);
1389 break;
1390 }
1391
1392 if (!bProcessed )
1393 mRc = wxWindow::OS2WindowProc( uMessage
1394 ,wParam
1395 ,lParam
1396 );
1397 return (MRESULT)0;
1398 } // wxFrame::OS2WindowProc
1399