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