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