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