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