]> git.saurik.com Git - wxWidgets.git/blame - src/msw/frame.cpp
Misc. fixes
[wxWidgets.git] / src / msw / frame.cpp
CommitLineData
2bda0e17
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: frame.cpp
3// Purpose: wxFrame
4// Author: Julian Smart
5// Modified by:
6// Created: 01/02/97
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart and Markus Holzem
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "frame.h"
14#endif
15
16// For compilers that support precompilation, includes "wx.h".
17#include "wx/wxprec.h"
18
19#ifdef __BORLANDC__
9f3362c4 20 #pragma hdrstop
2bda0e17
KB
21#endif
22
23#ifndef WX_PRECOMP
9f3362c4
VZ
24 #include "wx/setup.h"
25 #include "wx/frame.h"
26 #include "wx/menu.h"
27 #include "wx/app.h"
28 #include "wx/utils.h"
29 #include "wx/dialog.h"
30 #include "wx/settings.h"
31 #include "wx/dcclient.h"
32#endif // WX_PRECOMP
2bda0e17
KB
33
34#include "wx/msw/private.h"
35#include "wx/statusbr.h"
81d66cf3 36#include "wx/toolbar.h"
2bda0e17 37#include "wx/menuitem.h"
6776a0b2 38#include "wx/log.h"
2bda0e17
KB
39
40#ifdef LoadAccelerators
41#undef LoadAccelerators
42#endif
43
47d67540 44#if wxUSE_NATIVE_STATUSBAR
9f3362c4 45 #include <wx/msw/statbr95.h>
2bda0e17
KB
46#endif
47
48extern wxList wxModelessWindows;
cde9f08e 49extern wxList WXDLLEXPORT wxPendingDelete;
2bda0e17 50extern char wxFrameClassName[];
e1a6fc11 51extern wxMenu *wxCurrentPopupMenu;
2bda0e17
KB
52
53#if !USE_SHARED_LIBRARY
54BEGIN_EVENT_TABLE(wxFrame, wxWindow)
55 EVT_SIZE(wxFrame::OnSize)
56 EVT_ACTIVATE(wxFrame::OnActivate)
57 EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight)
58 EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged)
59 EVT_IDLE(wxFrame::OnIdle)
60 EVT_CLOSE(wxFrame::OnCloseWindow)
61END_EVENT_TABLE()
62
63IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxWindow)
64#endif
65
47d67540 66#if wxUSE_NATIVE_STATUSBAR
9f3362c4 67 bool wxFrame::m_useNativeStatusBar = TRUE;
2bda0e17 68#else
9f3362c4 69 bool wxFrame::m_useNativeStatusBar = FALSE;
2bda0e17
KB
70#endif
71
bfc6fde4 72wxFrame::wxFrame()
2bda0e17 73{
73e7daa0 74 m_frameToolBar = NULL ;
2bda0e17
KB
75 m_frameMenuBar = NULL;
76 m_frameStatusBar = NULL;
77
78 m_windowParent = NULL;
79 m_iconized = FALSE;
80}
81
82bool wxFrame::Create(wxWindow *parent,
debe6624 83 wxWindowID id,
2bda0e17
KB
84 const wxString& title,
85 const wxPoint& pos,
86 const wxSize& size,
debe6624 87 long style,
2bda0e17
KB
88 const wxString& name)
89{
9f3362c4
VZ
90#if wxUSE_TOOLTIPS
91 m_hwndToolTip = 0;
92#endif
93
2bda0e17
KB
94 if (!parent)
95 wxTopLevelWindows.Append(this);
96
97 SetName(name);
98// m_modalShowing = FALSE;
99 m_windowStyle = style;
100 m_frameMenuBar = NULL;
73e7daa0 101 m_frameToolBar = NULL ;
2bda0e17
KB
102 m_frameStatusBar = NULL;
103
104 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE));
105
106// m_icon = NULL;
107 if ( id > -1 )
108 m_windowId = id;
109 else
110 m_windowId = (int)NewControlId();
111
112 if (parent) parent->AddChild(this);
113
114 int x = pos.x;
115 int y = pos.y;
116 int width = size.x;
117 int height = size.y;
118
119 m_iconized = FALSE;
d2aef312
VZ
120
121 // we pass NULL as parent to MSWCreate because frames with parents behave
122 // very strangely under Win95 shell
aeab10d0
JS
123 // Alteration by JACS: keep normal Windows behaviour (float on top of parent)
124 // with this style.
125 if ((m_windowStyle & wxFRAME_FLOAT_ON_PARENT) == 0)
126 parent = NULL;
127
128 MSWCreate(m_windowId, parent, wxFrameClassName, this, title,
d2aef312 129 x, y, width, height, style);
2bda0e17
KB
130
131 wxModelessWindows.Append(this);
132 return TRUE;
133}
134
bfc6fde4 135wxFrame::~wxFrame()
2bda0e17
KB
136{
137 m_isBeingDeleted = TRUE;
138 wxTopLevelWindows.DeleteObject(this);
139
140 if (m_frameStatusBar)
141 delete m_frameStatusBar;
142 if (m_frameMenuBar)
143 delete m_frameMenuBar;
144
145/* New behaviour March 1998: check if it's the last top-level window */
146// if (wxTheApp && (this == wxTheApp->GetTopWindow()))
147
148 if (wxTheApp && (wxTopLevelWindows.Number() == 0))
149 {
150 wxTheApp->SetTopWindow(NULL);
151
152 if (wxTheApp->GetExitOnFrameDelete())
153 {
154 PostQuitMessage(0);
155 }
156 }
157
158 wxModelessWindows.DeleteObject(this);
159
160 // For some reason, wxWindows can activate another task altogether
161 // when a frame is destroyed after a modal dialog has been invoked.
162 // Try to bring the parent to the top.
163 if (GetParent() && GetParent()->GetHWND())
164 ::BringWindowToTop((HWND) GetParent()->GetHWND());
165}
166
bfc6fde4 167WXHMENU wxFrame::GetWinMenu() const
2bda0e17
KB
168{
169 return m_hMenu;
170}
171
81d66cf3 172// Get size *available for subwindows* i.e. excluding menu bar, toolbar etc.
2bda0e17
KB
173void wxFrame::GetClientSize(int *x, int *y) const
174{
175 RECT rect;
2de8030d 176 ::GetClientRect((HWND) GetHWND(), &rect);
2bda0e17 177
81d66cf3 178 if ( GetStatusBar() )
2bda0e17 179 {
81d66cf3
JS
180 int statusX, statusY;
181 GetStatusBar()->GetClientSize(&statusX, &statusY);
182 rect.bottom -= statusY;
2bda0e17 183 }
81d66cf3
JS
184
185 wxPoint pt(GetClientAreaOrigin());
186 rect.bottom -= pt.y;
187 rect.right -= pt.x;
188
2bda0e17
KB
189 *x = rect.right;
190 *y = rect.bottom;
191}
192
193// Set the client size (i.e. leave the calculation of borders etc.
194// to wxWindows)
bfc6fde4 195void wxFrame::DoSetClientSize(int width, int height)
2bda0e17
KB
196{
197 HWND hWnd = (HWND) GetHWND();
198
199 RECT rect;
2de8030d 200 ::GetClientRect(hWnd, &rect);
2bda0e17
KB
201
202 RECT rect2;
203 GetWindowRect(hWnd, &rect2);
204
205 // Find the difference between the entire window (title bar and all)
206 // and the client area; add this to the new client size to move the
207 // window
208 int actual_width = rect2.right - rect2.left - rect.right + width;
209 int actual_height = rect2.bottom - rect2.top - rect.bottom + height;
210
81d66cf3 211 if ( GetStatusBar() )
2bda0e17 212 {
81d66cf3
JS
213 int statusX, statusY;
214 GetStatusBar()->GetClientSize(&statusX, &statusY);
215 actual_height += statusY;
2bda0e17
KB
216 }
217
81d66cf3
JS
218 wxPoint pt(GetClientAreaOrigin());
219 actual_width += pt.y;
220 actual_height += pt.x;
221
2bda0e17
KB
222 POINT point;
223 point.x = rect2.left;
224 point.y = rect2.top;
225
226 MoveWindow(hWnd, point.x, point.y, actual_width, actual_height, (BOOL)TRUE);
debe6624 227
2bda0e17
KB
228 wxSizeEvent event(wxSize(width, height), m_windowId);
229 event.SetEventObject( this );
230 GetEventHandler()->ProcessEvent(event);
2bda0e17
KB
231}
232
233void wxFrame::GetSize(int *width, int *height) const
234{
235 RECT rect;
236 GetWindowRect((HWND) GetHWND(), &rect);
237 *width = rect.right - rect.left;
238 *height = rect.bottom - rect.top;
239}
240
241void wxFrame::GetPosition(int *x, int *y) const
242{
243 RECT rect;
244 GetWindowRect((HWND) GetHWND(), &rect);
245 POINT point;
246 point.x = rect.left;
247 point.y = rect.top;
248
249 *x = point.x;
250 *y = point.y;
251}
252
bfc6fde4 253void wxFrame::DoSetSize(int x, int y, int width, int height, int sizeFlags)
2bda0e17
KB
254{
255 int currentX, currentY;
256 int x1 = x;
257 int y1 = y;
258 int w1 = width;
259 int h1 = height;
260
261 GetPosition(&currentX, &currentY);
262 if (x == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
263 x1 = currentX;
264 if (y == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
265 y1 = currentY;
266
267 int ww,hh ;
268 GetSize(&ww,&hh) ;
269 if (width == -1) w1 = ww ;
270 if (height==-1) h1 = hh ;
271
272 MoveWindow((HWND) GetHWND(), x1, y1, w1, h1, (BOOL)TRUE);
273
2bda0e17
KB
274 wxSizeEvent event(wxSize(width, height), m_windowId);
275 event.SetEventObject( this );
276 GetEventHandler()->ProcessEvent(event);
2bda0e17
KB
277}
278
debe6624 279bool wxFrame::Show(bool show)
2bda0e17
KB
280{
281 int cshow;
282 if (show)
283 cshow = SW_SHOW;
284 else
285 cshow = SW_HIDE;
286
287 if (!show)
288 {
289 // Try to highlight the correct window (the parent)
290 HWND hWndParent = 0;
291 if (GetParent())
292 {
293 hWndParent = (HWND) GetParent()->GetHWND();
294 if (hWndParent)
295 ::BringWindowToTop(hWndParent);
296 }
297 }
298
299 ShowWindow((HWND) GetHWND(), (BOOL)cshow);
300 if (show)
301 {
302 BringWindowToTop((HWND) GetHWND());
303
2bda0e17
KB
304 wxActivateEvent event(wxEVT_ACTIVATE, TRUE, m_windowId);
305 event.SetEventObject( this );
306 GetEventHandler()->ProcessEvent(event);
2bda0e17
KB
307 }
308 return TRUE;
309}
310
debe6624 311void wxFrame::Iconize(bool iconize)
2bda0e17
KB
312{
313 if (!iconize)
314 Show(TRUE);
315
316 int cshow;
317 if (iconize)
318 cshow = SW_MINIMIZE;
319 else
320 cshow = SW_RESTORE;
321 ShowWindow((HWND) GetHWND(), (BOOL)cshow);
322 m_iconized = iconize;
323}
324
325// Equivalent to maximize/restore in Windows
debe6624 326void wxFrame::Maximize(bool maximize)
2bda0e17
KB
327{
328 Show(TRUE);
329 int cshow;
330 if (maximize)
331 cshow = SW_MAXIMIZE;
332 else
333 cshow = SW_RESTORE;
334 ShowWindow((HWND) GetHWND(), cshow);
335 m_iconized = FALSE;
336}
337
bfc6fde4 338bool wxFrame::IsIconized() const
2bda0e17
KB
339{
340 ((wxFrame *)this)->m_iconized = (::IsIconic((HWND) GetHWND()) != 0);
341 return m_iconized;
342}
343
6f63ec3f 344// Is it maximized?
bfc6fde4 345bool wxFrame::IsMaximized() const
6f63ec3f
JS
346{
347 return (::IsZoomed((HWND) GetHWND()) != 0) ;
348}
349
2bda0e17
KB
350void wxFrame::SetTitle(const wxString& title)
351{
352 SetWindowText((HWND) GetHWND(), (const char *)title);
353}
354
bfc6fde4 355wxString wxFrame::GetTitle() const
2bda0e17
KB
356{
357 GetWindowText((HWND) GetHWND(), wxBuffer, 1000);
358 return wxString(wxBuffer);
359}
360
361void wxFrame::SetIcon(const wxIcon& icon)
362{
363 m_icon = icon;
364#if defined(__WIN95__)
365 if ( m_icon.Ok() )
366 SendMessage((HWND) GetHWND(), WM_SETICON,
367 (WPARAM)TRUE, (LPARAM)(HICON) m_icon.GetHICON());
368#endif
369}
370
81d66cf3
JS
371wxStatusBar *wxFrame::OnCreateStatusBar(int number, long style, wxWindowID id,
372 const wxString& name)
2bda0e17
KB
373{
374 wxStatusBar *statusBar = NULL;
375
47d67540 376#if wxUSE_NATIVE_STATUSBAR
2bda0e17
KB
377 if (UsesNativeStatusBar())
378 {
81d66cf3 379 statusBar = new wxStatusBar95(this, id, style);
2bda0e17
KB
380 }
381 else
382#endif
383 {
81d66cf3
JS
384 statusBar = new wxStatusBar(this, id, wxPoint(0, 0), wxSize(100, 20),
385 style, name);
2bda0e17
KB
386
387 // Set the height according to the font and the border size
388 wxClientDC dc(statusBar);
c0ed460c 389 dc.SetFont(statusBar->GetFont());
2bda0e17
KB
390
391 long x, y;
392 dc.GetTextExtent("X", &x, &y);
393
394 int height = (int)( (y * 1.1) + 2* statusBar->GetBorderY());
395
396 statusBar->SetSize(-1, -1, 100, height);
397 }
398
399 statusBar->SetFieldsCount(number);
400 return statusBar;
401}
402
81d66cf3
JS
403wxStatusBar* wxFrame::CreateStatusBar(int number, long style, wxWindowID id,
404 const wxString& name)
2bda0e17
KB
405{
406 // VZ: calling CreateStatusBar twice is an error - why anyone would do it?
c2dcfdef 407 wxCHECK_MSG( m_frameStatusBar == NULL, FALSE,
1311c7a9 408 "recreating status bar in wxFrame" );
2bda0e17 409
81d66cf3
JS
410 m_frameStatusBar = OnCreateStatusBar(number, style, id,
411 name);
2bda0e17
KB
412 if ( m_frameStatusBar )
413 {
414 PositionStatusBar();
81d66cf3 415 return m_frameStatusBar;
2bda0e17
KB
416 }
417 else
81d66cf3 418 return NULL;
2bda0e17
KB
419}
420
debe6624 421void wxFrame::SetStatusText(const wxString& text, int number)
2bda0e17 422{
1311c7a9 423 wxCHECK_RET( m_frameStatusBar != NULL, "no statusbar to set text for" );
2bda0e17
KB
424
425 m_frameStatusBar->SetStatusText(text, number);
426}
427
8b9518ee 428void wxFrame::SetStatusWidths(int n, const int widths_field[])
2bda0e17 429{
1311c7a9 430 wxCHECK_RET( m_frameStatusBar != NULL, "no statusbar to set widths for" );
2bda0e17
KB
431
432 m_frameStatusBar->SetStatusWidths(n, widths_field);
433 PositionStatusBar();
434}
435
bfc6fde4 436void wxFrame::PositionStatusBar()
2bda0e17
KB
437{
438 // native status bar positions itself
439 if (m_frameStatusBar
47d67540 440#if wxUSE_NATIVE_STATUSBAR
2bda0e17
KB
441 && !m_frameStatusBar->IsKindOf(CLASSINFO(wxStatusBar95))
442#endif
443 )
444 {
445 int w, h;
446 GetClientSize(&w, &h);
447 int sw, sh;
448 m_frameStatusBar->GetSize(&sw, &sh);
81d66cf3
JS
449
450 // Since we wish the status bar to be directly under the client area,
451 // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.
2bda0e17
KB
452 m_frameStatusBar->SetSize(0, h, w, sh);
453 }
454}
455
456void wxFrame::SetMenuBar(wxMenuBar *menu_bar)
457{
c2dcfdef
VZ
458 if (!menu_bar)
459 {
460 m_frameMenuBar = NULL;
461 return;
462 }
2bda0e17 463
c2dcfdef 464 wxCHECK_RET( !menu_bar->GetFrame(), "this menubar is already attached" );
2bda0e17 465
c2dcfdef
VZ
466 if (m_frameMenuBar)
467 delete m_frameMenuBar;
2bda0e17 468
c2dcfdef 469 m_hMenu = menu_bar->Create();
2bda0e17 470
c2dcfdef
VZ
471 if ( !m_hMenu )
472 return;
2bda0e17 473
c2dcfdef
VZ
474 if ( !::SetMenu((HWND)GetHWND(), (HMENU)m_hMenu) )
475 {
476 wxLogLastError("SetMenu");
477 }
2bda0e17 478
c2dcfdef
VZ
479 m_frameMenuBar = menu_bar;
480 menu_bar->Attach(this);
2bda0e17
KB
481}
482
57a7b7c1 483#if 0
2bda0e17
KB
484bool wxFrame::LoadAccelerators(const wxString& table)
485{
486 m_acceleratorTable = (WXHANDLE)
487#ifdef __WIN32__
488#ifdef UNICODE
489 ::LoadAcceleratorsW(wxGetInstance(), (const char *)table);
490#else
491 ::LoadAcceleratorsA(wxGetInstance(), (const char *)table);
492#endif
493#else
494 ::LoadAccelerators(wxGetInstance(), (const char *)table);
495#endif
496
497 // The above is necessary because LoadAccelerators is a macro
498 // which we have undefed earlier in the file to avoid confusion
499 // with wxFrame::LoadAccelerators. Ugh!
500
501 return (m_acceleratorTable != (WXHANDLE) NULL);
502}
57a7b7c1 503#endif
2bda0e17 504
bfc6fde4 505void wxFrame::Fit()
2bda0e17
KB
506{
507 // Work out max. size
c0ed460c 508 wxNode *node = GetChildren().First();
2bda0e17
KB
509 int max_width = 0;
510 int max_height = 0;
511 while (node)
512 {
513 // Find a child that's a subwindow, but not a dialog box.
514 wxWindow *win = (wxWindow *)node->Data();
515
516 if (!win->IsKindOf(CLASSINFO(wxFrame)) &&
517 !win->IsKindOf(CLASSINFO(wxDialog)))
518 {
519 int width, height;
520 int x, y;
521 win->GetSize(&width, &height);
522 win->GetPosition(&x, &y);
523
524 if ((x + width) > max_width)
525 max_width = x + width;
526 if ((y + height) > max_height)
527 max_height = y + height;
528 }
529 node = node->Next();
530 }
531 SetClientSize(max_width, max_height);
532}
533
534// Responds to colour changes, and passes event on to children.
535void wxFrame::OnSysColourChanged(wxSysColourChangedEvent& event)
536{
537 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE));
538 Refresh();
539
540 if ( m_frameStatusBar )
541 {
542 wxSysColourChangedEvent event2;
543 event2.SetEventObject( m_frameStatusBar );
02800301 544 m_frameStatusBar->GetEventHandler()->ProcessEvent(event2);
2bda0e17
KB
545 }
546
547 // Propagate the event to the non-top-level children
548 wxWindow::OnSysColourChanged(event);
549}
550
551/*
552 * Frame window
553 *
554 */
555
debe6624
JS
556void wxFrame::MSWCreate(int id, wxWindow *parent, const char *wclass, wxWindow *wx_win, const char *title,
557 int x, int y, int width, int height, long style)
2bda0e17
KB
558
559{
560 m_defaultIcon = (WXHICON) (wxSTD_FRAME_ICON ? wxSTD_FRAME_ICON : wxDEFAULT_FRAME_ICON);
561
562 // If child windows aren't properly drawn initially, WS_CLIPCHILDREN
563 // could be the culprit. But without it, you can get a lot of flicker.
564
2bda0e17
KB
565 DWORD msflags = 0;
566 if ((style & wxCAPTION) == wxCAPTION)
1c089c47 567 msflags = WS_OVERLAPPED;
2bda0e17 568 else
1c089c47 569 msflags = WS_POPUP;
2bda0e17
KB
570
571 if (style & wxMINIMIZE_BOX)
572 msflags |= WS_MINIMIZEBOX;
573 if (style & wxMAXIMIZE_BOX)
574 msflags |= WS_MAXIMIZEBOX;
575 if (style & wxTHICK_FRAME)
576 msflags |= WS_THICKFRAME;
577 if (style & wxSYSTEM_MENU)
578 msflags |= WS_SYSMENU;
579 if ((style & wxMINIMIZE) || (style & wxICONIZE))
580 msflags |= WS_MINIMIZE;
581 if (style & wxMAXIMIZE)
582 msflags |= WS_MAXIMIZE;
583 if (style & wxCAPTION)
584 msflags |= WS_CAPTION;
1c089c47
JS
585 if (style & wxCLIP_CHILDREN)
586 msflags |= WS_CLIPCHILDREN;
2bda0e17
KB
587
588 // Keep this in wxFrame because it saves recoding this function
589 // in wxTinyFrame
47d67540 590#if wxUSE_ITSY_BITSY
2bda0e17
KB
591 if (style & wxTINY_CAPTION_VERT)
592 msflags |= IBS_VERTCAPTION;
593 if (style & wxTINY_CAPTION_HORIZ)
594 msflags |= IBS_HORZCAPTION;
595#else
596 if (style & wxTINY_CAPTION_VERT)
597 msflags |= WS_CAPTION;
598 if (style & wxTINY_CAPTION_HORIZ)
599 msflags |= WS_CAPTION;
600#endif
601 if ((style & wxTHICK_FRAME) == 0)
602 msflags |= WS_BORDER;
603
604 WXDWORD extendedStyle = MakeExtendedStyle(style);
605
2432b92d 606#if !defined(__WIN16__) && !defined(__SC__)
cd2df130
JS
607 if (style & wxFRAME_TOOL_WINDOW)
608 extendedStyle |= WS_EX_TOOLWINDOW;
1e6d9499 609#endif
cd2df130 610
2bda0e17
KB
611 if (style & wxSTAY_ON_TOP)
612 extendedStyle |= WS_EX_TOPMOST;
613
614 m_iconized = FALSE;
615 wxWindow::MSWCreate(id, parent, wclass, wx_win, title, x, y, width, height,
616 msflags, NULL, extendedStyle);
617 // Seems to be necessary if we use WS_POPUP
618 // style instead of WS_OVERLAPPED
619 if (width > -1 && height > -1)
620 ::PostMessage((HWND) GetHWND(), WM_SIZE, SIZE_RESTORED, MAKELPARAM(width, height));
621}
622
bfc6fde4 623bool wxFrame::MSWOnPaint()
2bda0e17 624{
2bda0e17
KB
625 RECT rect;
626 if (GetUpdateRect((HWND) GetHWND(), &rect, FALSE))
627 {
628 if (m_iconized)
629 {
630 HICON the_icon;
fd3f686c
VZ
631 if (m_icon.Ok())
632 the_icon = (HICON) m_icon.GetHICON();
633 else
2bda0e17
KB
634 the_icon = (HICON) m_defaultIcon;
635
636 PAINTSTRUCT ps;
637 // Hold a pointer to the dc so long as the OnPaint() message
638 // is being processed
639 HDC cdc = BeginPaint((HWND) GetHWND(), &ps);
c2dcfdef 640
2bda0e17 641 // Erase background before painting or we get white background
ce3ed50d 642 this->MSWDefWindowProc(WM_ICONERASEBKGND,(WORD)(LONG) ps.hdc,0L);
c2dcfdef 643
2bda0e17
KB
644 if (the_icon)
645 {
646 RECT rect;
2de8030d 647 ::GetClientRect((HWND) GetHWND(), &rect);
2bda0e17
KB
648 int icon_width = 32;
649 int icon_height = 32;
650 int icon_x = (int)((rect.right - icon_width)/2);
651 int icon_y = (int)((rect.bottom - icon_height)/2);
652 DrawIcon(cdc, icon_x, icon_y, the_icon);
653 }
654
655 EndPaint((HWND) GetHWND(), &ps);
656 }
1c089c47 657 else
2bda0e17 658 {
debe6624
JS
659 wxPaintEvent event(m_windowId);
660 event.m_eventObject = this;
661 if (!GetEventHandler()->ProcessEvent(event))
662 Default();
2bda0e17
KB
663 }
664 return 0;
665 }
666 return 1;
667}
668
bfc6fde4 669WXHICON wxFrame::MSWOnQueryDragIcon()
2bda0e17
KB
670{
671 if (m_icon.Ok() && (m_icon.GetHICON() != 0))
672 return m_icon.GetHICON();
673 else
674 return m_defaultIcon;
675}
676
debe6624 677void wxFrame::MSWOnSize(int x, int y, WXUINT id)
2bda0e17 678{
2bda0e17
KB
679 switch (id)
680 {
2bda0e17 681 case SIZENORMAL:
18453306
VZ
682 // only do it it if we were iconized before, otherwise resizing the
683 // parent frame has a curious side effect of bringing it under it's
684 // children
685 if ( !m_iconized )
686 break;
687
d2aef312
VZ
688 // restore all child frames too
689 IconizeChildFrames(FALSE);
690
691 // fall through
692
693 case SIZEFULLSCREEN:
2bda0e17 694 m_iconized = FALSE;
18453306 695 break;
d2aef312 696
2bda0e17 697 case SIZEICONIC:
d2aef312
VZ
698 // iconize all child frames too
699 IconizeChildFrames(TRUE);
700
2bda0e17 701 m_iconized = TRUE;
18453306 702 break;
2bda0e17
KB
703 }
704
705 if (!m_iconized)
706 {
707 // forward WM_SIZE to status bar control
47d67540 708#if wxUSE_NATIVE_STATUSBAR
2bda0e17
KB
709 if (m_frameStatusBar && m_frameStatusBar->IsKindOf(CLASSINFO(wxStatusBar95)))
710 {
711 wxSizeEvent event(wxSize(x, y), m_frameStatusBar->GetId());
712 event.SetEventObject( m_frameStatusBar );
713
714 ((wxStatusBar95 *)m_frameStatusBar)->OnSize(event);
715 }
716#endif
717
718 PositionStatusBar();
81d66cf3
JS
719 PositionToolBar();
720
2bda0e17
KB
721 wxSizeEvent event(wxSize(x, y), m_windowId);
722 event.SetEventObject( this );
debe6624
JS
723 if (!GetEventHandler()->ProcessEvent(event))
724 Default();
2bda0e17
KB
725 }
726}
727
bfc6fde4 728bool wxFrame::MSWOnClose()
2bda0e17 729{
2bda0e17
KB
730 return Close();
731}
732
debe6624 733bool wxFrame::MSWOnCommand(WXWORD id, WXWORD cmd, WXHWND control)
2bda0e17 734{
2bda0e17
KB
735 if (cmd == 0 || cmd == 1 ) // Can be either a menu command or an accelerator.
736 {
737 // In case it's e.g. a toolbar.
738 wxWindow *win = wxFindWinFromHandle(control);
739 if (win)
740 return win->MSWCommand(cmd, id);
741
e1a6fc11
JS
742 if (wxCurrentPopupMenu)
743 {
744 wxMenu *popupMenu = wxCurrentPopupMenu;
745 wxCurrentPopupMenu = NULL;
746 if (popupMenu->MSWCommand(cmd, id))
747 return TRUE;
748 }
749
2bda0e17
KB
750 if (GetMenuBar() && GetMenuBar()->FindItemForId(id))
751 {
752 ProcessCommand(id);
753 return TRUE;
754 }
755 else
756 return FALSE;
757 }
758 else
c4b10e41 759 return wxWindow::MSWOnCommand(id, cmd, control);
2bda0e17
KB
760}
761
debe6624 762void wxFrame::MSWOnMenuHighlight(WXWORD nItem, WXWORD nFlags, WXHMENU hSysMenu)
2bda0e17 763{
2bda0e17
KB
764 if (nFlags == 0xFFFF && hSysMenu == 0)
765 {
766 wxMenuEvent event(wxEVT_MENU_HIGHLIGHT, -1);
767 event.SetEventObject( this );
768 GetEventHandler()->ProcessEvent(event);
769 }
58abfef6 770 else if ((nFlags != MF_SEPARATOR) && (nItem != 0) && (nItem != 65535))
2bda0e17
KB
771 {
772 wxMenuEvent event(wxEVT_MENU_HIGHLIGHT, nItem);
773 event.SetEventObject( this );
774 GetEventHandler()->ProcessEvent(event);
775 }
2bda0e17
KB
776}
777
778bool wxFrame::MSWProcessMessage(WXMSG* pMsg)
779{
57a7b7c1
JS
780 return FALSE;
781}
782
783bool wxFrame::MSWTranslateMessage(WXMSG* pMsg)
784{
785 if (m_acceleratorTable.Ok() &&
786 ::TranslateAccelerator((HWND) GetHWND(), (HACCEL) m_acceleratorTable.GetHACCEL(), (MSG *)pMsg))
2bda0e17 787 return TRUE;
c2dcfdef 788
2bda0e17
KB
789 return FALSE;
790}
791
792// Default resizing behaviour - if only ONE subwindow,
793// resize to client rectangle size
794void wxFrame::OnSize(wxSizeEvent& event)
795{
cd70477b 796 // if we're using constraints - do use them
47d67540 797 #if wxUSE_CONSTRAINTS
cd70477b
VZ
798 if ( GetAutoLayout() ) {
799 Layout();
800 return;
801 }
802 #endif
803
804 // do we have _exactly_ one child?
2bda0e17 805 wxWindow *child = NULL;
c0ed460c 806 for ( wxNode *node = GetChildren().First(); node; node = node->Next() )
2bda0e17
KB
807 {
808 wxWindow *win = (wxWindow *)node->Data();
cd70477b 809 if ( !win->IsKindOf(CLASSINFO(wxFrame)) &&
c2dcfdef 810 !win->IsKindOf(CLASSINFO(wxDialog)) &&
73e7daa0
JS
811 (win != GetStatusBar()) &&
812 (win != GetToolBar()) )
2bda0e17 813 {
cd70477b
VZ
814 if ( child )
815 return; // it's our second subwindow - nothing to do
2bda0e17 816 child = win;
2bda0e17
KB
817 }
818 }
819
cd70477b
VZ
820 if ( child ) {
821 // we have exactly one child - set it's size to fill the whole frame
73e7daa0
JS
822 int clientW, clientH;
823 GetClientSize(&clientW, &clientH);
2bda0e17 824
73e7daa0
JS
825 int x = 0;
826 int y = 0;
827
73e7daa0 828 child->SetSize(x, y, clientW, clientH);
2bda0e17 829 }
2bda0e17
KB
830}
831
832// Default activation behaviour - set the focus for the first child
833// subwindow found.
834void wxFrame::OnActivate(wxActivateEvent& event)
835{
c0ed460c 836 for(wxNode *node = GetChildren().First(); node; node = node->Next())
2bda0e17
KB
837 {
838 // Find a child that's a subwindow, but not a dialog box.
839 wxWindow *child = (wxWindow *)node->Data();
840 if (!child->IsKindOf(CLASSINFO(wxFrame)) &&
841 !child->IsKindOf(CLASSINFO(wxDialog)))
842 {
2bda0e17
KB
843 child->SetFocus();
844 return;
845 }
846 }
847}
848
e3065973 849// The default implementation for the close window event.
2bda0e17
KB
850void wxFrame::OnCloseWindow(wxCloseEvent& event)
851{
e3065973 852 this->Destroy();
47fa7969
JS
853}
854
2bda0e17 855// Destroy the window (delayed, if a managed window)
bfc6fde4 856bool wxFrame::Destroy()
2bda0e17
KB
857{
858 if (!wxPendingDelete.Member(this))
859 wxPendingDelete.Append(this);
860 return TRUE;
861}
862
863// Default menu selection behaviour - display a help string
864void wxFrame::OnMenuHighlight(wxMenuEvent& event)
865{
866 if (GetStatusBar())
867 {
d20eef8a
VZ
868 int menuId = event.GetMenuId();
869 if ( menuId != -1 )
2bda0e17
KB
870 {
871 wxMenuBar *menuBar = GetMenuBar();
58abfef6 872 if (menuBar && menuBar->FindItem(menuId))
2bda0e17 873 {
d20eef8a
VZ
874 // set status text even if the string is empty - this will at
875 // least remove the string from the item which was previously
876 // selected
877 SetStatusText(menuBar->GetHelpString(menuId));
2bda0e17
KB
878 }
879 }
880 }
881}
882
bfc6fde4 883wxMenuBar *wxFrame::GetMenuBar() const
2bda0e17
KB
884{
885 return m_frameMenuBar;
886}
887
debe6624 888void wxFrame::Centre(int direction)
2bda0e17
KB
889{
890 int display_width, display_height, width, height, x, y;
891 wxDisplaySize(&display_width, &display_height);
892
893 GetSize(&width, &height);
894 GetPosition(&x, &y);
895
896 if (direction & wxHORIZONTAL)
897 x = (int)((display_width - width)/2);
898 if (direction & wxVERTICAL)
899 y = (int)((display_height - height)/2);
900
901 SetSize(x, y, width, height);
902}
903
904// Call this to simulate a menu command
905void wxFrame::Command(int id)
906{
907 ProcessCommand(id);
908}
909
910void wxFrame::ProcessCommand(int id)
911{
f5419957 912 wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, id);
2bda0e17
KB
913 commandEvent.SetInt( id );
914 commandEvent.SetEventObject( this );
915
916 wxMenuBar *bar = GetMenuBar() ;
917 if (!bar)
918 return;
919
2bda0e17
KB
920 wxMenuItem *item = bar->FindItemForId(id) ;
921 if (item && item->IsCheckable())
922 {
2bda0e17
KB
923 bar->Check(id,!bar->Checked(id)) ;
924 }
e702ff0f 925
6c41a418 926/*
e702ff0f
JS
927 // Process events starting with the window with the focus, if any.
928 wxWindow* focusWin = wxFindFocusDescendant(this);
929
930 wxEvtHandler* evtHandler = focusWin ? focusWin->GetEventHandler() : GetEventHandler();
6c41a418
JS
931*/
932
933 wxEvtHandler* evtHandler = GetEventHandler();
e702ff0f 934 evtHandler->ProcessEvent(commandEvent);
2bda0e17
KB
935}
936
81d66cf3
JS
937// Checks if there is a toolbar, and returns the first free client position
938wxPoint wxFrame::GetClientAreaOrigin() const
939{
940 wxPoint pt(0, 0);
941 if (GetToolBar())
942 {
943 int w, h;
944 GetToolBar()->GetSize(& w, & h);
945
946 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL)
947 {
948 pt.x += w;
949 }
950 else
951 {
952 pt.y += h;
953 }
954 }
955 return pt;
956}
957
87d1e11f
JS
958void wxFrame::ScreenToClient(int *x, int *y) const
959{
960 wxWindow::ScreenToClient(x, y);
961
962 // We may be faking the client origin.
963 // So a window that's really at (0, 30) may appear
964 // (to wxWin apps) to be at (0, 0).
965 wxPoint pt(GetClientAreaOrigin());
966 *x -= pt.x;
967 *y -= pt.y;
968}
969
970void wxFrame::ClientToScreen(int *x, int *y) const
971{
972 // We may be faking the client origin.
973 // So a window that's really at (0, 30) may appear
974 // (to wxWin apps) to be at (0, 0).
975 wxPoint pt1(GetClientAreaOrigin());
976 *x += pt1.x;
977 *y += pt1.y;
978
979 wxWindow::ClientToScreen(x, y);
980}
981
81d66cf3
JS
982wxToolBar* wxFrame::CreateToolBar(long style, wxWindowID id, const wxString& name)
983{
984 wxCHECK_MSG( m_frameToolBar == NULL, FALSE,
985 "recreating toolbar in wxFrame" );
986
987 wxToolBar* toolBar = OnCreateToolBar(style, id, name);
988 if (toolBar)
989 {
990 SetToolBar(toolBar);
991 PositionToolBar();
992 return toolBar;
993 }
994 else
995 {
996 return NULL;
997 }
998}
999
1000wxToolBar* wxFrame::OnCreateToolBar(long style, wxWindowID id, const wxString& name)
1001{
1002 return new wxToolBar(this, id, wxDefaultPosition, wxDefaultSize, style, name);
1003}
1004
bfc6fde4 1005void wxFrame::PositionToolBar()
81d66cf3 1006{
81d66cf3
JS
1007 RECT rect;
1008 ::GetClientRect((HWND) GetHWND(), &rect);
1009
1010 if ( GetStatusBar() )
1011 {
1012 int statusX, statusY;
1013 GetStatusBar()->GetClientSize(&statusX, &statusY);
1014 rect.bottom -= statusY;
1015 }
1016
1017 if (GetToolBar())
1018 {
1019 int tw, th;
1020 GetToolBar()->GetSize(& tw, & th);
1021
1022 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL)
1023 {
1024 // Use the 'real' MSW position
1025 GetToolBar()->SetSize(0, 0, tw, rect.bottom, wxSIZE_NO_ADJUSTMENTS);
1026 }
1027 else
1028 {
1029 // Use the 'real' MSW position
1030 GetToolBar()->SetSize(0, 0, rect.right, th, wxSIZE_NO_ADJUSTMENTS);
1031 }
1032 }
1033}
d2aef312
VZ
1034
1035// propagate our state change to all child frames
1036void wxFrame::IconizeChildFrames(bool bIconize)
1037{
c0ed460c 1038 for ( wxNode *node = GetChildren().First(); node; node = node->Next() ) {
d2aef312
VZ
1039 wxWindow *win = (wxWindow *)node->Data();
1040 if ( win->IsKindOf(CLASSINFO(wxFrame)) ) {
1041 ((wxFrame *)win)->Iconize(bIconize);
1042 }
1043 }
1044}
1045