more minimal stuff
[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 nShowCmd
343 )
344 {
345 ::WinShowWindow(GetHwnd(), nShowCmd);
346 m_bIconized = nShowCmd == SWP_MINIMIZE;
347 } // end of wxFrame::DoShowWindow
348
349 bool wxFrame::Show(
350 bool bShow
351 )
352 {
353 DoShowWindow(bShow ? SWP_SHOW : SWP_HIDE);
354
355 if (bShow)
356 {
357 wxActivateEvent vEvent(wxEVT_ACTIVATE, TRUE, m_windowId);
358
359 ::WinSetWindowPos( (HWND) GetHWND()
360 ,HWND_TOP
361 ,0
362 ,0
363 ,0
364 ,0
365 ,SWP_ZORDER
366 );
367 vEvent.SetEventObject(this);
368 GetEventHandler()->ProcessEvent(vEvent);
369 }
370 else
371 {
372 //
373 // Try to highlight the correct window (the parent)
374 //
375 if (GetParent())
376 {
377 HWND hWndParent = GetHwndOf(GetParent());
378
379 if (hWndParent)
380 ::WinSetWindowPos( hWndParent
381 ,HWND_TOP
382 ,0
383 ,0
384 ,0
385 ,0
386 ,SWP_ZORDER
387 );
388 }
389 }
390 return TRUE;
391 } // end of wxFrame::Show
392
393 void wxFrame::Iconize(
394 bool bIconize
395 )
396 {
397 DoShowWindow(bIconize ? SWP_MINIMIZE : SWP_RESTORE);
398 } // end of wxFrame::Iconize
399
400 void wxFrame::Maximize(
401 bool bMaximize)
402 {
403 DoShowWindow(bMaximize ? SWP_MAXIMIZE : SWP_RESTORE);
404 } // end of wxFrame::Maximize
405
406 void wxFrame::Restore()
407 {
408 DoShowWindow(SWP_RESTORE);
409 } // end of wxFrame::Restore
410
411 bool wxFrame::IsIconized() const
412 {
413 SWP vSwp;
414 bool bIconic;
415
416 ::WinQueryWindowPos(GetHwnd(), &vSwp);
417
418 if (vSwp.fl & SWP_MINIMIZE)
419 ((wxFrame*)this)->m_bIconized = TRUE;
420 else
421 ((wxFrame*)this)->m_bIconized = FALSE;
422 return m_bIconized;
423 } // end of wxFrame::IsIconized
424
425 // Is it maximized?
426 bool wxFrame::IsMaximized() const
427 {
428 SWP vSwp;
429 bool bIconic;
430
431 ::WinQueryWindowPos(GetHwnd(), &vSwp);
432 return (vSwp.fl & SWP_MAXIMIZE);
433 } // end of wxFrame::IsMaximized
434
435 void wxFrame::SetIcon(
436 const wxIcon& rIcon
437 )
438 {
439 wxFrameBase::SetIcon(rIcon);
440
441 if (m_icon.Ok())
442 {
443 ::WinSendMsg( GetHwnd()
444 ,WM_SETICON
445 ,(MPARAM)((HICON)m_icon.GetHICON())
446 ,NULL
447 );
448 ::WinSendMsg( GetHwnd()
449 ,WM_UPDATEFRAME
450 ,(MPARAM)FCF_ICON
451 ,(MPARAM)0
452 );
453 }
454 } // end of wxFrame::SetIcon
455
456 #if wxUSE_STATUSBAR
457 wxStatusBar* wxFrame::OnCreateStatusBar(
458 int nNumber
459 , long lulStyle
460 , wxWindowID vId
461 , const wxString& rName
462 )
463 {
464 wxStatusBar* pStatusBar = NULL;
465
466 pStatusBar = wxFrameBase::OnCreateStatusBar( nNumber
467 ,lulStyle
468 ,vId
469 ,rName
470 );
471 return pStatusBar;
472 } // end of wxFrame::OnCreateStatusBar
473
474 void wxFrame::PositionStatusBar()
475 {
476 //
477 // Native status bar positions itself
478 //
479 if (m_frameStatusBar)
480 {
481 int nWidth;
482 int nHeight;
483 int nStatbarWidth;
484 int nStatbarHeight;
485 HWND hWndClient;
486 RECTL vRect;
487
488 hWndClient = ::WinWindowFromID(GetHwnd(), FID_CLIENT);
489 ::WinQueryWindowRect(hWndClient, &vRect);
490 nWidth = vRect.xRight - vRect.xLeft;
491 nHeight = vRect.yTop - vRect.yBottom;
492
493 m_frameStatusBar->GetSize( &nStatbarWidth
494 ,&nStatbarHeight
495 );
496
497 //
498 // Since we wish the status bar to be directly under the client area,
499 // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.
500 //
501 m_frameStatusBar->SetSize( 0
502 ,nHeight
503 ,nWidth
504 ,nStatbarHeight
505 );
506 }
507 } // end of wxFrame::PositionStatusBar
508 #endif // wxUSE_STATUSBAR
509
510 void wxFrame::DetachMenuBar()
511 {
512 if (m_frameMenuBar)
513 {
514 m_frameMenuBar->Detach();
515 m_frameMenuBar = NULL;
516 }
517 } // end of wxFrame::DetachMenuBar
518
519 void wxFrame::SetMenuBar(
520 wxMenuBar* pMenuBar
521 )
522 {
523 if (!pMenuBar)
524 {
525 DetachMenuBar();
526 return;
527 }
528
529 m_frameMenuBar = NULL;
530
531 // Can set a menubar several times.
532 // TODO: how to prevent a memory leak if you have a currently-unattached
533 // menubar? wxWindows assumes that the frame will delete the menu (otherwise
534 // there are problems for MDI).
535 if (pMenuBar->GetHMenu())
536 {
537 m_hMenu = pMenuBar->GetHMenu();
538 }
539 else
540 {
541 pMenuBar->Detach();
542
543 m_hMenu = pMenuBar->Create();
544
545 if (!m_hMenu)
546 return;
547 }
548
549 InternalSetMenuBar();
550
551 m_frameMenuBar = pMenuBar;
552 pMenuBar->Attach(this);
553 } // end of wxFrame::SetMenuBar
554
555 void wxFrame::InternalSetMenuBar()
556 {
557 WinSendMsg((HWND)GetHwnd(), WM_UPDATEFRAME, (MPARAM)FCF_MENU, (MPARAM)0);
558 } // end of wxFrame::InternalSetMenuBar
559
560 //
561 // Responds to colour changes, and passes event on to children
562 //
563 void wxFrame::OnSysColourChanged(
564 wxSysColourChangedEvent& rEvent
565 )
566 {
567 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE));
568 Refresh();
569
570 if (m_frameStatusBar)
571 {
572 wxSysColourChangedEvent vEvent2;
573
574 vEvent2.SetEventObject(m_frameStatusBar);
575 m_frameStatusBar->GetEventHandler()->ProcessEvent(vEvent2);
576 }
577
578 //
579 // Propagate the event to the non-top-level children
580 //
581 wxWindow::OnSysColourChanged(rEvent);
582 } // end of wxFrame::OnSysColourChanged
583
584 // Pass TRUE to show full screen, FALSE to restore.
585 bool wxFrame::ShowFullScreen(
586 bool bShow
587 , long lStyle
588 )
589 {
590 /*
591 // TODO
592 if (show)
593 {
594 if (IsFullScreen())
595 return FALSE;
596
597 m_fsIsShowing = TRUE;
598 m_fsStyle = style;
599
600 wxToolBar *theToolBar = GetToolBar();
601 wxStatusBar *theStatusBar = GetStatusBar();
602
603 int dummyWidth;
604
605 if (theToolBar)
606 theToolBar->GetSize(&dummyWidth, &m_fsToolBarHeight);
607 if (theStatusBar)
608 theStatusBar->GetSize(&dummyWidth, &m_fsStatusBarHeight);
609
610 // zap the toolbar, menubar, and statusbar
611
612 if ((style & wxFULLSCREEN_NOTOOLBAR) && theToolBar)
613 {
614 theToolBar->SetSize(-1,0);
615 theToolBar->Show(FALSE);
616 }
617
618 if (style & wxFULLSCREEN_NOMENUBAR)
619 SetMenu((HWND)GetHWND(), (HMENU) NULL);
620
621 // Save the number of fields in the statusbar
622 if ((style & wxFULLSCREEN_NOSTATUSBAR) && theStatusBar)
623 {
624 m_fsStatusBarFields = theStatusBar->GetFieldsCount();
625 SetStatusBar((wxStatusBar*) NULL);
626 delete theStatusBar;
627 }
628 else
629 m_fsStatusBarFields = 0;
630
631 // zap the frame borders
632
633 // save the 'normal' window style
634 m_fsOldWindowStyle = GetWindowLong((HWND)GetHWND(), GWL_STYLE);
635
636 // save the old position, width & height, maximize state
637 m_fsOldSize = GetRect();
638 m_fsIsMaximized = IsMaximized();
639
640 // decide which window style flags to turn off
641 LONG newStyle = m_fsOldWindowStyle;
642 LONG offFlags = 0;
643
644 if (style & wxFULLSCREEN_NOBORDER)
645 offFlags |= WS_BORDER;
646 if (style & wxFULLSCREEN_NOCAPTION)
647 offFlags |= (WS_CAPTION | WS_SYSMENU);
648
649 newStyle &= (~offFlags);
650
651 // change our window style to be compatible with full-screen mode
652 SetWindowLong((HWND)GetHWND(), GWL_STYLE, newStyle);
653
654 // resize to the size of the desktop
655 int width, height;
656
657 RECT rect;
658 ::GetWindowRect(GetDesktopWindow(), &rect);
659 width = rect.right - rect.left;
660 height = rect.bottom - rect.top;
661
662 SetSize(width, height);
663
664 // now flush the window style cache and actually go full-screen
665 SetWindowPos((HWND)GetHWND(), HWND_TOP, 0, 0, width, height, SWP_FRAMECHANGED);
666
667 wxSizeEvent event(wxSize(width, height), GetId());
668 GetEventHandler()->ProcessEvent(event);
669
670 return TRUE;
671 }
672 else
673 {
674 if (!IsFullScreen())
675 return FALSE;
676
677 m_fsIsShowing = FALSE;
678
679 wxToolBar *theToolBar = GetToolBar();
680
681 // restore the toolbar, menubar, and statusbar
682 if (theToolBar && (m_fsStyle & wxFULLSCREEN_NOTOOLBAR))
683 {
684 theToolBar->SetSize(-1, m_fsToolBarHeight);
685 theToolBar->Show(TRUE);
686 }
687
688 if ((m_fsStyle & wxFULLSCREEN_NOSTATUSBAR) && (m_fsStatusBarFields > 0))
689 {
690 CreateStatusBar(m_fsStatusBarFields);
691 PositionStatusBar();
692 }
693
694 if ((m_fsStyle & wxFULLSCREEN_NOMENUBAR) && (m_hMenu != 0))
695 SetMenu((HWND)GetHWND(), (HMENU)m_hMenu);
696
697 Maximize(m_fsIsMaximized);
698 SetWindowLong((HWND)GetHWND(),GWL_STYLE, m_fsOldWindowStyle);
699 SetWindowPos((HWND)GetHWND(),HWND_TOP,m_fsOldSize.x, m_fsOldSize.y,
700 m_fsOldSize.width, m_fsOldSize.height, SWP_FRAMECHANGED);
701
702 return TRUE;
703 }
704 */
705 return TRUE;
706 } // end of wxFrame::ShowFullScreen
707
708 //
709 // Frame window
710 //
711 bool wxFrame::OS2Create(
712 int nId
713 , wxWindow* pParent
714 , const wxChar* zWclass
715 , wxWindow* pWxWin
716 , const wxChar* zTitle
717 , int nX
718 , int nY
719 , int nWidth
720 , int nHeight
721 , long ulStyle
722 )
723 {
724 ULONG ulCreateFlags = 0L;
725 ULONG ulStyleFlags = 0L;
726 ULONG ulExtraFlags = 0L;
727 FRAMECDATA vFrameCtlData;
728 HWND hParent = NULLHANDLE;
729 HWND hClient = NULLHANDLE;
730 HWND hTitlebar = NULLHANDLE;
731 HWND hHScroll = NULLHANDLE;
732 HWND hVScroll = NULLHANDLE;
733 SWP vSwp;
734 SWP vSwpTitlebar;
735 SWP vSwpVScroll;
736 SWP vSwpHScroll;
737
738 m_hDefaultIcon = (WXHICON) (wxSTD_FRAME_ICON ? wxSTD_FRAME_ICON : wxDEFAULT_FRAME_ICON);
739 memset(&vSwp, '\0', sizeof(SWP));
740 memset(&vSwpTitlebar, '\0', sizeof(SWP));
741 memset(&vSwpVScroll, '\0', sizeof(SWP));
742 memset(&vSwpHScroll, '\0', sizeof(SWP));
743 if (pParent)
744 hParent = GetWinHwnd(pParent);
745 else
746 hParent = HWND_DESKTOP;
747
748 if (ulStyle == wxDEFAULT_FRAME_STYLE)
749 ulCreateFlags = FCF_SIZEBORDER | FCF_TITLEBAR | FCF_SYSMENU |
750 FCF_MINMAX | FCF_VERTSCROLL | FCF_HORZSCROLL | FCF_TASKLIST;
751 else
752 {
753 if ((ulStyle & wxCAPTION) == wxCAPTION)
754 ulCreateFlags = FCF_TASKLIST;
755 else
756 ulCreateFlags = FCF_NOMOVEWITHOWNER;
757
758 if (ulStyle & wxMINIMIZE_BOX)
759 ulCreateFlags |= FCF_MINBUTTON;
760 if (ulStyle & wxMAXIMIZE_BOX)
761 ulCreateFlags |= FCF_MAXBUTTON;
762 if (ulStyle & wxTHICK_FRAME)
763 ulCreateFlags |= FCF_DLGBORDER;
764 if (ulStyle & wxSYSTEM_MENU)
765 ulCreateFlags |= FCF_SYSMENU;
766 if (ulStyle & wxCAPTION)
767 ulCreateFlags |= FCF_TASKLIST;
768 if (ulStyle & wxCLIP_CHILDREN)
769 {
770 // Invalid for frame windows under PM
771 }
772
773 if (ulStyle & wxTINY_CAPTION_VERT)
774 ulCreateFlags |= FCF_TASKLIST;
775 if (ulStyle & wxTINY_CAPTION_HORIZ)
776 ulCreateFlags |= FCF_TASKLIST;
777
778 if ((ulStyle & wxTHICK_FRAME) == 0)
779 ulCreateFlags |= FCF_BORDER;
780 if (ulStyle & wxFRAME_TOOL_WINDOW)
781 ulExtraFlags = kFrameToolWindow;
782
783 if (ulStyle & wxSTAY_ON_TOP)
784 ulCreateFlags |= FCF_SYSMODAL;
785 }
786 if ((ulStyle & wxMINIMIZE) || (ulStyle & wxICONIZE))
787 ulStyleFlags |= WS_MINIMIZED;
788 if (ulStyle & wxMAXIMIZE)
789 ulStyleFlags |= WS_MAXIMIZED;
790
791 //
792 // Clear the visible flag, we always call show
793 //
794 ulStyleFlags &= (unsigned long)~WS_VISIBLE;
795 m_bIconized = FALSE;
796
797 //
798 // Set the frame control block
799 //
800 vFrameCtlData.cb = sizeof(vFrameCtlData);
801 vFrameCtlData.flCreateFlags = ulCreateFlags;
802 vFrameCtlData.hmodResources = 0L;
803 vFrameCtlData.idResources = 0;
804
805 //
806 // Create the frame window
807 //
808 if (!wxWindow::OS2Create( hParent
809 ,WC_FRAME
810 ,zTitle
811 ,ulStyleFlags
812 ,(long)nX
813 ,(long)nY
814 ,(long)nWidth
815 ,(long)nHeight
816 ,NULLHANDLE
817 ,HWND_TOP
818 ,(long)nId
819 ,(void*)&vFrameCtlData
820 ,NULL
821 ))
822 {
823 return FALSE;
824 }
825
826 //
827 // Create the client window. We must call the API from here rather than
828 // the static base class create because we need a separate handle
829 //
830 if ((hClient = ::WinCreateWindow( GetHwnd() // Frame is parent
831 ,zWclass // Custom client class
832 ,NULL // Window title
833 ,0 // No styles
834 ,0, 0, 0, 0 // Window position
835 ,NULLHANDLE // Owner
836 ,HWND_TOP // Sibling
837 ,FID_CLIENT // standard client ID
838 ,NULL // Creation data
839 ,NULL // Window Pres Params
840 )) == 0L)
841 {
842 return FALSE;
843 }
844
845 //
846 // Now size everything. If adding a menu the client will need to be resized.
847 //
848 if (!::WinSetWindowPos( GetHwnd()
849 ,HWND_TOP
850 ,nX
851 ,nY
852 ,nWidth
853 ,nHeight
854 ,SWP_SIZE | SWP_MOVE | SWP_ACTIVATE
855 ))
856 return FALSE;
857
858 WinQueryWindowPos(GetHwnd(), &vSwp);
859
860 if (ulCreateFlags & FCF_TITLEBAR)
861 {
862 hTitlebar = WinWindowFromID(GetHwnd(), FID_TITLEBAR);
863 WinQueryWindowPos(hTitlebar, &vSwpTitlebar);
864 }
865 if (ulCreateFlags & FCF_HORZSCROLL)
866 {
867 hHScroll = WinWindowFromID(GetHwnd(), FID_HORZSCROLL);
868 WinQueryWindowPos(hHScroll, &vSwpHScroll);
869 }
870 if (ulCreateFlags & FCF_VERTSCROLL)
871 {
872 hVScroll = WinWindowFromID(GetHwnd(), FID_VERTSCROLL);
873 WinQueryWindowPos(hVScroll, &vSwpVScroll);
874 }
875 if (!::WinSetWindowPos( hClient
876 ,HWND_TOP
877 ,SV_CXSIZEBORDER
878 ,(SV_CYSIZEBORDER - 1) + vSwpHScroll.cy
879 ,vSwp.cx - ((SV_CXSIZEBORDER * 2) + vSwpVScroll.cx)
880 ,vSwp.cy - ((SV_CYSIZEBORDER * 2) + 1 + vSwpTitlebar.cy + vSwpHScroll.cy)
881 ,SWP_SIZE | SWP_MOVE
882 ))
883 return FALSE;
884 return TRUE;
885 } // end of wxFrame::OS2Create
886
887 //
888 // Default activation behaviour - set the focus for the first child
889 // subwindow found.
890 //
891 void wxFrame::OnActivate(
892 wxActivateEvent& rEvent
893 )
894 {
895 for (wxWindowList::Node* pNode = GetChildren().GetFirst();
896 pNode;
897 pNode = pNode->GetNext())
898 {
899 // FIXME all this is totally bogus - we need to do the same as wxPanel,
900 // but how to do it without duplicating the code?
901
902 // restore focus
903 wxWindow* pChild = pNode->GetData();
904
905 if (!pChild->IsTopLevel()
906 #if wxUSE_TOOLBAR
907 && !wxDynamicCast(pChild, wxToolBar)
908 #endif // wxUSE_TOOLBAR
909 #if wxUSE_STATUSBAR
910 && !wxDynamicCast(pChild, wxStatusBar)
911 #endif // wxUSE_STATUSBAR
912 )
913 {
914 pChild->SetFocus();
915 return;
916 }
917 }
918 } // end of wxFrame::OnActivate
919
920 // ----------------------------------------------------------------------------
921 // wxFrame size management: we exclude the areas taken by menu/status/toolbars
922 // from the client area, so the client area is what's really available for the
923 // frame contents
924 // ----------------------------------------------------------------------------
925
926 // Checks if there is a toolbar, and returns the first free client position
927 wxPoint wxFrame::GetClientAreaOrigin() const
928 {
929 wxPoint vPoint(0, 0);
930
931 if (GetToolBar())
932 {
933 int nWidth;
934 int nHeight;
935
936 GetToolBar()->GetSize( &nWidth
937 ,&nHeight
938 );
939
940 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL)
941 {
942 vPoint.x += nWidth;
943 }
944 else
945 {
946 // PM is backwards from windows
947 vPoint.y += nHeight;
948 }
949 }
950 return vPoint;
951 } // end of wxFrame::GetClientAreaOrigin
952
953 // ----------------------------------------------------------------------------
954 // tool/status bar stuff
955 // ----------------------------------------------------------------------------
956
957 #if wxUSE_TOOLBAR
958
959 wxToolBar* wxFrame::CreateToolBar(
960 long lStyle
961 , wxWindowID vId
962 , const wxString& rName
963 )
964 {
965 if (wxFrameBase::CreateToolBar( lStyle
966 ,vId
967 ,rName
968 ))
969 {
970 PositionToolBar();
971 }
972 return m_frameToolBar;
973 } // end of wxFrame::CreateToolBar
974
975 void wxFrame::PositionToolBar()
976 {
977 HWND hWndClient;
978 RECTL vRect;
979
980 hWndClient = ::WinWindowFromID(GetHwnd(), FID_CLIENT);
981 ::WinQueryWindowRect(hWndClient, &vRect);
982
983 #if wxUSE_STATUSBAR
984 if (GetStatusBar())
985 {
986 int nStatusX;
987 int nStatusY;
988
989 GetStatusBar()->GetClientSize( &nStatusX
990 ,&nStatusY
991 );
992 // PM is backwards from windows
993 vRect.yBottom += nStatusY;
994 }
995 #endif // wxUSE_STATUSBAR
996
997 if ( GetToolBar() )
998 {
999 int nToolbarWidth;
1000 int nToolbarHeight;
1001
1002 GetToolBar()->GetSize( &nToolbarWidth
1003 ,&nToolbarHeight
1004 );
1005
1006 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL)
1007 {
1008 nToolbarHeight = vRect.yBottom;
1009 }
1010 else
1011 {
1012 nToolbarWidth = vRect.xRight;
1013 }
1014
1015 //
1016 // Use the 'real' PM position here
1017 //
1018 GetToolBar()->SetSize( 0
1019 ,0
1020 ,nToolbarWidth
1021 ,nToolbarHeight
1022 ,wxSIZE_NO_ADJUSTMENTS
1023 );
1024 }
1025 } // end of wxFrame::PositionToolBar
1026 #endif // wxUSE_TOOLBAR
1027
1028 // ----------------------------------------------------------------------------
1029 // frame state (iconized/maximized/...)
1030 // ----------------------------------------------------------------------------
1031
1032 //
1033 // propagate our state change to all child frames: this allows us to emulate X
1034 // Windows behaviour where child frames float independently of the parent one
1035 // on the desktop, but are iconized/restored with it
1036 //
1037 void wxFrame::IconizeChildFrames(
1038 bool bIconize
1039 )
1040 {
1041 for (wxWindowList::Node* pNode = GetChildren().GetFirst();
1042 pNode;
1043 pNode = pNode->GetNext() )
1044 {
1045 wxWindow* pWin = pNode->GetData();
1046
1047 if (pWin->IsKindOf(CLASSINFO(wxFrame)) )
1048 {
1049 ((wxFrame *)pWin)->Iconize(bIconize);
1050 }
1051 }
1052 } // end of wxFrame::IconizeChildFrames
1053
1054 // ===========================================================================
1055 // message processing
1056 // ===========================================================================
1057
1058 // ---------------------------------------------------------------------------
1059 // preprocessing
1060 // ---------------------------------------------------------------------------
1061 bool wxFrame::OS2TranslateMessage(
1062 WXMSG* pMsg
1063 )
1064 {
1065 if (wxWindow::OS2TranslateMessage(pMsg))
1066 return TRUE;
1067 //
1068 // try the menu bar accels
1069 //
1070 wxMenuBar* pMenuBar = GetMenuBar();
1071
1072 if (!pMenuBar )
1073 return FALSE;
1074
1075 const wxAcceleratorTable& rAcceleratorTable = pMenuBar->GetAccelTable();
1076 return rAcceleratorTable.Translate(this, pMsg);
1077 } // end of wxFrame::OS2TranslateMessage
1078
1079 // ---------------------------------------------------------------------------
1080 // our private (non virtual) message handlers
1081 // ---------------------------------------------------------------------------
1082 bool wxFrame::HandlePaint()
1083 {
1084 RECTL vRect;
1085
1086 if (::WinQueryUpdateRect(GetHwnd(), &vRect))
1087 {
1088 if (m_bIconized)
1089 {
1090 //
1091 // Icons in PM are the same as "pointers"
1092 //
1093 HPOINTER hIcon;
1094
1095 if (m_icon.Ok())
1096 hIcon = (HPOINTER)::WinSendMsg(GetHwnd(), WM_QUERYICON, 0L, 0L);
1097 else
1098 hIcon = (HPOINTER)m_hDefaultIcon;
1099
1100 //
1101 // Hold a pointer to the dc so long as the OnPaint() message
1102 // is being processed
1103 //
1104 RECTL vRect2;
1105 HPS hPs = ::WinBeginPaint(GetHwnd(), NULLHANDLE, &vRect2);
1106
1107 //
1108 // Erase background before painting or we get white background
1109 //
1110 OS2DefWindowProc(WM_ERASEBACKGROUND, (MPARAM)hPs, (MPARAM)&vRect2);
1111
1112 if (hIcon)
1113 {
1114 HWND hWndClient;
1115 RECTL vRect3;
1116
1117 hWndClient = ::WinWindowFromID(GetHwnd(), FID_CLIENT);
1118 ::WinQueryWindowRect(hWndClient, &vRect3);
1119
1120 static const int nIconWidth = 32;
1121 static const int nIconHeight = 32;
1122 int nIconX = (int)((vRect3.xRight - nIconWidth)/2);
1123 int nIconY = (int)((vRect3.yBottom + nIconHeight)/2);
1124
1125 ::WinDrawPointer(hPs, nIconX, nIconY, hIcon, DP_NORMAL);
1126 }
1127 ::WinEndPaint(hPs);
1128 return TRUE;
1129 }
1130 else
1131 {
1132 return wxWindow::HandlePaint();
1133 }
1134 }
1135 else
1136 {
1137 // nothing to paint - processed
1138 return TRUE;
1139 }
1140 return FALSE;
1141 } // end of wxFrame::HandlePaint
1142
1143 bool wxFrame::HandleSize(
1144 int nX
1145 , int nY
1146 , WXUINT nId
1147 )
1148 {
1149 bool bProcessed = FALSE;
1150
1151 switch (nId)
1152 {
1153 case kSizeNormal:
1154 //
1155 // Only do it it if we were iconized before, otherwise resizing the
1156 // parent frame has a curious side effect of bringing it under it's
1157 // children
1158 if (!m_bIconized )
1159 break;
1160
1161 //
1162 // restore all child frames too
1163 //
1164 IconizeChildFrames(FALSE);
1165
1166 //
1167 // fall through
1168 //
1169
1170 case kSizeMax:
1171 m_bIconized = FALSE;
1172 break;
1173
1174 case kSizeMin:
1175 //
1176 // Iconize all child frames too
1177 //
1178 IconizeChildFrames(TRUE);
1179 m_bIconized = TRUE;
1180 break;
1181 }
1182
1183 if (!m_bIconized)
1184 {
1185 //
1186 // forward WM_SIZE to status bar control
1187 //
1188 #if wxUSE_NATIVE_STATUSBAR
1189 if (m_frameStatusBar && m_frameStatusBar->IsKindOf(CLASSINFO(wxStatusBar95)))
1190 {
1191 wxSizeEvent vEvent( wxSize( nX
1192 ,nY
1193 )
1194 ,m_frameStatusBar->GetId()
1195 );
1196
1197 vEvent.SetEventObject(m_frameStatusBar);
1198 m_frameStatusBar->OnSize(vEvent);
1199 }
1200 #endif // wxUSE_NATIVE_STATUSBAR
1201
1202 PositionStatusBar();
1203 PositionToolBar();
1204 wxSizeEvent vEvent( wxSize( nX
1205 ,nY
1206 )
1207 ,m_windowId
1208 );
1209
1210 vEvent.SetEventObject(this);
1211 bProcessed = GetEventHandler()->ProcessEvent(vEvent);
1212 }
1213 return bProcessed;
1214 } // end of wxFrame::HandleSize
1215
1216 bool wxFrame::HandleCommand(
1217 WXWORD nId
1218 , WXWORD nCmd
1219 , WXHWND hControl
1220 )
1221 {
1222 if (hControl)
1223 {
1224 //
1225 // In case it's e.g. a toolbar.
1226 //
1227 wxWindow* pWin = wxFindWinFromHandle(hControl);
1228
1229 if (pWin)
1230 return pWin->OS2Command( nCmd
1231 ,nId
1232 );
1233 }
1234
1235 //
1236 // Handle here commands from menus and accelerators
1237 //
1238 if (nCmd == 0 || nCmd == 1)
1239 {
1240 if (wxCurrentPopupMenu)
1241 {
1242 wxMenu* pPopupMenu = wxCurrentPopupMenu;
1243
1244 wxCurrentPopupMenu = NULL;
1245
1246 return pPopupMenu->OS2Command( nCmd
1247 ,nId
1248 );
1249 }
1250
1251 if (ProcessCommand(nId))
1252 {
1253 return TRUE;
1254 }
1255 }
1256 return FALSE;
1257 } // end of wxFrame::HandleCommand
1258
1259 bool wxFrame::HandleMenuSelect(
1260 WXWORD nItem
1261 , WXWORD nFlags
1262 , WXHMENU hMenu
1263 )
1264 {
1265 int nMenuItem;
1266
1267 if (nFlags == 0xFFFF && hMenu == 0)
1268 {
1269 //
1270 // Menu was removed from screen
1271 //
1272 nMenuItem = -1;
1273 }
1274 else if (!(nFlags & MIS_SUBMENU) && !(nFlags & MIS_SEPARATOR))
1275 {
1276 nMenuItem = nItem;
1277 }
1278 else
1279 {
1280 //
1281 // Don't give hints for separators (doesn't make sense) nor for the
1282 // items opening popup menus (they don't have them anyhow)
1283 //
1284 return FALSE;
1285 }
1286 wxMenuEvent vEvent(wxEVT_MENU_HIGHLIGHT, nMenuItem);
1287
1288 vEvent.SetEventObject(this);
1289 return GetEventHandler()->ProcessEvent(vEvent);
1290 } // end of wxFrame::HandleMenuSelect
1291
1292 // ---------------------------------------------------------------------------
1293 // the window proc for wxFrame
1294 // ---------------------------------------------------------------------------
1295
1296 MRESULT wxFrame::OS2WindowProc(
1297 WXUINT uMessage
1298 , WXWPARAM wParam
1299 , WXLPARAM lParam
1300 )
1301 {
1302 MRESULT mRc = 0L;
1303 bool bProcessed = FALSE;
1304
1305 switch (uMessage)
1306 {
1307 case WM_CLOSE:
1308 //
1309 // If we can't close, tell the system that we processed the
1310 // message - otherwise it would close us
1311 //
1312 bProcessed = !Close();
1313 break;
1314
1315 case WM_COMMAND:
1316 {
1317 WORD wId;
1318 WORD wCmd;
1319 WXHWND hWnd;
1320
1321 UnpackCommand( (WXWPARAM)wParam
1322 ,(WXLPARAM)lParam
1323 ,&wId
1324 ,&hWnd
1325 ,&wCmd
1326 );
1327 bProcessed = HandleCommand( wId
1328 ,wCmd
1329 ,(WXHWND)hWnd
1330 );
1331 }
1332 break;
1333
1334 case WM_MENUSELECT:
1335 {
1336 WXWORD wItem;
1337 WXWORD wFlags;
1338 WXHMENU hMenu;
1339
1340 UnpackMenuSelect( wParam
1341 ,lParam
1342 ,&wItem
1343 ,&wFlags
1344 ,&hMenu
1345 );
1346 bProcessed = HandleMenuSelect( wItem
1347 ,wFlags
1348 ,hMenu
1349 );
1350 }
1351 break;
1352
1353 case WM_PAINT:
1354 bProcessed = HandlePaint();
1355 break;
1356
1357 case CM_QUERYDRAGIMAGE:
1358 {
1359 HPOINTER hIcon;
1360
1361 if (m_icon.Ok())
1362 hIcon = (HPOINTER)::WinSendMsg(GetHwnd(), WM_QUERYICON, 0L, 0L);
1363 else
1364 hIcon = (HPOINTER)m_hDefaultIcon;
1365 mRc = (MRESULT)hIcon;
1366 bProcessed = mRc != 0;
1367 }
1368 break;
1369
1370 case WM_SIZE:
1371 bProcessed = HandleSize(LOWORD(lParam), HIWORD(lParam), (WXUINT)wParam);
1372 break;
1373 }
1374
1375 if (!bProcessed )
1376 mRc = wxWindow::OS2WindowProc( uMessage
1377 ,wParam
1378 ,lParam
1379 );
1380 return (MRESULT)0;
1381 } // wxFrame::OS2WindowProc
1382