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