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