1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/msw/toplevel.cpp 
   3 // Purpose:     implements wxTopLevelWindow for MSW 
   4 // Author:      Vadim Zeitlin 
   8 // Copyright:   (c) 2001 SciTech Software, Inc. (www.scitechsoft.com) 
   9 // License:     wxWindows licence 
  10 /////////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  20 // For compilers that support precompilation, includes "wx.h". 
  21 #include "wx/wxprec.h" 
  27 #include "wx/toplevel.h" 
  31     #include "wx/dialog.h" 
  32     #include "wx/string.h" 
  36     #include "wx/containr.h"        // wxSetFocusToChild() 
  39 #include "wx/module.h" 
  40 #include "wx/dynlib.h" 
  42 #include "wx/msw/private.h" 
  43 #if defined(__WXWINCE__) && !defined(__HANDHELDPC__) 
  46   // Standard SDK doesn't have aygshell.dll: see include/wx/msw/wince/libraries.h 
  47   #if _WIN32_WCE < 400 || !defined(__WINCE_STANDARDSDK__) 
  50 #include "wx/msw/wince/missing.h" 
  53 #include "wx/msw/missing.h" 
  54 #include "wx/msw/winundef.h" 
  56 #include "wx/display.h" 
  66 // ---------------------------------------------------------------------------- 
  67 // stubs for missing functions under MicroWindows 
  68 // ---------------------------------------------------------------------------- 
  72 // static inline bool IsIconic(HWND WXUNUSED(hwnd)) { return false; } 
  73 static inline bool IsZoomed(HWND 
WXUNUSED(hwnd
)) { return false; } 
  75 #endif // __WXMICROWIN__ 
  77 // NB: wxDlgProc must be defined here and not in dialog.cpp because the latter 
  78 //     is not included by wxUniv build which does need wxDlgProc 
  80 wxDlgProc(HWND hDlg
, UINT message
, WPARAM wParam
, LPARAM lParam
); 
  82 // ---------------------------------------------------------------------------- 
  84 // ---------------------------------------------------------------------------- 
  86 // the name of the default wxWidgets class 
  88 extern       wxChar 
*wxCanvasClassName
; 
  90 extern const wxChar 
*wxCanvasClassName
; 
  93 // ---------------------------------------------------------------------------- 
  94 // wxTLWHiddenParentModule: used to manage the hidden parent window (we need a 
  95 // module to ensure that the window is always deleted) 
  96 // ---------------------------------------------------------------------------- 
  98 class wxTLWHiddenParentModule 
: public wxModule
 
 101     // module init/finalize 
 102     virtual bool OnInit(); 
 103     virtual void OnExit(); 
 105     // get the hidden window (creates on demand) 
 106     static HWND 
GetHWND(); 
 109     // the HWND of the hidden parent 
 112     // the class used to create it 
 113     static const wxChar 
*ms_className
; 
 115     DECLARE_DYNAMIC_CLASS(wxTLWHiddenParentModule
) 
 118 IMPLEMENT_DYNAMIC_CLASS(wxTLWHiddenParentModule
, wxModule
) 
 120 // ============================================================================ 
 121 // wxTopLevelWindowMSW implementation 
 122 // ============================================================================ 
 124 BEGIN_EVENT_TABLE(wxTopLevelWindowMSW
, wxTopLevelWindowBase
) 
 125     EVT_ACTIVATE(wxTopLevelWindowMSW::OnActivate
) 
 128 // ---------------------------------------------------------------------------- 
 129 // wxTopLevelWindowMSW creation 
 130 // ---------------------------------------------------------------------------- 
 132 void wxTopLevelWindowMSW::Init() 
 135     m_maximizeOnShow 
= false; 
 137     // Data to save/restore when calling ShowFullScreen 
 139     m_fsOldWindowStyle 
= 0; 
 140     m_fsIsMaximized 
= false; 
 141     m_fsIsShowing 
= false; 
 143     m_winLastFocused 
= (wxWindow 
*)NULL
; 
 145 #if defined(__SMARTPHONE__) && defined(__WXWINCE__) 
 149 #if defined(__SMARTPHONE__) || defined(__POCKETPC__) 
 150     SHACTIVATEINFO
* info 
= new SHACTIVATEINFO
; 
 152     info
->cbSize 
= sizeof(SHACTIVATEINFO
); 
 154     m_activateInfo 
= (void*) info
; 
 158 WXDWORD 
wxTopLevelWindowMSW::MSWGetStyle(long style
, WXDWORD 
*exflags
) const 
 160     // let the base class deal with the common styles but fix the ones which 
 161     // don't make sense for us (we also deal with the borders ourselves) 
 162     WXDWORD msflags 
= wxWindow::MSWGetStyle
 
 164                         (style 
& ~wxBORDER_MASK
) | wxBORDER_NONE
, exflags
 
 165                       ) & ~WS_CHILD 
& ~WS_VISIBLE
; 
 167     // For some reason, WS_VISIBLE needs to be defined on creation for 
 168     // SmartPhone 2003. The title can fail to be displayed otherwise. 
 169 #if defined(__SMARTPHONE__) || (defined(__WXWINCE__) && _WIN32_WCE < 400) 
 170     msflags 
