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