]> git.saurik.com Git - wxWidgets.git/blame - src/os2/frame.cpp
wxImage::Rotate corrections added; docview improvements (menus updated properly)
[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// ----------------------------------------------------------------------------
0e320a79 67
f38374d0
DW
68#if wxUSE_NATIVE_STATUSBAR
69 bool wxFrame::m_useNativeStatusBar = TRUE;
70#else
71 bool wxFrame::m_useNativeStatusBar = FALSE;
72#endif
0e320a79 73
f38374d0
DW
74// ----------------------------------------------------------------------------
75// creation/destruction
76// ----------------------------------------------------------------------------
77
78void wxFrame::Init()
0e320a79 79{
80d83cbc 80 m_bIconized = FALSE;
f38374d0 81
21802234 82#if wxUSE_TOOLTIPS
80d83cbc 83 m_hHwndToolTip = 0;
21802234 84#endif
ea51d98d
DW
85 // Data to save/restore when calling ShowFullScreen
86 m_lFsStyle = 0L;
87 m_lFsOldWindowStyle = 0L;
88 m_nFsStatusBarFields = 0;
89 m_nFsStatusBarHeight = 0;
90 m_nFsToolBarHeight = 0;
91 m_bFsIsMaximized = FALSE;
92 m_bFsIsShowing = FALSE;
93} // end of wxFrame::Init
94
95bool wxFrame::Create(
96 wxWindow* pParent
97, wxWindowID vId
98, const wxString& rsTitle
99, const wxPoint& rPos
100, const wxSize& rSize
101, long lStyle
102, const wxString& rsName
103)
f38374d0 104{
ea51d98d
DW
105 int nX = rPos.x;
106 int nY = rPos.y;
107 int nWidth = rSize.x;
108 int nHeight = rSize.y;
ea51d98d
DW
109
110 SetName(rsName);
111 m_windowStyle = lStyle;
112 m_frameMenuBar = NULL;
113 m_frameToolBar = NULL;
114 m_frameStatusBar = NULL;
115
116 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE));
117
118 if (vId > -1 )
119 m_windowId = vId;
120 else
121 m_windowId = (int)NewControlId();
122
80d83cbc 123 if (pParent)
ea51d98d
DW
124 pParent->AddChild(this);
125
126 m_bIconized = FALSE;
127
128 //
129 // We pass NULL as parent to MSWCreate because frames with parents behave
80d83cbc 130 // very strangely under Win95 shell.
ea51d98d
DW
131 // Alteration by JACS: keep normal Windows behaviour (float on top of parent)
132 // with this style.
133 //
134 if ((m_windowStyle & wxFRAME_FLOAT_ON_PARENT) == 0)
135 pParent = NULL;
136
137 if (!pParent)
138 wxTopLevelWindows.Append(this);
139
140 OS2Create( m_windowId
141 ,pParent
142 ,wxFrameClassName
143 ,this
144 ,rsTitle
145 ,nX
146 ,nY
147 ,nWidth
148 ,nHeight
149 ,lStyle
150 );
151
152 wxModelessWindows.Append(this);
153 return TRUE;
154} // end of wxFrame::Create
0e320a79
DW
155
156wxFrame::~wxFrame()
157{
ea51d98d
DW
158 m_isBeingDeleted = TRUE;
159 wxTopLevelWindows.DeleteObject(this);
0e320a79 160
ea51d98d 161 DeleteAllBars();
29435d81 162
ea51d98d
DW
163 if (wxTheApp && (wxTopLevelWindows.Number() == 0))
164 {
165 wxTheApp->SetTopWindow(NULL);
0e320a79 166
ea51d98d
DW
167 if (wxTheApp->GetExitOnFrameDelete())
168 {
80d83cbc 169 ::WinPostMsg(GetHwnd(), WM_QUIT, 0, 0);
ea51d98d
DW
170 }
171 }
172 wxModelessWindows.DeleteObject(this);
173
174 //
175 // For some reason, wxWindows can activate another task altogether
176 // when a frame is destroyed after a modal dialog has been invoked.
177 // Try to bring the parent to the top.
178 //
179 // MT:Only do this if this frame is currently the active window, else weird
180 // things start to happen.
181 //
182 if (wxGetActiveWindow() == this)
0e320a79 183 {
ea51d98d
DW
184 if (GetParent() && GetParent()->GetHWND())
185 {
ea51d98d
DW
186 ::WinSetWindowPos( (HWND) GetParent()->GetHWND()
187 ,HWND_TOP
80d83cbc
DW
188 ,0
189 ,0
190 ,0
191 ,0
192 ,SWP_ZORDER
ea51d98d
DW
193 );
194 }
0e320a79 195 }
ea51d98d 196} // end of wxFrame::~wxFrame
0e320a79 197
ea51d98d 198//
0e320a79 199// Get size *available for subwindows* i.e. excluding menu bar, toolbar etc.
ea51d98d 200//
80d83cbc
DW
201void wxFrame::DoGetClientSize(
202 int* pX
203, int* pY
204) const
0e320a79 205{
80d83cbc
DW
206 //
207 // OS/2 PM's coordinates go from bottom-left not
208 // top-left thus the += instead of the -=
209 //
210 RECTL vRect;
211 HWND hWndClient;
212
213 //
214 // PM has no GetClientRect that inherantly knows about the client window
215 // We have to explicitly go fetch it!
216 //
217 hWndClient = ::WinWindowFromId(GetHwnd(), FID_CLIENT);
218 ::WinQueryWindowRect(hWndClient, &vRect);
21802234 219
f38374d0 220#if wxUSE_STATUSBAR
80d83cbc
DW
221 if ( GetStatusBar() )
222 {
223 int nStatusX
224 int nStatusY;
225
226 GetStatusBar()->GetClientSize( &nStatusX
227 ,&nStatusY
228 );
229 vRect.yBottom += nStatusY;
230 }
f38374d0 231#endif // wxUSE_STATUSBAR
21802234 232
80d83cbc
DW
233 wxPoint vPoint(GetClientAreaOrigin());
234
235 vRect.bottom += pt.y;
236 vRect.right -= pt.x;
21802234 237
80d83cbc
DW
238 if (pX)
239 *pX = vRect.xRight;
240 if (pY)
241 *pY = vRect.yBottom;
242} // end of wxFrame::DoGetClientSize
0e320a79 243
80d83cbc 244//
0e320a79
DW
245// Set the client size (i.e. leave the calculation of borders etc.
246// to wxWindows)
80d83cbc
DW
247//
248void wxFrame::DoSetClientSize(
249 int nWidth
250, int nHeight
251)
0e320a79 252{
80d83cbc
DW
253 HWND hWnd = GetHwnd();
254 HWND hWndClient;
255 RECTL vRect;
256 RECT vRect2;
0e320a79 257
80d83cbc
DW
258 hWndClient = ::WinWindowFromId(GetHwnd(), FID_CLIENT);
259 ::WinQueryWindowRect(hWndClient, &vRect);
21802234 260
80d83cbc 261 ::WinQueryWindowRect(hWnd, &vRect2);
21802234 262
80d83cbc
DW
263 //
264 // Find the difference between the entire window (title bar and all)
265 // and the client area; add this to the new client size to move the
266 // window. Remember OS/2's backwards y coord system!
267 //
268 int nActualWidth = vRect2.xRight - vRect2.xLeft - vRect.xRight + nWidth;
269 int nActualHeight = vRect2.yTop + vRect2.yTop - vRect.yTop + nHeight;
29435d81 270
f38374d0 271#if wxUSE_STATUSBAR
80d83cbc
DW
272 if ( GetStatusBar() )
273 {
274 int nStatusX;
275 int nStatusY;
276
277 GetStatusBar()->GetClientSize( &nStatusX
278 ,&nStatusY
279 );
280 nActualHeight += nStatusY;
281 }
f38374d0 282#endif // wxUSE_STATUSBAR
29435d81 283
80d83cbc
DW
284 wxPoint vPoint(GetClientAreaOrigin());
285 nActualWidth += vPoint.y;
286 nActualHeight += vPoint.x;
287
288 POINTL vPointl;
289
290 vPointl.x = vRect2.xLeft;
291 vPoint.y = vRect2.yTop;
292
293 ::WinSetWindowPos( hWnd
294 ,HWND_TOP
295 ,vPointl.x
296 ,vPointl.y
297 ,nActualWidth
298 ,nActualHeight
299 ,SWP_MOVE | SWP_SIZE | SWP_SHOW
300 );
301
302 wxSizeEvent vEvent( wxSize( nWidth
303 ,nHeight
304 )
305 ,m_windowId
306 );
307 vEvent.SetEventObject(this);
308 GetEventHandler()->ProcessEvent(vEvent);
309} // end of wxFrame::DoSetClientSize
310
311void wxFrame::DoGetSize(
312 int* pWidth
313, int* pHeight
314) const
315{
316 RECTL vRect;
21802234 317
80d83cbc
DW
318 ::WinQueryWindowRect(GetHwnd(), &vRect);
319 *pWidth = vRect.xRight - vRect.xLeft;
320 *pHeight = vRect.yTop - vRect.yBottom;
321} // end of wxFrame::DoGetSize
21802234 322
80d83cbc
DW
323void wxFrame::DoGetPosition(
324 int* pX
325, int* pY
326) const
327{
328 RECTL vRect;
329 POINT vPoint;
29435d81 330
80d83cbc
DW
331 ::WinQueryWindowRect(GetHwnd(), &vRect);
332 vPoint.x = vRect.xLeft;
0e320a79 333
80d83cbc
DW
334 //
335 // OS/2 is backwards [WIN32 it is vRect.yTop]
336 //
337 vPoint.y = vRect.yBottom;
0e320a79 338
80d83cbc
DW
339 *pX = vPoint.x;
340 *pY = vPoint.y;
341} // end of wxFrame::DoGetPosition
0e320a79 342
f38374d0
DW
343// ----------------------------------------------------------------------------
344// variations around ::ShowWindow()
345// ----------------------------------------------------------------------------
346
80d83cbc
DW
347void wxFrame::DoShowWindow(
348 int nShowCmd
349)
0e320a79 350{
80d83cbc
DW
351 ::WinShowWindow(GetHwnd(), nShowCmd);
352 m_bIconized = nShowCmd == SWP_MINIMIZE;
353} // end of wxFrame::DoShowWindow
21802234 354
80d83cbc
DW
355bool wxFrame::Show(
356 bool bShow
357)
0e320a79 358{
80d83cbc 359 DoShowWindow(show ? SWP_SHOW : SW_HIDE);
21802234 360
80d83cbc 361 if (bShow)
f38374d0 362 {
80d83cbc
DW
363 wxActivateEvent vEvent(wxEVT_ACTIVATE, TRUE, m_windowId);
364
365 ::WinSetWindowPos( (HWND) GetHWND()
366 ,HWND_TOP
367 ,0
368 ,0
369 ,0
370 ,0
371 ,SWP_ZORDER
372 );
373 vEvent.SetEventObject(this);
374 GetEventHandler()->ProcessEvent(vEvent);
f38374d0
DW
375 }
376 else
377 {
80d83cbc 378 //
f38374d0 379 // Try to highlight the correct window (the parent)
80d83cbc
DW
380 //
381 if (GetParent())
f38374d0 382 {
80d83cbc
DW
383 HWND hWndParent = GetHwndOf(GetParent());
384
f38374d0 385 if (hWndParent)
80d83cbc
DW
386 ::WinSetWindowPos( hWndParent
387 ,HWND_TOP
388 ,0
389 ,0
390 ,0
391 ,0
392 ,SWP_ZORDER
393 );
f38374d0
DW
394 }
395 }
f38374d0 396 return TRUE;
80d83cbc 397} // end of wxFrame::Show
f38374d0 398
80d83cbc
DW
399void wxFrame::Iconize(
400 bool bIconize
401)
f38374d0 402{
80d83cbc
DW
403 DoShowWindow(bIconize ? SWP_MINIMIZE : SWP_RESTORE);
404} // end of wxFrame::Iconize
0e320a79 405
80d83cbc
DW
406void wxFrame::Maximize(
407 bool bMaximize)
0e320a79 408{
80d83cbc
DW
409 DoShowWindow(bMaximize ? SWP_MAXIMIZE : SWP_RESTORE);
410} // end of wxFrame::Maximize
f38374d0
DW
411
412void wxFrame::Restore()
413{
80d83cbc
DW
414 DoShowWindow(SWP_RESTORE);
415} // end of wxFrame::Restore
0e320a79
DW
416
417bool wxFrame::IsIconized() const
418{
80d83cbc
DW
419 SWP vSwp;
420 bool bIconic;
421
422 ::WinQueryWindowPos(GetHwnd(), &vSwp)
423
424 if (vSwp.fl & SWP_MINIMIZE)
425 ((wxFrame*)this)->m_bIconized = TRUE;
426 else
427 ((wxFrame*)this)->m_bIconized = FALSE;
428 return m_bIconized;
429} // end of wxFrame::IsIconized
0e320a79 430
21802234
DW
431// Is it maximized?
432bool wxFrame::IsMaximized() const
0e320a79 433{
80d83cbc
DW
434 SWP vSwp;
435 bool bIconic;
436
437 ::WinQueryWindowPos(GetHwnd(), &vSwp)
438 return (vSwp.fl & SWP_MAXIMIZE);
439} // end of wxFrame::IsMaximized
0e320a79 440
0fe536e3
DW
441void wxFrame::SetIcon(
442 const wxIcon& rIcon
443)
0e320a79 444{
0fe536e3 445 wxFrameBase::SetIcon(rIcon);
f38374d0 446
0fe536e3 447 if (m_icon.Ok())
f38374d0 448 {
0fe536e3
DW
449 WinSendMessage( GetHwnd()
450 ,WM_SETICON
451 ,(HICON) m_icon.GetHICON()
452 ,NULL
453 )
f38374d0 454 }
0fe536e3 455} // end of wxFrame::SetIcon
0e320a79 456
21802234 457#if wxUSE_STATUSBAR
0fe536e3
DW
458wxStatusBar* wxFrame::OnCreateStatusBar(
459 int nNumber
460, long lStyle
461, wxWindowID vId
462, const wxString& rName
463)
0e320a79 464{
0fe536e3 465 wxStatusBar* pStatusBar = NULL;
0e320a79 466
0fe536e3
DW
467 pStatusBar = wxFrameBase::OnCreateStatusBar( nNumber
468 ,lStyle
469 ,vId
470 ,rName
471 );
472 return pStatusBar;
473} // end of wxFrame::OnCreateStatusBar
0e320a79
DW
474
475void wxFrame::PositionStatusBar()
476{
0fe536e3
DW
477 //
478 // Native status bar positions itself
479 //
480 if (m_frameStatusBar)
f38374d0 481 {
0fe536e3
DW
482 int nWidth
483 int nHeight;
484 int nStatbarWidth
485 int nStatbarHeight;
486 HWND hWndClient;
487 RECTL vRect;
488
489 hWndClient = ::WinWindowFromId(GetHwnd(), FID_CLIENT);
490 ::WinQueryWindowRect(hWndClient, &vRect);
491 nWidth = vRect.xRight - vRect.xLeft;
492 nHeight = vRect.xTop - vRect.xBottom;
493
494 m_frameStatusBar->GetSize( &nStatbarWidth
495 ,&nStatbarHeight
496 );
f38374d0 497
0fe536e3 498 //
f38374d0
DW
499 // Since we wish the status bar to be directly under the client area,
500 // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.
0fe536e3
DW
501 //
502 m_frameStatusBar->SetSize( 0
503 ,nHeight
504 ,nWidth
505 ,nStatbarHeight
506 );
f38374d0 507 }
0fe536e3 508} // end of wxFrame::PositionStatusBar
21802234 509#endif // wxUSE_STATUSBAR
0e320a79 510
21802234 511void wxFrame::DetachMenuBar()
0e320a79 512{
21802234 513 if (m_frameMenuBar)
0e320a79 514 {
29435d81 515 m_frameMenuBar->Detach();
0e320a79 516 m_frameMenuBar = NULL;
21802234 517 }
0fe536e3 518} // end of wxFrame::DetachMenuBar
21802234 519
0fe536e3
DW
520void wxFrame::SetMenuBar(
521 wxMenuBar* pMenuBbar
522)
21802234 523{
0fe536e3 524 if (!pMenuBar)
21802234
DW
525 {
526 DetachMenuBar();
0e320a79
DW
527 return;
528 }
c3d43472 529
0fe536e3 530 wxCHECK_RET(!pMenuBar->GetFrame(), wxT("this menubar is already attached"));
0e320a79 531
21802234
DW
532 if (m_frameMenuBar)
533 delete m_frameMenuBar;
534
0fe536e3
DW
535 m_hMenu = pMenuBbar->Create();
536 m_ulMenubarId = pMenubar->GetMenubarId();
537 if (m_ulMenubarId != FID_MENU)
538 {
539 ::WinSetWIndowUShort( m_hMenu
540 ,QWS_ID
541 ,(unsigned short(m_ulMenubarId)
542 );
543 }
21802234 544
0fe536e3 545 if (!m_hMenu)
21802234
DW
546 return;
547
548 InternalSetMenuBar();
549
550 m_frameMenuBar = menu_bar;
29435d81 551 menu_bar->Attach(this);
0fe536e3 552} // end of wxFrame::SetMenuBar
0e320a79 553
21802234 554void wxFrame::InternalSetMenuBar()
0e320a79 555{
0fe536e3
DW
556
557 ::WinPostMsg( GetHwnd()
558 ,WM_UPDATEFRAME
559 ,FCF_MENU
560 ,NULL
561 );
562} // end of wxFrame::InternalSetMenuBar
0e320a79
DW
563
564// Responds to colour changes, and passes event on to children.
565void wxFrame::OnSysColourChanged(wxSysColourChangedEvent& event)
566{
f38374d0
DW
567// TODO:
568/*
0e320a79
DW
569 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE));
570 Refresh();
571
572 if ( m_frameStatusBar )
573 {
574 wxSysColourChangedEvent event2;
575 event2.SetEventObject( m_frameStatusBar );
21802234 576 m_frameStatusBar->GetEventHandler()->ProcessEvent(event2);
0e320a79
DW
577 }
578
579 // Propagate the event to the non-top-level children
580 wxWindow::OnSysColourChanged(event);
f38374d0 581*/
0e320a79
DW
582}
583
21802234
DW
584/*
585 * Frame window
586 *
587 */
588
589bool wxFrame::OS2Create(int id, wxWindow *parent, const wxChar *wclass, wxWindow *wx_win, const wxChar *title,
590 int x, int y, int width, int height, long style)
591
592{
80d83cbc 593 m_hDefaultIcon = (WXHICON) (wxSTD_FRAME_ICON ? wxSTD_FRAME_ICON : wxDEFAULT_FRAME_ICON);
21802234
DW
594
595 // If child windows aren't properly drawn initially, WS_CLIPCHILDREN
596 // could be the culprit. But without it, you can get a lot of flicker.
29435d81 597
21802234
DW
598// TODO:
599/*
600 DWORD msflags = 0;
601 if ((style & wxCAPTION) == wxCAPTION)
602 msflags = WS_OVERLAPPED;
603 else
604 msflags = WS_POPUP;
605
606 if (style & wxMINIMIZE_BOX)
607 msflags |= WS_MINIMIZEBOX;
608 if (style & wxMAXIMIZE_BOX)
609 msflags |= WS_MAXIMIZEBOX;
610 if (style & wxTHICK_FRAME)
611 msflags |= WS_THICKFRAME;
612 if (style & wxSYSTEM_MENU)
613 msflags |= WS_SYSMENU;
614 if ((style & wxMINIMIZE) || (style & wxICONIZE))
615 msflags |= WS_MINIMIZE;
616 if (style & wxMAXIMIZE)
617 msflags |= WS_MAXIMIZE;
618 if (style & wxCAPTION)
619 msflags |= WS_CAPTION;
620 if (style & wxCLIP_CHILDREN)
621 msflags |= WS_CLIPCHILDREN;
622
623 // Keep this in wxFrame because it saves recoding this function
624 // in wxTinyFrame
625#if wxUSE_ITSY_BITSY
626 if (style & wxTINY_CAPTION_VERT)
627 msflags |= IBS_VERTCAPTION;
628 if (style & wxTINY_CAPTION_HORIZ)
629 msflags |= IBS_HORZCAPTION;
630#else
631 if (style & wxTINY_CAPTION_VERT)
632 msflags |= WS_CAPTION;
633 if (style & wxTINY_CAPTION_HORIZ)
634 msflags |= WS_CAPTION;
635#endif
636 if ((style & wxTHICK_FRAME) == 0)
637 msflags |= WS_BORDER;
638
639 WXDWORD extendedStyle = MakeExtendedStyle(style);
640
641#if !defined(__WIN16__) && !defined(__SC__)
642 if (style & wxFRAME_TOOL_WINDOW)
643 extendedStyle |= WS_EX_TOOLWINDOW;
644#endif
645
646 if (style & wxSTAY_ON_TOP)
647 extendedStyle |= WS_EX_TOPMOST;
648
649 m_iconized = FALSE;
29435d81 650 if ( !wxWindow::MSWCreate(id, parent, wclass, wx_win, title, x, y, width, height,
21802234
DW
651 msflags, NULL, extendedStyle) )
652 return FALSE;
653
654 // Seems to be necessary if we use WS_POPUP
655 // style instead of WS_OVERLAPPED
656 if (width > -1 && height > -1)
657 ::PostMessage(GetHwnd(), WM_SIZE, SIZE_RESTORED, MAKELPARAM(width, height));
29435d81 658*/
f38374d0 659 return TRUE;
0e320a79
DW
660}
661
662// Default activation behaviour - set the focus for the first child
663// subwindow found.
664void wxFrame::OnActivate(wxActivateEvent& event)
665{
21802234
DW
666 for ( wxWindowList::Node *node = GetChildren().GetFirst();
667 node;
668 node = node->GetNext() )
0e320a79 669 {
21802234
DW
670 // FIXME all this is totally bogus - we need to do the same as wxPanel,
671 // but how to do it without duplicating the code?
672
673 // restore focus
674 wxWindow *child = node->GetData();
675
676 if ( !child->IsTopLevel()
677#if wxUSE_TOOLBAR
678 && !wxDynamicCast(child, wxToolBar)
679#endif // wxUSE_TOOLBAR
680#if wxUSE_STATUSBAR
681 && !wxDynamicCast(child, wxStatusBar)
682#endif // wxUSE_STATUSBAR
683 )
684 {
685 child->SetFocus();
686 return;
687 }
0e320a79 688 }
0e320a79
DW
689}
690
f38374d0
DW
691// ----------------------------------------------------------------------------
692// wxFrame size management: we exclude the areas taken by menu/status/toolbars
693// from the client area, so the client area is what's really available for the
694// frame contents
695// ----------------------------------------------------------------------------
0e320a79
DW
696
697// Checks if there is a toolbar, and returns the first free client position
698wxPoint wxFrame::GetClientAreaOrigin() const
699{
700 wxPoint pt(0, 0);
701 if (GetToolBar())
702 {
703 int w, h;
704 GetToolBar()->GetSize(& w, & h);
705
706 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL)
707 {
708 pt.x += w;
709 }
710 else
711 {
712 pt.y += h;
713 }
714 }
715 return pt;
716}
717
e6ebb514 718void wxFrame::DoScreenToClient(int *x, int *y) const
0e320a79 719{
29435d81 720 wxWindow::DoScreenToClient(x, y);
0e320a79
DW
721
722 // We may be faking the client origin.
723 // So a window that's really at (0, 30) may appear
724 // (to wxWin apps) to be at (0, 0).
725 wxPoint pt(GetClientAreaOrigin());
726 *x -= pt.x;
727 *y -= pt.y;
728}
729
e6ebb514 730void wxFrame::DoClientToScreen(int *x, int *y) const
0e320a79
DW
731{
732 // We may be faking the client origin.
733 // So a window that's really at (0, 30) may appear
734 // (to wxWin apps) to be at (0, 0).
735 wxPoint pt1(GetClientAreaOrigin());
736 *x += pt1.x;
737 *y += pt1.y;
738
e6ebb514 739 wxWindow::DoClientToScreen(x, y);
0e320a79
DW
740}
741
f38374d0
DW
742// ----------------------------------------------------------------------------
743// tool/status bar stuff
744// ----------------------------------------------------------------------------
745
21802234 746#if wxUSE_TOOLBAR
f38374d0 747
0e320a79
DW
748wxToolBar* wxFrame::CreateToolBar(long style, wxWindowID id, const wxString& name)
749{
f38374d0 750 if ( wxFrameBase::CreateToolBar(style, id, name) )
0e320a79 751 {
0e320a79 752 PositionToolBar();
0e320a79 753 }
0e320a79 754
f38374d0 755 return m_frameToolBar;
0e320a79
DW
756}
757
758void wxFrame::PositionToolBar()
759{
29435d81
DW
760// TODO:
761/*
21802234 762 RECT rect;
29435d81 763 ::GetClientRect(GetHwnd(), &rect);
0e320a79 764
f38374d0 765#if wxUSE_STATUSBAR
0e320a79
DW
766 if ( GetStatusBar() )
767 {
f38374d0
DW
768 int statusX, statusY;
769 GetStatusBar()->GetClientSize(&statusX, &statusY);
770 rect.bottom -= statusY;
0e320a79 771 }
f38374d0 772#endif // wxUSE_STATUSBAR
0e320a79 773
f38374d0 774 if ( GetToolBar() )
0e320a79
DW
775 {
776 int tw, th;
f38374d0 777 GetToolBar()->GetSize(&tw, &th);
0e320a79 778
f38374d0 779 if ( GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL )
0e320a79 780 {
f38374d0 781 th = rect.bottom;
0e320a79
DW
782 }
783 else
784 {
f38374d0 785 tw = rect.right;
21802234 786 }
f38374d0
DW
787
788 // Use the 'real' MSW position here
789 GetToolBar()->SetSize(0, 0, tw, th, wxSIZE_NO_ADJUSTMENTS);
21802234 790 }
29435d81 791*/
21802234
DW
792}
793#endif // wxUSE_TOOLBAR
794
f38374d0
DW
795// ----------------------------------------------------------------------------
796// frame state (iconized/maximized/...)
797// ----------------------------------------------------------------------------
798
21802234
DW
799// propagate our state change to all child frames: this allows us to emulate X
800// Windows behaviour where child frames float independently of the parent one
801// on the desktop, but are iconized/restored with it
802void wxFrame::IconizeChildFrames(bool bIconize)
803{
804 for ( wxWindowList::Node *node = GetChildren().GetFirst();
805 node;
806 node = node->GetNext() )
807 {
808 wxWindow *win = node->GetData();
809
810 if ( win->IsKindOf(CLASSINFO(wxFrame)) )
811 {
812 ((wxFrame *)win)->Iconize(bIconize);
0e320a79
DW
813 }
814 }
815}
816
21802234
DW
817// ===========================================================================
818// message processing
819// ===========================================================================
820
821// ---------------------------------------------------------------------------
822// preprocessing
823// ---------------------------------------------------------------------------
824
825bool wxFrame::OS2TranslateMessage(WXMSG* pMsg)
826{
f38374d0
DW
827// TODO:
828/*
29435d81
DW
829 if ( wxWindow::OS2TranslateMessage(pMsg) )
830 return TRUE;
f38374d0 831*/
21802234
DW
832 // try the menu bar accels
833 wxMenuBar *menuBar = GetMenuBar();
834 if ( !menuBar )
835 return FALSE;
836
29435d81
DW
837 const wxAcceleratorTable& acceleratorTable = menuBar->GetAccelTable();
838 return acceleratorTable.Translate(this, pMsg);
21802234
DW
839}
840
841// ---------------------------------------------------------------------------
842// our private (non virtual) message handlers
843// ---------------------------------------------------------------------------
844
845bool wxFrame::HandlePaint()
846{
21802234 847// TODO:
29435d81
DW
848/*
849 RECT rect;
850 if ( GetUpdateRect(GetHwnd(), &rect, FALSE) )
851 {
852 if ( m_iconized )
853 {
854 HICON hIcon = m_icon.Ok() ? GetHiconOf(m_icon)
855 : (HICON)m_defaultIcon;
856
21802234
DW
857 // Hold a pointer to the dc so long as the OnPaint() message
858 // is being processed
29435d81
DW
859 PAINTSTRUCT ps;
860 HDC hdc = ::BeginPaint(GetHwnd(), &ps);
861
862 // Erase background before painting or we get white background
863 MSWDefWindowProc(WM_ICONERASEBKGND, (WORD)(LONG)ps.hdc, 0L);
864
865 if ( hIcon )
866 {
867 RECT rect;
868 ::GetClientRect(GetHwnd(), &rect);
21802234
DW
869
870 // FIXME: why hardcoded?
29435d81
DW
871 static const int icon_width = 32;
872 static const int icon_height = 32;
873
874 int icon_x = (int)((rect.right - icon_width)/2);
875 int icon_y = (int)((rect.bottom - icon_height)/2);
876
877 ::DrawIcon(hdc, icon_x, icon_y, hIcon);
878 }
879
880 ::EndPaint(GetHwnd(), &ps);
881
882 return TRUE;
883 }
884 else
885 {
886 return wxWindow::HandlePaint();
887 }
888 }
889 else
890 {
891 // nothing to paint - processed
892 return TRUE;
893 }
894*/
895 return FALSE;
21802234
DW
896}
897
898bool wxFrame::HandleSize(int x, int y, WXUINT id)
899{
900 bool processed = FALSE;
901
29435d81
DW
902// TODO:
903/*
904 switch ( id )
21802234
DW
905 {
906 case SIZENORMAL:
907 // only do it it if we were iconized before, otherwise resizing the
908 // parent frame has a curious side effect of bringing it under it's
909 // children
910 if ( !m_iconized )
911 break;
912
913 // restore all child frames too
914 IconizeChildFrames(FALSE);
915
916 // fall through
917
918 case SIZEFULLSCREEN:
919 m_iconized = FALSE;
920 break;
921
922 case SIZEICONIC:
923 // iconize all child frames too
924 IconizeChildFrames(TRUE);
925
926 m_iconized = TRUE;
927 break;
928 }
f38374d0 929
21802234
DW
930 if ( !m_iconized )
931 {
29435d81 932 // forward WM_SIZE to status bar control
f38374d0
DW
933#if wxUSE_NATIVE_STATUSBAR
934 if (m_frameStatusBar && m_frameStatusBar->IsKindOf(CLASSINFO(wxStatusBar95)))
935 {
936 wxSizeEvent event(wxSize(x, y), m_frameStatusBar->GetId());
937 event.SetEventObject( m_frameStatusBar );
938
939 ((wxStatusBar95 *)m_frameStatusBar)->OnSize(event);
940 }
941#endif // wxUSE_NATIVE_STATUSBAR
942
21802234
DW
943 PositionStatusBar();
944 PositionToolBar();
945
946 wxSizeEvent event(wxSize(x, y), m_windowId);
947 event.SetEventObject( this );
948 processed = GetEventHandler()->ProcessEvent(event);
949 }
f38374d0 950*/
21802234
DW
951 return processed;
952}
953
954bool wxFrame::HandleCommand(WXWORD id, WXWORD cmd, WXHWND control)
955{
f38374d0
DW
956// TODO:
957/*
21802234
DW
958 if ( control )
959 {
960 // In case it's e.g. a toolbar.
961 wxWindow *win = wxFindWinFromHandle(control);
962 if ( win )
f38374d0 963 return win->MSWCommand(cmd, id);
21802234
DW
964 }
965
966 // handle here commands from menus and accelerators
967 if ( cmd == 0 || cmd == 1 )
968 {
969 if ( wxCurrentPopupMenu )
970 {
971 wxMenu *popupMenu = wxCurrentPopupMenu;
972 wxCurrentPopupMenu = NULL;
973
f38374d0 974 return popupMenu->MSWCommand(cmd, id);
21802234
DW
975 }
976
977 if ( ProcessCommand(id) )
978 {
979 return TRUE;
980 }
981 }
f38374d0 982*/
21802234
DW
983 return FALSE;
984}
985
986bool wxFrame::HandleMenuSelect(WXWORD nItem, WXWORD flags, WXHMENU hMenu)
987{
988 int item;
989 if ( flags == 0xFFFF && hMenu == 0 )
990 {
991 // menu was removed from screen
992 item = -1;
993 }
29435d81 994// TODO:
21802234
DW
995/*
996 else if ( !(flags & MF_POPUP) && !(flags & MF_SEPARATOR) )
997 {
998 item = nItem;
999 }
21802234
DW
1000 else
1001 {
1002 // don't give hints for separators (doesn't make sense) nor for the
1003 // items opening popup menus (they don't have them anyhow)
1004 return FALSE;
1005 }
f38374d0 1006*/
21802234
DW
1007 wxMenuEvent event(wxEVT_MENU_HIGHLIGHT, item);
1008 event.SetEventObject( this );
1009
1010 return GetEventHandler()->ProcessEvent(event);
1011}
1012
1013// ---------------------------------------------------------------------------
1014// the window proc for wxFrame
1015// ---------------------------------------------------------------------------
1016
1017MRESULT wxFrame::OS2WindowProc(HWND hwnd, WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
1018{
f38374d0 1019 long rc = 0;
21802234
DW
1020 bool processed = FALSE;
1021
1022// TODO:
1023/*
1024 switch ( message )
1025 {
1026 case WM_CLOSE:
1027 // if we can't close, tell the system that we processed the
1028 // message - otherwise it would close us
1029 processed = !Close();
1030 break;
1031
1032 case WM_COMMAND:
1033 {
1034 WORD id, cmd;
1035 WXHWND hwnd;
1036 UnpackCommand((WXWPARAM)wParam, (WXLPARAM)lParam,
1037 &id, &hwnd, &cmd);
1038
1039 processed = HandleCommand(id, cmd, (WXHWND)hwnd);
1040 }
1041 break;
1042
1043 case WM_MENUSELECT:
1044 {
1045 WXWORD item, flags;
1046 WXHMENU hmenu;
1047 UnpackMenuSelect(wParam, lParam, &item, &flags, &hmenu);
1048
1049 processed = HandleMenuSelect(item, flags, hmenu);
1050 }
1051 break;
1052
1053 case WM_PAINT:
1054 processed = HandlePaint();
1055 break;
1056
1057 case WM_QUERYDRAGICON:
1058 {
1059 HICON hIcon = m_icon.Ok() ? GetHiconOf(m_icon)
1060 : (HICON)(m_defaultIcon);
1061 rc = (long)hIcon;
1062 processed = rc != 0;
1063 }
1064 break;
1065
1066 case WM_SIZE:
1067 processed = HandleSize(LOWORD(lParam), HIWORD(lParam), wParam);
1068 break;
1069 }
f38374d0 1070
21802234 1071 if ( !processed )
f38374d0 1072 rc = wxWindow::MSWWindowProc(message, wParam, lParam);
21802234
DW
1073
1074 return rc;
f38374d0
DW
1075*/
1076 return (MRESULT)0;
21802234
DW
1077}
1078