|= WS_VISIBLE
; 
 171     ((wxTopLevelWindowMSW
*)this)->wxWindowBase::Show(true); 
 174     // first select the kind of window being created 
 176     // note that if we don't set WS_POPUP, Windows assumes WS_OVERLAPPED and 
 177     // creates a window with both caption and border, hence we need to use 
 178     // WS_POPUP in a few cases just to avoid having caption/border which we 
 181     // border and caption styles 
 182     if ( ( style 
& wxRESIZE_BORDER 
) && !IsAlwaysMaximized()) 
 183         msflags 
|= WS_THICKFRAME
; 
 184     else if ( exflags 
&& ((style 
& wxBORDER_DOUBLE
) || (style 
& wxBORDER_RAISED
)) ) 
 185         *exflags 
|= WS_EX_DLGMODALFRAME
; 
 186     else if ( !(style 
& wxBORDER_NONE
) ) 
 187         msflags 
|= WS_BORDER
; 
 193     // normally we consider that all windows without a caption must be popups, 
 194     // but CE is an exception: there windows normally do not have the caption 
 195     // but shouldn't be made popups as popups can't have menus and don't look 
 196     // like normal windows anyhow 
 198     // TODO: Smartphone appears to like wxCAPTION, but we should check that 
 200 #if defined(__SMARTPHONE__) || !defined(__WXWINCE__) 
 201     if ( style 
& wxCAPTION 
) 
 202         msflags 
|= WS_CAPTION
; 
 206 #endif // !__WXWINCE__ 
 209     // next translate the individual flags 
 211     // WS_EX_CONTEXTHELP is incompatible with WS_MINIMIZEBOX and WS_MAXIMIZEBOX 
 212     // and is ignored if we specify both of them, but chances are that if we 
 213     // use wxWS_EX_CONTEXTHELP, we really do want to have the context help 
 214     // button while wxMINIMIZE/wxMAXIMIZE are included by default, so the help 
 216     if ( !(GetExtraStyle() & wxWS_EX_CONTEXTHELP
) ) 
 218         if ( style 
& wxMINIMIZE_BOX 
) 
 219             msflags 
|= WS_MINIMIZEBOX
; 
 220         if ( style 
& wxMAXIMIZE_BOX 
) 
 221             msflags 
|= WS_MAXIMIZEBOX
; 
 225     if ( style 
& wxSYSTEM_MENU 
) 
 226         msflags 
|= WS_SYSMENU
; 
 229     // NB: under CE these 2 styles are not supported currently, we should 
 230     //     call Minimize()/Maximize() "manually" if we want to support them 
 231     if ( style 
& wxMINIMIZE 
) 
 232         msflags 
|= WS_MINIMIZE
; 
 234     if ( style 
& wxMAXIMIZE 
) 
 235         msflags 
|= WS_MAXIMIZE
; 
 237     // Keep this here because it saves recoding this function in wxTinyFrame 
 238     if ( style 
& (wxTINY_CAPTION_VERT 
| wxTINY_CAPTION_HORIZ
) ) 
 239         msflags 
|= WS_CAPTION
; 
 243         // there is no taskbar under CE, so omit all this 
 244 #if !defined(__WXWINCE__) 
 245         if ( !(GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
) ) 
 247             if ( style 
& wxFRAME_TOOL_WINDOW 
) 
 249                 // create the palette-like window 
 250                 *exflags 
|= WS_EX_TOOLWINDOW
; 
 252                 // tool windows shouldn't appear on the taskbar (as documented) 
 253                 style 
|= wxFRAME_NO_TASKBAR
; 
 256             // We have to solve 2 different problems here: 
 258             // 1. frames with wxFRAME_NO_TASKBAR flag shouldn't appear in the 
 259             //    taskbar even if they don't have a parent 
 261             // 2. frames without this style should appear in the taskbar even 
 262             //    if they're owned (Windows only puts non owned windows into 
 263             //    the taskbar normally) 
 265             // The second one is solved here by using WS_EX_APPWINDOW flag, the 
 266             // first one is dealt with in our MSWGetParent() method 
 268             if ( !(style 
& wxFRAME_NO_TASKBAR
) && GetParent() ) 
 270                 // need to force the frame to appear in the taskbar 
 271                 *exflags 
|= WS_EX_APPWINDOW
; 
 273             //else: nothing to do [here] 
 276         if ( GetExtraStyle() & wxWS_EX_CONTEXTHELP 
) 
 277             *exflags 
|= WS_EX_CONTEXTHELP
; 
 278 #endif // !__WXWINCE__ 
 280         if ( style 
& wxSTAY_ON_TOP 
) 
 281             *exflags 
|= WS_EX_TOPMOST
; 
 287 WXHWND 
wxTopLevelWindowMSW::MSWGetParent() const 
 289     // for the frames without wxFRAME_FLOAT_ON_PARENT style we should use NULL 
 290     // parent HWND or it would be always on top of its parent which is not what 
 291     // we usually want (in fact, we only want it for frames with the 
 292     // wxFRAME_FLOAT_ON_PARENT flag) 
 293     HWND hwndParent 
= NULL
; 
 294     if ( HasFlag(wxFRAME_FLOAT_ON_PARENT
) ) 
 296         const wxWindow 
*parent 
= GetParent(); 
 300             // this flag doesn't make sense then and will be ignored 
 301             wxFAIL_MSG( _T("wxFRAME_FLOAT_ON_PARENT but no parent?") ); 
 305             hwndParent 
