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