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