1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/msw/window.cpp 
   3 // Purpose:     wxWindowMSW 
   4 // Author:      Julian Smart 
   5 // Modified by: VZ on 13.05.99: no more Default(), MSWOnXXX() reorganisation 
   8 // Copyright:   (c) Julian Smart 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // =========================================================================== 
  14 // =========================================================================== 
  16 // --------------------------------------------------------------------------- 
  18 // --------------------------------------------------------------------------- 
  20 // For compilers that support precompilation, includes "wx.h". 
  21 #include "wx/wxprec.h" 
  28     #include "wx/msw/wrapwin.h" 
  29     #include "wx/window.h" 
  33     #include "wx/dcclient.h" 
  34     #include "wx/dcmemory.h" 
  37     #include "wx/layout.h" 
  38     #include "wx/dialog.h" 
  40     #include "wx/listbox.h" 
  41     #include "wx/button.h" 
  42     #include "wx/msgdlg.h" 
  43     #include "wx/settings.h" 
  44     #include "wx/statbox.h" 
  48 #if wxUSE_OWNER_DRAWN && !defined(__WXUNIVERSAL__) 
  49     #include "wx/ownerdrw.h" 
  52 #include "wx/evtloop.h" 
  53 #include "wx/module.h" 
  54 #include "wx/sysopt.h" 
  56 #if wxUSE_DRAG_AND_DROP 
  60 #if wxUSE_ACCESSIBILITY 
  61     #include "wx/access.h" 
  65         #define WM_GETOBJECT 0x003D 
  68         #define OBJID_CLIENT 0xFFFFFFFC 
  72 #include "wx/menuitem.h" 
  75 #include "wx/msw/private.h" 
  78     #include "wx/tooltip.h" 
  86     #include "wx/spinctrl.h" 
  87 #endif // wxUSE_SPINCTRL 
  92 #include "wx/textctrl.h" 
  93 #include "wx/notebook.h" 
  94 #include "wx/listctrl.h" 
  98 #if (!defined(__GNUWIN32_OLD__) && !defined(__WXMICROWIN__) /* && !defined(__WXWINCE__) */ ) || defined(__CYGWIN10__) 
 100     #include <mmsystem.h> 
 104     #include <windowsx.h> 
 107 #include <commctrl.h> 
 109 #include "wx/msw/missing.h" 
 111 #if defined(__WXWINCE__) 
 112     #include "wx/msw/wince/missing.h" 
 115 #if defined(TME_LEAVE) && defined(WM_MOUSELEAVE) 
 116     #define HAVE_TRACKMOUSEEVENT 
 117 #endif // everything needed for TrackMouseEvent() 
 119 // if this is set to 1, we use deferred window sizing to reduce flicker when 
 120 // resizing complicated window hierarchies, but this can in theory result in 
 121 // different behaviour than the old code so we keep the possibility to use it 
 122 // by setting this to 0 (in the future this should be removed completely) 
 123 #define USE_DEFERRED_SIZING 1 
 125 // set this to 1 to filter out duplicate mouse events, e.g. mouse move events 
 126 // when mouse position didnd't change 
 128     #define wxUSE_MOUSEEVENT_HACK 0 
 130     #define wxUSE_MOUSEEVENT_HACK 1 
 133 // --------------------------------------------------------------------------- 
 135 // --------------------------------------------------------------------------- 
 137 #if wxUSE_MENUS_NATIVE 
 138 wxMenu 
*wxCurrentPopupMenu 
= NULL
; 
 139 #endif // wxUSE_MENUS_NATIVE 
 142 extern       wxChar 
*wxCanvasClassName
; 
 144 extern const wxChar 
*wxCanvasClassName
; 
 147 // true if we had already created the std colour map, used by 
 148 // wxGetStdColourMap() and wxWindow::OnSysColourChanged()           (FIXME-MT) 
 149 static bool gs_hasStdCmap 
= false; 
 151 // last mouse event information we need to filter out the duplicates 
 152 #if wxUSE_MOUSEEVENT_HACK 
 153 static struct MouseEventInfoDummy
 
 155     // mouse position (in screen coordinates) 
 158     // last mouse event type 
 161 #endif // wxUSE_MOUSEEVENT_HACK 
 163 // --------------------------------------------------------------------------- 
 165 // --------------------------------------------------------------------------- 
 167 // the window proc for all our windows 
 168 LRESULT WXDLLEXPORT APIENTRY _EXPORT 
wxWndProc(HWND hWnd
, UINT message
, 
 169                                    WPARAM wParam
, LPARAM lParam
); 
 173     const wxChar 
*wxGetMessageName(int message
); 
 176 void wxRemoveHandleAssociation(wxWindowMSW 
*win
); 
 177 extern void wxAssociateWinWithHandle(HWND hWnd
, wxWindowMSW 
*win
); 
 178 wxWindow 
*wxFindWinFromHandle(WXHWND hWnd
); 
 180 // get the text metrics for the current font 
 181 static TEXTMETRIC 
wxGetTextMetrics(const wxWindowMSW 
*win
); 
 184 // find the window for the mouse event at the specified position 
 185 static wxWindowMSW 
*FindWindowForMouseEvent(wxWindowMSW 
*win
, int *x
, int *y
); 
 186 #endif // __WXWINCE__ 
 188 // wrapper around BringWindowToTop() API 
 189 static inline void wxBringWindowToTop(HWND hwnd
) 
 191 #ifdef __WXMICROWIN__ 
 192     // It seems that MicroWindows brings the _parent_ of the window to the top, 
 193     // which can be the wrong one. 
 195     // activate (set focus to) specified window 
 199     // raise top level parent to top of z order 
 200     if (!::SetWindowPos(hwnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE 
| SWP_NOSIZE
)) 
 202         wxLogLastError(_T("SetWindowPos")); 
 208 // ensure that all our parent windows have WS_EX_CONTROLPARENT style 
 209 static void EnsureParentHasControlParentStyle(wxWindow 
*parent
) 
 212        If we have WS_EX_CONTROLPARENT flag we absolutely *must* set it for our 
 213        parent as well as otherwise several Win32 functions using 
 214        GetNextDlgTabItem() to iterate over all controls such as 
 215        IsDialogMessage() or DefDlgProc() would enter an infinite loop: indeed, 
 216        all of them iterate over all the controls starting from the currently 
 217        focused one and stop iterating when they get back to the focus but 
 218        unless all parents have WS_EX_CONTROLPARENT bit set, they would never 
 219        get back to the initial (focused) window: as we do have this style, 
 220        GetNextDlgTabItem() will leave this window and continue in its parent, 
 221        but if the parent doesn't have it, it wouldn't recurse inside it later 
 222        on and so wouldn't have a chance of getting back to this window either. 
 224     while ( parent 
&& !parent
->IsTopLevel() ) 
 226         LONG exStyle 
= ::GetWindowLong(GetHwndOf(parent
), GWL_EXSTYLE
); 
 227         if ( !(exStyle 
& WS_EX_CONTROLPARENT
) ) 
 229             // force the parent to have this style 
 230             ::SetWindowLong(GetHwndOf(parent
), GWL_EXSTYLE
, 
 231                             exStyle 
| WS_EX_CONTROLPARENT
); 
 234         parent 
= parent
->GetParent(); 
 238 #endif // !__WXWINCE__ 
 241 // On Windows CE, GetCursorPos can return an error, so use this function 
 243 bool GetCursorPosWinCE(POINT
* pt
) 
 245     if (!GetCursorPos(pt
)) 
 247         DWORD pos 
= GetMessagePos(); 
 255 // --------------------------------------------------------------------------- 
 257 // --------------------------------------------------------------------------- 
 259 // in wxUniv/MSW this class is abstract because it doesn't have DoPopupMenu() 
 261 #ifdef __WXUNIVERSAL__ 
 262     IMPLEMENT_ABSTRACT_CLASS(wxWindowMSW
, wxWindowBase
) 
 264 #if wxUSE_EXTENDED_RTTI 
 266 // windows that are created from a parent window during its Create method, eg. spin controls in a calendar controls 
 267 // must never been streamed out separately otherwise chaos occurs. Right now easiest is to test for negative ids, as 
 268 // windows with negative ids never can be recreated anyway 
 270 bool wxWindowStreamingCallback( const wxObject 
*object
, wxWriter 
* , wxPersister 
* , wxxVariantArray 
& ) 
 272     const wxWindow 
* win 
= dynamic_cast<const wxWindow
*>(object
) ; 
 273     if ( win 
&& win
->GetId() < 0 ) 
 278 IMPLEMENT_DYNAMIC_CLASS_XTI_CALLBACK(wxWindow
, wxWindowBase
,"wx/window.h", wxWindowStreamingCallback
) 
 280 // make wxWindowList known before the property is used 
 282 wxCOLLECTION_TYPE_INFO( wxWindow
* , wxWindowList 
) ; 
 284 template<> void wxCollectionToVariantArray( wxWindowList 
const &theList
, wxxVariantArray 
&value
) 
 286     wxListCollectionToVariantArray
