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