1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        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 license 
  10 /////////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  21     #pragma implementation "toplevel.h" 
  24 // For compilers that support precompilation, includes "wx.h". 
  25 #include "wx/wxprec.h" 
  33     #include "wx/toplevel.h" 
  34     #include "wx/string.h" 
  38     #include "wx/containr.h"        // wxSetFocusToChild() 
  41 #include "wx/module.h" 
  43 #include "wx/msw/private.h" 
  45 #include "wx/popupwin.h" 
  55 // ---------------------------------------------------------------------------- 
  56 // stubs for missing functions under MicroWindows 
  57 // ---------------------------------------------------------------------------- 
  61 // static inline bool IsIconic(HWND WXUNUSED(hwnd)) { return FALSE; } 
  62 static inline bool IsZoomed(HWND 
WXUNUSED(hwnd
)) { return FALSE
; } 
  64 #endif // __WXMICROWIN__ 
  66 // NB: wxDlgProc must be defined here and not in dialog.cpp because the latter 
  67 //     is not included by wxUniv build which does need wxDlgProc 
  69 wxDlgProc(HWND hDlg
, UINT message
, WPARAM wParam
, LPARAM lParam
); 
  71 // ---------------------------------------------------------------------------- 
  73 // ---------------------------------------------------------------------------- 
  75 // list of all frames and modeless dialogs 
  76 wxWindowList wxModelessWindows
; 
  78 // the name of the default wxWindows class 
  79 extern const wxChar 
*wxCanvasClassName
; 
  81 // ---------------------------------------------------------------------------- 
  82 // wxTLWHiddenParentModule: used to manage the hidden parent window (we need a 
  83 // module to ensure that the window is always deleted) 
  84 // ---------------------------------------------------------------------------- 
  86 class wxTLWHiddenParentModule 
: public wxModule
 
  89     // module init/finalize 
  90     virtual bool OnInit(); 
  91     virtual void OnExit(); 
  93     // get the hidden window (creates on demand) 
  94     static HWND 
GetHWND(); 
  97     // the HWND of the hidden parent 
 100     // the class used to create it 
 101     static const wxChar 
*ms_className
; 
 103     DECLARE_DYNAMIC_CLASS(wxTLWHiddenParentModule
) 
 106 IMPLEMENT_DYNAMIC_CLASS(wxTLWHiddenParentModule
, wxModule
) 
 108 // ============================================================================ 
 109 // wxTopLevelWindowMSW implementation 
 110 // ============================================================================ 
 112 BEGIN_EVENT_TABLE(wxTopLevelWindowMSW
, wxTopLevelWindowBase
) 
 113     EVT_ACTIVATE(wxTopLevelWindowMSW::OnActivate
) 
 116 // ---------------------------------------------------------------------------- 
 117 // wxTopLevelWindowMSW creation 
 118 // ---------------------------------------------------------------------------- 
 120 void wxTopLevelWindowMSW::Init() 
 123     m_maximizeOnShow 
= FALSE
; 
 125     // unlike (almost?) all other windows, frames are created hidden 
 128     // Data to save/restore when calling ShowFullScreen 
 130     m_fsOldWindowStyle 
= 0; 
 131     m_fsIsMaximized 
= FALSE
; 
 132     m_fsIsShowing 
= FALSE
; 
 134     m_winLastFocused 
= (wxWindow 
*)NULL
; 
 137 WXDWORD 
wxTopLevelWindowMSW::MSWGetStyle(long style
, WXDWORD 
*exflags
) const 
 139     // let the base class deal with the common styles but fix the ones which 
 140     // don't make sense for us (we also deal with the borders ourselves) 
 141     WXDWORD msflags 
= wxWindow::MSWGetStyle
 
 143                         (style 
& ~wxBORDER_MASK
) | wxBORDER_NONE
, exflags
 
 146     // first select the kind of window being created 
 148     // note that if we don't set WS_POPUP, Windows assumes WS_OVERLAPPED and 
 149     // creates a window with both caption and border, hence we also test it 
 150     // below in some other cases 
 151     if ( style 
& wxFRAME_TOOL_WINDOW 
) 
 154         msflags 
|= WS_OVERLAPPED
; 
 156     // border and caption styles 
 157     if ( style 
& wxRESIZE_BORDER 
) 
 158         msflags 
|= WS_THICKFRAME
; 
 159     else if ( !(style 
& wxBORDER_NONE
) ) 
 160         msflags 
