]> git.saurik.com Git - wxWidgets.git/blob - src/os2/frame.cpp
deprecate unneeded wxDIRCTRL_SHOW_FILTERS style, just always show the filters if...
[wxWidgets.git] / src / os2 / frame.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        src/os2/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/object.h"
17     #include "wx/dynarray.h"
18     #include "wx/list.h"
19     #include "wx/hash.h"
20     #include "wx/string.h"
21     #include "wx/intl.h"
22     #include "wx/log.h"
23     #include "wx/event.h"
24     #include "wx/frame.h"
25     #include "wx/menu.h"
26     #include "wx/app.h"
27     #include "wx/utils.h"
28     #include "wx/dialog.h"
29     #include "wx/settings.h"
30     #include "wx/dcclient.h"
31     #include "wx/mdi.h"
32     #include "wx/toolbar.h"
33     #include "wx/statusbr.h"
34     #include "wx/menuitem.h"
35 #endif // WX_PRECOMP
36
37 #include "wx/os2/private.h"
38
39 // ----------------------------------------------------------------------------
40 // globals
41 // ----------------------------------------------------------------------------
42
43 #if wxUSE_MENUS_NATIVE
44 extern wxMenu *wxCurrentPopupMenu;
45 #endif
46
47 // ----------------------------------------------------------------------------
48 // event tables
49 // ----------------------------------------------------------------------------
50
51 BEGIN_EVENT_TABLE(wxFrame, wxFrameBase)
52     EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged)
53 END_EVENT_TABLE()
54
55 IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxWindow)
56
57 // ============================================================================
58 // implementation
59 // ============================================================================
60
61 // ----------------------------------------------------------------------------
62 // static class members
63 // ----------------------------------------------------------------------------
64 #if wxUSE_STATUSBAR
65
66 #if wxUSE_NATIVE_STATUSBAR
67     bool wxFrame::m_bUseNativeStatusBar = true;
68 #else
69     bool wxFrame::m_bUseNativeStatusBar = false;
70 #endif
71
72 #endif //wxUSE_STATUSBAR
73
74 // ----------------------------------------------------------------------------
75 // creation/destruction
76 // ----------------------------------------------------------------------------
77
78 void wxFrame::Init()
79 {
80     m_nFsStatusBarFields = 0;
81     m_nFsStatusBarHeight = 0;
82     m_nFsToolBarHeight   = 0;
83     m_hWndToolTip        = 0L;
84     m_bWasMinimized      = false;
85
86
87     m_frameMenuBar   = NULL;
88     m_frameToolBar   = NULL;
89     m_frameStatusBar = NULL;
90
91     m_hTitleBar = NULLHANDLE;
92     m_hHScroll  = NULLHANDLE;
93     m_hVScroll  = NULLHANDLE;
94
95     //
96     // Initialize SWP's
97     //
98     memset(&m_vSwpTitleBar, 0, sizeof(SWP));
99     memset(&m_vSwpMenuBar, 0, sizeof(SWP));
100     memset(&m_vSwpHScroll, 0, sizeof(SWP));
101     memset(&m_vSwpVScroll, 0, sizeof(SWP));
102     memset(&m_vSwpStatusBar, 0, sizeof(SWP));
103     memset(&m_vSwpToolBar, 0, sizeof(SWP));
104     m_bIconized = false;
105
106 } // end of wxFrame::Init
107
108 bool wxFrame::Create( wxWindow*       pParent,
109                       wxWindowID      vId,
110                       const wxString& rsTitle,
111                       const wxPoint&  rPos,
112                       const wxSize&   rSize,
113                       long            lStyle,
114                       const wxString& rsName )
115 {
116     if (!wxTopLevelWindow::Create( pParent
117                                   ,vId
118                                   ,rsTitle
119                                   ,rPos
120                                   ,rSize
121                                   ,lStyle
122                                   ,rsName
123                                  ))
124         return false;
125     return true;
126 } // end of wxFrame::Create
127
128 wxFrame::~wxFrame()
129 {
130     m_isBeingDeleted = true;
131     DeleteAllBars();
132 } // end of wxFrame::~wxFrame
133
134 //
135 // Get size *available for subwindows* i.e. excluding menu bar, toolbar etc.
136 //
137 void wxFrame::DoGetClientSize(
138   int*                              pX
139 , int*                              pY
140 ) const
141 {
142     wxTopLevelWindow::DoGetClientSize( pX
143                                       ,pY
144                                      );
145     //
146     // No need to use statusbar code as in WIN32 as the FORMATFRAME
147     // window procedure ensures PM knows about the new frame client
148     // size internally.  A ::WinQueryWindowRect (that is called in
149     // wxWindow's GetClient size from above) is all that is needed!
150     //
151 } // end of wxFrame::DoGetClientSize
152
153 //
154 // Set the client size (i.e. leave the calculation of borders etc.
155 // to wxWidgets)
156 //
157 void wxFrame::DoSetClientSize(
158   int                               nWidth
159 , int                               nHeight
160 )
161 {
162     //
163     // Statusbars are not part of the OS/2 Client but parent frame
164     // so no statusbar consideration
165     //
166     wxTopLevelWindow::DoSetClientSize( nWidth
167                                       ,nHeight
168                                      );
169 } // end of wxFrame::DoSetClientSize
170
171 // ----------------------------------------------------------------------------
172 // wxFrame: various geometry-related functions
173 // ----------------------------------------------------------------------------
174
175 void wxFrame::Raise()
176 {
177     wxFrameBase::Raise();
178     ::WinSetWindowPos( (HWND) GetParent()->GetHWND()
179                       ,HWND_TOP
180                       ,0
181                       ,0
182                       ,0
183                       ,0
184                       ,SWP_ZORDER
185                      );
186 }
187
188 #if wxUSE_STATUSBAR
189 wxStatusBar* wxFrame::OnCreateStatusBar(
190   int                               nNumber
191 , long                              lulStyle
192 , wxWindowID                        vId
193 , const wxString&                   rName
194 )
195 {
196     wxStatusBar*                    pStatusBar = NULL;
197     wxString                        sError;
198
199     pStatusBar = wxFrameBase::OnCreateStatusBar( nNumber
200                                                 ,lulStyle
201                                                 ,vId
202                                                 ,rName
203                                                  );
204
205     if( !pStatusBar )
206         return NULL;
207
208     wxClientDC                      vDC(pStatusBar);
209     int                             nY;
210
211     //
212     // Set the height according to the font and the border size
213     //
214     vDC.SetFont(pStatusBar->GetFont()); // Screws up the menues for some reason
215     vDC.GetTextExtent( wxT("X")
216                       ,NULL
217                       ,&nY
218                      );
219
220     int                             nHeight = ((11 * nY) / 10 + 2 * pStatusBar->GetBorderY());
221
222     pStatusBar->SetSize( wxDefaultCoord
223                         ,wxDefaultCoord
224                         ,wxDefaultCoord
225                         ,nHeight
226                        );
227
228     ::WinSetParent( pStatusBar->GetHWND(), m_hFrame, FALSE );
229     ::WinSetOwner( pStatusBar->GetHWND(), m_hFrame);
230     //
231     // to show statusbar
232     //
233     if(::WinIsWindowShowing(m_hFrame))
234         ::WinSendMsg(m_hFrame, WM_UPDATEFRAME, (MPARAM)~0, 0);
235
236     return pStatusBar;
237 } // end of wxFrame::OnCreateStatusBar
238
239 void wxFrame::PositionStatusBar()
240 {
241     SWP                             vSwp;
242     ERRORID                         vError;
243     wxString                        sError;
244
245     //
246     // Native status bar positions itself
247     //
248     if (m_frameStatusBar)
249     {
250         int                         nWidth;
251         int                         nY;
252         int                         nStatbarWidth;
253         int                         nStatbarHeight;
254         RECTL                       vRect;
255         RECTL                       vFRect;
256
257         ::WinQueryWindowRect(m_hFrame, &vRect);
258         nY = vRect.yTop;
259         ::WinMapWindowPoints(m_hFrame, HWND_DESKTOP, (PPOINTL)&vRect, 2);
260         vFRect = vRect;
261         ::WinCalcFrameRect(m_hFrame, &vRect, TRUE);
262         nWidth = vRect.xRight - vRect.xLeft;
263         nY = nY - (vRect.yBottom - vFRect.yBottom);
264
265         m_frameStatusBar->GetSize( &nStatbarWidth
266                                   ,&nStatbarHeight
267                                  );
268
269         nY= nY - nStatbarHeight;
270         //
271         // Since we wish the status bar to be directly under the client area,
272         // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.
273         //
274         m_frameStatusBar->SetSize( vRect.xLeft - vFRect.xLeft
275                                   ,nY
276                                   ,nWidth
277                                   ,nStatbarHeight
278                                  );
279         if (!::WinQueryWindowPos(m_frameStatusBar->GetHWND(), &vSwp))
280         {
281             vError = ::WinGetLastError(vHabmain);
282             sError = wxPMErrorToStr(vError);
283             wxLogError(_T("Error setting parent for StatusBar. Error: %s\n"), sError.c_str());
284             return;
285         }
286     }
287 } // end of wxFrame::PositionStatusBar
288 #endif // wxUSE_STATUSBAR
289
290 #if wxUSE_TOOLBAR
291 wxToolBar* wxFrame::OnCreateToolBar( long lStyle, wxWindowID vId, const wxString& rsName )
292 {
293     wxToolBar*                      pToolBar = wxFrameBase::OnCreateToolBar( lStyle
294                                                                             ,vId
295                                                                             ,rsName
296                                                                            );
297
298     ::WinSetParent( pToolBar->GetHWND(), m_hFrame, FALSE);
299     ::WinSetOwner( pToolBar->GetHWND(), m_hFrame);
300     return pToolBar;
301 } // end of WinGuiBase_CFrame::OnCreateToolBar
302 #endif
303
304 #if wxUSE_MENUS_NATIVE
305 void wxFrame::DetachMenuBar()
306 {
307     if (m_frameMenuBar)
308     {
309         m_frameMenuBar->Detach();
310         m_frameMenuBar = NULL;
311     }
312 } // end of wxFrame::DetachMenuBar
313
314 void wxFrame::SetMenuBar(
315   wxMenuBar*                        pMenuBar
316 )
317 {
318     wxString                        sError;
319
320     if (!pMenuBar)
321     {
322         DetachMenuBar();
323
324         //
325         // Actually remove the menu from the frame
326         //
327         m_hMenu = (WXHMENU)0;
328         InternalSetMenuBar();
329     }
330     else // set new non NULL menu bar
331     {
332         m_frameMenuBar = NULL;
333
334         //
335         // Can set a menubar several times.
336         // TODO: how to prevent a memory leak if you have a currently-unattached
337         // menubar? wxWidgets assumes that the frame will delete the menu (otherwise
338         // there are problems for MDI).
339         //
340         if (pMenuBar->GetHMenu())
341         {
342             m_hMenu = pMenuBar->GetHMenu();
343         }
344         else
345         {
346             pMenuBar->Detach();
347             m_hMenu = pMenuBar->Create();
348             if (!m_hMenu)
349                 return;
350         }
351         InternalSetMenuBar();
352         m_frameMenuBar = pMenuBar;
353         pMenuBar->Attach((wxFrame*)this);
354     }
355 } // end of wxFrame::SetMenuBar
356
357 void wxFrame::AttachMenuBar(
358   wxMenuBar*                        pMenubar
359 )
360 {
361     wxFrameBase::AttachMenuBar(pMenubar);
362
363     m_frameMenuBar = pMenubar;
364
365     if (!pMenubar)
366     {
367         //
368         // Actually remove the menu from the frame
369         //
370         m_hMenu = (WXHMENU)0;
371         InternalSetMenuBar();
372     }
373     else // Set new non NULL menu bar
374     {
375         //
376         // Can set a menubar several times.
377         //
378         if (pMenubar->GetHMenu())
379         {
380             m_hMenu = pMenubar->GetHMenu();
381         }
382         else
383         {
384             if (pMenubar->IsAttached())
385                 pMenubar->Detach();
386
387             m_hMenu = pMenubar->Create();
388
389             if (!m_hMenu)
390                 return;
391         }
392         InternalSetMenuBar();
393     }
394 } // end of wxFrame::AttachMenuBar
395
396 void wxFrame::InternalSetMenuBar()
397 {
398     ERRORID                         vError;
399     wxString                        sError;
400     //
401     // Set the parent and owner of the menubar to be the frame
402     //
403     if (!::WinSetParent(m_hMenu, m_hFrame, FALSE))
404     {
405         vError = ::WinGetLastError(vHabmain);
406         sError = wxPMErrorToStr(vError);
407         wxLogError(_T("Error setting parent for submenu. Error: %s\n"), sError.c_str());
408     }
409
410     if (!::WinSetOwner(m_hMenu, m_hFrame))
411     {
412         vError = ::WinGetLastError(vHabmain);
413         sError = wxPMErrorToStr(vError);
414         wxLogError(_T("Error setting parent for submenu. Error: %s\n"), sError.c_str());
415     }
416     ::WinSendMsg(m_hFrame, WM_UPDATEFRAME, (MPARAM)FCF_MENU, (MPARAM)0);
417 } // end of wxFrame::InternalSetMenuBar
418 #endif // wxUSE_MENUS_NATIVE
419
420 //
421 // Responds to colour changes, and passes event on to children
422 //
423 void wxFrame::OnSysColourChanged(
424   wxSysColourChangedEvent&          rEvent
425 )
426 {
427     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE));
428     Refresh();
429
430 #if wxUSE_STATUSBAR
431     if (m_frameStatusBar)
432     {
433         wxSysColourChangedEvent     vEvent2;
434
435         vEvent2.SetEventObject(m_frameStatusBar);
436         m_frameStatusBar->GetEventHandler()->ProcessEvent(vEvent2);
437     }
438 #endif //wxUSE_STATUSBAR
439
440     //
441     // Propagate the event to the non-top-level children
442     //
443     wxWindow::OnSysColourChanged(rEvent);
444 } // end of wxFrame::OnSysColourChanged
445
446 // Pass true to show full screen, false to restore.
447 bool wxFrame::ShowFullScreen( bool bShow, long lStyle )
448 {
449     if (bShow)
450     {
451         if (IsFullScreen())
452             return false;
453
454         m_bFsIsShowing = true;
455         m_lFsStyle = lStyle;
456
457 #if wxUSE_TOOLBAR
458         wxToolBar*                  pTheToolBar = GetToolBar();
459 #endif //wxUSE_TOOLBAR
460
461 #if wxUSE_STATUSBAR
462         wxStatusBar*                pTheStatusBar = GetStatusBar();
463 #endif //wxUSE_STATUSBAR
464
465         int                         nDummyWidth;
466
467 #if wxUSE_TOOLBAR
468         if (pTheToolBar)
469             pTheToolBar->GetSize(&nDummyWidth, &m_nFsToolBarHeight);
470 #endif //wxUSE_TOOLBAR
471
472 #if wxUSE_STATUSBAR
473         if (pTheStatusBar)
474             pTheStatusBar->GetSize(&nDummyWidth, &m_nFsStatusBarHeight);
475 #endif //wxUSE_STATUSBAR
476
477 #if wxUSE_TOOLBAR
478         //
479         // Zap the toolbar, menubar, and statusbar
480         //
481         if ((lStyle & wxFULLSCREEN_NOTOOLBAR) && pTheToolBar)
482         {
483             pTheToolBar->SetSize(wxDefaultCoord,0);
484             pTheToolBar->Show(false);
485         }
486 #endif //wxUSE_TOOLBAR
487
488         if (lStyle & wxFULLSCREEN_NOMENUBAR)
489         {
490             ::WinSetParent(m_hMenu, m_hFrame, FALSE);
491             ::WinSetOwner(m_hMenu, m_hFrame);
492             ::WinSendMsg((HWND)m_hFrame, WM_UPDATEFRAME, (MPARAM)FCF_MENU, (MPARAM)0);
493         }
494
495 #if wxUSE_STATUSBAR
496         //
497         // Save the number of fields in the statusbar
498         //
499         if ((lStyle & wxFULLSCREEN_NOSTATUSBAR) && pTheStatusBar)
500         {
501             m_nFsStatusBarFields = pTheStatusBar->GetFieldsCount();
502             SetStatusBar((wxStatusBar*) NULL);
503             delete pTheStatusBar;
504         }
505         else
506             m_nFsStatusBarFields = 0;
507 #endif //wxUSE_STATUSBAR
508
509         //
510         // Zap the frame borders
511         //
512
513         //
514         // Save the 'normal' window style
515         //
516         m_lFsOldWindowStyle = ::WinQueryWindowULong(m_hFrame, QWL_STYLE);
517
518         //
519         // Save the old position, width & height, maximize state
520         //
521         m_vFsOldSize = GetRect();
522         m_bFsIsMaximized = IsMaximized();
523
524         //
525         // Decide which window style flags to turn off
526         //
527         LONG lNewStyle = m_lFsOldWindowStyle;
528         LONG lOffFlags = 0;
529
530         if (lStyle & wxFULLSCREEN_NOBORDER)
531             lOffFlags |= FCF_BORDER;
532         if (lStyle & wxFULLSCREEN_NOCAPTION)
533             lOffFlags |= (FCF_TASKLIST | FCF_SYSMENU);
534
535         lNewStyle &= (~lOffFlags);
536
537         //
538         // Change our window style to be compatible with full-screen mode
539         //
540         ::WinSetWindowULong((HWND)m_hFrame, QWL_STYLE, (ULONG)lNewStyle);
541
542         //
543         // Resize to the size of the desktop
544         int                         nWidth;
545         int                         nHeight;
546
547         RECTL                       vRect;
548
549         ::WinQueryWindowRect(HWND_DESKTOP, &vRect);
550         nWidth = vRect.xRight - vRect.xLeft;
551         //
552         // Remember OS/2 is backwards!
553         //
554         nHeight = vRect.yTop - vRect.yBottom;
555
556         SetSize( nWidth, nHeight);
557
558         //
559         // Now flush the window style cache and actually go full-screen
560         //
561         ::WinSetWindowPos( (HWND) GetParent()->GetHWND()
562                           ,HWND_TOP
563                           ,0
564                           ,0
565                           ,nWidth
566                           ,nHeight
567                           ,SWP_SIZE | SWP_SHOW
568                          );
569
570         wxSize sz( nWidth, nHeight );
571         wxSizeEvent vEvent( sz, GetId() );
572
573         GetEventHandler()->ProcessEvent(vEvent);
574         return true;
575     }
576     else
577     {
578         if (!IsFullScreen())
579             return false;
580
581         m_bFsIsShowing = false;
582
583 #if wxUSE_TOOLBAR
584         wxToolBar*                  pTheToolBar = GetToolBar();
585
586         //
587         // Restore the toolbar, menubar, and statusbar
588         //
589         if (pTheToolBar && (m_lFsStyle & wxFULLSCREEN_NOTOOLBAR))
590         {
591             pTheToolBar->SetSize(wxDefaultCoord, m_nFsToolBarHeight);
592             pTheToolBar->Show(true);
593         }
594 #endif //wxUSE_TOOLBAR
595
596 #if wxUSE_STATUSBAR
597         if ((m_lFsStyle & wxFULLSCREEN_NOSTATUSBAR) && (m_nFsStatusBarFields > 0))
598         {
599             CreateStatusBar(m_nFsStatusBarFields);
600 //          PositionStatusBar();
601         }
602 #endif //wxUSE_STATUSBAR
603
604         if ((m_lFsStyle & wxFULLSCREEN_NOMENUBAR) && (m_hMenu != 0))
605         {
606             ::WinSetParent(m_hMenu, m_hFrame, FALSE);
607             ::WinSetOwner(m_hMenu, m_hFrame);
608             ::WinSendMsg(m_hFrame, WM_UPDATEFRAME, (MPARAM)FCF_MENU, (MPARAM)0);
609         }
610         Maximize(m_bFsIsMaximized);
611
612         ::WinSetWindowULong( m_hFrame
613                             ,QWL_STYLE
614                             ,(ULONG)m_lFsOldWindowStyle
615                            );
616         ::WinSetWindowPos( (HWND) GetParent()->GetHWND()
617                           ,HWND_TOP
618                           ,m_vFsOldSize.x
619                           ,m_vFsOldSize.y
620                           ,m_vFsOldSize.width
621                           ,m_vFsOldSize.height
622                           ,SWP_SIZE | SWP_SHOW
623                          );
624     }
625     return wxFrameBase::ShowFullScreen(bShow, lStyle);
626 } // end of wxFrame::ShowFullScreen
627
628 //
629 // Frame window
630 //
631 // ----------------------------------------------------------------------------
632 // wxFrame size management: we exclude the areas taken by menu/status/toolbars
633 // from the client area, so the client area is what's really available for the
634 // frame contents
635 // ----------------------------------------------------------------------------
636
637 // Checks if there is a toolbar, and returns the first free client position
638 wxPoint wxFrame::GetClientAreaOrigin() const
639 {
640     wxPoint                         vPoint = wxTopLevelWindow::GetClientAreaOrigin();
641
642     //
643     // In OS/2 the toolbar and statusbar are frame extensions so there is no
644     // adjustment.  The client is supposedly resized for a toolbar in OS/2
645     // as it is for the status bar.
646     //
647     return vPoint;
648 } // end of wxFrame::GetClientAreaOrigin
649
650 // ----------------------------------------------------------------------------
651 // tool/status bar stuff
652 // ----------------------------------------------------------------------------
653
654 #if wxUSE_TOOLBAR
655
656 wxToolBar* wxFrame::CreateToolBar(
657   long                              lStyle
658 , wxWindowID                        vId
659 , const wxString&                   rName
660 )
661 {
662     if (wxFrameBase::CreateToolBar( lStyle
663                                    ,vId
664                                    ,rName
665                                   ))
666     {
667         PositionToolBar();
668     }
669     return m_frameToolBar;
670 } // end of wxFrame::CreateToolBar
671
672 void wxFrame::PositionToolBar()
673 {
674     wxToolBar*                      pToolBar = GetToolBar();
675     wxCoord                         vWidth;
676     wxCoord                         vHeight;
677     wxCoord                         vTWidth;
678     wxCoord                         vTHeight;
679
680     if (!pToolBar)
681         return;
682
683     RECTL                           vRect;
684     RECTL                           vFRect;
685     wxPoint                         vPos;
686
687     ::WinQueryWindowRect(m_hFrame, &vRect);
688     vPos.y = (wxCoord)vRect.yTop;
689     ::WinMapWindowPoints(m_hFrame, HWND_DESKTOP, (PPOINTL)&vRect, 2);
690     vFRect = vRect;
691     ::WinCalcFrameRect(m_hFrame, &vRect, TRUE);
692
693     vPos.y = (wxCoord)(vFRect.yTop - vRect.yTop);
694     pToolBar->GetSize( &vTWidth
695                       ,&vTHeight
696                      );
697
698     if (pToolBar->GetWindowStyleFlag() & wxTB_TOP)
699     {
700         vWidth = (wxCoord)(vRect.xRight - vRect.xLeft);
701         pToolBar->SetSize( vRect.xLeft - vFRect.xLeft
702                           ,vPos.y
703                           ,vWidth
704                           ,vTHeight
705                          );
706     }
707     else if (pToolBar->GetWindowStyleFlag() & wxTB_BOTTOM)
708     {
709         wxCoord                     vSwidth = 0;
710         wxCoord                     vSheight = 0;
711
712         if (m_frameStatusBar)
713             m_frameStatusBar->GetSize( &vSwidth
714                                       ,&vSheight
715                                      );
716         vWidth = (wxCoord)(vRect.xRight - vRect.xLeft);
717         pToolBar->SetSize( vRect.xLeft - vFRect.xLeft
718                           ,vFRect.yTop - vRect.yBottom - vTHeight - vSheight
719                           ,vWidth
720                           ,vTHeight
721                          );
722     }
723     else if (pToolBar->GetWindowStyleFlag() & wxTB_LEFT)
724     {
725         wxCoord                     vSwidth = 0;
726         wxCoord                     vSheight = 0;
727
728         if (m_frameStatusBar)
729             m_frameStatusBar->GetSize( &vSwidth
730                                       ,&vSheight
731                                      );
732         vHeight = (wxCoord)(vRect.yTop - vRect.yBottom);
733         pToolBar->SetSize( vRect.xLeft - vRect.xLeft
734                           ,vPos.y
735                           ,vTWidth
736                           ,vHeight - vSheight
737                          );
738     }
739     else
740     {
741         wxCoord                     vSwidth = 0;
742         wxCoord                     vSheight = 0;
743
744         if (m_frameStatusBar)
745             m_frameStatusBar->GetSize( &vSwidth
746                                       ,&vSheight
747                                      );
748         vHeight = (wxCoord)(vRect.yTop - vRect.yBottom);
749         pToolBar->SetSize( vRect.xRight - vFRect.xLeft - vTWidth
750                           ,vPos.y
751                           ,vTWidth
752                           ,vHeight - vSheight
753                          );
754     }
755     if( ::WinIsWindowShowing(m_hFrame) )
756         ::WinSendMsg(m_hFrame, WM_UPDATEFRAME, (MPARAM)~0, 0);
757 } // end of wxFrame::PositionToolBar
758 #endif // wxUSE_TOOLBAR
759
760 // ----------------------------------------------------------------------------
761 // frame state (iconized/maximized/...)
762 // ----------------------------------------------------------------------------
763
764 //
765 // propagate our state change to all child frames: this allows us to emulate X
766 // Windows behaviour where child frames float independently of the parent one
767 // on the desktop, but are iconized/restored with it
768 //
769 void wxFrame::IconizeChildFrames( bool WXUNUSED(bIconize) )
770 {
771   // FIXME: Generic MDI does not use Frames for the Childs, so this does _not_
772   //        work. Possibly, the right thing is simply to eliminate this
773   //        functions and all the calls to it from within this file.
774 #if 0
775     for (wxWindowList::Node* pNode = GetChildren().GetFirst();
776          pNode;
777          pNode = pNode->GetNext() )
778     {
779         wxWindow*                   pWin = pNode->GetData();
780         wxFrame*                    pFrame = wxDynamicCast(pWin, wxFrame);
781
782         if ( pFrame
783 #if wxUSE_MDI_ARCHITECTURE
784                 && !wxDynamicCast(pFrame, wxMDIChildFrame)
785 #endif // wxUSE_MDI_ARCHITECTURE
786            )
787         {
788             //
789             // We don't want to restore the child frames which had been
790             // iconized even before we were iconized, so save the child frame
791             // status when iconizing the parent frame and check it when
792             // restoring it.
793             //
794             if (bIconize)
795             {
796                 pFrame->m_bWasMinimized = pFrame->IsIconized();
797             }
798
799             //
800             // This test works for both iconizing and restoring
801             //
802             if (!pFrame->m_bWasMinimized)
803                 pFrame->Iconize(bIconize);
804         }
805     }
806 #endif
807 } // end of wxFrame::IconizeChildFrames
808
809 WXHICON wxFrame::GetDefaultIcon() const
810 {
811     return (WXHICON)(wxSTD_FRAME_ICON ? wxSTD_FRAME_ICON
812                                       : wxDEFAULT_FRAME_ICON);
813 }
814 // ===========================================================================
815 // message processing
816 // ===========================================================================
817
818 // ---------------------------------------------------------------------------
819 // preprocessing
820 // ---------------------------------------------------------------------------
821 bool wxFrame::OS2TranslateMessage( WXMSG* pMsg )
822 {
823     //
824     // try the menu bar accels
825     //
826     wxMenuBar* pMenuBar = GetMenuBar();
827
828     if (!pMenuBar)
829         return false;
830
831 #if wxUSE_ACCEL && wxUSE_MENUS_NATIVE
832     const wxAcceleratorTable&       rAcceleratorTable = pMenuBar->GetAccelTable();
833     return rAcceleratorTable.Translate(GetHWND(), pMsg);
834 #else
835     return false;
836 #endif //wxUSE_ACCEL
837 } // end of wxFrame::OS2TranslateMessage
838
839 // ---------------------------------------------------------------------------
840 // our private (non virtual) message handlers
841 // ---------------------------------------------------------------------------
842 bool wxFrame::HandlePaint()
843 {
844     RECTL vRect;
845
846     if (::WinQueryUpdateRect(GetHWND(), &vRect))
847     {
848         if (m_bIconized)
849         {
850             //
851             // Icons in PM are the same as "pointers"
852             //
853             const wxIcon&           vIcon = GetIcon();
854             HPOINTER                hIcon;
855
856             if (vIcon.Ok())
857                 hIcon = (HPOINTER)::WinSendMsg(m_hFrame, WM_QUERYICON, 0L, 0L);
858             else
859                 hIcon = (HPOINTER)m_hDefaultIcon;
860
861             //
862             // Hold a pointer to the dc so long as the OnPaint() message
863             // is being processed
864             //
865             RECTL                   vRect2;
866             HPS                     hPs = ::WinBeginPaint(GetHwnd(), NULLHANDLE, &vRect2);
867
868             //
869             // Erase background before painting or we get white background
870             //
871             OS2DefWindowProc(WM_ERASEBACKGROUND, (MPARAM)hPs, (MPARAM)&vRect2);
872
873             if (hIcon)
874             {
875                 RECTL                           vRect3;
876
877                 ::WinQueryWindowRect(GetHwnd(), &vRect3);
878
879                 static const int    nIconWidth = 32;
880                 static const int    nIconHeight = 32;
881                 int                 nIconX = (int)((vRect3.xRight - nIconWidth)/2);
882                 int                 nIconY = (int)((vRect3.yBottom + nIconHeight)/2);
883
884                 ::WinDrawPointer(hPs, nIconX, nIconY, hIcon, DP_NORMAL);
885             }
886             ::WinEndPaint(hPs);
887         }
888         else
889         {
890             if (!wxWindow::HandlePaint())
891             {
892                 HPS                     hPS;
893                 RECTL                   vRect;
894
895                 hPS = ::WinBeginPaint( GetHwnd()
896                                       ,NULLHANDLE
897                                       ,&vRect
898                                      );
899                 if(hPS)
900                 {
901                     ::GpiCreateLogColorTable( hPS
902                                              ,0L
903                                              ,LCOLF_CONSECRGB
904                                              ,0L
905                                              ,(LONG)wxTheColourDatabase->m_nSize
906                                              ,(PLONG)wxTheColourDatabase->m_palTable
907                                             );
908                     ::GpiCreateLogColorTable( hPS
909                                              ,0L
910                                              ,LCOLF_RGB
911                                              ,0L
912                                              ,0L
913                                              ,NULL
914                                             );
915
916                     ::WinFillRect( hPS
917                                   ,&vRect
918                                   ,GetBackgroundColour().GetPixel()
919                                  );
920                     ::WinEndPaint(hPS);
921                 }
922             }
923         }
924     }
925
926     return true;
927 } // end of wxFrame::HandlePaint
928
929 bool wxFrame::HandleSize( int nX, int nY, WXUINT nId )
930 {
931     bool bProcessed = false;
932
933     switch (nId)
934     {
935         case kSizeNormal:
936             //
937             // Only do it it if we were iconized before, otherwise resizing the
938             // parent frame has a curious side effect of bringing it under it's
939             // children
940             if (!m_bIconized )
941                 break;
942
943             //
944             // restore all child frames too
945             //
946             IconizeChildFrames(false);
947             (void)SendIconizeEvent(false);
948
949             //
950             // fall through
951             //
952
953         case kSizeMax:
954             m_bIconized = false;
955             break;
956
957         case kSizeMin:
958             //
959             // Iconize all child frames too
960             //
961             IconizeChildFrames(true);
962             (void)SendIconizeEvent();
963             m_bIconized = true;
964             break;
965     }
966
967     if (!m_bIconized)
968     {
969         //
970         // forward WM_SIZE to status bar control
971         //
972 #if wxUSE_NATIVE_STATUSBAR
973         if (m_frameStatusBar && m_frameStatusBar->IsKindOf(CLASSINFO(wxStatusBar95)))
974         {
975             wxSizeEvent             vEvent( wxSize( nX
976                                                    ,nY
977                                                   )
978                                            ,m_frameStatusBar->GetId()
979                                           );
980
981             vEvent.SetEventObject(m_frameStatusBar);
982             m_frameStatusBar->OnSize(vEvent);
983         }
984 #endif // wxUSE_NATIVE_STATUSBAR
985
986         PositionStatusBar();
987 #if  wxUSE_TOOLBAR
988         PositionToolBar();
989 #endif // wxUSE_TOOLBAR
990
991         bProcessed = wxWindow::HandleSize( nX
992                                           ,nY
993                                           ,nId
994                                          );
995     }
996     return bProcessed;
997 } // end of wxFrame::HandleSize
998
999 bool wxFrame::HandleCommand( WXWORD nId,
1000                              WXWORD nCmd,
1001                              WXHWND hControl )
1002 {
1003     if (hControl)
1004     {
1005         //
1006         // In case it's e.g. a toolbar.
1007         //
1008         wxWindow*                   pWin = wxFindWinFromHandle(hControl);
1009
1010         if (pWin)
1011             return pWin->OS2Command( nCmd, nId );
1012     }
1013
1014     //
1015     // Handle here commands from menus and accelerators
1016     //
1017     if (nCmd == CMDSRC_MENU || nCmd == CMDSRC_ACCELERATOR)
1018     {
1019 #if wxUSE_MENUS_NATIVE
1020         if (wxCurrentPopupMenu)
1021         {
1022             wxMenu*                 pPopupMenu = wxCurrentPopupMenu;
1023
1024             wxCurrentPopupMenu = NULL;
1025
1026             return pPopupMenu->OS2Command( nCmd, nId );
1027         }
1028 #endif
1029
1030         if (ProcessCommand(nId))
1031         {
1032             return true;
1033         }
1034     }
1035     return false;
1036 } // end of wxFrame::HandleCommand
1037
1038 bool wxFrame::HandleMenuSelect( WXWORD nItem,
1039                                 WXWORD nFlags,
1040                                 WXHMENU hMenu )
1041 {
1042     if( !nFlags )
1043     {
1044         MENUITEM mItem;
1045         MRESULT  rc;
1046
1047         rc = ::WinSendMsg(hMenu, MM_QUERYITEM, MPFROM2SHORT(nItem, TRUE), (MPARAM)&mItem);
1048
1049         if(rc && !(mItem.afStyle & (MIS_SUBMENU | MIS_SEPARATOR)))
1050         {
1051             wxMenuEvent                     vEvent(wxEVT_MENU_HIGHLIGHT, nItem);
1052
1053             vEvent.SetEventObject(this);
1054             GetEventHandler()->ProcessEvent(vEvent); // return value would be ignored by PM
1055         }
1056         else
1057         {
1058             DoGiveHelp(wxEmptyString, true);
1059             return false;
1060         }
1061     }
1062     return true;
1063 } // end of wxFrame::HandleMenuSelect
1064
1065 // ---------------------------------------------------------------------------
1066 // Main Frame window proc
1067 // ---------------------------------------------------------------------------
1068 MRESULT EXPENTRY wxFrameMainWndProc( HWND   hWnd,
1069                                      ULONG  ulMsg,
1070                                      MPARAM wParam,
1071                                      MPARAM lParam )
1072 {
1073     MRESULT  rc = (MRESULT)0;
1074     bool     bProcessed = false;
1075     wxFrame* pWnd  = NULL;
1076
1077     pWnd = (wxFrame*) wxFindWinFromHandle((WXHWND) hWnd);
1078     switch (ulMsg)
1079     {
1080         case WM_QUERYFRAMECTLCOUNT:
1081             if(pWnd && pWnd->m_fnOldWndProc)
1082             {
1083                 USHORT              uItemCount = SHORT1FROMMR(pWnd->m_fnOldWndProc(hWnd, ulMsg, wParam, lParam));
1084
1085                 rc = MRFROMSHORT(uItemCount);
1086             }
1087             break;
1088
1089         case WM_FORMATFRAME:
1090 /////////////////////////////////////////////////////////////////////////////////
1091 // Applications that subclass frame controls may find that the frame is already
1092 // subclassed the number of frame controls is variable.
1093 // The WM_FORMATFRAME and WM_QUERYFRAMECTLCOUNT messages must always be
1094 // subclassed by calling the previous window procedure and modifying its result.
1095 ////////////////////////////////////////////////////////////////////////////////
1096             {
1097                 int                 nItemCount;
1098                 int                 i;
1099                 PSWP                pSWP = NULL;
1100                 RECTL               vRectl;
1101                 RECTL               vRstb;
1102                 RECTL               vRtlb;
1103                 int                 nHeight = 0;
1104                 int                 nHeight2 = 0;
1105                 int                 nWidth = 0;
1106
1107                 pSWP = (PSWP)PVOIDFROMMP(wParam);
1108                 nItemCount = SHORT1FROMMR(pWnd->m_fnOldWndProc(hWnd, ulMsg, wParam, lParam));
1109                 if(pWnd->m_frameStatusBar)
1110                 {
1111                     ::WinQueryWindowRect(pWnd->m_frameStatusBar->GetHWND(), &vRstb);
1112                     pWnd->m_frameStatusBar->GetSize(NULL, &nHeight);
1113                 }
1114                 if(pWnd->m_frameToolBar)
1115                 {
1116                     ::WinQueryWindowRect(pWnd->m_frameToolBar->GetHWND(), &vRtlb);
1117                     pWnd->m_frameToolBar->GetSize(&nWidth, &nHeight2);
1118                 }
1119                 ::WinQueryWindowRect(pWnd->m_hFrame, &vRectl);
1120                 ::WinMapWindowPoints(pWnd->m_hFrame, HWND_DESKTOP, (PPOINTL)&vRectl, 2);
1121                 ::WinCalcFrameRect(pWnd->m_hFrame, &vRectl, TRUE);
1122                 ::WinMapWindowPoints(HWND_DESKTOP, pWnd->m_hFrame, (PPOINTL)&vRectl, 2);
1123                 for(i = 0; i < nItemCount; i++)
1124                 {
1125                     if(pWnd->m_hWnd && pSWP[i].hwnd == pWnd->m_hWnd)
1126                     {
1127                         if (pWnd->m_frameToolBar && pWnd->m_frameToolBar->GetWindowStyleFlag() & wxTB_TOP)
1128                         {
1129                             pSWP[i].x    = vRectl.xLeft;
1130                             pSWP[i].y    = vRectl.yBottom + nHeight;
1131                             pSWP[i].cx   = vRectl.xRight - vRectl.xLeft;
1132                             pSWP[i].cy   = vRectl.yTop - vRectl.yBottom - (nHeight + nHeight2);
1133                         }
1134                         else if (pWnd->m_frameToolBar && pWnd->m_frameToolBar->GetWindowStyleFlag() & wxTB_BOTTOM)
1135                         {
1136                             pSWP[i].x    = vRectl.xLeft;
1137                             pSWP[i].y    = vRectl.yBottom + nHeight + nHeight2;
1138                             pSWP[i].cx   = vRectl.xRight - vRectl.xLeft;
1139                             pSWP[i].cy   = vRectl.yTop - vRectl.yBottom - (nHeight + nHeight2);
1140                          }
1141                         else if (pWnd->m_frameToolBar && pWnd->m_frameToolBar->GetWindowStyleFlag() & wxTB_LEFT)
1142                         {
1143                             pSWP[i].x    = vRectl.xLeft + nWidth;
1144                             pSWP[i].y    = vRectl.yBottom + nHeight;
1145                             pSWP[i].cx   = vRectl.xRight - (vRectl.xLeft + nWidth);
1146                             pSWP[i].cy   = vRectl.yTop - vRectl.yBottom - nHeight;
1147                         }
1148                         else
1149                         {
1150                             pSWP[i].x    = vRectl.xLeft;
1151                             pSWP[i].y    = vRectl.yBottom + nHeight;
1152                             pSWP[i].cx   = vRectl.xRight - (vRectl.xLeft + nWidth);
1153                             pSWP[i].cy   = vRectl.yTop - vRectl.yBottom - nHeight;
1154                         }
1155                         pSWP[i].fl   = SWP_SIZE | SWP_MOVE | SWP_SHOW;
1156                         pSWP[i].hwndInsertBehind = HWND_TOP;
1157                     }
1158                 }
1159                 bProcessed = true;
1160                 rc = MRFROMSHORT(nItemCount);
1161             }
1162             break;
1163
1164        default:
1165             if(pWnd && pWnd->m_fnOldWndProc)
1166                 rc = pWnd->m_fnOldWndProc(hWnd, ulMsg, wParam, lParam);
1167             else
1168                 rc = ::WinDefWindowProc(hWnd, ulMsg, wParam, lParam);
1169     }
1170     return rc;
1171 } // end of wxFrameMainWndProc
1172
1173 MRESULT EXPENTRY wxFrameWndProc(
1174   HWND                              hWnd
1175 , ULONG                             ulMsg
1176 , MPARAM                            wParam
1177 , MPARAM                            lParam
1178 )
1179 {
1180     //
1181     // Trace all ulMsgs - useful for the debugging
1182     //
1183     HWND                            parentHwnd;
1184     wxFrame*                        pWnd  = NULL;
1185
1186     parentHwnd  = WinQueryWindow(hWnd,QW_PARENT);
1187     pWnd = (wxFrame*) wxFindWinFromHandle((WXHWND) hWnd);
1188
1189     //
1190     // When we get the first message for the HWND we just created, we associate
1191     // it with wxWindow stored in wxWndHook
1192     //
1193
1194     MRESULT                         rc = (MRESULT)0;
1195
1196     //
1197     // Stop right here if we don't have a valid handle in our wxWindow object.
1198     //
1199     if (pWnd && !pWnd->GetHWND())
1200     {
1201         pWnd->SetHWND((WXHWND) hWnd);
1202         rc = pWnd->OS2DefWindowProc(ulMsg, wParam, lParam );
1203         pWnd->SetHWND(0);
1204     }
1205     else
1206     {
1207         if (pWnd)
1208             rc = pWnd->OS2WindowProc(ulMsg, wParam, lParam);
1209         else
1210             rc = ::WinDefWindowProc(hWnd, ulMsg, wParam, lParam);
1211     }
1212     return rc;
1213 } // end of wxFrameWndProc
1214
1215 MRESULT wxFrame::OS2WindowProc( WXUINT uMessage,
1216                                 WXWPARAM wParam,
1217                                 WXLPARAM lParam )
1218 {
1219     MRESULT mRc = 0L;
1220     bool    bProcessed = false;
1221
1222     switch (uMessage)
1223     {
1224         case WM_CLOSE:
1225             //
1226             // If we can't close, tell the system that we processed the
1227             // message - otherwise it would close us
1228             //
1229             bProcessed = !Close();
1230             break;
1231
1232         case WM_PAINT:
1233             bProcessed = HandlePaint();
1234             mRc = (MRESULT)FALSE;
1235             break;
1236
1237          case WM_ERASEBACKGROUND:
1238             //
1239             // Returning TRUE to requests PM to paint the window background
1240             // in SYSCLR_WINDOW. We capture this here because the PS returned
1241             // in Frames is the PS for the whole frame, which we can't really
1242             // use at all. If you want to paint a different background, do it
1243             // in an OnPaint using a wxPaintDC.
1244             //
1245             mRc = (MRESULT)(TRUE);
1246             break;
1247
1248       case WM_COMMAND:
1249             {
1250                 WORD                wId;
1251                 WORD                wCmd;
1252                 WXHWND              hWnd;
1253
1254                 UnpackCommand( (WXWPARAM)wParam
1255                               ,(WXLPARAM)lParam
1256                               ,&wId
1257                               ,&hWnd
1258                               ,&wCmd
1259                              );
1260
1261                 bProcessed = HandleCommand( wId
1262                                            ,wCmd
1263                                            ,(WXHWND)hWnd
1264                                           );
1265             }
1266             break;
1267
1268         case WM_MENUSELECT:
1269             {
1270                 WXWORD              wItem;
1271                 WXWORD              wFlags;
1272                 WXHMENU             hMenu;
1273
1274                 UnpackMenuSelect( wParam
1275                                  ,lParam
1276                                  ,&wItem
1277                                  ,&wFlags
1278                                  ,&hMenu
1279                                 );
1280                 bProcessed = HandleMenuSelect( wItem
1281                                               ,wFlags
1282                                               ,hMenu
1283                                              );
1284                 mRc = (MRESULT)TRUE;
1285             }
1286             break;
1287
1288         case WM_SIZE:
1289             {
1290                 SHORT               nScxnew = SHORT1FROMMP(lParam); // New horizontal size.
1291                 SHORT               nScynew = SHORT2FROMMP(lParam); // New vertical size.
1292
1293                 lParam = MRFROM2SHORT( nScxnew - 20
1294                                       ,nScynew - 30
1295                                      );
1296             }
1297             bProcessed = HandleSize(LOWORD(lParam), HIWORD(lParam), (WXUINT)wParam);
1298             mRc = (MRESULT)FALSE;
1299             break;
1300
1301         case CM_QUERYDRAGIMAGE:
1302             {
1303                 const wxIcon&           vIcon = GetIcon();
1304                 HPOINTER                hIcon;
1305
1306                 if (vIcon.Ok())
1307                     hIcon = (HPOINTER)::WinSendMsg(GetHWND(), WM_QUERYICON, 0L, 0L);
1308                 else
1309                     hIcon = (HPOINTER)m_hDefaultIcon;
1310                 mRc = (MRESULT)hIcon;
1311                 bProcessed = mRc != 0;
1312             }
1313             break;
1314     }
1315
1316     if (!bProcessed )
1317         mRc = wxWindow::OS2WindowProc( uMessage
1318                                       ,wParam
1319                                       ,lParam
1320                                      );
1321     return (MRESULT)mRc;
1322 } // wxFrame::OS2WindowProc
1323
1324 void wxFrame::SetClient(WXHWND WXUNUSED(c_Hwnd))
1325 {
1326    // Duh...nothing to do under OS/2
1327 }
1328
1329 void wxFrame::SetClient( wxWindow* pWindow )
1330 {
1331     wxWindow* pOldClient      = this->GetClient();
1332     bool      bClientHasFocus = pOldClient && (pOldClient == wxWindow::FindFocus());
1333
1334     if(pOldClient == pWindow)  // nothing to do
1335         return;
1336     if(pWindow == NULL) // just need to remove old client
1337     {
1338         if(pOldClient == NULL) // nothing to do
1339             return;
1340
1341         if(bClientHasFocus )
1342             this->SetFocus();
1343
1344         pOldClient->Enable( false );
1345         pOldClient->Show( false );
1346         ::WinSetWindowUShort(pOldClient->GetHWND(), QWS_ID, (USHORT)pOldClient->GetId());
1347         // to avoid OS/2 bug need to update frame
1348         ::WinSendMsg((HWND)this->GetFrame(), WM_UPDATEFRAME, (MPARAM)~0, 0);
1349         return;
1350     }
1351
1352     //
1353     // Else need to change client
1354     //
1355     if(bClientHasFocus)
1356          this->SetFocus();
1357
1358     ::WinEnableWindowUpdate((HWND)GetHWND(), FALSE);
1359     if(pOldClient)
1360     {
1361         pOldClient->Enable(false);
1362         pOldClient->Show(false);
1363         ::WinSetWindowUShort(pOldClient->GetHWND(), QWS_ID, (USHORT)pOldClient->GetId());
1364     }
1365     pWindow->Reparent(this);
1366     ::WinSetWindowUShort(pWindow->GetHWND(), QWS_ID, FID_CLIENT);
1367     ::WinEnableWindowUpdate((HWND)GetHWND(), TRUE);
1368     pWindow->Enable();
1369     pWindow->Show();   // ensure client is showing
1370     if( this->IsShown() )
1371     {
1372         this->Show();
1373         ::WinSendMsg(m_hFrame, WM_UPDATEFRAME, (MPARAM)~0, 0);
1374     }
1375 }
1376
1377 wxWindow* wxFrame::GetClient()
1378 {
1379     return wxFindWinFromHandle((WXHWND)::WinWindowFromID(m_hFrame, FID_CLIENT));
1380 }
1381
1382 void wxFrame::SendSizeEvent()
1383 {
1384     if (!m_bIconized)
1385     {
1386         RECTL                       vRect = wxGetWindowRect(GetHwnd());
1387
1388         ::WinPostMsg( GetHwnd()
1389                      ,WM_SIZE
1390                      ,MPFROM2SHORT( vRect.xRight - vRect.xLeft
1391                                    ,vRect.xRight - vRect.xLeft
1392                                   )
1393                      ,MPFROM2SHORT( vRect.yTop - vRect.yBottom
1394                                    ,vRect.yTop - vRect.yBottom
1395                                   )
1396                     );
1397     }
1398 }