= GetHwndOf(parent
); 
 308     //else: don't float on parent, must not be owned 
 310     // now deal with the 2nd taskbar-related problem (see comments above in 
 312     if ( HasFlag(wxFRAME_NO_TASKBAR
) && !hwndParent 
) 
 315         hwndParent 
= wxTLWHiddenParentModule::GetHWND(); 
 318     return (WXHWND
)hwndParent
; 
 321 #if defined(__SMARTPHONE__) || defined(__POCKETPC__) 
 322 bool wxTopLevelWindowMSW::HandleSettingChange(WXWPARAM wParam
, WXLPARAM lParam
) 
 324     SHACTIVATEINFO 
*info 
= (SHACTIVATEINFO
*) m_activateInfo
; 
 327         SHHandleWMSettingChange(GetHwnd(), wParam
, lParam
, info
); 
 330     return wxWindowMSW::HandleSettingChange(wParam
, lParam
); 
 334 WXLRESULT 
wxTopLevelWindowMSW::MSWWindowProc(WXUINT message
, WXWPARAM wParam
, WXLPARAM lParam
) 
 337     bool processed 
= false; 
 339 #if defined(__SMARTPHONE__) || defined(__POCKETPC__) 
 344             SHACTIVATEINFO
* info 
= (SHACTIVATEINFO
*) m_activateInfo
; 
 348                 if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
) flags 
= SHA_INPUTDIALOG
; 
 349                 SHHandleWMActivate(GetHwnd(), wParam
, lParam
, info
, flags
); 
 352             // This implicitly sends a wxEVT_ACTIVATE_APP event 
 354                 wxTheApp
->SetActive(wParam 
!= 0, FindFocus()); 
 362                 wxActivateEvent 
event(wxEVT_HIBERNATE
, true, wxID_ANY
); 
 363                 event
.SetEventObject(wxTheApp
); 
 364                 processed 
= wxTheApp
->ProcessEvent(event
); 
 372         rc 
