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