Implementing some more controls and an MDI child frame fix for wxFrame.
[wxWidgets.git] / src / os2 / frame.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: frame.cpp
3 // Purpose: wxFrame
4 // Author: David Webster
5 // Modified by:
6 // Created: 10/27/99
7 // RCS-ID: $Id$
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #ifndef WX_PRECOMP
16 #include "wx/defs.h"
17 #include "wx/object.h"
18 #include "wx/dynarray.h"
19 #include "wx/list.h"
20 #include "wx/hash.h"
21 #include "wx/string.h"
22 #include "wx/intl.h"
23 #include "wx/log.h"
24 #include "wx/event.h"
25 #include "wx/setup.h"
26 #include "wx/frame.h"
27 #include "wx/menu.h"
28 #include "wx/app.h"
29 #include "wx/utils.h"
30 #include "wx/dialog.h"
31 #include "wx/settings.h"
32 #include "wx/dcclient.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 #if wxUSE_TOOLBAR
43 #include "wx/toolbar.h"
44 #endif // wxUSE_TOOLBAR
45
46 #include "wx/menuitem.h"
47 #include "wx/log.h"
48
49 // ----------------------------------------------------------------------------
50 // globals
51 // ----------------------------------------------------------------------------
52
53 extern wxWindowList wxModelessWindows;
54 extern wxList WXDLLEXPORT wxPendingDelete;
55 extern wxChar wxFrameClassName[];
56
57 #if wxUSE_MENUS_NATIVE
58 extern wxMenu *wxCurrentPopupMenu;
59 #endif
60
61 extern void wxAssociateWinWithHandle( HWND hWnd
62 ,wxWindowOS2* pWin
63 );
64
65 // ----------------------------------------------------------------------------
66 // event tables
67 // ----------------------------------------------------------------------------
68
69 BEGIN_EVENT_TABLE(wxFrame, wxFrameBase)
70 EVT_ACTIVATE(wxFrame::OnActivate)
71 EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged)
72 END_EVENT_TABLE()
73
74 IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxWindow)
75
76 // ============================================================================
77 // implementation
78 // ============================================================================
79
80 // ----------------------------------------------------------------------------
81 // static class members
82 // ----------------------------------------------------------------------------
83 #if wxUSE_STATUSBAR
84
85 #if wxUSE_NATIVE_STATUSBAR
86 bool wxFrame::m_bUseNativeStatusBar = TRUE;
87 #else
88 bool wxFrame::m_bUseNativeStatusBar = FALSE;
89 #endif
90
91 #endif //wxUSE_STATUSBAR
92
93 // ----------------------------------------------------------------------------
94 // creation/destruction
95 // ----------------------------------------------------------------------------
96
97 void wxFrame::Init()
98 {
99 m_bIconized = FALSE;
100
101 #if wxUSE_TOOLTIPS
102 m_hWndToolTip = 0;
103 #endif
104 // Data to save/restore when calling ShowFullScreen
105 m_lFsStyle = 0L;
106 m_lFsOldWindowStyle = 0L;
107 m_nFsStatusBarFields = 0;
108 m_nFsStatusBarHeight = 0;
109 m_nFsToolBarHeight = 0;
110 m_bFsIsMaximized = FALSE;
111 m_bWasMinimized = FALSE;
112 m_bFsIsShowing = FALSE;
113 m_bIsShown = FALSE;
114 m_pWinLastFocused = (wxWindow *)NULL;
115
116 m_hFrame = NULL;
117 m_hTitleBar = NULL;
118 m_hHScroll = NULL;
119 m_hVScroll = NULL;
120
121 //
122 // Initialize SWP's
123 //
124 memset(&m_vSwp, 0, sizeof(SWP));
125 memset(&m_vSwpClient, 0, sizeof(SWP));
126 memset(&m_vSwpTitleBar, 0, sizeof(SWP));
127 memset(&m_vSwpMenuBar, 0, sizeof(SWP));
128 memset(&m_vSwpHScroll, 0, sizeof(SWP));
129 memset(&m_vSwpVScroll, 0, sizeof(SWP));
130 memset(&m_vSwpStatusBar, 0, sizeof(SWP));
131 memset(&m_vSwpToolBar, 0, sizeof(SWP));
132 } // end of wxFrame::Init
133
134 bool wxFrame::Create(
135 wxWindow* pParent
136 , wxWindowID vId
137 , const wxString& rsTitle
138 , const wxPoint& rPos
139 , const wxSize& rSize
140 , long lulStyle
141 , const wxString& rsName
142 )
143 {
144 int nX = rPos.x;
145 int nY = rPos.y;
146 int nWidth = rSize.x;
147 int nHeight = rSize.y;
148 bool bOk = FALSE;
149
150 SetName(rsName);
151 m_windowStyle = lulStyle;
152 m_frameMenuBar = NULL;
153 #if wxUSE_TOOLBAR
154 m_frameToolBar = NULL;
155 #endif //wxUSE_TOOLBAR
156
157 #if wxUSE_STATUSBAR
158 m_frameStatusBar = NULL;
159 #endif //wxUSE_STATUSBAR
160
161 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE));
162
163 if (vId > -1 )
164 m_windowId = vId;
165 else
166 m_windowId = (int)NewControlId();
167
168 if (pParent)
169 pParent->AddChild(this);
170
171 m_bIconized = FALSE;
172
173 if ((m_windowStyle & wxFRAME_FLOAT_ON_PARENT) == 0)
174 pParent = NULL;
175
176 bOk = OS2Create( m_windowId
177 ,pParent
178 ,wxFrameClassName
179 ,this
180 ,rsTitle
181 ,nX
182 ,nY
183 ,nWidth
184 ,nHeight
185 ,lulStyle
186 );
187 if (bOk)
188 {
189 if (!pParent)
190 wxTopLevelWindows.Append(this);
191 wxModelessWindows.Append(this);
192 }
193 return(bOk);
194 } // end of wxFrame::Create
195
196 wxFrame::~wxFrame()
197 {
198 m_isBeingDeleted = TRUE;
199
200 wxTopLevelWindows.DeleteObject(this);
201
202 DeleteAllBars();
203
204 if (wxTheApp && (wxTopLevelWindows.Number() == 0))
205 {
206 wxTheApp->SetTopWindow(NULL);
207
208 if (wxTheApp->GetExitOnFrameDelete())
209 {
210 ::WinPostMsg(NULL, WM_QUIT, 0, 0);
211 }
212 }
213
214 wxModelessWindows.DeleteObject(this);
215
216 //
217 // For some reason, wxWindows can activate another task altogether
218 // when a frame is destroyed after a modal dialog has been invoked.
219 // Try to bring the parent to the top.
220 //
221 // MT:Only do this if this frame is currently the active window, else weird
222 // things start to happen.
223 //
224 if (wxGetActiveWindow() == this)
225 {
226 if (GetParent() && GetParent()->GetHWND())
227 {
228 ::WinSetWindowPos( (HWND) GetParent()->GetHWND()
229 ,HWND_TOP
230 ,0
231 ,0
232 ,0
233 ,0
234 ,SWP_ZORDER
235 );
236 }
237 }
238 } // end of wxFrame::~wxFrame
239
240 //
241 // IF we have child controls in the Frame's client we need to alter
242 // the y position, because, OS/2 controls are positioned relative to
243 // wxWindows orgin (top left) not the OS/2 origin (bottom left)
244 void wxFrame::AlterChildPos()
245 {
246 //
247 // OS/2 is the only OS concerned about this
248 //
249 wxWindow* pChild = NULL;
250 wxControl* pCtrl = NULL;
251 RECTL vRect;
252 SWP vSwp;
253
254 ::WinQueryWindowRect(GetHwnd(), &vRect);
255 for (wxWindowList::Node* pNode = GetChildren().GetFirst();
256 pNode;
257 pNode = pNode->GetNext())
258 {
259 wxWindow* pChild = pNode->GetData();
260
261 ::WinQueryWindowPos(pChild->GetHWND(), &vSwp);
262 vSwp.y += (vRect.yTop - m_vSwpClient.cy);
263 if (pChild->IsKindOf(CLASSINFO(wxControl)))
264 {
265 pCtrl = wxDynamicCast(pChild, wxControl);
266 //
267 // Must deal with controls that have margins like ENTRYFIELD. The SWP
268 // struct of such a control will have and origin offset from its intended
269 // position by the width of the margins.
270 //
271 vSwp.y -= pCtrl->GetYComp();
272 vSwp.x -= pCtrl->GetXComp();
273 }
274 ::WinSetWindowPos( pChild->GetHWND()
275 ,HWND_TOP
276 ,vSwp.x
277 ,vSwp.y
278 ,vSwp.cx
279 ,vSwp.cy
280 ,SWP_MOVE
281 );
282 ::WinQueryWindowPos(pChild->GetHWND(), &vSwp);
283 pChild = NULL;
284 }
285 } // end of wxFrame::AlterChildPos
286
287 //
288 // Get size *available for subwindows* i.e. excluding menu bar, toolbar etc.
289 //
290 void wxFrame::DoGetClientSize(
291 int* pX
292 , int* pY
293 ) const
294 {
295 RECTL vRect;
296 ::WinQueryWindowRect(GetHwnd(), &vRect);
297
298 //
299 // No need to use statusbar code as in WIN32 as the FORMATFRAME
300 // window procedure ensures PM knows about the new frame client
301 // size internally. A ::WinQueryWindowRect is all that is needed!
302 //
303
304 if (pX)
305 *pX = vRect.xRight - vRect.xLeft;
306 if (pY)
307 *pY = vRect.yTop - vRect.yBottom;
308 } // end of wxFrame::DoGetClientSize
309
310 //
311 // Set the client size (i.e. leave the calculation of borders etc.
312 // to wxWindows)
313 //
314 void wxFrame::DoSetClientSize(
315 int nWidth
316 , int nHeight
317 )
318 {
319 HWND hWnd = GetHwnd();
320 RECTL vRect;
321 RECTL vRect2;
322
323 ::WinQueryWindowRect(GetHwnd(), &vRect);
324 ::WinQueryWindowRect(GetHwnd(), &vRect2);
325
326 //
327 // Find the difference between the entire window (title bar and all)
328 // and the client area; add this to the new client size to move the
329 // window. Remember OS/2's backwards y coord system!
330 //
331 int nActualWidth = vRect2.xRight - vRect2.xLeft - vRect.xRight;
332 int nActualHeight = vRect2.yTop + vRect2.yTop - vRect.yTop;
333
334 #if wxUSE_STATUSBAR
335 wxStatusBar* pStatusBar = GetStatusBar();
336
337 if (pStatusBar && pStatusBar->IsShown())
338 {
339 nActualHeight += pStatusBar->GetSize().y;
340 }
341
342 #endif // wxUSE_STATUSBAR
343
344 wxPoint vPoint(GetClientAreaOrigin());
345
346 nActualWidth += vPoint.x;
347 nActualHeight += vPoint.y;
348
349 POINTL vPointl;
350
351 vPointl.x = vRect2.xLeft;
352 vPointl.y = vRect2.yTop;
353
354 ::WinSetWindowPos( hWnd
355 ,HWND_TOP
356 ,vPointl.x
357 ,vPointl.y
358 ,nActualWidth
359 ,nActualHeight
360 ,SWP_MOVE | SWP_SIZE | SWP_SHOW
361 );
362
363 wxSizeEvent vEvent( wxSize( nWidth
364 ,nHeight
365 )
366 ,m_windowId
367 );
368 vEvent.SetEventObject(this);
369 GetEventHandler()->ProcessEvent(vEvent);
370 } // end of wxFrame::DoSetClientSize
371
372 void wxFrame::DoGetSize(
373 int* pWidth
374 , int* pHeight
375 ) const
376 {
377 RECTL vRect;
378
379 ::WinQueryWindowRect(m_hFrame, &vRect);
380 *pWidth = vRect.xRight - vRect.xLeft;
381 *pHeight = vRect.yTop - vRect.yBottom;
382 } // end of wxFrame::DoGetSize
383
384 void wxFrame::DoGetPosition(
385 int* pX
386 , int* pY
387 ) const
388 {
389 RECTL vRect;
390 POINTL vPoint;
391
392 ::WinQueryWindowRect(m_hFrame, &vRect);
393
394 *pX = vRect.xRight - vRect.xLeft;
395 *pY = vRect.yTop - vRect.yBottom;
396 } // end of wxFrame::DoGetPosition
397
398 // ----------------------------------------------------------------------------
399 // variations around ::ShowWindow()
400 // ----------------------------------------------------------------------------
401
402 void wxFrame::DoShowWindow(
403 int bShowCmd
404 )
405 {
406 ::WinShowWindow(m_hFrame, (BOOL)bShowCmd);
407 m_bIconized = bShowCmd == SWP_MINIMIZE;
408 } // end of wxFrame::DoShowWindow
409
410 bool wxFrame::Show(
411 bool bShow
412 )
413 {
414 int nShowCmd;
415 SWP vSwp;
416
417 if (bShow)
418 {
419 nShowCmd = SWP_SHOW;
420 }
421 else // hide
422 {
423 nShowCmd = SWP_HIDE;
424 }
425
426 DoShowWindow(nShowCmd);
427
428 if (bShow)
429 {
430 wxActivateEvent vEvent(wxEVT_ACTIVATE, TRUE, m_windowId);
431
432 ::WinQueryWindowPos(m_hFrame, &vSwp);
433 m_bIconized = vSwp.fl & SWP_MINIMIZE;
434 ::WinQueryWindowPos(m_hWnd, &m_vSwpClient);
435 ::WinSendMsg(m_hFrame, WM_UPDATEFRAME, (MPARAM)~0, 0);
436 ::WinEnableWindow(m_hFrame, TRUE);
437 vEvent.SetEventObject(this);
438 GetEventHandler()->ProcessEvent(vEvent);
439 }
440 else
441 {
442 //
443 // Try to highlight the correct window (the parent)
444 //
445 if (GetParent())
446 {
447 HWND hWndParent = GetHwndOf(GetParent());
448
449 ::WinQueryWindowPos(hWndParent, &vSwp);
450 m_bIconized = vSwp.fl & SWP_MINIMIZE;
451 if (hWndParent)
452 ::WinSetWindowPos( hWndParent
453 ,HWND_TOP
454 ,vSwp.x
455 ,vSwp.y
456 ,vSwp.cx
457 ,vSwp.cy
458 ,SWP_ZORDER | SWP_ACTIVATE | SWP_SHOW | SWP_MOVE
459 );
460 ::WinEnableWindow(hWndParent, TRUE);
461 }
462 }
463 return TRUE;
464 } // end of wxFrame::Show
465
466 void wxFrame::Iconize(
467 bool bIconize
468 )
469 {
470 DoShowWindow(bIconize ? SWP_MINIMIZE : SWP_RESTORE);
471 } // end of wxFrame::Iconize
472
473 void wxFrame::Maximize(
474 bool bMaximize)
475 {
476 DoShowWindow(bMaximize ? SWP_MAXIMIZE : SWP_RESTORE);
477 } // end of wxFrame::Maximize
478
479 void wxFrame::Restore()
480 {
481 DoShowWindow(SWP_RESTORE);
482 } // end of wxFrame::Restore
483
484 bool wxFrame::IsIconized() const
485 {
486 SWP vSwp;
487
488 ::WinQueryWindowPos(m_hFrame, &vSwp);
489
490 if (vSwp.fl & SWP_MINIMIZE)
491 ((wxFrame*)this)->m_bIconized = TRUE;
492 else
493 ((wxFrame*)this)->m_bIconized = FALSE;
494 return m_bIconized;
495 } // end of wxFrame::IsIconized
496
497 // Is it maximized?
498 bool wxFrame::IsMaximized() const
499 {
500 SWP vSwp;
501 bool bIconic;
502
503 ::WinQueryWindowPos(m_hFrame, &vSwp);
504 return (vSwp.fl & SWP_MAXIMIZE);
505 } // end of wxFrame::IsMaximized
506
507 void wxFrame::SetIcon(
508 const wxIcon& rIcon
509 )
510 {
511 wxFrameBase::SetIcon(rIcon);
512
513 if ((m_icon.GetHICON()) != NULLHANDLE)
514 {
515 ::WinSendMsg( m_hFrame
516 ,WM_SETICON
517 ,(MPARAM)((HPOINTER)m_icon.GetHICON())
518 ,NULL
519 );
520 ::WinSendMsg( m_hFrame
521 ,WM_UPDATEFRAME
522 ,(MPARAM)FCF_ICON
523 ,(MPARAM)0
524 );
525 }
526 } // end of wxFrame::SetIcon
527
528 #if wxUSE_STATUSBAR
529 wxStatusBar* wxFrame::OnCreateStatusBar(
530 int nNumber
531 , long lulStyle
532 , wxWindowID vId
533 , const wxString& rName
534 )
535 {
536 wxStatusBar* pStatusBar = NULL;
537 SWP vSwp;
538 ERRORID vError;
539 wxString sError;
540
541 pStatusBar = wxFrameBase::OnCreateStatusBar( nNumber
542 ,lulStyle
543 ,vId
544 ,rName
545 );
546
547 if( !pStatusBar )
548 return NULL;
549
550 ::WinSetParent( pStatusBar->GetHWND()
551 ,m_hFrame
552 ,FALSE
553 );
554 ::WinSetOwner( pStatusBar->GetHWND()
555 ,m_hFrame
556 );
557 //
558 // to show statusbar
559 //
560 if(::WinIsWindowShowing(m_hFrame))
561 ::WinSendMsg(m_hFrame, WM_UPDATEFRAME, (MPARAM)~0, 0);
562
563 return pStatusBar;
564 } // end of wxFrame::OnCreateStatusBar
565
566 void wxFrame::PositionStatusBar()
567 {
568 SWP vSwp;
569 ERRORID vError;
570 wxString sError;
571
572 //
573 // Native status bar positions itself
574 //
575 if (m_frameStatusBar)
576 {
577 int nWidth;
578 int nY;
579 int nStatbarWidth;
580 int nStatbarHeight;
581 HWND hWndClient;
582 RECTL vRect;
583 RECTL vFRect;
584
585 ::WinQueryWindowRect(m_hFrame, &vRect);
586 nY = vRect.yTop;
587 ::WinMapWindowPoints(m_hFrame, HWND_DESKTOP, (PPOINTL)&vRect, 2);
588 vFRect = vRect;
589 ::WinCalcFrameRect(m_hFrame, &vRect, TRUE);
590 nWidth = vRect.xRight - vRect.xLeft;
591 nY = nY - (vRect.yBottom - vFRect.yBottom);
592
593 m_frameStatusBar->GetSize( &nStatbarWidth
594 ,&nStatbarHeight
595 );
596
597 nY= nY - nStatbarHeight;
598 //
599 // Since we wish the status bar to be directly under the client area,
600 // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.
601 //
602 m_frameStatusBar->SetSize( vRect.xLeft - vFRect.xLeft
603 ,nY
604 ,nWidth
605 ,nStatbarHeight
606 );
607 if (!::WinQueryWindowPos(m_frameStatusBar->GetHWND(), &vSwp))
608 {
609 vError = ::WinGetLastError(vHabmain);
610 sError = wxPMErrorToStr(vError);
611 wxLogError("Error setting parent for StautsBar. Error: %s\n", sError);
612 return;
613 }
614 }
615 } // end of wxFrame::PositionStatusBar
616 #endif // wxUSE_STATUSBAR
617
618 #if wxUSE_MENUS_NATIVE
619 void wxFrame::DetachMenuBar()
620 {
621 if (m_frameMenuBar)
622 {
623 m_frameMenuBar->Detach();
624 m_frameMenuBar = NULL;
625 }
626 } // end of wxFrame::DetachMenuBar
627
628 void wxFrame::SetMenuBar(
629 wxMenuBar* pMenuBar
630 )
631 {
632 ERRORID vError;
633 wxString sError;
634 HWND hTitlebar = NULLHANDLE;
635 HWND hHScroll = NULLHANDLE;
636 HWND hVScroll = NULLHANDLE;
637 HWND hMenuBar = NULLHANDLE;
638 SWP vSwp;
639 SWP vSwpTitlebar;
640 SWP vSwpVScroll;
641 SWP vSwpHScroll;
642 SWP vSwpMenu;
643
644 if (!pMenuBar)
645 {
646 DetachMenuBar();
647
648 //
649 // Actually remove the menu from the frame
650 //
651 m_hMenu = (WXHMENU)0;
652 InternalSetMenuBar();
653 }
654 else // set new non NULL menu bar
655 {
656 m_frameMenuBar = NULL;
657
658 //
659 // Can set a menubar several times.
660 // TODO: how to prevent a memory leak if you have a currently-unattached
661 // menubar? wxWindows assumes that the frame will delete the menu (otherwise
662 // there are problems for MDI).
663 //
664 if (pMenuBar->GetHMenu())
665 {
666 m_hMenu = pMenuBar->GetHMenu();
667 }
668 else
669 {
670 pMenuBar->Detach();
671 m_hMenu = pMenuBar->Create();
672 if (!m_hMenu)
673 return;
674 }
675 InternalSetMenuBar();
676 m_frameMenuBar = pMenuBar;
677 pMenuBar->Attach((wxFrame*)this);
678 }
679 } // end of wxFrame::SetMenuBar
680
681 void wxFrame::AttachMenuBar(
682 wxMenuBar* pMenubar
683 )
684 {
685 wxFrameBase::AttachMenuBar(pMenubar);
686
687 m_frameMenuBar = pMenubar;
688
689 if (!pMenubar)
690 {
691 //
692 // Actually remove the menu from the frame
693 //
694 m_hMenu = (WXHMENU)0;
695 InternalSetMenuBar();
696 }
697 else // Set new non NULL menu bar
698 {
699 //
700 // Can set a menubar several times.
701 //
702 if (pMenubar->GetHMenu())
703 {
704 m_hMenu = pMenubar->GetHMenu();
705 }
706 else
707 {
708 if (pMenubar->IsAttached())
709 pMenubar->Detach();
710
711 m_hMenu = pMenubar->Create();
712
713 if (!m_hMenu)
714 return;
715 }
716 InternalSetMenuBar();
717 }
718 } // end of wxFrame::AttachMenuBar
719
720 void wxFrame::InternalSetMenuBar()
721 {
722 ERRORID vError;
723 wxString sError;
724 //
725 // Set the parent and owner of the menubar to be the frame
726 //
727 if (!::WinSetParent(m_hMenu, m_hFrame, FALSE))
728 {
729 vError = ::WinGetLastError(vHabmain);
730 sError = wxPMErrorToStr(vError);
731 wxLogError("Error setting parent for submenu. Error: %s\n", sError);
732 }
733
734 if (!::WinSetOwner(m_hMenu, m_hFrame))
735 {
736 vError = ::WinGetLastError(vHabmain);
737 sError = wxPMErrorToStr(vError);
738 wxLogError("Error setting parent for submenu. Error: %s\n", sError);
739 }
740 ::WinSendMsg(m_hFrame, WM_UPDATEFRAME, (MPARAM)FCF_MENU, (MPARAM)0);
741 } // end of wxFrame::InternalSetMenuBar
742 #endif // wxUSE_MENUS_NATIVE
743
744 //
745 // Responds to colour changes, and passes event on to children
746 //
747 void wxFrame::OnSysColourChanged(
748 wxSysColourChangedEvent& rEvent
749 )
750 {
751 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE));
752 Refresh();
753
754 #if wxUSE_STATUSBAR
755 if (m_frameStatusBar)
756 {
757 wxSysColourChangedEvent vEvent2;
758
759 vEvent2.SetEventObject(m_frameStatusBar);
760 m_frameStatusBar->GetEventHandler()->ProcessEvent(vEvent2);
761 }
762 #endif //wxUSE_STATUSBAR
763
764 //
765 // Propagate the event to the non-top-level children
766 //
767 wxWindow::OnSysColourChanged(rEvent);
768 } // end of wxFrame::OnSysColourChanged
769
770 // Pass TRUE to show full screen, FALSE to restore.
771 bool wxFrame::ShowFullScreen(
772 bool bShow
773 , long lStyle
774 )
775 {
776 if (bShow)
777 {
778 if (IsFullScreen())
779 return FALSE;
780
781 m_bFsIsShowing = TRUE;
782 m_lFsStyle = lStyle;
783
784 #if wxUSE_TOOLBAR
785 wxToolBar* pTheToolBar = GetToolBar();
786 #endif //wxUSE_TOOLBAR
787
788 #if wxUSE_STATUSBAR
789 wxStatusBar* pTheStatusBar = GetStatusBar();
790 #endif //wxUSE_STATUSBAR
791
792 int nDummyWidth;
793
794 #if wxUSE_TOOLBAR
795 if (pTheToolBar)
796 pTheToolBar->GetSize(&nDummyWidth, &m_nFsToolBarHeight);
797 #endif //wxUSE_TOOLBAR
798
799 #if wxUSE_STATUSBAR
800 if (pTheStatusBar)
801 pTheStatusBar->GetSize(&nDummyWidth, &m_nFsStatusBarHeight);
802 #endif //wxUSE_STATUSBAR
803
804 #if wxUSE_TOOLBAR
805 //
806 // Zap the toolbar, menubar, and statusbar
807 //
808 if ((lStyle & wxFULLSCREEN_NOTOOLBAR) && pTheToolBar)
809 {
810 pTheToolBar->SetSize(-1,0);
811 pTheToolBar->Show(FALSE);
812 }
813 #endif //wxUSE_TOOLBAR
814
815 if (lStyle & wxFULLSCREEN_NOMENUBAR)
816 {
817 ::WinSetParent(m_hMenu, m_hFrame, FALSE);
818 ::WinSetOwner(m_hMenu, m_hFrame);
819 ::WinSendMsg((HWND)m_hFrame, WM_UPDATEFRAME, (MPARAM)FCF_MENU, (MPARAM)0);
820 }
821
822 #if wxUSE_STATUSBAR
823 //
824 // Save the number of fields in the statusbar
825 //
826 if ((lStyle & wxFULLSCREEN_NOSTATUSBAR) && pTheStatusBar)
827 {
828 m_nFsStatusBarFields = pTheStatusBar->GetFieldsCount();
829 SetStatusBar((wxStatusBar*) NULL);
830 delete pTheStatusBar;
831 }
832 else
833 m_nFsStatusBarFields = 0;
834 #endif //wxUSE_STATUSBAR
835
836 //
837 // Zap the frame borders
838 //
839
840 //
841 // Save the 'normal' window style
842 //
843 m_lFsOldWindowStyle = ::WinQueryWindowULong(m_hFrame, QWL_STYLE);
844
845 //
846 // Save the old position, width & height, maximize state
847 //
848 m_vFsOldSize = GetRect();
849 m_bFsIsMaximized = IsMaximized();
850
851 //
852 // Decide which window style flags to turn off
853 //
854 LONG lNewStyle = m_lFsOldWindowStyle;
855 LONG lOffFlags = 0;
856
857 if (lStyle & wxFULLSCREEN_NOBORDER)
858 lOffFlags |= FCF_BORDER;
859 if (lStyle & wxFULLSCREEN_NOCAPTION)
860 lOffFlags |= (FCF_TASKLIST | FCF_SYSMENU);
861
862 lNewStyle &= (~lOffFlags);
863
864 //
865 // Change our window style to be compatible with full-screen mode
866 //
867 ::WinSetWindowULong((HWND)m_hFrame, QWL_STYLE, (ULONG)lNewStyle);
868
869 //
870 // Resize to the size of the desktop
871 int nWidth;
872 int nHeight;
873
874 RECTL vRect;
875
876 ::WinQueryWindowRect(HWND_DESKTOP, &vRect);
877 nWidth = vRect.xRight - vRect.xLeft;
878 //
879 // Rmember OS/2 is backwards!
880 //
881 nHeight = vRect.yTop - vRect.yBottom;
882
883 SetSize( nWidth
884 ,nHeight
885 );
886
887 //
888 // Now flush the window style cache and actually go full-screen
889 //
890 ::WinSetWindowPos( (HWND) GetParent()->GetHWND()
891 ,HWND_TOP
892 ,0
893 ,0
894 ,nWidth
895 ,nHeight
896 ,SWP_SIZE | SWP_SHOW
897 );
898
899 wxSizeEvent vEvent( wxSize( nWidth
900 ,nHeight
901 )
902 ,GetId()
903 );
904
905 GetEventHandler()->ProcessEvent(vEvent);
906 return TRUE;
907 }
908 else
909 {
910 if (!IsFullScreen())
911 return FALSE;
912
913 m_bFsIsShowing = FALSE;
914
915 #if wxUSE_TOOLBAR
916 wxToolBar* pTheToolBar = GetToolBar();
917
918 //
919 // Restore the toolbar, menubar, and statusbar
920 //
921 if (pTheToolBar && (m_lFsStyle & wxFULLSCREEN_NOTOOLBAR))
922 {
923 pTheToolBar->SetSize(-1, m_nFsToolBarHeight);
924 pTheToolBar->Show(TRUE);
925 }
926 #endif //wxUSE_TOOLBAR
927
928 #if wxUSE_STATUSBAR
929 if ((m_lFsStyle & wxFULLSCREEN_NOSTATUSBAR) && (m_nFsStatusBarFields > 0))
930 {
931 CreateStatusBar(m_nFsStatusBarFields);
932 // PositionStatusBar();
933 }
934 #endif //wxUSE_STATUSBAR
935
936 if ((m_lFsStyle & wxFULLSCREEN_NOMENUBAR) && (m_hMenu != 0))
937 {
938 ::WinSetParent(m_hMenu, m_hFrame, FALSE);
939 ::WinSetOwner(m_hMenu, m_hFrame);
940 ::WinSendMsg(m_hFrame, WM_UPDATEFRAME, (MPARAM)FCF_MENU, (MPARAM)0);
941 }
942 Maximize(m_bFsIsMaximized);
943
944 ::WinSetWindowULong( m_hFrame
945 ,QWL_STYLE
946 ,(ULONG)m_lFsOldWindowStyle
947 );
948 ::WinSetWindowPos( (HWND) GetParent()->GetHWND()
949 ,HWND_TOP
950 ,m_vFsOldSize.x
951 ,m_vFsOldSize.y
952 ,m_vFsOldSize.width
953 ,m_vFsOldSize.height
954 ,SWP_SIZE | SWP_SHOW
955 );
956 return TRUE;
957 }
958 } // end of wxFrame::ShowFullScreen
959
960 //
961 // Frame window
962 //
963 bool wxFrame::OS2Create(
964 int nId
965 , wxWindow* pParent
966 , const wxChar* zWclass
967 , wxWindow* pWxWin
968 , const wxChar* zTitle
969 , int nX
970 , int nY
971 , int nWidth
972 , int nHeight
973 , long ulStyle
974 )
975 {
976 ULONG ulCreateFlags = 0L;
977 ULONG ulStyleFlags = 0L;
978 ULONG ulExtraFlags = 0L;
979 FRAMECDATA vFrameCtlData;
980 HWND hParent = NULLHANDLE;
981 HWND hTitlebar = NULLHANDLE;
982 HWND hHScroll = NULLHANDLE;
983 HWND hVScroll = NULLHANDLE;
984 HWND hFrame = NULLHANDLE;
985 HWND hClient = NULLHANDLE;
986 SWP vSwp[10];
987 RECTL vRect[10];
988 USHORT uCtlCount;
989 ERRORID vError;
990 wxString sError;
991
992 m_hDefaultIcon = (WXHICON) (wxSTD_FRAME_ICON ? wxSTD_FRAME_ICON : wxDEFAULT_FRAME_ICON);
993
994 if (pParent)
995 hParent = GetWinHwnd(pParent);
996 else
997 hParent = HWND_DESKTOP;
998
999 if (ulStyle == wxDEFAULT_FRAME_STYLE)
1000 ulCreateFlags = FCF_SIZEBORDER | FCF_TITLEBAR | FCF_SYSMENU |
1001 FCF_MINMAX | FCF_TASKLIST;
1002 else
1003 {
1004 if ((ulStyle & wxCAPTION) == wxCAPTION)
1005 ulCreateFlags = FCF_TASKLIST;
1006 else
1007 ulCreateFlags = FCF_NOMOVEWITHOWNER;
1008
1009 if ((ulStyle & wxVSCROLL) == wxVSCROLL)
1010 ulCreateFlags |= FCF_VERTSCROLL;
1011 if ((ulStyle & wxHSCROLL) == wxHSCROLL)
1012 ulCreateFlags |= FCF_HORZSCROLL;
1013 if (ulStyle & wxMINIMIZE_BOX)
1014 ulCreateFlags |= FCF_MINBUTTON;
1015 if (ulStyle & wxMAXIMIZE_BOX)
1016 ulCreateFlags |= FCF_MAXBUTTON;
1017 if (ulStyle & wxTHICK_FRAME)
1018 ulCreateFlags |= FCF_DLGBORDER;
1019 if (ulStyle & wxSYSTEM_MENU)
1020 ulCreateFlags |= FCF_SYSMENU;
1021 if (ulStyle & wxCAPTION)
1022 ulCreateFlags |= FCF_TASKLIST;
1023 if (ulStyle & wxCLIP_CHILDREN)
1024 {
1025 // Invalid for frame windows under PM
1026 }
1027
1028 if (ulStyle & wxTINY_CAPTION_VERT)
1029 ulCreateFlags |= FCF_TASKLIST;
1030 if (ulStyle & wxTINY_CAPTION_HORIZ)
1031 ulCreateFlags |= FCF_TASKLIST;
1032
1033 if ((ulStyle & wxTHICK_FRAME) == 0)
1034 ulCreateFlags |= FCF_BORDER;
1035 if (ulStyle & wxFRAME_TOOL_WINDOW)
1036 ulExtraFlags = kFrameToolWindow;
1037
1038 if (ulStyle & wxSTAY_ON_TOP)
1039 ulCreateFlags |= FCF_SYSMODAL;
1040 }
1041 if ((ulStyle & wxMINIMIZE) || (ulStyle & wxICONIZE))
1042 ulStyleFlags |= WS_MINIMIZED;
1043 if (ulStyle & wxMAXIMIZE)
1044 ulStyleFlags |= WS_MAXIMIZED;
1045
1046 //
1047 // Clear the visible flag, we always call show
1048 //
1049 ulStyleFlags &= (unsigned long)~WS_VISIBLE;
1050 m_bIconized = FALSE;
1051
1052 //
1053 // Set the frame control block
1054 //
1055 vFrameCtlData.cb = sizeof(vFrameCtlData);
1056 vFrameCtlData.flCreateFlags = ulCreateFlags;
1057 vFrameCtlData.hmodResources = 0L;
1058 vFrameCtlData.idResources = 0;
1059
1060 //
1061 // Create the frame window: We break ranks with other ports now
1062 // and instead of calling down into the base wxWindow class' OS2Create
1063 // we do all our own stuff here. We will set the needed pieces
1064 // of wxWindow manually, here.
1065 //
1066
1067 hFrame = ::WinCreateStdWindow( hParent
1068 ,ulStyleFlags // frame-window style
1069 ,&ulCreateFlags // window style
1070 ,(PSZ)zWclass // class name
1071 ,(PSZ)zTitle // window title
1072 ,0L // default client style
1073 ,NULLHANDLE // resource in executable file
1074 ,0 // resource id
1075 ,&hClient // receives client window handle
1076 );
1077 if (!hFrame)
1078 {
1079 vError = ::WinGetLastError(vHabmain);
1080 sError = wxPMErrorToStr(vError);
1081 wxLogError("Error creating frame. Error: %s\n", sError);
1082 return FALSE;
1083 }
1084
1085 //
1086 // wxWindow class' m_hWnd set here and needed associations
1087 //
1088 m_hFrame = hFrame;
1089 m_hWnd = hClient;
1090 wxAssociateWinWithHandle(m_hWnd, this);
1091 wxAssociateWinWithHandle(m_hFrame, this);
1092
1093 m_backgroundColour.Set(wxString("GREY"));
1094
1095 LONG lColor = (LONG)m_backgroundColour.GetPixel();
1096
1097 if (!::WinSetPresParam( m_hWnd
1098 ,PP_BACKGROUNDCOLOR
1099 ,sizeof(LONG)
1100 ,(PVOID)&lColor
1101 ))
1102 {
1103 vError = ::WinGetLastError(vHabmain);
1104 sError = wxPMErrorToStr(vError);
1105 wxLogError("Error creating frame. Error: %s\n", sError);
1106 return FALSE;
1107 }
1108
1109 //
1110 // Now need to subclass window. Instead of calling the SubClassWin in wxWindow
1111 // we manually subclass here because we don't want to use the main wxWndProc
1112 // by default
1113 //
1114 m_fnOldWndProc = (WXFARPROC) ::WinSubclassWindow(m_hFrame, (PFNWP)wxFrameMainWndProc);
1115
1116 //
1117 // Now size everything. If adding a menu the client will need to be resized.
1118 //
1119
1120 if (pParent)
1121 {
1122 nY = pParent->GetSize().y - (nY + nHeight);
1123 }
1124 else
1125 {
1126 RECTL vRect;
1127
1128 ::WinQueryWindowRect(HWND_DESKTOP, &vRect);
1129 nY = vRect.yTop - (nY + nHeight);
1130 }
1131 if (!::WinSetWindowPos( m_hFrame
1132 ,HWND_TOP
1133 ,nX
1134 ,nY
1135 ,nWidth
1136 ,nHeight
1137 ,SWP_SIZE | SWP_MOVE | SWP_ACTIVATE | SWP_ZORDER
1138 ))
1139 {
1140 vError = ::WinGetLastError(vHabmain);
1141 sError = wxPMErrorToStr(vError);
1142 wxLogError("Error sizing frame. Error: %s\n", sError);
1143 return FALSE;
1144 }
1145 return TRUE;
1146 } // end of wxFrame::OS2Create
1147
1148 //
1149 // Default activation behaviour - set the focus for the first child
1150 // subwindow found.
1151 //
1152 void wxFrame::OnActivate(
1153 wxActivateEvent& rEvent
1154 )
1155 {
1156 if ( rEvent.GetActive() )
1157 {
1158 // restore focus to the child which was last focused
1159 wxLogTrace(_T("focus"), _T("wxFrame %08x activated."), m_hWnd);
1160
1161 wxWindow* pParent = m_pWinLastFocused ? m_pWinLastFocused->GetParent()
1162 : NULL;
1163 if (!pParent)
1164 {
1165 pParent = this;
1166 }
1167
1168 wxSetFocusToChild( pParent
1169 ,&m_pWinLastFocused
1170 );
1171 }
1172 else // deactivating
1173 {
1174 //
1175 // Remember the last focused child if it is our child
1176 //
1177 m_pWinLastFocused = FindFocus();
1178
1179 for (wxWindowList::Node* pNode = GetChildren().GetFirst();
1180 pNode;
1181 pNode = pNode->GetNext())
1182 {
1183 // FIXME all this is totally bogus - we need to do the same as wxPanel,
1184 // but how to do it without duplicating the code?
1185
1186 // restore focus
1187 wxWindow* pChild = pNode->GetData();
1188
1189 if (!pChild->IsTopLevel()
1190 #if wxUSE_TOOLBAR
1191 && !wxDynamicCast(pChild, wxToolBar)
1192 #endif // wxUSE_TOOLBAR
1193 #if wxUSE_STATUSBAR
1194 && !wxDynamicCast(pChild, wxStatusBar)
1195 #endif // wxUSE_STATUSBAR
1196 )
1197 {
1198 pChild->SetFocus();
1199 return;
1200 }
1201 }
1202 }
1203 } // end of wxFrame::OnActivate
1204
1205 // ----------------------------------------------------------------------------
1206 // wxFrame size management: we exclude the areas taken by menu/status/toolbars
1207 // from the client area, so the client area is what's really available for the
1208 // frame contents
1209 // ----------------------------------------------------------------------------
1210
1211 // Checks if there is a toolbar, and returns the first free client position
1212 wxPoint wxFrame::GetClientAreaOrigin() const
1213 {
1214 wxPoint vPoint(0, 0);
1215
1216 #if wxUSE_TOOLBAR
1217 if (GetToolBar())
1218 {
1219 int nWidth;
1220 int nHeight;
1221
1222 GetToolBar()->GetSize( &nWidth
1223 ,&nHeight
1224 );
1225
1226 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL)
1227 {
1228 vPoint.x += nWidth;
1229 }
1230 else
1231 {
1232 // PM is backwards from windows
1233 vPoint.y += nHeight;
1234 }
1235 }
1236 #endif //wxUSE_TOOLBAR
1237 return vPoint;
1238 } // end of wxFrame::GetClientAreaOrigin
1239
1240 // ----------------------------------------------------------------------------
1241 // tool/status bar stuff
1242 // ----------------------------------------------------------------------------
1243
1244 #if wxUSE_TOOLBAR
1245
1246 wxToolBar* wxFrame::CreateToolBar(
1247 long lStyle
1248 , wxWindowID vId
1249 , const wxString& rName
1250 )
1251 {
1252 if (wxFrameBase::CreateToolBar( lStyle
1253 ,vId
1254 ,rName
1255 ))
1256 {
1257 PositionToolBar();
1258 }
1259 return m_frameToolBar;
1260 } // end of wxFrame::CreateToolBar
1261
1262 void wxFrame::PositionToolBar()
1263 {
1264 HWND hWndClient;
1265 RECTL vRect;
1266
1267 ::WinQueryWindowRect(GetHwnd(), &vRect);
1268
1269 #if wxUSE_STATUSBAR
1270 if (GetStatusBar())
1271 {
1272 int nStatusX;
1273 int nStatusY;
1274
1275 GetStatusBar()->GetClientSize( &nStatusX
1276 ,&nStatusY
1277 );
1278 // PM is backwards from windows
1279 vRect.yBottom += nStatusY;
1280 }
1281 #endif // wxUSE_STATUSBAR
1282
1283 if ( m_frameToolBar )
1284 {
1285 int nToolbarWidth;
1286 int nToolbarHeight;
1287
1288 m_frameToolBar->GetSize( &nToolbarWidth
1289 ,&nToolbarHeight
1290 );
1291
1292 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL)
1293 {
1294 nToolbarHeight = vRect.yBottom;
1295 }
1296 else
1297 {
1298 nToolbarWidth = vRect.xRight;
1299 }
1300
1301 //
1302 // Use the 'real' PM position here
1303 //
1304 GetToolBar()->SetSize( 0
1305 ,0
1306 ,nToolbarWidth
1307 ,nToolbarHeight
1308 ,wxSIZE_NO_ADJUSTMENTS
1309 );
1310 }
1311 } // end of wxFrame::PositionToolBar
1312 #endif // wxUSE_TOOLBAR
1313
1314 // ----------------------------------------------------------------------------
1315 // frame state (iconized/maximized/...)
1316 // ----------------------------------------------------------------------------
1317
1318 //
1319 // propagate our state change to all child frames: this allows us to emulate X
1320 // Windows behaviour where child frames float independently of the parent one
1321 // on the desktop, but are iconized/restored with it
1322 //
1323 void wxFrame::IconizeChildFrames(
1324 bool bIconize
1325 )
1326 {
1327 for (wxWindowList::Node* pNode = GetChildren().GetFirst();
1328 pNode;
1329 pNode = pNode->GetNext() )
1330 {
1331 wxWindow* pWin = pNode->GetData();
1332 wxFrame* pFrame = wxDynamicCast(pWin, wxFrame);
1333
1334 if ( pFrame
1335 #if wxUSE_MDI_ARCHITECTURE
1336 && !wxDynamicCast(pFrame, wxMDIChildFrame)
1337 #endif // wxUSE_MDI_ARCHITECTURE
1338 )
1339 {
1340 //
1341 // We don't want to restore the child frames which had been
1342 // iconized even before we were iconized, so save the child frame
1343 // status when iconizing the parent frame and check it when
1344 // restoring it.
1345 //
1346 if (bIconize)
1347 {
1348 pFrame->m_bWasMinimized = pFrame->IsIconized();
1349 }
1350
1351 //
1352 // This test works for both iconizing and restoring
1353 //
1354 if (!pFrame->m_bWasMinimized)
1355 pFrame->Iconize(bIconize);
1356 }
1357 }
1358 } // end of wxFrame::IconizeChildFrames
1359
1360 // ===========================================================================
1361 // message processing
1362 // ===========================================================================
1363
1364 // ---------------------------------------------------------------------------
1365 // preprocessing
1366 // ---------------------------------------------------------------------------
1367 bool wxFrame::OS2TranslateMessage(
1368 WXMSG* pMsg
1369 )
1370 {
1371 //
1372 // try the menu bar accels
1373 //
1374 wxMenuBar* pMenuBar = GetMenuBar();
1375
1376 if (!pMenuBar)
1377 return FALSE;
1378
1379 #if wxUSE_ACCEL && wxUSE_MENUS_NATIVE
1380 const wxAcceleratorTable& rAcceleratorTable = pMenuBar->GetAccelTable();
1381 return rAcceleratorTable.Translate(GetHWND(), pMsg);
1382 #else
1383 return FALSE;
1384 #endif //wxUSE_ACCEL
1385 } // end of wxFrame::OS2TranslateMessage
1386
1387 // ---------------------------------------------------------------------------
1388 // our private (non virtual) message handlers
1389 // ---------------------------------------------------------------------------
1390 bool wxFrame::HandlePaint()
1391 {
1392 RECTL vRect;
1393
1394 if (::WinQueryUpdateRect(GetHWND(), &vRect))
1395 {
1396 if (m_bIconized)
1397 {
1398 //
1399 // Icons in PM are the same as "pointers"
1400 //
1401 HPOINTER hIcon;
1402
1403 if (m_icon.Ok())
1404 hIcon = (HPOINTER)::WinSendMsg(m_hFrame, WM_QUERYICON, 0L, 0L);
1405 else
1406 hIcon = (HPOINTER)m_hDefaultIcon;
1407
1408 //
1409 // Hold a pointer to the dc so long as the OnPaint() message
1410 // is being processed
1411 //
1412 RECTL vRect2;
1413 HPS hPs = ::WinBeginPaint(GetHwnd(), NULLHANDLE, &vRect2);
1414
1415 //
1416 // Erase background before painting or we get white background
1417 //
1418 OS2DefWindowProc(WM_ERASEBACKGROUND, (MPARAM)hPs, (MPARAM)&vRect2);
1419
1420 if (hIcon)
1421 {
1422 HWND hWndClient;
1423 RECTL vRect3;
1424
1425 ::WinQueryWindowRect(GetHwnd(), &vRect3);
1426
1427 static const int nIconWidth = 32;
1428 static const int nIconHeight = 32;
1429 int nIconX = (int)((vRect3.xRight - nIconWidth)/2);
1430 int nIconY = (int)((vRect3.yBottom + nIconHeight)/2);
1431
1432 ::WinDrawPointer(hPs, nIconX, nIconY, hIcon, DP_NORMAL);
1433 }
1434 ::WinEndPaint(hPs);
1435 return TRUE;
1436 }
1437 else
1438 {
1439 if (!wxWindow::HandlePaint())
1440 {
1441 HPS hPS;
1442 RECTL vRect;
1443
1444 hPS = ::WinBeginPaint( GetHwnd()
1445 ,NULLHANDLE
1446 ,&vRect
1447 );
1448 if(hPS)
1449 {
1450 ::GpiCreateLogColorTable( hPS
1451 ,0L
1452 ,LCOLF_CONSECRGB
1453 ,0L
1454 ,(LONG)wxTheColourDatabase->m_nSize
1455 ,(PLONG)wxTheColourDatabase->m_palTable
1456 );
1457 ::GpiCreateLogColorTable( hPS
1458 ,0L
1459 ,LCOLF_RGB
1460 ,0L
1461 ,0L
1462 ,NULL
1463 );
1464
1465 ::WinFillRect( hPS
1466 ,&vRect
1467 ,GetBackgroundColour().GetPixel()
1468 );
1469 ::WinEndPaint(hPS);
1470 }
1471 }
1472 return TRUE;
1473 }
1474 }
1475 else
1476 {
1477 // nothing to paint - processed
1478 return TRUE;
1479 }
1480 return FALSE;
1481 } // end of wxFrame::HandlePaint
1482
1483 bool wxFrame::HandleSize(
1484 int nX
1485 , int nY
1486 , WXUINT nId
1487 )
1488 {
1489 bool bProcessed = FALSE;
1490
1491 switch (nId)
1492 {
1493 case kSizeNormal:
1494 //
1495 // Only do it it if we were iconized before, otherwise resizing the
1496 // parent frame has a curious side effect of bringing it under it's
1497 // children
1498 if (!m_bIconized )
1499 break;
1500
1501 //
1502 // restore all child frames too
1503 //
1504 IconizeChildFrames(FALSE);
1505 (void)SendIconizeEvent(FALSE);
1506
1507 //
1508 // fall through
1509 //
1510
1511 case kSizeMax:
1512 m_bIconized = FALSE;
1513 break;
1514
1515 case kSizeMin:
1516 //
1517 // Iconize all child frames too
1518 //
1519 IconizeChildFrames(TRUE);
1520 (void)SendIconizeEvent();
1521 m_bIconized = TRUE;
1522 break;
1523 }
1524
1525 if (!m_bIconized)
1526 {
1527 //
1528 // forward WM_SIZE to status bar control
1529 //
1530 #if wxUSE_NATIVE_STATUSBAR
1531 if (m_frameStatusBar && m_frameStatusBar->IsKindOf(CLASSINFO(wxStatusBar95)))
1532 {
1533 wxSizeEvent vEvent( wxSize( nX
1534 ,nY
1535 )
1536 ,m_frameStatusBar->GetId()
1537 );
1538
1539 vEvent.SetEventObject(m_frameStatusBar);
1540 m_frameStatusBar->OnSize(vEvent);
1541 }
1542 #endif // wxUSE_NATIVE_STATUSBAR
1543
1544 PositionStatusBar();
1545 #if wxUSE_TOOLBAR
1546 PositionToolBar();
1547 #endif // wxUSE_TOOLBAR
1548
1549 wxSizeEvent vEvent( wxSize( nX
1550 ,nY
1551 )
1552 ,m_windowId
1553 );
1554
1555 vEvent.SetEventObject(this);
1556 bProcessed = GetEventHandler()->ProcessEvent(vEvent);
1557 AlterChildPos();
1558 }
1559 return bProcessed;
1560 } // end of wxFrame::HandleSize
1561
1562 bool wxFrame::HandleCommand(
1563 WXWORD nId
1564 , WXWORD nCmd
1565 , WXHWND hControl
1566 )
1567 {
1568 if (hControl)
1569 {
1570 //
1571 // In case it's e.g. a toolbar.
1572 //
1573 wxWindow* pWin = wxFindWinFromHandle(hControl);
1574
1575 if (pWin)
1576 return pWin->OS2Command( nCmd
1577 ,nId
1578 );
1579 }
1580
1581 //
1582 // Handle here commands from menus and accelerators
1583 //
1584 if (nCmd == CMDSRC_MENU || nCmd == CMDSRC_ACCELERATOR)
1585 {
1586 #if wxUSE_MENUS_NATIVE
1587 if (wxCurrentPopupMenu)
1588 {
1589 wxMenu* pPopupMenu = wxCurrentPopupMenu;
1590
1591 wxCurrentPopupMenu = NULL;
1592
1593 return pPopupMenu->OS2Command( nCmd
1594 ,nId
1595 );
1596 return TRUE;
1597 }
1598 #endif
1599
1600 if (ProcessCommand(nId))
1601 {
1602 return TRUE;
1603 }
1604 }
1605 return FALSE;
1606 } // end of wxFrame::HandleCommand
1607
1608 bool wxFrame::HandleMenuSelect(
1609 WXWORD nItem
1610 , WXWORD nFlags
1611 , WXHMENU hMenu
1612 )
1613 {
1614 if( !nFlags )
1615 {
1616 MENUITEM mItem;
1617 MRESULT rc;
1618
1619 rc = ::WinSendMsg(hMenu, MM_QUERYITEM, MPFROM2SHORT(nItem, TRUE), (MPARAM)&mItem);
1620
1621 if(rc && !(mItem.afStyle & (MIS_SUBMENU | MIS_SEPARATOR)))
1622 {
1623 wxMenuEvent vEvent(wxEVT_MENU_HIGHLIGHT, nItem);
1624
1625 vEvent.SetEventObject(this);
1626 GetEventHandler()->ProcessEvent(vEvent); // return value would be ignored by PM
1627 }
1628 }
1629 return TRUE;
1630 } // end of wxFrame::HandleMenuSelect
1631
1632 // ---------------------------------------------------------------------------
1633 // Main Frame window proc
1634 // ---------------------------------------------------------------------------
1635 MRESULT EXPENTRY wxFrameMainWndProc(
1636 HWND hWnd
1637 , ULONG ulMsg
1638 , MPARAM wParam
1639 , MPARAM lParam
1640 )
1641 {
1642 MRESULT rc = (MRESULT)0;
1643 bool bProcessed = FALSE;
1644 wxFrame* pWnd = NULL;
1645
1646 pWnd = (wxFrame*) wxFindWinFromHandle((WXHWND) hWnd);
1647 switch (ulMsg)
1648 {
1649 case WM_QUERYFRAMECTLCOUNT:
1650 if(pWnd && pWnd->m_fnOldWndProc)
1651 {
1652 USHORT uItemCount = SHORT1FROMMR(pWnd->m_fnOldWndProc(hWnd, ulMsg, wParam, lParam));
1653
1654 rc = MRFROMSHORT(uItemCount);
1655 }
1656 break;
1657
1658 case WM_FORMATFRAME:
1659 /////////////////////////////////////////////////////////////////////////////////
1660 // Applications that subclass frame controls may find that the frame is already
1661 // subclassed the number of frame controls is variable.
1662 // The WM_FORMATFRAME and WM_QUERYFRAMECTLCOUNT messages must always be
1663 // subclassed by calling the previous window procedure and modifying its result.
1664 ////////////////////////////////////////////////////////////////////////////////
1665 {
1666 int nItemCount;
1667 int i;
1668 PSWP pSWP = NULL;
1669 SWP vSwpStb;
1670 RECTL vRectl;
1671 RECTL vRstb;
1672 int nHeight=0;
1673
1674 pSWP = (PSWP)PVOIDFROMMP(wParam);
1675 nItemCount = SHORT1FROMMR(pWnd->m_fnOldWndProc(hWnd, ulMsg, wParam, lParam));
1676 if(pWnd->m_frameStatusBar)
1677 {
1678 ::WinQueryWindowRect(pWnd->m_frameStatusBar->GetHWND(), &vRstb);
1679 pWnd->m_frameStatusBar->GetSize(NULL, &nHeight);
1680 ::WinQueryWindowRect(pWnd->m_hFrame, &vRectl);
1681 ::WinMapWindowPoints(pWnd->m_hFrame, HWND_DESKTOP, (PPOINTL)&vRectl, 2);
1682 vRstb = vRectl;
1683 ::WinCalcFrameRect(pWnd->m_hFrame, &vRectl, TRUE);
1684
1685 vSwpStb.x = vRectl.xLeft - vRstb.xLeft;
1686 vSwpStb.y = vRectl.yBottom - vRstb.yBottom;
1687 vSwpStb.cx = vRectl.xRight - vRectl.xLeft - 1; //?? -1 ??
1688 vSwpStb.cy = nHeight;
1689 vSwpStb.fl = SWP_SIZE |SWP_MOVE | SWP_SHOW;
1690 vSwpStb.hwnd = pWnd->m_frameStatusBar->GetHWND();
1691 vSwpStb.hwndInsertBehind = HWND_TOP;
1692 }
1693 ::WinQueryWindowRect(pWnd->m_hFrame, &vRectl);
1694 ::WinMapWindowPoints(pWnd->m_hFrame, HWND_DESKTOP, (PPOINTL)&vRectl, 2);
1695 ::WinCalcFrameRect(pWnd->m_hFrame, &vRectl, TRUE);
1696 ::WinMapWindowPoints(HWND_DESKTOP, pWnd->m_hFrame, (PPOINTL)&vRectl, 2);
1697 for(i = 0; i < nItemCount; i++)
1698 {
1699 if(pWnd->m_hWnd && pSWP[i].hwnd == pWnd->m_hWnd)
1700 {
1701 pSWP[i].x = vRectl.xLeft;
1702 pSWP[i].y = vRectl.yBottom + nHeight;
1703 pSWP[i].cx = vRectl.xRight - vRectl.xLeft;
1704 pSWP[i].cy = vRectl.yTop - vRectl.yBottom - nHeight;
1705 pSWP[i].fl = SWP_SIZE | SWP_MOVE | SWP_SHOW;
1706 pSWP[i].hwndInsertBehind = HWND_TOP;
1707 }
1708 }
1709 bProcessed = TRUE;
1710 rc = MRFROMSHORT(nItemCount);
1711 }
1712 break;
1713
1714 default:
1715 if(pWnd && pWnd->m_fnOldWndProc)
1716 rc = pWnd->m_fnOldWndProc(hWnd, ulMsg, wParam, lParam);
1717 else
1718 rc = ::WinDefWindowProc(hWnd, ulMsg, wParam, lParam);
1719 }
1720 return rc;
1721 } // end of wxFrameMainWndProc
1722
1723 MRESULT EXPENTRY wxFrameWndProc(
1724 HWND hWnd
1725 , ULONG ulMsg
1726 , MPARAM wParam
1727 , MPARAM lParam
1728 )
1729 {
1730 //
1731 // Trace all ulMsgs - useful for the debugging
1732 //
1733 HWND parentHwnd;
1734 wxFrame* pWnd = NULL;
1735
1736 parentHwnd = WinQueryWindow(hWnd,QW_PARENT);
1737 pWnd = (wxFrame*) wxFindWinFromHandle((WXHWND) hWnd);
1738
1739 //
1740 // When we get the first message for the HWND we just created, we associate
1741 // it with wxWindow stored in wxWndHook
1742 //
1743
1744 MRESULT rc = (MRESULT)0;
1745 bool bProcessed = FALSE;
1746
1747 //
1748 // Stop right here if we don't have a valid handle in our wxWindow object.
1749 //
1750 if (pWnd && !pWnd->GetHWND())
1751 {
1752 pWnd->SetHWND((WXHWND) hWnd);
1753 rc = pWnd->OS2DefWindowProc(ulMsg, wParam, lParam );
1754 pWnd->SetHWND(0);
1755 }
1756 else
1757 {
1758 if (pWnd)
1759 rc = pWnd->OS2WindowProc(ulMsg, wParam, lParam);
1760 else
1761 rc = ::WinDefWindowProc(hWnd, ulMsg, wParam, lParam);
1762 }
1763 return rc;
1764 } // end of wxFrameWndProc
1765
1766 MRESULT wxFrame::OS2WindowProc(
1767 WXUINT uMessage
1768 , WXWPARAM wParam
1769 , WXLPARAM lParam
1770 )
1771 {
1772 MRESULT mRc = 0L;
1773 bool bProcessed = FALSE;
1774
1775 switch (uMessage)
1776 {
1777 case WM_CLOSE:
1778 //
1779 // If we can't close, tell the system that we processed the
1780 // message - otherwise it would close us
1781 //
1782 bProcessed = !Close();
1783 break;
1784
1785 case WM_PAINT:
1786 bProcessed = HandlePaint();
1787 mRc = (MRESULT)FALSE;
1788 break;
1789
1790 case WM_ERASEBACKGROUND:
1791 //
1792 // Returning TRUE to requests PM to paint the window background
1793 // in SYSCLR_WINDOW. We capture this here because the PS returned
1794 // in Frames is the PS for the whole frame, which we can't really
1795 // use at all. If you want to paint a different background, do it
1796 // in an OnPaint using a wxPaintDC.
1797 //
1798 mRc = (MRESULT)(TRUE);
1799 break;
1800
1801 case WM_COMMAND:
1802 {
1803 WORD wId;
1804 WORD wCmd;
1805 WXHWND hWnd;
1806
1807 UnpackCommand( (WXWPARAM)wParam
1808 ,(WXLPARAM)lParam
1809 ,&wId
1810 ,&hWnd
1811 ,&wCmd
1812 );
1813
1814 bProcessed = HandleCommand( wId
1815 ,wCmd
1816 ,(WXHWND)hWnd
1817 );
1818 }
1819 break;
1820
1821 case WM_MENUSELECT:
1822 {
1823 WXWORD wItem;
1824 WXWORD wFlags;
1825 WXHMENU hMenu;
1826
1827 UnpackMenuSelect( wParam
1828 ,lParam
1829 ,&wItem
1830 ,&wFlags
1831 ,&hMenu
1832 );
1833 bProcessed = HandleMenuSelect( wItem
1834 ,wFlags
1835 ,hMenu
1836 );
1837 mRc = (MRESULT)TRUE;
1838 }
1839 break;
1840
1841 case WM_SIZE:
1842 {
1843 SHORT nScxold = SHORT1FROMMP(wParam); // Old horizontal size.
1844 SHORT nScyold = SHORT2FROMMP(wParam); // Old vertical size.
1845 SHORT nScxnew = SHORT1FROMMP(lParam); // New horizontal size.
1846 SHORT nScynew = SHORT2FROMMP(lParam); // New vertical size.
1847
1848 lParam = MRFROM2SHORT( nScxnew - 20
1849 ,nScynew - 30
1850 );
1851 }
1852 bProcessed = HandleSize(LOWORD(lParam), HIWORD(lParam), (WXUINT)wParam);
1853 mRc = (MRESULT)FALSE;
1854 break;
1855
1856 case CM_QUERYDRAGIMAGE:
1857 {
1858 HPOINTER hIcon;
1859
1860 if (m_icon.Ok())
1861 hIcon = (HPOINTER)::WinSendMsg(GetHWND(), WM_QUERYICON, 0L, 0L);
1862 else
1863 hIcon = (HPOINTER)m_hDefaultIcon;
1864 mRc = (MRESULT)hIcon;
1865 bProcessed = mRc != 0;
1866 }
1867 break;
1868 }
1869
1870 if (!bProcessed )
1871 mRc = wxWindow::OS2WindowProc( uMessage
1872 ,wParam
1873 ,lParam
1874 );
1875 return (MRESULT)mRc;
1876 } // wxFrame::OS2WindowProc
1877
1878 void wxFrame::SetClient(WXHWND c_Hwnd)
1879 {
1880 // Duh...nothing to do under OS/2
1881 }
1882
1883 void wxFrame::SetClient(
1884 wxWindow* pWindow
1885 )
1886 {
1887 wxWindow* pOldClient = this->GetClient();
1888 bool bClientHasFocus = pOldClient && (pOldClient == wxWindow::FindFocus());
1889
1890 if(pOldClient == pWindow) // nothing to do
1891 return;
1892 if(pWindow == NULL) // just need to remove old client
1893 {
1894 if(pOldClient == NULL) // nothing to do
1895 return;
1896
1897 if(bClientHasFocus )
1898 this->SetFocus();
1899
1900 pOldClient->Enable( FALSE );
1901 pOldClient->Show( FALSE );
1902 ::WinSetWindowUShort(pOldClient->GetHWND(), QWS_ID, (USHORT)pOldClient->GetId());
1903 // to avoid OS/2 bug need to update frame
1904 ::WinSendMsg((HWND)this->GetFrame(), WM_UPDATEFRAME, (MPARAM)~0, 0);
1905 return;
1906 }
1907
1908 //
1909 // Else need to change client
1910 //
1911 if(bClientHasFocus)
1912 this->SetFocus();
1913
1914 ::WinEnableWindowUpdate((HWND)GetHWND(), FALSE);
1915 if(pOldClient)
1916 {
1917 pOldClient->Enable(FALSE);
1918 pOldClient->Show(FALSE);
1919 ::WinSetWindowUShort(pOldClient->GetHWND(), QWS_ID, (USHORT)pOldClient->GetId());
1920 }
1921 pWindow->Reparent(this);
1922 ::WinSetWindowUShort(pWindow->GetHWND(), QWS_ID, FID_CLIENT);
1923 ::WinEnableWindowUpdate((HWND)GetHWND(), TRUE);
1924 pWindow->Enable();
1925 pWindow->Show(); // ensure client is showing
1926 if( this->IsShown() )
1927 {
1928 this->Show();
1929 ::WinSendMsg(m_hFrame, WM_UPDATEFRAME, (MPARAM)~0, 0);
1930 }
1931 }
1932
1933 wxWindow* wxFrame::GetClient()
1934 {
1935 return wxFindWinFromHandle((WXHWND)::WinWindowFromID(m_hFrame, FID_CLIENT));
1936 }