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