= wxTopLevelWindowBase::MSWWindowProc(message
, wParam
, lParam
); 
 377 bool wxTopLevelWindowMSW::CreateDialog(const void *dlgTemplate
, 
 378                                        const wxString
& title
, 
 382 #ifdef __WXMICROWIN__ 
 383     // no dialogs support under MicroWin yet 
 384     return CreateFrame(title
, pos
, size
); 
 385 #else // !__WXMICROWIN__ 
 386     wxWindow 
*parent 
= GetParent(); 
 388     // for the dialogs without wxDIALOG_NO_PARENT style, use the top level 
 389     // app window as parent - this avoids creating modal dialogs without 
 391     if ( !parent 
&& !(GetWindowStyleFlag() & wxDIALOG_NO_PARENT
) ) 
 393         parent 
= wxTheApp
->GetTopWindow(); 
 397             // don't use transient windows as parents, this is dangerous as it 
 398             // can lead to a crash if the parent is destroyed before the child 
 400             // also don't use the window which is currently hidden as then the 
 401             // dialog would be hidden as well 
 402             if ( (parent
->GetExtraStyle() & wxWS_EX_TRANSIENT
) || 
 410     m_hWnd 
= (WXHWND
)::CreateDialogIndirect
 
 413                         (DLGTEMPLATE
*)dlgTemplate
, 
 414                         parent 
? GetHwndOf(parent
) : NULL
, 
 420         wxFAIL_MSG(wxT("Failed to create dialog. Incorrect DLGTEMPLATE?")); 
 422         wxLogSysError(wxT("Can't create dialog using memory template")); 
 428     (void)MSWGetCreateWindowFlags(&exflags
); 
 432         ::SetWindowLong(GetHwnd(), GWL_EXSTYLE
, exflags
); 
 433         ::SetWindowPos(GetHwnd(), 
 434                        exflags 
& WS_EX_TOPMOST 
? HWND_TOPMOST 
: 0, 
 438                        (exflags 
& WS_EX_TOPMOST 
? 0 : SWP_NOZORDER
) | 
 442 #if !defined(__WXWINCE__) 
 443     // For some reason, the system menu is activated when we use the 
 444     // WS_EX_CONTEXTHELP style, so let's set a reasonable icon 
 445     if ( exflags 
& WS_EX_CONTEXTHELP 
) 
 447         wxFrame 
*winTop 
= wxDynamicCast(wxTheApp
->GetTopWindow(), wxFrame
); 
 450             wxIcon icon 
= winTop
->GetIcon(); 
 453                 ::SendMessage(GetHwnd(), WM_SETICON
, 
 455                               (LPARAM
)GetHiconOf(icon
)); 
 461     // move the dialog to its initial position without forcing repainting 
 463     (void)MSWGetCreateWindowCoords(pos
, size
, x
, y
, w
, h
); 
 465     if ( x 
== (int)CW_USEDEFAULT 
) 
 467         // centre it on the screen - what else can we do? 
 468         wxSize sizeDpy 
= wxGetDisplaySize(); 
 470         x 
= (sizeDpy
.x 
- w
) / 2; 
 471         y 
= (sizeDpy
.y 
- h
) / 2; 
 474 #if !defined(__WXWINCE__) || defined(__WINCE_STANDARDSDK__) 
 475     if ( !::MoveWindow(GetHwnd(), x
, y
, w
, h
, FALSE
) ) 
 477         wxLogLastError(wxT("MoveWindow")); 
 481     if ( !title
.empty() ) 
 483         ::SetWindowText(GetHwnd(), title
); 
 488 #ifdef __SMARTPHONE__ 
 489     // Work around title non-display glitch 
 494 #endif // __WXMICROWIN__/!__WXMICROWIN__ 
 497 bool wxTopLevelWindowMSW::CreateFrame(const wxString
& title
, 
 502     WXDWORD flags 
= MSWGetCreateWindowFlags(&exflags
); 
 504     const wxSize sz 
= IsAlwaysMaximized() ? wxDefaultSize 
: size
; 
 506     return MSWCreate(wxCanvasClassName
, title
, pos
, sz
, flags
, exflags
); 
 509 bool wxTopLevelWindowMSW::Create(wxWindow 
*parent
, 
 511                                  const wxString
& title
, 
 515                                  const wxString
& name
) 
 517     bool ret 
wxDUMMY_INITIALIZE(false); 
 522     wxSize sizeReal 
= size
; 
 523     if ( !sizeReal
.IsFullySpecified() ) 
 525         sizeReal
.SetDefaults(GetDefaultSize()); 
 528     m_windowStyle 
= style
; 
 532     m_windowId 
= id 
== wxID_ANY 
? NewControlId() : id
; 
 534     wxTopLevelWindows
.Append(this); 
 537         parent
->AddChild(this); 
 539     if ( GetExtraStyle() & wxTOPLEVEL_EX_DIALOG 
) 
 541         // we have different dialog templates to allows creation of dialogs 
 542         // with & without captions under MSWindows, resizeable or not (but a 
 543         // resizeable dialog always has caption - otherwise it would look too 
 546         // we need 3 additional WORDs for dialog menu, class and title (as we 
 547         // don't use DS_SETFONT we don't need the fourth WORD for the font) 
 548         static const int dlgsize 
= sizeof(DLGTEMPLATE
) + (sizeof(WORD
) * 3); 
 549         DLGTEMPLATE 
*dlgTemplate 
= (DLGTEMPLATE 
*)malloc(dlgsize
); 
 550         memset(dlgTemplate
, 0, dlgsize
); 
 552         // these values are arbitrary, they won't be used normally anyhow 
 555         dlgTemplate
->cx 
= 144; 
 556         dlgTemplate
->cy 
= 75; 
 558         // reuse the code in MSWGetStyle() but correct the results slightly for 
 560         dlgTemplate
->style 
= MSWGetStyle(style
, NULL
); 
 562         // all dialogs are popups 
 563         dlgTemplate
->style 
|= WS_POPUP
; 
 566         // force 3D-look if necessary, it looks impossibly ugly otherwise 
 567         if ( style 
& (wxRESIZE_BORDER 
| wxCAPTION
) ) 
 568             dlgTemplate
->style 
|= DS_MODALFRAME
; 
 571         ret 
= CreateDialog(dlgTemplate
, title
, pos
, sizeReal
); 
 576         ret 
= CreateFrame(title
, pos
, sizeReal
); 
 580     if ( ret 
&& !(GetWindowStyleFlag() & wxCLOSE_BOX
) ) 
 582         EnableCloseButton(false); 
 586     // for standard dialogs the dialog manager generates WM_CHANGEUISTATE 
 587     // itself but for custom windows we have to do it ourselves in order to 
 588     // make the keyboard indicators (such as underlines for accelerators and 
 589     // focus rectangles) work under Win2k+ 
 592         MSWUpdateUIState(UIS_INITIALIZE
); 
 595     // Note: if we include PocketPC in this test, dialogs can fail to show up, 
 596     // for example the text entry dialog in the dialogs sample. Problem with Maximise()? 
 597 #if defined(__WXWINCE__) && (defined(__SMARTPHONE__) || defined(__WINCE_STANDARDSDK__)) 
 598     if ( ( style 
& wxMAXIMIZE 
) || IsAlwaysMaximized() ) 
 604 #if defined(__SMARTPHONE__) && defined(__WXWINCE__) 
 605     SetRightMenu(); // to nothing for initialization 
 611 wxTopLevelWindowMSW::~wxTopLevelWindowMSW() 
 613 #if defined(__SMARTPHONE__) || defined(__POCKETPC__) 
 614     SHACTIVATEINFO
* info 
= (SHACTIVATEINFO
*) m_activateInfo
; 
 616     m_activateInfo 
= NULL
; 
 619     // after destroying an owned window, Windows activates the next top level 
 620     // window in Z order but it may be different from our owner (to reproduce 
 621     // this simply Alt-TAB to another application and back before closing the 
 622     // owned frame) whereas we always want to yield activation to our parent 
 623     if ( HasFlag(wxFRAME_FLOAT_ON_PARENT
) ) 
 625         wxWindow 
*parent 
= GetParent(); 
 628             ::BringWindowToTop(GetHwndOf(parent
)); 
 633 // ---------------------------------------------------------------------------- 
 634 // wxTopLevelWindowMSW showing 
 635 // ---------------------------------------------------------------------------- 
 637 void wxTopLevelWindowMSW::DoShowWindow(int nShowCmd
) 
 639     ::ShowWindow(GetHwnd(), nShowCmd
); 
 641     m_iconized 
= nShowCmd 
== SW_MINIMIZE
; 
 644 bool wxTopLevelWindowMSW::Show(bool show
) 
 646     // don't use wxWindow version as we want to call DoShowWindow() ourselves 
 647     if ( !wxWindowBase::Show(show
) ) 
 653         if ( m_maximizeOnShow 
) 
 656             nShowCmd 
= SW_MAXIMIZE
; 
 658             // This is necessary, or no window appears 
 659 #if defined( __WINCE_STANDARDSDK__) || defined(__SMARTPHONE__) 
 660             DoShowWindow(SW_SHOW
); 
 663             m_maximizeOnShow 
= false; 
 667            if ( GetWindowStyle() & wxFRAME_TOOL_WINDOW 
) 
 668                nShowCmd 
= SW_SHOWNA
; 
 678     DoShowWindow(nShowCmd
); 
 680 #if defined(__WXWINCE__) && (_WIN32_WCE >= 400 && !defined(__POCKETPC__) && !defined(__SMARTPHONE__)) 
 681     // Addornments have to be added when the frame is the correct size 
 682     wxFrame
* frame 
= wxDynamicCast(this, wxFrame
); 
 683     if (frame 
&& frame
->GetMenuBar()) 
 684         frame
->GetMenuBar()->AddAdornments(GetWindowStyleFlag()); 
 687     // we only set pending size if we're maximized before being shown, now that 
 688     // we're shown we don't need it any more (it is reset in size event handler 
 689     // for child windows but we have to do it ourselves for this parent window) 
 690     m_pendingSize 
= wxDefaultSize
; 
 695 // ---------------------------------------------------------------------------- 
 696 // wxTopLevelWindowMSW maximize/minimize 
 697 // ---------------------------------------------------------------------------- 
 699 void wxTopLevelWindowMSW::Maximize(bool maximize
) 
 703         // just maximize it directly 
 704         DoShowWindow(maximize 
? SW_MAXIMIZE 
: SW_RESTORE
); 
 708         // we can't maximize the hidden frame because it shows it as well, 
 709         // so just remember that we should do it later in this case 
 710         m_maximizeOnShow 
= maximize
; 
 712         // after calling Maximize() the client code expects to get the frame 
 713         // "real" size and doesn't want to know that, because of implementation 
 714         // details, the frame isn't really maximized yet but will be only once 
 715         // it's shown, so return our size as it will be then in this case 
 718             // we must only change pending size here, and not call SetSize() 
 719             // because otherwise Windows would think that this (full screen) 
 720             // size is the natural size for the frame and so would use it when 
 721             // the user clicks on "restore" title bar button instead of the 
 722             // correct initial frame size 
 724             // NB: unfortunately we don't know which display we're on yet so we 
 725             //     have to use the default one 
 726             m_pendingSize 
= wxGetClientDisplayRect().GetSize(); 
 728         //else: can't do anything in this case, we don't have the old size 
 732 bool wxTopLevelWindowMSW::IsMaximized() const 
 734     return IsAlwaysMaximized() || 
 735 #if !defined(__SMARTPHONE__) && !defined(__POCKETPC__) 
 736            (::IsZoomed(GetHwnd()) != 0) || 
 741 void wxTopLevelWindowMSW::Iconize(bool iconize
) 
 743     DoShowWindow(iconize 
? SW_MINIMIZE 
: SW_RESTORE
); 
 746 bool wxTopLevelWindowMSW::IsIconized() const 
 751     // don't use m_iconized, it may be briefly out of sync with the real state 
 752     // as it's only modified when we receive a WM_SIZE and we could be called 
 753     // from an event handler from one of the messages we receive before it, 
 755     return ::IsIconic(GetHwnd()) != 0; 
 759 void wxTopLevelWindowMSW::Restore() 
 761     DoShowWindow(SW_RESTORE
); 
 764 // ---------------------------------------------------------------------------- 
 765 // wxTopLevelWindowMSW fullscreen 
 766 // ---------------------------------------------------------------------------- 
 768 bool wxTopLevelWindowMSW::ShowFullScreen(bool show
, long style
) 
 770     if ( show 
== IsFullScreen() ) 
 776     m_fsIsShowing 
= show
; 
 782         // zap the frame borders 
 784         // save the 'normal' window style 
 785         m_fsOldWindowStyle 
= GetWindowLong(GetHwnd(), GWL_STYLE
); 
 787         // save the old position, width & height, maximize state 
 788         m_fsOldSize 
= GetRect(); 
 789         m_fsIsMaximized 
= IsMaximized(); 
 791         // decide which window style flags to turn off 
 792         LONG newStyle 
= m_fsOldWindowStyle
; 
 795         if (style 
& wxFULLSCREEN_NOBORDER
) 
 797             offFlags 
|= WS_BORDER
; 
 799             offFlags 
|= WS_THICKFRAME
; 
 802         if (style 
& wxFULLSCREEN_NOCAPTION
) 
 803             offFlags 
|= WS_CAPTION 
| WS_SYSMENU
; 
 805         newStyle 
&= ~offFlags
; 
 807         // change our window style to be compatible with full-screen mode 
 808         ::SetWindowLong(GetHwnd(), GWL_STYLE
, newStyle
); 
 812         // resize to the size of the display containing us 
 813         int dpy 
= wxDisplay::GetFromWindow(this); 
 814         if ( dpy 
!= wxNOT_FOUND 
) 
 816             rect 
= wxDisplay(dpy
).GetGeometry(); 
 818         else // fall back to the main desktop 
 819 #endif // wxUSE_DISPLAY 
 821             // resize to the size of the desktop 
 822             wxCopyRECTToRect(wxGetWindowRect(::GetDesktopWindow()), rect
); 
 824             // FIXME: size of the bottom menu (toolbar) 
 825             // should be taken in account 
 826             rect
.height 
+= rect
.y
; 
 833         // now flush the window style cache and actually go full-screen 
 834         long flags 
= SWP_FRAMECHANGED
; 
 836         // showing the frame full screen should also show it if it's still 
 840             // don't call wxWindow version to avoid flicker from calling 
 841             // ::ShowWindow() -- we're going to show the window at the correct 
 842             // location directly below -- but do call the wxWindowBase version 
 843             // to sync the internal m_isShown flag 
 844             wxWindowBase::Show(); 
 846             flags 
|= SWP_SHOWWINDOW
; 
 849         SetWindowPos(GetHwnd(), HWND_TOP
, 
 850                      rect
.x
, rect
.y
, rect
.width
, rect
.height
, 
 853 #if !defined(__HANDHELDPC__) && (defined(__WXWINCE__) && (_WIN32_WCE < 400)) 
 854         ::SHFullScreen(GetHwnd(), SHFS_HIDETASKBAR 
| SHFS_HIDESIPBUTTON
); 
 857         // finally send an event allowing the window to relayout itself &c 
 858         wxSizeEvent 
event(rect
.GetSize(), GetId()); 
 859         GetEventHandler()->ProcessEvent(event
); 
 861     else // stop showing full screen 
 863 #if !defined(__HANDHELDPC__) && (defined(__WXWINCE__) && (_WIN32_WCE < 400)) 
 864         ::SHFullScreen(GetHwnd(), SHFS_SHOWTASKBAR 
| SHFS_SHOWSIPBUTTON
); 
 866         Maximize(m_fsIsMaximized
); 
 867         SetWindowLong(GetHwnd(),GWL_STYLE
, m_fsOldWindowStyle
); 
 868         SetWindowPos(GetHwnd(),HWND_TOP
,m_fsOldSize
.x
, m_fsOldSize
.y
, 
 869             m_fsOldSize
.width
, m_fsOldSize
.height
, SWP_FRAMECHANGED
); 
 875 // ---------------------------------------------------------------------------- 
 876 // wxTopLevelWindowMSW misc 
 877 // ---------------------------------------------------------------------------- 
 879 void wxTopLevelWindowMSW::SetTitle( const wxString
& title
) 
 884 wxString 
wxTopLevelWindowMSW::GetTitle() const 
 889 void wxTopLevelWindowMSW::SetIcon(const wxIcon
& icon
) 
 891     SetIcons( wxIconBundle( icon 
) ); 
 894 void wxTopLevelWindowMSW::SetIcons(const wxIconBundle
& icons
) 
 896     wxTopLevelWindowBase::SetIcons(icons
); 
 898 #if !defined(__WXMICROWIN__) 
 899     const wxIcon
& sml 
= icons
.GetIcon( wxSize( 16, 16 ) ); 
 900     if( sml
.Ok() && sml
.GetWidth() == 16 && sml
.GetHeight() == 16 ) 
 902         ::SendMessage( GetHwndOf( this ), WM_SETICON
, ICON_SMALL
, 
 903                        (LPARAM
)GetHiconOf(sml
) ); 
 906     const wxIcon
& big 
= icons
.GetIcon( wxSize( 32, 32 ) ); 
 907     if( big
.Ok() && big
.GetWidth() == 32 && big
.GetHeight() == 32 ) 
 909         ::SendMessage( GetHwndOf( this ), WM_SETICON
, ICON_BIG
, 
 910                        (LPARAM
)GetHiconOf(big
) ); 
 912 #endif // !__WXMICROWIN__ 
 915 bool wxTopLevelWindowMSW::EnableCloseButton(bool enable
) 
 917 #if !defined(__WXMICROWIN__) 
 918     // get system (a.k.a. window) menu 
 919     HMENU hmenu 
= GetSystemMenu(GetHwnd(), FALSE 
/* get it */); 
 922         // no system menu at all -- ok if we want to remove the close button 
 923         // anyhow, but bad if we want to show it 
 927     // enabling/disabling the close item from it also automatically 
 928     // disables/enables the close title bar button 
 929     if ( ::EnableMenuItem(hmenu
, SC_CLOSE
, 
 931                           (enable 
? MF_ENABLED 
: MF_GRAYED
)) == -1 ) 
 933         wxLogLastError(_T("EnableMenuItem(SC_CLOSE)")); 
 938     // update appearance immediately 
 939     if ( !::DrawMenuBar(GetHwnd()) ) 
 941         wxLogLastError(_T("DrawMenuBar")); 
 944 #endif // !__WXMICROWIN__ 
 951 bool wxTopLevelWindowMSW::SetShape(const wxRegion
& region
) 
 953     wxCHECK_MSG( HasFlag(wxFRAME_SHAPED
), false, 
 954                  _T("Shaped windows must be created with the wxFRAME_SHAPED style.")); 
 956     // The empty region signifies that the shape should be removed from the 
 958     if ( region
.IsEmpty() ) 
 960         if (::SetWindowRgn(GetHwnd(), NULL
, TRUE
) == 0) 
 962             wxLogLastError(_T("SetWindowRgn")); 
 968     // Windows takes ownership of the region, so 
 969     // we'll have to make a copy of the region to give to it. 
 970     DWORD noBytes 
= ::GetRegionData(GetHrgnOf(region
), 0, NULL
); 
 971     RGNDATA 
*rgnData 
= (RGNDATA
*) new char[noBytes
]; 
 972     ::GetRegionData(GetHrgnOf(region
), noBytes
, rgnData
); 
 973     HRGN hrgn 
= ::ExtCreateRegion(NULL
, noBytes
, rgnData
); 
 974     delete[] (char*) rgnData
; 
 976     // SetWindowRgn expects the region to be in coordinants 
 977     // relative to the window, not the client area.  Figure 
 978     // out the offset, if any. 
 980     DWORD dwStyle 
=   ::GetWindowLong(GetHwnd(), GWL_STYLE
); 
 981     DWORD dwExStyle 
= ::GetWindowLong(GetHwnd(), GWL_EXSTYLE
); 
 982     ::GetClientRect(GetHwnd(), &rect
); 
 983     ::AdjustWindowRectEx(&rect
, dwStyle
, FALSE
, dwExStyle
); 
 984     ::OffsetRgn(hrgn
, -rect
.left
, -rect
.top
); 
 986     // Now call the shape API with the new region. 
 987     if (::SetWindowRgn(GetHwnd(), hrgn
, TRUE
) == 0) 
 989         wxLogLastError(_T("SetWindowRgn")); 
 995 #endif // !__WXWINCE__ 
 997 void wxTopLevelWindowMSW::RequestUserAttention(int flags
) 
 999     // check if we can use FlashWindowEx(): unfortunately a simple test for 
1000     // FLASHW_STOP doesn't work because MSVC6 headers do #define it but don't 
1001     // provide FlashWindowEx() declaration, so try to detect whether we have 
1002     // real headers for WINVER 0x0500 by checking for existence of a symbol not 
1003     // declated in MSVC6 header 
1004 #if defined(FLASHW_STOP) && defined(VK_XBUTTON1) 
1005     // available in the headers, check if it is supported by the system 
1006     typedef BOOL (WINAPI 
*FlashWindowEx_t
)(FLASHWINFO 
*pfwi
); 
1007     FlashWindowEx_t s_pfnFlashWindowEx 
= NULL
; 
1008     if ( !s_pfnFlashWindowEx 
) 
1010         wxDynamicLibrary 
dllUser32(_T("user32.dll")); 
1011         s_pfnFlashWindowEx 
= (FlashWindowEx_t
) 
1012                                 dllUser32
.GetSymbol(_T("FlashWindowEx")); 
1014         // we can safely unload user32.dll here, it's going to remain loaded as 
1015         // long as the program is running anyhow 
1018     if ( s_pfnFlashWindowEx 
) 
1020         WinStruct
<FLASHWINFO
> fwi
; 
1021         fwi
.hwnd 
= GetHwnd(); 
1022         fwi
.dwFlags 
= FLASHW_ALL
; 
1023         if ( flags 
& wxUSER_ATTENTION_INFO 
) 
1025             // just flash a few times 
1028         else // wxUSER_ATTENTION_ERROR 
1030             // flash until the user notices it 
1031             fwi
.dwFlags 
|= FLASHW_TIMERNOFG
; 
1034         s_pfnFlashWindowEx(&fwi
); 
1036     else // FlashWindowEx() not available 
1037 #endif // FlashWindowEx() defined 
1041         ::FlashWindow(GetHwnd(), TRUE
); 
1042 #endif // __WXWINCE__ 
1046 // --------------------------------------------------------------------------- 
1048 bool wxTopLevelWindowMSW::SetTransparent(wxByte alpha
) 
1050     typedef DWORD (WINAPI 
*PSETLAYEREDWINDOWATTR
)(HWND
, DWORD
, BYTE
, DWORD
); 
1051     static PSETLAYEREDWINDOWATTR pSetLayeredWindowAttributes 
= NULL
; 
1053     if ( pSetLayeredWindowAttributes 
== NULL 
) 
1055         wxDynamicLibrary 
dllUser32(_T("user32.dll")); 
1056         pSetLayeredWindowAttributes 
= (PSETLAYEREDWINDOWATTR
) 
1057             dllUser32
.GetSymbol(wxT("SetLayeredWindowAttributes")); 
1059     if ( pSetLayeredWindowAttributes 
== NULL 
) 
1062     LONG exstyle 
= GetWindowLong(GetHwnd(), GWL_EXSTYLE
); 
1064     // if setting alpha to fully opaque then turn off the layered style 
1067         SetWindowLong(GetHwnd(), GWL_EXSTYLE
, exstyle 
& ~WS_EX_LAYERED
); 
1072     // Otherwise, set the layered style if needed and set the alpha value 
1073     if ((exstyle 
& WS_EX_LAYERED
) == 0 ) 
1074         SetWindowLong(GetHwnd(), GWL_EXSTYLE
, exstyle 
| WS_EX_LAYERED
); 
1076     return pSetLayeredWindowAttributes(GetHwnd(), 0, (BYTE
)alpha
, LWA_ALPHA
) != 0;    
1079 bool wxTopLevelWindowMSW::CanSetTransparent() 
1081     // The API is available on win2k and above 
1083     static int os_type 
= -1; 
1084     static int ver_major 
= -1; 
1087         os_type 
= ::wxGetOsVersion(&ver_major
); 
1089     return (os_type 
== wxWINDOWS_NT 
&& ver_major 
>= 5); 
1092 // ---------------------------------------------------------------------------- 
1093 // wxTopLevelWindow event handling 
1094 // ---------------------------------------------------------------------------- 
1096 // Default activation behaviour - set the focus for the first child 
1098 void wxTopLevelWindowMSW::OnActivate(wxActivateEvent
& event
) 
1100     if ( event
.GetActive() ) 
1102         // restore focus to the child which was last focused unless we already 
1104         wxLogTrace(_T("focus"), _T("wxTLW %08x activated."), (int) m_hWnd
); 
1106         wxWindow 
*winFocus 
= FindFocus(); 
1107         if ( !winFocus 
|| wxGetTopLevelParent(winFocus
) != this ) 
1109             wxWindow 
*parent 
= m_winLastFocused 
? m_winLastFocused
->GetParent() 
1116             wxSetFocusToChild(parent
, &m_winLastFocused
); 
1119     else // deactivating 
1121         // remember the last focused child if it is our child 
1122         m_winLastFocused 
= FindFocus(); 
1124         if ( m_winLastFocused 
) 
1126             // let it know that it doesn't have focus any more 
1127             m_winLastFocused
->HandleKillFocus((WXHWND
)NULL
); 
1129             // and don't remember it if it's a child from some other frame 
1130             if ( wxGetTopLevelParent(m_winLastFocused
) != this ) 
1132                 m_winLastFocused 
= NULL
; 
1136         wxLogTrace(_T("focus"), 
1137                    _T("wxTLW %08x deactivated, last focused: %08x."), 
1139                    (int) (m_winLastFocused 
? GetHwndOf(m_winLastFocused
) 
1146 // the DialogProc for all wxWidgets dialogs 
1147 LONG APIENTRY _EXPORT
 
1148 wxDlgProc(HWND hDlg
, 
1150           WPARAM 
WXUNUSED(wParam
), 
1151           LPARAM 
WXUNUSED(lParam
)) 
1157             // under CE, add a "Ok" button in the dialog title bar and make it full 
1160             // TODO: find the window for this HWND, and take into account 
1161             // wxMAXIMIZE and wxCLOSE_BOX. For now, assume both are present. 
1163             // Standard SDK doesn't have aygshell.dll: see 
1164             // include/wx/msw/wince/libraries.h 
1165 #if defined(__WXWINCE__) && !defined(__WINCE_STANDARDSDK__) && !defined(__HANDHELDPC__) 
1166             SHINITDLGINFO shidi
; 
1167             shidi
.dwMask 
= SHIDIM_FLAGS
; 
1168             shidi
.dwFlags 
= SHIDIF_SIZEDLG 
// take account of the SIP or menubar 
1169 #ifndef __SMARTPHONE__ 
1174             SHInitDialog( &shidi 
); 
1175 #else // no SHInitDialog() 
1178             // for WM_INITDIALOG, returning TRUE tells system to set focus to 
1179             // the first control in the dialog box, but as we set the focus 
1180             // ourselves, we return FALSE for it as well 
1185     // for almost all messages, returning FALSE means that we didn't process 
1190 // ============================================================================ 
1191 // wxTLWHiddenParentModule implementation 
1192 // ============================================================================ 
1194 HWND 
wxTLWHiddenParentModule::ms_hwnd 
= NULL
; 
1196 const wxChar 
*wxTLWHiddenParentModule::ms_className 
= NULL
; 
1198 bool wxTLWHiddenParentModule::OnInit() 
1201     ms_className 
= NULL
; 
1206 void wxTLWHiddenParentModule::OnExit() 
1210         if ( !::DestroyWindow(ms_hwnd
) ) 
1212             wxLogLastError(_T("DestroyWindow(hidden TLW parent)")); 
1220         if ( !::UnregisterClass(ms_className
, wxGetInstance()) ) 
1222             wxLogLastError(_T("UnregisterClass(\"wxTLWHiddenParent\")")); 
1225         ms_className 
= NULL
; 
1230 HWND 
wxTLWHiddenParentModule::GetHWND() 
1234         if ( !ms_className 
) 
1236             static const wxChar 
*HIDDEN_PARENT_CLASS 
= _T("wxTLWHiddenParent"); 
1239             wxZeroMemory(wndclass
); 
1241             wndclass
.lpfnWndProc   
= DefWindowProc
; 
1242             wndclass
.hInstance     
= wxGetInstance(); 
1243             wndclass
.lpszClassName 
= HIDDEN_PARENT_CLASS
; 
1245             if ( !::RegisterClass(&wndclass
) ) 
1247                 wxLogLastError(_T("RegisterClass(\"wxTLWHiddenParent\")")); 
1251                 ms_className 
= HIDDEN_PARENT_CLASS
; 
1255         ms_hwnd 
= ::CreateWindow(ms_className
, wxEmptyString
, 0, 0, 0, 0, 0, NULL
, 
1256                                  (HMENU
)NULL
, wxGetInstance(), NULL
); 
1259             wxLogLastError(_T("CreateWindow(hidden TLW parent)"));