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