<wxWindowList::compatibility_iterator
>( theList 
, value 
) ; 
 289 WX_DEFINE_FLAGS( wxWindowStyle 
) 
 291 wxBEGIN_FLAGS( wxWindowStyle 
) 
 292     // new style border flags, we put them first to 
 293     // use them for streaming out 
 295     wxFLAGS_MEMBER(wxBORDER_SIMPLE
) 
 296     wxFLAGS_MEMBER(wxBORDER_SUNKEN
) 
 297     wxFLAGS_MEMBER(wxBORDER_DOUBLE
) 
 298     wxFLAGS_MEMBER(wxBORDER_RAISED
) 
 299     wxFLAGS_MEMBER(wxBORDER_STATIC
) 
 300     wxFLAGS_MEMBER(wxBORDER_NONE
) 
 302     // old style border flags 
 303     wxFLAGS_MEMBER(wxSIMPLE_BORDER
) 
 304     wxFLAGS_MEMBER(wxSUNKEN_BORDER
) 
 305     wxFLAGS_MEMBER(wxDOUBLE_BORDER
) 
 306     wxFLAGS_MEMBER(wxRAISED_BORDER
) 
 307     wxFLAGS_MEMBER(wxSTATIC_BORDER
) 
 308     wxFLAGS_MEMBER(wxBORDER
) 
 310     // standard window styles 
 311     wxFLAGS_MEMBER(wxTAB_TRAVERSAL
) 
 312     wxFLAGS_MEMBER(wxCLIP_CHILDREN
) 
 313     wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW
) 
 314     wxFLAGS_MEMBER(wxWANTS_CHARS
) 
 315     wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE
) 
 316     wxFLAGS_MEMBER(wxALWAYS_SHOW_SB 
) 
 317     wxFLAGS_MEMBER(wxVSCROLL
) 
 318     wxFLAGS_MEMBER(wxHSCROLL
) 
 320 wxEND_FLAGS( wxWindowStyle 
) 
 322 wxBEGIN_PROPERTIES_TABLE(wxWindow
) 
 323     wxEVENT_PROPERTY( Close 
, wxEVT_CLOSE_WINDOW 
, wxCloseEvent
) 
 324     wxEVENT_PROPERTY( Create 
, wxEVT_CREATE 
, wxWindowCreateEvent 
) 
 325     wxEVENT_PROPERTY( Destroy 
, wxEVT_DESTROY 
, wxWindowDestroyEvent 
) 
 326     // Always constructor Properties first 
 328     wxREADONLY_PROPERTY( Parent
,wxWindow
*, GetParent
, EMPTY_MACROVALUE 
, 0 /*flags*/ , wxT("Helpstring") , wxT("group")) 
 329     wxPROPERTY( Id
,wxWindowID
, SetId
, GetId
, -1 /*wxID_ANY*/ , 0 /*flags*/ , wxT("Helpstring") , wxT("group") ) 
 330     wxPROPERTY( Position
,wxPoint
, SetPosition 
, GetPosition
, wxDefaultPosition 
, 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // pos 
 331     wxPROPERTY( Size
,wxSize
, SetSize
, GetSize
, wxDefaultSize 
, 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // size 
 332     wxPROPERTY( WindowStyle 
, long , SetWindowStyleFlag 
, GetWindowStyleFlag 
, EMPTY_MACROVALUE 
, 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style 
 334     // Then all relations of the object graph 
 336     wxREADONLY_PROPERTY_COLLECTION( Children 
, wxWindowList 
, wxWindowBase
* , GetWindowChildren 
, wxPROP_OBJECT_GRAPH 
/*flags*/ , wxT("Helpstring") , wxT("group")) 
 338    // and finally all other properties 
 340     wxPROPERTY( ExtraStyle 
, long , SetExtraStyle 
, GetExtraStyle 
, EMPTY_MACROVALUE 
, 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // extstyle 
 341     wxPROPERTY( BackgroundColour 
, wxColour 
, SetBackgroundColour 
, GetBackgroundColour 
, EMPTY_MACROVALUE 
, 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // bg 
 342     wxPROPERTY( ForegroundColour 
, wxColour 
, SetForegroundColour 
, GetForegroundColour 
, EMPTY_MACROVALUE 
, 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // fg 
 343     wxPROPERTY( Enabled 
, bool , Enable 
, IsEnabled 
, wxxVariant((bool)true) , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) 
 344     wxPROPERTY( Shown 
, bool , Show 
, IsShown 
, wxxVariant((bool)true) , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) 
 346     // possible property candidates (not in xrc) or not valid in all subclasses 
 347     wxPROPERTY( Title
,wxString
, SetTitle
, GetTitle
, wxEmptyString 
) 
 348     wxPROPERTY( Font 
, wxFont 
, SetFont 
, GetWindowFont  
, ) 
 349     wxPROPERTY( Label
,wxString
, SetLabel
, GetLabel
, wxEmptyString 
) 
 350     // MaxHeight, Width , MinHeight , Width 
 351     // TODO switch label to control and title to toplevels 
 353     wxPROPERTY( ThemeEnabled 
, bool , SetThemeEnabled 
, GetThemeEnabled 
, ) 
 354     //wxPROPERTY( Cursor , wxCursor , SetCursor , GetCursor , ) 
 355     // wxPROPERTY( ToolTip , wxString , SetToolTip , GetToolTipText , ) 
 356     wxPROPERTY( AutoLayout 
, bool , SetAutoLayout 
, GetAutoLayout 
, ) 
 361 wxEND_PROPERTIES_TABLE() 
 363 wxBEGIN_HANDLERS_TABLE(wxWindow
) 
 364 wxEND_HANDLERS_TABLE() 
 366 wxCONSTRUCTOR_DUMMY(wxWindow
) 
 369     IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
) 
 371 #endif // __WXUNIVERSAL__/__WXMSW__ 
 373 BEGIN_EVENT_TABLE(wxWindowMSW
, wxWindowBase
) 
 374     EVT_SYS_COLOUR_CHANGED(wxWindowMSW::OnSysColourChanged
) 
 375     EVT_ERASE_BACKGROUND(wxWindowMSW::OnEraseBackground
) 
 377     EVT_INIT_DIALOG(wxWindowMSW::OnInitDialog
) 
 381 // =========================================================================== 
 383 // =========================================================================== 
 385 // --------------------------------------------------------------------------- 
 386 // wxWindow utility functions 
 387 // --------------------------------------------------------------------------- 
 389 // Find an item given the MS Windows id 
 390 wxWindow 
*wxWindowMSW::FindItem(long id
) const 
 393     wxControl 
*item 
= wxDynamicCastThis(wxControl
); 
 396         // is it us or one of our "internal" children? 
 397         if ( item
->GetId() == id
 
 398 #ifndef __WXUNIVERSAL__ 
 399                 || (item
->GetSubcontrols().Index(id
) != wxNOT_FOUND
) 
 400 #endif // __WXUNIVERSAL__ 
 406 #endif // wxUSE_CONTROLS 
 408     wxWindowList::compatibility_iterator current 
= GetChildren().GetFirst(); 
 411         wxWindow 
*childWin 
= current
->GetData(); 
 413         wxWindow 
*wnd 
= childWin
->FindItem(id
); 
 417         current 
= current
->GetNext(); 
 423 // Find an item given the MS Windows handle 
 424 wxWindow 
*wxWindowMSW::FindItemByHWND(WXHWND hWnd
, bool controlOnly
) const 
 426     wxWindowList::compatibility_iterator current 
= GetChildren().GetFirst(); 
 429         wxWindow 
*parent 
= current
->GetData(); 
 431         // Do a recursive search. 
 432         wxWindow 
*wnd 
= parent
->FindItemByHWND(hWnd
); 
 438                 || parent
->IsKindOf(CLASSINFO(wxControl
)) 
 439 #endif // wxUSE_CONTROLS 
 442             wxWindow 
*item 
= current
->GetData(); 
 443             if ( item
->GetHWND() == hWnd 
) 
 447                 if ( item
->ContainsHWND(hWnd
) ) 
 452         current 
= current
->GetNext(); 
 457 // Default command handler 
 458 bool wxWindowMSW::MSWCommand(WXUINT 
WXUNUSED(param
), WXWORD 
WXUNUSED(id
)) 
 463 // ---------------------------------------------------------------------------- 
 464 // constructors and such 
 465 // ---------------------------------------------------------------------------- 
 467 void wxWindowMSW::Init() 
 470     m_isBeingDeleted 
= false; 
 472     m_mouseInWindow 
= false; 
 473     m_lastKeydownProcessed 
= false; 
 475     m_childrenDisabled 
= NULL
; 
 484     m_pendingPosition 
= wxDefaultPosition
; 
 485     m_pendingSize 
= wxDefaultSize
; 
 489 wxWindowMSW::~wxWindowMSW() 
 491     m_isBeingDeleted 
= true; 
 493 #ifndef __WXUNIVERSAL__ 
 494     // VS: make sure there's no wxFrame with last focus set to us: 
 495     for ( wxWindow 
*win 
= GetParent(); win
; win 
= win
->GetParent() ) 
 497         wxTopLevelWindow 
*frame 
= wxDynamicCast(win
, wxTopLevelWindow
); 
 500             if ( frame
->GetLastFocus() == this ) 
 502                 frame
->SetLastFocus(NULL
); 
 505             // apparently sometimes we can end up with our grand parent 
 506             // pointing to us as well: this is surely a bug in focus handling 
 507             // code but it's not clear where it happens so for now just try to 
 508             // fix it here by not breaking out of the loop 
 512 #endif // __WXUNIVERSAL__ 
 514     // VS: destroy children first and _then_ detach *this from its parent. 
 515     //     If we did it the other way around, children wouldn't be able 
 516     //     find their parent frame (see above). 
 521         // VZ: test temp removed to understand what really happens here 
 522         //if (::IsWindow(GetHwnd())) 
 524             if ( !::DestroyWindow(GetHwnd()) ) 
 525                 wxLogLastError(wxT("DestroyWindow")); 
 528         // remove hWnd <-> wxWindow association 
 529         wxRemoveHandleAssociation(this); 
 532     delete m_childrenDisabled
; 
 536 // real construction (Init() must have been called before!) 
 537 bool wxWindowMSW::Create(wxWindow 
*parent
, 
 542                          const wxString
& name
) 
 544     wxCHECK_MSG( parent
, false, wxT("can't create wxWindow without parent") ); 
 546     if ( !CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
) ) 
 549     parent
->AddChild(this); 
 552     DWORD msflags 
= MSWGetCreateWindowFlags(&exstyle
); 
 554 #ifdef __WXUNIVERSAL__ 
 555     // no borders, we draw them ourselves 
 556     exstyle 
&= ~(WS_EX_DLGMODALFRAME 
| 
 560     msflags 
&= ~WS_BORDER
; 
 561 #endif // wxUniversal 
 565         msflags 
|= WS_VISIBLE
; 
 568     if ( !MSWCreate(wxCanvasClassName
, NULL
, pos
, size
, msflags
, exstyle
) ) 
 576 // --------------------------------------------------------------------------- 
 578 // --------------------------------------------------------------------------- 
 580 void wxWindowMSW::SetFocus() 
 582     HWND hWnd 
= GetHwnd(); 
 583     wxCHECK_RET( hWnd
, _T("can't set focus to invalid window") ); 
 585 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__) 
 589     if ( !::SetFocus(hWnd
) ) 
 591 #if defined(__WXDEBUG__) && !defined(__WXMICROWIN__) 
 592         // was there really an error? 
 593         DWORD dwRes 
= ::GetLastError(); 
 596             HWND hwndFocus 
= ::GetFocus(); 
 597             if ( hwndFocus 
!= hWnd 
) 
 599                 wxLogApiError(_T("SetFocus"), dwRes
); 
 606 void wxWindowMSW::SetFocusFromKbd() 
 608     // when the focus is given to the control with DLGC_HASSETSEL style from 
 609     // keyboard its contents should be entirely selected: this is what 
 610     // ::IsDialogMessage() does and so we should do it as well to provide the 
 611     // same LNF as the native programs 
 612     if ( ::SendMessage(GetHwnd(), WM_GETDLGCODE
, 0, 0) & DLGC_HASSETSEL 
) 
 614         ::SendMessage(GetHwnd(), EM_SETSEL
, 0, -1); 
 617     // do this after (maybe) setting the selection as like this when 
 618     // wxEVT_SET_FOCUS handler is called, the selection would have been already 
 619     // set correctly -- this may be important 
 620     wxWindowBase::SetFocusFromKbd(); 
 623 // Get the window with the focus 
 624 wxWindow 
*wxWindowBase::DoFindFocus() 
 626     HWND hWnd 
= ::GetFocus(); 
 629         return wxGetWindowFromHWND((WXHWND
)hWnd
); 
 635 bool wxWindowMSW::Enable(bool enable
) 
 637     if ( !wxWindowBase::Enable(enable
) ) 
 640     HWND hWnd 
= GetHwnd(); 
 642         ::EnableWindow(hWnd
, (BOOL
)enable
); 
 644     // the logic below doesn't apply to the top level windows -- otherwise 
 645     // showing a modal dialog would result in total greying out (and ungreying 
 646     // out later) of everything which would be really ugly 
 650     // when the parent is disabled, all of its children should be disabled as 
 651     // well but when it is enabled back, only those of the children which 
 652     // hadn't been already disabled in the beginning should be enabled again, 
 653     // so we have to keep the list of those children 
 654     for ( wxWindowList::compatibility_iterator node 
= GetChildren().GetFirst(); 
 656           node 
= node
->GetNext() ) 
 658         wxWindow 
*child 
= node
->GetData(); 
 659         if ( child
->IsTopLevel() ) 
 661             // the logic below doesn't apply to top level children 
 667             // re-enable the child unless it had been disabled before us 
 668             if ( !m_childrenDisabled 
|| !m_childrenDisabled
->Find(child
) ) 
 671         else // we're being disabled 
 673             if ( child
->IsEnabled() ) 
 675                 // disable it as children shouldn't stay enabled while the 
 679             else // child already disabled, remember it 
 681                 // have we created the list of disabled children already? 
 682                 if ( !m_childrenDisabled 
) 
 683                     m_childrenDisabled 
= new wxWindowList
; 
 685                 m_childrenDisabled
->Append(child
); 
 690     if ( enable 
&& m_childrenDisabled 
) 
 692         // we don't need this list any more, don't keep unused memory 
 693         delete m_childrenDisabled
; 
 694         m_childrenDisabled 
= NULL
; 
 700 bool wxWindowMSW::Show(bool show
) 
 702     if ( !wxWindowBase::Show(show
) ) 
 705     HWND hWnd 
= GetHwnd(); 
 707     // we could be called before the underlying window is created (this is 
 708     // actually useful to prevent it from being initially shown), e.g. 
 710     //      wxFoo *foo = new wxFoo; 
 712     //      foo->Create(parent, ...); 
 714     // should work without errors 
 717         ::ShowWindow(hWnd
, show 
? SW_SHOW 
: SW_HIDE
); 
 723 // Raise the window to the top of the Z order 
 724 void wxWindowMSW::Raise() 
 726     wxBringWindowToTop(GetHwnd()); 
 729 // Lower the window to the bottom of the Z order 
 730 void wxWindowMSW::Lower() 
 732     ::SetWindowPos(GetHwnd(), HWND_BOTTOM
, 0, 0, 0, 0, 
 733                    SWP_NOMOVE 
| SWP_NOSIZE 
| SWP_NOACTIVATE
); 
 736 void wxWindowMSW::DoCaptureMouse() 
 738     HWND hWnd 
= GetHwnd(); 
 745 void wxWindowMSW::DoReleaseMouse() 
 747     if ( !::ReleaseCapture() ) 
 749         wxLogLastError(_T("ReleaseCapture")); 
 753 /* static */ wxWindow 
*wxWindowBase::GetCapture() 
 755     HWND hwnd 
= ::GetCapture(); 
 756     return hwnd 
? wxFindWinFromHandle((WXHWND
)hwnd
) : (wxWindow 
*)NULL
; 
 759 bool wxWindowMSW::SetFont(const wxFont
& font
) 
 761     if ( !wxWindowBase::SetFont(font
) ) 
 767     HWND hWnd 
= GetHwnd(); 
 770         WXHANDLE hFont 
= m_font
.GetResourceHandle(); 
 772         wxASSERT_MSG( hFont
, wxT("should have valid font") ); 
 774         ::SendMessage(hWnd
, WM_SETFONT
, (WPARAM
)hFont
, MAKELPARAM(TRUE
, 0)); 
 779 bool wxWindowMSW::SetCursor(const wxCursor
& cursor
) 
 781     if ( !wxWindowBase::SetCursor(cursor
) ) 
 789         HWND hWnd 
= GetHwnd(); 
 791         // Change the cursor NOW if we're within the correct window 
 794         ::GetCursorPosWinCE(&point
); 
 796         ::GetCursorPos(&point
); 
 799         RECT rect 
= wxGetWindowRect(hWnd
); 
 801         if ( ::PtInRect(&rect
, point
) && !wxIsBusy() ) 
 802             ::SetCursor(GetHcursorOf(m_cursor
)); 
 808 void wxWindowMSW::WarpPointer(int x
, int y
) 
 810     ClientToScreen(&x
, &y
); 
 812     if ( !::SetCursorPos(x
, y
) ) 
 814         wxLogLastError(_T("SetCursorPos")); 
 818 void wxWindowMSW::MSWUpdateUIState(int action
, int state
) 
 820     // WM_CHANGEUISTATE only appeared in Windows 2000 so it can do us no good 
 821     // to use it on older systems -- and could possibly do some harm 
 822     static int s_needToUpdate 
= -1; 
 823     if ( s_needToUpdate 
== -1 ) 
 826         s_needToUpdate 
= wxGetOsVersion(&verMaj
, &verMin
) == wxWINDOWS_NT 
&& 
 830     if ( s_needToUpdate 
) 
 832         // we send WM_CHANGEUISTATE so if nothing needs changing then the system 
 833         // won't send WM_UPDATEUISTATE 
 834         ::SendMessage(GetHwnd(), WM_CHANGEUISTATE
, MAKEWPARAM(action
, state
), 0); 
 838 // --------------------------------------------------------------------------- 
 840 // --------------------------------------------------------------------------- 
 842 inline int GetScrollPosition(HWND hWnd
, int wOrient
) 
 844 #ifdef __WXMICROWIN__ 
 845     return ::GetScrollPosWX(hWnd
, wOrient
); 
 847     WinStruct
<SCROLLINFO
> scrollInfo
; 
 848     scrollInfo
.cbSize 
= sizeof(SCROLLINFO
); 
 849     scrollInfo
.fMask 
= SIF_POS
; 
 850     ::GetScrollInfo(hWnd
, wOrient
, &scrollInfo 
); 
 852     return scrollInfo
.nPos
; 
 857 int wxWindowMSW::GetScrollPos(int orient
) const 
 859     HWND hWnd 
= GetHwnd(); 
 860     wxCHECK_MSG( hWnd
, 0, _T("no HWND in GetScrollPos") ); 
 862     return GetScrollPosition(hWnd
, orient 
== wxHORIZONTAL 
? SB_HORZ 
: SB_VERT
); 
 865 // This now returns the whole range, not just the number 
 866 // of positions that we can scroll. 
 867 int wxWindowMSW::GetScrollRange(int orient
) const 
 870     HWND hWnd 
= GetHwnd(); 
 874     ::GetScrollRange(hWnd
, orient 
== wxHORIZONTAL 
? SB_HORZ 
: SB_VERT
, 
 877     WinStruct
<SCROLLINFO
> scrollInfo
; 
 878     scrollInfo
.fMask 
= SIF_RANGE
; 
 879     if ( !::GetScrollInfo(hWnd
, 
 880                           orient 
== wxHORIZONTAL 
? SB_HORZ 
: SB_VERT
, 
 883         // Most of the time this is not really an error, since the return 
 884         // value can also be zero when there is no scrollbar yet. 
 885         // wxLogLastError(_T("GetScrollInfo")); 
 887     maxPos 
= scrollInfo
.nMax
; 
 889     // undo "range - 1" done in SetScrollbar() 
 893 int wxWindowMSW::GetScrollThumb(int orient
) const 
 895     return orient 
== wxHORIZONTAL 
? m_xThumbSize 
: m_yThumbSize
; 
 898 void wxWindowMSW::SetScrollPos(int orient
, int pos
, bool refresh
) 
 900     HWND hWnd 
= GetHwnd(); 
 901     wxCHECK_RET( hWnd
, _T("SetScrollPos: no HWND") ); 
 903     WinStruct
<SCROLLINFO
> info
; 
 907     info
.fMask 
= SIF_POS
; 
 908     if ( HasFlag(wxALWAYS_SHOW_SB
) ) 
 910         // disable scrollbar instead of removing it then 
 911         info
.fMask 
|= SIF_DISABLENOSCROLL
; 
 914     ::SetScrollInfo(hWnd
, orient 
== wxHORIZONTAL 
? SB_HORZ 
: SB_VERT
, 
 918 // New function that will replace some of the above. 
 919 void wxWindowMSW::SetScrollbar(int orient
, 
 925     WinStruct
<SCROLLINFO
> info
; 
 926     info
.nPage 
= pageSize
; 
 927     info
.nMin 
= 0;              // range is nMax - nMin + 1 
 928     info
.nMax 
= range 
- 1;      //  as both nMax and nMax are inclusive 
 930     info
.fMask 
= SIF_RANGE 
| SIF_PAGE 
| SIF_POS
; 
 931     if ( HasFlag(wxALWAYS_SHOW_SB
) ) 
 933         // disable scrollbar instead of removing it then 
 934         info
.fMask 
|= SIF_DISABLENOSCROLL
; 
 937     HWND hWnd 
= GetHwnd(); 
 940         // We have to set the variables here to make them valid in events 
 941         // triggered by ::SetScrollInfo() 
 942         *(orient 
== wxHORIZONTAL 
? &m_xThumbSize 
: &m_yThumbSize
) = pageSize
; 
 944         ::SetScrollInfo(hWnd
, orient 
== wxHORIZONTAL 
? SB_HORZ 
: SB_VERT
, 
 949 void wxWindowMSW::ScrollWindow(int dx
, int dy
, const wxRect 
*prect
) 
 955         rect
.left 
= prect
->x
; 
 957         rect
.right 
= prect
->x 
+ prect
->width
; 
 958         rect
.bottom 
= prect
->y 
+ prect
->height
; 
 968     // FIXME: is this the exact equivalent of the line below? 
 969     ::ScrollWindowEx(GetHwnd(), dx
, dy
, pr
, pr
, 0, 0, SW_SCROLLCHILDREN
|SW_ERASE
|SW_INVALIDATE
); 
 971     ::ScrollWindow(GetHwnd(), dx
, dy
, pr
, pr
); 
 975 static bool ScrollVertically(HWND hwnd
, int kind
, int count
) 
 977     int posStart 
= GetScrollPosition(hwnd
, SB_VERT
); 
 980     for ( int n 
= 0; n 
< count
; n
++ ) 
 982         ::SendMessage(hwnd
, WM_VSCROLL
, kind
, 0); 
 984         int posNew 
= GetScrollPosition(hwnd
, SB_VERT
); 
 987             // don't bother to continue, we're already at top/bottom 
 994     return pos 
!= posStart
; 
 997 bool wxWindowMSW::ScrollLines(int lines
) 
 999     bool down 
= lines 
> 0; 
1001     return ScrollVertically(GetHwnd(), 
1002                             down 
? SB_LINEDOWN 
: SB_LINEUP
, 
1003                             down 
? lines 
: -lines
); 
1006 bool wxWindowMSW::ScrollPages(int pages
) 
1008     bool down 
= pages 
> 0; 
1010     return ScrollVertically(GetHwnd(), 
1011                             down 
? SB_PAGEDOWN 
: SB_PAGEUP
, 
1012                             down 
? pages 
: -pages
); 
1015 // --------------------------------------------------------------------------- 
1017 // --------------------------------------------------------------------------- 
1019 void wxWindowMSW::SubclassWin(WXHWND hWnd
) 
1021     wxASSERT_MSG( !m_oldWndProc
, wxT("subclassing window twice?") ); 
1023     HWND hwnd 
= (HWND
)hWnd
; 
1024     wxCHECK_RET( ::IsWindow(hwnd
), wxT("invalid HWND in SubclassWin") ); 
1026     wxAssociateWinWithHandle(hwnd
, this); 
1028     m_oldWndProc 
= (WXFARPROC
)wxGetWindowProc((HWND
)hWnd
); 
1030     // we don't need to subclass the window of our own class (in the Windows 
1031     // sense of the word) 
1032     if ( !wxCheckWindowWndProc(hWnd
, (WXFARPROC
)wxWndProc
) ) 
1034         wxSetWindowProc(hwnd
, wxWndProc
); 
1038         // don't bother restoring it either: this also makes it easy to 
1039         // implement IsOfStandardClass() method which returns true for the 
1040         // standard controls and false for the wxWidgets own windows as it can 
1041         // simply check m_oldWndProc 
1042         m_oldWndProc 
= NULL
; 
1046 void wxWindowMSW::UnsubclassWin() 
1048     wxRemoveHandleAssociation(this); 
1050     // Restore old Window proc 
1051     HWND hwnd 
= GetHwnd(); 
1056         wxCHECK_RET( ::IsWindow(hwnd
), wxT("invalid HWND in UnsubclassWin") ); 
1060             if ( !wxCheckWindowWndProc((WXHWND
)hwnd
, m_oldWndProc
) ) 
1062                 wxSetWindowProc(hwnd
, (WNDPROC
)m_oldWndProc
); 
1065             m_oldWndProc 
= NULL
; 
1070 void wxWindowMSW::AssociateHandle(WXWidget handle
) 
1074       if ( !::DestroyWindow(GetHwnd()) ) 
1075         wxLogLastError(wxT("DestroyWindow")); 
1078     WXHWND wxhwnd 
= (WXHWND
)handle
; 
1081     SubclassWin(wxhwnd
); 
1084 void wxWindowMSW::DissociateHandle() 
1086     // this also calls SetHWND(0) for us 
1091 bool wxCheckWindowWndProc(WXHWND hWnd
, 
1092                           WXFARPROC 
WXUNUSED(wndProc
)) 
1094 // TODO: This list of window class names should be factored out so they can be 
1095 // managed in one place and then accessed from here and other places, such as 
1096 // wxApp::RegisterWindowClasses() and wxApp::UnregisterWindowClasses() 
1099     extern       wxChar 
*wxCanvasClassName
; 
1100     extern       wxChar 
*wxCanvasClassNameNR
; 
1102     extern const wxChar 
*wxCanvasClassName
; 
1103     extern const wxChar 
*wxCanvasClassNameNR
; 
1105     extern const wxChar 
*wxMDIFrameClassName
; 
1106     extern const wxChar 
*wxMDIFrameClassNameNoRedraw
; 
1107     extern const wxChar 
*wxMDIChildFrameClassName
; 
1108     extern const wxChar 
*wxMDIChildFrameClassNameNoRedraw
; 
1109     wxString 
str(wxGetWindowClass(hWnd
)); 
1110     if (str 
== wxCanvasClassName 
|| 
1111         str 
== wxCanvasClassNameNR 
|| 
1112         str 
== wxMDIFrameClassName 
|| 
1113         str 
== wxMDIFrameClassNameNoRedraw 
|| 
1114         str 
== wxMDIChildFrameClassName 
|| 
1115         str 
== wxMDIChildFrameClassNameNoRedraw 
|| 
1116         str 
== _T("wxTLWHiddenParent")) 
1117         return true; // Effectively means don't subclass 
1122 // ---------------------------------------------------------------------------- 
1124 // ---------------------------------------------------------------------------- 
1126 void wxWindowMSW::SetWindowStyleFlag(long flags
) 
1128     long flagsOld 
= GetWindowStyleFlag(); 
1129     if ( flags 
== flagsOld 
) 
1132     // update the internal variable 
1133     wxWindowBase::SetWindowStyleFlag(flags
); 
1135     // now update the Windows style as well if needed - and if the window had 
1136     // been already created 
1140     WXDWORD exstyle
, exstyleOld
; 
1141     long style 
= MSWGetStyle(flags
, &exstyle
), 
1142          styleOld 
= MSWGetStyle(flagsOld
, &exstyleOld
); 
1144     if ( style 
!= styleOld 
) 
1146         // some flags (e.g. WS_VISIBLE or WS_DISABLED) should not be changed by 
1147         // this function so instead of simply setting the style to the new 
1148         // value we clear the bits which were set in styleOld but are set in 
1149         // the new one and set the ones which were not set before 
1150         long styleReal 
= ::GetWindowLong(GetHwnd(), GWL_STYLE
); 
1151         styleReal 
&= ~styleOld
; 
1154         ::SetWindowLong(GetHwnd(), GWL_STYLE
, styleReal
); 
1157     // and the extended style 
1158     if ( exstyle 
!= exstyleOld 
) 
1160         long exstyleReal 
= ::GetWindowLong(GetHwnd(), GWL_EXSTYLE
); 
1161         exstyleReal 
&= ~exstyleOld
; 
1162         exstyleReal 
|= exstyle
; 
1164         ::SetWindowLong(GetHwnd(), GWL_EXSTYLE
, exstyleReal
); 
1166         // we must call SetWindowPos() to flush the cached extended style and 
1167         // also to make the change to wxSTAY_ON_TOP style take effect: just 
1168         // setting the style simply doesn't work 
1169         if ( !::SetWindowPos(GetHwnd(), 
1170                              exstyleReal 
& WS_EX_TOPMOST 
? HWND_TOPMOST
 
1173                              SWP_NOMOVE 
| SWP_NOSIZE
) ) 
1175             wxLogLastError(_T("SetWindowPos")); 
1180 WXDWORD 
wxWindowMSW::MSWGetStyle(long flags
, WXDWORD 
*exstyle
) const 
1182     // translate common wxWidgets styles to Windows ones 
1184     // most of windows are child ones, those which are not (such as 
1185     // wxTopLevelWindow) should remove WS_CHILD in their MSWGetStyle() 
1186     WXDWORD style 
= WS_CHILD
; 
1188     // using this flag results in very significant reduction in flicker, 
1189     // especially with controls inside the static boxes (as the interior of the 
1190     // box is not redrawn twice), but sometimes results in redraw problems, so 
1191     // optionally allow the old code to continue to use it provided a special 
1192     // system option is turned on 
1193     if ( !wxSystemOptions::GetOptionInt(wxT("msw.window.no-clip-children")) 
1194             || (flags 
& wxCLIP_CHILDREN
) ) 
1195         style 
|= WS_CLIPCHILDREN
; 
1197     // it doesn't seem useful to use WS_CLIPSIBLINGS here as we officially 
1198     // don't support overlapping windows and it only makes sense for them and, 
1199     // presumably, gives the system some extra work (to manage more clipping 
1200     // regions), so avoid it alltogether 
1203     if ( flags 
& wxVSCROLL 
) 
1204         style 
|= WS_VSCROLL
; 
1206     if ( flags 
& wxHSCROLL 
) 
1207         style 
|= WS_HSCROLL
; 
1209     const wxBorder border 
= GetBorder(flags
); 
1211     // WS_BORDER is only required for wxBORDER_SIMPLE 
1212     if ( border 
== wxBORDER_SIMPLE 
) 
1215     // now deal with ext style if the caller wants it 
1221         if ( flags 
& wxTRANSPARENT_WINDOW 
) 
1222             *exstyle 
|= WS_EX_TRANSPARENT
; 
1228             case wxBORDER_DEFAULT
: 
1229                 wxFAIL_MSG( _T("unknown border style") ); 
1233             case wxBORDER_SIMPLE
: 
1236             case wxBORDER_STATIC
: 
1237                 *exstyle 
|= WS_EX_STATICEDGE
; 
1240             case wxBORDER_RAISED
: 
1241                 *exstyle 
|= WS_EX_DLGMODALFRAME
; 
1244             case wxBORDER_SUNKEN
: 
1245                 *exstyle 
|= WS_EX_CLIENTEDGE
; 
1246                 style 
&= ~WS_BORDER
; 
1249             case wxBORDER_DOUBLE
: 
1250                 *exstyle 
|= WS_EX_DLGMODALFRAME
; 
1254         // wxUniv doesn't use Windows dialog navigation functions at all 
1255 #if !defined(__WXUNIVERSAL__) && !defined(__WXWINCE__) 
1256         // to make the dialog navigation work with the nested panels we must 
1257         // use this style (top level windows such as dialogs don't need it) 
1258         if ( (flags 
& wxTAB_TRAVERSAL
) && !IsTopLevel() ) 
1260             *exstyle 
|= WS_EX_CONTROLPARENT
; 
1262 #endif // __WXUNIVERSAL__ 
1268 // Setup background and foreground colours correctly 
1269 void wxWindowMSW::SetupColours() 
1272         SetBackgroundColour(GetParent()->GetBackgroundColour()); 
1275 bool wxWindowMSW::IsMouseInWindow() const 
1277     // get the mouse position 
1280     ::GetCursorPosWinCE(&pt
); 
1282     ::GetCursorPos(&pt
); 
1285     // find the window which currently has the cursor and go up the window 
1286     // chain until we find this window - or exhaust it 
1287     HWND hwnd 
= ::WindowFromPoint(pt
); 
1288     while ( hwnd 
&& (hwnd 
!= GetHwnd()) ) 
1289         hwnd 
= ::GetParent(hwnd
); 
1291     return hwnd 
!= NULL
; 
1294 void wxWindowMSW::OnInternalIdle() 
1296 #ifndef HAVE_TRACKMOUSEEVENT 
1297     // Check if we need to send a LEAVE event 
1298     if ( m_mouseInWindow 
) 
1300         // note that we should generate the leave event whether the window has 
1301         // or doesn't have mouse capture 
1302         if ( !IsMouseInWindow() ) 
1304             GenerateMouseLeave(); 
1307 #endif // !HAVE_TRACKMOUSEEVENT 
1309     if (wxUpdateUIEvent::CanUpdate(this)) 
1310         UpdateWindowUI(wxUPDATE_UI_FROMIDLE
); 
1313 // Set this window to be the child of 'parent'. 
1314 bool wxWindowMSW::Reparent(wxWindowBase 
*parent
) 
1316     if ( !wxWindowBase::Reparent(parent
) ) 
1319     HWND hWndChild 
= GetHwnd(); 
1320     HWND hWndParent 
= GetParent() ? GetWinHwnd(GetParent()) : (HWND
)0; 
1322     ::SetParent(hWndChild
, hWndParent
); 
1325     if ( ::GetWindowLong(hWndChild
, GWL_EXSTYLE
) & WS_EX_CONTROLPARENT 
) 
1327         EnsureParentHasControlParentStyle(GetParent()); 
1329 #endif // !__WXWINCE__ 
1334 static inline void SendSetRedraw(HWND hwnd
, bool on
) 
1336 #ifndef __WXMICROWIN__ 
1337     ::SendMessage(hwnd
, WM_SETREDRAW
, (WPARAM
)on
, 0); 
1341 void wxWindowMSW::Freeze() 
1343     if ( !m_frozenness
++ ) 
1346             SendSetRedraw(GetHwnd(), false); 
1350 void wxWindowMSW::Thaw() 
1352     wxASSERT_MSG( m_frozenness 
> 0, _T("Thaw() without matching Freeze()") ); 
1354     if ( !--m_frozenness 
) 
1358             SendSetRedraw(GetHwnd(), true); 
1360             // we need to refresh everything or otherwise the invalidated area 
1361             // is not going to be repainted 
1367 void wxWindowMSW::Refresh(bool eraseBack
, const wxRect 
*rect
) 
1369     HWND hWnd 
= GetHwnd(); 
1376             mswRect
.left 
= rect
->x
; 
1377             mswRect
.top 
= rect
->y
; 
1378             mswRect
.right 
= rect
->x 
+ rect
->width
; 
1379             mswRect
.bottom 
= rect
->y 
+ rect
->height
; 
1388         // RedrawWindow not available on SmartPhone or eVC++ 3 
1389 #if !defined(__SMARTPHONE__) && !(defined(_WIN32_WCE) && _WIN32_WCE < 400) 
1390         UINT flags 
= RDW_INVALIDATE 
| RDW_ALLCHILDREN
; 
1394         ::RedrawWindow(hWnd
, pRect
, NULL
, flags
); 
1396         ::InvalidateRect(hWnd
, pRect
, eraseBack
); 
1401 void wxWindowMSW::Update() 
1403     if ( !::UpdateWindow(GetHwnd()) ) 
1405         wxLogLastError(_T("UpdateWindow")); 
1408 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__) 
1409     // just calling UpdateWindow() is not enough, what we did in our WM_PAINT 
1410     // handler needs to be really drawn right now 
1415 // --------------------------------------------------------------------------- 
1417 // --------------------------------------------------------------------------- 
1420 #if wxUSE_DRAG_AND_DROP 
1421 void wxWindowMSW::SetDropTarget(wxDropTarget 
*pDropTarget
) 
1423     if ( m_dropTarget 
!= 0 ) { 
1424         m_dropTarget
->Revoke(m_hWnd
); 
1425         delete m_dropTarget
; 
1428     m_dropTarget 
= pDropTarget
; 
1429     if ( m_dropTarget 
!= 0 ) 
1430         m_dropTarget
->Register(m_hWnd
); 
1432 #endif // wxUSE_DRAG_AND_DROP 
1434 // old-style file manager drag&drop support: we retain the old-style 
1435 // DragAcceptFiles in parallel with SetDropTarget. 
1436 void wxWindowMSW::DragAcceptFiles(bool WXUNUSED_IN_WINCE(accept
)) 
1439     HWND hWnd 
= GetHwnd(); 
1441         ::DragAcceptFiles(hWnd
, (BOOL
)accept
); 
1445 // ---------------------------------------------------------------------------- 
1447 // ---------------------------------------------------------------------------- 
1451 void wxWindowMSW::DoSetToolTip(wxToolTip 
*tooltip
) 
1453     wxWindowBase::DoSetToolTip(tooltip
); 
1456         m_tooltip
->SetWindow((wxWindow 
*)this); 
1459 #endif // wxUSE_TOOLTIPS 
1461 // --------------------------------------------------------------------------- 
1462 // moving and resizing 
1463 // --------------------------------------------------------------------------- 
1465 bool wxWindowMSW::IsSizeDeferred() const 
1467 #if USE_DEFERRED_SIZING 
1468     if ( m_pendingPosition 
!= wxDefaultPosition 
|| 
1469          m_pendingSize     
!= wxDefaultSize 
) 
1471 #endif // USE_DEFERRED_SIZING 
1477 void wxWindowMSW::DoGetSize(int *x
, int *y
) const 
1479     // if SetSize() had been called at wx level but not realized at Windows 
1480     // level yet (i.e. EndDeferWindowPos() not called), we still should return 
1481     // the new and not the old position to the other wx code 
1482     if ( m_pendingSize 
!= wxDefaultSize 
) 
1485             *x 
= m_pendingSize
.x
; 
1487             *y 
= m_pendingSize
.y
; 
1489     else // use current size 
1491         RECT rect 
= wxGetWindowRect(GetHwnd()); 
1494             *x 
= rect
.right 
- rect
.left
; 
1496             *y 
= rect
.bottom 
- rect
.top
; 
1500 // Get size *available for subwindows* i.e. excluding menu bar etc. 
1501 void wxWindowMSW::DoGetClientSize(int *x
, int *y
) const 
1503     if ( IsTopLevel() || m_pendingSize 
== wxDefaultSize 
) 
1505         // top level windows resizing is never deferred, so we can safely use 
1506         // the current size here 
1507         RECT rect 
= wxGetClientRect(GetHwnd()); 
1514     else // non top level and using deferred sizing 
1516         // we need to calculate the *pending* client size here 
1518         rect
.left 
= m_pendingPosition
.x
; 
1519         rect
.top 
= m_pendingPosition
.y
; 
1520         rect
.right 
= rect
.left 
+ m_pendingSize
.x
; 
1521         rect
.bottom 
= rect
.top 
+ m_pendingSize
.y
; 
1523         ::SendMessage(GetHwnd(), WM_NCCALCSIZE
, FALSE
, (LPARAM
)&rect
); 
1526             *x 
= rect
.right 
- rect
.left
; 
1528             *y 
= rect
.bottom 
- rect
.top
; 
1532 void wxWindowMSW::DoGetPosition(int *x
, int *y
) const 
1534     wxWindow 
* const parent 
= GetParent(); 
1537     if ( m_pendingPosition 
!= wxDefaultPosition 
) 
1539         pos 
= m_pendingPosition
; 
1541     else // use current position 
1543         RECT rect 
= wxGetWindowRect(GetHwnd()); 
1546         point
.x 
= rect
.left
; 
1549         // we do the adjustments with respect to the parent only for the "real" 
1550         // children, not for the dialogs/frames 
1551         if ( !IsTopLevel() ) 
1553             // Since we now have the absolute screen coords, if there's a 
1554             // parent we must subtract its top left corner 
1557                 ::ScreenToClient(GetHwndOf(parent
), &point
); 
1565     // we also must adjust by the client area offset: a control which is just 
1566     // under a toolbar could be at (0, 30) in Windows but at (0, 0) in wx 
1567     if ( parent 
&& !IsTopLevel() ) 
1569         const wxPoint 
pt(parent
->GetClientAreaOrigin()); 
1580 void wxWindowMSW::DoScreenToClient(int *x
, int *y
) const 
1588     ::ScreenToClient(GetHwnd(), &pt
); 
1596 void wxWindowMSW::DoClientToScreen(int *x
, int *y
) const 
1604     ::ClientToScreen(GetHwnd(), &pt
); 
1613 wxWindowMSW::DoMoveSibling(WXHWND hwnd
, int x
, int y
, int width
, int height
) 
1615 #if USE_DEFERRED_SIZING 
1616     // if our parent had prepared a defer window handle for us, use it (unless 
1617     // we are a top level window) 
1618     wxWindowMSW 
* const parent 
= IsTopLevel() ? NULL 
: GetParent(); 
1620     HDWP hdwp 
= parent 
? (HDWP
)parent
->m_hDWP 
: NULL
; 
1623         hdwp 
= ::DeferWindowPos(hdwp
, (HWND
)hwnd
, NULL
, x
, y
, width
, height
, 
1624                                 SWP_NOZORDER 
| SWP_NOOWNERZORDER 
| SWP_NOACTIVATE
); 
1627             wxLogLastError(_T("DeferWindowPos")); 
1633         // hdwp must be updated as it may have been changed 
1634         parent
->m_hDWP 
= (WXHANDLE
)hdwp
; 
1639         // did deferred move, remember new coordinates of the window as they're 
1640         // different from what Windows would return for it 
1644     // otherwise (or if deferring failed) move the window in place immediately 
1645 #endif // USE_DEFERRED_SIZING 
1646     if ( !::MoveWindow((HWND
)hwnd
, x
, y
, width
, height
, IsShown()) ) 
1648         wxLogLastError(wxT("MoveWindow")); 
1651     // if USE_DEFERRED_SIZING, indicates that we didn't use deferred move, 
1652     // ignored otherwise 
1656 void wxWindowMSW::DoMoveWindow(int x
, int y
, int width
, int height
) 
1658     // TODO: is this consistent with other platforms? 
1659     // Still, negative width or height shouldn't be allowed 
1665     if ( DoMoveSibling(m_hWnd
, x
, y
, width
, height
) ) 
1667 #if USE_DEFERRED_SIZING 
1668         m_pendingPosition 
= wxPoint(x
, y
); 
1669         m_pendingSize 
= wxSize(width
, height
); 
1670 #endif // USE_DEFERRED_SIZING 
1674 // set the size of the window: if the dimensions are positive, just use them, 
1675 // but if any of them is equal to -1, it means that we must find the value for 
1676 // it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in 
1677 // which case -1 is a valid value for x and y) 
1679 // If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate 
1680 // the width/height to best suit our contents, otherwise we reuse the current 
1682 void wxWindowMSW::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
) 
1684     // get the current size and position... 
1685     int currentX
, currentY
; 
1686     int currentW
, currentH
; 
1688     GetPosition(¤tX
, ¤tY
); 
1689     GetSize(¤tW
, ¤tH
); 
1691     // ... and don't do anything (avoiding flicker) if it's already ok unless 
1692     // we're forced to resize the window 
1693     if ( x 
== currentX 
&& y 
== currentY 
&& 
1694          width 
== currentW 
&& height 
== currentH 
&& 
1695             !(sizeFlags 
& wxSIZE_FORCE
) ) 
1700     if ( x 
== wxDefaultCoord 
&& !(sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
) ) 
1702     if ( y 
== wxDefaultCoord 
&& !(sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
) ) 
1705     AdjustForParentClientOrigin(x
, y
, sizeFlags
); 
1707     wxSize size 
= wxDefaultSize
; 
1708     if ( width 
== wxDefaultCoord 
) 
1710         if ( sizeFlags 
& wxSIZE_AUTO_WIDTH 
) 
1712             size 
= DoGetBestSize(); 
1717             // just take the current one 
1722     if ( height 
== wxDefaultCoord 
) 
1724         if ( sizeFlags 
& wxSIZE_AUTO_HEIGHT 
) 
1726             if ( size
.x 
== wxDefaultCoord 
) 
1728                 size 
= DoGetBestSize(); 
1730             //else: already called DoGetBestSize() above 
1736             // just take the current one 
1741     DoMoveWindow(x
, y
, width
, height
); 
1744 void wxWindowMSW::DoSetClientSize(int width
, int height
) 
1746     // setting the client size is less obvious than it could have been 
1747     // because in the result of changing the total size the window scrollbar 
1748     // may [dis]appear and/or its menubar may [un]wrap (and AdjustWindowRect() 
1749     // doesn't take neither into account) and so the client size will not be 
1750     // correct as the difference between the total and client size changes -- 
1751     // so we keep changing it until we get it right 
1753     // normally this loop shouldn't take more than 3 iterations (usually 1 but 
1754     // if scrollbars [dis]appear as the result of the first call, then 2 and it 
1755     // may become 3 if the window had 0 size originally and so we didn't 
1756     // calculate the scrollbar correction correctly during the first iteration) 
1757     // but just to be on the safe side we check for it instead of making it an 
1758     // "infinite" loop (i.e. leaving break inside as the only way to get out) 
1759     for ( int i 
= 0; i 
< 4; i
++ ) 
1762         ::GetClientRect(GetHwnd(), &rectClient
); 
1764         // if the size is already ok, stop here (NB: rectClient.left = top = 0) 
1765         if ( (rectClient
.right 
== width 
|| width 
== wxDefaultCoord
) && 
1766              (rectClient
.bottom 
== height 
|| height 
== wxDefaultCoord
) ) 
1771         // Find the difference between the entire window (title bar and all) 
1772         // and the client area; add this to the new client size to move the 
1775         ::GetWindowRect(GetHwnd(), &rectWin
); 
1777         const int widthWin 
= rectWin
.right 
- rectWin
.left
, 
1778                   heightWin 
= rectWin
.bottom 
- rectWin
.top
; 
1780         // MoveWindow positions the child windows relative to the parent, so 
1781         // adjust if necessary 
1782         if ( !IsTopLevel() ) 
1784             wxWindow 
*parent 
= GetParent(); 
1787                 ::ScreenToClient(GetHwndOf(parent
), (POINT 
*)&rectWin
); 
1791         // don't call DoMoveWindow() because we want to move window immediately 
1792         // and not defer it here as otherwise the value returned by 
1793         // GetClient/WindowRect() wouldn't change as the window wouldn't be 
1795         if ( !::MoveWindow(GetHwnd(), 
1798                            width 
+ widthWin 
- rectClient
.right
, 
1799                            height 
+ heightWin 
- rectClient
.bottom
, 
1802             wxLogLastError(_T("MoveWindow")); 
1807 // --------------------------------------------------------------------------- 
1809 // --------------------------------------------------------------------------- 
1811 int wxWindowMSW::GetCharHeight() const 
1813     return wxGetTextMetrics(this).tmHeight
; 
1816 int wxWindowMSW::GetCharWidth() const 
1818     // +1 is needed because Windows apparently adds it when calculating the 
1819     // dialog units size in pixels 
1820 #if wxDIALOG_UNIT_COMPATIBILITY 
1821     return wxGetTextMetrics(this).tmAveCharWidth
; 
1823     return wxGetTextMetrics(this).tmAveCharWidth 
+ 1; 
1827 void wxWindowMSW::GetTextExtent(const wxString
& string
, 
1829                              int *descent
, int *externalLeading
, 
1830                              const wxFont 
*theFont
) const 
1832     wxASSERT_MSG( !theFont 
|| theFont
->Ok(), 
1833                     _T("invalid font in GetTextExtent()") ); 
1837         fontToUse 
= *theFont
; 
1839         fontToUse 
= GetFont(); 
1841     WindowHDC 
hdc(GetHwnd()); 
1842     SelectInHDC 
selectFont(hdc
, GetHfontOf(fontToUse
)); 
1846     ::GetTextExtentPoint32(hdc
, string
, string
.length(), &sizeRect
); 
1847     GetTextMetrics(hdc
, &tm
); 
1854         *descent 
= tm
.tmDescent
; 
1855     if ( externalLeading 
) 
1856         *externalLeading 
= tm
.tmExternalLeading
; 
1859 // --------------------------------------------------------------------------- 
1861 // --------------------------------------------------------------------------- 
1863 #if wxUSE_MENUS_NATIVE 
1865 // yield for WM_COMMAND events only, i.e. process all WM_COMMANDs in the queue 
1866 // immediately, without waiting for the next event loop iteration 
1868 // NB: this function should probably be made public later as it can almost 
1869 //     surely replace wxYield() elsewhere as well 
1870 static void wxYieldForCommandsOnly() 
1872     // peek all WM_COMMANDs (it will always return WM_QUIT too but we don't 
1873     // want to process it here) 
1875     while ( ::PeekMessage(&msg
, (HWND
)0, WM_COMMAND
, WM_COMMAND
, PM_REMOVE
) ) 
1877         if ( msg
.message 
== WM_QUIT 
) 
1879             // if we retrieved a WM_QUIT, insert back into the message queue. 
1880             ::PostQuitMessage(0); 
1884         // luckily (as we don't have access to wxEventLoopImpl method from here 
1885         // anyhow...) we don't need to pre process WM_COMMANDs so dispatch it 
1887         ::TranslateMessage(&msg
); 
1888         ::DispatchMessage(&msg
); 
1892 bool wxWindowMSW::DoPopupMenu(wxMenu 
*menu
, int x
, int y
) 
1894     menu
->SetInvokingWindow(this); 
1897     if ( x 
== wxDefaultCoord 
&& y 
== wxDefaultCoord 
) 
1899         wxPoint mouse 
= ScreenToClient(wxGetMousePosition()); 
1900         x 
= mouse
.x
; y 
= mouse
.y
; 
1903     HWND hWnd 
= GetHwnd(); 
1904     HMENU hMenu 
= GetHmenuOf(menu
); 
1908     ::ClientToScreen(hWnd
, &point
); 
1909     wxCurrentPopupMenu 
= menu
; 
1910 #if defined(__WXWINCE__) 
1913     UINT flags 
= TPM_RIGHTBUTTON
; 
1915     ::TrackPopupMenu(hMenu
, flags
, point
.x
, point
.y
, 0, hWnd
, NULL
); 
1917     // we need to do it right now as otherwise the events are never going to be 
1918     // sent to wxCurrentPopupMenu from HandleCommand() 
1920     // note that even eliminating (ugly) wxCurrentPopupMenu global wouldn't 
1921     // help and we'd still need wxYieldForCommandsOnly() as the menu may be 
1922     // destroyed as soon as we return (it can be a local variable in the caller 
1923     // for example) and so we do need to process the event immediately 
1924     wxYieldForCommandsOnly(); 
1926     wxCurrentPopupMenu 
= NULL
; 
1928     menu
->SetInvokingWindow(NULL
); 
1933 #endif // wxUSE_MENUS_NATIVE 
1935 // =========================================================================== 
1936 // pre/post message processing 
1937 // =========================================================================== 
1939 WXLRESULT 
wxWindowMSW::MSWDefWindowProc(WXUINT nMsg
, WXWPARAM wParam
, WXLPARAM lParam
) 
1942         return ::CallWindowProc(CASTWNDPROC m_oldWndProc
, GetHwnd(), (UINT
) nMsg
, (WPARAM
) wParam
, (LPARAM
) lParam
); 
1944         return ::DefWindowProc(GetHwnd(), nMsg
, wParam
, lParam
); 
1947 bool wxWindowMSW::MSWProcessMessage(WXMSG
* pMsg
) 
1949     // wxUniversal implements tab traversal itself 
1950 #ifndef __WXUNIVERSAL__ 
1951     if ( m_hWnd 
!= 0 && (GetWindowStyleFlag() & wxTAB_TRAVERSAL
) ) 
1953         // intercept dialog navigation keys 
1954         MSG 
*msg 
= (MSG 
*)pMsg
; 
1956         // here we try to do all the job which ::IsDialogMessage() usually does 
1958         if ( msg
->message 
== WM_KEYDOWN 
) 
1960             bool bCtrlDown 
= wxIsCtrlDown(); 
1961             bool bShiftDown 
= wxIsShiftDown(); 
1963             // WM_GETDLGCODE: ask the control if it wants the key for itself, 
1964             // don't process it if it's the case (except for Ctrl-Tab/Enter 
1965             // combinations which are always processed) 
1969                 lDlgCode 
= ::SendMessage(msg
->hwnd
, WM_GETDLGCODE
, 0, 0); 
1971                 // surprizingly, DLGC_WANTALLKEYS bit mask doesn't contain the 
1972                 // DLGC_WANTTAB nor DLGC_WANTARROWS bits although, logically, 
1973                 // it, of course, implies them 
1974                 if ( lDlgCode 
& DLGC_WANTALLKEYS 
) 
1976                     lDlgCode 
|= DLGC_WANTTAB 
| DLGC_WANTARROWS
; 
1980             bool bForward 
= true, 
1981                  bWindowChange 
= false, 
1984             // should we process this message specially? 
1985             bool bProcess 
= true; 
1986             switch ( msg
->wParam 
) 
1989                     if ( lDlgCode 
& DLGC_WANTTAB 
) { 
1993                         // Ctrl-Tab cycles thru notebook pages 
1994                         bWindowChange 
= bCtrlDown
; 
1995                         bForward 
= !bShiftDown
; 
2002                     if ( (lDlgCode 
& DLGC_WANTARROWS
) || bCtrlDown 
) 
2010                     if ( (lDlgCode 
& DLGC_WANTARROWS
) || bCtrlDown 
) 
2016                         if ( (lDlgCode 
& DLGC_WANTMESSAGE
) && !bCtrlDown 
) 
2018                             // control wants to process Enter itself, don't 
2019                             // call IsDialogMessage() which would interpret 
2024                         // currently active button should get enter press even 
2025                         // if there is a default button elsewhere 
2026                         if ( lDlgCode 
& DLGC_DEFPUSHBUTTON 
) 
2028                             // let IsDialogMessage() handle this for all 
2029                             // buttons except the owner-drawn ones which it 
2030                             // just seems to ignore 
2031                             long style 
= ::GetWindowLong(msg
->hwnd
, GWL_STYLE
); 
2032                             if ( (style 
& BS_OWNERDRAW
) == BS_OWNERDRAW 
) 
2034                                 // emulate the button click 
2036                                     btn 
= wxFindWinFromHandle((WXHWND
)msg
->hwnd
); 
2038                                     btn
->MSWCommand(BN_CLICKED
, 0 /* unused */); 
2043                         else // not a button itself 
2046                             wxButton 
*btn 
= wxDynamicCast(GetDefaultItem(), 
2048                             if ( btn 
&& btn
->IsEnabled() ) 
2050                                 // if we do have a default button, do press it 
2051                                 btn
->MSWCommand(BN_CLICKED
, 0 /* unused */); 
2055                             else // no default button 
2056 #endif // wxUSE_BUTTON 
2059                                 wxJoystickEvent 
event(wxEVT_JOY_BUTTON_DOWN
); 
2060                                 event
.SetEventObject(this); 
2061                                 if(GetEventHandler()->ProcessEvent(event
)) 
2064                                 // this is a quick and dirty test for a text 
2066                                 if ( !(lDlgCode 
& DLGC_HASSETSEL
) ) 
2068                                     // don't process Enter, the control might 
2069                                     // need it for itself and don't let 
2070                                     // ::IsDialogMessage() have it as it can 
2071                                     // eat the Enter events sometimes 
2074                                 else if (!IsTopLevel()) 
2076                                     // if not a top level window, let parent 
2080                                 //else: treat Enter as TAB: pass to the next 
2081                                 //      control as this is the best thing to do 
2082                                 //      if the text doesn't handle Enter itself 
2094                 wxNavigationKeyEvent event
; 
2095                 event
.SetDirection(bForward
); 
2096                 event
.SetWindowChange(bWindowChange
); 
2097                 event
.SetFromTab(bFromTab
); 
2098                 event
.SetEventObject(this); 
2100                 if ( GetEventHandler()->ProcessEvent(event
) ) 
2102                     // as we don't call IsDialogMessage(), which would take of 
2103                     // this by default, we need to manually send this message 
2104                     // so that controls can change their UI state if needed 
2105                     MSWUpdateUIState(UIS_CLEAR
, UISF_HIDEFOCUS
); 
2112         // don't let IsDialogMessage() get VK_ESCAPE as it _always_ eats the 
2113         // message even when there is no cancel button and when the message is 
2114         // needed by the control itself: in particular, it prevents the tree in 
2115         // place edit control from being closed with Escape in a dialog 
2116         if ( msg
->message 
!= WM_KEYDOWN 
|| msg
->wParam 
!= VK_ESCAPE 
) 
2118             // ::IsDialogMessage() is broken and may sometimes hang the 
2119             // application by going into an infinite loop, so we try to detect 
2120             // [some of] the situations when this may happen and not call it 
2123             // assume we can call it by default 
2124             bool canSafelyCallIsDlgMsg 
= true; 
2126             HWND hwndFocus 
= ::GetFocus(); 
2128             // if the currently focused window itself has WS_EX_CONTROLPARENT style, ::IsDialogMessage() will also enter 
2129             // an infinite loop, because it will recursively check the child 
2130             // windows but not the window itself and so if none of the children 
2131             // accepts focus it loops forever (as it only stops when it gets 
2132             // back to the window it started from) 
2134             // while it is very unusual that a window with WS_EX_CONTROLPARENT 
2135             // style has the focus, it can happen. One such possibility is if 
2136             // all windows are either toplevel, wxDialog, wxPanel or static 
2137             // controls and no window can actually accept keyboard input. 
2138 #if !defined(__WXWINCE__) 
2139             if ( ::GetWindowLong(hwndFocus
, GWL_EXSTYLE
) & WS_EX_CONTROLPARENT 
) 
2141                 // pessimistic by default 
2142                 canSafelyCallIsDlgMsg 
= false; 
2143                 for ( wxWindowList::compatibility_iterator node 
= GetChildren().GetFirst(); 
2145                       node 
= node
->GetNext() ) 
2147                     wxWindow 
* const win 
= node
->GetData(); 
2148                     if ( win
->AcceptsFocus() && 
2149                             !(::GetWindowLong(GetHwndOf(win
), GWL_EXSTYLE
) & 
2150                                 WS_EX_CONTROLPARENT
) ) 
2152                         // it shouldn't hang... 
2153                         canSafelyCallIsDlgMsg 
= true; 
2159 #endif // !__WXWINCE__ 
2161             if ( canSafelyCallIsDlgMsg 
) 
2163                 // ::IsDialogMessage() can enter in an infinite loop when the 
2164                 // currently focused window is disabled or hidden and its 
2165                 // parent has WS_EX_CONTROLPARENT style, so don't call it in 
2169                     if ( !::IsWindowEnabled(hwndFocus
) || 
2170                             !::IsWindowVisible(hwndFocus
) ) 
2172                         // it would enter an infinite loop if we do this! 
2173                         canSafelyCallIsDlgMsg 
= false; 
2178                     if ( !(::GetWindowLong(hwndFocus
, GWL_STYLE
) & WS_CHILD
) ) 
2180                         // it's a top level window, don't go further -- e.g. even 
2181                         // if the parent of a dialog is disabled, this doesn't 
2182                         // break navigation inside the dialog 
2186                     hwndFocus 
= ::GetParent(hwndFocus
); 
2190             // let IsDialogMessage() have the message if it's safe to call it 
2191             if ( canSafelyCallIsDlgMsg 
&& ::IsDialogMessage(GetHwnd(), msg
) ) 
2193                 // IsDialogMessage() did something... 
2198 #endif // __WXUNIVERSAL__ 
2203         // relay mouse move events to the tooltip control 
2204         MSG 
*msg 
= (MSG 
*)pMsg
; 
2205         if ( msg
->message 
== WM_MOUSEMOVE 
) 
2206             m_tooltip
->RelayEvent(pMsg
); 
2208 #endif // wxUSE_TOOLTIPS 
2213 bool wxWindowMSW::MSWTranslateMessage(WXMSG
* pMsg
) 
2215 #if wxUSE_ACCEL && !defined(__WXUNIVERSAL__) 
2216     return m_acceleratorTable
.Translate(this, pMsg
); 
2220 #endif // wxUSE_ACCEL 
2223 bool wxWindowMSW::MSWShouldPreProcessMessage(WXMSG
* WXUNUSED(pMsg
)) 
2225     // preprocess all messages by default 
2229 // --------------------------------------------------------------------------- 
2230 // message params unpackers 
2231 // --------------------------------------------------------------------------- 
2233 void wxWindowMSW::UnpackCommand(WXWPARAM wParam
, WXLPARAM lParam
, 
2234                              WORD 
*id
, WXHWND 
*hwnd
, WORD 
*cmd
) 
2236     *id 
= LOWORD(wParam
); 
2237     *hwnd 
= (WXHWND
)lParam
; 
2238     *cmd 
= HIWORD(wParam
); 
2241 void wxWindowMSW::UnpackActivate(WXWPARAM wParam
, WXLPARAM lParam
, 
2242                               WXWORD 
*state
, WXWORD 
*minimized
, WXHWND 
*hwnd
) 
2244     *state 
= LOWORD(wParam
); 
2245     *minimized 
= HIWORD(wParam
); 
2246     *hwnd 
= (WXHWND
)lParam
; 
2249 void wxWindowMSW::UnpackScroll(WXWPARAM wParam
, WXLPARAM lParam
, 
2250                             WXWORD 
*code
, WXWORD 
*pos
, WXHWND 
*hwnd
) 
2252     *code 
= LOWORD(wParam
); 
2253     *pos 
= HIWORD(wParam
); 
2254     *hwnd 
= (WXHWND
)lParam
; 
2257 void wxWindowMSW::UnpackCtlColor(WXWPARAM wParam
, WXLPARAM lParam
, 
2258                                  WXHDC 
*hdc
, WXHWND 
*hwnd
) 
2260     *hwnd 
= (WXHWND
)lParam
; 
2261     *hdc 
= (WXHDC
)wParam
; 
2264 void wxWindowMSW::UnpackMenuSelect(WXWPARAM wParam
, WXLPARAM lParam
, 
2265                                 WXWORD 
*item
, WXWORD 
*flags
, WXHMENU 
*hmenu
) 
2267     *item 
= (WXWORD
)wParam
; 
2268     *flags 
= HIWORD(wParam
); 
2269     *hmenu 
= (WXHMENU
)lParam
; 
2272 // --------------------------------------------------------------------------- 
2273 // Main wxWidgets window proc and the window proc for wxWindow 
2274 // --------------------------------------------------------------------------- 
2276 // Hook for new window just as it's being created, when the window isn't yet 
2277 // associated with the handle 
2278 static wxWindowMSW 
*gs_winBeingCreated 
= NULL
; 
2280 // implementation of wxWindowCreationHook class: it just sets gs_winBeingCreated to the 
2281 // window being created and insures that it's always unset back later 
2282 wxWindowCreationHook::wxWindowCreationHook(wxWindowMSW 
*winBeingCreated
) 
2284     gs_winBeingCreated 
= winBeingCreated
; 
2287 wxWindowCreationHook::~wxWindowCreationHook() 
2289     gs_winBeingCreated 
= NULL
; 
2293 LRESULT WXDLLEXPORT APIENTRY _EXPORT 
wxWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
) 
2295     // trace all messages - useful for the debugging 
2297     wxLogTrace(wxTraceMessages
, 
2298                wxT("Processing %s(hWnd=%08lx, wParam=%8lx, lParam=%8lx)"), 
2299                wxGetMessageName(message
), (long)hWnd
, (long)wParam
, lParam
); 
2300 #endif // __WXDEBUG__ 
2302     wxWindowMSW 
*wnd 
= wxFindWinFromHandle((WXHWND
) hWnd
); 
2304     // when we get the first message for the HWND we just created, we associate 
2305     // it with wxWindow stored in gs_winBeingCreated 
2306     if ( !wnd 
&& gs_winBeingCreated 
) 
2308         wxAssociateWinWithHandle(hWnd
, gs_winBeingCreated
); 
2309         wnd 
= gs_winBeingCreated
; 
2310         gs_winBeingCreated 
= NULL
; 
2311         wnd
->SetHWND((WXHWND
)hWnd
); 
2316     if ( wnd 
&& wxEventLoop::AllowProcessing(wnd
) ) 
2317         rc 
= wnd
->MSWWindowProc(message
, wParam
, lParam
); 
2319         rc 
= ::DefWindowProc(hWnd
, message
, wParam
, lParam
); 
2324 WXLRESULT 
wxWindowMSW::MSWWindowProc(WXUINT message
, WXWPARAM wParam
, WXLPARAM lParam
) 
2326     // did we process the message? 
2327     bool processed 
= false; 
2337     // for most messages we should return 0 when we do process the message 
2345                 processed 
= HandleCreate((WXLPCREATESTRUCT
)lParam
, &mayCreate
); 
2348                     // return 0 to allow window creation 
2349                     rc
.result 
= mayCreate 
? 0 : -1; 
2355             // never set processed to true and *always* pass WM_DESTROY to 
2356             // DefWindowProc() as Windows may do some internal cleanup when 
2357             // processing it and failing to pass the message along may cause 
2358             // memory and resource leaks! 
2359             (void)HandleDestroy(); 
2363             processed 
= HandleSize(LOWORD(lParam
), HIWORD(lParam
), wParam
); 
2367             processed 
= HandleMove(GET_X_LPARAM(lParam
), GET_Y_LPARAM(lParam
)); 
2370 #if !defined(__WXWINCE__) 
2373                 LPRECT pRect 
= (LPRECT
)lParam
; 
2375                 rc
.SetLeft(pRect
->left
); 
2376                 rc
.SetTop(pRect
->top
); 
2377                 rc
.SetRight(pRect
->right
); 
2378                 rc
.SetBottom(pRect
->bottom
); 
2379                 processed 
= HandleMoving(rc
); 
2381                     pRect
->left 
= rc
.GetLeft(); 
2382                     pRect
->top 
= rc
.GetTop(); 
2383                     pRect
->right 
= rc
.GetRight(); 
2384                     pRect
->bottom 
= rc
.GetBottom(); 
2391                 LPRECT pRect 
= (LPRECT
)lParam
; 
2393                 rc
.SetLeft(pRect
->left
); 
2394                 rc
.SetTop(pRect
->top
); 
2395                 rc
.SetRight(pRect
->right
); 
2396                 rc
.SetBottom(pRect
->bottom
); 
2397                 processed 
= HandleSizing(rc
); 
2399                     pRect
->left 
= rc
.GetLeft(); 
2400                     pRect
->top 
= rc
.GetTop(); 
2401                     pRect
->right 
= rc
.GetRight(); 
2402                     pRect
->bottom 
= rc
.GetBottom(); 
2406 #endif // !__WXWINCE__ 
2408 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__) 
2409         case WM_ACTIVATEAPP
: 
2410             // This implicitly sends a wxEVT_ACTIVATE_APP event 
2411             wxTheApp
->SetActive(wParam 
!= 0, FindFocus()); 
2417                 WXWORD state
, minimized
; 
2419                 UnpackActivate(wParam
, lParam
, &state
, &minimized
, &hwnd
); 
2421                 processed 
= HandleActivate(state
, minimized 
!= 0, (WXHWND
)hwnd
); 
2426             processed 
= HandleSetFocus((WXHWND
)(HWND
)wParam
); 
2430             processed 
= HandleKillFocus((WXHWND
)(HWND
)wParam
); 
2433         case WM_PRINTCLIENT
: 
2434             processed 
= HandlePrintClient((WXHDC
)wParam
); 
2440                 wxPaintDCEx 
dc((wxWindow 
*)this, (WXHDC
)wParam
); 
2442                 processed 
= HandlePaint(); 
2446                 processed 
= HandlePaint(); 
2451 #ifdef __WXUNIVERSAL__ 
2452             // Universal uses its own wxFrame/wxDialog, so we don't receive 
2453             // close events unless we have this. 
2455 #endif // __WXUNIVERSAL__ 
2457             // don't let the DefWindowProc() destroy our window - we'll do it 
2458             // ourselves in ~wxWindow 
2464             processed 
= HandleShow(wParam 
!= 0, (int)lParam
); 
2468             processed 
= HandleMouseMove(GET_X_LPARAM(lParam
), 
2469                                         GET_Y_LPARAM(lParam
), 
2473 #ifdef HAVE_TRACKMOUSEEVENT 
2475             // filter out excess WM_MOUSELEAVE events sent after PopupMenu() (on XP at least) 
2476             if ( m_mouseInWindow 
) 
2478                 GenerateMouseLeave(); 
2481             // always pass processed back as false, this allows the window 
2482             // manager to process the message too.  This is needed to 
2483             // ensure windows XP themes work properly as the mouse moves 
2484             // over widgets like buttons. So don't set processed to true here. 
2486 #endif // HAVE_TRACKMOUSEEVENT 
2488 #if wxUSE_MOUSEWHEEL 
2490             processed 
= HandleMouseWheel(wParam
, lParam
); 
2494         case WM_LBUTTONDOWN
: 
2496         case WM_LBUTTONDBLCLK
: 
2497         case WM_RBUTTONDOWN
: 
2499         case WM_RBUTTONDBLCLK
: 
2500         case WM_MBUTTONDOWN
: 
2502         case WM_MBUTTONDBLCLK
: 
2504 #ifdef __WXMICROWIN__ 
2505                 // MicroWindows seems to ignore the fact that a window is 
2506                 // disabled. So catch mouse events and throw them away if 
2508                 wxWindowMSW
* win 
= this; 
2511                     if (!win
->IsEnabled()) 
2517                     win 
= win
->GetParent(); 
2518                     if ( !win 
|| win
->IsTopLevel() ) 
2525 #endif // __WXMICROWIN__ 
2526                 int x 
= GET_X_LPARAM(lParam
), 
2527                     y 
= GET_Y_LPARAM(lParam
); 
2530                 // redirect the event to a static control if necessary by 
2531                 // finding one under mouse because under CE the static controls 
2532                 // don't generate mouse events (even with SS_NOTIFY) 
2534                 if ( GetCapture() == this ) 
2536                     // but don't do it if the mouse is captured by this window 
2537                     // because then it should really get this event itself 
2542                     win 
= FindWindowForMouseEvent(this, &x
, &y
); 
2544                     // this should never happen 
2545                     wxCHECK_MSG( win
, 0, 
2546                                  _T("FindWindowForMouseEvent() returned NULL") ); 
2548 #else // !__WXWINCE__ 
2549                 wxWindowMSW 
*win 
= this; 
2550 #endif // __WXWINCE__/!__WXWINCE__ 
2552                 processed 
= win
->HandleMouseEvent(message
, x
, y
, wParam
); 
2554                 // if the app didn't eat the event, handle it in the default 
2555                 // way, that is by giving this window the focus 
2558                     // for the standard classes their WndProc sets the focus to 
2559                     // them anyhow and doing it from here results in some weird 
2560                     // problems, so don't do it for them (unnecessary anyhow) 
2561                     if ( !win
->IsOfStandardClass() ) 
2563                         if ( message 
== WM_LBUTTONDOWN 
&& win
->AcceptsFocus() ) 
2575         case MM_JOY1BUTTONDOWN
: 
2576         case MM_JOY2BUTTONDOWN
: 
2577         case MM_JOY1BUTTONUP
: 
2578         case MM_JOY2BUTTONUP
: 
2579             processed 
= HandleJoystickEvent(message
, 
2580                                             GET_X_LPARAM(lParam
), 
2581                                             GET_Y_LPARAM(lParam
), 
2584 #endif // __WXMICROWIN__ 
2590                 UnpackCommand(wParam
, lParam
, &id
, &hwnd
, &cmd
); 
2592                 processed 
= HandleCommand(id
, cmd
, hwnd
); 
2597             processed 
= HandleNotify((int)wParam
, lParam
, &rc
.result
); 
2600         // we only need to reply to WM_NOTIFYFORMAT manually when using MSLU, 
2601         // otherwise DefWindowProc() does it perfectly fine for us, but MSLU 
2602         // apparently doesn't always behave properly and needs some help 
2603 #if wxUSE_UNICODE_MSLU && defined(NF_QUERY) 
2604         case WM_NOTIFYFORMAT
: 
2605             if ( lParam 
== NF_QUERY 
) 
2608                 rc
.result 
= NFR_UNICODE
; 
2611 #endif // wxUSE_UNICODE_MSLU 
2613             // for these messages we must return true if process the message 
2616         case WM_MEASUREITEM
: 
2618                 int idCtrl 
= (UINT
)wParam
; 
2619                 if ( message 
== WM_DRAWITEM 
) 
2621                     processed 
= MSWOnDrawItem(idCtrl
, 
2622                                               (WXDRAWITEMSTRUCT 
*)lParam
); 
2626                     processed 
= MSWOnMeasureItem(idCtrl
, 
2627                                                  (WXMEASUREITEMSTRUCT 
*)lParam
); 
2634 #endif // defined(WM_DRAWITEM) 
2637             if ( !IsOfStandardClass() ) 
2639                 // we always want to get the char events 
2640                 rc
.result 
= DLGC_WANTCHARS
; 
2642                 if ( GetWindowStyleFlag() & wxWANTS_CHARS 
) 
2644                     // in fact, we want everything 
2645                     rc
.result 
|= DLGC_WANTARROWS 
| 
2652             //else: get the dlg code from the DefWindowProc() 
2657             // If this has been processed by an event handler, return 0 now 
2658             // (we've handled it). 
2659             m_lastKeydownProcessed 
= HandleKeyDown((WORD
) wParam
, lParam
); 
2660             if ( m_lastKeydownProcessed 
) 
2669                     // we consider these messages "not interesting" to OnChar, so 
2670                     // just don't do anything more with them 
2680                     // avoid duplicate messages to OnChar for these ASCII keys: 
2681                     // they will be translated by TranslateMessage() and received 
2703                         // but set processed to false, not true to still pass them 
2704                         // to the control's default window proc - otherwise 
2705                         // built-in keyboard handling won't work 
2710                     // special case of VK_APPS: treat it the same as right mouse 
2711                     // click because both usually pop up a context menu 
2713                         processed 
= HandleMouseEvent(WM_RBUTTONDOWN
, -1, -1, 0); 
2718                         // do generate a CHAR event 
2719                         processed 
= HandleChar((WORD
)wParam
, lParam
); 
2722             if (message 
== WM_SYSKEYDOWN
)  // Let Windows still handle the SYSKEYs 
2729             // special case of VK_APPS: treat it the same as right mouse button 
2730             if ( wParam 
== VK_APPS 
) 
2732                 processed 
= HandleMouseEvent(WM_RBUTTONUP
, -1, -1, 0); 
2737                 processed 
= HandleKeyUp((WORD
) wParam
, lParam
); 
2742         case WM_CHAR
: // Always an ASCII character 
2743             if ( m_lastKeydownProcessed 
) 
2745                 // The key was handled in the EVT_KEY_DOWN and handling 
2746                 // a key in an EVT_KEY_DOWN handler is meant, by 
2747                 // design, to prevent EVT_CHARs from happening 
2748                 m_lastKeydownProcessed 
= false; 
2753                 processed 
= HandleChar((WORD
)wParam
, lParam
, true); 
2759             processed 
= HandleHotKey((WORD
)wParam
, lParam
); 
2761 #endif // wxUSE_HOTKEY 
2768                 UnpackScroll(wParam
, lParam
, &code
, &pos
, &hwnd
); 
2770                 processed 
= MSWOnScroll(message 
== WM_HSCROLL 
? wxHORIZONTAL
 
2776         // CTLCOLOR messages are sent by children to query the parent for their 
2778 #ifndef __WXMICROWIN__ 
2779         case WM_CTLCOLORMSGBOX
: 
2780         case WM_CTLCOLOREDIT
: 
2781         case WM_CTLCOLORLISTBOX
: 
2782         case WM_CTLCOLORBTN
: 
2783         case WM_CTLCOLORDLG
: 
2784         case WM_CTLCOLORSCROLLBAR
: 
2785         case WM_CTLCOLORSTATIC
: 
2789                 UnpackCtlColor(wParam
, lParam
, &hdc
, &hwnd
); 
2791                 processed 
= HandleCtlColor(&rc
.hBrush
, (WXHDC
)hdc
, (WXHWND
)hwnd
); 
2794 #endif // !__WXMICROWIN__ 
2796         case WM_SYSCOLORCHANGE
: 
2797             // the return value for this message is ignored 
2798             processed 
= HandleSysColorChange(); 
2801 #if !defined(__WXWINCE__) 
2802         case WM_DISPLAYCHANGE
: 
2803             processed 
= HandleDisplayChange(); 
2807         case WM_PALETTECHANGED
: 
2808             processed 
= HandlePaletteChanged((WXHWND
) (HWND
) wParam
); 
2811         case WM_CAPTURECHANGED
: 
2812             processed 
= HandleCaptureChanged((WXHWND
) (HWND
) lParam
); 
2815         case WM_QUERYNEWPALETTE
: 
2816             processed 
= HandleQueryNewPalette(); 
2820             processed 
= HandleEraseBkgnd((WXHDC
)(HDC
)wParam
); 
2823                 // we processed the message, i.e. erased the background 
2828 #if !defined(__WXWINCE__) 
2830             processed 
= HandleDropFiles(wParam
); 
2835             processed 
= HandleInitDialog((WXHWND
)(HWND
)wParam
); 
2839                 // we never set focus from here 
2844 #if !defined(__WXWINCE__) 
2845         case WM_QUERYENDSESSION
: 
2846             processed 
= HandleQueryEndSession(lParam
, &rc
.allow
); 
2850             processed 
= HandleEndSession(wParam 
!= 0, lParam
); 
2853         case WM_GETMINMAXINFO
: 
2854             processed 
= HandleGetMinMaxInfo((MINMAXINFO
*)lParam
); 
2859             processed 
= HandleSetCursor((WXHWND
)(HWND
)wParam
, 
2860                                         LOWORD(lParam
),     // hit test 
2861                                         HIWORD(lParam
));    // mouse msg 
2865                 // returning TRUE stops the DefWindowProc() from further 
2866                 // processing this message - exactly what we need because we've 
2867                 // just set the cursor. 
2872 #if wxUSE_ACCESSIBILITY 
2875                 //WPARAM dwFlags = (WPARAM) (DWORD) wParam; 
2876                 LPARAM dwObjId 
= (LPARAM
) (DWORD
) lParam
; 
2878                 if (dwObjId 
== (LPARAM
)OBJID_CLIENT 
&& GetOrCreateAccessible()) 
2880                     return LresultFromObject(IID_IAccessible
, wParam
, (IUnknown
*) GetAccessible()->GetIAccessible()); 
2886 #if defined(WM_HELP) 
2889                 // HELPINFO doesn't seem to be supported on WinCE. 
2891                 HELPINFO
* info 
= (HELPINFO
*) lParam
; 
2892                 // Don't yet process menu help events, just windows 
2893                 if (info
->iContextType 
== HELPINFO_WINDOW
) 
2896                     wxWindowMSW
* subjectOfHelp 
= this; 
2897                     bool eventProcessed 
= false; 
2898                     while (subjectOfHelp 
&& !eventProcessed
) 
2900                         wxHelpEvent 
helpEvent(wxEVT_HELP
, 
2901                                               subjectOfHelp
->GetId(), 
2905                                               wxPoint(info
->MousePos
.x
, info
->MousePos
.y
) 
2909                         helpEvent
.SetEventObject(this); 
2911                             GetEventHandler()->ProcessEvent(helpEvent
); 
2913                         // Go up the window hierarchy until the event is 
2915                         subjectOfHelp 
= subjectOfHelp
->GetParent(); 
2918                     processed 
= eventProcessed
; 
2921                 else if (info
->iContextType 
== HELPINFO_MENUITEM
) 
2923                     wxHelpEvent 
helpEvent(wxEVT_HELP
, info
->iCtrlId
); 
2924                     helpEvent
.SetEventObject(this); 
2925                     processed 
= GetEventHandler()->ProcessEvent(helpEvent
); 
2928                 //else: processed is already false 
2934 #if !defined(__WXWINCE__) 
2935         case WM_CONTEXTMENU
: 
2937                 // we don't convert from screen to client coordinates as 
2938                 // the event may be handled by a parent window 
2939                 wxPoint 
pt(GET_X_LPARAM(lParam
), GET_Y_LPARAM(lParam
)); 
2941                 wxContextMenuEvent 
evtCtx(wxEVT_CONTEXT_MENU
, GetId(), pt
); 
2943                 // we could have got an event from our child, reflect it back 
2944                 // to it if this is the case 
2945                 wxWindowMSW 
*win 
= NULL
; 
2946                 if ( (WXHWND
)wParam 
!= m_hWnd 
) 
2948                     win 
= FindItemByHWND((WXHWND
)wParam
); 
2954                 evtCtx
.SetEventObject(win
); 
2955                 processed 
= win
->GetEventHandler()->ProcessEvent(evtCtx
); 
2961             // we're only interested in our own menus, not MF_SYSMENU 
2962             if ( HIWORD(wParam
) == MF_POPUP 
) 
2964                 // handle menu chars for ownerdrawn menu items 
2965                 int i 
= HandleMenuChar(toupper(LOWORD(wParam
)), lParam
); 
2966                 if ( i 
!= wxNOT_FOUND 
) 
2968                     rc
.result 
= MAKELRESULT(i
, MNC_EXECUTE
); 
2978         wxLogTrace(wxTraceMessages
, wxT("Forwarding %s to DefWindowProc."), 
2979                    wxGetMessageName(message
)); 
2980 #endif // __WXDEBUG__ 
2981         rc
.result 
= MSWDefWindowProc(message
, wParam
, lParam
); 
2987 // ---------------------------------------------------------------------------- 
2988 // wxWindow <-> HWND map 
2989 // ---------------------------------------------------------------------------- 
2991 wxWinHashTable 
*wxWinHandleHash 
= NULL
; 
2993 wxWindow 
*wxFindWinFromHandle(WXHWND hWnd
) 
2995     return (wxWindow
*)wxWinHandleHash
->Get((long)hWnd
); 
2998 void wxAssociateWinWithHandle(HWND hWnd
, wxWindowMSW 
*win
) 
3000     // adding NULL hWnd is (first) surely a result of an error and 
3001     // (secondly) breaks menu command processing 
3002     wxCHECK_RET( hWnd 
!= (HWND
)NULL
, 
3003                  wxT("attempt to add a NULL hWnd to window list ignored") ); 
3005     wxWindow 
*oldWin 
= wxFindWinFromHandle((WXHWND
) hWnd
); 
3007     if ( oldWin 
&& (oldWin 
!= win
) ) 
3009         wxLogDebug(wxT("HWND %X already associated with another window (%s)"), 
3010                    (int) hWnd
, win
->GetClassInfo()->GetClassName()); 
3013 #endif // __WXDEBUG__ 
3016         wxWinHandleHash
->Put((long)hWnd
, (wxWindow 
*)win
); 
3020 void wxRemoveHandleAssociation(wxWindowMSW 
*win
) 
3022     wxWinHandleHash
->Delete((long)win
->GetHWND()); 
3025 // ---------------------------------------------------------------------------- 
3026 // various MSW speciic class dependent functions 
3027 // ---------------------------------------------------------------------------- 
3029 // Default destroyer - override if you destroy it in some other way 
3030 // (e.g. with MDI child windows) 
3031 void wxWindowMSW::MSWDestroyWindow() 
3035 bool wxWindowMSW::MSWGetCreateWindowCoords(const wxPoint
& pos
, 
3038                                            int& w
, int& h
) const 
3040     // yes, those are just some arbitrary hardcoded numbers 
3041     static const int DEFAULT_Y 
= 200; 
3043     bool nonDefault 
= false; 
3045     if ( pos
.x 
== wxDefaultCoord 
) 
3047         // if x is set to CW_USEDEFAULT, y parameter is ignored anyhow so we 
3048         // can just as well set it to CW_USEDEFAULT as well 
3054         // OTOH, if x is not set to CW_USEDEFAULT, y shouldn't be set to it 
3055         // neither because it is not handled as a special value by Windows then 
3056         // and so we have to choose some default value for it 
3058         y 
= pos
.y 
== wxDefaultCoord 
? DEFAULT_Y 
: pos
.y
; 
3064       NB: there used to be some code here which set the initial size of the 
3065           window to the client size of the parent if no explicit size was 
3066           specified. This was wrong because wxWidgets programs often assume 
3067           that they get a WM_SIZE (EVT_SIZE) upon creation, however this broke 
3068           it. To see why, you should understand that Windows sends WM_SIZE from 
3069           inside ::CreateWindow() anyhow. However, ::CreateWindow() is called 
3070           from some base class ctor and so this WM_SIZE is not processed in the 
3071           real class' OnSize() (because it's not fully constructed yet and the 
3072           event goes to some base class OnSize() instead). So the WM_SIZE we 
3073           rely on is the one sent when the parent frame resizes its children 
3074           but here is the problem: if the child already has just the right 
3075           size, nothing will happen as both wxWidgets and Windows check for 
3076           this and ignore any attempts to change the window size to the size it 
3077           already has - so no WM_SIZE would be sent. 
3081     // we don't use CW_USEDEFAULT here for several reasons: 
3083     //  1. it results in huge frames on modern screens (1000*800 is not 
3084     //     uncommon on my 1280*1024 screen) which is way too big for a half 
3085     //     empty frame of most of wxWidgets samples for example) 
3087     //  2. it is buggy for frames with wxFRAME_TOOL_WINDOW style for which 
3088     //     the default is for whatever reason 8*8 which breaks client <-> 
3089     //     window size calculations (it would be nice if it didn't, but it 
3090     //     does and the simplest way to fix it seemed to change the broken 
3091     //     default size anyhow) 
3093     //  3. there is just no advantage in doing it: with x and y it is 
3094     //     possible that [future versions of] Windows position the new top 
3095     //     level window in some smart way which we can't do, but we can 
3096     //     guess a reasonably good size for a new window just as well 
3099     // However, on PocketPC devices, we must use the default 
3100     // size if possible. 
3102     if (size
.x 
== wxDefaultCoord
) 
3106     if (size
.y 
== wxDefaultCoord
) 
3111     if ( size
.x 
== wxDefaultCoord 
|| size
.y 
== wxDefaultCoord
) 
3115     w 
= WidthDefault(size
.x
); 
3116     h 
= HeightDefault(size
.y
); 
3119     AdjustForParentClientOrigin(x
, y
); 
3124 WXHWND 
wxWindowMSW::MSWGetParent() const 
3126     return m_parent 
? m_parent
->GetHWND() : WXHWND(NULL
); 
3129 bool wxWindowMSW::MSWCreate(const wxChar 
*wclass
, 
3130                             const wxChar 
*title
, 
3134                             WXDWORD extendedStyle
) 
3136     // choose the position/size for the new window 
3138     (void)MSWGetCreateWindowCoords(pos
, size
, x
, y
, w
, h
); 
3140     // controlId is menu handle for the top level windows, so set it to 0 
3141     // unless we're creating a child window 
3142     int controlId 
= style 
& WS_CHILD 
? GetId() : 0; 
3144     // for each class "Foo" we have we also have "FooNR" ("no repaint") class 
3145     // which is the same but without CS_[HV]REDRAW class styles so using it 
3146     // ensures that the window is not fully repainted on each resize 
3147     wxString 
className(wclass
); 
3148     if ( !HasFlag(wxFULL_REPAINT_ON_RESIZE
) ) 
3150         className 
+= wxT("NR"); 
3153     // do create the window 
3154     wxWindowCreationHook 
hook(this); 
3156     m_hWnd 
= (WXHWND
)::CreateWindowEx
 
3160                         title 
? title 
: m_windowName
.c_str(), 
3163                         (HWND
)MSWGetParent(), 
3166                         NULL                        
// no extra data 
3171         wxLogSysError(_("Can't create window of class %s"), className
.c_str()); 
3176     SubclassWin(m_hWnd
); 
3181 // =========================================================================== 
3182 // MSW message handlers 
3183 // =========================================================================== 
3185 // --------------------------------------------------------------------------- 
3187 // --------------------------------------------------------------------------- 
3189 bool wxWindowMSW::HandleNotify(int idCtrl
, WXLPARAM lParam
, WXLPARAM 
*result
) 
3191 #ifndef __WXMICROWIN__ 
3192     LPNMHDR hdr 
= (LPNMHDR
)lParam
; 
3193     HWND hWnd 
= hdr
->hwndFrom
; 
3194     wxWindow 
*win 
= wxFindWinFromHandle((WXHWND
)hWnd
); 
3196     // if the control is one of our windows, let it handle the message itself 
3199         return win
->MSWOnNotify(idCtrl
, lParam
, result
); 
3202     // VZ: why did we do it? normally this is unnecessary and, besides, it 
3203     //     breaks the message processing for the toolbars because the tooltip 
3204     //     notifications were being forwarded to the toolbar child controls 
3205     //     (if it had any) before being passed to the toolbar itself, so in my 
3206     //     example the tooltip for the combobox was always shown instead of the 
3207     //     correct button tooltips 
3209     // try all our children 
3210     wxWindowList::compatibility_iterator node 
= GetChildren().GetFirst(); 
3213         wxWindow 
*child 
= node
->GetData(); 
3214         if ( child
->MSWOnNotify(idCtrl
, lParam
, result
) ) 
3219         node 
= node
->GetNext(); 
3223     // by default, handle it ourselves 
3224     return MSWOnNotify(idCtrl
, lParam
, result
); 
3225 #else // __WXMICROWIN__ 
3232 bool wxWindowMSW::HandleTooltipNotify(WXUINT code
, 
3234                                       const wxString
& ttip
) 
3236     // I don't know why it happens, but the versions of comctl32.dll starting 
3237     // from 4.70 sometimes send TTN_NEEDTEXTW even to ANSI programs (normally, 
3238     // this message is supposed to be sent to Unicode programs only) -- hence 
3239     // we need to handle it as well, otherwise no tooltips will be shown in 
3242     if ( !(code 
== (WXUINT
) TTN_NEEDTEXTA 
|| code 
== (WXUINT
) TTN_NEEDTEXTW
) 
3245         // not a tooltip message or no tooltip to show anyhow 
3250     LPTOOLTIPTEXT ttText 
= (LPTOOLTIPTEXT
)lParam
; 
3252     // We don't want to use the szText buffer because it has a limit of 80 
3253     // bytes and this is not enough, especially for Unicode build where it 
3254     // limits the tooltip string length to only 40 characters 
3256     // The best would be, of course, to not impose any length limitations at 
3257     // all but then the buffer would have to be dynamic and someone would have 
3258     // to free it and we don't have the tooltip owner object here any more, so 
3259     // for now use our own static buffer with a higher fixed max length. 
3261     // Note that using a static buffer should not be a problem as only a single 
3262     // tooltip can be shown at the same time anyhow. 
3264     if ( code 
== (WXUINT
) TTN_NEEDTEXTW 
) 
3266         // We need to convert tooltip from multi byte to Unicode on the fly. 
3267         static wchar_t buf
[513]; 
3269         // Truncate tooltip length if needed as otherwise we might not have 
3270         // enough space for it in the buffer and MultiByteToWideChar() would 
3272         size_t tipLength 
= wxMin(ttip
.Len(), WXSIZEOF(buf
) - 1); 
3274         // Convert to WideChar without adding the NULL character. The NULL 
3275         // character is added afterwards (this is more efficient). 
3276         int len 
= ::MultiByteToWideChar
 
3288             wxLogLastError(_T("MultiByteToWideChar()")); 
3292         ttText
->lpszText 
= (LPSTR
) buf
; 
3294     else // TTN_NEEDTEXTA 
3295 #endif // !wxUSE_UNICODE 
3297         // we get here if we got TTN_NEEDTEXTA (only happens in ANSI build) or 
3298         // if we got TTN_NEEDTEXTW in Unicode build: in this case we just have 
3299         // to copy the string we have into the buffer 
3300         static wxChar buf
[513]; 
3301         wxStrncpy(buf
, ttip
.c_str(), WXSIZEOF(buf
) - 1); 
3302         buf
[WXSIZEOF(buf
) - 1] = _T('\0'); 
3303         ttText
->lpszText 
= buf
; 
3309 #endif // wxUSE_TOOLTIPS 
3311 bool wxWindowMSW::MSWOnNotify(int WXUNUSED(idCtrl
), 
3313                               WXLPARAM
* WXUNUSED(result
)) 
3318         NMHDR
* hdr 
= (NMHDR 
*)lParam
; 
3319         if ( HandleTooltipNotify(hdr
->code
, lParam
, m_tooltip
->GetTip())) 
3326     wxUnusedVar(lParam
); 
3327 #endif // wxUSE_TOOLTIPS 
3332 // --------------------------------------------------------------------------- 
3333 // end session messages 
3334 // --------------------------------------------------------------------------- 
3336 bool wxWindowMSW::HandleQueryEndSession(long logOff
, bool *mayEnd
) 
3338 #ifdef ENDSESSION_LOGOFF 
3339     wxCloseEvent 
event(wxEVT_QUERY_END_SESSION
, wxID_ANY
); 
3340     event
.SetEventObject(wxTheApp
); 
3341     event
.SetCanVeto(true); 
3342     event
.SetLoggingOff(logOff 
== (long)ENDSESSION_LOGOFF
); 
3344     bool rc 
= wxTheApp
->ProcessEvent(event
); 
3348         // we may end only if the app didn't veto session closing (double 
3350         *mayEnd 
= !event
.GetVeto(); 
3355     wxUnusedVar(logOff
); 
3356     wxUnusedVar(mayEnd
); 
3361 bool wxWindowMSW::HandleEndSession(bool endSession
, long logOff
) 
3363 #ifdef ENDSESSION_LOGOFF 
3364     // do nothing if the session isn't ending 
3369     if ( (this != wxTheApp
->GetTopWindow()) ) 
3372     wxCloseEvent 
event(wxEVT_END_SESSION
, wxID_ANY
); 
3373     event
.SetEventObject(wxTheApp
); 
3374     event
.SetCanVeto(false); 
3375     event
.SetLoggingOff( (logOff 
== (long)ENDSESSION_LOGOFF
) ); 
3377     return wxTheApp
->ProcessEvent(event
); 
3379     wxUnusedVar(endSession
); 
3380     wxUnusedVar(logOff
); 
3385 // --------------------------------------------------------------------------- 
3386 // window creation/destruction 
3387 // --------------------------------------------------------------------------- 
3389 bool wxWindowMSW::HandleCreate(WXLPCREATESTRUCT 
WXUNUSED_IN_WINCE(cs
), 
3392     // VZ: why is this commented out for WinCE? If it doesn't support 
3393     //     WS_EX_CONTROLPARENT at all it should be somehow handled globally, 
3394     //     not with multiple #ifdef's! 
3396     if ( ((CREATESTRUCT 
*)cs
)->dwExStyle 
& WS_EX_CONTROLPARENT 
) 
3397         EnsureParentHasControlParentStyle(GetParent()); 
3398 #endif // !__WXWINCE__ 
3400     // TODO: should generate this event from WM_NCCREATE 
3401     wxWindowCreateEvent 
event((wxWindow 
*)this); 
3402     (void)GetEventHandler()->ProcessEvent(event
); 
3409 bool wxWindowMSW::HandleDestroy() 
3413     // delete our drop target if we've got one 
3414 #if wxUSE_DRAG_AND_DROP 
3415     if ( m_dropTarget 
!= NULL 
) 
3417         m_dropTarget
->Revoke(m_hWnd
); 
3419         delete m_dropTarget
; 
3420         m_dropTarget 
= NULL
; 
3422 #endif // wxUSE_DRAG_AND_DROP 
3424     // WM_DESTROY handled 
3428 // --------------------------------------------------------------------------- 
3430 // --------------------------------------------------------------------------- 
3432 bool wxWindowMSW::HandleActivate(int state
, 
3433                               bool WXUNUSED(minimized
), 
3434                               WXHWND 
WXUNUSED(activate
)) 
3436     wxActivateEvent 
event(wxEVT_ACTIVATE
, 
3437                           (state 
== WA_ACTIVE
) || (state 
== WA_CLICKACTIVE
), 
3439     event
.SetEventObject(this); 
3441     return GetEventHandler()->ProcessEvent(event
); 
3444 bool wxWindowMSW::HandleSetFocus(WXHWND hwnd
) 
3446     // Strangly enough, some controls get set focus events when they are being 
3447     // deleted, even if they already had focus before. 
3448     if ( m_isBeingDeleted 
) 
3453     // notify the parent keeping track of focus for the kbd navigation 
3454     // purposes that we got it 
3455     wxChildFocusEvent 
eventFocus((wxWindow 
*)this); 
3456     (void)GetEventHandler()->ProcessEvent(eventFocus
); 
3462         m_caret
->OnSetFocus(); 
3464 #endif // wxUSE_CARET 
3467     // If it's a wxTextCtrl don't send the event as it will be done 
3468     // after the control gets to process it from EN_FOCUS handler 
3469     if ( wxDynamicCastThis(wxTextCtrl
) ) 
3473 #endif // wxUSE_TEXTCTRL 
3475     wxFocusEvent 
event(wxEVT_SET_FOCUS
, m_windowId
); 
3476     event
.SetEventObject(this); 
3478     // wxFindWinFromHandle() may return NULL, it is ok 
3479     event
.SetWindow(wxFindWinFromHandle(hwnd
)); 
3481     return GetEventHandler()->ProcessEvent(event
); 
3484 bool wxWindowMSW::HandleKillFocus(WXHWND hwnd
) 
3490         m_caret
->OnKillFocus(); 
3492 #endif // wxUSE_CARET 
3495     // If it's a wxTextCtrl don't send the event as it will be done 
3496     // after the control gets to process it. 
3497     wxTextCtrl 
*ctrl 
= wxDynamicCastThis(wxTextCtrl
); 
3504     // Don't send the event when in the process of being deleted.  This can 
3505     // only cause problems if the event handler tries to access the object. 
3506     if ( m_isBeingDeleted 
) 
3511     wxFocusEvent 
event(wxEVT_KILL_FOCUS
, m_windowId
); 
3512     event
.SetEventObject(this); 
3514     // wxFindWinFromHandle() may return NULL, it is ok 
3515     event
.SetWindow(wxFindWinFromHandle(hwnd
)); 
3517     return GetEventHandler()->ProcessEvent(event
); 
3520 // --------------------------------------------------------------------------- 
3522 // --------------------------------------------------------------------------- 
3524 void wxWindowMSW::SetLabel( const wxString
& label
) 
3526     SetWindowText(GetHwnd(), label
.c_str()); 
3529 wxString 
wxWindowMSW::GetLabel() const 
3531     return wxGetWindowText(GetHWND()); 
3534 // --------------------------------------------------------------------------- 
3536 // --------------------------------------------------------------------------- 
3538 bool wxWindowMSW::HandleShow(bool show
, int WXUNUSED(status
)) 
3540     wxShowEvent 
event(GetId(), show
); 
3541     event
.SetEventObject(this); 
3543     return GetEventHandler()->ProcessEvent(event
); 
3546 bool wxWindowMSW::HandleInitDialog(WXHWND 
WXUNUSED(hWndFocus
)) 
3548     wxInitDialogEvent 
event(GetId()); 
3549     event
.SetEventObject(this); 
3551     return GetEventHandler()->ProcessEvent(event
); 
3554 bool wxWindowMSW::HandleDropFiles(WXWPARAM wParam
) 
3556 #if defined (__WXMICROWIN__) || defined(__WXWINCE__) 
3557     wxUnusedVar(wParam
); 
3559 #else // __WXMICROWIN__ 
3560     HDROP hFilesInfo 
= (HDROP
) wParam
; 
3562     // Get the total number of files dropped 
3563     UINT gwFilesDropped 
= ::DragQueryFile
 
3571     wxString 
*files 
= new wxString
[gwFilesDropped
]; 
3572     for ( UINT wIndex 
= 0; wIndex 
< gwFilesDropped
; wIndex
++ ) 
3574         // first get the needed buffer length (+1 for terminating NUL) 
3575         size_t len 
= ::DragQueryFile(hFilesInfo
, wIndex
, NULL
, 0) + 1; 
3577         // and now get the file name 
3578         ::DragQueryFile(hFilesInfo
, wIndex
, 
3579                         wxStringBuffer(files
[wIndex
], len
), len
); 
3581     DragFinish (hFilesInfo
); 
3583     wxDropFilesEvent 
event(wxEVT_DROP_FILES
, gwFilesDropped
, files
); 
3584     event
.SetEventObject(this); 
3587     DragQueryPoint(hFilesInfo
, (LPPOINT
) &dropPoint
); 
3588     event
.m_pos
.x 
= dropPoint
.x
; 
3589     event
.m_pos
.y 
= dropPoint
.y
; 
3591     return GetEventHandler()->ProcessEvent(event
); 
3596 bool wxWindowMSW::HandleSetCursor(WXHWND 
WXUNUSED(hWnd
), 
3598                                   int WXUNUSED(mouseMsg
)) 
3600 #ifndef __WXMICROWIN__ 
3601     // the logic is as follows: 
3602     // -1. don't set cursor for non client area, including but not limited to 
3603     //     the title bar, scrollbars, &c 
3604     //  0. allow the user to override default behaviour by using EVT_SET_CURSOR 
3605     //  1. if we have the cursor set it unless wxIsBusy() 
3606     //  2. if we're a top level window, set some cursor anyhow 
3607     //  3. if wxIsBusy(), set the busy cursor, otherwise the global one 
3609     if ( nHitTest 
!= HTCLIENT 
) 
3614     HCURSOR hcursor 
= 0; 
3616     // first ask the user code - it may wish to set the cursor in some very 
3617     // specific way (for example, depending on the current position) 
3620     if ( !::GetCursorPosWinCE(&pt
)) 
3622     if ( !::GetCursorPos(&pt
) ) 
3625         wxLogLastError(wxT("GetCursorPos")); 
3630     ScreenToClient(&x
, &y
); 
3631     wxSetCursorEvent 
event(x
, y
); 
3633     bool processedEvtSetCursor 
= GetEventHandler()->ProcessEvent(event
); 
3634     if ( processedEvtSetCursor 
&& event
.HasCursor() ) 
3636         hcursor 
= GetHcursorOf(event
.GetCursor()); 
3641         bool isBusy 
= wxIsBusy(); 
3643         // the test for processedEvtSetCursor is here to prevent using m_cursor 
3644         // if the user code caught EVT_SET_CURSOR() and returned nothing from 
3645         // it - this is a way to say that our cursor shouldn't be used for this 
3647         if ( !processedEvtSetCursor 
&& m_cursor
.Ok() ) 
3649             hcursor 
= GetHcursorOf(m_cursor
); 
3656                 hcursor 
= wxGetCurrentBusyCursor(); 
3658             else if ( !hcursor 
) 
3660                 const wxCursor 
*cursor 
= wxGetGlobalCursor(); 
3661                 if ( cursor 
&& cursor
->Ok() ) 
3663                     hcursor 
= GetHcursorOf(*cursor
); 
3671 //        wxLogDebug("HandleSetCursor: Setting cursor %ld", (long) hcursor); 
3673         ::SetCursor(hcursor
); 
3675         // cursor set, stop here 
3678 #endif // __WXMICROWIN__ 
3680     // pass up the window chain 
3684 // --------------------------------------------------------------------------- 
3685 // owner drawn stuff 
3686 // --------------------------------------------------------------------------- 
3688 #if (wxUSE_OWNER_DRAWN && wxUSE_MENUS_NATIVE) || \ 
3689         (wxUSE_CONTROLS && !defined(__WXUNIVERSAL__)) 
3690     #define WXUNUSED_UNLESS_ODRAWN(param) param 
3692     #define WXUNUSED_UNLESS_ODRAWN(param) 
3696 wxWindowMSW::MSWOnDrawItem(int WXUNUSED_UNLESS_ODRAWN(id
), 
3697                            WXDRAWITEMSTRUCT 
* WXUNUSED_UNLESS_ODRAWN(itemStruct
)) 
3699 #if wxUSE_OWNER_DRAWN 
3701 #if wxUSE_MENUS_NATIVE 
3702     // is it a menu item? 
3703     DRAWITEMSTRUCT 
*pDrawStruct 
= (DRAWITEMSTRUCT 
*)itemStruct
; 
3704     if ( id 
== 0 && pDrawStruct
->CtlType 
== ODT_MENU 
) 
3706         wxMenuItem 
*pMenuItem 
= (wxMenuItem 
*)(pDrawStruct
->itemData
); 
3708         // see comment before the same test in MSWOnMeasureItem() below 
3712         wxCHECK_MSG( wxDynamicCast(pMenuItem
, wxMenuItem
), 
3713                          false, _T("MSWOnDrawItem: bad wxMenuItem pointer") ); 
3715         // prepare to call OnDrawItem(): notice using of wxDCTemp to prevent 
3716         // the DC from being released 
3717         wxDCTemp 
dc((WXHDC
)pDrawStruct
->hDC
); 
3718         wxRect 
rect(pDrawStruct
->rcItem
.left
, pDrawStruct
->rcItem
.top
, 
3719                     pDrawStruct
->rcItem
.right 
- pDrawStruct
->rcItem
.left
, 
3720                     pDrawStruct
->rcItem
.bottom 
- pDrawStruct
->rcItem
.top
); 
3722         return pMenuItem
->OnDrawItem
 
3726                 (wxOwnerDrawn::wxODAction
)pDrawStruct
->itemAction
, 
3727                 (wxOwnerDrawn::wxODStatus
)pDrawStruct
->itemState
 
3730 #endif // wxUSE_MENUS_NATIVE 
3732 #endif // USE_OWNER_DRAWN 
3734 #if wxUSE_CONTROLS && !defined(__WXUNIVERSAL__) 
3736 #if wxUSE_OWNER_DRAWN 
3737     wxControl 
*item 
= wxDynamicCast(FindItem(id
), wxControl
); 
3738 #else // !wxUSE_OWNER_DRAWN 
3739     // we may still have owner-drawn buttons internally because we have to make 
3740     // them owner-drawn to support colour change 
3743                          wxDynamicCast(FindItem(id
), wxButton
) 
3748 #endif // USE_OWNER_DRAWN 
3752         return item
->MSWOnDraw(itemStruct
); 
3755 #endif // wxUSE_CONTROLS 
3761 wxWindowMSW::MSWOnMeasureItem(int id
, WXMEASUREITEMSTRUCT 
*itemStruct
) 
3763 #if wxUSE_OWNER_DRAWN && wxUSE_MENUS_NATIVE 
3764     // is it a menu item? 
3765     MEASUREITEMSTRUCT 
*pMeasureStruct 
= (MEASUREITEMSTRUCT 
*)itemStruct
; 
3766     if ( id 
== 0 && pMeasureStruct
->CtlType 
== ODT_MENU 
) 
3768         wxMenuItem 
*pMenuItem 
= (wxMenuItem 
*)(pMeasureStruct
->itemData
); 
3770         // according to Carsten Fuchs the pointer may be NULL under XP if an 
3771         // MDI child frame is initially maximized, see this for more info: 
3772         // http://article.gmane.org/gmane.comp.lib.wxwidgets.general/27745 
3774         // so silently ignore it instead of asserting 
3778         wxCHECK_MSG( wxDynamicCast(pMenuItem
, wxMenuItem
), 
3779                         false, _T("MSWOnMeasureItem: bad wxMenuItem pointer") ); 
3782         bool rc 
= pMenuItem
->OnMeasureItem(&w
, &h
); 
3784         pMeasureStruct
->itemWidth 
= w
; 
3785         pMeasureStruct
->itemHeight 
= h
; 
3790     wxControl 
*item 
= wxDynamicCast(FindItem(id
), wxControl
); 
3793         return item
->MSWOnMeasure(itemStruct
); 
3797     wxUnusedVar(itemStruct
); 
3798 #endif // wxUSE_OWNER_DRAWN && wxUSE_MENUS_NATIVE 
3803 // --------------------------------------------------------------------------- 
3804 // colours and palettes 
3805 // --------------------------------------------------------------------------- 
3807 bool wxWindowMSW::HandleSysColorChange() 
3809     wxSysColourChangedEvent event
; 
3810     event
.SetEventObject(this); 
3812     (void)GetEventHandler()->ProcessEvent(event
); 
3814     // always let the system carry on the default processing to allow the 
3815     // native controls to react to the colours update 
3819 bool wxWindowMSW::HandleDisplayChange() 
3821     wxDisplayChangedEvent event
; 
3822     event
.SetEventObject(this); 
3824     return GetEventHandler()->ProcessEvent(event
); 
3827 #ifndef __WXMICROWIN__ 
3829 bool wxWindowMSW::HandleCtlColor(WXHBRUSH 
*brush
, WXHDC hDC
, WXHWND hWnd
) 
3831 #if !wxUSE_CONTROLS || defined(__WXUNIVERSAL__) 
3835     wxControl 
*item 
= wxDynamicCast(FindItemByHWND(hWnd
, true), wxControl
); 
3838         *brush 
= item
->MSWControlColor(hDC
, hWnd
); 
3840 #endif // wxUSE_CONTROLS 
3843     return *brush 
!= NULL
; 
3846 #endif // __WXMICROWIN__ 
3848 bool wxWindowMSW::HandlePaletteChanged(WXHWND hWndPalChange
) 
3851     // same as below except we don't respond to our own messages 
3852     if ( hWndPalChange 
!= GetHWND() ) 
3854         // check to see if we our our parents have a custom palette 
3855         wxWindowMSW 
*win 
= this; 
3856         while ( win 
&& !win
->HasCustomPalette() ) 
3858             win 
= win
->GetParent(); 
3861         if ( win 
&& win
->HasCustomPalette() ) 
3863             // realize the palette to see whether redrawing is needed 
3864             HDC hdc 
= ::GetDC((HWND
) hWndPalChange
); 
3865             win
->m_palette
.SetHPALETTE((WXHPALETTE
) 
3866                     ::SelectPalette(hdc
, GetHpaletteOf(win
->m_palette
), FALSE
)); 
3868             int result 
= ::RealizePalette(hdc
); 
3870             // restore the palette (before releasing the DC) 
3871             win
->m_palette
.SetHPALETTE((WXHPALETTE
) 
3872                     ::SelectPalette(hdc
, GetHpaletteOf(win
->m_palette
), FALSE
)); 
3873             ::RealizePalette(hdc
); 
3874             ::ReleaseDC((HWND
) hWndPalChange
, hdc
); 
3876             // now check for the need to redraw 
3878                 ::InvalidateRect((HWND
) hWndPalChange
, NULL
, TRUE
); 
3882 #endif // wxUSE_PALETTE 
3884     wxPaletteChangedEvent 
event(GetId()); 
3885     event
.SetEventObject(this); 
3886     event
.SetChangedWindow(wxFindWinFromHandle(hWndPalChange
)); 
3888     return GetEventHandler()->ProcessEvent(event
); 
3891 bool wxWindowMSW::HandleCaptureChanged(WXHWND hWndGainedCapture
) 
3893     wxMouseCaptureChangedEvent 
event(GetId(), wxFindWinFromHandle(hWndGainedCapture
)); 
3894     event
.SetEventObject(this); 
3896     return GetEventHandler()->ProcessEvent(event
); 
3899 bool wxWindowMSW::HandleQueryNewPalette() 
3903     // check to see if we our our parents have a custom palette 
3904     wxWindowMSW 
*win 
= this; 
3905     while (!win
->HasCustomPalette() && win
->GetParent()) win 
= win
->GetParent(); 
3906     if (win
->HasCustomPalette()) { 
3907         /* realize the palette to see whether redrawing is needed */ 
3908         HDC hdc 
= ::GetDC((HWND
) GetHWND()); 
3909         win
->m_palette
.SetHPALETTE( (WXHPALETTE
) 
3910              ::SelectPalette(hdc
, (HPALETTE
) win
->m_palette
.GetHPALETTE(), FALSE
) ); 
3912         int result 
= ::RealizePalette(hdc
); 
3913         /* restore the palette (before releasing the DC) */ 
3914         win
->m_palette
.SetHPALETTE( (WXHPALETTE
) 
3915              ::SelectPalette(hdc
, (HPALETTE
) win
->m_palette
.GetHPALETTE(), TRUE
) ); 
3916         ::RealizePalette(hdc
); 
3917         ::ReleaseDC((HWND
) GetHWND(), hdc
); 
3918         /* now check for the need to redraw */ 
3920             ::InvalidateRect((HWND
) GetHWND(), NULL
, TRUE
); 
3922 #endif // wxUSE_PALETTE 
3924     wxQueryNewPaletteEvent 
event(GetId()); 
3925     event
.SetEventObject(this); 
3927     return GetEventHandler()->ProcessEvent(event
) && event
.GetPaletteRealized(); 
3930 // Responds to colour changes: passes event on to children. 
3931 void wxWindowMSW::OnSysColourChanged(wxSysColourChangedEvent
& WXUNUSED(event
)) 
3933     // the top level window also reset the standard colour map as it might have 
3934     // changed (there is no need to do it for the non top level windows as we 
3935     // only have to do it once) 
3939         gs_hasStdCmap 
= false; 
3941     wxWindowList::compatibility_iterator node 
= GetChildren().GetFirst(); 
3944         // Only propagate to non-top-level windows because Windows already 
3945         // sends this event to all top-level ones 
3946         wxWindow 
*win 
= node
->GetData(); 
3947         if ( !win
->IsTopLevel() ) 
3949             // we need to send the real WM_SYSCOLORCHANGE and not just trigger 
3950             // EVT_SYS_COLOUR_CHANGED call because the latter wouldn't work for 
3951             // the standard controls 
3952             ::SendMessage(GetHwndOf(win
), WM_SYSCOLORCHANGE
, 0, 0); 
3955         node 
= node
->GetNext(); 
3959 extern wxCOLORMAP 
*wxGetStdColourMap() 
3961     static COLORREF s_stdColours
[wxSTD_COL_MAX
]; 
3962     static wxCOLORMAP s_cmap
[wxSTD_COL_MAX
]; 
3964     if ( !gs_hasStdCmap 
) 
3966         static bool s_coloursInit 
= false; 
3968         if ( !s_coloursInit 
) 
3970             // When a bitmap is loaded, the RGB values can change (apparently 
3971             // because Windows adjusts them to care for the old programs always 
3972             // using 0xc0c0c0 while the transparent colour for the new Windows 
3973             // versions is different). But we do this adjustment ourselves so 
3974             // we want to avoid Windows' "help" and for this we need to have a 
3975             // reference bitmap which can tell us what the RGB values change 
3977             wxLogNull logNo
; // suppress error if we couldn't load the bitmap 
3978             wxBitmap 
stdColourBitmap(_T("wxBITMAP_STD_COLOURS")); 
3979             if ( stdColourBitmap
.Ok() ) 
3981                 // the pixels in the bitmap must correspond to wxSTD_COL_XXX! 
3982                 wxASSERT_MSG( stdColourBitmap
.GetWidth() == wxSTD_COL_MAX
, 
3983                               _T("forgot to update wxBITMAP_STD_COLOURS!") ); 
3986                 memDC
.SelectObject(stdColourBitmap
); 
3989                 for ( size_t i 
= 0; i 
< WXSIZEOF(s_stdColours
); i
++ ) 
3991                     memDC
.GetPixel(i
, 0, &colour
); 
3992                     s_stdColours
[i
] = wxColourToRGB(colour
); 
3995             else // wxBITMAP_STD_COLOURS couldn't be loaded 
3997                 s_stdColours
[0] = RGB(000,000,000);     // black 
3998                 s_stdColours
[1] = RGB(128,128,128);     // dark grey 
3999                 s_stdColours
[2] = RGB(192,192,192);     // light grey 
4000                 s_stdColours
[3] = RGB(255,255,255);     // white 
4001                 //s_stdColours[4] = RGB(000,000,255);     // blue 
4002                 //s_stdColours[5] = RGB(255,000,255);     // magenta 
4005             s_coloursInit 
= true; 
4008         gs_hasStdCmap 
= true; 
4010         // create the colour map 
4011 #define INIT_CMAP_ENTRY(col) \ 
4012             s_cmap[wxSTD_COL_##col].from = s_stdColours[wxSTD_COL_##col]; \ 
4013             s_cmap[wxSTD_COL_##col].to = ::GetSysColor(COLOR_##col) 
4015         INIT_CMAP_ENTRY(BTNTEXT
); 
4016         INIT_CMAP_ENTRY(BTNSHADOW
); 
4017         INIT_CMAP_ENTRY(BTNFACE
); 
4018         INIT_CMAP_ENTRY(BTNHIGHLIGHT
); 
4020 #undef INIT_CMAP_ENTRY 
4026 // --------------------------------------------------------------------------- 
4028 // --------------------------------------------------------------------------- 
4030 bool wxWindowMSW::HandlePaint() 
4032     HRGN hRegion 
= ::CreateRectRgn(0, 0, 0, 0); // Dummy call to get a handle 
4034         wxLogLastError(wxT("CreateRectRgn")); 
4035     if ( ::GetUpdateRgn(GetHwnd(), hRegion
, FALSE
) == ERROR 
) 
4036         wxLogLastError(wxT("GetUpdateRgn")); 
4038     m_updateRegion 
= wxRegion((WXHRGN
) hRegion
); 
4040     wxPaintEvent 
event(m_windowId
); 
4041     event
.SetEventObject(this); 
4043     bool processed 
= GetEventHandler()->ProcessEvent(event
); 
4045     // note that we must generate NC event after the normal one as otherwise 
4046     // BeginPaint() will happily overwrite our decorations with the background 
4048     wxNcPaintEvent 
eventNc(m_windowId
); 
4049     eventNc
.SetEventObject(this); 
4050     GetEventHandler()->ProcessEvent(eventNc
); 
4055 // Can be called from an application's OnPaint handler 
4056 void wxWindowMSW::OnPaint(wxPaintEvent
& event
) 
4058 #ifdef __WXUNIVERSAL__ 
4061     HDC hDC 
= (HDC
) wxPaintDC::FindDCInCache((wxWindow
*) event
.GetEventObject()); 
4064         MSWDefWindowProc(WM_PAINT
, (WPARAM
) hDC
, 0); 
4069 bool wxWindowMSW::HandleEraseBkgnd(WXHDC hdc
) 
4074     dc
.SetWindow((wxWindow 
*)this); 
4077     wxEraseEvent 
event(m_windowId
, &dc
); 
4078     event
.SetEventObject(this); 
4079     bool rc 
= GetEventHandler()->ProcessEvent(event
); 
4083     // must be called manually as ~wxDC doesn't do anything for wxDCTemp 
4084     dc
.SelectOldObjects(hdc
); 
4089 void wxWindowMSW::OnEraseBackground(wxEraseEvent
& event
) 
4091     // standard non top level controls (i.e. except the dialogs) always erase 
4092     // their background themselves in HandleCtlColor() or have some control- 
4093     // specific ways to set the colours (common controls) 
4094     if ( IsOfStandardClass() && !IsTopLevel() ) 
4100     if ( GetBackgroundStyle() == wxBG_STYLE_CUSTOM 
) 
4102         // don't skip the event here, custom background means that the app 
4103         // is drawing it itself in its OnPaint(), so don't draw it at all 
4104         // now to avoid flicker 
4109     // do default background painting 
4110     if ( !DoEraseBackground(GetHdcOf(*event
.GetDC())) ) 
4112         // let the system paint the background 
4117 bool wxWindowMSW::DoEraseBackground(WXHDC hDC
) 
4119     HBRUSH hbr 
= (HBRUSH
)MSWGetBgBrush(hDC
); 
4123     wxFillRect(GetHwnd(), (HDC
)hDC
, hbr
); 
4129 wxWindowMSW::MSWGetBgBrushForChild(WXHDC 
WXUNUSED(hDC
), WXHWND hWnd
) 
4133         // our background colour applies to: 
4134         //  1. this window itself, always 
4135         //  2. all children unless the colour is "not inheritable" 
4136         //  3. even if it is not inheritable, our immediate transparent 
4137         //     children should still inherit it -- but not any transparent 
4138         //     children because it would look wrong if a child of non 
4139         //     transparent child would show our bg colour when the child itself 
4141         wxWindow 
*win 
= wxFindWinFromHandle(hWnd
); 
4144                     (win 
&& win
->HasTransparentBackground() && 
4145                         win
->GetParent() == this) ) 
4147             // draw children with the same colour as the parent 
4149                 brush 
= wxTheBrushList
->FindOrCreateBrush(GetBackgroundColour()); 
4151             return (WXHBRUSH
)GetHbrushOf(*brush
); 
4158 WXHBRUSH 
wxWindowMSW::MSWGetBgBrush(WXHDC hDC
, WXHWND hWndToPaint
) 
4161         hWndToPaint 
= GetHWND(); 
4163     for ( wxWindowMSW 
*win 
= this; win
; win 
= win
->GetParent() ) 
4165         WXHBRUSH hBrush 
= win
->MSWGetBgBrushForChild(hDC
, hWndToPaint
); 
4169         // background is not inherited beyond top level windows 
4170         if ( win
->IsTopLevel() ) 
4177 bool wxWindowMSW::HandlePrintClient(WXHDC hDC
) 
4179     // we receive this message when DrawThemeParentBackground() is 
4180     // called from def window proc of several controls under XP and we 
4181     // must draw properly themed background here 
4183     // note that naively I'd expect filling the client rect with the 
4184     // brush returned by MSWGetBgBrush() work -- but for some reason it 
4185     // doesn't and we have to call parents MSWPrintChild() which is 
4186     // supposed to call DrawThemeBackground() with appropriate params 
4188     // also note that in this case lParam == PRF_CLIENT but we're 
4189     // clearly expected to paint the background and nothing else! 
4191     if ( IsTopLevel() || InheritsBackgroundColour() ) 
4194     // sometimes we don't want the parent to handle it at all, instead 
4195     // return whatever value this window wants 
4196     if ( !MSWShouldPropagatePrintChild() ) 
4197         return MSWPrintChild(hDC
, (wxWindow 
*)this); 
4199     for ( wxWindow 
*win 
= GetParent(); win
; win 
= win
->GetParent() ) 
4201         if ( win
->MSWPrintChild(hDC
, (wxWindow 
*)this) ) 
4204         if ( win
->IsTopLevel() || win
->InheritsBackgroundColour() ) 
4211 // --------------------------------------------------------------------------- 
4212 // moving and resizing 
4213 // --------------------------------------------------------------------------- 
4215 bool wxWindowMSW::HandleMinimize() 
4217     wxIconizeEvent 
event(m_windowId
); 
4218     event
.SetEventObject(this); 
4220     return GetEventHandler()->ProcessEvent(event
); 
4223 bool wxWindowMSW::HandleMaximize() 
4225     wxMaximizeEvent 
event(m_windowId
); 
4226     event
.SetEventObject(this); 
4228     return GetEventHandler()->ProcessEvent(event
); 
4231 bool wxWindowMSW::HandleMove(int x
, int y
) 
4234     wxMoveEvent 
event(point
, m_windowId
); 
4235     event
.SetEventObject(this); 
4237     return GetEventHandler()->ProcessEvent(event
); 
4240 bool wxWindowMSW::HandleMoving(wxRect
& rect
) 
4242     wxMoveEvent 
event(rect
, m_windowId
); 
4243     event
.SetEventObject(this); 
4245     bool rc 
= GetEventHandler()->ProcessEvent(event
); 
4247         rect 
= event
.GetRect(); 
4251 bool wxWindowMSW::HandleSize(int WXUNUSED(w
), int WXUNUSED(h
), WXUINT wParam
) 
4253 #if USE_DEFERRED_SIZING 
4254     // when we resize this window, its children are probably going to be 
4255     // repositioned as well, prepare to use DeferWindowPos() for them 
4256     int numChildren 
= 0; 
4257     for ( HWND child 
= ::GetWindow(GetHwndOf(this), GW_CHILD
); 
4259           child 
= ::GetWindow(child
, GW_HWNDNEXT
) ) 
4264     // Protect against valid m_hDWP being overwritten 
4265     bool useDefer 
= false; 
4267     if ( numChildren 
> 1 ) 
4271             m_hDWP 
= (WXHANDLE
)::BeginDeferWindowPos(numChildren
); 
4274                 wxLogLastError(_T("BeginDeferWindowPos")); 
4280 #endif // USE_DEFERRED_SIZING 
4282     // update this window size 
4283     bool processed 
= false; 
4287             wxFAIL_MSG( _T("unexpected WM_SIZE parameter") ); 
4288             // fall through nevertheless 
4292             // we're not interested in these messages at all 
4295         case SIZE_MINIMIZED
: 
4296             processed 
= HandleMinimize(); 
4299         case SIZE_MAXIMIZED
: 
4300             /* processed = */ HandleMaximize(); 
4301             // fall through to send a normal size event as well 
4304             // don't use w and h parameters as they specify the client size 
4305             // while according to the docs EVT_SIZE handler is supposed to 
4306             // receive the total size 
4307             wxSizeEvent 
event(GetSize(), m_windowId
); 
4308             event
.SetEventObject(this); 
4310             processed 
= GetEventHandler()->ProcessEvent(event
); 
4313 #if USE_DEFERRED_SIZING 
4314     // and finally change the positions of all child windows at once 
4315     if ( useDefer 
&& m_hDWP 
) 
4317         // reset m_hDWP to NULL so that child windows don't try to use our 
4318         // m_hDWP after we call EndDeferWindowPos() on it (this shouldn't 
4319         // happen anyhow normally but who knows what weird flow of control we 
4320         // may have depending on what the users EVT_SIZE handler does...) 
4321         HDWP hDWP 
= (HDWP
)m_hDWP
; 
4324         // do put all child controls in place at once 
4325         if ( !::EndDeferWindowPos(hDWP
) ) 
4327             wxLogLastError(_T("EndDeferWindowPos")); 
4330         // Reset our children's pending pos/size values. 
4331         for ( wxWindowList::compatibility_iterator node 
= GetChildren().GetFirst(); 
4333               node 
= node
->GetNext() ) 
4335             wxWindowMSW 
*child 
= node
->GetData(); 
4336             child
->m_pendingPosition 
= wxDefaultPosition
; 
4337             child
->m_pendingSize 
= wxDefaultSize
; 
4340 #endif // USE_DEFERRED_SIZING 
4345 bool wxWindowMSW::HandleSizing(wxRect
& rect
) 
4347     wxSizeEvent 
event(rect
, m_windowId
); 
4348     event
.SetEventObject(this); 
4350     bool rc 
= GetEventHandler()->ProcessEvent(event
); 
4352         rect 
= event
.GetRect(); 
4356 bool wxWindowMSW::HandleGetMinMaxInfo(void *WXUNUSED_IN_WINCE(mmInfo
)) 
4361     MINMAXINFO 
*info 
= (MINMAXINFO 
*)mmInfo
; 
4365     int minWidth 
= GetMinWidth(), 
4366         minHeight 
= GetMinHeight(), 
4367         maxWidth 
= GetMaxWidth(), 
4368         maxHeight 
= GetMaxHeight(); 
4370     if ( minWidth 
!= wxDefaultCoord 
) 
4372         info
->ptMinTrackSize
.x 
= minWidth
; 
4376     if ( minHeight 
!= wxDefaultCoord 
) 
4378         info
->ptMinTrackSize
.y 
= minHeight
; 
4382     if ( maxWidth 
!= wxDefaultCoord 
) 
4384         info
->ptMaxTrackSize
.x 
= maxWidth
; 
4388     if ( maxHeight 
!= wxDefaultCoord 
) 
4390         info
->ptMaxTrackSize
.y 
= maxHeight
; 
4398 // --------------------------------------------------------------------------- 
4400 // --------------------------------------------------------------------------- 
4402 bool wxWindowMSW::HandleCommand(WXWORD id
, WXWORD cmd
, WXHWND control
) 
4404 #if wxUSE_MENUS_NATIVE 
4405     if ( !cmd 
&& wxCurrentPopupMenu 
) 
4407         wxMenu 
*popupMenu 
= wxCurrentPopupMenu
; 
4408         wxCurrentPopupMenu 
= NULL
; 
4410         return popupMenu
->MSWCommand(cmd
, id
); 
4412 #endif // wxUSE_MENUS_NATIVE 
4414     wxWindow 
*win 
= NULL
; 
4416     // first try to find it from HWND - this works even with the broken 
4417     // programs using the same ids for different controls 
4420         win 
= wxFindWinFromHandle(control
); 
4426         // must cast to a signed type before comparing with other ids! 
4427         win 
= FindItem((signed short)id
); 
4432         return win
->MSWCommand(cmd
, id
); 
4435     // the messages sent from the in-place edit control used by the treectrl 
4436     // for label editing have id == 0, but they should _not_ be treated as menu 
4437     // messages (they are EN_XXX ones, in fact) so don't translate anything 
4438     // coming from a control to wxEVT_COMMAND_MENU_SELECTED 
4441         // If no child window, it may be an accelerator, e.g. for a popup menu 
4444         wxCommandEvent 
event(wxEVT_COMMAND_MENU_SELECTED
); 
4445         event
.SetEventObject(this); 
4449         return GetEventHandler()->ProcessEvent(event
); 
4453 #if wxUSE_SPINCTRL && !defined(__WXUNIVERSAL__) 
4454         // the text ctrl which is logically part of wxSpinCtrl sends WM_COMMAND 
4455         // notifications to its parent which we want to reflect back to 
4457         wxSpinCtrl 
*spin 
= wxSpinCtrl::GetSpinForTextCtrl(control
); 
4458         if ( spin 
&& spin
->ProcessTextCommand(cmd
, id
) ) 
4460 #endif // wxUSE_SPINCTRL 
4462 #if wxUSE_CHOICE && defined(__SMARTPHONE__) 
4463         // the listbox ctrl which is logically part of wxChoice sends WM_COMMAND 
4464         // notifications to its parent which we want to reflect back to 
4466         wxChoice 
*choice 
= wxChoice::GetChoiceForListBox(control
); 
4467         if ( choice 
&& choice
->MSWCommand(cmd
, id
) ) 
4475 // --------------------------------------------------------------------------- 
4477 // --------------------------------------------------------------------------- 
4479 void wxWindowMSW::InitMouseEvent(wxMouseEvent
& event
, 
4483     // our client coords are not quite the same as Windows ones 
4484     wxPoint pt 
= GetClientAreaOrigin(); 
4485     event
.m_x 
= x 
- pt
.x
; 
4486     event
.m_y 
= y 
- pt
.y
; 
4488     event
.m_shiftDown 
= (flags 
& MK_SHIFT
) != 0; 
4489     event
.m_controlDown 
= (flags 
& MK_CONTROL
) != 0; 
4490     event
.m_leftDown 
= (flags 
& MK_LBUTTON
) != 0; 
4491     event
.m_middleDown 
= (flags 
& MK_MBUTTON
) != 0; 
4492     event
.m_rightDown 
= (flags 
& MK_RBUTTON
) != 0; 
4493     event
.m_altDown 
= ::GetKeyState(VK_MENU
) < 0; 
4496     event
.SetTimestamp(::GetMessageTime()); 
4499     event
.SetEventObject(this); 
4500     event
.SetId(GetId()); 
4502 #if wxUSE_MOUSEEVENT_HACK 
4503     gs_lastMouseEvent
.pos 
= ClientToScreen(wxPoint(x
, y
)); 
4504     gs_lastMouseEvent
.type 
= event
.GetEventType(); 
4505 #endif // wxUSE_MOUSEEVENT_HACK 
4509 // Windows doesn't send the mouse events to the static controls (which are 
4510 // transparent in the sense that their WM_NCHITTEST handler returns 
4511 // HTTRANSPARENT) at all but we want all controls to receive the mouse events 
4512 // and so we manually check if we don't have a child window under mouse and if 
4513 // we do, send the event to it instead of the window Windows had sent WM_XXX 
4516 // Notice that this is not done for the mouse move events because this could 
4517 // (would?) be too slow, but only for clicks which means that the static texts 
4518 // still don't get move, enter nor leave events. 
4519 static wxWindowMSW 
*FindWindowForMouseEvent(wxWindowMSW 
*win
, int *x
, int *y
) 
4521     wxCHECK_MSG( x 
&& y
, win
, _T("NULL pointer in FindWindowForMouseEvent") ); 
4523     // first try to find a non transparent child: this allows us to send events 
4524     // to a static text which is inside a static box, for example 
4525     POINT pt 
= { *x
, *y 
}; 
4526     HWND hwnd 
= GetHwndOf(win
), 
4530     hwndUnderMouse 
= ::ChildWindowFromPoint
 
4536     hwndUnderMouse 
= ::ChildWindowFromPointEx
 
4546     if ( !hwndUnderMouse 
|| hwndUnderMouse 
== hwnd 
) 
4548         // now try any child window at all 
4549         hwndUnderMouse 
= ::ChildWindowFromPoint(hwnd
, pt
); 
4552     // check that we have a child window which is susceptible to receive mouse 
4553     // events: for this it must be shown and enabled 
4554     if ( hwndUnderMouse 
&& 
4555             hwndUnderMouse 
!= hwnd 
&& 
4556                 ::IsWindowVisible(hwndUnderMouse
) && 
4557                     ::IsWindowEnabled(hwndUnderMouse
) ) 
4559         wxWindow 
*winUnderMouse 
= wxFindWinFromHandle((WXHWND
)hwndUnderMouse
); 
4560         if ( winUnderMouse 
) 
4562             // translate the mouse coords to the other window coords 
4563             win
->ClientToScreen(x
, y
); 
4564             winUnderMouse
->ScreenToClient(x
, y
); 
4566             win 
= winUnderMouse
; 
4572 #endif // __WXWINCE__ 
4574 bool wxWindowMSW::HandleMouseEvent(WXUINT msg
, int x
, int y
, WXUINT flags
) 
4576     // the mouse events take consecutive IDs from WM_MOUSEFIRST to 
4577     // WM_MOUSELAST, so it's enough to subtract WM_MOUSEMOVE == WM_MOUSEFIRST 
4578     // from the message id and take the value in the table to get wxWin event 
4580     static const wxEventType eventsMouse
[] = 
4594     wxMouseEvent 
event(eventsMouse
[msg 
- WM_MOUSEMOVE
]); 
4595     InitMouseEvent(event
, x
, y
, flags
); 
4597     return GetEventHandler()->ProcessEvent(event
); 
4600 bool wxWindowMSW::HandleMouseMove(int x
, int y
, WXUINT flags
) 
4602     if ( !m_mouseInWindow 
) 
4604         // it would be wrong to assume that just because we get a mouse move 
4605         // event that the mouse is inside the window: although this is usually 
4606         // true, it is not if we had captured the mouse, so we need to check 
4607         // the mouse coordinates here 
4608         if ( !HasCapture() || IsMouseInWindow() ) 
4610             // Generate an ENTER event 
4611             m_mouseInWindow 
= true; 
4613 #ifdef HAVE_TRACKMOUSEEVENT 
4614             WinStruct
<TRACKMOUSEEVENT
> trackinfo
; 
4616             trackinfo
.dwFlags 
= TME_LEAVE
; 
4617             trackinfo
.hwndTrack 
= GetHwnd(); 
4619             // Use the commctrl.h _TrackMouseEvent(), which will call the real 
4620             // TrackMouseEvent() if available or emulate it 
4621             _TrackMouseEvent(&trackinfo
); 
4622 #endif // HAVE_TRACKMOUSEEVENT 
4624             wxMouseEvent 
event(wxEVT_ENTER_WINDOW
); 
4625             InitMouseEvent(event
, x
, y
, flags
); 
4627             (void)GetEventHandler()->ProcessEvent(event
); 
4630 #ifdef HAVE_TRACKMOUSEEVENT 
4633         // Check if we need to send a LEAVE event 
4634         // Windows doesn't send WM_MOUSELEAVE if the mouse has been captured so 
4635         // send it here if we are using native mouse leave tracking 
4636         if ( HasCapture() && !IsMouseInWindow() ) 
4638             GenerateMouseLeave(); 
4641 #endif // HAVE_TRACKMOUSEEVENT 
4643 #if wxUSE_MOUSEEVENT_HACK 
4644     // Windows often generates mouse events even if mouse position hasn't 
4645     // changed (http://article.gmane.org/gmane.comp.lib.wxwidgets.devel/66576) 
4647     // Filter this out as it can result in unexpected behaviour compared to 
4649     if ( gs_lastMouseEvent
.type 
== wxEVT_RIGHT_DOWN 
|| 
4650          gs_lastMouseEvent
.type 
== wxEVT_LEFT_DOWN 
|| 
4651          gs_lastMouseEvent
.type 
== wxEVT_MIDDLE_DOWN 
|| 
4652          gs_lastMouseEvent
.type 
== wxEVT_MOTION 
) 
4654         if ( ClientToScreen(wxPoint(x
, y
)) == gs_lastMouseEvent
.pos 
) 
4656             gs_lastMouseEvent
.type 
= wxEVT_MOTION
; 
4661 #endif // wxUSE_MOUSEEVENT_HACK 
4663     return HandleMouseEvent(WM_MOUSEMOVE
, x
, y
, flags
); 
4667 bool wxWindowMSW::HandleMouseWheel(WXWPARAM wParam
, WXLPARAM lParam
) 
4669 #if wxUSE_MOUSEWHEEL 
4670     // notice that WM_MOUSEWHEEL position is in screen coords (as it's 
4671     // forwarded up to the parent by DefWindowProc()) and not in the client 
4672     // ones as all the other messages, translate them to the client coords for 
4675         pt 
= ScreenToClient(wxPoint(GET_X_LPARAM(lParam
), GET_Y_LPARAM(lParam
))); 
4676     wxMouseEvent 
event(wxEVT_MOUSEWHEEL
); 
4677     InitMouseEvent(event
, pt
.x
, pt
.y
, LOWORD(wParam
)); 
4678     event
.m_wheelRotation 
= (short)HIWORD(wParam
); 
4679     event
.m_wheelDelta 
= WHEEL_DELTA
; 
4681     static int s_linesPerRotation 
= -1; 
4682     if ( s_linesPerRotation 
== -1 ) 
4684         if ( !::SystemParametersInfo(SPI_GETWHEELSCROLLLINES
, 0, 
4685                                      &s_linesPerRotation
, 0)) 
4687             // this is not supposed to happen 
4688             wxLogLastError(_T("SystemParametersInfo(GETWHEELSCROLLLINES)")); 
4690             // the default is 3, so use it if SystemParametersInfo() failed 
4691             s_linesPerRotation 
= 3; 
4695     event
.m_linesPerAction 
= s_linesPerRotation
; 
4696     return GetEventHandler()->ProcessEvent(event
); 
4698 #else // !wxUSE_MOUSEWHEEL 
4699     wxUnusedVar(wParam
); 
4700     wxUnusedVar(lParam
); 
4703 #endif // wxUSE_MOUSEWHEEL/!wxUSE_MOUSEWHEEL 
4706 void wxWindowMSW::GenerateMouseLeave() 
4708     m_mouseInWindow 
= false; 
4711     if ( wxIsShiftDown() ) 
4713     if ( wxIsCtrlDown() ) 
4714         state 
|= MK_CONTROL
; 
4716     // Only the high-order bit should be tested 
4717     if ( GetKeyState( VK_LBUTTON 
) & (1<<15) ) 
4718         state 
|= MK_LBUTTON
; 
4719     if ( GetKeyState( VK_MBUTTON 
) & (1<<15) ) 
4720         state 
|= MK_MBUTTON
; 
4721     if ( GetKeyState( VK_RBUTTON 
) & (1<<15) ) 
4722         state 
|= MK_RBUTTON
; 
4726     if ( !::GetCursorPosWinCE(&pt
) ) 
4728     if ( !::GetCursorPos(&pt
) ) 
4731         wxLogLastError(_T("GetCursorPos")); 
4734     // we need to have client coordinates here for symmetry with 
4735     // wxEVT_ENTER_WINDOW 
4736     RECT rect 
= wxGetWindowRect(GetHwnd()); 
4740     wxMouseEvent 
event(wxEVT_LEAVE_WINDOW
); 
4741     InitMouseEvent(event
, pt
.x
, pt
.y
, state
); 
4743     (void)GetEventHandler()->ProcessEvent(event
); 
4746 // --------------------------------------------------------------------------- 
4747 // keyboard handling 
4748 // --------------------------------------------------------------------------- 
4750 // create the key event of the given type for the given key - used by 
4751 // HandleChar and HandleKeyDown/Up 
4752 wxKeyEvent 
wxWindowMSW::CreateKeyEvent(wxEventType evType
, 
4755                                        WXWPARAM wParam
) const 
4757     wxKeyEvent 
event(evType
); 
4758     event
.SetId(GetId()); 
4759     event
.m_shiftDown 
= wxIsShiftDown(); 
4760     event
.m_controlDown 
= wxIsCtrlDown(); 
4761     event
.m_altDown 
= (HIWORD(lParam
) & KF_ALTDOWN
) == KF_ALTDOWN
; 
4763     event
.SetEventObject((wxWindow 
*)this); // const_cast 
4764     event
.m_keyCode 
= id
; 
4766     event
.m_uniChar 
= (wxChar
) wParam
; 
4768     event
.m_rawCode 
= (wxUint32
) wParam
; 
4769     event
.m_rawFlags 
= (wxUint32
) lParam
; 
4771     event
.SetTimestamp(::GetMessageTime()); 
4774     // translate the position to client coords 
4777     GetCursorPosWinCE(&pt
); 
4782     GetWindowRect(GetHwnd(),&rect
); 
4792 // isASCII is true only when we're called from WM_CHAR handler and not from 
4794 bool wxWindowMSW::HandleChar(WXWPARAM wParam
, WXLPARAM lParam
, bool isASCII
) 
4799         // If 1 -> 26, translate to either special keycode or just set 
4800         // ctrlDown.  IOW, Ctrl-C should result in keycode == 3 and 
4801         // ControlDown() == true. 
4803         if ( (id 
> 0) && (id 
< 27) ) 
4825     else // we're called from WM_KEYDOWN 
4827         id 
= wxCharCodeMSWToWX(wParam
, lParam
); 
4830             // it's ASCII and will be processed here only when called from 
4831             // WM_CHAR (i.e. when isASCII = true), don't process it now 
4836     wxKeyEvent 
event(CreateKeyEvent(wxEVT_CHAR
, id
, lParam
, wParam
)); 
4838     // the alphanumeric keys produced by pressing AltGr+something on European 
4839     // keyboards have both Ctrl and Alt modifiers which may confuse the user 
4840     // code as, normally, keys with Ctrl and/or Alt don't result in anything 
4841     // alphanumeric, so pretend that there are no modifiers at all (the 
4842     // KEY_DOWN event would still have the correct modifiers if they're really 
4844     if ( event
.m_controlDown 
&& event
.m_altDown 
&& 
4845             (id 
>= 32 && id 
< 256) ) 
4847         event
.m_controlDown 
= 
4848         event
.m_altDown 
= false; 
4851     return GetEventHandler()->ProcessEvent(event
); 
4854 bool wxWindowMSW::HandleKeyDown(WXWPARAM wParam
, WXLPARAM lParam
) 
4856     int id 
= wxCharCodeMSWToWX(wParam
, lParam
); 
4860         // normal ASCII char 
4864     if ( id 
!= -1 ) // VZ: does this ever happen (FIXME)? 
4866         wxKeyEvent 
event(CreateKeyEvent(wxEVT_KEY_DOWN
, id
, lParam
, wParam
)); 
4867         if ( GetEventHandler()->ProcessEvent(event
) ) 
4876 bool wxWindowMSW::HandleKeyUp(WXWPARAM wParam
, WXLPARAM lParam
) 
4878     int id 
= wxCharCodeMSWToWX(wParam
, lParam
); 
4882         // normal ASCII char 
4886     if ( id 
!= -1 ) // VZ: does this ever happen (FIXME)? 
4888         wxKeyEvent 
event(CreateKeyEvent(wxEVT_KEY_UP
, id
, lParam
, wParam
)); 
4889         if ( GetEventHandler()->ProcessEvent(event
) ) 
4896 int wxWindowMSW::HandleMenuChar(int WXUNUSED_IN_WINCE(chAccel
), 
4897                                 WXLPARAM 
WXUNUSED_IN_WINCE(lParam
)) 
4899     // FIXME: implement GetMenuItemCount for WinCE, possibly 
4900     // in terms of GetMenuItemInfo 
4902     const HMENU hmenu 
= (HMENU
)lParam
; 
4906     mii
.cbSize 
= sizeof(MENUITEMINFO
); 
4908     // we could use MIIM_FTYPE here as we only need to know if the item is 
4909     // ownerdrawn or not and not dwTypeData which MIIM_TYPE also returns, but 
4910     // MIIM_FTYPE is not supported under Win95 
4911     mii
.fMask 
= MIIM_TYPE 
| MIIM_DATA
; 
4913     // find if we have this letter in any owner drawn item 
4914     const int count 
= ::GetMenuItemCount(hmenu
); 
4915     for ( int i 
= 0; i 
< count
; i
++ ) 
4917         // previous loop iteration could modify it, reset it back before 
4918         // calling GetMenuItemInfo() to prevent it from overflowing dwTypeData 
4921         if ( ::GetMenuItemInfo(hmenu
, i
, TRUE
, &mii
) ) 
4923             if ( mii
.fType 
== MFT_OWNERDRAW 
) 
4925                 //  dwItemData member of the MENUITEMINFO is a 
4926                 //  pointer to the associated wxMenuItem -- see the 
4927                 //  menu creation code 
4928                 wxMenuItem 
*item 
= (wxMenuItem
*)mii
.dwItemData
; 
4930                 const wxChar 
*p 
= wxStrchr(item
->GetText(), _T('&')); 
4933                     if ( *p 
== _T('&') ) 
4935                         // this is not the accel char, find the real one 
4936                         p 
= wxStrchr(p 
+ 1, _T('&')); 
4938                     else // got the accel char 
4940                         // FIXME-UNICODE: this comparison doesn't risk to work 
4941                         // for non ASCII accelerator characters I'm afraid, but 
4943                         if ( (wchar_t)wxToupper(*p
) == (wchar_t)chAccel 
) 
4949                             // this one doesn't match 
4956         else // failed to get the menu text? 
4958             // it's not fatal, so don't show error, but still log it 
4959             wxLogLastError(_T("GetMenuItemInfo")); 
4966 // --------------------------------------------------------------------------- 
4968 // --------------------------------------------------------------------------- 
4970 bool wxWindowMSW::HandleJoystickEvent(WXUINT msg
, int x
, int y
, WXUINT flags
) 
4974     if ( flags 
& JOY_BUTTON1CHG 
) 
4975         change 
= wxJOY_BUTTON1
; 
4976     if ( flags 
& JOY_BUTTON2CHG 
) 
4977         change 
= wxJOY_BUTTON2
; 
4978     if ( flags 
& JOY_BUTTON3CHG 
) 
4979         change 
= wxJOY_BUTTON3
; 
4980     if ( flags 
& JOY_BUTTON4CHG 
) 
4981         change 
= wxJOY_BUTTON4
; 
4984     if ( flags 
& JOY_BUTTON1 
) 
4985         buttons 
|= wxJOY_BUTTON1
; 
4986     if ( flags 
& JOY_BUTTON2 
) 
4987         buttons 
|= wxJOY_BUTTON2
; 
4988     if ( flags 
& JOY_BUTTON3 
) 
4989         buttons 
|= wxJOY_BUTTON3
; 
4990     if ( flags 
& JOY_BUTTON4 
) 
4991         buttons 
|= wxJOY_BUTTON4
; 
4993     // the event ids aren't consecutive so we can't use table based lookup 
4995     wxEventType eventType
; 
5000             eventType 
= wxEVT_JOY_MOVE
; 
5005             eventType 
= wxEVT_JOY_MOVE
; 
5010             eventType 
= wxEVT_JOY_ZMOVE
; 
5015             eventType 
= wxEVT_JOY_ZMOVE
; 
5018         case MM_JOY1BUTTONDOWN
: 
5020             eventType 
= wxEVT_JOY_BUTTON_DOWN
; 
5023         case MM_JOY2BUTTONDOWN
: 
5025             eventType 
= wxEVT_JOY_BUTTON_DOWN
; 
5028         case MM_JOY1BUTTONUP
: 
5030             eventType 
= wxEVT_JOY_BUTTON_UP
; 
5033         case MM_JOY2BUTTONUP
: 
5035             eventType 
= wxEVT_JOY_BUTTON_UP
; 
5039             wxFAIL_MSG(wxT("no such joystick event")); 
5044     wxJoystickEvent 
event(eventType
, buttons
, joystick
, change
); 
5045     event
.SetPosition(wxPoint(x
, y
)); 
5046     event
.SetEventObject(this); 
5048     return GetEventHandler()->ProcessEvent(event
); 
5058 // --------------------------------------------------------------------------- 
5060 // --------------------------------------------------------------------------- 
5062 bool wxWindowMSW::MSWOnScroll(int orientation
, WXWORD wParam
, 
5063                               WXWORD pos
, WXHWND control
) 
5065     if ( control 
&& control 
!= m_hWnd 
) // Prevent infinite recursion 
5067         wxWindow 
*child 
= wxFindWinFromHandle(control
); 
5069             return child
->MSWOnScroll(orientation
, wParam
, pos
, control
); 
5072     wxScrollWinEvent event
; 
5073     event
.SetPosition(pos
); 
5074     event
.SetOrientation(orientation
); 
5075     event
.SetEventObject(this); 
5080         event
.SetEventType(wxEVT_SCROLLWIN_TOP
); 
5084         event
.SetEventType(wxEVT_SCROLLWIN_BOTTOM
); 
5088         event
.SetEventType(wxEVT_SCROLLWIN_LINEUP
); 
5092         event
.SetEventType(wxEVT_SCROLLWIN_LINEDOWN
); 
5096         event
.SetEventType(wxEVT_SCROLLWIN_PAGEUP
); 
5100         event
.SetEventType(wxEVT_SCROLLWIN_PAGEDOWN
); 
5103     case SB_THUMBPOSITION
: 
5105         // under Win32, the scrollbar range and position are 32 bit integers, 
5106         // but WM_[HV]SCROLL only carry the low 16 bits of them, so we must 
5107         // explicitly query the scrollbar for the correct position (this must 
5108         // be done only for these two SB_ events as they are the only one 
5109         // carrying the scrollbar position) 
5111             WinStruct
<SCROLLINFO
> scrollInfo
; 
5112             scrollInfo
.fMask 
= SIF_TRACKPOS
; 
5114             if ( !::GetScrollInfo(GetHwnd(), 
5115                                   orientation 
== wxHORIZONTAL 
? SB_HORZ
 
5119                 // Not necessarily an error, if there are no scrollbars yet. 
5120                 // wxLogLastError(_T("GetScrollInfo")); 
5123             event
.SetPosition(scrollInfo
.nTrackPos
); 
5126         event
.SetEventType( wParam 
== SB_THUMBPOSITION
 
5127                                 ? wxEVT_SCROLLWIN_THUMBRELEASE
 
5128                                 : wxEVT_SCROLLWIN_THUMBTRACK 
); 
5135     return GetEventHandler()->ProcessEvent(event
); 
5138 // =========================================================================== 
5140 // =========================================================================== 
5142 void wxGetCharSize(WXHWND wnd
, int *x
, int *y
, const wxFont
& the_font
) 
5145     HDC dc 
= ::GetDC((HWND
) wnd
); 
5148     //    the_font.UseResource(); 
5149     //    the_font.RealizeResource(); 
5150     HFONT fnt 
= (HFONT
)the_font
.GetResourceHandle(); // const_cast 
5152         was 
= (HFONT
) SelectObject(dc
,fnt
); 
5154     GetTextMetrics(dc
, &tm
); 
5157         SelectObject(dc
,was
); 
5159     ReleaseDC((HWND
)wnd
, dc
); 
5162         *x 
= tm
.tmAveCharWidth
; 
5164         *y 
= tm
.tmHeight 
+ tm
.tmExternalLeading
; 
5166     //   the_font.ReleaseResource(); 
5169 // use the "extended" bit (24) of lParam to distinguish extended keys 
5170 // from normal keys as the same key is sent 
5171 static inline int ChooseNormalOrExtended(int lParam
, int keyNormal
, int keyExtended
) 
5173     return lParam 
& (1 << 24) ? keyExtended 
: keyNormal
; 
5176 // Returns 0 if was a normal ASCII value, not a special key. This indicates that 
5177 // the key should be ignored by WM_KEYDOWN and processed by WM_CHAR instead. 
5178 int wxCharCodeMSWToWX(int keySym
, WXLPARAM lParam
) 
5183         case VK_CANCEL
:     id 
= WXK_CANCEL
; break; 
5184         case VK_BACK
:       id 
= WXK_BACK
; break; 
5185         case VK_TAB
:        id 
= WXK_TAB
; break; 
5186         case VK_CLEAR
:      id 
= WXK_CLEAR
; break; 
5187         case VK_SHIFT
:      id 
= WXK_SHIFT
; break; 
5188         case VK_CONTROL
:    id 
= WXK_CONTROL
; break; 
5189         case VK_MENU 
:      id 
= WXK_ALT
; break; 
5190         case VK_PAUSE
:      id 
= WXK_PAUSE
; break; 
5191         case VK_CAPITAL
:    id 
= WXK_CAPITAL
; break; 
5192         case VK_SPACE
:      id 
= WXK_SPACE
; break; 
5193         case VK_ESCAPE
:     id 
= WXK_ESCAPE
; break; 
5194         case VK_SELECT
:     id 
= WXK_SELECT
; break; 
5195         case VK_PRINT
:      id 
= WXK_PRINT
; break; 
5196         case VK_EXECUTE
:    id 
= WXK_EXECUTE
; break; 
5197         case VK_HELP 
:      id 
= WXK_HELP
; break; 
5198         case VK_NUMPAD0
:    id 
= WXK_NUMPAD0
; break; 
5199         case VK_NUMPAD1
:    id 
= WXK_NUMPAD1
; break; 
5200         case VK_NUMPAD2
:    id 
= WXK_NUMPAD2
; break; 
5201         case VK_NUMPAD3
:    id 
= WXK_NUMPAD3
; break; 
5202         case VK_NUMPAD4
:    id 
= WXK_NUMPAD4
; break; 
5203         case VK_NUMPAD5
:    id 
= WXK_NUMPAD5
; break; 
5204         case VK_NUMPAD6
:    id 
= WXK_NUMPAD6
; break; 
5205         case VK_NUMPAD7
:    id 
= WXK_NUMPAD7
; break; 
5206         case VK_NUMPAD8
:    id 
= WXK_NUMPAD8
; break; 
5207         case VK_NUMPAD9
:    id 
= WXK_NUMPAD9
; break; 
5208         case VK_MULTIPLY
:   id 
= WXK_NUMPAD_MULTIPLY
; break; 
5209         case VK_ADD
:        id 
= WXK_NUMPAD_ADD
; break; 
5210         case VK_SUBTRACT
:   id 
= WXK_NUMPAD_SUBTRACT
; break; 
5211         case VK_DECIMAL
:    id 
= WXK_NUMPAD_DECIMAL
; break; 
5212         case VK_DIVIDE
:     id 
= WXK_NUMPAD_DIVIDE
; break; 
5213         case VK_F1
:         id 
= WXK_F1
; break; 
5214         case VK_F2
:         id 
= WXK_F2
; break; 
5215         case VK_F3
:         id 
= WXK_F3
; break; 
5216         case VK_F4
:         id 
= WXK_F4
; break; 
5217         case VK_F5
:         id 
= WXK_F5
; break; 
5218         case VK_F6
:         id 
= WXK_F6
; break; 
5219         case VK_F7
:         id 
= WXK_F7
; break; 
5220         case VK_F8
:         id 
= WXK_F8
; break; 
5221         case VK_F9
:         id 
= WXK_F9
; break; 
5222         case VK_F10
:        id 
= WXK_F10
; break; 
5223         case VK_F11
:        id 
= WXK_F11
; break; 
5224         case VK_F12
:        id 
= WXK_F12
; break; 
5225         case VK_F13
:        id 
= WXK_F13
; break; 
5226         case VK_F14
:        id 
= WXK_F14
; break; 
5227         case VK_F15
:        id 
= WXK_F15
; break; 
5228         case VK_F16
:        id 
= WXK_F16
; break; 
5229         case VK_F17
:        id 
= WXK_F17
; break; 
5230         case VK_F18
:        id 
= WXK_F18
; break; 
5231         case VK_F19
:        id 
= WXK_F19
; break; 
5232         case VK_F20
:        id 
= WXK_F20
; break; 
5233         case VK_F21
:        id 
= WXK_F21
; break; 
5234         case VK_F22
:        id 
= WXK_F22
; break; 
5235         case VK_F23
:        id 
= WXK_F23
; break; 
5236         case VK_F24
:        id 
= WXK_F24
; break; 
5237         case VK_NUMLOCK
:    id 
= WXK_NUMLOCK
; break; 
5238         case VK_SCROLL
:     id 
= WXK_SCROLL
; break; 
5240         // the mapping for these keys may be incorrect on non-US keyboards so 
5241         // maybe we shouldn't map them to ASCII values at all 
5242         case VK_OEM_1
:      id 
= ';'; break; 
5243         case VK_OEM_PLUS
:   id 
= '+'; break; 
5244         case VK_OEM_COMMA
:  id 
= ','; break; 
5245         case VK_OEM_MINUS
:  id 
= '-'; break; 
5246         case VK_OEM_PERIOD
: id 
= '.'; break; 
5247         case VK_OEM_2
:      id 
= '/'; break; 
5248         case VK_OEM_3
:      id 
= '~'; break; 
5249         case VK_OEM_4
:      id 
= '['; break; 
5250         case VK_OEM_5
:      id 
= '\\'; break; 
5251         case VK_OEM_6
:      id 
= ']'; break; 
5252         case VK_OEM_7
:      id 
= '\''; break; 
5255         case VK_LWIN
:       id 
= WXK_WINDOWS_LEFT
; break; 
5256         case VK_RWIN
:       id 
= WXK_WINDOWS_RIGHT
; break; 
5257         case VK_APPS
:       id 
= WXK_WINDOWS_MENU
; break; 
5258 #endif // VK_APPS defined 
5260         // handle extended keys 
5262             id 
= ChooseNormalOrExtended(lParam
, WXK_NUMPAD_PRIOR
, WXK_PRIOR
); 
5265             id 
= ChooseNormalOrExtended(lParam
, WXK_NUMPAD_NEXT
, WXK_NEXT
); 
5268             id 
= ChooseNormalOrExtended(lParam
, WXK_NUMPAD_END
, WXK_END
); 
5271             id 
= ChooseNormalOrExtended(lParam
, WXK_NUMPAD_HOME
, WXK_HOME
); 
5274             id 
= ChooseNormalOrExtended(lParam
, WXK_NUMPAD_LEFT
, WXK_LEFT
); 
5277             id 
= ChooseNormalOrExtended(lParam
, WXK_NUMPAD_UP
, WXK_UP
); 
5280             id 
= ChooseNormalOrExtended(lParam
, WXK_NUMPAD_RIGHT
, WXK_RIGHT
); 
5283             id 
= ChooseNormalOrExtended(lParam
, WXK_NUMPAD_DOWN
, WXK_DOWN
); 
5286             id 
= ChooseNormalOrExtended(lParam
, WXK_NUMPAD_INSERT
, WXK_INSERT
); 
5289             id 
= ChooseNormalOrExtended(lParam
, WXK_NUMPAD_DELETE
, WXK_DELETE
); 
5291         // this order is correct as the numpad enter is the extended key 
5293             id 
= ChooseNormalOrExtended(lParam
, WXK_RETURN
, WXK_NUMPAD_ENTER
); 
5303 WXWORD 
wxCharCodeWXToMSW(int id
, bool *isVirtual
) 
5309     case WXK_CANCEL
:    keySym 
= VK_CANCEL
; break; 
5310     case WXK_CLEAR
:     keySym 
= VK_CLEAR
; break; 
5311     case WXK_SHIFT
:     keySym 
= VK_SHIFT
; break; 
5312     case WXK_CONTROL
:   keySym 
= VK_CONTROL
; break; 
5313     case WXK_ALT
:       keySym 
= VK_MENU
; break; 
5314     case WXK_PAUSE
:     keySym 
= VK_PAUSE
; break; 
5315     case WXK_CAPITAL
:   keySym 
= VK_CAPITAL
; break; 
5316     case WXK_PRIOR
:     keySym 
= VK_PRIOR
; break; 
5317     case WXK_NEXT 
:     keySym 
= VK_NEXT
; break; 
5318     case WXK_END
:       keySym 
= VK_END
; break; 
5319     case WXK_HOME 
:     keySym 
= VK_HOME
; break; 
5320     case WXK_LEFT 
:     keySym 
= VK_LEFT
; break; 
5321     case WXK_UP
:        keySym 
= VK_UP
; break; 
5322     case WXK_RIGHT
:     keySym 
= VK_RIGHT
; break; 
5323     case WXK_DOWN 
:     keySym 
= VK_DOWN
; break; 
5324     case WXK_SELECT
:    keySym 
= VK_SELECT
; break; 
5325     case WXK_PRINT
:     keySym 
= VK_PRINT
; break; 
5326     case WXK_EXECUTE
:   keySym 
= VK_EXECUTE
; break; 
5327     case WXK_INSERT
:    keySym 
= VK_INSERT
; break; 
5328     case WXK_DELETE
:    keySym 
= VK_DELETE
; break; 
5329     case WXK_HELP 
:     keySym 
= VK_HELP
; break; 
5330     case WXK_NUMPAD0
:   keySym 
= VK_NUMPAD0
; break; 
5331     case WXK_NUMPAD1
:   keySym 
= VK_NUMPAD1
; break; 
5332     case WXK_NUMPAD2
:   keySym 
= VK_NUMPAD2
; break; 
5333     case WXK_NUMPAD3
:   keySym 
= VK_NUMPAD3
; break; 
5334     case WXK_NUMPAD4
:   keySym 
= VK_NUMPAD4
; break; 
5335     case WXK_NUMPAD5
:   keySym 
= VK_NUMPAD5
; break; 
5336     case WXK_NUMPAD6
:   keySym 
= VK_NUMPAD6
; break; 
5337     case WXK_NUMPAD7
:   keySym 
= VK_NUMPAD7
; break; 
5338     case WXK_NUMPAD8
:   keySym 
= VK_NUMPAD8
; break; 
5339     case WXK_NUMPAD9
:   keySym 
= VK_NUMPAD9
; break; 
5340     case WXK_NUMPAD_MULTIPLY
:  keySym 
= VK_MULTIPLY
; break; 
5341     case WXK_NUMPAD_ADD
:       keySym 
= VK_ADD
; break; 
5342     case WXK_NUMPAD_SUBTRACT
:  keySym 
= VK_SUBTRACT
; break; 
5343     case WXK_NUMPAD_DECIMAL
:   keySym 
= VK_DECIMAL
; break; 
5344     case WXK_NUMPAD_DIVIDE
:    keySym 
= VK_DIVIDE
; break; 
5345     case WXK_F1
:        keySym 
= VK_F1
; break; 
5346     case WXK_F2
:        keySym 
= VK_F2
; break; 
5347     case WXK_F3
:        keySym 
= VK_F3
; break; 
5348     case WXK_F4
:        keySym 
= VK_F4
; break; 
5349     case WXK_F5
:        keySym 
= VK_F5
; break; 
5350     case WXK_F6
:        keySym 
= VK_F6
; break; 
5351     case WXK_F7
:        keySym 
= VK_F7
; break; 
5352     case WXK_F8
:        keySym 
= VK_F8
; break; 
5353     case WXK_F9
:        keySym 
= VK_F9
; break; 
5354     case WXK_F10
:       keySym 
= VK_F10
; break; 
5355     case WXK_F11
:       keySym 
= VK_F11
; break; 
5356     case WXK_F12
:       keySym 
= VK_F12
; break; 
5357     case WXK_F13
:       keySym 
= VK_F13
; break; 
5358     case WXK_F14
:       keySym 
= VK_F14
; break; 
5359     case WXK_F15
:       keySym 
= VK_F15
; break; 
5360     case WXK_F16
:       keySym 
= VK_F16
; break; 
5361     case WXK_F17
:       keySym 
= VK_F17
; break; 
5362     case WXK_F18
:       keySym 
= VK_F18
; break; 
5363     case WXK_F19
:       keySym 
= VK_F19
; break; 
5364     case WXK_F20
:       keySym 
= VK_F20
; break; 
5365     case WXK_F21
:       keySym 
= VK_F21
; break; 
5366     case WXK_F22
:       keySym 
= VK_F22
; break; 
5367     case WXK_F23
:       keySym 
= VK_F23
; break; 
5368     case WXK_F24
:       keySym 
= VK_F24
; break; 
5369     case WXK_NUMLOCK
:   keySym 
= VK_NUMLOCK
; break; 
5370     case WXK_SCROLL
:    keySym 
= VK_SCROLL
; break; 
5381 bool wxGetKeyState(wxKeyCode key
) 
5385     wxASSERT_MSG(key 
!= WXK_LBUTTON 
&& key 
!= WXK_RBUTTON 
&& key 
!= 
5386         WXK_MBUTTON
, wxT("can't use wxGetKeyState() for mouse buttons")); 
5388 //High order with GetAsyncKeyState only available on WIN32 
5390     //If the requested key is a LED key, return 
5391     //true if the led is pressed 
5392     if (key 
== WXK_NUMLOCK 
|| 
5393         key 
== WXK_CAPITAL 
|| 
5397         //low order bit means LED is highlighted, 
5398         //high order means key is down 
5399         //Here, for compat with other ports we want both 
5400         return GetKeyState( wxCharCodeWXToMSW(key
, &bVirtual
) ) != 0; 
5407         //low order bit means key pressed since last call 
5408         //high order means key is down 
5409         //We want only the high order bit - the key may not be down if only low order 
5410         return ( GetAsyncKeyState( wxCharCodeWXToMSW(key
, &bVirtual
) ) & (1<<15) ) != 0; 
5416 wxMouseState 
wxGetMouseState() 
5420     GetCursorPos( &pt 
); 
5424     ms
.SetLeftDown( (GetAsyncKeyState(VK_LBUTTON
) & (1<<15)) != 0 ); 
5425     ms
.SetMiddleDown( (GetAsyncKeyState(VK_MBUTTON
) & (1<<15)) != 0 ); 
5426     ms
.SetRightDown( (GetAsyncKeyState(VK_RBUTTON
) & (1<<15)) != 0 ); 
5428     ms
.SetControlDown( (GetAsyncKeyState(VK_CONTROL
) & (1<<15)) != 0 ); 
5429     ms
.SetShiftDown( (GetAsyncKeyState(VK_SHIFT
) & (1<<15)) != 0 ); 
5430     ms
.SetAltDown( (GetAsyncKeyState(VK_MENU
) & (1<<15)) != 0 ); 
5431 //    ms.SetMetaDown(); 
5437 wxWindow 
*wxGetActiveWindow() 
5439     HWND hWnd 
= GetActiveWindow(); 
5442         return wxFindWinFromHandle((WXHWND
) hWnd
); 
5447 extern wxWindow 
*wxGetWindowFromHWND(WXHWND hWnd
) 
5449     HWND hwnd 
= (HWND
)hWnd
; 
5451     // For a radiobutton, we get the radiobox from GWL_USERDATA (which is set 
5452     // by code in msw/radiobox.cpp), for all the others we just search up the 
5454     wxWindow 
*win 
= (wxWindow 
*)NULL
; 
5457         win 
= wxFindWinFromHandle((WXHWND
)hwnd
); 
5461             // native radiobuttons return DLGC_RADIOBUTTON here and for any 
5462             // wxWindow class which overrides WM_GETDLGCODE processing to 
5463             // do it as well, win would be already non NULL 
5464             if ( ::SendMessage(hwnd
, WM_GETDLGCODE
, 0, 0) & DLGC_RADIOBUTTON 
) 
5466                 win 
= (wxWindow 
*)wxGetWindowUserData(hwnd
); 
5468             //else: it's a wxRadioButton, not a radiobutton from wxRadioBox 
5469 #endif // wxUSE_RADIOBOX 
5471             // spin control text buddy window should be mapped to spin ctrl 
5472             // itself so try it too 
5473 #if wxUSE_SPINCTRL && !defined(__WXUNIVERSAL__) 
5476                 win 
= wxSpinCtrl::GetSpinForTextCtrl((WXHWND
)hwnd
); 
5478 #endif // wxUSE_SPINCTRL 
5482     while ( hwnd 
&& !win 
) 
5484         // this is a really ugly hack needed to avoid mistakenly returning the 
5485         // parent frame wxWindow for the find/replace modeless dialog HWND - 
5486         // this, in turn, is needed to call IsDialogMessage() from 
5487         // wxApp::ProcessMessage() as for this we must return NULL from here 
5489         // FIXME: this is clearly not the best way to do it but I think we'll 
5490         //        need to change HWND <-> wxWindow code more heavily than I can 
5491         //        do it now to fix it 
5492 #ifndef __WXMICROWIN__ 
5493         if ( ::GetWindow(hwnd
, GW_OWNER
) ) 
5495             // it's a dialog box, don't go upwards 
5500         hwnd 
= ::GetParent(hwnd
); 
5501         win 
= wxFindWinFromHandle((WXHWND
)hwnd
); 
5507 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__) 
5509 // Windows keyboard hook. Allows interception of e.g. F1, ESCAPE 
5510 // in active frames and dialogs, regardless of where the focus is. 
5511 static HHOOK wxTheKeyboardHook 
= 0; 
5512 static FARPROC wxTheKeyboardHookProc 
= 0; 
5513 int APIENTRY _EXPORT
 
5514 wxKeyboardHook(int nCode
, WORD wParam
, DWORD lParam
); 
5516 void wxSetKeyboardHook(bool doIt
) 
5520         wxTheKeyboardHookProc 
= MakeProcInstance((FARPROC
) wxKeyboardHook
, wxGetInstance()); 
5521         wxTheKeyboardHook 
= SetWindowsHookEx(WH_KEYBOARD
, (HOOKPROC
) wxTheKeyboardHookProc
, wxGetInstance(), 
5523             GetCurrentThreadId() 
5524         //      (DWORD)GetCurrentProcess()); // This is another possibility. Which is right? 
5529         UnhookWindowsHookEx(wxTheKeyboardHook
); 
5533 int APIENTRY _EXPORT
 
5534 wxKeyboardHook(int nCode
, WORD wParam
, DWORD lParam
) 
5536     DWORD hiWord 
= HIWORD(lParam
); 
5537     if ( nCode 
!= HC_NOREMOVE 
&& ((hiWord 
& KF_UP
) == 0) ) 
5539         int id 
= wxCharCodeMSWToWX(wParam
, lParam
); 
5542             wxKeyEvent 
event(wxEVT_CHAR_HOOK
); 
5543             if ( (HIWORD(lParam
) & KF_ALTDOWN
) == KF_ALTDOWN 
) 
5544                 event
.m_altDown 
= true; 
5546             event
.SetEventObject(NULL
); 
5547             event
.m_keyCode 
= id
; 
5548             event
.m_shiftDown 
= wxIsShiftDown(); 
5549             event
.m_controlDown 
= wxIsCtrlDown(); 
5551             event
.SetTimestamp(::GetMessageTime()); 
5553             wxWindow 
*win 
= wxGetActiveWindow(); 
5554             wxEvtHandler 
*handler
; 
5557                 handler 
= win
->GetEventHandler(); 
5558                 event
.SetId(win
->GetId()); 
5563                 event
.SetId(wxID_ANY
); 
5566             if ( handler 
&& handler
->ProcessEvent(event
) ) 
5574     return (int)CallNextHookEx(wxTheKeyboardHook
, nCode
, wParam
, lParam
); 
5577 #endif // !__WXMICROWIN__ 
5580 const wxChar 
*wxGetMessageName(int message
) 
5584         case 0x0000: return wxT("WM_NULL"); 
5585         case 0x0001: return wxT("WM_CREATE"); 
5586         case 0x0002: return wxT("WM_DESTROY"); 
5587         case 0x0003: return wxT("WM_MOVE"); 
5588         case 0x0005: return wxT("WM_SIZE"); 
5589         case 0x0006: return wxT("WM_ACTIVATE"); 
5590         case 0x0007: return wxT("WM_SETFOCUS"); 
5591         case 0x0008: return wxT("WM_KILLFOCUS"); 
5592         case 0x000A: return wxT("WM_ENABLE"); 
5593         case 0x000B: return wxT("WM_SETREDRAW"); 
5594         case 0x000C: return wxT("WM_SETTEXT"); 
5595         case 0x000D: return wxT("WM_GETTEXT"); 
5596         case 0x000E: return wxT("WM_GETTEXTLENGTH"); 
5597         case 0x000F: return wxT("WM_PAINT"); 
5598         case 0x0010: return wxT("WM_CLOSE"); 
5599         case 0x0011: return wxT("WM_QUERYENDSESSION"); 
5600         case 0x0012: return wxT("WM_QUIT"); 
5601         case 0x0013: return wxT("WM_QUERYOPEN"); 
5602         case 0x0014: return wxT("WM_ERASEBKGND"); 
5603         case 0x0015: return wxT("WM_SYSCOLORCHANGE"); 
5604         case 0x0016: return wxT("WM_ENDSESSION"); 
5605         case 0x0017: return wxT("WM_SYSTEMERROR"); 
5606         case 0x0018: return wxT("WM_SHOWWINDOW"); 
5607         case 0x0019: return wxT("WM_CTLCOLOR"); 
5608         case 0x001A: return wxT("WM_WININICHANGE"); 
5609         case 0x001B: return wxT("WM_DEVMODECHANGE"); 
5610         case 0x001C: return wxT("WM_ACTIVATEAPP"); 
5611         case 0x001D: return wxT("WM_FONTCHANGE"); 
5612         case 0x001E: return wxT("WM_TIMECHANGE"); 
5613         case 0x001F: return wxT("WM_CANCELMODE"); 
5614         case 0x0020: return wxT("WM_SETCURSOR"); 
5615         case 0x0021: return wxT("WM_MOUSEACTIVATE"); 
5616         case 0x0022: return wxT("WM_CHILDACTIVATE"); 
5617         case 0x0023: return wxT("WM_QUEUESYNC"); 
5618         case 0x0024: return wxT("WM_GETMINMAXINFO"); 
5619         case 0x0026: return wxT("WM_PAINTICON"); 
5620         case 0x0027: return wxT("WM_ICONERASEBKGND"); 
5621         case 0x0028: return wxT("WM_NEXTDLGCTL"); 
5622         case 0x002A: return wxT("WM_SPOOLERSTATUS"); 
5623         case 0x002B: return wxT("WM_DRAWITEM"); 
5624         case 0x002C: return wxT("WM_MEASUREITEM"); 
5625         case 0x002D: return wxT("WM_DELETEITEM"); 
5626         case 0x002E: return wxT("WM_VKEYTOITEM"); 
5627         case 0x002F: return wxT("WM_CHARTOITEM"); 
5628         case 0x0030: return wxT("WM_SETFONT"); 
5629         case 0x0031: return wxT("WM_GETFONT"); 
5630         case 0x0037: return wxT("WM_QUERYDRAGICON"); 
5631         case 0x0039: return wxT("WM_COMPAREITEM"); 
5632         case 0x0041: return wxT("WM_COMPACTING"); 
5633         case 0x0044: return wxT("WM_COMMNOTIFY"); 
5634         case 0x0046: return wxT("WM_WINDOWPOSCHANGING"); 
5635         case 0x0047: return wxT("WM_WINDOWPOSCHANGED"); 
5636         case 0x0048: return wxT("WM_POWER"); 
5638         case 0x004A: return wxT("WM_COPYDATA"); 
5639         case 0x004B: return wxT("WM_CANCELJOURNAL"); 
5640         case 0x004E: return wxT("WM_NOTIFY"); 
5641         case 0x0050: return wxT("WM_INPUTLANGCHANGEREQUEST"); 
5642         case 0x0051: return wxT("WM_INPUTLANGCHANGE"); 
5643         case 0x0052: return wxT("WM_TCARD"); 
5644         case 0x0053: return wxT("WM_HELP"); 
5645         case 0x0054: return wxT("WM_USERCHANGED"); 
5646         case 0x0055: return wxT("WM_NOTIFYFORMAT"); 
5647         case 0x007B: return wxT("WM_CONTEXTMENU"); 
5648         case 0x007C: return wxT("WM_STYLECHANGING"); 
5649         case 0x007D: return wxT("WM_STYLECHANGED"); 
5650         case 0x007E: return wxT("WM_DISPLAYCHANGE"); 
5651         case 0x007F: return wxT("WM_GETICON"); 
5652         case 0x0080: return wxT("WM_SETICON"); 
5654         case 0x0081: return wxT("WM_NCCREATE"); 
5655         case 0x0082: return wxT("WM_NCDESTROY"); 
5656         case 0x0083: return wxT("WM_NCCALCSIZE"); 
5657         case 0x0084: return wxT("WM_NCHITTEST"); 
5658         case 0x0085: return wxT("WM_NCPAINT"); 
5659         case 0x0086: return wxT("WM_NCACTIVATE"); 
5660         case 0x0087: return wxT("WM_GETDLGCODE"); 
5661         case 0x00A0: return wxT("WM_NCMOUSEMOVE"); 
5662         case 0x00A1: return wxT("WM_NCLBUTTONDOWN"); 
5663         case 0x00A2: return wxT("WM_NCLBUTTONUP"); 
5664         case 0x00A3: return wxT("WM_NCLBUTTONDBLCLK"); 
5665         case 0x00A4: return wxT("WM_NCRBUTTONDOWN"); 
5666         case 0x00A5: return wxT("WM_NCRBUTTONUP"); 
5667         case 0x00A6: return wxT("WM_NCRBUTTONDBLCLK"); 
5668         case 0x00A7: return wxT("WM_NCMBUTTONDOWN"); 
5669         case 0x00A8: return wxT("WM_NCMBUTTONUP"); 
5670         case 0x00A9: return wxT("WM_NCMBUTTONDBLCLK"); 
5671         case 0x0100: return wxT("WM_KEYDOWN"); 
5672         case 0x0101: return wxT("WM_KEYUP"); 
5673         case 0x0102: return wxT("WM_CHAR"); 
5674         case 0x0103: return wxT("WM_DEADCHAR"); 
5675         case 0x0104: return wxT("WM_SYSKEYDOWN"); 
5676         case 0x0105: return wxT("WM_SYSKEYUP"); 
5677         case 0x0106: return wxT("WM_SYSCHAR"); 
5678         case 0x0107: return wxT("WM_SYSDEADCHAR"); 
5679         case 0x0108: return wxT("WM_KEYLAST"); 
5681         case 0x010D: return wxT("WM_IME_STARTCOMPOSITION"); 
5682         case 0x010E: return wxT("WM_IME_ENDCOMPOSITION"); 
5683         case 0x010F: return wxT("WM_IME_COMPOSITION"); 
5685         case 0x0110: return wxT("WM_INITDIALOG"); 
5686         case 0x0111: return wxT("WM_COMMAND"); 
5687         case 0x0112: return wxT("WM_SYSCOMMAND"); 
5688         case 0x0113: return wxT("WM_TIMER"); 
5689         case 0x0114: return wxT("WM_HSCROLL"); 
5690         case 0x0115: return wxT("WM_VSCROLL"); 
5691         case 0x0116: return wxT("WM_INITMENU"); 
5692         case 0x0117: return wxT("WM_INITMENUPOPUP"); 
5693         case 0x011F: return wxT("WM_MENUSELECT"); 
5694         case 0x0120: return wxT("WM_MENUCHAR"); 
5695         case 0x0121: return wxT("WM_ENTERIDLE"); 
5696         case 0x0200: return wxT("WM_MOUSEMOVE"); 
5697         case 0x0201: return wxT("WM_LBUTTONDOWN"); 
5698         case 0x0202: return wxT("WM_LBUTTONUP"); 
5699         case 0x0203: return wxT("WM_LBUTTONDBLCLK"); 
5700         case 0x0204: return wxT("WM_RBUTTONDOWN"); 
5701         case 0x0205: return wxT("WM_RBUTTONUP"); 
5702         case 0x0206: return wxT("WM_RBUTTONDBLCLK"); 
5703         case 0x0207: return wxT("WM_MBUTTONDOWN"); 
5704         case 0x0208: return wxT("WM_MBUTTONUP"); 
5705         case 0x0209: return wxT("WM_MBUTTONDBLCLK"); 
5706         case 0x020A: return wxT("WM_MOUSEWHEEL"); 
5707         case 0x0210: return wxT("WM_PARENTNOTIFY"); 
5708         case 0x0211: return wxT("WM_ENTERMENULOOP"); 
5709         case 0x0212: return wxT("WM_EXITMENULOOP"); 
5711         case 0x0213: return wxT("WM_NEXTMENU"); 
5712         case 0x0214: return wxT("WM_SIZING"); 
5713         case 0x0215: return wxT("WM_CAPTURECHANGED"); 
5714         case 0x0216: return wxT("WM_MOVING"); 
5715         case 0x0218: return wxT("WM_POWERBROADCAST"); 
5716         case 0x0219: return wxT("WM_DEVICECHANGE"); 
5718         case 0x0220: return wxT("WM_MDICREATE"); 
5719         case 0x0221: return wxT("WM_MDIDESTROY"); 
5720         case 0x0222: return wxT("WM_MDIACTIVATE"); 
5721         case 0x0223: return wxT("WM_MDIRESTORE"); 
5722         case 0x0224: return wxT("WM_MDINEXT"); 
5723         case 0x0225: return wxT("WM_MDIMAXIMIZE"); 
5724         case 0x0226: return wxT("WM_MDITILE"); 
5725         case 0x0227: return wxT("WM_MDICASCADE"); 
5726         case 0x0228: return wxT("WM_MDIICONARRANGE"); 
5727         case 0x0229: return wxT("WM_MDIGETACTIVE"); 
5728         case 0x0230: return wxT("WM_MDISETMENU"); 
5729         case 0x0233: return wxT("WM_DROPFILES"); 
5731         case 0x0281: return wxT("WM_IME_SETCONTEXT"); 
5732         case 0x0282: return wxT("WM_IME_NOTIFY"); 
5733         case 0x0283: return wxT("WM_IME_CONTROL"); 
5734         case 0x0284: return wxT("WM_IME_COMPOSITIONFULL"); 
5735         case 0x0285: return wxT("WM_IME_SELECT"); 
5736         case 0x0286: return wxT("WM_IME_CHAR"); 
5737         case 0x0290: return wxT("WM_IME_KEYDOWN"); 
5738         case 0x0291: return wxT("WM_IME_KEYUP"); 
5740         case 0x0300: return wxT("WM_CUT"); 
5741         case 0x0301: return wxT("WM_COPY"); 
5742         case 0x0302: return wxT("WM_PASTE"); 
5743         case 0x0303: return wxT("WM_CLEAR"); 
5744         case 0x0304: return wxT("WM_UNDO"); 
5745         case 0x0305: return wxT("WM_RENDERFORMAT"); 
5746         case 0x0306: return wxT("WM_RENDERALLFORMATS"); 
5747         case 0x0307: return wxT("WM_DESTROYCLIPBOARD"); 
5748         case 0x0308: return wxT("WM_DRAWCLIPBOARD"); 
5749         case 0x0309: return wxT("WM_PAINTCLIPBOARD"); 
5750         case 0x030A: return wxT("WM_VSCROLLCLIPBOARD"); 
5751         case 0x030B: return wxT("WM_SIZECLIPBOARD"); 
5752         case 0x030C: return wxT("WM_ASKCBFORMATNAME"); 
5753         case 0x030D: return wxT("WM_CHANGECBCHAIN"); 
5754         case 0x030E: return wxT("WM_HSCROLLCLIPBOARD"); 
5755         case 0x030F: return wxT("WM_QUERYNEWPALETTE"); 
5756         case 0x0310: return wxT("WM_PALETTEISCHANGING"); 
5757         case 0x0311: return wxT("WM_PALETTECHANGED"); 
5759         case 0x0312: return wxT("WM_HOTKEY"); 
5762         // common controls messages - although they're not strictly speaking 
5763         // standard, it's nice to decode them nevertheless 
5766         case 0x1000 + 0: return wxT("LVM_GETBKCOLOR"); 
5767         case 0x1000 + 1: return wxT("LVM_SETBKCOLOR"); 
5768         case 0x1000 + 2: return wxT("LVM_GETIMAGELIST"); 
5769         case 0x1000 + 3: return wxT("LVM_SETIMAGELIST"); 
5770         case 0x1000 + 4: return wxT("LVM_GETITEMCOUNT"); 
5771         case 0x1000 + 5: return wxT("LVM_GETITEMA"); 
5772         case 0x1000 + 75: return wxT("LVM_GETITEMW"); 
5773         case 0x1000 + 6: return wxT("LVM_SETITEMA"); 
5774         case 0x1000 + 76: return wxT("LVM_SETITEMW"); 
5775         case 0x1000 + 7: return wxT("LVM_INSERTITEMA"); 
5776         case 0x1000 + 77: return wxT("LVM_INSERTITEMW"); 
5777         case 0x1000 + 8: return wxT("LVM_DELETEITEM"); 
5778         case 0x1000 + 9: return wxT("LVM_DELETEALLITEMS"); 
5779         case 0x1000 + 10: return wxT("LVM_GETCALLBACKMASK"); 
5780         case 0x1000 + 11: return wxT("LVM_SETCALLBACKMASK"); 
5781         case 0x1000 + 12: return wxT("LVM_GETNEXTITEM"); 
5782         case 0x1000 + 13: return wxT("LVM_FINDITEMA"); 
5783         case 0x1000 + 83: return wxT("LVM_FINDITEMW"); 
5784         case 0x1000 + 14: return wxT("LVM_GETITEMRECT"); 
5785         case 0x1000 + 15: return wxT("LVM_SETITEMPOSITION"); 
5786         case 0x1000 + 16: return wxT("LVM_GETITEMPOSITION"); 
5787         case 0x1000 + 17: return wxT("LVM_GETSTRINGWIDTHA"); 
5788         case 0x1000 + 87: return wxT("LVM_GETSTRINGWIDTHW"); 
5789         case 0x1000 + 18: return wxT("LVM_HITTEST"); 
5790         case 0x1000 + 19: return wxT("LVM_ENSUREVISIBLE"); 
5791         case 0x1000 + 20: return wxT("LVM_SCROLL"); 
5792         case 0x1000 + 21: return wxT("LVM_REDRAWITEMS"); 
5793         case 0x1000 + 22: return wxT("LVM_ARRANGE"); 
5794         case 0x1000 + 23: return wxT("LVM_EDITLABELA"); 
5795         case 0x1000 + 118: return wxT("LVM_EDITLABELW"); 
5796         case 0x1000 + 24: return wxT("LVM_GETEDITCONTROL"); 
5797         case 0x1000 + 25: return wxT("LVM_GETCOLUMNA"); 
5798         case 0x1000 + 95: return wxT("LVM_GETCOLUMNW"); 
5799         case 0x1000 + 26: return wxT("LVM_SETCOLUMNA"); 
5800         case 0x1000 + 96: return wxT("LVM_SETCOLUMNW"); 
5801         case 0x1000 + 27: return wxT("LVM_INSERTCOLUMNA"); 
5802         case 0x1000 + 97: return wxT("LVM_INSERTCOLUMNW"); 
5803         case 0x1000 + 28: return wxT("LVM_DELETECOLUMN"); 
5804         case 0x1000 + 29: return wxT("LVM_GETCOLUMNWIDTH"); 
5805         case 0x1000 + 30: return wxT("LVM_SETCOLUMNWIDTH"); 
5806         case 0x1000 + 31: return wxT("LVM_GETHEADER"); 
5807         case 0x1000 + 33: return wxT("LVM_CREATEDRAGIMAGE"); 
5808         case 0x1000 + 34: return wxT("LVM_GETVIEWRECT"); 
5809         case 0x1000 + 35: return wxT("LVM_GETTEXTCOLOR"); 
5810         case 0x1000 + 36: return wxT("LVM_SETTEXTCOLOR"); 
5811         case 0x1000 + 37: return wxT("LVM_GETTEXTBKCOLOR"); 
5812         case 0x1000 + 38: return wxT("LVM_SETTEXTBKCOLOR"); 
5813         case 0x1000 + 39: return wxT("LVM_GETTOPINDEX"); 
5814         case 0x1000 + 40: return wxT("LVM_GETCOUNTPERPAGE"); 
5815         case 0x1000 + 41: return wxT("LVM_GETORIGIN"); 
5816         case 0x1000 + 42: return wxT("LVM_UPDATE"); 
5817         case 0x1000 + 43: return wxT("LVM_SETITEMSTATE"); 
5818         case 0x1000 + 44: return wxT("LVM_GETITEMSTATE"); 
5819         case 0x1000 + 45: return wxT("LVM_GETITEMTEXTA"); 
5820         case 0x1000 + 115: return wxT("LVM_GETITEMTEXTW"); 
5821         case 0x1000 + 46: return wxT("LVM_SETITEMTEXTA"); 
5822         case 0x1000 + 116: return wxT("LVM_SETITEMTEXTW"); 
5823         case 0x1000 + 47: return wxT("LVM_SETITEMCOUNT"); 
5824         case 0x1000 + 48: return wxT("LVM_SORTITEMS"); 
5825         case 0x1000 + 49: return wxT("LVM_SETITEMPOSITION32"); 
5826         case 0x1000 + 50: return wxT("LVM_GETSELECTEDCOUNT"); 
5827         case 0x1000 + 51: return wxT("LVM_GETITEMSPACING"); 
5828         case 0x1000 + 52: return wxT("LVM_GETISEARCHSTRINGA"); 
5829         case 0x1000 + 117: return wxT("LVM_GETISEARCHSTRINGW"); 
5830         case 0x1000 + 53: return wxT("LVM_SETICONSPACING"); 
5831         case 0x1000 + 54: return wxT("LVM_SETEXTENDEDLISTVIEWSTYLE"); 
5832         case 0x1000 + 55: return wxT("LVM_GETEXTENDEDLISTVIEWSTYLE"); 
5833         case 0x1000 + 56: return wxT("LVM_GETSUBITEMRECT"); 
5834         case 0x1000 + 57: return wxT("LVM_SUBITEMHITTEST"); 
5835         case 0x1000 + 58: return wxT("LVM_SETCOLUMNORDERARRAY"); 
5836         case 0x1000 + 59: return wxT("LVM_GETCOLUMNORDERARRAY"); 
5837         case 0x1000 + 60: return wxT("LVM_SETHOTITEM"); 
5838         case 0x1000 + 61: return wxT("LVM_GETHOTITEM"); 
5839         case 0x1000 + 62: return wxT("LVM_SETHOTCURSOR"); 
5840         case 0x1000 + 63: return wxT("LVM_GETHOTCURSOR"); 
5841         case 0x1000 + 64: return wxT("LVM_APPROXIMATEVIEWRECT"); 
5842         case 0x1000 + 65: return wxT("LVM_SETWORKAREA"); 
5845         case 0x1100 + 0: return wxT("TVM_INSERTITEMA"); 
5846         case 0x1100 + 50: return wxT("TVM_INSERTITEMW"); 
5847         case 0x1100 + 1: return wxT("TVM_DELETEITEM"); 
5848         case 0x1100 + 2: return wxT("TVM_EXPAND"); 
5849         case 0x1100 + 4: return wxT("TVM_GETITEMRECT"); 
5850         case 0x1100 + 5: return wxT("TVM_GETCOUNT"); 
5851         case 0x1100 + 6: return wxT("TVM_GETINDENT"); 
5852         case 0x1100 + 7: return wxT("TVM_SETINDENT"); 
5853         case 0x1100 + 8: return wxT("TVM_GETIMAGELIST"); 
5854         case 0x1100 + 9: return wxT("TVM_SETIMAGELIST"); 
5855         case 0x1100 + 10: return wxT("TVM_GETNEXTITEM"); 
5856         case 0x1100 + 11: return wxT("TVM_SELECTITEM"); 
5857         case 0x1100 + 12: return wxT("TVM_GETITEMA"); 
5858         case 0x1100 + 62: return wxT("TVM_GETITEMW"); 
5859         case 0x1100 + 13: return wxT("TVM_SETITEMA"); 
5860         case 0x1100 + 63: return wxT("TVM_SETITEMW"); 
5861         case 0x1100 + 14: return wxT("TVM_EDITLABELA"); 
5862         case 0x1100 + 65: return wxT("TVM_EDITLABELW"); 
5863         case 0x1100 + 15: return wxT("TVM_GETEDITCONTROL"); 
5864         case 0x1100 + 16: return wxT("TVM_GETVISIBLECOUNT"); 
5865         case 0x1100 + 17: return wxT("TVM_HITTEST"); 
5866         case 0x1100 + 18: return wxT("TVM_CREATEDRAGIMAGE"); 
5867         case 0x1100 + 19: return wxT("TVM_SORTCHILDREN"); 
5868         case 0x1100 + 20: return wxT("TVM_ENSUREVISIBLE"); 
5869         case 0x1100 + 21: return wxT("TVM_SORTCHILDRENCB"); 
5870         case 0x1100 + 22: return wxT("TVM_ENDEDITLABELNOW"); 
5871         case 0x1100 + 23: return wxT("TVM_GETISEARCHSTRINGA"); 
5872         case 0x1100 + 64: return wxT("TVM_GETISEARCHSTRINGW"); 
5873         case 0x1100 + 24: return wxT("TVM_SETTOOLTIPS"); 
5874         case 0x1100 + 25: return wxT("TVM_GETTOOLTIPS"); 
5877         case 0x1200 + 0: return wxT("HDM_GETITEMCOUNT"); 
5878         case 0x1200 + 1: return wxT("HDM_INSERTITEMA"); 
5879         case 0x1200 + 10: return wxT("HDM_INSERTITEMW"); 
5880         case 0x1200 + 2: return wxT("HDM_DELETEITEM"); 
5881         case 0x1200 + 3: return wxT("HDM_GETITEMA"); 
5882         case 0x1200 + 11: return wxT("HDM_GETITEMW"); 
5883         case 0x1200 + 4: return wxT("HDM_SETITEMA"); 
5884         case 0x1200 + 12: return wxT("HDM_SETITEMW"); 
5885         case 0x1200 + 5: return wxT("HDM_LAYOUT"); 
5886         case 0x1200 + 6: return wxT("HDM_HITTEST"); 
5887         case 0x1200 + 7: return wxT("HDM_GETITEMRECT"); 
5888         case 0x1200 + 8: return wxT("HDM_SETIMAGELIST"); 
5889         case 0x1200 + 9: return wxT("HDM_GETIMAGELIST"); 
5890         case 0x1200 + 15: return wxT("HDM_ORDERTOINDEX"); 
5891         case 0x1200 + 16: return wxT("HDM_CREATEDRAGIMAGE"); 
5892         case 0x1200 + 17: return wxT("HDM_GETORDERARRAY"); 
5893         case 0x1200 + 18: return wxT("HDM_SETORDERARRAY"); 
5894         case 0x1200 + 19: return wxT("HDM_SETHOTDIVIDER"); 
5897         case 0x1300 + 2: return wxT("TCM_GETIMAGELIST"); 
5898         case 0x1300 + 3: return wxT("TCM_SETIMAGELIST"); 
5899         case 0x1300 + 4: return wxT("TCM_GETITEMCOUNT"); 
5900         case 0x1300 + 5: return wxT("TCM_GETITEMA"); 
5901         case 0x1300 + 60: return wxT("TCM_GETITEMW"); 
5902         case 0x1300 + 6: return wxT("TCM_SETITEMA"); 
5903         case 0x1300 + 61: return wxT("TCM_SETITEMW"); 
5904         case 0x1300 + 7: return wxT("TCM_INSERTITEMA"); 
5905         case 0x1300 + 62: return wxT("TCM_INSERTITEMW"); 
5906         case 0x1300 + 8: return wxT("TCM_DELETEITEM"); 
5907         case 0x1300 + 9: return wxT("TCM_DELETEALLITEMS"); 
5908         case 0x1300 + 10: return wxT("TCM_GETITEMRECT"); 
5909         case 0x1300 + 11: return wxT("TCM_GETCURSEL"); 
5910         case 0x1300 + 12: return wxT("TCM_SETCURSEL"); 
5911         case 0x1300 + 13: return wxT("TCM_HITTEST"); 
5912         case 0x1300 + 14: return wxT("TCM_SETITEMEXTRA"); 
5913         case 0x1300 + 40: return wxT("TCM_ADJUSTRECT"); 
5914         case 0x1300 + 41: return wxT("TCM_SETITEMSIZE"); 
5915         case 0x1300 + 42: return wxT("TCM_REMOVEIMAGE"); 
5916         case 0x1300 + 43: return wxT("TCM_SETPADDING"); 
5917         case 0x1300 + 44: return wxT("TCM_GETROWCOUNT"); 
5918         case 0x1300 + 45: return wxT("TCM_GETTOOLTIPS"); 
5919         case 0x1300 + 46: return wxT("TCM_SETTOOLTIPS"); 
5920         case 0x1300 + 47: return wxT("TCM_GETCURFOCUS"); 
5921         case 0x1300 + 48: return wxT("TCM_SETCURFOCUS"); 
5922         case 0x1300 + 49: return wxT("TCM_SETMINTABWIDTH"); 
5923         case 0x1300 + 50: return wxT("TCM_DESELECTALL"); 
5926         case WM_USER
+1: return wxT("TB_ENABLEBUTTON"); 
5927         case WM_USER
+2: return wxT("TB_CHECKBUTTON"); 
5928         case WM_USER
+3: return wxT("TB_PRESSBUTTON"); 
5929         case WM_USER
+4: return wxT("TB_HIDEBUTTON"); 
5930         case WM_USER
+5: return wxT("TB_INDETERMINATE"); 
5931         case WM_USER
+9: return wxT("TB_ISBUTTONENABLED"); 
5932         case WM_USER
+10: return wxT("TB_ISBUTTONCHECKED"); 
5933         case WM_USER
+11: return wxT("TB_ISBUTTONPRESSED"); 
5934         case WM_USER
+12: return wxT("TB_ISBUTTONHIDDEN"); 
5935         case WM_USER
+13: return wxT("TB_ISBUTTONINDETERMINATE"); 
5936         case WM_USER
+17: return wxT("TB_SETSTATE"); 
5937         case WM_USER
+18: return wxT("TB_GETSTATE"); 
5938         case WM_USER
+19: return wxT("TB_ADDBITMAP"); 
5939         case WM_USER
+20: return wxT("TB_ADDBUTTONS"); 
5940         case WM_USER
+21: return wxT("TB_INSERTBUTTON"); 
5941         case WM_USER
+22: return wxT("TB_DELETEBUTTON"); 
5942         case WM_USER
+23: return wxT("TB_GETBUTTON"); 
5943         case WM_USER
+24: return wxT("TB_BUTTONCOUNT"); 
5944         case WM_USER
+25: return wxT("TB_COMMANDTOINDEX"); 
5945         case WM_USER
+26: return wxT("TB_SAVERESTOREA"); 
5946         case WM_USER
+76: return wxT("TB_SAVERESTOREW"); 
5947         case WM_USER
+27: return wxT("TB_CUSTOMIZE"); 
5948         case WM_USER
+28: return wxT("TB_ADDSTRINGA"); 
5949         case WM_USER
+77: return wxT("TB_ADDSTRINGW"); 
5950         case WM_USER
+29: return wxT("TB_GETITEMRECT"); 
5951         case WM_USER
+30: return wxT("TB_BUTTONSTRUCTSIZE"); 
5952         case WM_USER
+31: return wxT("TB_SETBUTTONSIZE"); 
5953         case WM_USER
+32: return wxT("TB_SETBITMAPSIZE"); 
5954         case WM_USER
+33: return wxT("TB_AUTOSIZE"); 
5955         case WM_USER
+35: return wxT("TB_GETTOOLTIPS"); 
5956         case WM_USER
+36: return wxT("TB_SETTOOLTIPS"); 
5957         case WM_USER
+37: return wxT("TB_SETPARENT"); 
5958         case WM_USER
+39: return wxT("TB_SETROWS"); 
5959         case WM_USER
+40: return wxT("TB_GETROWS"); 
5960         case WM_USER
+42: return wxT("TB_SETCMDID"); 
5961         case WM_USER
+43: return wxT("TB_CHANGEBITMAP"); 
5962         case WM_USER
+44: return wxT("TB_GETBITMAP"); 
5963         case WM_USER
+45: return wxT("TB_GETBUTTONTEXTA"); 
5964         case WM_USER
+75: return wxT("TB_GETBUTTONTEXTW"); 
5965         case WM_USER
+46: return wxT("TB_REPLACEBITMAP"); 
5966         case WM_USER
+47: return wxT("TB_SETINDENT"); 
5967         case WM_USER
+48: return wxT("TB_SETIMAGELIST"); 
5968         case WM_USER
+49: return wxT("TB_GETIMAGELIST"); 
5969         case WM_USER
+50: return wxT("TB_LOADIMAGES"); 
5970         case WM_USER
+51: return wxT("TB_GETRECT"); 
5971         case WM_USER
+52: return wxT("TB_SETHOTIMAGELIST"); 
5972         case WM_USER
+53: return wxT("TB_GETHOTIMAGELIST"); 
5973         case WM_USER
+54: return wxT("TB_SETDISABLEDIMAGELIST"); 
5974         case WM_USER
+55: return wxT("TB_GETDISABLEDIMAGELIST"); 
5975         case WM_USER
+56: return wxT("TB_SETSTYLE"); 
5976         case WM_USER
+57: return wxT("TB_GETSTYLE"); 
5977         case WM_USER
+58: return wxT("TB_GETBUTTONSIZE"); 
5978         case WM_USER
+59: return wxT("TB_SETBUTTONWIDTH"); 
5979         case WM_USER
+60: return wxT("TB_SETMAXTEXTROWS"); 
5980         case WM_USER
+61: return wxT("TB_GETTEXTROWS"); 
5981         case WM_USER
+41: return wxT("TB_GETBITMAPFLAGS"); 
5984             static wxString s_szBuf
; 
5985             s_szBuf
.Printf(wxT("<unknown message = %d>"), message
); 
5986             return s_szBuf
.c_str(); 
5989 #endif //__WXDEBUG__ 
5991 static TEXTMETRIC 
wxGetTextMetrics(const wxWindowMSW 
*win
) 
5995     HWND hwnd 
= GetHwndOf(win
); 
5996     HDC hdc 
= ::GetDC(hwnd
); 
5998 #if !wxDIALOG_UNIT_COMPATIBILITY 
5999     // and select the current font into it 
6000     HFONT hfont 
= GetHfontOf(win
->GetFont()); 
6003         hfont 
= (HFONT
)::SelectObject(hdc
, hfont
); 
6007     // finally retrieve the text metrics from it 
6008     GetTextMetrics(hdc
, &tm
); 
6010 #if !wxDIALOG_UNIT_COMPATIBILITY 
6014         (void)::SelectObject(hdc
, hfont
); 
6018     ::ReleaseDC(hwnd
, hdc
); 
6023 // Find the wxWindow at the current mouse position, returning the mouse 
6025 wxWindow
* wxFindWindowAtPointer(wxPoint
& pt
) 
6027     pt 
= wxGetMousePosition(); 
6028     return wxFindWindowAtPoint(pt
); 
6031 wxWindow
* wxFindWindowAtPoint(const wxPoint
& pt
) 
6036     HWND hWndHit 
= ::WindowFromPoint(pt2
); 
6038     wxWindow
* win 
= wxFindWinFromHandle((WXHWND
) hWndHit
) ; 
6039     HWND hWnd 
= hWndHit
; 
6041     // Try to find a window with a wxWindow associated with it 
6042     while (!win 
&& (hWnd 
!= 0)) 
6044         hWnd 
= ::GetParent(hWnd
); 
6045         win 
= wxFindWinFromHandle((WXHWND
) hWnd
) ; 
6050 // Get the current mouse position. 
6051 wxPoint 
wxGetMousePosition() 
6055     GetCursorPosWinCE(&pt
); 
6057     GetCursorPos( & pt 
); 
6060     return wxPoint(pt
.x
, pt
.y
); 
6065 #if defined(__SMARTPHONE__) || defined(__POCKETPC__) 
6066 static void WinCEUnregisterHotKey(int modifiers
, int id
) 
6068     // Register hotkeys for the hardware buttons 
6070     typedef BOOL (WINAPI 
*UnregisterFunc1Proc
)(UINT
, UINT
); 
6072     UnregisterFunc1Proc procUnregisterFunc
; 
6073     hCoreDll 
= LoadLibrary(_T("coredll.dll")); 
6076         procUnregisterFunc 
= (UnregisterFunc1Proc
)GetProcAddress(hCoreDll
, _T("UnregisterFunc1")); 
6077         if (procUnregisterFunc
) 
6078             procUnregisterFunc(modifiers
, id
); 
6079         FreeLibrary(hCoreDll
); 
6084 bool wxWindowMSW::RegisterHotKey(int hotkeyId
, int modifiers
, int keycode
) 
6086     UINT win_modifiers
=0; 
6087     if ( modifiers 
& wxMOD_ALT 
) 
6088         win_modifiers 
|= MOD_ALT
; 
6089     if ( modifiers 
& wxMOD_SHIFT 
) 
6090         win_modifiers 
|= MOD_SHIFT
; 
6091     if ( modifiers 
& wxMOD_CONTROL 
) 
6092         win_modifiers 
|= MOD_CONTROL
; 
6093     if ( modifiers 
& wxMOD_WIN 
) 
6094         win_modifiers 
|= MOD_WIN
; 
6096 #if defined(__SMARTPHONE__) || defined(__POCKETPC__) 
6097     // Required for PPC and Smartphone hardware buttons 
6098     if (keycode 
>= WXK_SPECIAL1 
&& keycode 
<= WXK_SPECIAL20
) 
6099         WinCEUnregisterHotKey(win_modifiers
, hotkeyId
); 
6102     if ( !::RegisterHotKey(GetHwnd(), hotkeyId
, win_modifiers
, keycode
) ) 
6104         wxLogLastError(_T("RegisterHotKey")); 
6112 bool wxWindowMSW::UnregisterHotKey(int hotkeyId
) 
6114 #if defined(__SMARTPHONE__) || defined(__POCKETPC__) 
6115     WinCEUnregisterHotKey(MOD_WIN
, hotkeyId
); 
6118     if ( !::UnregisterHotKey(GetHwnd(), hotkeyId
) ) 
6120         wxLogLastError(_T("UnregisterHotKey")); 
6130 bool wxWindowMSW::HandleHotKey(WXWPARAM wParam
, WXLPARAM lParam
) 
6132     int hotkeyId 
= wParam
; 
6133     int virtualKey 
= HIWORD(lParam
); 
6134     int win_modifiers 
= LOWORD(lParam
); 
6136     wxKeyEvent 
event(CreateKeyEvent(wxEVT_HOTKEY
, virtualKey
, wParam
, lParam
)); 
6137     event
.SetId(hotkeyId
); 
6138     event
.m_shiftDown 
= (win_modifiers 
& MOD_SHIFT
) != 0; 
6139     event
.m_controlDown 
= (win_modifiers 
& MOD_CONTROL
) != 0; 
6140     event
.m_altDown 
= (win_modifiers 
& MOD_ALT
) != 0; 
6141     event
.m_metaDown 
= (win_modifiers 
& MOD_WIN
) != 0; 
6143     return GetEventHandler()->ProcessEvent(event
); 
6146 #endif // wxUSE_ACCEL 
6148 #endif // wxUSE_HOTKEY 
6150 // Not tested under WinCE 
6153 // this class installs a message hook which really wakes up our idle processing 
6154 // each time a WM_NULL is received (wxWakeUpIdle does this), even if we're 
6155 // sitting inside a local modal loop (e.g. a menu is opened or scrollbar is 
6156 // being dragged or even inside ::MessageBox()) and so don't control message 
6157 // dispatching otherwise 
6158 class wxIdleWakeUpModule 
: public wxModule
 
6161     virtual bool OnInit() 
6163         ms_hMsgHookProc 
= ::SetWindowsHookEx
 
6166                              &wxIdleWakeUpModule::MsgHookProc
, 
6168                              GetCurrentThreadId() 
6171         if ( !ms_hMsgHookProc 
) 
6173             wxLogLastError(_T("SetWindowsHookEx(WH_GETMESSAGE)")); 
6181     virtual void OnExit() 
6183         ::UnhookWindowsHookEx(wxIdleWakeUpModule::ms_hMsgHookProc
); 
6186     static LRESULT CALLBACK 
MsgHookProc(int nCode
, WPARAM wParam
, LPARAM lParam
) 
6188         MSG 
*msg 
= (MSG
*)lParam
; 
6190         // only process the message if it is actually going to be removed from 
6191         // the message queue, this prevents that the same event from being 
6192         // processed multiple times if now someone just called PeekMessage() 
6193         if ( msg
->message 
== WM_NULL 
&& wParam 
== PM_REMOVE 
) 
6195             wxTheApp
->ProcessPendingEvents(); 
6198         return CallNextHookEx(ms_hMsgHookProc
, nCode
, wParam
, lParam
); 
6202     static HHOOK ms_hMsgHookProc
; 
6204     DECLARE_DYNAMIC_CLASS(wxIdleWakeUpModule
) 
6207 HHOOK 
wxIdleWakeUpModule::ms_hMsgHookProc 
= 0; 
6209 IMPLEMENT_DYNAMIC_CLASS(wxIdleWakeUpModule
, wxModule
) 
6211 #endif // __WXWINCE__ 
6216 static void wxAdjustZOrder(wxWindow
* parent
) 
6218     if (parent
->IsKindOf(CLASSINFO(wxStaticBox
))) 
6220         // Set the z-order correctly 
6221         SetWindowPos((HWND
) parent
->GetHWND(), HWND_BOTTOM
, 0, 0, 0, 0, SWP_NOMOVE
|SWP_NOSIZE
); 
6224     wxWindowList::compatibility_iterator current 
= parent
->GetChildren().GetFirst(); 
6227         wxWindow 
*childWin 
= current
->GetData(); 
6228         wxAdjustZOrder(childWin
); 
6229         current 
= current
->GetNext(); 
6234 // We need to adjust the z-order of static boxes in WinCE, to 
6235 // make 'contained' controls visible 
6236 void wxWindowMSW::OnInitDialog( wxInitDialogEvent
& event 
) 
6239     wxAdjustZOrder(this);