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