|= WS_BORDER
; 
 164     if ( style 
& wxCAPTION 
) 
 165         msflags 
|= WS_CAPTION
; 
 169     // next translate the individual flags 
 170     if ( style 
& wxMINIMIZE_BOX 
) 
 171         msflags 
|= WS_MINIMIZEBOX
; 
 172     if ( style 
& wxMAXIMIZE_BOX 
) 
 173         msflags 
|= WS_MAXIMIZEBOX
; 
 174     if ( style 
& wxSYSTEM_MENU 
) 
 175         msflags 
|= WS_SYSMENU
; 
 176     if ( style 
& wxMINIMIZE 
) 
 177         msflags 
|= WS_MINIMIZE
; 
 178     if ( style 
& wxMAXIMIZE 
) 
 179         msflags 
|= WS_MAXIMIZE
; 
 181     // Keep this here because it saves recoding this function in wxTinyFrame 
 182 #if wxUSE_ITSY_BITSY && !defined(__WIN32__) 
 183     if ( style 
& wxTINY_CAPTION_VERT 
) 
 184         msflags 
|= IBS_VERTCAPTION
; 
 185     if ( style 
& wxTINY_CAPTION_HORIZ 
) 
 186         msflags 
|= IBS_HORZCAPTION
; 
 188     if ( style 
& (wxTINY_CAPTION_VERT 
| wxTINY_CAPTION_HORIZ
) ) 
 189         msflags 
|= WS_CAPTION
; 
 194 #if !defined(__WIN16__) && !defined(__SC__) 
 195         if ( !(GetExtraStyle() & wxTOPLEVEL_EX_DIALOG
) ) 
 197             if ( style 
& wxFRAME_TOOL_WINDOW 
) 
 199                 // create the palette-like window 
 200                 *exflags 
|= WS_EX_TOOLWINDOW
; 
 203             // We have to solve 2 different problems here: 
 205             // 1. frames with wxFRAME_NO_TASKBAR flag shouldn't appear in the 
 206             //    taskbar even if they don't have a parent 
 208             // 2. frames without this style should appear in the taskbar even 
 209             //    if they're owned (Windows only puts non owned windows into 
 210             //    the taskbar normally) 
 212             // The second one is solved here by using WS_EX_APPWINDOW flag, the 
 213             // first one is dealt with in our MSWGetParent() method 
 215             if ( !(style 
& wxFRAME_NO_TASKBAR
) && GetParent() ) 
 217                 // need to force the frame to appear in the taskbar 
 218                 *exflags 
|= WS_EX_APPWINDOW
; 
 220             //else: nothing to do [here] 
 224         if ( style 
& wxSTAY_ON_TOP 
) 
 225             *exflags 
|= WS_EX_TOPMOST
; 
 228         if ( GetExtraStyle() & wxFRAME_EX_CONTEXTHELP 
) 
 229             *exflags 
|= WS_EX_CONTEXTHELP
; 
 236 WXHWND 
wxTopLevelWindowMSW::MSWGetParent() const 
 238     // for the frames without wxFRAME_FLOAT_ON_PARENT style we should use NULL 
 239     // parent HWND or it would be always on top of its parent which is not what 
 240     // we usually want (in fact, we only want it for frames with the 
 241     // wxFRAME_FLOAT_ON_PARENT flag) 
 242     HWND hwndParent 
= NULL
; 
 243     if ( HasFlag(wxFRAME_FLOAT_ON_PARENT
) ) 
 245         const wxWindow 
*parent 
= GetParent(); 
 249             // this flag doesn't make sense then and will be ignored 
 250             wxFAIL_MSG( _T("wxFRAME_FLOAT_ON_PARENT but no parent?") ); 
 254             hwndParent 
= GetHwndOf(parent
); 
 257     //else: don't float on parent, must not be owned 
 259     // now deal with the 2nd taskbar-related problem (see comments above in 
 261     if ( HasFlag(wxFRAME_NO_TASKBAR
) && !hwndParent 
) 
 264         hwndParent 
