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