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