]> git.saurik.com Git - wxWidgets.git/blob - src/os2/frame.cpp
*** empty log message ***
[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/setup.h"
17 #include "wx/frame.h"
18 #include "wx/menu.h"
19 #include "wx/app.h"
20 #include "wx/utils.h"
21 #include "wx/dialog.h"
22 #include "wx/settings.h"
23 #include "wx/dcclient.h"
24 #endif // WX_PRECOMP
25
26 #include "wx/os2/private.h"
27
28 #if wxUSE_STATUSBAR
29 #include "wx/statusbr.h"
30 #include "wx/generic/statusbr.h"
31 #endif // wxUSE_STATUSBAR
32
33 #if wxUSE_TOOLBAR
34 #include "wx/toolbar.h"
35 #endif // wxUSE_TOOLBAR
36
37 #include "wx/menuitem.h"
38 #include "wx/log.h"
39
40 // ----------------------------------------------------------------------------
41 // globals
42 // ----------------------------------------------------------------------------
43
44 extern wxWindowList wxModelessWindows;
45 extern wxList WXDLLEXPORT wxPendingDelete;
46 extern wxChar wxFrameClassName[];
47 extern wxMenu *wxCurrentPopupMenu;
48
49 // ----------------------------------------------------------------------------
50 // event tables
51 // ----------------------------------------------------------------------------
52
53 BEGIN_EVENT_TABLE(wxFrame, wxFrameBase)
54 EVT_ACTIVATE(wxFrame::OnActivate)
55 EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged)
56 END_EVENT_TABLE()
57
58 IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxWindow)
59
60 // ============================================================================
61 // implementation
62 // ============================================================================
63
64 // ----------------------------------------------------------------------------
65 // static class members
66 // ----------------------------------------------------------------------------
67
68 #if wxUSE_NATIVE_STATUSBAR
69 bool wxFrame::m_bUseNativeStatusBar = TRUE;
70 #else
71 bool wxFrame::m_bUseNativeStatusBar = FALSE;
72 #endif
73
74 // ----------------------------------------------------------------------------
75 // creation/destruction
76 // ----------------------------------------------------------------------------
77
78 void wxFrame::Init()
79 {
80 m_bIconized = FALSE;
81
82 #if wxUSE_TOOLTIPS
83 m_hWndToolTip = 0;
84 #endif
85 // Data to save/restore when calling ShowFullScreen
86 m_lFsStyle = 0L;
87 m_lFsOldWindowStyle = 0L;
88 m_nFsStatusBarFields = 0;
89 m_nFsStatusBarHeight = 0;
90 m_nFsToolBarHeight = 0;
91 m_bFsIsMaximized = FALSE;
92 m_bFsIsShowing = FALSE;
93 } // end of wxFrame::Init
94
95 bool wxFrame::Create(
96 wxWindow* pParent
97 , wxWindowID vId
98 , const wxString& rsTitle
99 , const wxPoint& rPos
100 , const wxSize& rSize
101 , long lulStyle
102 , const wxString& rsName
103 )
104 {
105 int nX = rPos.x;
106 int nY = rPos.y;
107 int nWidth = rSize.x;
108 int nHeight = rSize.y;
109
110 SetName(rsName);
111 m_windowStyle = lulStyle;
112 m_frameMenuBar = NULL;
113 m_frameToolBar = NULL;
114 m_frameStatusBar = NULL;
115
116 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE));
117
118 if (vId > -1 )
119 m_windowId = vId;
120 else
121 m_windowId = (int)NewControlId();
122
123 if (pParent)
124 pParent->AddChild(this);
125
126 m_bIconized = FALSE;
127
128 if ((m_windowStyle & wxFRAME_FLOAT_ON_PARENT) == 0)
129 pParent = NULL;
130
131 if (!pParent)
132 wxTopLevelWindows.Append(this);
133
134 OS2Create( m_windowId
135 ,pParent
136 ,wxFrameClassName
137 ,this
138 ,rsTitle
139 ,nX
140 ,nY
141 ,nWidth
142 ,nHeight
143 ,lulStyle
144 );
145
146 wxModelessWindows.Append(this);
147 return TRUE;
148 } // end of wxFrame::Create
149
150 wxFrame::~wxFrame()
151 {
152 m_isBeingDeleted = TRUE;
153 wxTopLevelWindows.DeleteObject(this);
154
155 DeleteAllBars();
156
157 if (wxTheApp && (wxTopLevelWindows.Number() == 0))
158 {
159 wxTheApp->SetTopWindow(NULL);
160
161 if (wxTheApp->GetExitOnFrameDelete())
162 {
163 ::WinPostMsg(GetHwnd(), WM_QUIT, 0, 0);
164 }
165 }
166 wxModelessWindows.DeleteObject(this);
167
168 //
169 // For some reason, wxWindows can activate another task altogether
170 // when a frame is destroyed after a modal dialog has been invoked.
171 // Try to bring the parent to the top.
172 //
173 // MT:Only do this if this frame is currently the active window, else weird
174 // things start to happen.
175 //
176 if (wxGetActiveWindow() == this)
177 {
178 if (GetParent() && GetParent()->GetHWND())
179 {
180 ::WinSetWindowPos( (HWND) GetParent()->GetHWND()
181 ,HWND_TOP
182 ,0
183 ,0
184 ,0
185 ,0
186 ,SWP_ZORDER
187 );
188 }
189 }
190 } // end of wxFrame::~wxFrame
191
192 //
193 // Get size *available for subwindows* i.e. excluding menu bar, toolbar etc.
194 //
195 void wxFrame::DoGetClientSize(
196 int* pX
197 , int* pY
198 ) const
199 {
200 //
201 // OS/2 PM's coordinates go from bottom-left not
202 // top-left thus the += instead of the -=
203 //
204 RECTL vRect;
205 HWND hWndClient;
206
207 //
208 // PM has no GetClientRect that inherantly knows about the client window
209 // We have to explicitly go fetch it!
210 //
211 hWndClient = ::WinWindowFromID(GetHwnd(), FID_CLIENT);
212 ::WinQueryWindowRect(hWndClient, &vRect);
213
214 #if wxUSE_STATUSBAR
215 if ( GetStatusBar() )
216 {
217 int nStatusX;
218 int nStatusY;
219
220 GetStatusBar()->GetClientSize( &nStatusX
221 ,&nStatusY
222 );
223 vRect.yBottom += nStatusY;
224 }
225 #endif // wxUSE_STATUSBAR
226
227 wxPoint vPoint(GetClientAreaOrigin());
228
229 vRect.yBottom += vPoint.y;
230 vRect.xRight -= vPoint.x;
231
232 if (pX)
233 *pX = vRect.xRight;
234 if (pY)
235 *pY = vRect.yBottom;
236 } // end of wxFrame::DoGetClientSize
237
238 //
239 // Set the client size (i.e. leave the calculation of borders etc.
240 // to wxWindows)
241 //
242 void wxFrame::DoSetClientSize(
243 int nWidth
244 , int nHeight
245 )
246 {
247 HWND hWnd = GetHwnd();
248 HWND hWndClient;
249 RECTL vRect;
250 RECTL vRect2;
251
252 hWndClient = ::WinWindowFromID(GetHwnd(), FID_CLIENT);
253 ::WinQueryWindowRect(hWndClient, &vRect);
254
255 ::WinQueryWindowRect(hWnd, &vRect2);
256
257 //
258 // Find the difference between the entire window (title bar and all)
259 // and the client area; add this to the new client size to move the
260 // window. Remember OS/2's backwards y coord system!
261 //
262 int nActualWidth = vRect2.xRight - vRect2.xLeft - vRect.xRight + nWidth;
263 int nActualHeight = vRect2.yTop + vRect2.yTop - vRect.yTop + nHeight;
264
265 #if wxUSE_STATUSBAR
266 if ( GetStatusBar() )
267 {
268 int nStatusX;
269 int nStatusY;
270
271 GetStatusBar()->GetClientSize( &nStatusX
272 ,&nStatusY
273 );
274 nActualHeight += nStatusY;
275 }
276 #endif // wxUSE_STATUSBAR
277
278 wxPoint vPoint(GetClientAreaOrigin());
279 nActualWidth += vPoint.y;
280 nActualHeight += vPoint.x;
281
282 POINTL vPointl;
283
284 vPointl.x = vRect2.xLeft;
285 vPoint.y = vRect2.yTop;
286
287 ::WinSetWindowPos( hWnd
288 ,HWND_TOP
289 ,vPointl.x
290 ,vPointl.y
291 ,nActualWidth
292 ,nActualHeight
293 ,SWP_MOVE | SWP_SIZE | SWP_SHOW
294 );
295
296 wxSizeEvent vEvent( wxSize( nWidth
297 ,nHeight
298 )
299 ,m_windowId
300 );
301 vEvent.SetEventObject(this);
302 GetEventHandler()->ProcessEvent(vEvent);
303 } // end of wxFrame::DoSetClientSize
304
305 void wxFrame::DoGetSize(
306 int* pWidth
307 , int* pHeight
308 ) const
309 {
310 RECTL vRect;
311
312 ::WinQueryWindowRect(GetHwnd(), &vRect);
313 *pWidth = vRect.xRight - vRect.xLeft;
314 *pHeight = vRect.yTop - vRect.yBottom;
315 } // end of wxFrame::DoGetSize
316
317 void wxFrame::DoGetPosition(
318 int* pX
319 , int* pY
320 ) const
321 {
322 RECTL vRect;
323 POINTL vPoint;
324
325 ::WinQueryWindowRect(GetHwnd(), &vRect);
326 vPoint.x = vRect.xLeft;
327
328 //
329 // OS/2 is backwards [WIN32 it is vRect.yTop]
330 //
331 vPoint.y = vRect.yBottom;
332
333 *pX = vPoint.x;
334 *pY = vPoint.y;
335 } // end of wxFrame::DoGetPosition
336
337 // ----------------------------------------------------------------------------
338 // variations around ::ShowWindow()
339 // ----------------------------------------------------------------------------
340
341 void wxFrame::DoShowWindow(
342 int bShowCmd
343 )
344 {
345 HWND hClient;
346
347 //
348 // Send anything to initialize the frame
349 //
350 ::WinSendMsg( GetHwnd()
351 ,WM_UPDATEFRAME
352 ,(MPARAM)FCF_MENU
353 ,(MPARAM)0
354 );
355 hClient = ::WinWindowFromID(GetHwnd(), FID_CLIENT);
356 ::WinShowWindow(GetHwnd(), (BOOL)bShowCmd);
357 ::WinShowWindow(hClient, (BOOL)bShowCmd);
358 } // end of wxFrame::DoShowWindow
359
360 bool wxFrame::Show(
361 bool bShow
362 )
363 {
364 SWP vSwp;
365
366 DoShowWindow((int)bShow);
367
368 if (bShow)
369 {
370 wxActivateEvent vEvent(wxEVT_ACTIVATE, TRUE, m_windowId);
371
372 ::WinQueryWindowPos(GetHwnd(), &vSwp);
373 m_bIconized = vSwp.fl & SWP_MINIMIZE;
374 ::WinSetWindowPos( (HWND) GetHWND()
375 ,HWND_TOP
376 ,vSwp.x
377 ,vSwp.y
378 ,vSwp.cx
379 ,vSwp.cy
380 ,SWP_ZORDER | SWP_ACTIVATE | SWP_SHOW | SWP_MOVE
381 );
382 vEvent.SetEventObject(this);
383 GetEventHandler()->ProcessEvent(vEvent);
384 }
385 else
386 {
387 //
388 // Try to highlight the correct window (the parent)
389 //
390 if (GetParent())
391 {
392 HWND hWndParent = GetHwndOf(GetParent());
393
394 ::WinQueryWindowPos(hWndParent, &vSwp);
395 m_bIconized = vSwp.fl & SWP_MINIMIZE;
396 if (hWndParent)
397 ::WinSetWindowPos( hWndParent
398 ,HWND_TOP
399 ,vSwp.x
400 ,vSwp.y
401 ,vSwp.cx
402 ,vSwp.cy
403 ,SWP_ZORDER | SWP_ACTIVATE | SWP_SHOW | SWP_MOVE
404 );
405 }
406 }
407 return TRUE;
408 } // end of wxFrame::Show
409
410 void wxFrame::Iconize(
411 bool bIconize
412 )
413 {
414 DoShowWindow(bIconize ? SWP_MINIMIZE : SWP_RESTORE);
415 } // end of wxFrame::Iconize
416
417 void wxFrame::Maximize(
418 bool bMaximize)
419 {
420 DoShowWindow(bMaximize ? SWP_MAXIMIZE : SWP_RESTORE);
421 } // end of wxFrame::Maximize
422
423 void wxFrame::Restore()
424 {
425 DoShowWindow(SWP_RESTORE);
426 } // end of wxFrame::Restore
427
428 bool wxFrame::IsIconized() const
429 {
430 SWP vSwp;
431 bool bIconic;
432
433 ::WinQueryWindowPos(GetHwnd(), &vSwp);
434
435 if (vSwp.fl & SWP_MINIMIZE)
436 ((wxFrame*)this)->m_bIconized = TRUE;
437 else
438 ((wxFrame*)this)->m_bIconized = FALSE;
439 return m_bIconized;
440 } // end of wxFrame::IsIconized
441
442 // Is it maximized?
443 bool wxFrame::IsMaximized() const
444 {
445 SWP vSwp;
446 bool bIconic;
447
448 ::WinQueryWindowPos(GetHwnd(), &vSwp);
449 return (vSwp.fl & SWP_MAXIMIZE);
450 } // end of wxFrame::IsMaximized
451
452 void wxFrame::SetIcon(
453 const wxIcon& rIcon
454 )
455 {
456 wxFrameBase::SetIcon(rIcon);
457
458 if ((m_icon.GetHICON()) != NULLHANDLE)
459 {
460 ::WinSendMsg( GetHwnd()
461 ,WM_SETICON
462 ,(MPARAM)((HPOINTER)m_icon.GetHICON())
463 ,NULL
464 );
465 ::WinSendMsg( GetHwnd()
466 ,WM_UPDATEFRAME
467 ,(MPARAM)FCF_ICON
468 ,(MPARAM)0
469 );
470 }
471 } // end of wxFrame::SetIcon
472
473 #if wxUSE_STATUSBAR
474 wxStatusBar* wxFrame::OnCreateStatusBar(
475 int nNumber
476 , long lulStyle
477 , wxWindowID vId
478 , const wxString& rName
479 )
480 {
481 wxStatusBar* pStatusBar = NULL;
482
483 pStatusBar = wxFrameBase::OnCreateStatusBar( nNumber
484 ,lulStyle
485 ,vId
486 ,rName
487 );
488 return pStatusBar;
489 } // end of wxFrame::OnCreateStatusBar
490
491 void wxFrame::PositionStatusBar()
492 {
493 //
494 // Native status bar positions itself
495 //
496 if (m_frameStatusBar)
497 {
498 int nWidth;
499 int nHeight;
500 int nStatbarWidth;
501 int nStatbarHeight;
502 HWND hWndClient;
503 RECTL vRect;
504
505 hWndClient = ::WinWindowFromID(GetHwnd(), FID_CLIENT);
506 ::WinQueryWindowRect(hWndClient, &vRect);
507 nWidth = vRect.xRight - vRect.xLeft;
508 nHeight = vRect.yTop - vRect.yBottom;
509
510 m_frameStatusBar->GetSize( &nStatbarWidth
511 ,&nStatbarHeight
512 );
513
514 //
515 // Since we wish the status bar to be directly under the client area,
516 // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.
517 //
518 m_frameStatusBar->SetSize( 0
519 ,nHeight
520 ,nWidth
521 ,nStatbarHeight
522 );
523 }
524 } // end of wxFrame::PositionStatusBar
525 #endif // wxUSE_STATUSBAR
526
527 void wxFrame::DetachMenuBar()
528 {
529 if (m_frameMenuBar)
530 {
531 m_frameMenuBar->Detach();
532 m_frameMenuBar = NULL;
533 }
534 } // end of wxFrame::DetachMenuBar
535
536 void wxFrame::SetMenuBar(
537 wxMenuBar* pMenuBar
538 )
539 {
540 if (!pMenuBar)
541 {
542 DetachMenuBar();
543 return;
544 }
545
546 m_frameMenuBar = NULL;
547
548 // Can set a menubar several times.
549 // TODO: how to prevent a memory leak if you have a currently-unattached
550 // menubar? wxWindows assumes that the frame will delete the menu (otherwise
551 // there are problems for MDI).
552 if (pMenuBar->GetHMenu())
553 {
554 m_hMenu = pMenuBar->GetHMenu();
555 }
556 else
557 {
558 pMenuBar->Detach();
559
560 m_hMenu = pMenuBar->Create();
561
562 if (!m_hMenu)
563 return;
564 }
565
566 InternalSetMenuBar();
567
568 m_frameMenuBar = pMenuBar;
569 pMenuBar->Attach(this);
570 } // end of wxFrame::SetMenuBar
571
572 void wxFrame::InternalSetMenuBar()
573 {
574 WinSendMsg((HWND)GetHwnd(), WM_UPDATEFRAME, (MPARAM)FCF_MENU, (MPARAM)0);
575 } // end of wxFrame::InternalSetMenuBar
576
577 //
578 // Responds to colour changes, and passes event on to children
579 //
580 void wxFrame::OnSysColourChanged(
581 wxSysColourChangedEvent& rEvent
582 )
583 {
584 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE));
585 Refresh();
586
587 if (m_frameStatusBar)
588 {
589 wxSysColourChangedEvent vEvent2;
590
591 vEvent2.SetEventObject(m_frameStatusBar);
592 m_frameStatusBar->GetEventHandler()->ProcessEvent(vEvent2);
593 }
594
595 //
596 // Propagate the event to the non-top-level children
597 //
598 wxWindow::OnSysColourChanged(rEvent);
599 } // end of wxFrame::OnSysColourChanged
600
601 // Pass TRUE to show full screen, FALSE to restore.
602 bool wxFrame::ShowFullScreen(
603 bool bShow
604 , long lStyle
605 )
606 {
607 /*
608 // TODO
609 if (show)
610 {
611 if (IsFullScreen())
612 return FALSE;
613
614 m_fsIsShowing = TRUE;
615 m_fsStyle = style;
616
617 wxToolBar *theToolBar = GetToolBar();
618 wxStatusBar *theStatusBar = GetStatusBar();
619
620 int dummyWidth;
621
622 if (theToolBar)
623 theToolBar->GetSize(&dummyWidth, &m_fsToolBarHeight);
624 if (theStatusBar)
625 theStatusBar->GetSize(&dummyWidth, &m_fsStatusBarHeight);
626
627 // zap the toolbar, menubar, and statusbar
628
629 if ((style & wxFULLSCREEN_NOTOOLBAR) && theToolBar)
630 {
631 theToolBar->SetSize(-1,0);
632 theToolBar->Show(FALSE);
633 }
634
635 if (style & wxFULLSCREEN_NOMENUBAR)
636 SetMenu((HWND)GetHWND(), (HMENU) NULL);
637
638 // Save the number of fields in the statusbar
639 if ((style & wxFULLSCREEN_NOSTATUSBAR) && theStatusBar)
640 {
641 m_fsStatusBarFields = theStatusBar->GetFieldsCount();
642 SetStatusBar((wxStatusBar*) NULL);
643 delete theStatusBar;
644 }
645 else
646 m_fsStatusBarFields = 0;
647
648 // zap the frame borders
649
650 // save the 'normal' window style
651 m_fsOldWindowStyle = GetWindowLong((HWND)GetHWND(), GWL_STYLE);
652
653 // save the old position, width & height, maximize state
654 m_fsOldSize = GetRect();
655 m_fsIsMaximized = IsMaximized();
656
657 // decide which window style flags to turn off
658 LONG newStyle = m_fsOldWindowStyle;
659 LONG offFlags = 0;
660
661 if (style & wxFULLSCREEN_NOBORDER)
662 offFlags |= WS_BORDER;
663 if (style & wxFULLSCREEN_NOCAPTION)
664 offFlags |= (WS_CAPTION | WS_SYSMENU);
665
666 newStyle &= (~offFlags);
667
668 // change our window style to be compatible with full-screen mode
669 SetWindowLong((HWND)GetHWND(), GWL_STYLE, newStyle);
670
671 // resize to the size of the desktop
672 int width, height;
673
674 RECT rect;
675 ::GetWindowRect(GetDesktopWindow(), &rect);
676 width = rect.right - rect.left;
677 height = rect.bottom - rect.top;
678
679 SetSize(width, height);
680
681 // now flush the window style cache and actually go full-screen
682 SetWindowPos((HWND)GetHWND(), HWND_TOP, 0, 0, width, height, SWP_FRAMECHANGED);
683
684 wxSizeEvent event(wxSize(width, height), GetId());
685 GetEventHandler()->ProcessEvent(event);
686
687 return TRUE;
688 }
689 else
690 {
691 if (!IsFullScreen())
692 return FALSE;
693
694 m_fsIsShowing = FALSE;
695
696 wxToolBar *theToolBar = GetToolBar();
697
698 // restore the toolbar, menubar, and statusbar
699 if (theToolBar && (m_fsStyle & wxFULLSCREEN_NOTOOLBAR))
700 {
701 theToolBar->SetSize(-1, m_fsToolBarHeight);
702 theToolBar->Show(TRUE);
703 }
704
705 if ((m_fsStyle & wxFULLSCREEN_NOSTATUSBAR) && (m_fsStatusBarFields > 0))
706 {
707 CreateStatusBar(m_fsStatusBarFields);
708 PositionStatusBar();
709 }
710
711 if ((m_fsStyle & wxFULLSCREEN_NOMENUBAR) && (m_hMenu != 0))
712 SetMenu((HWND)GetHWND(), (HMENU)m_hMenu);
713
714 Maximize(m_fsIsMaximized);
715 SetWindowLong((HWND)GetHWND(),GWL_STYLE, m_fsOldWindowStyle);
716 SetWindowPos((HWND)GetHWND(),HWND_TOP,m_fsOldSize.x, m_fsOldSize.y,
717 m_fsOldSize.width, m_fsOldSize.height, SWP_FRAMECHANGED);
718
719 return TRUE;
720 }
721 */
722 return TRUE;
723 } // end of wxFrame::ShowFullScreen
724
725 //
726 // Frame window
727 //
728 bool wxFrame::OS2Create(
729 int nId
730 , wxWindow* pParent
731 , const wxChar* zWclass
732 , wxWindow* pWxWin
733 , const wxChar* zTitle
734 , int nX
735 , int nY
736 , int nWidth
737 , int nHeight
738 , long ulStyle
739 )
740 {
741 ULONG ulCreateFlags = 0L;
742 ULONG ulStyleFlags = 0L;
743 ULONG ulExtraFlags = 0L;
744 FRAMECDATA vFrameCtlData;
745 HWND hParent = NULLHANDLE;
746 HWND hClient = NULLHANDLE;
747 HWND hTitlebar = NULLHANDLE;
748 HWND hHScroll = NULLHANDLE;
749 HWND hVScroll = NULLHANDLE;
750 SWP vSwp;
751 SWP vSwpTitlebar;
752 SWP vSwpVScroll;
753 SWP vSwpHScroll;
754
755 m_hDefaultIcon = (WXHICON) (wxSTD_FRAME_ICON ? wxSTD_FRAME_ICON : wxDEFAULT_FRAME_ICON);
756 memset(&vSwp, '\0', sizeof(SWP));
757 memset(&vSwpTitlebar, '\0', sizeof(SWP));
758 memset(&vSwpVScroll, '\0', sizeof(SWP));
759 memset(&vSwpHScroll, '\0', sizeof(SWP));
760 if (pParent)
761 hParent = GetWinHwnd(pParent);
762 else
763 hParent = HWND_DESKTOP;
764
765 if (ulStyle == wxDEFAULT_FRAME_STYLE)
766 ulCreateFlags = FCF_SIZEBORDER | FCF_TITLEBAR | FCF_SYSMENU |
767 FCF_MINMAX | FCF_VERTSCROLL | FCF_HORZSCROLL | FCF_TASKLIST;
768 else
769 {
770 if ((ulStyle & wxCAPTION) == wxCAPTION)
771 ulCreateFlags = FCF_TASKLIST;
772 else
773 ulCreateFlags = FCF_NOMOVEWITHOWNER;
774
775 if (ulStyle & wxMINIMIZE_BOX)
776 ulCreateFlags |= FCF_MINBUTTON;
777 if (ulStyle & wxMAXIMIZE_BOX)
778 ulCreateFlags |= FCF_MAXBUTTON;
779 if (ulStyle & wxTHICK_FRAME)
780 ulCreateFlags |= FCF_DLGBORDER;
781 if (ulStyle & wxSYSTEM_MENU)
782 ulCreateFlags |= FCF_SYSMENU;
783 if (ulStyle & wxCAPTION)
784 ulCreateFlags |= FCF_TASKLIST;
785 if (ulStyle & wxCLIP_CHILDREN)
786 {
787 // Invalid for frame windows under PM
788 }
789
790 if (ulStyle & wxTINY_CAPTION_VERT)
791 ulCreateFlags |= FCF_TASKLIST;
792 if (ulStyle & wxTINY_CAPTION_HORIZ)
793 ulCreateFlags |= FCF_TASKLIST;
794
795 if ((ulStyle & wxTHICK_FRAME) == 0)
796 ulCreateFlags |= FCF_BORDER;
797 if (ulStyle & wxFRAME_TOOL_WINDOW)
798 ulExtraFlags = kFrameToolWindow;
799
800 if (ulStyle & wxSTAY_ON_TOP)
801 ulCreateFlags |= FCF_SYSMODAL;
802 }
803 if ((ulStyle & wxMINIMIZE) || (ulStyle & wxICONIZE))
804 ulStyleFlags |= WS_MINIMIZED;
805 if (ulStyle & wxMAXIMIZE)
806 ulStyleFlags |= WS_MAXIMIZED;
807
808 //
809 // Clear the visible flag, we always call show
810 //
811 ulStyleFlags &= (unsigned long)~WS_VISIBLE;
812 m_bIconized = FALSE;
813
814 //
815 // Set the frame control block
816 //
817 vFrameCtlData.cb = sizeof(vFrameCtlData);
818 vFrameCtlData.flCreateFlags = ulCreateFlags;
819 vFrameCtlData.hmodResources = 0L;
820 vFrameCtlData.idResources = 0;
821
822 //
823 // Create the frame window
824 //
825 if (!wxWindow::OS2Create( hParent
826 ,WC_FRAME
827 ,zTitle
828 ,ulStyleFlags
829 ,(long)nX
830 ,(long)nY
831 ,(long)nWidth
832 ,(long)nHeight
833 ,NULLHANDLE
834 ,HWND_TOP
835 ,(long)nId
836 ,(void*)&vFrameCtlData
837 ,NULL
838 ))
839 {
840 return FALSE;
841 }
842
843 //
844 // Create the client window. We must call the API from here rather than
845 // the static base class create because we need a separate handle
846 //
847 if ((hClient = ::WinCreateWindow( GetHwnd() // Frame is parent
848 ,zWclass // Custom client class
849 ,NULL // Window title
850 ,0 // No styles
851 ,0, 0, 0, 0 // Window position
852 ,NULLHANDLE // Owner
853 ,HWND_TOP // Sibling
854 ,FID_CLIENT // standard client ID
855 ,NULL // Creation data
856 ,NULL // Window Pres Params
857 )) == 0L)
858 {
859 return FALSE;
860 }
861 //
862 // Send anything to initialize the frame
863 //
864 ::WinSendMsg( GetHwnd()
865 ,WM_UPDATEFRAME
866 ,(MPARAM)FCF_TASKLIST
867 ,(MPARAM)0
868 );
869
870 //
871 // Now size everything. If adding a menu the client will need to be resized.
872 //
873 if (!::WinSetWindowPos( GetHwnd()
874 ,HWND_TOP
875 ,nX
876 ,nY
877 ,nWidth
878 ,nHeight
879 ,SWP_SIZE | SWP_MOVE | SWP_ACTIVATE
880 ))
881 return FALSE;
882
883 WinQueryWindowPos(GetHwnd(), &vSwp);
884
885 if (ulCreateFlags & FCF_TITLEBAR)
886 {
887 hTitlebar = WinWindowFromID(GetHwnd(), FID_TITLEBAR);
888 WinQueryWindowPos(hTitlebar, &vSwpTitlebar);
889 }
890 if (ulCreateFlags & FCF_HORZSCROLL)
891 {
892 hHScroll = WinWindowFromID(GetHwnd(), FID_HORZSCROLL);
893 WinQueryWindowPos(hHScroll, &vSwpHScroll);
894 }
895 if (ulCreateFlags & FCF_VERTSCROLL)
896 {
897 hVScroll = WinWindowFromID(GetHwnd(), FID_VERTSCROLL);
898 WinQueryWindowPos(hVScroll, &vSwpVScroll);
899 }
900 if (!::WinSetWindowPos( hClient
901 ,HWND_TOP
902 ,SV_CXSIZEBORDER
903 ,(SV_CYSIZEBORDER - 1) + vSwpHScroll.cy
904 ,vSwp.cx - ((SV_CXSIZEBORDER * 2) + vSwpVScroll.cx)
905 ,vSwp.cy - ((SV_CYSIZEBORDER * 2) + 1 + vSwpTitlebar.cy + vSwpHScroll.cy)
906 ,SWP_SIZE | SWP_MOVE
907 ))
908 return FALSE;
909 WinQueryWindowPos(hClient, &vSwp);
910 return TRUE;
911 } // end of wxFrame::OS2Create
912
913 //
914 // Default activation behaviour - set the focus for the first child
915 // subwindow found.
916 //
917 void wxFrame::OnActivate(
918 wxActivateEvent& rEvent
919 )
920 {
921 for (wxWindowList::Node* pNode = GetChildren().GetFirst();
922 pNode;
923 pNode = pNode->GetNext())
924 {
925 // FIXME all this is totally bogus - we need to do the same as wxPanel,
926 // but how to do it without duplicating the code?
927
928 // restore focus
929 wxWindow* pChild = pNode->GetData();
930
931 if (!pChild->IsTopLevel()
932 #if wxUSE_TOOLBAR
933 && !wxDynamicCast(pChild, wxToolBar)
934 #endif // wxUSE_TOOLBAR
935 #if wxUSE_STATUSBAR
936 && !wxDynamicCast(pChild, wxStatusBar)
937 #endif // wxUSE_STATUSBAR
938 )
939 {
940 pChild->SetFocus();
941 return;
942 }
943 }
944 } // end of wxFrame::OnActivate
945
946 // ----------------------------------------------------------------------------
947 // wxFrame size management: we exclude the areas taken by menu/status/toolbars
948 // from the client area, so the client area is what's really available for the
949 // frame contents
950 // ----------------------------------------------------------------------------
951
952 // Checks if there is a toolbar, and returns the first free client position
953 wxPoint wxFrame::GetClientAreaOrigin() const
954 {
955 wxPoint vPoint(0, 0);
956
957 if (GetToolBar())
958 {
959 int nWidth;
960 int nHeight;
961
962 GetToolBar()->GetSize( &nWidth
963 ,&nHeight
964 );
965
966 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL)
967 {
968 vPoint.x += nWidth;
969 }
970 else
971 {
972 // PM is backwards from windows
973 vPoint.y += nHeight;
974 }
975 }
976 return vPoint;
977 } // end of wxFrame::GetClientAreaOrigin
978
979 // ----------------------------------------------------------------------------
980 // tool/status bar stuff
981 // ----------------------------------------------------------------------------
982
983 #if wxUSE_TOOLBAR
984
985 wxToolBar* wxFrame::CreateToolBar(
986 long lStyle
987 , wxWindowID vId
988 , const wxString& rName
989 )
990 {
991 if (wxFrameBase::CreateToolBar( lStyle
992 ,vId
993 ,rName
994 ))
995 {
996 PositionToolBar();
997 }
998 return m_frameToolBar;
999 } // end of wxFrame::CreateToolBar
1000
1001 void wxFrame::PositionToolBar()
1002 {
1003 HWND hWndClient;
1004 RECTL vRect;
1005
1006 hWndClient = ::WinWindowFromID(GetHwnd(), FID_CLIENT);
1007 ::WinQueryWindowRect(hWndClient, &vRect);
1008
1009 #if wxUSE_STATUSBAR
1010 if (GetStatusBar())
1011 {
1012 int nStatusX;
1013 int nStatusY;
1014
1015 GetStatusBar()->GetClientSize( &nStatusX
1016 ,&nStatusY
1017 );
1018 // PM is backwards from windows
1019 vRect.yBottom += nStatusY;
1020 }
1021 #endif // wxUSE_STATUSBAR
1022
1023 if ( GetToolBar() )
1024 {
1025 int nToolbarWidth;
1026 int nToolbarHeight;
1027
1028 GetToolBar()->GetSize( &nToolbarWidth
1029 ,&nToolbarHeight
1030 );
1031
1032 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL)
1033 {
1034 nToolbarHeight = vRect.yBottom;
1035 }
1036 else
1037 {
1038 nToolbarWidth = vRect.xRight;
1039 }
1040
1041 //
1042 // Use the 'real' PM position here
1043 //
1044 GetToolBar()->SetSize( 0
1045 ,0
1046 ,nToolbarWidth
1047 ,nToolbarHeight
1048 ,wxSIZE_NO_ADJUSTMENTS
1049 );
1050 }
1051 } // end of wxFrame::PositionToolBar
1052 #endif // wxUSE_TOOLBAR
1053
1054 // ----------------------------------------------------------------------------
1055 // frame state (iconized/maximized/...)
1056 // ----------------------------------------------------------------------------
1057
1058 //
1059 // propagate our state change to all child frames: this allows us to emulate X
1060 // Windows behaviour where child frames float independently of the parent one
1061 // on the desktop, but are iconized/restored with it
1062 //
1063 void wxFrame::IconizeChildFrames(
1064 bool bIconize
1065 )
1066 {
1067 for (wxWindowList::Node* pNode = GetChildren().GetFirst();
1068 pNode;
1069 pNode = pNode->GetNext() )
1070 {
1071 wxWindow* pWin = pNode->GetData();
1072
1073 if (pWin->IsKindOf(CLASSINFO(wxFrame)) )
1074 {
1075 ((wxFrame *)pWin)->Iconize(bIconize);
1076 }
1077 }
1078 } // end of wxFrame::IconizeChildFrames
1079
1080 // ===========================================================================
1081 // message processing
1082 // ===========================================================================
1083
1084 // ---------------------------------------------------------------------------
1085 // preprocessing
1086 // ---------------------------------------------------------------------------
1087 bool wxFrame::OS2TranslateMessage(
1088 WXMSG* pMsg
1089 )
1090 {
1091 if (wxWindow::OS2TranslateMessage(pMsg))
1092 return TRUE;
1093 //
1094 // try the menu bar accels
1095 //
1096 wxMenuBar* pMenuBar = GetMenuBar();
1097
1098 if (!pMenuBar )
1099 return FALSE;
1100
1101 const wxAcceleratorTable& rAcceleratorTable = pMenuBar->GetAccelTable();
1102 return rAcceleratorTable.Translate(this, pMsg);
1103 } // end of wxFrame::OS2TranslateMessage
1104
1105 // ---------------------------------------------------------------------------
1106 // our private (non virtual) message handlers
1107 // ---------------------------------------------------------------------------
1108 bool wxFrame::HandlePaint()
1109 {
1110 RECTL vRect;
1111
1112 if (::WinQueryUpdateRect(GetHwnd(), &vRect))
1113 {
1114 if (m_bIconized)
1115 {
1116 //
1117 // Icons in PM are the same as "pointers"
1118 //
1119 HPOINTER hIcon;
1120
1121 if (m_icon.Ok())
1122 hIcon = (HPOINTER)::WinSendMsg(GetHwnd(), WM_QUERYICON, 0L, 0L);
1123 else
1124 hIcon = (HPOINTER)m_hDefaultIcon;
1125
1126 //
1127 // Hold a pointer to the dc so long as the OnPaint() message
1128 // is being processed
1129 //
1130 RECTL vRect2;
1131 HPS hPs = ::WinBeginPaint(GetHwnd(), NULLHANDLE, &vRect2);
1132
1133 //
1134 // Erase background before painting or we get white background
1135 //
1136 OS2DefWindowProc(WM_ERASEBACKGROUND, (MPARAM)hPs, (MPARAM)&vRect2);
1137
1138 if (hIcon)
1139 {
1140 HWND hWndClient;
1141 RECTL vRect3;
1142
1143 hWndClient = ::WinWindowFromID(GetHwnd(), FID_CLIENT);
1144 ::WinQueryWindowRect(hWndClient, &vRect3);
1145
1146 static const int nIconWidth = 32;
1147 static const int nIconHeight = 32;
1148 int nIconX = (int)((vRect3.xRight - nIconWidth)/2);
1149 int nIconY = (int)((vRect3.yBottom + nIconHeight)/2);
1150
1151 ::WinDrawPointer(hPs, nIconX, nIconY, hIcon, DP_NORMAL);
1152 }
1153 ::WinEndPaint(hPs);
1154 return TRUE;
1155 }
1156 else
1157 {
1158 return wxWindow::HandlePaint();
1159 }
1160 }
1161 else
1162 {
1163 // nothing to paint - processed
1164 return TRUE;
1165 }
1166 return FALSE;
1167 } // end of wxFrame::HandlePaint
1168
1169 bool wxFrame::HandleSize(
1170 int nX
1171 , int nY
1172 , WXUINT nId
1173 )
1174 {
1175 bool bProcessed = FALSE;
1176
1177 switch (nId)
1178 {
1179 case kSizeNormal:
1180 //
1181 // Only do it it if we were iconized before, otherwise resizing the
1182 // parent frame has a curious side effect of bringing it under it's
1183 // children
1184 if (!m_bIconized )
1185 break;
1186
1187 //
1188 // restore all child frames too
1189 //
1190 IconizeChildFrames(FALSE);
1191
1192 //
1193 // fall through
1194 //
1195
1196 case kSizeMax:
1197 m_bIconized = FALSE;
1198 break;
1199
1200 case kSizeMin:
1201 //
1202 // Iconize all child frames too
1203 //
1204 IconizeChildFrames(TRUE);
1205 m_bIconized = TRUE;
1206 break;
1207 }
1208
1209 if (!m_bIconized)
1210 {
1211 //
1212 // forward WM_SIZE to status bar control
1213 //
1214 #if wxUSE_NATIVE_STATUSBAR
1215 if (m_frameStatusBar && m_frameStatusBar->IsKindOf(CLASSINFO(wxStatusBar95)))
1216 {
1217 wxSizeEvent vEvent( wxSize( nX
1218 ,nY
1219 )
1220 ,m_frameStatusBar->GetId()
1221 );
1222
1223 vEvent.SetEventObject(m_frameStatusBar);
1224 m_frameStatusBar->OnSize(vEvent);
1225 }
1226 #endif // wxUSE_NATIVE_STATUSBAR
1227
1228 PositionStatusBar();
1229 PositionToolBar();
1230 wxSizeEvent vEvent( wxSize( nX
1231 ,nY
1232 )
1233 ,m_windowId
1234 );
1235
1236 vEvent.SetEventObject(this);
1237 bProcessed = GetEventHandler()->ProcessEvent(vEvent);
1238 }
1239 return bProcessed;
1240 } // end of wxFrame::HandleSize
1241
1242 bool wxFrame::HandleCommand(
1243 WXWORD nId
1244 , WXWORD nCmd
1245 , WXHWND hControl
1246 )
1247 {
1248 if (hControl)
1249 {
1250 //
1251 // In case it's e.g. a toolbar.
1252 //
1253 wxWindow* pWin = wxFindWinFromHandle(hControl);
1254
1255 if (pWin)
1256 return pWin->OS2Command( nCmd
1257 ,nId
1258 );
1259 }
1260
1261 //
1262 // Handle here commands from menus and accelerators
1263 //
1264 if (nCmd == 0 || nCmd == 1)
1265 {
1266 if (wxCurrentPopupMenu)
1267 {
1268 wxMenu* pPopupMenu = wxCurrentPopupMenu;
1269
1270 wxCurrentPopupMenu = NULL;
1271
1272 return pPopupMenu->OS2Command( nCmd
1273 ,nId
1274 );
1275 }
1276
1277 if (ProcessCommand(nId))
1278 {
1279 return TRUE;
1280 }
1281 }
1282 return FALSE;
1283 } // end of wxFrame::HandleCommand
1284
1285 bool wxFrame::HandleMenuSelect(
1286 WXWORD nItem
1287 , WXWORD nFlags
1288 , WXHMENU hMenu
1289 )
1290 {
1291 int nMenuItem;
1292
1293 if (nFlags == 0xFFFF && hMenu == 0)
1294 {
1295 //
1296 // Menu was removed from screen
1297 //
1298 nMenuItem = -1;
1299 }
1300 else if (!(nFlags & MIS_SUBMENU) && !(nFlags & MIS_SEPARATOR))
1301 {
1302 nMenuItem = nItem;
1303 }
1304 else
1305 {
1306 //
1307 // Don't give hints for separators (doesn't make sense) nor for the
1308 // items opening popup menus (they don't have them anyhow)
1309 //
1310 return FALSE;
1311 }
1312 wxMenuEvent vEvent(wxEVT_MENU_HIGHLIGHT, nMenuItem);
1313
1314 vEvent.SetEventObject(this);
1315 return GetEventHandler()->ProcessEvent(vEvent);
1316 } // end of wxFrame::HandleMenuSelect
1317
1318 // ---------------------------------------------------------------------------
1319 // the window proc for wxFrame
1320 // ---------------------------------------------------------------------------
1321
1322 MRESULT wxFrame::OS2WindowProc(
1323 WXUINT uMessage
1324 , WXWPARAM wParam
1325 , WXLPARAM lParam
1326 )
1327 {
1328 MRESULT mRc = 0L;
1329 bool bProcessed = FALSE;
1330
1331 switch (uMessage)
1332 {
1333 case WM_CLOSE:
1334 //
1335 // If we can't close, tell the system that we processed the
1336 // message - otherwise it would close us
1337 //
1338 bProcessed = !Close();
1339 break;
1340
1341 case WM_COMMAND:
1342 {
1343 WORD wId;
1344 WORD wCmd;
1345 WXHWND hWnd;
1346
1347 UnpackCommand( (WXWPARAM)wParam
1348 ,(WXLPARAM)lParam
1349 ,&wId
1350 ,&hWnd
1351 ,&wCmd
1352 );
1353 bProcessed = HandleCommand( wId
1354 ,wCmd
1355 ,(WXHWND)hWnd
1356 );
1357 }
1358 break;
1359
1360 case WM_MENUSELECT:
1361 {
1362 WXWORD wItem;
1363 WXWORD wFlags;
1364 WXHMENU hMenu;
1365
1366 UnpackMenuSelect( wParam
1367 ,lParam
1368 ,&wItem
1369 ,&wFlags
1370 ,&hMenu
1371 );
1372 bProcessed = HandleMenuSelect( wItem
1373 ,wFlags
1374 ,hMenu
1375 );
1376 }
1377 break;
1378
1379 case WM_PAINT:
1380 bProcessed = HandlePaint();
1381 break;
1382
1383 case CM_QUERYDRAGIMAGE:
1384 {
1385 HPOINTER hIcon;
1386
1387 if (m_icon.Ok())
1388 hIcon = (HPOINTER)::WinSendMsg(GetHwnd(), WM_QUERYICON, 0L, 0L);
1389 else
1390 hIcon = (HPOINTER)m_hDefaultIcon;
1391 mRc = (MRESULT)hIcon;
1392 bProcessed = mRc != 0;
1393 }
1394 break;
1395
1396 case WM_SIZE:
1397 bProcessed = HandleSize(LOWORD(lParam), HIWORD(lParam), (WXUINT)wParam);
1398 break;
1399 }
1400
1401 if (!bProcessed )
1402 mRc = wxWindow::OS2WindowProc( uMessage
1403 ,wParam
1404 ,lParam
1405 );
1406 return (MRESULT)0;
1407 } // wxFrame::OS2WindowProc
1408