]> git.saurik.com Git - wxWidgets.git/blame - src/msw/toplevel.cpp
undid WS_EX_CONTROLPARENT change -- I recall now why we can't use it
[wxWidgets.git] / src / msw / toplevel.cpp
CommitLineData
82c9f85c
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: msw/toplevel.cpp
3// Purpose: implements wxTopLevelWindow for MSW
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 24.09.01
7// RCS-ID: $Id$
8// Copyright: (c) 2001 SciTech Software, Inc. (www.scitechsoft.com)
9// License: wxWindows license
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20#ifdef __GNUG__
21 #pragma implementation "toplevel.h"
22#endif
23
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
27#ifdef __BORLANDC__
28 #pragma hdrstop
29#endif
30
31#ifndef WX_PRECOMP
3a922bb4
RL
32 #include "wx/app.h"
33 #include "wx/toplevel.h"
82c9f85c
VZ
34 #include "wx/string.h"
35 #include "wx/log.h"
36 #include "wx/intl.h"
14dd645e 37 #include "wx/frame.h"
82c9f85c
VZ
38#endif //WX_PRECOMP
39
40#include "wx/msw/private.h"
41
7e25f59e
VZ
42#include "wx/popupwin.h"
43
e121a72a
MB
44#ifndef ICON_BIG
45 #define ICON_BIG 1
46#endif
47
48#ifndef ICON_SMALL
49 #define ICON_SMALL 0
50#endif
51
82c9f85c
VZ
52// ----------------------------------------------------------------------------
53// stubs for missing functions under MicroWindows
54// ----------------------------------------------------------------------------
55
56#ifdef __WXMICROWIN__
57
c67d6888 58// static inline bool IsIconic(HWND WXUNUSED(hwnd)) { return FALSE; }
82c9f85c
VZ
59static inline bool IsZoomed(HWND WXUNUSED(hwnd)) { return FALSE; }
60
61#endif // __WXMICROWIN__
62
63// ----------------------------------------------------------------------------
64// globals
65// ----------------------------------------------------------------------------
66
67// list of all frames and modeless dialogs
68wxWindowList wxModelessWindows;
69
b225f659
VZ
70// the name of the default wxWindows class
71extern const wxChar *wxCanvasClassName;
72
9dfef5ac
VZ
73// the hidden parent for wxFRAME_NO_TASKBAR unowned frames
74wxWindow *wxTopLevelWindowMSW::ms_hiddenParent = NULL;
75
82c9f85c
VZ
76// ============================================================================
77// wxTopLevelWindowMSW implementation
78// ============================================================================
79
7fe1a8b5
VZ
80// ----------------------------------------------------------------------------
81// wxDialog helpers
82// ----------------------------------------------------------------------------
83
b225f659
VZ
84// Dialog window proc
85LONG APIENTRY _EXPORT
7fe1a8b5 86wxDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
b225f659 87{
7fe1a8b5 88 switch ( message )
b225f659 89 {
7fe1a8b5 90 case WM_INITDIALOG:
dea077b1
VZ
91 // for this message, returning TRUE tells system to set focus to
92 // the first control in the dialog box, but as we set the focus
93 // ourselves, we return FALSE from here as well, so fall through
7fe1a8b5
VZ
94
95 default:
96 // for all the other ones, FALSE means that we didn't process the
97 // message
98 return FALSE;
b225f659
VZ
99 }
100}
101
82c9f85c
VZ
102// ----------------------------------------------------------------------------
103// wxTopLevelWindowMSW creation
104// ----------------------------------------------------------------------------
105
106void wxTopLevelWindowMSW::Init()
107{
108 m_iconized =
109 m_maximizeOnShow = FALSE;
b225f659
VZ
110
111 // unlike (almost?) all other windows, frames are created hidden
112 m_isShown = FALSE;
c641b1d2
VS
113
114 // Data to save/restore when calling ShowFullScreen
115 m_fsStyle = 0;
116 m_fsOldWindowStyle = 0;
117 m_fsIsMaximized = FALSE;
118 m_fsIsShowing = FALSE;
b225f659
VZ
119}
120
b2d5a7ee 121WXDWORD wxTopLevelWindowMSW::MSWGetStyle(long style, WXDWORD *exflags) const
b225f659 122{
b2d5a7ee
VZ
123 // let the base class deal with the common styles but fix the ones which
124 // don't make sense for us (we also deal with the borders ourselves)
125 WXDWORD msflags = wxWindow::MSWGetStyle
126 (
127 (style & ~wxBORDER_MASK) | wxBORDER_NONE, exflags
128 ) & ~WS_CHILD;
b225f659
VZ
129
130 // first select the kind of window being created
dfb06c62
VZ
131 //
132 // note that if we don't set WS_POPUP, Windows assumes WS_OVERLAPPED and
133 // creates a window with both caption and border, hence we also test it
134 // below in some other cases
0e082993 135 if ( style & wxFRAME_TOOL_WINDOW )
b2d5a7ee 136 msflags |= WS_POPUP;
b225f659 137 else
b2d5a7ee 138 msflags |= WS_OVERLAPPED;
0e082993
VZ
139
140 // border and caption styles
141 if ( style & wxRESIZE_BORDER )
142 msflags |= WS_THICKFRAME;
143 else if ( !(style & wxBORDER_NONE) )
144 msflags |= WS_BORDER;
dfb06c62
VZ
145 else
146 msflags |= WS_POPUP;
0e082993
VZ
147
148 if ( style & wxCAPTION )
149 msflags |= WS_CAPTION;
dfb06c62 150 else
b225f659 151 msflags |= WS_POPUP;
b225f659
VZ
152
153 // next translate the individual flags
154 if ( style & wxMINIMIZE_BOX )
155 msflags |= WS_MINIMIZEBOX;
156 if ( style & wxMAXIMIZE_BOX )
157 msflags |= WS_MAXIMIZEBOX;
b225f659
VZ
158 if ( style & wxSYSTEM_MENU )
159 msflags |= WS_SYSMENU;
160 if ( style & wxMINIMIZE )
161 msflags |= WS_MINIMIZE;
162 if ( style & wxMAXIMIZE )
163 msflags |= WS_MAXIMIZE;
0e082993 164
b225f659
VZ
165 // Keep this here because it saves recoding this function in wxTinyFrame
166#if wxUSE_ITSY_BITSY && !defined(__WIN32__)
167 if ( style & wxTINY_CAPTION_VERT )
168 msflags |= IBS_VERTCAPTION;
169 if ( style & wxTINY_CAPTION_HORIZ )
170 msflags |= IBS_HORZCAPTION;
171#else
172 if ( style & (wxTINY_CAPTION_VERT | wxTINY_CAPTION_HORIZ) )
173 msflags |= WS_CAPTION;
174#endif
175
176 if ( exflags )
177 {
b225f659 178#if !defined(__WIN16__) && !defined(__SC__)
35bf863b
VZ
179 if ( !(GetExtraStyle() & wxTOPLEVEL_EX_DIALOG) )
180 {
9dfef5ac
VZ
181 if ( style & wxFRAME_TOOL_WINDOW )
182 {
183 // create the palette-like window
35bf863b 184 *exflags |= WS_EX_TOOLWINDOW;
9dfef5ac
VZ
185 }
186
187 // We have to solve 2 different problems here:
188 //
189 // 1. frames with wxFRAME_NO_TASKBAR flag shouldn't appear in the
190 // taskbar even if they don't have a parent
191 //
192 // 2. frames without this style should appear in the taskbar even
193 // if they're owned (Windows only puts non owned windows into
194 // the taskbar normally)
195 //
196 // The second one is solved here by using WS_EX_APPWINDOW flag, the
197 // first one is dealt with in our MSWGetParent() method
198 // implementation
199 if ( !(style & wxFRAME_NO_TASKBAR) && GetParent() )
200 {
201 // need to force the frame to appear in the taskbar
35bf863b 202 *exflags |= WS_EX_APPWINDOW;
9dfef5ac
VZ
203 }
204 //else: nothing to do [here]
35bf863b
VZ
205 }
206#endif // !Win16
b225f659
VZ
207
208 if ( style & wxSTAY_ON_TOP )
209 *exflags |= WS_EX_TOPMOST;
210
211#ifdef __WIN32__
b2d5a7ee 212 if ( GetExtraStyle() & wxFRAME_EX_CONTEXTHELP )
68d02db3 213 *exflags |= WS_EX_CONTEXTHELP;
b225f659
VZ
214#endif // __WIN32__
215 }
216
217 return msflags;
218}
219
9dfef5ac
VZ
220WXHWND wxTopLevelWindowMSW::MSWGetParent() const
221{
222 // for the frames without wxFRAME_FLOAT_ON_PARENT style we should use NULL
223 // parent HWND or it would be always on top of its parent which is not what
224 // we usually want (in fact, we only want it for frames with the
225 // wxFRAME_FLOAT_ON_PARENT flag)
226 wxWindow *parent;
227 if ( HasFlag(wxFRAME_FLOAT_ON_PARENT) )
228 {
229 parent = GetParent();
230
231 // this flag doesn't make sense then and will be ignored
232 wxASSERT_MSG( parent,
233 _T("wxFRAME_FLOAT_ON_PARENT but no parent?") );
234 }
235 else // don't float on parent, must not be owned
236 {
237 parent = NULL;
238 }
239
240 // now deal with the 2nd taskbar-related problem (see comments above in
241 // MSWGetStyle())
242 if ( HasFlag(wxFRAME_NO_TASKBAR) && !parent )
243 {
244 if ( !ms_hiddenParent )
245 {
246 ms_hiddenParent = new wxTopLevelWindowMSW(NULL, -1, _T(""));
247
248 // we shouldn't leave it in wxTopLevelWindows or we wouldn't
249 // terminate the app when the last user-created frame is deleted --
250 // see ~wxTopLevelWindowMSW
251 wxTopLevelWindows.DeleteObject(ms_hiddenParent);
252 }
253
254 parent = ms_hiddenParent;
255 }
256
257 return parent ? parent->GetHWND() : NULL;
258}
259
6e8515a3 260bool wxTopLevelWindowMSW::CreateDialog(const void *dlgTemplate,
b225f659
VZ
261 const wxString& title,
262 const wxPoint& pos,
263 const wxSize& size)
264{
265#ifdef __WXMICROWIN__
266 // no dialogs support under MicroWin yet
267 return CreateFrame(title, pos, size);
268#else // !__WXMICROWIN__
269 wxWindow *parent = GetParent();
270
271 // for the dialogs without wxDIALOG_NO_PARENT style, use the top level
272 // app window as parent - this avoids creating modal dialogs without
273 // parent
274 if ( !parent && !(GetWindowStyleFlag() & wxDIALOG_NO_PARENT) )
275 {
276 parent = wxTheApp->GetTopWindow();
e058b98d 277
39cc7a0b 278 if ( parent )
e058b98d 279 {
39cc7a0b
VZ
280 // don't use transient windows as parents, this is dangerous as it
281 // can lead to a crash if the parent is destroyed before the child
282 //
283 // also don't use the window which is currently hidden as then the
284 // dialog would be hidden as well
285 if ( (parent->GetExtraStyle() & wxWS_EX_TRANSIENT) ||
286 !parent->IsShown() )
287 {
288 parent = NULL;
289 }
e058b98d 290 }
b225f659
VZ
291 }
292
434005ca
VZ
293 m_hWnd = (WXHWND)::CreateDialogIndirect
294 (
295 wxGetInstance(),
296 (DLGTEMPLATE*)dlgTemplate,
297 parent ? GetHwndOf(parent) : NULL,
298 (DLGPROC)wxDlgProc
299 );
b225f659
VZ
300
301 if ( !m_hWnd )
302 {
6e8515a3 303 wxFAIL_MSG(_("Failed to create dialog. Incorrect DLGTEMPLATE?"));
b225f659 304
6e8515a3 305 wxLogSysError(_("Can't create dialog using memory template"));
b225f659
VZ
306
307 return FALSE;
308 }
309
b2d5a7ee 310 WXDWORD exflags;
b225f659
VZ
311 (void)MSWGetCreateWindowFlags(&exflags);
312
313 if ( exflags )
314 {
315 ::SetWindowLong(GetHwnd(), GWL_EXSTYLE, exflags);
316 ::SetWindowPos(GetHwnd(), NULL, 0, 0, 0, 0,
317 SWP_NOSIZE |
318 SWP_NOMOVE |
319 SWP_NOZORDER |
320 SWP_NOACTIVATE);
321 }
322
323#if defined(__WIN95__)
324 // For some reason, the system menu is activated when we use the
325 // WS_EX_CONTEXTHELP style, so let's set a reasonable icon
326 if ( exflags & WS_EX_CONTEXTHELP )
327 {
328 wxFrame *winTop = wxDynamicCast(wxTheApp->GetTopWindow(), wxFrame);
329 if ( winTop )
330 {
331 wxIcon icon = winTop->GetIcon();
332 if ( icon.Ok() )
333 {
334 ::SendMessage(GetHwnd(), WM_SETICON,
335 (WPARAM)TRUE,
336 (LPARAM)GetHiconOf(icon));
337 }
338 }
339 }
340#endif // __WIN95__
341
342 // move the dialog to its initial position without forcing repainting
343 int x, y, w, h;
4c53c743 344 if ( !MSWGetCreateWindowCoords(pos, size, x, y, w, h) )
b225f659 345 {
4c53c743
VZ
346 x =
347 w = (int)CW_USEDEFAULT;
348 }
f04a0744 349
4c53c743
VZ
350 // we can't use CW_USEDEFAULT here as we're not calling CreateWindow()
351 // and passing CW_USEDEFAULT to MoveWindow() results in resizing the
352 // window to (0, 0) size which breaks quite a lot of things, e.g. the
353 // sizer calculation in wxSizer::Fit()
354 if ( w == (int)CW_USEDEFAULT )
355 {
356 // the exact number doesn't matter, the dialog will be resized
357 // again soon anyhow but it should be big enough to allow
358 // calculation relying on "totalSize - clientSize > 0" work, i.e.
359 // at least greater than the title bar height
360 w =
361 h = 100;
362 }
f0adbe0f 363
4c53c743
VZ
364 if ( x == (int)CW_USEDEFAULT )
365 {
366 // centre it on the screen - what else can we do?
367 wxSize sizeDpy = wxGetDisplaySize();
368
369 x = (sizeDpy.x - w) / 2;
370 y = (sizeDpy.y - h) / 2;
371 }
372
373 if ( !::MoveWindow(GetHwnd(), x, y, w, h, FALSE) )
374 {
375 wxLogLastError(wxT("MoveWindow"));
b225f659 376 }
b225f659
VZ
377
378 if ( !title.empty() )
379 {
380 ::SetWindowText(GetHwnd(), title);
381 }
382
383 SubclassWin(m_hWnd);
384
385 return TRUE;
386#endif // __WXMICROWIN__/!__WXMICROWIN__
387}
388
389bool wxTopLevelWindowMSW::CreateFrame(const wxString& title,
390 const wxPoint& pos,
391 const wxSize& size)
392{
b2d5a7ee
VZ
393 WXDWORD exflags;
394 WXDWORD flags = MSWGetCreateWindowFlags(&exflags);
b225f659
VZ
395
396 return MSWCreate(wxCanvasClassName, title, pos, size, flags, exflags);
82c9f85c
VZ
397}
398
399bool wxTopLevelWindowMSW::Create(wxWindow *parent,
400 wxWindowID id,
401 const wxString& title,
402 const wxPoint& pos,
403 const wxSize& size,
404 long style,
405 const wxString& name)
406{
407 // init our fields
408 Init();
409
410 m_windowStyle = style;
411
412 SetName(name);
413
414 m_windowId = id == -1 ? NewControlId() : id;
415
416 wxTopLevelWindows.Append(this);
417
418 if ( parent )
419 parent->AddChild(this);
420
b225f659
VZ
421 if ( GetExtraStyle() & wxTOPLEVEL_EX_DIALOG )
422 {
b225f659
VZ
423 // we have different dialog templates to allows creation of dialogs
424 // with & without captions under MSWindows, resizeable or not (but a
425 // resizeable dialog always has caption - otherwise it would look too
426 // strange)
434005ca
VZ
427
428 // we need 3 additional WORDs for dialog menu, class and title (as we
429 // don't use DS_SETFONT we don't need the fourth WORD for the font)
430 static const int dlgsize = sizeof(DLGTEMPLATE) + (sizeof(WORD) * 3);
431 DLGTEMPLATE *dlgTemplate = (DLGTEMPLATE *)malloc(dlgsize);
432 memset(dlgTemplate, 0, dlgsize);
433
434 // these values are arbitrary, they won't be used normally anyhow
6e8515a3
JS
435 dlgTemplate->x = 34;
436 dlgTemplate->y = 22;
437 dlgTemplate->cx = 144;
438 dlgTemplate->cy = 75;
439
434005ca
VZ
440 // reuse the code in MSWGetStyle() but correct the results slightly for
441 // the dialog
442 dlgTemplate->style = MSWGetStyle(style, NULL);
443
444 // all dialogs are popups
445 dlgTemplate->style |= WS_POPUP;
446
447 // force 3D-look if necessary, it looks impossibly ugly otherwise
448 if ( style & (wxRESIZE_BORDER | wxCAPTION) )
449 dlgTemplate->style |= DS_MODALFRAME;
b225f659 450
6e8515a3
JS
451 bool ret = CreateDialog(dlgTemplate, title, pos, size);
452 free(dlgTemplate);
434005ca 453
6e8515a3 454 return ret;
b225f659
VZ
455 }
456 else // !dialog
457 {
458 return CreateFrame(title, pos, size);
459 }
82c9f85c
VZ
460}
461
462wxTopLevelWindowMSW::~wxTopLevelWindowMSW()
463{
9dfef5ac
VZ
464 if ( this == ms_hiddenParent )
465 {
466 // stop [infinite] recursion which would otherwise happen when we do
467 // "delete ms_hiddenParent" below
468 return;
469 }
470
82c9f85c
VZ
471 wxTopLevelWindows.DeleteObject(this);
472
473 if ( wxModelessWindows.Find(this) )
474 wxModelessWindows.DeleteObject(this);
475
476 // If this is the last top-level window, exit.
477 if ( wxTheApp && (wxTopLevelWindows.Number() == 0) )
478 {
9dfef5ac
VZ
479 if ( ms_hiddenParent )
480 {
481 delete ms_hiddenParent;
482 ms_hiddenParent = NULL;
483 }
484
82c9f85c
VZ
485 wxTheApp->SetTopWindow(NULL);
486
487 if ( wxTheApp->GetExitOnFrameDelete() )
488 {
489 ::PostQuitMessage(0);
490 }
491 }
492}
493
82c9f85c
VZ
494// ----------------------------------------------------------------------------
495// wxTopLevelWindowMSW showing
496// ----------------------------------------------------------------------------
497
498void wxTopLevelWindowMSW::DoShowWindow(int nShowCmd)
499{
500 ::ShowWindow(GetHwnd(), nShowCmd);
501
502 m_iconized = nShowCmd == SW_MINIMIZE;
503}
504
505bool wxTopLevelWindowMSW::Show(bool show)
506{
507 // don't use wxWindow version as we want to call DoShowWindow() ourselves
508 if ( !wxWindowBase::Show(show) )
509 return FALSE;
510
511 int nShowCmd;
512 if ( show )
513 {
514 if ( m_maximizeOnShow )
515 {
516 // show and maximize
517 nShowCmd = SW_MAXIMIZE;
518
519 m_maximizeOnShow = FALSE;
520 }
521 else // just show
522 {
523 nShowCmd = SW_SHOW;
524 }
525 }
526 else // hide
527 {
528 nShowCmd = SW_HIDE;
529 }
530
531 DoShowWindow(nShowCmd);
532
533 if ( show )
534 {
535 ::BringWindowToTop(GetHwnd());
536
537 wxActivateEvent event(wxEVT_ACTIVATE, TRUE, m_windowId);
538 event.SetEventObject( this );
539 GetEventHandler()->ProcessEvent(event);
540 }
541 else // hide
542 {
543 // Try to highlight the correct window (the parent)
544 if ( GetParent() )
545 {
546 HWND hWndParent = GetHwndOf(GetParent());
547 if (hWndParent)
548 ::BringWindowToTop(hWndParent);
549 }
550 }
551
552 return TRUE;
553}
554
555// ----------------------------------------------------------------------------
556// wxTopLevelWindowMSW maximize/minimize
557// ----------------------------------------------------------------------------
558
559void wxTopLevelWindowMSW::Maximize(bool maximize)
560{
561 if ( IsShown() )
562 {
563 // just maximize it directly
564 DoShowWindow(maximize ? SW_MAXIMIZE : SW_RESTORE);
565 }
566 else // hidden
567 {
568 // we can't maximize the hidden frame because it shows it as well, so
569 // just remember that we should do it later in this case
570 m_maximizeOnShow = TRUE;
571 }
572}
573
574bool wxTopLevelWindowMSW::IsMaximized() const
575{
576 return ::IsZoomed(GetHwnd()) != 0;
577}
578
579void wxTopLevelWindowMSW::Iconize(bool iconize)
580{
581 DoShowWindow(iconize ? SW_MINIMIZE : SW_RESTORE);
582}
583
584bool wxTopLevelWindowMSW::IsIconized() const
585{
586 // also update the current state
587 ((wxTopLevelWindowMSW *)this)->m_iconized = ::IsIconic(GetHwnd()) != 0;
588
589 return m_iconized;
590}
591
592void wxTopLevelWindowMSW::Restore()
593{
594 DoShowWindow(SW_RESTORE);
595}
596
c641b1d2
VS
597// ----------------------------------------------------------------------------
598// wxTopLevelWindowMSW fullscreen
599// ----------------------------------------------------------------------------
600
601bool wxTopLevelWindowMSW::ShowFullScreen(bool show, long style)
602{
603 if (show)
604 {
605 if (IsFullScreen())
606 return FALSE;
607
608 m_fsIsShowing = TRUE;
609 m_fsStyle = style;
610
611 // zap the frame borders
612
613 // save the 'normal' window style
614 m_fsOldWindowStyle = GetWindowLong((HWND)GetHWND(), GWL_STYLE);
615
616 // save the old position, width & height, maximize state
617 m_fsOldSize = GetRect();
618 m_fsIsMaximized = IsMaximized();
619
620 // decide which window style flags to turn off
621 LONG newStyle = m_fsOldWindowStyle;
622 LONG offFlags = 0;
623
624 if (style & wxFULLSCREEN_NOBORDER)
625 offFlags |= WS_BORDER | WS_THICKFRAME;
626 if (style & wxFULLSCREEN_NOCAPTION)
627 offFlags |= (WS_CAPTION | WS_SYSMENU);
628
629 newStyle &= (~offFlags);
630
631 // change our window style to be compatible with full-screen mode
632 ::SetWindowLong((HWND)GetHWND(), GWL_STYLE, newStyle);
633
634 // resize to the size of the desktop
635 int width, height;
636
637 RECT rect = wxGetWindowRect(::GetDesktopWindow());
638 width = rect.right - rect.left;
639 height = rect.bottom - rect.top;
640
641 SetSize(width, height);
642
643 // now flush the window style cache and actually go full-screen
644 SetWindowPos((HWND)GetHWND(), HWND_TOP, 0, 0, width, height, SWP_FRAMECHANGED);
645
646 wxSizeEvent event(wxSize(width, height), GetId());
647 GetEventHandler()->ProcessEvent(event);
648
649 return TRUE;
650 }
651 else
652 {
653 if (!IsFullScreen())
654 return FALSE;
655
656 m_fsIsShowing = FALSE;
657
658 Maximize(m_fsIsMaximized);
659 SetWindowLong((HWND)GetHWND(),GWL_STYLE, m_fsOldWindowStyle);
660 SetWindowPos((HWND)GetHWND(),HWND_TOP,m_fsOldSize.x, m_fsOldSize.y,
661 m_fsOldSize.width, m_fsOldSize.height, SWP_FRAMECHANGED);
662
663 return TRUE;
664 }
665}
666
82c9f85c
VZ
667// ----------------------------------------------------------------------------
668// wxTopLevelWindowMSW misc
669// ----------------------------------------------------------------------------
670
671void wxTopLevelWindowMSW::SetIcon(const wxIcon& icon)
672{
f618020a
MB
673 SetIcons( wxIconBundle( icon ) );
674}
675
676void wxTopLevelWindowMSW::SetIcons(const wxIconBundle& icons)
677{
678 wxTopLevelWindowBase::SetIcons(icons);
82c9f85c
VZ
679
680#if defined(__WIN95__) && !defined(__WXMICROWIN__)
f618020a
MB
681 const wxIcon& sml = icons.GetIcon( wxSize( 16, 16 ) );
682 if( sml.Ok() && sml.GetWidth() == 16 && sml.GetHeight() == 16 )
683 {
684 ::SendMessage( GetHwndOf( this ), WM_SETICON, ICON_SMALL,
685 (LPARAM)GetHiconOf(sml) );
686 }
687
688 const wxIcon& big = icons.GetIcon( wxSize( 32, 32 ) );
689 if( big.Ok() && big.GetWidth() == 32 && big.GetHeight() == 32 )
82c9f85c 690 {
f618020a
MB
691 ::SendMessage( GetHwndOf( this ), WM_SETICON, ICON_BIG,
692 (LPARAM)GetHiconOf(big) );
82c9f85c
VZ
693 }
694#endif // __WIN95__
695}
a91cf80c
VZ
696
697bool wxTopLevelWindowMSW::EnableCloseButton(bool enable)
698{
699#ifndef __WXMICROWIN__
700 // get system (a.k.a. window) menu
701 HMENU hmenu = ::GetSystemMenu(GetHwnd(), FALSE /* get it */);
702 if ( !hmenu )
703 {
704 wxLogLastError(_T("GetSystemMenu"));
705
706 return FALSE;
707 }
708
709 // enabling/disabling the close item from it also automatically
710 // disables/enables the close title bar button
aaf765a5
VZ
711 if ( ::EnableMenuItem(hmenu, SC_CLOSE,
712 MF_BYCOMMAND |
713 (enable ? MF_ENABLED : MF_GRAYED)) == -1 )
a91cf80c
VZ
714 {
715 wxLogLastError(_T("EnableMenuItem(SC_CLOSE)"));
716
717 return FALSE;
718 }
719
720 // update appearance immediately
721 if ( !::DrawMenuBar(GetHwnd()) )
722 {
723 wxLogLastError(_T("DrawMenuBar"));
724 }
725#endif // !__WXMICROWIN__
726
727 return TRUE;
728}
729
7e25f59e
VZ
730// ----------------------------------------------------------------------------
731// wxTopLevelWindowMSW message processing
732// ----------------------------------------------------------------------------
733
734long wxTopLevelWindowMSW::HandleNcActivate(bool activate)
735{
736#if wxUSE_POPUPWIN
737 /*
738 Normally, when another top level (whether it is overlapped or popup)
739 window is shown, it is activated and the parent window (i.e. we) loses
740 the activation. This, however, looks very ugly when the child window is
741 a [custom] combobox which we implement using a popup window as surely
742 opening a combobox shouldn't result in deactivating the parent window.
743
744 So we don't redraw the title bar in this case, even if we still return
745 TRUE to let the change of activation to take place as otherwise the
746 controls inside the popup window wouldn't work properly.
747 */
748 if ( !activate && wxPopupWindow::FindPopupFor(this) )
749 {
750 return TRUE;
751 }
752#endif // wxUSE_POPUPWIN
753
754 return FALSE;
755}
756
757long
758wxTopLevelWindowMSW::MSWWindowProc(WXUINT msg, WXWPARAM wParam, WXLPARAM lParam)
759{
760 if ( msg == WM_NCACTIVATE && HandleNcActivate(wParam != 0) )
761 {
762 // we processed WM_NCACTIVATE ourselves
763 return TRUE;
764 }
765
766 return wxTopLevelWindowBase::MSWWindowProc(msg, wParam, lParam);
767}