]> git.saurik.com Git - wxWidgets.git/blame - src/msw/frame.cpp
now compiles with USE_XPM_IN_MSW on, added error messages if bitmap can't
[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__
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
46extern wxList wxModelessWindows;
47extern wxList wxPendingDelete;
48extern char wxFrameClassName[];
49
50#if !USE_SHARED_LIBRARY
51BEGIN_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)
58END_EVENT_TABLE()
59
60IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxWindow)
61#endif
62
63#if USE_NATIVE_STATUSBAR
64bool wxFrame::m_useNativeStatusBar = TRUE;
65#else
66bool wxFrame::m_useNativeStatusBar = FALSE;
67#endif
68
69wxFrame::wxFrame(void)
70{
71 m_frameMenuBar = NULL;
72 m_frameStatusBar = NULL;
73
74 m_windowParent = NULL;
75 m_iconized = FALSE;
76}
77
78bool 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
118wxFrame::~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
150WXHMENU 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
157void 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)
174void 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
211void 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
219void 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
231void 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
261bool 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
297void 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
312void 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
324bool wxFrame::IsIconized(void) const
325{
326 ((wxFrame *)this)->m_iconized = (::IsIconic((HWND) GetHWND()) != 0);
327 return m_iconized;
328}
329
330void wxFrame::SetTitle(const wxString& title)
331{
332 SetWindowText((HWND) GetHWND(), (const char *)title);
333}
334
335wxString wxFrame::GetTitle(void) const
336{
337 GetWindowText((HWND) GetHWND(), wxBuffer, 1000);
338 return wxString(wxBuffer);
339}
340
341void 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
351wxStatusBar *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
381bool 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
396void wxFrame::SetStatusText(const wxString& text, const int number)
397{
398 wxCHECK( m_frameStatusBar != NULL );
399
400 m_frameStatusBar->SetStatusText(text, number);
401}
402
403void 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
411void 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
428void 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
474bool 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
494void 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.
524void 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
545void 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
607bool 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
656WXHICON 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
664void 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
704bool wxFrame::MSWOnClose(void)
705{
706#if DEBUG > 1
707 wxDebugMsg("wxFrameWnd::OnClose %d\n", handle);
708#endif
709 return Close();
710}
711
712bool 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
736void 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
759bool 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
770void 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.
817void 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
838void 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)
848bool 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
856void 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
876void 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.
927void 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
952void 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
978wxMenuBar *wxFrame::GetMenuBar(void) const
979{
980 return m_frameMenuBar;
981}
982
983void 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
1000void wxFrame::Command(int id)
1001{
1002 ProcessCommand(id);
1003}
1004
1005void 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
1028void wxFrame::OnIdle(wxIdleEvent& event)
1029{
1030 DoMenuUpdates();
1031}
1032
1033// Query app for menu item updates (called from OnIdle)
1034void 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
1049void 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}