= wxTLWHiddenParentModule::GetHWND(); 
 267     return (WXHWND
)hwndParent
; 
 270 bool wxTopLevelWindowMSW::CreateDialog(const void *dlgTemplate
, 
 271                                        const wxString
& title
, 
 275 #ifdef __WXMICROWIN__ 
 276     // no dialogs support under MicroWin yet 
 277     return CreateFrame(title
, pos
, size
); 
 278 #else // !__WXMICROWIN__ 
 279     wxWindow 
*parent 
= GetParent(); 
 281     // for the dialogs without wxDIALOG_NO_PARENT style, use the top level 
 282     // app window as parent - this avoids creating modal dialogs without 
 284     if ( !parent 
&& !(GetWindowStyleFlag() & wxDIALOG_NO_PARENT
) ) 
 286         parent 
= wxTheApp
->GetTopWindow(); 
 290             // don't use transient windows as parents, this is dangerous as it 
 291             // can lead to a crash if the parent is destroyed before the child 
 293             // also don't use the window which is currently hidden as then the 
 294             // dialog would be hidden as well 
 295             if ( (parent
->GetExtraStyle() & wxWS_EX_TRANSIENT
) || 
 303     m_hWnd 
= (WXHWND
)::CreateDialogIndirect
 
 306                         (DLGTEMPLATE
*)dlgTemplate
, 
 307                         parent 
? GetHwndOf(parent
) : NULL
, 
 313         wxFAIL_MSG(_("Failed to create dialog. Incorrect DLGTEMPLATE?")); 
 315         wxLogSysError(_("Can't create dialog using memory template")); 
 321     (void)MSWGetCreateWindowFlags(&exflags
); 
 325         ::SetWindowLong(GetHwnd(), GWL_EXSTYLE
, exflags
); 
 326         ::SetWindowPos(GetHwnd(), NULL
, 0, 0, 0, 0, 
 333 #if defined(__WIN95__) 
 334     // For some reason, the system menu is activated when we use the 
 335     // WS_EX_CONTEXTHELP style, so let's set a reasonable icon 
 336     if ( exflags 
& WS_EX_CONTEXTHELP 
) 
 338         wxFrame 
*winTop 
= wxDynamicCast(wxTheApp
->GetTopWindow(), wxFrame
); 
 341             wxIcon icon 
= winTop
->GetIcon(); 
 344                 ::SendMessage(GetHwnd(), WM_SETICON
, 
 346                               (LPARAM
)GetHiconOf(icon
)); 
 352     // move the dialog to its initial position without forcing repainting 
 354     if ( !MSWGetCreateWindowCoords(pos
, size
, x
, y
, w
, h
) ) 
 357         w 
= (int)CW_USEDEFAULT
; 
 360     // we can't use CW_USEDEFAULT here as we're not calling CreateWindow() 
 361     // and passing CW_USEDEFAULT to MoveWindow() results in resizing the 
 362     // window to (0, 0) size which breaks quite a lot of things, e.g. the 
 363     // sizer calculation in wxSizer::Fit() 
 364     if ( w 
== (int)CW_USEDEFAULT 
) 
 366         // the exact number doesn't matter, the dialog will be resized 
 367         // again soon anyhow but it should be big enough to allow 
 368         // calculation relying on "totalSize - clientSize > 0" work, i.e. 
 369         // at least greater than the title bar height 
 374     if ( x 
== (int)CW_USEDEFAULT 
) 
 376         // centre it on the screen - what else can we do? 
 377         wxSize sizeDpy 
= wxGetDisplaySize(); 
 379         x 
= (sizeDpy
.x 
- w
) / 2; 
 380         y 
= (sizeDpy
.y 
- h
) / 2; 
 383     if ( !::MoveWindow(GetHwnd(), x
, y
, w
, h
, FALSE
) ) 
 385         wxLogLastError(wxT("MoveWindow")); 
 388     if ( !title
.empty() ) 
 390         ::SetWindowText(GetHwnd(), title
); 
 396 #endif // __WXMICROWIN__/!__WXMICROWIN__ 
 399 bool wxTopLevelWindowMSW::CreateFrame(const wxString
& title
, 
 404     WXDWORD flags 
= MSWGetCreateWindowFlags(&exflags
); 
 406     return MSWCreate(wxCanvasClassName
, title
, pos
, size
, flags
, exflags
); 
 409 bool wxTopLevelWindowMSW::Create(wxWindow 
*parent
, 
 411                                  const wxString
& title
, 
 415                                  const wxString
& name
) 
 420     m_windowStyle 
= style
; 
 424     m_windowId 
= id 
== -1 ? NewControlId() : id
; 
 426     wxTopLevelWindows
.Append(this); 
 429         parent
->AddChild(this); 
 431     if ( GetExtraStyle() & wxTOPLEVEL_EX_DIALOG 
) 
 433         // we have different dialog templates to allows creation of dialogs 
 434         // with & without captions under MSWindows, resizeable or not (but a 
 435         // resizeable dialog always has caption - otherwise it would look too 
 438         // we need 3 additional WORDs for dialog menu, class and title (as we 
 439         // don't use DS_SETFONT we don't need the fourth WORD for the font) 
 440         static const int dlgsize 
= sizeof(DLGTEMPLATE
) + (sizeof(WORD
) * 3); 
 441         DLGTEMPLATE 
*dlgTemplate 
= (DLGTEMPLATE 
*)malloc(dlgsize
); 
 442         memset(dlgTemplate
, 0, dlgsize
); 
 444         // these values are arbitrary, they won't be used normally anyhow 
 447         dlgTemplate
->cx 
= 144; 
 448         dlgTemplate
->cy 
= 75; 
 450         // reuse the code in MSWGetStyle() but correct the results slightly for 
 452         dlgTemplate
->style 
= MSWGetStyle(style
, NULL
); 
 454         // all dialogs are popups 
 455         dlgTemplate
->style 
|= WS_POPUP
; 
 457         // force 3D-look if necessary, it looks impossibly ugly otherwise 
 458         if ( style 
& (wxRESIZE_BORDER 
| wxCAPTION
) ) 
 459             dlgTemplate
->style 
|= DS_MODALFRAME
; 
 461         bool ret 
= CreateDialog(dlgTemplate
, title
, pos
, size
); 
 468         return CreateFrame(title
, pos
, size
); 
 472 wxTopLevelWindowMSW::~wxTopLevelWindowMSW() 
 474     if ( wxModelessWindows
.Find(this) ) 
 475         wxModelessWindows
.DeleteObject(this); 
 477     // after destroying an owned window, Windows activates the next top level 
 478     // window in Z order but it may be different from our owner (to reproduce 
 479     // this simply Alt-TAB to another application and back before closing the 
 480     // owned frame) whereas we always want to yield activation to our parent 
 481     if ( HasFlag(wxFRAME_FLOAT_ON_PARENT
) ) 
 483         wxWindow 
*parent 
= GetParent(); 
 486             ::BringWindowToTop(GetHwndOf(parent
)); 
 491 // ---------------------------------------------------------------------------- 
 492 // wxTopLevelWindowMSW showing 
 493 // ---------------------------------------------------------------------------- 
 495 void wxTopLevelWindowMSW::DoShowWindow(int nShowCmd
) 
 497     ::ShowWindow(GetHwnd(), nShowCmd
); 
 499     m_iconized 
= nShowCmd 
== SW_MINIMIZE
; 
 502 bool wxTopLevelWindowMSW::Show(bool show
) 
 504     // don't use wxWindow version as we want to call DoShowWindow() ourselves 
 505     if ( !wxWindowBase::Show(show
) ) 
 511         if ( m_maximizeOnShow 
) 
 514             nShowCmd 
= SW_MAXIMIZE
; 
 516             m_maximizeOnShow 
= FALSE
; 
 528     DoShowWindow(nShowCmd
); 
 532         ::BringWindowToTop(GetHwnd()); 
 534         wxActivateEvent 
event(wxEVT_ACTIVATE
, TRUE
, m_windowId
); 
 535         event
.SetEventObject( this ); 
 536         GetEventHandler()->ProcessEvent(event
); 
 540         // Try to highlight the correct window (the parent) 
 543             HWND hWndParent 
= GetHwndOf(GetParent()); 
 545                 ::BringWindowToTop(hWndParent
); 
 552 // ---------------------------------------------------------------------------- 
 553 // wxTopLevelWindowMSW maximize/minimize 
 554 // ---------------------------------------------------------------------------- 
 556 void wxTopLevelWindowMSW::Maximize(bool maximize
) 
 560         // just maximize it directly 
 561         DoShowWindow(maximize 
? SW_MAXIMIZE 
: SW_RESTORE
); 
 565         // we can't maximize the hidden frame because it shows it as well, so 
 566         // just remember that we should do it later in this case 
 567         m_maximizeOnShow 
= TRUE
; 
 571 bool wxTopLevelWindowMSW::IsMaximized() const 
 573     return ::IsZoomed(GetHwnd()) != 0; 
 576 void wxTopLevelWindowMSW::Iconize(bool iconize
) 
 578     DoShowWindow(iconize 
? SW_MINIMIZE 
: SW_RESTORE
); 
 581 bool wxTopLevelWindowMSW::IsIconized() const 
 583     // also update the current state 
 584     ((wxTopLevelWindowMSW 
*)this)->m_iconized 
= ::IsIconic(GetHwnd()) != 0; 
 589 void wxTopLevelWindowMSW::Restore() 
 591     DoShowWindow(SW_RESTORE
); 
 594 // ---------------------------------------------------------------------------- 
 595 // wxTopLevelWindowMSW fullscreen 
 596 // ---------------------------------------------------------------------------- 
 598 bool wxTopLevelWindowMSW::ShowFullScreen(bool show
, long style
) 
 605         m_fsIsShowing 
= TRUE
; 
 608         // zap the frame borders 
 610         // save the 'normal' window style 
 611         m_fsOldWindowStyle 
= GetWindowLong((HWND
)GetHWND(), GWL_STYLE
); 
 613         // save the old position, width & height, maximize state 
 614         m_fsOldSize 
= GetRect(); 
 615         m_fsIsMaximized 
= IsMaximized(); 
 617         // decide which window style flags to turn off 
 618         LONG newStyle 
= m_fsOldWindowStyle
; 
 621         if (style 
& wxFULLSCREEN_NOBORDER
) 
 622             offFlags 
|= WS_BORDER 
| WS_THICKFRAME
; 
 623         if (style 
& wxFULLSCREEN_NOCAPTION
) 
 624             offFlags 
|= (WS_CAPTION 
| WS_SYSMENU
); 
 626         newStyle 
&= (~offFlags
); 
 628         // change our window style to be compatible with full-screen mode 
 629         ::SetWindowLong((HWND
)GetHWND(), GWL_STYLE
, newStyle
); 
 631         // resize to the size of the desktop 
 634         RECT rect 
= wxGetWindowRect(::GetDesktopWindow()); 
 635         width 
= rect
.right 
- rect
.left
; 
 636         height 
= rect
.bottom 
- rect
.top
; 
 638         SetSize(width
, height
); 
 640         // now flush the window style cache and actually go full-screen 
 641         SetWindowPos((HWND
)GetHWND(), HWND_TOP
, 0, 0, width
, height
, SWP_FRAMECHANGED
); 
 643         wxSizeEvent 
event(wxSize(width
, height
), GetId()); 
 644         GetEventHandler()->ProcessEvent(event
); 
 653         m_fsIsShowing 
= FALSE
; 
 655         Maximize(m_fsIsMaximized
); 
 656         SetWindowLong((HWND
)GetHWND(),GWL_STYLE
, m_fsOldWindowStyle
); 
 657         SetWindowPos((HWND
)GetHWND(),HWND_TOP
,m_fsOldSize
.x
, m_fsOldSize
.y
, 
 658             m_fsOldSize
.width
, m_fsOldSize
.height
, SWP_FRAMECHANGED
); 
 664 // ---------------------------------------------------------------------------- 
 665 // wxTopLevelWindowMSW misc 
 666 // ---------------------------------------------------------------------------- 
 668 void wxTopLevelWindowMSW::SetIcon(const wxIcon
& icon
) 
 670     SetIcons( wxIconBundle( icon 
) ); 
 673 void wxTopLevelWindowMSW::SetIcons(const wxIconBundle
& icons
) 
 675     wxTopLevelWindowBase::SetIcons(icons
); 
 677 #if defined(__WIN95__) && !defined(__WXMICROWIN__) 
 678     const wxIcon
& sml 
= icons
.GetIcon( wxSize( 16, 16 ) ); 
 679     if( sml
.Ok() && sml
.GetWidth() == 16 && sml
.GetHeight() == 16 ) 
 681         ::SendMessage( GetHwndOf( this ), WM_SETICON
, ICON_SMALL
, 
 682                        (LPARAM
)GetHiconOf(sml
) ); 
 685     const wxIcon
& big 
= icons
.GetIcon( wxSize( 32, 32 ) ); 
 686     if( big
.Ok() && big
.GetWidth() == 32 && big
.GetHeight() == 32 ) 
 688         ::SendMessage( GetHwndOf( this ), WM_SETICON
, ICON_BIG
, 
 689                        (LPARAM
)GetHiconOf(big
) ); 
 694 bool wxTopLevelWindowMSW::EnableCloseButton(bool enable
) 
 696 #ifndef __WXMICROWIN__ 
 697     // get system (a.k.a. window) menu 
 698     HMENU hmenu 
= ::GetSystemMenu(GetHwnd(), FALSE 
/* get it */); 
 701         wxLogLastError(_T("GetSystemMenu")); 
 706     // enabling/disabling the close item from it also automatically 
 707     // disables/enables the close title bar button 
 708     if ( ::EnableMenuItem(hmenu
, SC_CLOSE
, 
 710                           (enable 
? MF_ENABLED 
: MF_GRAYED
)) == -1 ) 
 712         wxLogLastError(_T("EnableMenuItem(SC_CLOSE)")); 
 717     // update appearance immediately 
 718     if ( !::DrawMenuBar(GetHwnd()) ) 
 720         wxLogLastError(_T("DrawMenuBar")); 
 722 #endif // !__WXMICROWIN__ 
 727 // ---------------------------------------------------------------------------- 
 728 // wxTopLevelWindow event handling 
 729 // ---------------------------------------------------------------------------- 
 731 // Default activation behaviour - set the focus for the first child 
 733 void wxTopLevelWindowMSW::OnActivate(wxActivateEvent
& event
) 
 735     if ( event
.GetActive() ) 
 737         // restore focus to the child which was last focused 
 738         wxLogTrace(_T("focus"), _T("wxTLW %08x activated."), (int) m_hWnd
); 
 740         wxWindow 
*parent 
= m_winLastFocused 
? m_winLastFocused
->GetParent() 
 747         wxSetFocusToChild(parent
, &m_winLastFocused
); 
 751         // remember the last focused child if it is our child 
 752         m_winLastFocused 
= FindFocus(); 
 754         // so we NULL it out if it's a child from some other frame 
 755         wxWindow 
*win 
= m_winLastFocused
; 
 758             if ( win
->IsTopLevel() ) 
 762                     m_winLastFocused 
= NULL
; 
 768             win 
= win
->GetParent(); 
 771         wxLogTrace(_T("focus"), 
 772                    _T("wxTLW %08x deactivated, last focused: %08x."), 
 774                    (int) (m_winLastFocused 
? GetHwndOf(m_winLastFocused
) 
 781 // the DialogProc for all wxWindows dialogs 
 782 LONG APIENTRY _EXPORT
 
 783 wxDlgProc(HWND hDlg
, UINT message
, WPARAM wParam
, LPARAM lParam
) 
 788             // for this message, returning TRUE tells system to set focus to 
 789             // the first control in the dialog box, but as we set the focus 
 790             // ourselves, we return FALSE from here as well, so fall through 
 793             // for all the other ones, FALSE means that we didn't process the 
 799 // ============================================================================ 
 800 // wxTLWHiddenParentModule implementation 
 801 // ============================================================================ 
 803 HWND 
wxTLWHiddenParentModule::ms_hwnd 
= NULL
; 
 805 const wxChar 
*wxTLWHiddenParentModule::ms_className 
= NULL
; 
 807 bool wxTLWHiddenParentModule::OnInit() 
 815 void wxTLWHiddenParentModule::OnExit() 
 819         if ( !::DestroyWindow(ms_hwnd
) ) 
 821             wxLogLastError(_T("DestroyWindow(hidden TLW parent)")); 
 829         if ( !::UnregisterClass(ms_className
, wxGetInstance()) ) 
 831             wxLogLastError(_T("UnregisterClass(\"wxTLWHiddenParent\")")); 
 839 HWND 
wxTLWHiddenParentModule::GetHWND() 
 845             static const wxChar 
*HIDDEN_PARENT_CLASS 
= _T("wxTLWHiddenParent"); 
 848             wxZeroMemory(wndclass
); 
 850             wndclass
.lpfnWndProc   
= DefWindowProc
; 
 851             wndclass
.hInstance     
= wxGetInstance(); 
 852             wndclass
.lpszClassName 
= HIDDEN_PARENT_CLASS
; 
 854             if ( !::RegisterClass(&wndclass
) ) 
 856                 wxLogLastError(_T("RegisterClass(\"wxTLWHiddenParent\")")); 
 860                 ms_className 
= HIDDEN_PARENT_CLASS
; 
 864         ms_hwnd 
= ::CreateWindow(ms_className
, _T(""), 0, 0, 0, 0, 0, NULL
, 
 865                                  (HMENU
)NULL
, wxGetInstance(), NULL
); 
 868             wxLogLastError(_T("CreateWindow(hidden TLW parent)"));