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