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