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