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" 
  27 #include "wx/window.h" 
  30     #include "wx/msw/wrapwin.h" 
  31     #include "wx/msw/wrapcctl.h" // include <commctrl.h> "properly" 
  32     #include "wx/msw/missing.h" 
  36     #include "wx/dcclient.h" 
  37     #include "wx/dcmemory.h" 
  40     #include "wx/layout.h" 
  41     #include "wx/dialog.h" 
  43     #include "wx/listbox.h" 
  44     #include "wx/button.h" 
  45     #include "wx/msgdlg.h" 
  46     #include "wx/settings.h" 
  47     #include "wx/statbox.h" 
  51     #include "wx/textctrl.h" 
  52     #include "wx/menuitem.h" 
  53     #include "wx/module.h" 
  56 #if wxUSE_OWNER_DRAWN && !defined(__WXUNIVERSAL__) 
  57     #include "wx/ownerdrw.h" 
  60 #include "wx/hashmap.h" 
  61 #include "wx/evtloop.h" 
  63 #include "wx/sysopt.h" 
  65 #if wxUSE_DRAG_AND_DROP 
  69 #if wxUSE_ACCESSIBILITY 
  70     #include "wx/access.h" 
  74         #define WM_GETOBJECT 0x003D 
  77         #define OBJID_CLIENT 0xFFFFFFFC 
  81 #include "wx/msw/private.h" 
  84     #include "wx/tooltip.h" 
  92     #include "wx/spinctrl.h" 
  93 #endif // wxUSE_SPINCTRL 
  95 #include "wx/notebook.h" 
  96 #include "wx/listctrl.h" 
  97 #include "wx/dynlib.h" 
 101 #if (!defined(__GNUWIN32_OLD__) && !defined(__WXMICROWIN__) /* && !defined(__WXWINCE__) */ ) || defined(__CYGWIN10__) 
 102     #include <shellapi.h> 
 103     #include <mmsystem.h> 
 107     #include <windowsx.h> 
 110 #if !defined __WXWINCE__ && !defined NEED_PBT_H 
 114 #if defined(__WXWINCE__) 
 115     #include "wx/msw/wince/missing.h" 
 118     #include <shellapi.h> 
 120     #include <aygshell.h> 
 125     #include "wx/msw/uxtheme.h" 
 126     #define EP_EDITTEXT         1 
 129     #define ETS_SELECTED        3 
 130     #define ETS_DISABLED        4 
 131     #define ETS_FOCUSED         5 
 132     #define ETS_READONLY        6 
 136 #if defined(TME_LEAVE) && defined(WM_MOUSELEAVE) && wxUSE_DYNLIB_CLASS 
 137     #define HAVE_TRACKMOUSEEVENT 
 138 #endif // everything needed for TrackMouseEvent() 
 140 // if this is set to 1, we use deferred window sizing to reduce flicker when 
 141 // resizing complicated window hierarchies, but this can in theory result in 
 142 // different behaviour than the old code so we keep the possibility to use it 
 143 // by setting this to 0 (in the future this should be removed completely) 
 145 #define USE_DEFERRED_SIZING 0 
 147 #define USE_DEFERRED_SIZING 1 
 150 // set this to 1 to filter out duplicate mouse events, e.g. mouse move events 
 151 // when mouse position didnd't change 
 153     #define wxUSE_MOUSEEVENT_HACK 0 
 155     #define wxUSE_MOUSEEVENT_HACK 1 
 158 // not all compilers/platforms have X button related declarations (notably 
 159 // Windows CE doesn't, and probably some old SDKs don't neither) 
 160 #ifdef WM_XBUTTONDOWN 
 161     #define wxHAS_XBUTTON 
 164 // --------------------------------------------------------------------------- 
 166 // --------------------------------------------------------------------------- 
 168 #if wxUSE_MENUS_NATIVE 
 169 wxMenu 
*wxCurrentPopupMenu 
= NULL
; 
 170 #endif // wxUSE_MENUS_NATIVE 
 173 extern       wxChar 
*wxCanvasClassName
; 
 175 extern const wxChar 
*wxCanvasClassName
; 
 178 // true if we had already created the std colour map, used by 
 179 // wxGetStdColourMap() and wxWindow::OnSysColourChanged()           (FIXME-MT) 
 180 static bool gs_hasStdCmap 
= false; 
 182 // last mouse event information we need to filter out the duplicates 
 183 #if wxUSE_MOUSEEVENT_HACK 
 184 static struct MouseEventInfoDummy
 
 186     // mouse position (in screen coordinates) 
 189     // last mouse event type 
 192 #endif // wxUSE_MOUSEEVENT_HACK 
 194 // hash containing the registered handlers for the custom messages 
 195 WX_DECLARE_HASH_MAP(int, wxWindow::MSWMessageHandler
, 
 196                     wxIntegerHash
, wxIntegerEqual
, 
 199 static MSWMessageHandlers gs_messageHandlers
; 
 201 // --------------------------------------------------------------------------- 
 203 // --------------------------------------------------------------------------- 
 205 // the window proc for all our windows 
 206 LRESULT WXDLLEXPORT APIENTRY _EXPORT 
wxWndProc(HWND hWnd
, UINT message
, 
 207                                    WPARAM wParam
, LPARAM lParam
); 
 211     const wxChar 
*wxGetMessageName(int message
); 
 214 void wxRemoveHandleAssociation(wxWindowMSW 
*win
); 
 215 extern void wxAssociateWinWithHandle(HWND hWnd
, wxWindowMSW 
*win
); 
 216 wxWindow 
*wxFindWinFromHandle(WXHWND hWnd
); 
 218 // get the text metrics for the current font 
 219 static TEXTMETRIC 
wxGetTextMetrics(const wxWindowMSW 
*win
); 
 222 // find the window for the mouse event at the specified position 
 223 static wxWindowMSW 
*FindWindowForMouseEvent(wxWindowMSW 
*win
, int *x
, int *y
); 
 224 #endif // __WXWINCE__ 
 226 // wrapper around BringWindowToTop() API 
 227 static inline void wxBringWindowToTop(HWND hwnd
) 
 229 #ifdef __WXMICROWIN__ 
 230     // It seems that MicroWindows brings the _parent_ of the window to the top, 
 231     // which can be the wrong one. 
 233     // activate (set focus to) specified window 
 237     // raise top level parent to top of z order 
 238     if (!::SetWindowPos(hwnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE 
| SWP_NOSIZE
)) 
 240         wxLogLastError(_T("SetWindowPos")); 
 246 // ensure that all our parent windows have WS_EX_CONTROLPARENT style 
 247 static void EnsureParentHasControlParentStyle(wxWindow 
*parent
) 
 250        If we have WS_EX_CONTROLPARENT flag we absolutely *must* set it for our 
 251        parent as well as otherwise several Win32 functions using 
 252        GetNextDlgTabItem() to iterate over all controls such as 
 253        IsDialogMessage() or DefDlgProc() would enter an infinite loop: indeed, 
 254        all of them iterate over all the controls starting from the currently 
 255        focused one and stop iterating when they get back to the focus but 
 256        unless all parents have WS_EX_CONTROLPARENT bit set, they would never 
 257        get back to the initial (focused) window: as we do have this style, 
 258        GetNextDlgTabItem() will leave this window and continue in its parent, 
 259        but if the parent doesn't have it, it wouldn't recurse inside it later 
 260        on and so wouldn't have a chance of getting back to this window either. 
 262     while ( parent 
&& !parent
->IsTopLevel() ) 
 264         LONG exStyle 
= ::GetWindowLong(GetHwndOf(parent
), GWL_EXSTYLE
); 
 265         if ( !(exStyle 
& WS_EX_CONTROLPARENT
) ) 
 267             // force the parent to have this style 
 268             ::SetWindowLong(GetHwndOf(parent
), GWL_EXSTYLE
, 
 269                             exStyle 
| WS_EX_CONTROLPARENT
); 
 272         parent 
= parent
->GetParent(); 
 276 #endif // !__WXWINCE__ 
 279 // On Windows CE, GetCursorPos can return an error, so use this function 
 281 bool GetCursorPosWinCE(POINT
* pt
) 
 283     if (!GetCursorPos(pt
)) 
 285         DWORD pos 
= GetMessagePos(); 
 293 // --------------------------------------------------------------------------- 
 295 // --------------------------------------------------------------------------- 
 297 // in wxUniv/MSW this class is abstract because it doesn't have DoPopupMenu() 
 299 #ifdef __WXUNIVERSAL__ 
 300     IMPLEMENT_ABSTRACT_CLASS(wxWindowMSW
, wxWindowBase
) 
 302 #if wxUSE_EXTENDED_RTTI 
 304 // windows that are created from a parent window during its Create method, eg. spin controls in a calendar controls 
 305 // must never been streamed out separately otherwise chaos occurs. Right now easiest is to test for negative ids, as 
 306 // windows with negative ids never can be recreated anyway 
 308 bool wxWindowStreamingCallback( const wxObject 
*object
, wxWriter 
* , wxPersister 
* , wxxVariantArray 
& ) 
 310     const wxWindow 
* win 
= dynamic_cast<const wxWindow
*>(object
) ; 
 311     if ( win 
&& win
->GetId() < 0 ) 
 316 IMPLEMENT_DYNAMIC_CLASS_XTI_CALLBACK(wxWindow
, wxWindowBase
,"wx/window.h", wxWindowStreamingCallback
) 
 318 // make wxWindowList known before the property is used 
 320 wxCOLLECTION_TYPE_INFO( wxWindow
* , wxWindowList 
) ; 
 322 template<> void wxCollectionToVariantArray( wxWindowList 
const &theList
, wxxVariantArray 
&value
) 
 324     wxListCollectionToVariantArray
<wxWindowList::compatibility_iterator
>( theList 
, value 
) ; 
 327 WX_DEFINE_FLAGS( wxWindowStyle 
) 
 329 wxBEGIN_FLAGS( wxWindowStyle 
) 
 330     // new style border flags, we put them first to 
 331     // use them for streaming out 
 333     wxFLAGS_MEMBER(wxBORDER_SIMPLE
) 
 334     wxFLAGS_MEMBER(wxBORDER_SUNKEN
) 
 335     wxFLAGS_MEMBER(wxBORDER_DOUBLE
) 
 336     wxFLAGS_MEMBER(wxBORDER_RAISED
) 
 337     wxFLAGS_MEMBER(wxBORDER_STATIC
) 
 338     wxFLAGS_MEMBER(wxBORDER_NONE
) 
 340     // old style border flags 
 341     wxFLAGS_MEMBER(wxSIMPLE_BORDER
) 
 342     wxFLAGS_MEMBER(wxSUNKEN_BORDER
) 
 343     wxFLAGS_MEMBER(wxDOUBLE_BORDER
) 
 344     wxFLAGS_MEMBER(wxRAISED_BORDER
) 
 345     wxFLAGS_MEMBER(wxSTATIC_BORDER
) 
 346     wxFLAGS_MEMBER(wxBORDER
) 
 348     // standard window styles 
 349     wxFLAGS_MEMBER(wxTAB_TRAVERSAL
) 
 350     wxFLAGS_MEMBER(wxCLIP_CHILDREN
) 
 351     wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW
) 
 352     wxFLAGS_MEMBER(wxWANTS_CHARS
) 
 353     wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE
) 
 354     wxFLAGS_MEMBER(wxALWAYS_SHOW_SB 
) 
 355     wxFLAGS_MEMBER(wxVSCROLL
) 
 356     wxFLAGS_MEMBER(wxHSCROLL
) 
 358 wxEND_FLAGS( wxWindowStyle 
) 
 360 wxBEGIN_PROPERTIES_TABLE(wxWindow
) 
 361     wxEVENT_PROPERTY( Close 
, wxEVT_CLOSE_WINDOW 
, wxCloseEvent
) 
 362     wxEVENT_PROPERTY( Create 
, wxEVT_CREATE 
, wxWindowCreateEvent 
) 
 363     wxEVENT_PROPERTY( Destroy 
, wxEVT_DESTROY 
, wxWindowDestroyEvent 
) 
 364     // Always constructor Properties first 
 366     wxREADONLY_PROPERTY( Parent
,wxWindow
*, GetParent
, EMPTY_MACROVALUE 
, 0 /*flags*/ , wxT("Helpstring") , wxT("group")) 
 367     wxPROPERTY( Id
,wxWindowID
, SetId
, GetId
, -1 /*wxID_ANY*/ , 0 /*flags*/ , wxT("Helpstring") , wxT("group") ) 
 368     wxPROPERTY( Position
,wxPoint
, SetPosition 
, GetPosition
, wxDefaultPosition 
, 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // pos 
 369     wxPROPERTY( Size
,wxSize
, SetSize
, GetSize
, wxDefaultSize 
, 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // size 
 370     wxPROPERTY( WindowStyle 
, long , SetWindowStyleFlag 
, GetWindowStyleFlag 
, EMPTY_MACROVALUE 
, 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style 
 372     // Then all relations of the object graph 
 374     wxREADONLY_PROPERTY_COLLECTION( Children 
, wxWindowList 
, wxWindowBase
* , GetWindowChildren 
, wxPROP_OBJECT_GRAPH 
/*flags*/ , wxT("Helpstring") , wxT("group")) 
 376    // and finally all other properties 
 378     wxPROPERTY( ExtraStyle 
, long , SetExtraStyle 
, GetExtraStyle 
, EMPTY_MACROVALUE 
, 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // extstyle 
 379     wxPROPERTY( BackgroundColour 
, wxColour 
, SetBackgroundColour 
, GetBackgroundColour 
, EMPTY_MACROVALUE 
, 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // bg 
 380     wxPROPERTY( ForegroundColour 
, wxColour 
, SetForegroundColour 
, GetForegroundColour 
, EMPTY_MACROVALUE 
, 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // fg 
 381     wxPROPERTY( Enabled 
, bool , Enable 
, IsEnabled 
, wxxVariant((bool)true) , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) 
 382     wxPROPERTY( Shown 
, bool , Show 
, IsShown 
, wxxVariant((bool)true) , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) 
 384     // possible property candidates (not in xrc) or not valid in all subclasses 
 385     wxPROPERTY( Title
,wxString
, SetTitle
, GetTitle
, wxEmptyString 
) 
 386     wxPROPERTY( Font 
, wxFont 
, SetFont 
, GetWindowFont  
, ) 
 387     wxPROPERTY( Label
,wxString
, SetLabel
, GetLabel
, wxEmptyString 
) 
 388     // MaxHeight, Width , MinHeight , Width 
 389     // TODO switch label to control and title to toplevels 
 391     wxPROPERTY( ThemeEnabled 
, bool , SetThemeEnabled 
, GetThemeEnabled 
, ) 
 392     //wxPROPERTY( Cursor , wxCursor , SetCursor , GetCursor , ) 
 393     // wxPROPERTY( ToolTip , wxString , SetToolTip , GetToolTipText , ) 
 394     wxPROPERTY( AutoLayout 
, bool , SetAutoLayout 
, GetAutoLayout 
, ) 
 399 wxEND_PROPERTIES_TABLE() 
 401 wxBEGIN_HANDLERS_TABLE(wxWindow
) 
 402 wxEND_HANDLERS_TABLE() 
 404 wxCONSTRUCTOR_DUMMY(wxWindow
) 
 407     IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
) 
 409 #endif // __WXUNIVERSAL__/__WXMSW__ 
 411 BEGIN_EVENT_TABLE(wxWindowMSW
, wxWindowBase
) 
 412     EVT_SYS_COLOUR_CHANGED(wxWindowMSW::OnSysColourChanged
) 
 413     EVT_ERASE_BACKGROUND(wxWindowMSW::OnEraseBackground
) 
 415     EVT_INIT_DIALOG(wxWindowMSW::OnInitDialog
) 
 419 // =========================================================================== 
 421 // =========================================================================== 
 423 // --------------------------------------------------------------------------- 
 424 // wxWindow utility functions 
 425 // --------------------------------------------------------------------------- 
 427 // Find an item given the MS Windows id 
 428 wxWindow 
*wxWindowMSW::FindItem(long id
) const 
 431     wxControl 
*item 
= wxDynamicCastThis(wxControl
); 
 434         // is it us or one of our "internal" children? 
 435         if ( item
->GetId() == id
 
 436 #ifndef __WXUNIVERSAL__ 
 437                 || (item
->GetSubcontrols().Index(id
) != wxNOT_FOUND
) 
 438 #endif // __WXUNIVERSAL__ 
 444 #endif // wxUSE_CONTROLS 
 446     wxWindowList::compatibility_iterator current 
= GetChildren().GetFirst(); 
 449         wxWindow 
*childWin 
= current
->GetData(); 
 451         wxWindow 
*wnd 
= childWin
->FindItem(id
); 
 455         current 
= current
->GetNext(); 
 461 // Find an item given the MS Windows handle 
 462 wxWindow 
*wxWindowMSW::FindItemByHWND(WXHWND hWnd
, bool controlOnly
) const 
 464     wxWindowList::compatibility_iterator current 
= GetChildren().GetFirst(); 
 467         wxWindow 
*parent 
= current
->GetData(); 
 469         // Do a recursive search. 
 470         wxWindow 
*wnd 
= parent
->FindItemByHWND(hWnd
); 
 476                 || parent
->IsKindOf(CLASSINFO(wxControl
)) 
 477 #endif // wxUSE_CONTROLS 
 480             wxWindow 
*item 
= current
->GetData(); 
 481             if ( item
->GetHWND() == hWnd 
) 
 485                 if ( item
->ContainsHWND(hWnd
) ) 
 490         current 
= current
->GetNext(); 
 495 // Default command handler 
 496 bool wxWindowMSW::MSWCommand(WXUINT 
WXUNUSED(param
), WXWORD 
WXUNUSED(id
)) 
 501 // ---------------------------------------------------------------------------- 
 502 // constructors and such 
 503 // ---------------------------------------------------------------------------- 
 505 void wxWindowMSW::Init() 
 508     m_isBeingDeleted 
= false; 
 510     m_mouseInWindow 
= false; 
 511     m_lastKeydownProcessed 
= false; 
 521     m_pendingPosition 
= wxDefaultPosition
; 
 522     m_pendingSize 
= wxDefaultSize
; 
 525     m_contextMenuEnabled 
= false; 
 530 wxWindowMSW::~wxWindowMSW() 
 532     m_isBeingDeleted 
= true; 
 534 #ifndef __WXUNIVERSAL__ 
 535     // VS: make sure there's no wxFrame with last focus set to us: 
 536     for ( wxWindow 
*win 
= GetParent(); win
; win 
= win
->GetParent() ) 
 538         wxTopLevelWindow 
*frame 
= wxDynamicCast(win
, wxTopLevelWindow
); 
 541             if ( frame
->GetLastFocus() == this ) 
 543                 frame
->SetLastFocus(NULL
); 
 546             // apparently sometimes we can end up with our grand parent 
 547             // pointing to us as well: this is surely a bug in focus handling 
 548             // code but it's not clear where it happens so for now just try to 
 549             // fix it here by not breaking out of the loop 
 553 #endif // __WXUNIVERSAL__ 
 555     // VS: destroy children first and _then_ detach *this from its parent. 
 556     //     If we did it the other way around, children wouldn't be able 
 557     //     find their parent frame (see above). 
 562         // VZ: test temp removed to understand what really happens here 
 563         //if (::IsWindow(GetHwnd())) 
 565             if ( !::DestroyWindow(GetHwnd()) ) 
 566                 wxLogLastError(wxT("DestroyWindow")); 
 569         // remove hWnd <-> wxWindow association 
 570         wxRemoveHandleAssociation(this); 
 575 // real construction (Init() must have been called before!) 
 576 bool wxWindowMSW::Create(wxWindow 
*parent
, 
 581                          const wxString
& name
) 
 583     wxCHECK_MSG( parent
, false, wxT("can't create wxWindow without parent") ); 
 585     if ( !CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
) ) 
 588     parent
->AddChild(this); 
 591     DWORD msflags 
= MSWGetCreateWindowFlags(&exstyle
); 
 593 #ifdef __WXUNIVERSAL__ 
 594     // no borders, we draw them ourselves 
 595     exstyle 
&= ~(WS_EX_DLGMODALFRAME 
| 
 599     msflags 
&= ~WS_BORDER
; 
 600 #endif // wxUniversal 
 604         msflags 
|= WS_VISIBLE
; 
 607     if ( !MSWCreate(wxCanvasClassName
, NULL
, pos
, size
, msflags
, exstyle
) ) 
 615 // --------------------------------------------------------------------------- 
 617 // --------------------------------------------------------------------------- 
 619 void wxWindowMSW::SetFocus() 
 621     HWND hWnd 
= GetHwnd(); 
 622     wxCHECK_RET( hWnd
, _T("can't set focus to invalid window") ); 
 624 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__) 
 628     if ( !::SetFocus(hWnd
) ) 
 630 #if defined(__WXDEBUG__) && !defined(__WXMICROWIN__) 
 631         // was there really an error? 
 632         DWORD dwRes 
= ::GetLastError(); 
 635             HWND hwndFocus 
= ::GetFocus(); 
 636             if ( hwndFocus 
!= hWnd 
) 
 638                 wxLogApiError(_T("SetFocus"), dwRes
); 
 645 void wxWindowMSW::SetFocusFromKbd() 
 647     // when the focus is given to the control with DLGC_HASSETSEL style from 
 648     // keyboard its contents should be entirely selected: this is what 
 649     // ::IsDialogMessage() does and so we should do it as well to provide the 
 650     // same LNF as the native programs 
 651     if ( ::SendMessage(GetHwnd(), WM_GETDLGCODE
, 0, 0) & DLGC_HASSETSEL 
) 
 653         ::SendMessage(GetHwnd(), EM_SETSEL
, 0, -1); 
 656     // do this after (maybe) setting the selection as like this when 
 657     // wxEVT_SET_FOCUS handler is called, the selection would have been already 
 658     // set correctly -- this may be important 
 659     wxWindowBase::SetFocusFromKbd(); 
 662 // Get the window with the focus 
 663 wxWindow 
*wxWindowBase::DoFindFocus() 
 665     HWND hWnd 
= ::GetFocus(); 
 668         return wxGetWindowFromHWND((WXHWND
)hWnd
); 
 674 void wxWindowMSW::DoEnable( bool enable 
) 
 676     HWND hWnd 
= GetHwnd(); 
 678         ::EnableWindow(hWnd
, (BOOL
)enable
); 
 681 bool wxWindowMSW::Show(bool show
) 
 683     if ( !wxWindowBase::Show(show
) ) 
 686     HWND hWnd 
= GetHwnd(); 
 688     // we could be called before the underlying window is created (this is 
 689     // actually useful to prevent it from being initially shown), e.g. 
 691     //      wxFoo *foo = new wxFoo; 
 693     //      foo->Create(parent, ...); 
 695     // should work without errors 
 698         ::ShowWindow(hWnd
, show 
? SW_SHOW 
: SW_HIDE
); 
 704 // Raise the window to the top of the Z order 
 705 void wxWindowMSW::Raise() 
 707     wxBringWindowToTop(GetHwnd()); 
 710 // Lower the window to the bottom of the Z order 
 711 void wxWindowMSW::Lower() 
 713     ::SetWindowPos(GetHwnd(), HWND_BOTTOM
, 0, 0, 0, 0, 
 714                    SWP_NOMOVE 
| SWP_NOSIZE 
| SWP_NOACTIVATE
); 
 717 void wxWindowMSW::DoCaptureMouse() 
 719     HWND hWnd 
= GetHwnd(); 
 726 void wxWindowMSW::DoReleaseMouse() 
 728     if ( !::ReleaseCapture() ) 
 730         wxLogLastError(_T("ReleaseCapture")); 
 734 /* static */ wxWindow 
*wxWindowBase::GetCapture() 
 736     HWND hwnd 
= ::GetCapture(); 
 737     return hwnd 
? wxFindWinFromHandle((WXHWND
)hwnd
) : (wxWindow 
*)NULL
; 
 740 bool wxWindowMSW::SetFont(const wxFont
& font
) 
 742     if ( !wxWindowBase::SetFont(font
) ) 
 748     HWND hWnd 
= GetHwnd(); 
 751         WXHANDLE hFont 
= m_font
.GetResourceHandle(); 
 753         wxASSERT_MSG( hFont
, wxT("should have valid font") ); 
 755         ::SendMessage(hWnd
, WM_SETFONT
, (WPARAM
)hFont
, MAKELPARAM(TRUE
, 0)); 
 760 bool wxWindowMSW::SetCursor(const wxCursor
& cursor
) 
 762     if ( !wxWindowBase::SetCursor(cursor
) ) 
 768     // don't "overwrite" busy cursor 
 769     if ( m_cursor
.Ok() && !wxIsBusy() ) 
 771         // normally we should change the cursor only if it's over this window 
 772         // but we should do it always if we capture the mouse currently 
 773         bool set 
= HasCapture(); 
 776             HWND hWnd 
= GetHwnd(); 
 780             ::GetCursorPosWinCE(&point
); 
 782             ::GetCursorPos(&point
); 
 785             RECT rect 
= wxGetWindowRect(hWnd
); 
 787             set 
= ::PtInRect(&rect
, point
) != 0; 
 792             ::SetCursor(GetHcursorOf(m_cursor
)); 
 794         //else: will be set later when the mouse enters this window 
 800 void wxWindowMSW::WarpPointer(int x
, int y
) 
 802     ClientToScreen(&x
, &y
); 
 804     if ( !::SetCursorPos(x
, y
) ) 
 806         wxLogLastError(_T("SetCursorPos")); 
 810 void wxWindowMSW::MSWUpdateUIState(int action
, int state
) 
 812     // WM_CHANGEUISTATE only appeared in Windows 2000 so it can do us no good 
 813     // to use it on older systems -- and could possibly do some harm 
 814     static int s_needToUpdate 
= -1; 
 815     if ( s_needToUpdate 
== -1 ) 
 818         s_needToUpdate 
= wxGetOsVersion(&verMaj
, &verMin
) == wxOS_WINDOWS_NT 
&& 
 822     if ( s_needToUpdate 
) 
 824         // we send WM_CHANGEUISTATE so if nothing needs changing then the system 
 825         // won't send WM_UPDATEUISTATE 
 826         ::SendMessage(GetHwnd(), WM_CHANGEUISTATE
, MAKEWPARAM(action
, state
), 0); 
 830 // --------------------------------------------------------------------------- 
 832 // --------------------------------------------------------------------------- 
 834 inline int GetScrollPosition(HWND hWnd
, int wOrient
) 
 836 #ifdef __WXMICROWIN__ 
 837     return ::GetScrollPosWX(hWnd
, wOrient
); 
 839     WinStruct
<SCROLLINFO
> scrollInfo
; 
 840     scrollInfo
.cbSize 
= sizeof(SCROLLINFO
); 
 841     scrollInfo
.fMask 
= SIF_POS
; 
 842     ::GetScrollInfo(hWnd
, wOrient
, &scrollInfo 
); 
 844     return scrollInfo
.nPos
; 
 849 int wxWindowMSW::GetScrollPos(int orient
) const 
 851     HWND hWnd 
= GetHwnd(); 
 852     wxCHECK_MSG( hWnd
, 0, _T("no HWND in GetScrollPos") ); 
 854     return GetScrollPosition(hWnd
, orient 
== wxHORIZONTAL 
? SB_HORZ 
: SB_VERT
); 
 857 // This now returns the whole range, not just the number 
 858 // of positions that we can scroll. 
 859 int wxWindowMSW::GetScrollRange(int orient
) const 
 862     HWND hWnd 
= GetHwnd(); 
 866     ::GetScrollRange(hWnd
, orient 
== wxHORIZONTAL 
? SB_HORZ 
: SB_VERT
, 
 869     WinStruct
<SCROLLINFO
> scrollInfo
; 
 870     scrollInfo
.fMask 
= SIF_RANGE
; 
 871     if ( !::GetScrollInfo(hWnd
, 
 872                           orient 
== wxHORIZONTAL 
? SB_HORZ 
: SB_VERT
, 
 875         // Most of the time this is not really an error, since the return 
 876         // value can also be zero when there is no scrollbar yet. 
 877         // wxLogLastError(_T("GetScrollInfo")); 
 879     maxPos 
= scrollInfo
.nMax
; 
 881     // undo "range - 1" done in SetScrollbar() 
 885 int wxWindowMSW::GetScrollThumb(int orient
) const 
 887     return orient 
== wxHORIZONTAL 
? m_xThumbSize 
: m_yThumbSize
; 
 890 void wxWindowMSW::SetScrollPos(int orient
, int pos
, bool refresh
) 
 892     HWND hWnd 
= GetHwnd(); 
 893     wxCHECK_RET( hWnd
, _T("SetScrollPos: no HWND") ); 
 895     WinStruct
<SCROLLINFO
> info
; 
 899     info
.fMask 
= SIF_POS
; 
 900     if ( HasFlag(wxALWAYS_SHOW_SB
) ) 
 902         // disable scrollbar instead of removing it then 
 903         info
.fMask 
|= SIF_DISABLENOSCROLL
; 
 906     ::SetScrollInfo(hWnd
, orient 
== wxHORIZONTAL 
? SB_HORZ 
: SB_VERT
, 
 910 // New function that will replace some of the above. 
 911 void wxWindowMSW::SetScrollbar(int orient
, 
 917     WinStruct
<SCROLLINFO
> info
; 
 918     info
.nPage 
= pageSize
; 
 919     info
.nMin 
= 0;              // range is nMax - nMin + 1 
 920     info
.nMax 
= range 
- 1;      //  as both nMax and nMax are inclusive 
 922     info
.fMask 
= SIF_RANGE 
| SIF_PAGE 
| SIF_POS
; 
 923     if ( HasFlag(wxALWAYS_SHOW_SB
) ) 
 925         // disable scrollbar instead of removing it then 
 926         info
.fMask 
|= SIF_DISABLENOSCROLL
; 
 929     HWND hWnd 
= GetHwnd(); 
 932         // We have to set the variables here to make them valid in events 
 933         // triggered by ::SetScrollInfo() 
 934         *(orient 
== wxHORIZONTAL 
? &m_xThumbSize 
: &m_yThumbSize
) = pageSize
; 
 936         ::SetScrollInfo(hWnd
, orient 
== wxHORIZONTAL 
? SB_HORZ 
: SB_VERT
, 
 941 void wxWindowMSW::ScrollWindow(int dx
, int dy
, const wxRect 
*prect
) 
 947         wxCopyRectToRECT(*prect
, rect
); 
 957     // FIXME: is this the exact equivalent of the line below? 
 958     ::ScrollWindowEx(GetHwnd(), dx
, dy
, pr
, pr
, 0, 0, SW_SCROLLCHILDREN
|SW_ERASE
|SW_INVALIDATE
); 
 960     ::ScrollWindow(GetHwnd(), dx
, dy
, pr
, pr
); 
 964 static bool ScrollVertically(HWND hwnd
, int kind
, int count
) 
 966     int posStart 
= GetScrollPosition(hwnd
, SB_VERT
); 
 969     for ( int n 
= 0; n 
< count
; n
++ ) 
 971         ::SendMessage(hwnd
, WM_VSCROLL
, kind
, 0); 
 973         int posNew 
= GetScrollPosition(hwnd
, SB_VERT
); 
 976             // don't bother to continue, we're already at top/bottom 
 983     return pos 
!= posStart
; 
 986 bool wxWindowMSW::ScrollLines(int lines
) 
 988     bool down 
= lines 
> 0; 
 990     return ScrollVertically(GetHwnd(), 
 991                             down 
? SB_LINEDOWN 
: SB_LINEUP
, 
 992                             down 
? lines 
: -lines
); 
 995 bool wxWindowMSW::ScrollPages(int pages
) 
 997     bool down 
= pages 
> 0; 
 999     return ScrollVertically(GetHwnd(), 
1000                             down 
? SB_PAGEDOWN 
: SB_PAGEUP
, 
1001                             down 
? pages 
: -pages
); 
1004 // ---------------------------------------------------------------------------- 
1006 // ---------------------------------------------------------------------------- 
1008 void wxWindowMSW::SetLayoutDirection(wxLayoutDirection dir
) 
1013     const HWND hwnd 
= GetHwnd(); 
1014     wxCHECK_RET( hwnd
, _T("layout direction must be set after window creation") ); 
1016     LONG styleOld 
= ::GetWindowLong(hwnd
, GWL_EXSTYLE
); 
1018     LONG styleNew 
= styleOld
; 
1021         case wxLayout_LeftToRight
: 
1022             styleNew 
&= ~WS_EX_LAYOUTRTL
; 
1025         case wxLayout_RightToLeft
: 
1026             styleNew 
|= WS_EX_LAYOUTRTL
; 
1030             wxFAIL_MSG(_T("unsupported layout direction")); 
1034     if ( styleNew 
!= styleOld 
) 
1036         ::SetWindowLong(hwnd
, GWL_EXSTYLE
, styleNew
); 
1041 wxLayoutDirection 
wxWindowMSW::GetLayoutDirection() const 
1044     return wxLayout_Default
; 
1046     const HWND hwnd 
= GetHwnd(); 
1047     wxCHECK_MSG( hwnd
, wxLayout_Default
, _T("invalid window") ); 
1049     return ::GetWindowLong(hwnd
, GWL_EXSTYLE
) & WS_EX_LAYOUTRTL
 
1050                 ? wxLayout_RightToLeft
 
1051                 : wxLayout_LeftToRight
; 
1056 wxWindowMSW::AdjustForLayoutDirection(wxCoord x
, 
1057                                       wxCoord 
WXUNUSED(width
), 
1058                                       wxCoord 
WXUNUSED(widthTotal
)) const 
1060     // Win32 mirrors the coordinates of RTL windows automatically, so don't 
1061     // redo it ourselves 
1065 // --------------------------------------------------------------------------- 
1067 // --------------------------------------------------------------------------- 
1069 void wxWindowMSW::SubclassWin(WXHWND hWnd
) 
1071     wxASSERT_MSG( !m_oldWndProc
, wxT("subclassing window twice?") ); 
1073     HWND hwnd 
= (HWND
)hWnd
; 
1074     wxCHECK_RET( ::IsWindow(hwnd
), wxT("invalid HWND in SubclassWin") ); 
1076     wxAssociateWinWithHandle(hwnd
, this); 
1078     m_oldWndProc 
= (WXFARPROC
)wxGetWindowProc((HWND
)hWnd
); 
1080     // we don't need to subclass the window of our own class (in the Windows 
1081     // sense of the word) 
1082     if ( !wxCheckWindowWndProc(hWnd
, (WXFARPROC
)wxWndProc
) ) 
1084         wxSetWindowProc(hwnd
, wxWndProc
); 
1088         // don't bother restoring it either: this also makes it easy to 
1089         // implement IsOfStandardClass() method which returns true for the 
1090         // standard controls and false for the wxWidgets own windows as it can 
1091         // simply check m_oldWndProc 
1092         m_oldWndProc 
= NULL
; 
1095     // we're officially created now, send the event 
1096     wxWindowCreateEvent 
event((wxWindow 
*)this); 
1097     (void)GetEventHandler()->ProcessEvent(event
); 
1100 void wxWindowMSW::UnsubclassWin() 
1102     wxRemoveHandleAssociation(this); 
1104     // Restore old Window proc 
1105     HWND hwnd 
= GetHwnd(); 
1110         wxCHECK_RET( ::IsWindow(hwnd
), wxT("invalid HWND in UnsubclassWin") ); 
1114             if ( !wxCheckWindowWndProc((WXHWND
)hwnd
, m_oldWndProc
) ) 
1116                 wxSetWindowProc(hwnd
, (WNDPROC
)m_oldWndProc
); 
1119             m_oldWndProc 
= NULL
; 
1124 void wxWindowMSW::AssociateHandle(WXWidget handle
) 
1128       if ( !::DestroyWindow(GetHwnd()) ) 
1129         wxLogLastError(wxT("DestroyWindow")); 
1132     WXHWND wxhwnd 
= (WXHWND
)handle
; 
1135     SubclassWin(wxhwnd
); 
1138 void wxWindowMSW::DissociateHandle() 
1140     // this also calls SetHWND(0) for us 
1145 bool wxCheckWindowWndProc(WXHWND hWnd
, 
1146                           WXFARPROC 
WXUNUSED(wndProc
)) 
1148 // TODO: This list of window class names should be factored out so they can be 
1149 // managed in one place and then accessed from here and other places, such as 
1150 // wxApp::RegisterWindowClasses() and wxApp::UnregisterWindowClasses() 
1153     extern       wxChar 
*wxCanvasClassName
; 
1154     extern       wxChar 
*wxCanvasClassNameNR
; 
1156     extern const wxChar 
*wxCanvasClassName
; 
1157     extern const wxChar 
*wxCanvasClassNameNR
; 
1159     extern const wxChar 
*wxMDIFrameClassName
; 
1160     extern const wxChar 
*wxMDIFrameClassNameNoRedraw
; 
1161     extern const wxChar 
*wxMDIChildFrameClassName
; 
1162     extern const wxChar 
*wxMDIChildFrameClassNameNoRedraw
; 
1163     wxString 
str(wxGetWindowClass(hWnd
)); 
1164     if (str 
== wxCanvasClassName 
|| 
1165         str 
== wxCanvasClassNameNR 
|| 
1167         str 
== _T("wxGLCanvasClass") || 
1168         str 
== _T("wxGLCanvasClassNR") || 
1169 #endif // wxUSE_GLCANVAS 
1170         str 
== wxMDIFrameClassName 
|| 
1171         str 
== wxMDIFrameClassNameNoRedraw 
|| 
1172         str 
== wxMDIChildFrameClassName 
|| 
1173         str 
== wxMDIChildFrameClassNameNoRedraw 
|| 
1174         str 
== _T("wxTLWHiddenParent")) 
1175         return true; // Effectively means don't subclass 
1180 // ---------------------------------------------------------------------------- 
1182 // ---------------------------------------------------------------------------- 
1184 void wxWindowMSW::SetWindowStyleFlag(long flags
) 
1186     long flagsOld 
= GetWindowStyleFlag(); 
1187     if ( flags 
== flagsOld 
) 
1190     // update the internal variable 
1191     wxWindowBase::SetWindowStyleFlag(flags
); 
1193     // and the real window flags 
1194     MSWUpdateStyle(flagsOld
, GetExtraStyle()); 
1197 void wxWindowMSW::SetExtraStyle(long exflags
) 
1199     long exflagsOld 
= GetExtraStyle(); 
1200     if ( exflags 
== exflagsOld 
) 
1203     // update the internal variable 
1204     wxWindowBase::SetExtraStyle(exflags
); 
1206     // and the real window flags 
1207     MSWUpdateStyle(GetWindowStyleFlag(), exflagsOld
); 
1210 void wxWindowMSW::MSWUpdateStyle(long flagsOld
, long exflagsOld
) 
1212     // now update the Windows style as well if needed - and if the window had 
1213     // been already created 
1217     // we may need to call SetWindowPos() when we change some styles 
1218     bool callSWP 
= false; 
1221     long style 
= MSWGetStyle(GetWindowStyleFlag(), &exstyle
); 
1223     // this is quite a horrible hack but we need it because MSWGetStyle() 
1224     // doesn't take exflags as parameter but uses GetExtraStyle() internally 
1225     // and so we have to modify the window exflags temporarily to get the 
1226     // correct exstyleOld 
1227     long exflagsNew 
= GetExtraStyle(); 
1228     wxWindowBase::SetExtraStyle(exflagsOld
); 
1231     long styleOld 
= MSWGetStyle(flagsOld
, &exstyleOld
); 
1233     wxWindowBase::SetExtraStyle(exflagsNew
); 
1236     if ( style 
!= styleOld 
) 
1238         // some flags (e.g. WS_VISIBLE or WS_DISABLED) should not be changed by 
1239         // this function so instead of simply setting the style to the new 
1240         // value we clear the bits which were set in styleOld but are set in 
1241         // the new one and set the ones which were not set before 
1242         long styleReal 
= ::GetWindowLong(GetHwnd(), GWL_STYLE
); 
1243         styleReal 
&= ~styleOld
; 
1246         ::SetWindowLong(GetHwnd(), GWL_STYLE
, styleReal
); 
1248         // we need to call SetWindowPos() if any of the styles affecting the 
1249         // frame appearance have changed 
1250         callSWP 
= ((styleOld 
^ style 
) & (WS_BORDER 
| 
1259     // and the extended style 
1260     long exstyleReal 
= ::GetWindowLong(GetHwnd(), GWL_EXSTYLE
); 
1262     if ( exstyle 
!= exstyleOld 
) 
1264         exstyleReal 
&= ~exstyleOld
; 
1265         exstyleReal 
|= exstyle
; 
1267         ::SetWindowLong(GetHwnd(), GWL_EXSTYLE
, exstyleReal
); 
1269         // ex style changes don't take effect without calling SetWindowPos 
1275         // we must call SetWindowPos() to flush the cached extended style and 
1276         // also to make the change to wxSTAY_ON_TOP style take effect: just 
1277         // setting the style simply doesn't work 
1278         if ( !::SetWindowPos(GetHwnd(), 
1279                              exstyleReal 
& WS_EX_TOPMOST 
? HWND_TOPMOST
 
1282                              SWP_NOMOVE 
| SWP_NOSIZE 
| SWP_FRAMECHANGED
) ) 
1284             wxLogLastError(_T("SetWindowPos")); 
1289 wxBorder 
wxWindowMSW::GetDefaultBorderForControl() const 
1291     // we want to automatically give controls a sunken style (confusingly, 
1292     // it may not really mean sunken at all as we map it to WS_EX_CLIENTEDGE 
1293     // which is not sunken at all under Windows XP -- rather, just the default) 
1295 #if defined(__POCKETPC__) || defined(__SMARTPHONE__) 
1296     return wxBORDER_SIMPLE
; 
1299     if (CanApplyThemeBorder()) 
1301         wxUxThemeEngine
* theme 
= wxUxThemeEngine::GetIfActive(); 
1303             return wxBORDER_THEME
; 
1306     return wxBORDER_SUNKEN
; 
1310 wxBorder 
wxWindowMSW::GetDefaultBorder() const 
1312     return GetDefaultBorderForControl(); 
1315 WXDWORD 
wxWindowMSW::MSWGetStyle(long flags
, WXDWORD 
*exstyle
) const 
1317     // translate common wxWidgets styles to Windows ones 
1319     // most of windows are child ones, those which are not (such as 
1320     // wxTopLevelWindow) should remove WS_CHILD in their MSWGetStyle() 
1321     WXDWORD style 
= WS_CHILD
; 
1323     // using this flag results in very significant reduction in flicker, 
1324     // especially with controls inside the static boxes (as the interior of the 
1325     // box is not redrawn twice), but sometimes results in redraw problems, so 
1326     // optionally allow the old code to continue to use it provided a special 
1327     // system option is turned on 
1328     if ( !wxSystemOptions::GetOptionInt(wxT("msw.window.no-clip-children")) 
1329             || (flags 
& wxCLIP_CHILDREN
) ) 
1330         style 
|= WS_CLIPCHILDREN
; 
1332     // it doesn't seem useful to use WS_CLIPSIBLINGS here as we officially 
1333     // don't support overlapping windows and it only makes sense for them and, 
1334     // presumably, gives the system some extra work (to manage more clipping 
1335     // regions), so avoid it alltogether 
1338     if ( flags 
& wxVSCROLL 
) 
1339         style 
|= WS_VSCROLL
; 
1341     if ( flags 
& wxHSCROLL 
) 
1342         style 
|= WS_HSCROLL
; 
1344     const wxBorder border 
= GetBorder(flags
); 
1346     // WS_BORDER is only required for wxBORDER_SIMPLE 
1347     if ( border 
== wxBORDER_SIMPLE 
) 
1350     // now deal with ext style if the caller wants it 
1356         if ( flags 
& wxTRANSPARENT_WINDOW 
) 
1357             *exstyle 
|= WS_EX_TRANSPARENT
; 
1362             case wxBORDER_DEFAULT
: // also wxBORDER_THEME 
1366             case wxBORDER_SIMPLE
: 
1369             case wxBORDER_STATIC
: 
1370                 *exstyle 
|= WS_EX_STATICEDGE
; 
1373             case wxBORDER_RAISED
: 
1374                 *exstyle 
|= WS_EX_DLGMODALFRAME
; 
1377             case wxBORDER_SUNKEN
: 
1378                 *exstyle 
|= WS_EX_CLIENTEDGE
; 
1379                 style 
&= ~WS_BORDER
; 
1383                 wxFAIL_MSG( _T("unknown border style") ); 
1386             case wxBORDER_DOUBLE
: 
1387                 *exstyle 
|= WS_EX_DLGMODALFRAME
; 
1391         // wxUniv doesn't use Windows dialog navigation functions at all 
1392 #if !defined(__WXUNIVERSAL__) && !defined(__WXWINCE__) 
1393         // to make the dialog navigation work with the nested panels we must 
1394         // use this style (top level windows such as dialogs don't need it) 
1395         if ( (flags 
& wxTAB_TRAVERSAL
) && !IsTopLevel() ) 
1397             *exstyle 
|= WS_EX_CONTROLPARENT
; 
1399 #endif // __WXUNIVERSAL__ 
1405 // Setup background and foreground colours correctly 
1406 void wxWindowMSW::SetupColours() 
1409         SetBackgroundColour(GetParent()->GetBackgroundColour()); 
1412 bool wxWindowMSW::IsMouseInWindow() const 
1414     // get the mouse position 
1417     ::GetCursorPosWinCE(&pt
); 
1419     ::GetCursorPos(&pt
); 
1422     // find the window which currently has the cursor and go up the window 
1423     // chain until we find this window - or exhaust it 
1424     HWND hwnd 
= ::WindowFromPoint(pt
); 
1425     while ( hwnd 
&& (hwnd 
!= GetHwnd()) ) 
1426         hwnd 
= ::GetParent(hwnd
); 
1428     return hwnd 
!= NULL
; 
1431 void wxWindowMSW::OnInternalIdle() 
1433 #ifndef HAVE_TRACKMOUSEEVENT 
1434     // Check if we need to send a LEAVE event 
1435     if ( m_mouseInWindow 
) 
1437         // note that we should generate the leave event whether the window has 
1438         // or doesn't have mouse capture 
1439         if ( !IsMouseInWindow() ) 
1441             GenerateMouseLeave(); 
1444 #endif // !HAVE_TRACKMOUSEEVENT 
1446     if (wxUpdateUIEvent::CanUpdate(this)) 
1447         UpdateWindowUI(wxUPDATE_UI_FROMIDLE
); 
1450 // Set this window to be the child of 'parent'. 
1451 bool wxWindowMSW::Reparent(wxWindowBase 
*parent
) 
1453     if ( !wxWindowBase::Reparent(parent
) ) 
1456     HWND hWndChild 
= GetHwnd(); 
1457     HWND hWndParent 
= GetParent() ? GetWinHwnd(GetParent()) : (HWND
)0; 
1459     ::SetParent(hWndChild
, hWndParent
); 
1462     if ( ::GetWindowLong(hWndChild
, GWL_EXSTYLE
) & WS_EX_CONTROLPARENT 
) 
1464         EnsureParentHasControlParentStyle(GetParent()); 
1466 #endif // !__WXWINCE__ 
1471 static inline void SendSetRedraw(HWND hwnd
, bool on
) 
1473 #ifndef __WXMICROWIN__ 
1474     ::SendMessage(hwnd
, WM_SETREDRAW
, (WPARAM
)on
, 0); 
1478 void wxWindowMSW::Freeze() 
1480     if ( !m_frozenness
++ ) 
1483             SendSetRedraw(GetHwnd(), false); 
1487 void wxWindowMSW::Thaw() 
1489     wxASSERT_MSG( m_frozenness 
> 0, _T("Thaw() without matching Freeze()") ); 
1491     if ( --m_frozenness 
== 0 ) 
1495             SendSetRedraw(GetHwnd(), true); 
1497             // we need to refresh everything or otherwise the invalidated area 
1498             // is not going to be repainted 
1504 void wxWindowMSW::Refresh(bool eraseBack
, const wxRect 
*rect
) 
1506     HWND hWnd 
= GetHwnd(); 
1513             wxCopyRectToRECT(*rect
, mswRect
); 
1521         // RedrawWindow not available on SmartPhone or eVC++ 3 
1522 #if !defined(__SMARTPHONE__) && !(defined(_WIN32_WCE) && _WIN32_WCE < 400) 
1523         UINT flags 
= RDW_INVALIDATE 
| RDW_ALLCHILDREN
; 
1527         ::RedrawWindow(hWnd
, pRect
, NULL
, flags
); 
1529         ::InvalidateRect(hWnd
, pRect
, eraseBack
); 
1534 void wxWindowMSW::Update() 
1536     if ( !::UpdateWindow(GetHwnd()) ) 
1538         wxLogLastError(_T("UpdateWindow")); 
1541 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__) 
1542     // just calling UpdateWindow() is not enough, what we did in our WM_PAINT 
1543     // handler needs to be really drawn right now 
1548 // --------------------------------------------------------------------------- 
1550 // --------------------------------------------------------------------------- 
1552 #if wxUSE_DRAG_AND_DROP || !defined(__WXWINCE__) 
1556 // we need to lower the sibling static boxes so controls contained within can be 
1558 static void AdjustStaticBoxZOrder(wxWindow 
*parent
) 
1560     // no sibling static boxes if we have no parent (ie TLW) 
1564     for ( wxWindowList::compatibility_iterator node 
= parent
->GetChildren().GetFirst(); 
1566           node 
= node
->GetNext() ) 
1568         wxStaticBox 
*statbox 
= wxDynamicCast(node
->GetData(), wxStaticBox
); 
1571             ::SetWindowPos(GetHwndOf(statbox
), HWND_BOTTOM
, 0, 0, 0, 0, 
1572                            SWP_NOMOVE 
| SWP_NOSIZE 
| SWP_NOACTIVATE
); 
1577 #else // !wxUSE_STATBOX 
1579 static inline void AdjustStaticBoxZOrder(wxWindow 
* WXUNUSED(parent
)) 
1583 #endif // wxUSE_STATBOX/!wxUSE_STATBOX 
1585 #endif // drag and drop is used 
1587 #if wxUSE_DRAG_AND_DROP 
1588 void wxWindowMSW::SetDropTarget(wxDropTarget 
*pDropTarget
) 
1590     if ( m_dropTarget 
!= 0 ) { 
1591         m_dropTarget
->Revoke(m_hWnd
); 
1592         delete m_dropTarget
; 
1595     m_dropTarget 
= pDropTarget
; 
1596     if ( m_dropTarget 
!= 0 ) 
1598         AdjustStaticBoxZOrder(GetParent()); 
1599         m_dropTarget
->Register(m_hWnd
); 
1602 #endif // wxUSE_DRAG_AND_DROP 
1604 // old-style file manager drag&drop support: we retain the old-style 
1605 // DragAcceptFiles in parallel with SetDropTarget. 
1606 void wxWindowMSW::DragAcceptFiles(bool WXUNUSED_IN_WINCE(accept
)) 
1609     HWND hWnd 
= GetHwnd(); 
1612         AdjustStaticBoxZOrder(GetParent()); 
1613         ::DragAcceptFiles(hWnd
, (BOOL
)accept
); 
1618 // ---------------------------------------------------------------------------- 
1620 // ---------------------------------------------------------------------------- 
1624 void wxWindowMSW::DoSetToolTip(wxToolTip 
*tooltip
) 
1626     wxWindowBase::DoSetToolTip(tooltip
); 
1629         m_tooltip
->SetWindow((wxWindow 
*)this); 
1632 #endif // wxUSE_TOOLTIPS 
1634 // --------------------------------------------------------------------------- 
1635 // moving and resizing 
1636 // --------------------------------------------------------------------------- 
1638 bool wxWindowMSW::IsSizeDeferred() const 
1640 #if USE_DEFERRED_SIZING 
1641     if ( m_pendingPosition 
!= wxDefaultPosition 
|| 
1642          m_pendingSize     
!= wxDefaultSize 
) 
1644 #endif // USE_DEFERRED_SIZING 
1650 void wxWindowMSW::DoGetSize(int *x
, int *y
) const 
1652 #if USE_DEFERRED_SIZING 
1653     // if SetSize() had been called at wx level but not realized at Windows 
1654     // level yet (i.e. EndDeferWindowPos() not called), we still should return 
1655     // the new and not the old position to the other wx code 
1656     if ( m_pendingSize 
!= wxDefaultSize 
) 
1659             *x 
= m_pendingSize
.x
; 
1661             *y 
= m_pendingSize
.y
; 
1663     else // use current size 
1664 #endif // USE_DEFERRED_SIZING 
1666         RECT rect 
= wxGetWindowRect(GetHwnd()); 
1669             *x 
= rect
.right 
- rect
.left
; 
1671             *y 
= rect
.bottom 
- rect
.top
; 
1675 // Get size *available for subwindows* i.e. excluding menu bar etc. 
1676 void wxWindowMSW::DoGetClientSize(int *x
, int *y
) const 
1678 #if USE_DEFERRED_SIZING 
1679     if ( m_pendingSize 
!= wxDefaultSize 
) 
1681         // we need to calculate the client size corresponding to pending size 
1683         rect
.left 
= m_pendingPosition
.x
; 
1684         rect
.top 
= m_pendingPosition
.y
; 
1685         rect
.right 
= rect
.left 
+ m_pendingSize
.x
; 
1686         rect
.bottom 
= rect
.top 
+ m_pendingSize
.y
; 
1688         ::SendMessage(GetHwnd(), WM_NCCALCSIZE
, FALSE
, (LPARAM
)&rect
); 
1691             *x 
= rect
.right 
- rect
.left
; 
1693             *y 
= rect
.bottom 
- rect
.top
; 
1696 #endif // USE_DEFERRED_SIZING 
1698         RECT rect 
= wxGetClientRect(GetHwnd()); 
1707 void wxWindowMSW::DoGetPosition(int *x
, int *y
) const 
1709     wxWindow 
* const parent 
= GetParent(); 
1712     if ( m_pendingPosition 
!= wxDefaultPosition 
) 
1714         pos 
= m_pendingPosition
; 
1716     else // use current position 
1718         RECT rect 
= wxGetWindowRect(GetHwnd()); 
1721         point
.x 
= rect
.left
; 
1724         // we do the adjustments with respect to the parent only for the "real" 
1725         // children, not for the dialogs/frames 
1726         if ( !IsTopLevel() ) 
1728             if ( wxTheApp
->GetLayoutDirection() == wxLayout_RightToLeft 
) 
1730                 // In RTL mode, we want the logical left x-coordinate, 
1731                 // which would be the physical right x-coordinate. 
1732                 point
.x 
= rect
.right
; 
1735             // Since we now have the absolute screen coords, if there's a 
1736             // parent we must subtract its top left corner 
1739                 ::ScreenToClient(GetHwndOf(parent
), &point
); 
1747     // we also must adjust by the client area offset: a control which is just 
1748     // under a toolbar could be at (0, 30) in Windows but at (0, 0) in wx 
1749     if ( parent 
&& !IsTopLevel() ) 
1751         const wxPoint 
pt(parent
->GetClientAreaOrigin()); 
1762 void wxWindowMSW::DoScreenToClient(int *x
, int *y
) const 
1770     ::ScreenToClient(GetHwnd(), &pt
); 
1778 void wxWindowMSW::DoClientToScreen(int *x
, int *y
) const 
1786     ::ClientToScreen(GetHwnd(), &pt
); 
1795 wxWindowMSW::DoMoveSibling(WXHWND hwnd
, int x
, int y
, int width
, int height
) 
1797 #if USE_DEFERRED_SIZING 
1798     // if our parent had prepared a defer window handle for us, use it (unless 
1799     // we are a top level window) 
1800     wxWindowMSW 
* const parent 
= IsTopLevel() ? NULL 
: GetParent(); 
1802     HDWP hdwp 
= parent 
? (HDWP
)parent
->m_hDWP 
: NULL
; 
1805         hdwp 
= ::DeferWindowPos(hdwp
, (HWND
)hwnd
, NULL
, x
, y
, width
, height
, 
1806                                 SWP_NOZORDER 
| SWP_NOOWNERZORDER 
| SWP_NOACTIVATE
); 
1809             wxLogLastError(_T("DeferWindowPos")); 
1815         // hdwp must be updated as it may have been changed 
1816         parent
->m_hDWP 
= (WXHANDLE
)hdwp
; 
1821         // did deferred move, remember new coordinates of the window as they're 
1822         // different from what Windows would return for it 
1826     // otherwise (or if deferring failed) move the window in place immediately 
1827 #endif // USE_DEFERRED_SIZING 
1828     if ( !::MoveWindow((HWND
)hwnd
, x
, y
, width
, height
, IsShown()) ) 
1830         wxLogLastError(wxT("MoveWindow")); 
1833     // if USE_DEFERRED_SIZING, indicates that we didn't use deferred move, 
1834     // ignored otherwise 
1838 void wxWindowMSW::DoMoveWindow(int x
, int y
, int width
, int height
) 
1840     // TODO: is this consistent with other platforms? 
1841     // Still, negative width or height shouldn't be allowed 
1847     if ( DoMoveSibling(m_hWnd
, x
, y
, width
, height
) ) 
1849 #if USE_DEFERRED_SIZING 
1850         m_pendingPosition 
= wxPoint(x
, y
); 
1851         m_pendingSize 
= wxSize(width
, height
); 
1852 #endif // USE_DEFERRED_SIZING 
1856 // set the size of the window: if the dimensions are positive, just use them, 
1857 // but if any of them is equal to -1, it means that we must find the value for 
1858 // it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in 
1859 // which case -1 is a valid value for x and y) 
1861 // If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate 
1862 // the width/height to best suit our contents, otherwise we reuse the current 
1864 void wxWindowMSW::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
) 
1866     // get the current size and position... 
1867     int currentX
, currentY
; 
1868     int currentW
, currentH
; 
1870     GetPosition(¤tX
, ¤tY
); 
1871     GetSize(¤tW
, ¤tH
); 
1873     // ... and don't do anything (avoiding flicker) if it's already ok unless 
1874     // we're forced to resize the window 
1875     if ( x 
== currentX 
&& y 
== currentY 
&& 
1876          width 
== currentW 
&& height 
== currentH 
&& 
1877             !(sizeFlags 
& wxSIZE_FORCE
) ) 
1882     if ( x 
== wxDefaultCoord 
&& !(sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
) ) 
1884     if ( y 
== wxDefaultCoord 
&& !(sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
) ) 
1887     AdjustForParentClientOrigin(x
, y
, sizeFlags
); 
1889     wxSize size 
= wxDefaultSize
; 
1890     if ( width 
== wxDefaultCoord 
) 
1892         if ( sizeFlags 
& wxSIZE_AUTO_WIDTH 
) 
1894             size 
= DoGetBestSize(); 
1899             // just take the current one 
1904     if ( height 
== wxDefaultCoord 
) 
1906         if ( sizeFlags 
& wxSIZE_AUTO_HEIGHT 
) 
1908             if ( size
.x 
== wxDefaultCoord 
) 
1910                 size 
= DoGetBestSize(); 
1912             //else: already called DoGetBestSize() above 
1918             // just take the current one 
1923     DoMoveWindow(x
, y
, width
, height
); 
1926 void wxWindowMSW::DoSetClientSize(int width
, int height
) 
1928     // setting the client size is less obvious than it could have been 
1929     // because in the result of changing the total size the window scrollbar 
1930     // may [dis]appear and/or its menubar may [un]wrap (and AdjustWindowRect() 
1931     // doesn't take neither into account) and so the client size will not be 
1932     // correct as the difference between the total and client size changes -- 
1933     // so we keep changing it until we get it right 
1935     // normally this loop shouldn't take more than 3 iterations (usually 1 but 
1936     // if scrollbars [dis]appear as the result of the first call, then 2 and it 
1937     // may become 3 if the window had 0 size originally and so we didn't 
1938     // calculate the scrollbar correction correctly during the first iteration) 
1939     // but just to be on the safe side we check for it instead of making it an 
1940     // "infinite" loop (i.e. leaving break inside as the only way to get out) 
1941     for ( int i 
= 0; i 
< 4; i
++ ) 
1944         ::GetClientRect(GetHwnd(), &rectClient
); 
1946         // if the size is already ok, stop here (NB: rectClient.left = top = 0) 
1947         if ( (rectClient
.right 
== width 
|| width 
== wxDefaultCoord
) && 
1948              (rectClient
.bottom 
== height 
|| height 
== wxDefaultCoord
) ) 
1953         // Find the difference between the entire window (title bar and all) 
1954         // and the client area; add this to the new client size to move the 
1957         ::GetWindowRect(GetHwnd(), &rectWin
); 
1959         const int widthWin 
= rectWin
.right 
- rectWin
.left
, 
1960                   heightWin 
= rectWin
.bottom 
- rectWin
.top
; 
1962         // MoveWindow positions the child windows relative to the parent, so 
1963         // adjust if necessary 
1964         if ( !IsTopLevel() ) 
1966             wxWindow 
*parent 
= GetParent(); 
1969                 ::ScreenToClient(GetHwndOf(parent
), (POINT 
*)&rectWin
); 
1973         // don't call DoMoveWindow() because we want to move window immediately 
1974         // and not defer it here as otherwise the value returned by 
1975         // GetClient/WindowRect() wouldn't change as the window wouldn't be 
1977         if ( !::MoveWindow(GetHwnd(), 
1980                            width 
+ widthWin 
- rectClient
.right
, 
1981                            height 
+ heightWin 
- rectClient
.bottom
, 
1984             wxLogLastError(_T("MoveWindow")); 
1989 // --------------------------------------------------------------------------- 
1991 // --------------------------------------------------------------------------- 
1993 int wxWindowMSW::GetCharHeight() const 
1995     return wxGetTextMetrics(this).tmHeight
; 
1998 int wxWindowMSW::GetCharWidth() const 
2000     // +1 is needed because Windows apparently adds it when calculating the 
2001     // dialog units size in pixels 
2002 #if wxDIALOG_UNIT_COMPATIBILITY 
2003     return wxGetTextMetrics(this).tmAveCharWidth
; 
2005     return wxGetTextMetrics(this).tmAveCharWidth 
+ 1; 
2009 void wxWindowMSW::GetTextExtent(const wxString
& string
, 
2011                              int *descent
, int *externalLeading
, 
2012                              const wxFont 
*theFont
) const 
2014     wxASSERT_MSG( !theFont 
|| theFont
->Ok(), 
2015                     _T("invalid font in GetTextExtent()") ); 
2019         fontToUse 
= *theFont
; 
2021         fontToUse 
= GetFont(); 
2023     WindowHDC 
hdc(GetHwnd()); 
2024     SelectInHDC 
selectFont(hdc
, GetHfontOf(fontToUse
)); 
2028     ::GetTextExtentPoint32(hdc
, string
.wx_str(), string
.length(), &sizeRect
); 
2029     GetTextMetrics(hdc
, &tm
); 
2036         *descent 
= tm
.tmDescent
; 
2037     if ( externalLeading 
) 
2038         *externalLeading 
= tm
.tmExternalLeading
; 
2041 // --------------------------------------------------------------------------- 
2043 // --------------------------------------------------------------------------- 
2045 #if wxUSE_MENUS_NATIVE 
2047 // yield for WM_COMMAND events only, i.e. process all WM_COMMANDs in the queue 
2048 // immediately, without waiting for the next event loop iteration 
2050 // NB: this function should probably be made public later as it can almost 
2051 //     surely replace wxYield() elsewhere as well 
2052 static void wxYieldForCommandsOnly() 
2054     // peek all WM_COMMANDs (it will always return WM_QUIT too but we don't 
2055     // want to process it here) 
2057     while ( ::PeekMessage(&msg
, (HWND
)0, WM_COMMAND
, WM_COMMAND
, PM_REMOVE
) ) 
2059         if ( msg
.message 
== WM_QUIT 
) 
2061             // if we retrieved a WM_QUIT, insert back into the message queue. 
2062             ::PostQuitMessage(0); 
2066         // luckily (as we don't have access to wxEventLoopImpl method from here 
2067         // anyhow...) we don't need to pre process WM_COMMANDs so dispatch it 
2069         ::TranslateMessage(&msg
); 
2070         ::DispatchMessage(&msg
); 
2074 bool wxWindowMSW::DoPopupMenu(wxMenu 
*menu
, int x
, int y
) 
2076     menu
->SetInvokingWindow(this); 
2079     if ( x 
== wxDefaultCoord 
&& y 
== wxDefaultCoord 
) 
2081         wxPoint mouse 
= ScreenToClient(wxGetMousePosition()); 
2082         x 
= mouse
.x
; y 
= mouse
.y
; 
2085     HWND hWnd 
= GetHwnd(); 
2086     HMENU hMenu 
= GetHmenuOf(menu
); 
2090     ::ClientToScreen(hWnd
, &point
); 
2091     wxCurrentPopupMenu 
= menu
; 
2092 #if defined(__WXWINCE__) 
2093     static const UINT flags 
= 0; 
2094 #else // !__WXWINCE__ 
2095     UINT flags 
= TPM_RIGHTBUTTON
; 
2096     // NT4 doesn't support TPM_RECURSE and simply doesn't show the menu at all 
2097     // when it's use, I'm not sure about Win95/98 but prefer to err on the safe 
2098     // side and not to use it there neither -- modify the test if it does work 
2100     if ( wxGetWinVersion() >= wxWinVersion_5 
) 
2102         // using TPM_RECURSE allows us to show a popup menu while another menu 
2103         // is opened which can be useful and is supported by the other 
2104         // platforms, so allow it under Windows too 
2105         flags 
|= TPM_RECURSE
; 
2107 #endif // __WXWINCE__/!__WXWINCE__ 
2109     ::TrackPopupMenu(hMenu
, flags
, point
.x
, point
.y
, 0, hWnd
, NULL
); 
2111     // we need to do it right now as otherwise the events are never going to be 
2112     // sent to wxCurrentPopupMenu from HandleCommand() 
2114     // note that even eliminating (ugly) wxCurrentPopupMenu global wouldn't 
2115     // help and we'd still need wxYieldForCommandsOnly() as the menu may be 
2116     // destroyed as soon as we return (it can be a local variable in the caller 
2117     // for example) and so we do need to process the event immediately 
2118     wxYieldForCommandsOnly(); 
2120     wxCurrentPopupMenu 
= NULL
; 
2122     menu
->SetInvokingWindow(NULL
); 
2127 #endif // wxUSE_MENUS_NATIVE 
2129 // =========================================================================== 
2130 // pre/post message processing 
2131 // =========================================================================== 
2133 WXLRESULT 
wxWindowMSW::MSWDefWindowProc(WXUINT nMsg
, WXWPARAM wParam
, WXLPARAM lParam
) 
2136         return ::CallWindowProc(CASTWNDPROC m_oldWndProc
, GetHwnd(), (UINT
) nMsg
, (WPARAM
) wParam
, (LPARAM
) lParam
); 
2138         return ::DefWindowProc(GetHwnd(), nMsg
, wParam
, lParam
); 
2141 bool wxWindowMSW::MSWProcessMessage(WXMSG
* pMsg
) 
2143     // wxUniversal implements tab traversal itself 
2144 #ifndef __WXUNIVERSAL__ 
2145     if ( m_hWnd 
!= 0 && (GetWindowStyleFlag() & wxTAB_TRAVERSAL
) ) 
2147         // intercept dialog navigation keys 
2148         MSG 
*msg 
= (MSG 
*)pMsg
; 
2150         // here we try to do all the job which ::IsDialogMessage() usually does 
2152         if ( msg
->message 
== WM_KEYDOWN 
) 
2154             bool bCtrlDown 
= wxIsCtrlDown(); 
2155             bool bShiftDown 
= wxIsShiftDown(); 
2157             // WM_GETDLGCODE: ask the control if it wants the key for itself, 
2158             // don't process it if it's the case (except for Ctrl-Tab/Enter 
2159             // combinations which are always processed) 
2160             LONG lDlgCode 
= ::SendMessage(msg
->hwnd
, WM_GETDLGCODE
, 0, 0); 
2162             // surprizingly, DLGC_WANTALLKEYS bit mask doesn't contain the 
2163             // DLGC_WANTTAB nor DLGC_WANTARROWS bits although, logically, 
2164             // it, of course, implies them 
2165             if ( lDlgCode 
& DLGC_WANTALLKEYS 
) 
2167                 lDlgCode 
|= DLGC_WANTTAB 
| DLGC_WANTARROWS
; 
2170             bool bForward 
= true, 
2171                  bWindowChange 
= false, 
2174             // should we process this message specially? 
2175             bool bProcess 
= true; 
2176             switch ( msg
->wParam 
) 
2179                     if ( (lDlgCode 
& DLGC_WANTTAB
) && !bCtrlDown 
) 
2181                         // let the control have the TAB 
2184                     else // use it for navigation 
2186                         // Ctrl-Tab cycles thru notebook pages 
2187                         bWindowChange 
= bCtrlDown
; 
2188                         bForward 
= !bShiftDown
; 
2195                     if ( (lDlgCode 
& DLGC_WANTARROWS
) || bCtrlDown 
) 
2203                     if ( (lDlgCode 
& DLGC_WANTARROWS
) || bCtrlDown 
) 
2212                     // we treat PageUp/Dn as arrows because chances are that 
2213                     // a control which needs arrows also needs them for 
2214                     // navigation (e.g. wxTextCtrl, wxListCtrl, ...) 
2215                     if ( (lDlgCode 
& DLGC_WANTARROWS
) && !bCtrlDown 
) 
2217                     else // OTOH Ctrl-PageUp/Dn works as [Shift-]Ctrl-Tab 
2218                         bWindowChange 
= true; 
2223                         if ( (lDlgCode 
& DLGC_WANTMESSAGE
) && !bCtrlDown 
) 
2225                             // control wants to process Enter itself, don't 
2226                             // call IsDialogMessage() which would consume it 
2231                         // currently active button should get enter press even 
2232                         // if there is a default button elsewhere so check if 
2233                         // this window is a button first 
2234                         wxWindow 
*btn 
= NULL
; 
2235                         if ( lDlgCode 
& DLGC_DEFPUSHBUTTON 
) 
2237                             // let IsDialogMessage() handle this for all 
2238                             // buttons except the owner-drawn ones which it 
2239                             // just seems to ignore 
2240                             long style 
= ::GetWindowLong(msg
->hwnd
, GWL_STYLE
); 
2241                             if ( (style 
& BS_OWNERDRAW
) == BS_OWNERDRAW 
) 
2243                                 // emulate the button click 
2244                                 btn 
= wxFindWinFromHandle((WXHWND
)msg
->hwnd
); 
2249                         else // not a button itself, do we have default button? 
2252                                 tlw 
= wxDynamicCast(wxGetTopLevelParent(this), 
2256                                 btn 
= wxDynamicCast(tlw
->GetDefaultItem(), 
2261                         if ( btn 
&& btn
->IsEnabled() ) 
2263                             btn
->MSWCommand(BN_CLICKED
, 0 /* unused */); 
2267 #endif // wxUSE_BUTTON 
2270                         // map Enter presses into button presses on PDAs 
2271                         wxJoystickEvent 
event(wxEVT_JOY_BUTTON_DOWN
); 
2272                         event
.SetEventObject(this); 
2273                         if ( GetEventHandler()->ProcessEvent(event
) ) 
2275 #endif // __WXWINCE__ 
2285                 wxNavigationKeyEvent event
; 
2286                 event
.SetDirection(bForward
); 
2287                 event
.SetWindowChange(bWindowChange
); 
2288                 event
.SetFromTab(bFromTab
); 
2289                 event
.SetEventObject(this); 
2291                 if ( GetEventHandler()->ProcessEvent(event
) ) 
2293                     // as we don't call IsDialogMessage(), which would take of 
2294                     // this by default, we need to manually send this message 
2295                     // so that controls can change their UI state if needed 
2296                     MSWUpdateUIState(UIS_CLEAR
, UISF_HIDEFOCUS
); 
2303         if ( ::IsDialogMessage(GetHwnd(), msg
) ) 
2305             // IsDialogMessage() did something... 
2309 #endif // __WXUNIVERSAL__ 
2314         // relay mouse move events to the tooltip control 
2315         MSG 
*msg 
= (MSG 
*)pMsg
; 
2316         if ( msg
->message 
== WM_MOUSEMOVE 
) 
2317             wxToolTip::RelayEvent(pMsg
); 
2319 #endif // wxUSE_TOOLTIPS 
2324 bool wxWindowMSW::MSWTranslateMessage(WXMSG
* pMsg
) 
2326 #if wxUSE_ACCEL && !defined(__WXUNIVERSAL__) 
2327     return m_acceleratorTable
.Translate(this, pMsg
); 
2331 #endif // wxUSE_ACCEL 
2334 bool wxWindowMSW::MSWShouldPreProcessMessage(WXMSG
* msg
) 
2336     // all tests below have to deal with various bugs/misfeatures of 
2337     // IsDialogMessage(): we have to prevent it from being called from our 
2338     // MSWProcessMessage() in some situations 
2340     // don't let IsDialogMessage() get VK_ESCAPE as it _always_ eats the 
2341     // message even when there is no cancel button and when the message is 
2342     // needed by the control itself: in particular, it prevents the tree in 
2343     // place edit control from being closed with Escape in a dialog 
2344     if ( msg
->message 
== WM_KEYDOWN 
&& msg
->wParam 
== VK_ESCAPE 
) 
2349     // ::IsDialogMessage() is broken and may sometimes hang the application by 
2350     // going into an infinite loop when it tries to find the control to give 
2351     // focus to when Alt-<key> is pressed, so we try to detect [some of] the 
2352     // situations when this may happen and not call it then 
2353     if ( msg
->message 
!= WM_SYSCHAR 
) 
2356     // assume we can call it by default 
2357     bool canSafelyCallIsDlgMsg 
= true; 
2359     HWND hwndFocus 
= ::GetFocus(); 
2361     // if the currently focused window itself has WS_EX_CONTROLPARENT style, 
2362     // ::IsDialogMessage() will also enter an infinite loop, because it will 
2363     // recursively check the child windows but not the window itself and so if 
2364     // none of the children accepts focus it loops forever (as it only stops 
2365     // when it gets back to the window it started from) 
2367     // while it is very unusual that a window with WS_EX_CONTROLPARENT 
2368     // style has the focus, it can happen. One such possibility is if 
2369     // all windows are either toplevel, wxDialog, wxPanel or static 
2370     // controls and no window can actually accept keyboard input. 
2371 #if !defined(__WXWINCE__) 
2372     if ( ::GetWindowLong(hwndFocus
, GWL_EXSTYLE
) & WS_EX_CONTROLPARENT 
) 
2374         // pessimistic by default 
2375         canSafelyCallIsDlgMsg 
= false; 
2376         for ( wxWindowList::compatibility_iterator node 
= GetChildren().GetFirst(); 
2378               node 
= node
->GetNext() ) 
2380             wxWindow 
* const win 
= node
->GetData(); 
2381             if ( win
->CanAcceptFocus() && 
2382                     !(::GetWindowLong(GetHwndOf(win
), GWL_EXSTYLE
) & 
2383                         WS_EX_CONTROLPARENT
) ) 
2385                 // it shouldn't hang... 
2386                 canSafelyCallIsDlgMsg 
= true; 
2392 #endif // !__WXWINCE__ 
2394     if ( canSafelyCallIsDlgMsg 
) 
2396         // ::IsDialogMessage() can enter in an infinite loop when the 
2397         // currently focused window is disabled or hidden and its 
2398         // parent has WS_EX_CONTROLPARENT style, so don't call it in 
2402             if ( !::IsWindowEnabled(hwndFocus
) || 
2403                     !::IsWindowVisible(hwndFocus
) ) 
2405                 // it would enter an infinite loop if we do this! 
2406                 canSafelyCallIsDlgMsg 
= false; 
2411             if ( !(::GetWindowLong(hwndFocus
, GWL_STYLE
) & WS_CHILD
) ) 
2413                 // it's a top level window, don't go further -- e.g. even 
2414                 // if the parent of a dialog is disabled, this doesn't 
2415                 // break navigation inside the dialog 
2419             hwndFocus 
= ::GetParent(hwndFocus
); 
2423     return canSafelyCallIsDlgMsg
; 
2426 // --------------------------------------------------------------------------- 
2427 // message params unpackers 
2428 // --------------------------------------------------------------------------- 
2430 void wxWindowMSW::UnpackCommand(WXWPARAM wParam
, WXLPARAM lParam
, 
2431                              WORD 
*id
, WXHWND 
*hwnd
, WORD 
*cmd
) 
2433     *id 
= LOWORD(wParam
); 
2434     *hwnd 
= (WXHWND
)lParam
; 
2435     *cmd 
= HIWORD(wParam
); 
2438 void wxWindowMSW::UnpackActivate(WXWPARAM wParam
, WXLPARAM lParam
, 
2439                               WXWORD 
*state
, WXWORD 
*minimized
, WXHWND 
*hwnd
) 
2441     *state 
= LOWORD(wParam
); 
2442     *minimized 
= HIWORD(wParam
); 
2443     *hwnd 
= (WXHWND
)lParam
; 
2446 void wxWindowMSW::UnpackScroll(WXWPARAM wParam
, WXLPARAM lParam
, 
2447                             WXWORD 
*code
, WXWORD 
*pos
, WXHWND 
*hwnd
) 
2449     *code 
= LOWORD(wParam
); 
2450     *pos 
= HIWORD(wParam
); 
2451     *hwnd 
= (WXHWND
)lParam
; 
2454 void wxWindowMSW::UnpackCtlColor(WXWPARAM wParam
, WXLPARAM lParam
, 
2455                                  WXHDC 
*hdc
, WXHWND 
*hwnd
) 
2457     *hwnd 
= (WXHWND
)lParam
; 
2458     *hdc 
= (WXHDC
)wParam
; 
2461 void wxWindowMSW::UnpackMenuSelect(WXWPARAM wParam
, WXLPARAM lParam
, 
2462                                 WXWORD 
*item
, WXWORD 
*flags
, WXHMENU 
*hmenu
) 
2464     *item 
= (WXWORD
)wParam
; 
2465     *flags 
= HIWORD(wParam
); 
2466     *hmenu 
= (WXHMENU
)lParam
; 
2469 // --------------------------------------------------------------------------- 
2470 // Main wxWidgets window proc and the window proc for wxWindow 
2471 // --------------------------------------------------------------------------- 
2473 // Hook for new window just as it's being created, when the window isn't yet 
2474 // associated with the handle 
2475 static wxWindowMSW 
*gs_winBeingCreated 
= NULL
; 
2477 // implementation of wxWindowCreationHook class: it just sets gs_winBeingCreated to the 
2478 // window being created and insures that it's always unset back later 
2479 wxWindowCreationHook::wxWindowCreationHook(wxWindowMSW 
*winBeingCreated
) 
2481     gs_winBeingCreated 
= winBeingCreated
; 
2484 wxWindowCreationHook::~wxWindowCreationHook() 
2486     gs_winBeingCreated 
= NULL
; 
2490 LRESULT WXDLLEXPORT APIENTRY _EXPORT 
wxWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
) 
2492     // trace all messages - useful for the debugging 
2494     wxLogTrace(wxTraceMessages
, 
2495                wxT("Processing %s(hWnd=%08lx, wParam=%8lx, lParam=%8lx)"), 
2496                wxGetMessageName(message
), (long)hWnd
, (long)wParam
, lParam
); 
2497 #endif // __WXDEBUG__ 
2499     wxWindowMSW 
*wnd 
= wxFindWinFromHandle((WXHWND
) hWnd
); 
2501     // when we get the first message for the HWND we just created, we associate 
2502     // it with wxWindow stored in gs_winBeingCreated 
2503     if ( !wnd 
&& gs_winBeingCreated 
) 
2505         wxAssociateWinWithHandle(hWnd
, gs_winBeingCreated
); 
2506         wnd 
= gs_winBeingCreated
; 
2507         gs_winBeingCreated 
= NULL
; 
2508         wnd
->SetHWND((WXHWND
)hWnd
); 
2513     if ( wnd 
&& wxGUIEventLoop::AllowProcessing(wnd
) ) 
2514         rc 
= wnd
->MSWWindowProc(message
, wParam
, lParam
); 
2516         rc 
= ::DefWindowProc(hWnd
, message
, wParam
, lParam
); 
2521 WXLRESULT 
wxWindowMSW::MSWWindowProc(WXUINT message
, WXWPARAM wParam
, WXLPARAM lParam
) 
2523     // did we process the message? 
2524     bool processed 
= false; 
2534     // for most messages we should return 0 when we do process the message 
2542                 processed 
= HandleCreate((WXLPCREATESTRUCT
)lParam
, &mayCreate
); 
2545                     // return 0 to allow window creation 
2546                     rc
.result 
= mayCreate 
? 0 : -1; 
2552             // never set processed to true and *always* pass WM_DESTROY to 
2553             // DefWindowProc() as Windows may do some internal cleanup when 
2554             // processing it and failing to pass the message along may cause 
2555             // memory and resource leaks! 
2556             (void)HandleDestroy(); 
2560             processed 
= HandleSize(LOWORD(lParam
), HIWORD(lParam
), wParam
); 
2564             processed 
= HandleMove(GET_X_LPARAM(lParam
), GET_Y_LPARAM(lParam
)); 
2567 #if !defined(__WXWINCE__) 
2570                 LPRECT pRect 
= (LPRECT
)lParam
; 
2572                 rc
.SetLeft(pRect
->left
); 
2573                 rc
.SetTop(pRect
->top
); 
2574                 rc
.SetRight(pRect
->right
); 
2575                 rc
.SetBottom(pRect
->bottom
); 
2576                 processed 
= HandleMoving(rc
); 
2578                     pRect
->left 
= rc
.GetLeft(); 
2579                     pRect
->top 
= rc
.GetTop(); 
2580                     pRect
->right 
= rc
.GetRight(); 
2581                     pRect
->bottom 
= rc
.GetBottom(); 
2586         case WM_ENTERSIZEMOVE
: 
2588                 processed 
= HandleEnterSizeMove(); 
2592         case WM_EXITSIZEMOVE
: 
2594                 processed 
= HandleExitSizeMove(); 
2600                 LPRECT pRect 
= (LPRECT
)lParam
; 
2602                 rc
.SetLeft(pRect
->left
); 
2603                 rc
.SetTop(pRect
->top
); 
2604                 rc
.SetRight(pRect
->right
); 
2605                 rc
.SetBottom(pRect
->bottom
); 
2606                 processed 
= HandleSizing(rc
); 
2608                     pRect
->left 
= rc
.GetLeft(); 
2609                     pRect
->top 
= rc
.GetTop(); 
2610                     pRect
->right 
= rc
.GetRight(); 
2611                     pRect
->bottom 
= rc
.GetBottom(); 
2615 #endif // !__WXWINCE__ 
2617 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__) 
2618         case WM_ACTIVATEAPP
: 
2619             // This implicitly sends a wxEVT_ACTIVATE_APP event 
2620             wxTheApp
->SetActive(wParam 
!= 0, FindFocus()); 
2626                 WXWORD state
, minimized
; 
2628                 UnpackActivate(wParam
, lParam
, &state
, &minimized
, &hwnd
); 
2630                 processed 
= HandleActivate(state
, minimized 
!= 0, (WXHWND
)hwnd
); 
2635             processed 
= HandleSetFocus((WXHWND
)(HWND
)wParam
); 
2639             processed 
= HandleKillFocus((WXHWND
)(HWND
)wParam
); 
2642         case WM_PRINTCLIENT
: 
2643             processed 
= HandlePrintClient((WXHDC
)wParam
); 
2649                 wxPaintDCEx 
dc((wxWindow 
*)this, (WXHDC
)wParam
); 
2651                 processed 
= HandlePaint(); 
2655                 processed 
= HandlePaint(); 
2660 #ifdef __WXUNIVERSAL__ 
2661             // Universal uses its own wxFrame/wxDialog, so we don't receive 
2662             // close events unless we have this. 
2664 #endif // __WXUNIVERSAL__ 
2666             // don't let the DefWindowProc() destroy our window - we'll do it 
2667             // ourselves in ~wxWindow 
2673             processed 
= HandleShow(wParam 
!= 0, (int)lParam
); 
2677             processed 
= HandleMouseMove(GET_X_LPARAM(lParam
), 
2678                                         GET_Y_LPARAM(lParam
), 
2682 #ifdef HAVE_TRACKMOUSEEVENT 
2684             // filter out excess WM_MOUSELEAVE events sent after PopupMenu() 
2686             if ( m_mouseInWindow 
) 
2688                 GenerateMouseLeave(); 
2691             // always pass processed back as false, this allows the window 
2692             // manager to process the message too.  This is needed to 
2693             // ensure windows XP themes work properly as the mouse moves 
2694             // over widgets like buttons. So don't set processed to true here. 
2696 #endif // HAVE_TRACKMOUSEEVENT 
2698 #if wxUSE_MOUSEWHEEL 
2700             processed 
= HandleMouseWheel(wParam
, lParam
); 
2704         case WM_LBUTTONDOWN
: 
2706         case WM_LBUTTONDBLCLK
: 
2707         case WM_RBUTTONDOWN
: 
2709         case WM_RBUTTONDBLCLK
: 
2710         case WM_MBUTTONDOWN
: 
2712         case WM_MBUTTONDBLCLK
: 
2713 #ifdef wxHAS_XBUTTON 
2714         case WM_XBUTTONDOWN
: 
2716         case WM_XBUTTONDBLCLK
: 
2717 #endif // wxHAS_XBUTTON 
2719 #ifdef __WXMICROWIN__ 
2720                 // MicroWindows seems to ignore the fact that a window is 
2721                 // disabled. So catch mouse events and throw them away if 
2723                 wxWindowMSW
* win 
= this; 
2726                     if (!win
->IsEnabled()) 
2732                     win 
= win
->GetParent(); 
2733                     if ( !win 
|| win
->IsTopLevel() ) 
2740 #endif // __WXMICROWIN__ 
2741                 int x 
= GET_X_LPARAM(lParam
), 
2742                     y 
= GET_Y_LPARAM(lParam
); 
2745                 // redirect the event to a static control if necessary by 
2746                 // finding one under mouse because under CE the static controls 
2747                 // don't generate mouse events (even with SS_NOTIFY) 
2749                 if ( GetCapture() == this ) 
2751                     // but don't do it if the mouse is captured by this window 
2752                     // because then it should really get this event itself 
2757                     win 
= FindWindowForMouseEvent(this, &x
, &y
); 
2759                     // this should never happen 
2760                     wxCHECK_MSG( win
, 0, 
2761                                  _T("FindWindowForMouseEvent() returned NULL") ); 
2764                 if (IsContextMenuEnabled() && message 
== WM_LBUTTONDOWN
) 
2766                     SHRGINFO shrgi 
= {0}; 
2768                     shrgi
.cbSize 
= sizeof(SHRGINFO
); 
2769                     shrgi
.hwndClient 
= (HWND
) GetHWND(); 
2773                     shrgi
.dwFlags 
= SHRG_RETURNCMD
; 
2774                     // shrgi.dwFlags = SHRG_NOTIFYPARENT; 
2776                     if (GN_CONTEXTMENU 
== ::SHRecognizeGesture(&shrgi
)) 
2779                         pt 
= ClientToScreen(pt
); 
2781                         wxContextMenuEvent 
evtCtx(wxEVT_CONTEXT_MENU
, GetId(), pt
); 
2783                         evtCtx
.SetEventObject(this); 
2784                         if (GetEventHandler()->ProcessEvent(evtCtx
)) 
2793 #else // !__WXWINCE__ 
2794                 wxWindowMSW 
*win 
= this; 
2795 #endif // __WXWINCE__/!__WXWINCE__ 
2797                 processed 
= win
->HandleMouseEvent(message
, x
, y
, wParam
); 
2799                 // if the app didn't eat the event, handle it in the default 
2800                 // way, that is by giving this window the focus 
2803                     // for the standard classes their WndProc sets the focus to 
2804                     // them anyhow and doing it from here results in some weird 
2805                     // problems, so don't do it for them (unnecessary anyhow) 
2806                     if ( !win
->IsOfStandardClass() ) 
2808                         if ( message 
== WM_LBUTTONDOWN 
&& win
->IsFocusable() ) 
2820         case MM_JOY1BUTTONDOWN
: 
2821         case MM_JOY2BUTTONDOWN
: 
2822         case MM_JOY1BUTTONUP
: 
2823         case MM_JOY2BUTTONUP
: 
2824             processed 
= HandleJoystickEvent(message
, 
2825                                             GET_X_LPARAM(lParam
), 
2826                                             GET_Y_LPARAM(lParam
), 
2829 #endif // __WXMICROWIN__ 
2835                 UnpackCommand(wParam
, lParam
, &id
, &hwnd
, &cmd
); 
2837                 processed 
= HandleCommand(id
, cmd
, hwnd
); 
2842             processed 
= HandleNotify((int)wParam
, lParam
, &rc
.result
); 
2845         // we only need to reply to WM_NOTIFYFORMAT manually when using MSLU, 
2846         // otherwise DefWindowProc() does it perfectly fine for us, but MSLU 
2847         // apparently doesn't always behave properly and needs some help 
2848 #if wxUSE_UNICODE_MSLU && defined(NF_QUERY) 
2849         case WM_NOTIFYFORMAT
: 
2850             if ( lParam 
== NF_QUERY 
) 
2853                 rc
.result 
= NFR_UNICODE
; 
2856 #endif // wxUSE_UNICODE_MSLU 
2858             // for these messages we must return true if process the message 
2861         case WM_MEASUREITEM
: 
2863                 int idCtrl 
= (UINT
)wParam
; 
2864                 if ( message 
== WM_DRAWITEM 
) 
2866                     processed 
= MSWOnDrawItem(idCtrl
, 
2867                                               (WXDRAWITEMSTRUCT 
*)lParam
); 
2871                     processed 
= MSWOnMeasureItem(idCtrl
, 
2872                                                  (WXMEASUREITEMSTRUCT 
*)lParam
); 
2879 #endif // defined(WM_DRAWITEM) 
2882             if ( !IsOfStandardClass() || HasFlag(wxWANTS_CHARS
) ) 
2884                 // we always want to get the char events 
2885                 rc
.result 
= DLGC_WANTCHARS
; 
2887                 if ( HasFlag(wxWANTS_CHARS
) ) 
2889                     // in fact, we want everything 
2890                     rc
.result 
|= DLGC_WANTARROWS 
| 
2897             //else: get the dlg code from the DefWindowProc() 
2902             // If this has been processed by an event handler, return 0 now 
2903             // (we've handled it). 
2904             m_lastKeydownProcessed 
= HandleKeyDown((WORD
) wParam
, lParam
); 
2905             if ( m_lastKeydownProcessed 
) 
2914                     // we consider these messages "not interesting" to OnChar, so 
2915                     // just don't do anything more with them 
2925                     // avoid duplicate messages to OnChar for these ASCII keys: 
2926                     // they will be translated by TranslateMessage() and received 
2958                         // but set processed to false, not true to still pass them 
2959                         // to the control's default window proc - otherwise 
2960                         // built-in keyboard handling won't work 
2965                     // special case of VK_APPS: treat it the same as right mouse 
2966                     // click because both usually pop up a context menu 
2968                         processed 
= HandleMouseEvent(WM_RBUTTONDOWN
, -1, -1, 0); 
2973                         // do generate a CHAR event 
2974                         processed 
= HandleChar((WORD
)wParam
, lParam
); 
2977             if (message 
== WM_SYSKEYDOWN
)  // Let Windows still handle the SYSKEYs 
2984             // special case of VK_APPS: treat it the same as right mouse button 
2985             if ( wParam 
== VK_APPS 
) 
2987                 processed 
= HandleMouseEvent(WM_RBUTTONUP
, -1, -1, 0); 
2992                 processed 
= HandleKeyUp((WORD
) wParam
, lParam
); 
2997         case WM_CHAR
: // Always an ASCII character 
2998             if ( m_lastKeydownProcessed 
) 
3000                 // The key was handled in the EVT_KEY_DOWN and handling 
3001                 // a key in an EVT_KEY_DOWN handler is meant, by 
3002                 // design, to prevent EVT_CHARs from happening 
3003                 m_lastKeydownProcessed 
= false; 
3008                 processed 
= HandleChar((WORD
)wParam
, lParam
, true); 
3014             processed 
= HandleHotKey((WORD
)wParam
, lParam
); 
3016 #endif // wxUSE_HOTKEY 
3023                 UnpackScroll(wParam
, lParam
, &code
, &pos
, &hwnd
); 
3025                 processed 
= MSWOnScroll(message 
== WM_HSCROLL 
? wxHORIZONTAL
 
3031         // CTLCOLOR messages are sent by children to query the parent for their 
3033 #ifndef __WXMICROWIN__ 
3034         case WM_CTLCOLORMSGBOX
: 
3035         case WM_CTLCOLOREDIT
: 
3036         case WM_CTLCOLORLISTBOX
: 
3037         case WM_CTLCOLORBTN
: 
3038         case WM_CTLCOLORDLG
: 
3039         case WM_CTLCOLORSCROLLBAR
: 
3040         case WM_CTLCOLORSTATIC
: 
3044                 UnpackCtlColor(wParam
, lParam
, &hdc
, &hwnd
); 
3046                 processed 
= HandleCtlColor(&rc
.hBrush
, (WXHDC
)hdc
, (WXHWND
)hwnd
); 
3049 #endif // !__WXMICROWIN__ 
3051         case WM_SYSCOLORCHANGE
: 
3052             // the return value for this message is ignored 
3053             processed 
= HandleSysColorChange(); 
3056 #if !defined(__WXWINCE__) 
3057         case WM_DISPLAYCHANGE
: 
3058             processed 
= HandleDisplayChange(); 
3062         case WM_PALETTECHANGED
: 
3063             processed 
= HandlePaletteChanged((WXHWND
) (HWND
) wParam
); 
3066         case WM_CAPTURECHANGED
: 
3067             processed 
= HandleCaptureChanged((WXHWND
) (HWND
) lParam
); 
3070         case WM_SETTINGCHANGE
: 
3071             processed 
= HandleSettingChange(wParam
, lParam
); 
3074         case WM_QUERYNEWPALETTE
: 
3075             processed 
= HandleQueryNewPalette(); 
3079             processed 
= HandleEraseBkgnd((WXHDC
)(HDC
)wParam
); 
3082                 // we processed the message, i.e. erased the background 
3087 #if !defined(__WXWINCE__) 
3089             processed 
= HandleDropFiles(wParam
); 
3094             processed 
= HandleInitDialog((WXHWND
)(HWND
)wParam
); 
3098                 // we never set focus from here 
3103 #if !defined(__WXWINCE__) 
3104         case WM_QUERYENDSESSION
: 
3105             processed 
= HandleQueryEndSession(lParam
, &rc
.allow
); 
3109             processed 
= HandleEndSession(wParam 
!= 0, lParam
); 
3112         case WM_GETMINMAXINFO
: 
3113             processed 
= HandleGetMinMaxInfo((MINMAXINFO
*)lParam
); 
3118             processed 
= HandleSetCursor((WXHWND
)(HWND
)wParam
, 
3119                                         LOWORD(lParam
),     // hit test 
3120                                         HIWORD(lParam
));    // mouse msg 
3124                 // returning TRUE stops the DefWindowProc() from further 
3125                 // processing this message - exactly what we need because we've 
3126                 // just set the cursor. 
3131 #if wxUSE_ACCESSIBILITY 
3134                 //WPARAM dwFlags = (WPARAM) (DWORD) wParam; 
3135                 LPARAM dwObjId 
= (LPARAM
) (DWORD
) lParam
; 
3137                 if (dwObjId 
== (LPARAM
)OBJID_CLIENT 
&& GetOrCreateAccessible()) 
3139                     return LresultFromObject(IID_IAccessible
, wParam
, (IUnknown
*) GetAccessible()->GetIAccessible()); 
3145 #if defined(WM_HELP) 
3148                 // by default, WM_HELP is propagated by DefWindowProc() upwards 
3149                 // to the window parent but as we do it ourselves already 
3150                 // (wxHelpEvent is derived from wxCommandEvent), we don't want 
3151                 // to get the other events if we process this message at all 
3154                 // WM_HELP doesn't use lParam under CE 
3156                 HELPINFO
* info 
= (HELPINFO
*) lParam
; 
3157                 if ( info
->iContextType 
== HELPINFO_WINDOW 
) 
3159 #endif // !__WXWINCE__ 
3160                     wxHelpEvent helpEvent
 
3165                                     wxGetMousePosition() // what else? 
3167                                     wxPoint(info
->MousePos
.x
, info
->MousePos
.y
) 
3171                     helpEvent
.SetEventObject(this); 
3172                     GetEventHandler()->ProcessEvent(helpEvent
); 
3175                 else if ( info
->iContextType 
== HELPINFO_MENUITEM 
) 
3177                     wxHelpEvent 
helpEvent(wxEVT_HELP
, info
->iCtrlId
); 
3178                     helpEvent
.SetEventObject(this); 
3179                     GetEventHandler()->ProcessEvent(helpEvent
); 
3182                 else // unknown help event? 
3186 #endif // !__WXWINCE__ 
3191 #if !defined(__WXWINCE__) 
3192         case WM_CONTEXTMENU
: 
3194                 // we don't convert from screen to client coordinates as 
3195                 // the event may be handled by a parent window 
3196                 wxPoint 
pt(GET_X_LPARAM(lParam
), GET_Y_LPARAM(lParam
)); 
3198                 wxContextMenuEvent 
evtCtx(wxEVT_CONTEXT_MENU
, GetId(), pt
); 
3200                 // we could have got an event from our child, reflect it back 
3201                 // to it if this is the case 
3202                 wxWindowMSW 
*win 
= NULL
; 
3203                 if ( (WXHWND
)wParam 
!= m_hWnd 
) 
3205                     win 
= FindItemByHWND((WXHWND
)wParam
); 
3211                 evtCtx
.SetEventObject(win
); 
3212                 processed 
= win
->GetEventHandler()->ProcessEvent(evtCtx
); 
3219             // we're only interested in our own menus, not MF_SYSMENU 
3220             if ( HIWORD(wParam
) == MF_POPUP 
) 
3222                 // handle menu chars for ownerdrawn menu items 
3223                 int i 
= HandleMenuChar(toupper(LOWORD(wParam
)), lParam
); 
3224                 if ( i 
!= wxNOT_FOUND 
) 
3226                     rc
.result 
= MAKELRESULT(i
, MNC_EXECUTE
); 
3231 #endif // wxUSE_MENUS 
3234         case WM_POWERBROADCAST
: 
3237                 processed 
= HandlePower(wParam
, lParam
, &vetoed
); 
3238                 rc
.result 
= processed 
&& vetoed 
? BROADCAST_QUERY_DENY 
: TRUE
; 
3241 #endif // __WXWINCE__ 
3244         // If we want the default themed border then we need to draw it ourselves 
3247                 wxUxThemeEngine
* theme 
= wxUxThemeEngine::GetIfActive(); 
3248                 if (theme 
&& GetBorder() == wxBORDER_THEME
) 
3250                     // first ask the widget to calculate the border size 
3251                     rc
.result 
= MSWDefWindowProc(message
, wParam
, lParam
); 
3254                     // now alter the client size making room for drawing a themed border 
3255                     NCCALCSIZE_PARAMS 
*csparam 
= NULL
; 
3259                         csparam 
= (NCCALCSIZE_PARAMS
*)lParam
; 
3260                         rect 
= csparam
->rgrc
[0]; 
3264                         rect 
= *((RECT
*)lParam
); 
3266                     wxUxThemeHandle 
hTheme(this, L
"EDIT"); 
3267                     RECT rcClient 
= { 0, 0, 0, 0 }; 
3268                     wxClientDC 
dc(this); 
3270                     if (theme
->GetThemeBackgroundContentRect( 
3271                             hTheme
, GetHdcOf(dc
), EP_EDITTEXT
, ETS_NORMAL
, 
3272                             &rect
, &rcClient
) == S_OK
) 
3274                         InflateRect(&rcClient
, -1, -1); 
3276                             csparam
->rgrc
[0] = rcClient
; 
3278                             *((RECT
*)lParam
) = rcClient
; 
3279                         rc
.result 
= WVR_REDRAW
; 
3287                 wxUxThemeEngine
* theme 
= wxUxThemeEngine::GetIfActive(); 
3288                 if (theme 
&& GetBorder() == wxBORDER_THEME
) 
3290                     // first ask the widget to paint its non-client area, such as scrollbars, etc. 
3291                     rc
.result 
= MSWDefWindowProc(message
, wParam
, lParam
); 
3294                     wxUxThemeHandle 
hTheme(this, L
"EDIT"); 
3295                     wxWindowDC 
dc(this); 
3297                     // Clip the DC so that you only draw on the non-client area 
3299                     wxCopyRectToRECT(GetSize(), rcBorder
); 
3302                     theme
->GetThemeBackgroundContentRect( 
3303                         hTheme
, GetHdcOf(dc
), EP_EDITTEXT
, ETS_NORMAL
, &rcBorder
, &rcClient
); 
3304                     InflateRect(&rcClient
, -1, -1); 
3306                     ::ExcludeClipRect(GetHdcOf(dc
), rcClient
.left
, rcClient
.top
, 
3307                                       rcClient
.right
, rcClient
.bottom
); 
3309                     // Make sure the background is in a proper state 
3310                     if (theme
->IsThemeBackgroundPartiallyTransparent(hTheme
, EP_EDITTEXT
, ETS_NORMAL
)) 
3312                         theme
->DrawThemeParentBackground(GetHwnd(), GetHdcOf(dc
), &rcBorder
); 
3318                         nState 
= ETS_DISABLED
; 
3319                     // should we check this? 
3320                     //else if ( ::GetWindowLong(GetHwnd(), GWL_STYLE) & ES_READONLY) 
3321                     //    nState = ETS_READONLY; 
3323                         nState 
= ETS_NORMAL
; 
3324                     theme
->DrawThemeBackground(hTheme
, GetHdcOf(dc
), EP_EDITTEXT
, nState
, &rcBorder
, NULL
); 
3329 #endif // wxUSE_UXTHEME 
3332             // try a custom message handler 
3333             const MSWMessageHandlers::const_iterator
 
3334                 i 
= gs_messageHandlers
.find(message
); 
3335             if ( i 
!= gs_messageHandlers
.end() ) 
3337                 processed 
= (*i
->second
)(this, message
, wParam
, lParam
); 
3344         wxLogTrace(wxTraceMessages
, wxT("Forwarding %s to DefWindowProc."), 
3345                    wxGetMessageName(message
)); 
3346 #endif // __WXDEBUG__ 
3347         rc
.result 
= MSWDefWindowProc(message
, wParam
, lParam
); 
3353 // ---------------------------------------------------------------------------- 
3354 // wxWindow <-> HWND map 
3355 // ---------------------------------------------------------------------------- 
3357 wxWinHashTable 
*wxWinHandleHash 
= NULL
; 
3359 wxWindow 
*wxFindWinFromHandle(WXHWND hWnd
) 
3361     return (wxWindow
*)wxWinHandleHash
->Get((long)hWnd
); 
3364 void wxAssociateWinWithHandle(HWND hWnd
, wxWindowMSW 
*win
) 
3366     // adding NULL hWnd is (first) surely a result of an error and 
3367     // (secondly) breaks menu command processing 
3368     wxCHECK_RET( hWnd 
!= (HWND
)NULL
, 
3369                  wxT("attempt to add a NULL hWnd to window list ignored") ); 
3371     wxWindow 
*oldWin 
= wxFindWinFromHandle((WXHWND
) hWnd
); 
3373     if ( oldWin 
&& (oldWin 
!= win
) ) 
3375         wxLogDebug(wxT("HWND %X already associated with another window (%s)"), 
3376                    (int) hWnd
, win
->GetClassInfo()->GetClassName()); 
3379 #endif // __WXDEBUG__ 
3382         wxWinHandleHash
->Put((long)hWnd
, (wxWindow 
*)win
); 
3386 void wxRemoveHandleAssociation(wxWindowMSW 
*win
) 
3388     wxWinHandleHash
->Delete((long)win
->GetHWND()); 
3391 // ---------------------------------------------------------------------------- 
3392 // various MSW speciic class dependent functions 
3393 // ---------------------------------------------------------------------------- 
3395 // Default destroyer - override if you destroy it in some other way 
3396 // (e.g. with MDI child windows) 
3397 void wxWindowMSW::MSWDestroyWindow() 
3401 bool wxWindowMSW::MSWGetCreateWindowCoords(const wxPoint
& pos
, 
3404                                            int& w
, int& h
) const 
3406     // yes, those are just some arbitrary hardcoded numbers 
3407     static const int DEFAULT_Y 
= 200; 
3409     bool nonDefault 
= false; 
3411     if ( pos
.x 
== wxDefaultCoord 
) 
3413         // if x is set to CW_USEDEFAULT, y parameter is ignored anyhow so we 
3414         // can just as well set it to CW_USEDEFAULT as well 
3420         // OTOH, if x is not set to CW_USEDEFAULT, y shouldn't be set to it 
3421         // neither because it is not handled as a special value by Windows then 
3422         // and so we have to choose some default value for it 
3424         y 
= pos
.y 
== wxDefaultCoord 
? DEFAULT_Y 
: pos
.y
; 
3430       NB: there used to be some code here which set the initial size of the 
3431           window to the client size of the parent if no explicit size was 
3432           specified. This was wrong because wxWidgets programs often assume 
3433           that they get a WM_SIZE (EVT_SIZE) upon creation, however this broke 
3434           it. To see why, you should understand that Windows sends WM_SIZE from 
3435           inside ::CreateWindow() anyhow. However, ::CreateWindow() is called 
3436           from some base class ctor and so this WM_SIZE is not processed in the 
3437           real class' OnSize() (because it's not fully constructed yet and the 
3438           event goes to some base class OnSize() instead). So the WM_SIZE we 
3439           rely on is the one sent when the parent frame resizes its children 
3440           but here is the problem: if the child already has just the right 
3441           size, nothing will happen as both wxWidgets and Windows check for 
3442           this and ignore any attempts to change the window size to the size it 
3443           already has - so no WM_SIZE would be sent. 
3447     // we don't use CW_USEDEFAULT here for several reasons: 
3449     //  1. it results in huge frames on modern screens (1000*800 is not 
3450     //     uncommon on my 1280*1024 screen) which is way too big for a half 
3451     //     empty frame of most of wxWidgets samples for example) 
3453     //  2. it is buggy for frames with wxFRAME_TOOL_WINDOW style for which 
3454     //     the default is for whatever reason 8*8 which breaks client <-> 
3455     //     window size calculations (it would be nice if it didn't, but it 
3456     //     does and the simplest way to fix it seemed to change the broken 
3457     //     default size anyhow) 
3459     //  3. there is just no advantage in doing it: with x and y it is 
3460     //     possible that [future versions of] Windows position the new top 
3461     //     level window in some smart way which we can't do, but we can 
3462     //     guess a reasonably good size for a new window just as well 
3465     // However, on PocketPC devices, we must use the default 
3466     // size if possible. 
3468     if (size
.x 
== wxDefaultCoord
) 
3472     if (size
.y 
== wxDefaultCoord
) 
3477     if ( size
.x 
== wxDefaultCoord 
|| size
.y 
== wxDefaultCoord
) 
3481     w 
= WidthDefault(size
.x
); 
3482     h 
= HeightDefault(size
.y
); 
3485     AdjustForParentClientOrigin(x
, y
); 
3490 WXHWND 
wxWindowMSW::MSWGetParent() const 
3492     return m_parent 
? m_parent
->GetHWND() : WXHWND(NULL
); 
3495 bool wxWindowMSW::MSWCreate(const wxChar 
*wclass
, 
3496                             const wxChar 
*title
, 
3500                             WXDWORD extendedStyle
) 
3502     // choose the position/size for the new window 
3504     (void)MSWGetCreateWindowCoords(pos
, size
, x
, y
, w
, h
); 
3506     // controlId is menu handle for the top level windows, so set it to 0 
3507     // unless we're creating a child window 
3508     int controlId 
= style 
& WS_CHILD 
? GetId() : 0; 
3510     // for each class "Foo" we have we also have "FooNR" ("no repaint") class 
3511     // which is the same but without CS_[HV]REDRAW class styles so using it 
3512     // ensures that the window is not fully repainted on each resize 
3513     wxString 
className(wclass
); 
3514     if ( !HasFlag(wxFULL_REPAINT_ON_RESIZE
) ) 
3516         className 
+= wxT("NR"); 
3519     // do create the window 
3520     wxWindowCreationHook 
hook(this); 
3522     m_hWnd 
= (WXHWND
)::CreateWindowEx
 
3526                         title 
? title 
: m_windowName
.wx_str(), 
3529                         (HWND
)MSWGetParent(), 
3532                         NULL                        
// no extra data 
3537         wxLogSysError(_("Can't create window of class %s"), className
.c_str()); 
3542     SubclassWin(m_hWnd
); 
3547 // =========================================================================== 
3548 // MSW message handlers 
3549 // =========================================================================== 
3551 // --------------------------------------------------------------------------- 
3553 // --------------------------------------------------------------------------- 
3555 bool wxWindowMSW::HandleNotify(int idCtrl
, WXLPARAM lParam
, WXLPARAM 
*result
) 
3557 #ifndef __WXMICROWIN__ 
3558     LPNMHDR hdr 
= (LPNMHDR
)lParam
; 
3559     HWND hWnd 
= hdr
->hwndFrom
; 
3560     wxWindow 
*win 
= wxFindWinFromHandle((WXHWND
)hWnd
); 
3562     // if the control is one of our windows, let it handle the message itself 
3565         return win
->MSWOnNotify(idCtrl
, lParam
, result
); 
3568     // VZ: why did we do it? normally this is unnecessary and, besides, it 
3569     //     breaks the message processing for the toolbars because the tooltip 
3570     //     notifications were being forwarded to the toolbar child controls 
3571     //     (if it had any) before being passed to the toolbar itself, so in my 
3572     //     example the tooltip for the combobox was always shown instead of the 
3573     //     correct button tooltips 
3575     // try all our children 
3576     wxWindowList::compatibility_iterator node 
= GetChildren().GetFirst(); 
3579         wxWindow 
*child 
= node
->GetData(); 
3580         if ( child
->MSWOnNotify(idCtrl
, lParam
, result
) ) 
3585         node 
= node
->GetNext(); 
3589     // by default, handle it ourselves 
3590     return MSWOnNotify(idCtrl
, lParam
, result
); 
3591 #else // __WXMICROWIN__ 
3598 bool wxWindowMSW::HandleTooltipNotify(WXUINT code
, 
3600                                       const wxString
& ttip
) 
3602     // I don't know why it happens, but the versions of comctl32.dll starting 
3603     // from 4.70 sometimes send TTN_NEEDTEXTW even to ANSI programs (normally, 
3604     // this message is supposed to be sent to Unicode programs only) -- hence 
3605     // we need to handle it as well, otherwise no tooltips will be shown in 
3608     if ( !(code 
== (WXUINT
) TTN_NEEDTEXTA 
|| code 
== (WXUINT
) TTN_NEEDTEXTW
) 
3611         // not a tooltip message or no tooltip to show anyhow 
3616     LPTOOLTIPTEXT ttText 
= (LPTOOLTIPTEXT
)lParam
; 
3618     // We don't want to use the szText buffer because it has a limit of 80 
3619     // bytes and this is not enough, especially for Unicode build where it 
3620     // limits the tooltip string length to only 40 characters 
3622     // The best would be, of course, to not impose any length limitations at 
3623     // all but then the buffer would have to be dynamic and someone would have 
3624     // to free it and we don't have the tooltip owner object here any more, so 
3625     // for now use our own static buffer with a higher fixed max length. 
3627     // Note that using a static buffer should not be a problem as only a single 
3628     // tooltip can be shown at the same time anyhow. 
3630     if ( code 
== (WXUINT
) TTN_NEEDTEXTW 
) 
3632         // We need to convert tooltip from multi byte to Unicode on the fly. 
3633         static wchar_t buf
[513]; 
3635         // Truncate tooltip length if needed as otherwise we might not have 
3636         // enough space for it in the buffer and MultiByteToWideChar() would 
3638         size_t tipLength 
= wxMin(ttip
.length(), WXSIZEOF(buf
) - 1); 
3640         // Convert to WideChar without adding the NULL character. The NULL 
3641         // character is added afterwards (this is more efficient). 
3642         int len 
= ::MultiByteToWideChar
 
3654             wxLogLastError(_T("MultiByteToWideChar()")); 
3658         ttText
->lpszText 
= (LPSTR
) buf
; 
3660     else // TTN_NEEDTEXTA 
3661 #endif // !wxUSE_UNICODE 
3663         // we get here if we got TTN_NEEDTEXTA (only happens in ANSI build) or 
3664         // if we got TTN_NEEDTEXTW in Unicode build: in this case we just have 
3665         // to copy the string we have into the buffer 
3666         static wxChar buf
[513]; 
3667         wxStrncpy(buf
, ttip
.c_str(), WXSIZEOF(buf
) - 1); 
3668         buf
[WXSIZEOF(buf
) - 1] = _T('\0'); 
3669         ttText
->lpszText 
= buf
; 
3675 #endif // wxUSE_TOOLTIPS 
3677 bool wxWindowMSW::MSWOnNotify(int WXUNUSED(idCtrl
), 
3679                               WXLPARAM
* WXUNUSED(result
)) 
3684         NMHDR
* hdr 
= (NMHDR 
*)lParam
; 
3685         if ( HandleTooltipNotify(hdr
->code
, lParam
, m_tooltip
->GetTip())) 
3692     wxUnusedVar(lParam
); 
3693 #endif // wxUSE_TOOLTIPS 
3698 // --------------------------------------------------------------------------- 
3699 // end session messages 
3700 // --------------------------------------------------------------------------- 
3702 bool wxWindowMSW::HandleQueryEndSession(long logOff
, bool *mayEnd
) 
3704 #ifdef ENDSESSION_LOGOFF 
3705     wxCloseEvent 
event(wxEVT_QUERY_END_SESSION
, wxID_ANY
); 
3706     event
.SetEventObject(wxTheApp
); 
3707     event
.SetCanVeto(true); 
3708     event
.SetLoggingOff(logOff 
== (long)ENDSESSION_LOGOFF
); 
3710     bool rc 
= wxTheApp
->ProcessEvent(event
); 
3714         // we may end only if the app didn't veto session closing (double 
3716         *mayEnd 
= !event
.GetVeto(); 
3721     wxUnusedVar(logOff
); 
3722     wxUnusedVar(mayEnd
); 
3727 bool wxWindowMSW::HandleEndSession(bool endSession
, long logOff
) 
3729 #ifdef ENDSESSION_LOGOFF 
3730     // do nothing if the session isn't ending 
3735     if ( (this != wxTheApp
->GetTopWindow()) ) 
3738     wxCloseEvent 
event(wxEVT_END_SESSION
, wxID_ANY
); 
3739     event
.SetEventObject(wxTheApp
); 
3740     event
.SetCanVeto(false); 
3741     event
.SetLoggingOff( (logOff 
== (long)ENDSESSION_LOGOFF
) ); 
3743     return wxTheApp
->ProcessEvent(event
); 
3745     wxUnusedVar(endSession
); 
3746     wxUnusedVar(logOff
); 
3751 // --------------------------------------------------------------------------- 
3752 // window creation/destruction 
3753 // --------------------------------------------------------------------------- 
3755 bool wxWindowMSW::HandleCreate(WXLPCREATESTRUCT 
WXUNUSED_IN_WINCE(cs
), 
3758     // VZ: why is this commented out for WinCE? If it doesn't support 
3759     //     WS_EX_CONTROLPARENT at all it should be somehow handled globally, 
3760     //     not with multiple #ifdef's! 
3762     if ( ((CREATESTRUCT 
*)cs
)->dwExStyle 
& WS_EX_CONTROLPARENT 
) 
3763         EnsureParentHasControlParentStyle(GetParent()); 
3764 #endif // !__WXWINCE__ 
3771 bool wxWindowMSW::HandleDestroy() 
3775     // delete our drop target if we've got one 
3776 #if wxUSE_DRAG_AND_DROP 
3777     if ( m_dropTarget 
!= NULL 
) 
3779         m_dropTarget
->Revoke(m_hWnd
); 
3781         delete m_dropTarget
; 
3782         m_dropTarget 
= NULL
; 
3784 #endif // wxUSE_DRAG_AND_DROP 
3786     // WM_DESTROY handled 
3790 // --------------------------------------------------------------------------- 
3792 // --------------------------------------------------------------------------- 
3794 bool wxWindowMSW::HandleActivate(int state
, 
3795                               bool WXUNUSED(minimized
), 
3796                               WXHWND 
WXUNUSED(activate
)) 
3798     wxActivateEvent 
event(wxEVT_ACTIVATE
, 
3799                           (state 
== WA_ACTIVE
) || (state 
== WA_CLICKACTIVE
), 
3801     event
.SetEventObject(this); 
3803     return GetEventHandler()->ProcessEvent(event
); 
3806 bool wxWindowMSW::HandleSetFocus(WXHWND hwnd
) 
3808     // Strangly enough, some controls get set focus events when they are being 
3809     // deleted, even if they already had focus before. 
3810     if ( m_isBeingDeleted 
) 
3815     // notify the parent keeping track of focus for the kbd navigation 
3816     // purposes that we got it 
3817     wxChildFocusEvent 
eventFocus((wxWindow 
*)this); 
3818     (void)GetEventHandler()->ProcessEvent(eventFocus
); 
3824         m_caret
->OnSetFocus(); 
3826 #endif // wxUSE_CARET 
3829     // If it's a wxTextCtrl don't send the event as it will be done 
3830     // after the control gets to process it from EN_FOCUS handler 
3831     if ( wxDynamicCastThis(wxTextCtrl
) ) 
3835 #endif // wxUSE_TEXTCTRL 
3837     wxFocusEvent 
event(wxEVT_SET_FOCUS
, m_windowId
); 
3838     event
.SetEventObject(this); 
3840     // wxFindWinFromHandle() may return NULL, it is ok 
3841     event
.SetWindow(wxFindWinFromHandle(hwnd
)); 
3843     return GetEventHandler()->ProcessEvent(event
); 
3846 bool wxWindowMSW::HandleKillFocus(WXHWND hwnd
) 
3852         m_caret
->OnKillFocus(); 
3854 #endif // wxUSE_CARET 
3857     // If it's a wxTextCtrl don't send the event as it will be done 
3858     // after the control gets to process it. 
3859     wxTextCtrl 
*ctrl 
= wxDynamicCastThis(wxTextCtrl
); 
3866     // Don't send the event when in the process of being deleted.  This can 
3867     // only cause problems if the event handler tries to access the object. 
3868     if ( m_isBeingDeleted 
) 
3873     wxFocusEvent 
event(wxEVT_KILL_FOCUS
, m_windowId
); 
3874     event
.SetEventObject(this); 
3876     // wxFindWinFromHandle() may return NULL, it is ok 
3877     event
.SetWindow(wxFindWinFromHandle(hwnd
)); 
3879     return GetEventHandler()->ProcessEvent(event
); 
3882 // --------------------------------------------------------------------------- 
3884 // --------------------------------------------------------------------------- 
3886 void wxWindowMSW::SetLabel( const wxString
& label
) 
3888     SetWindowText(GetHwnd(), label
.c_str()); 
3891 wxString 
wxWindowMSW::GetLabel() const 
3893     return wxGetWindowText(GetHWND()); 
3896 // --------------------------------------------------------------------------- 
3898 // --------------------------------------------------------------------------- 
3900 bool wxWindowMSW::HandleShow(bool show
, int WXUNUSED(status
)) 
3902     wxShowEvent 
event(GetId(), show
); 
3903     event
.SetEventObject(this); 
3905     return GetEventHandler()->ProcessEvent(event
); 
3908 bool wxWindowMSW::HandleInitDialog(WXHWND 
WXUNUSED(hWndFocus
)) 
3910     wxInitDialogEvent 
event(GetId()); 
3911     event
.SetEventObject(this); 
3913     return GetEventHandler()->ProcessEvent(event
); 
3916 bool wxWindowMSW::HandleDropFiles(WXWPARAM wParam
) 
3918 #if defined (__WXMICROWIN__) || defined(__WXWINCE__) 
3919     wxUnusedVar(wParam
); 
3921 #else // __WXMICROWIN__ 
3922     HDROP hFilesInfo 
= (HDROP
) wParam
; 
3924     // Get the total number of files dropped 
3925     UINT gwFilesDropped 
= ::DragQueryFile
 
3933     wxString 
*files 
= new wxString
[gwFilesDropped
]; 
3934     for ( UINT wIndex 
= 0; wIndex 
< gwFilesDropped
; wIndex
++ ) 
3936         // first get the needed buffer length (+1 for terminating NUL) 
3937         size_t len 
= ::DragQueryFile(hFilesInfo
, wIndex
, NULL
, 0) + 1; 
3939         // and now get the file name 
3940         ::DragQueryFile(hFilesInfo
, wIndex
, 
3941                         wxStringBuffer(files
[wIndex
], len
), len
); 
3943     DragFinish (hFilesInfo
); 
3945     wxDropFilesEvent 
event(wxEVT_DROP_FILES
, gwFilesDropped
, files
); 
3946     event
.SetEventObject(this); 
3949     DragQueryPoint(hFilesInfo
, (LPPOINT
) &dropPoint
); 
3950     event
.m_pos
.x 
= dropPoint
.x
; 
3951     event
.m_pos
.y 
= dropPoint
.y
; 
3953     return GetEventHandler()->ProcessEvent(event
); 
3958 bool wxWindowMSW::HandleSetCursor(WXHWND 
WXUNUSED(hWnd
), 
3960                                   int WXUNUSED(mouseMsg
)) 
3962 #ifndef __WXMICROWIN__ 
3963     // the logic is as follows: 
3964     //  0. if we're busy, set the busy cursor (even for non client elements) 
3965     //  1. don't set custom cursor for non client area of enabled windows 
3966     //  2. ask user EVT_SET_CURSOR handler for the cursor 
3967     //  3. if still no cursor but we're in a TLW, set the global cursor 
3969     HCURSOR hcursor 
= 0; 
3972         hcursor 
= wxGetCurrentBusyCursor(); 
3976         if ( nHitTest 
!= HTCLIENT 
) 
3979         // first ask the user code - it may wish to set the cursor in some very 
3980         // specific way (for example, depending on the current position) 
3983         if ( !::GetCursorPosWinCE(&pt
)) 
3985         if ( !::GetCursorPos(&pt
) ) 
3988             wxLogLastError(wxT("GetCursorPos")); 
3993         ScreenToClient(&x
, &y
); 
3994         wxSetCursorEvent 
event(x
, y
); 
3996         bool processedEvtSetCursor 
= GetEventHandler()->ProcessEvent(event
); 
3997         if ( processedEvtSetCursor 
&& event
.HasCursor() ) 
3999             hcursor 
= GetHcursorOf(event
.GetCursor()); 
4004             // the test for processedEvtSetCursor is here to prevent using 
4005             // m_cursor if the user code caught EVT_SET_CURSOR() and returned 
4006             // nothing from it - this is a way to say that our cursor shouldn't 
4007             // be used for this point 
4008             if ( !processedEvtSetCursor 
&& m_cursor
.Ok() ) 
4010                 hcursor 
= GetHcursorOf(m_cursor
); 
4013             if ( !hcursor 
&& !GetParent() ) 
4015                 const wxCursor 
*cursor 
= wxGetGlobalCursor(); 
4016                 if ( cursor 
&& cursor
->Ok() ) 
4018                     hcursor 
= GetHcursorOf(*cursor
); 
4027         ::SetCursor(hcursor
); 
4029         // cursor set, stop here 
4032 #endif // __WXMICROWIN__ 
4034     // pass up the window chain 
4038 bool wxWindowMSW::HandlePower(WXWPARAM 
WXUNUSED_IN_WINCE(wParam
), 
4039                               WXLPARAM 
WXUNUSED(lParam
), 
4040                               bool *WXUNUSED_IN_WINCE(vetoed
)) 
4046     wxEventType evtType
; 
4049         case PBT_APMQUERYSUSPEND
: 
4050             evtType 
= wxEVT_POWER_SUSPENDING
; 
4053         case PBT_APMQUERYSUSPENDFAILED
: 
4054             evtType 
= wxEVT_POWER_SUSPEND_CANCEL
; 
4057         case PBT_APMSUSPEND
: 
4058             evtType 
= wxEVT_POWER_SUSPENDED
; 
4061         case PBT_APMRESUMESUSPEND
: 
4062 #ifdef PBT_APMRESUMEAUTOMATIC 
4063         case PBT_APMRESUMEAUTOMATIC
: 
4065             evtType 
= wxEVT_POWER_RESUME
; 
4069             wxLogDebug(_T("Unknown WM_POWERBROADCAST(%d) event"), wParam
); 
4072         // these messages are currently not mapped to wx events 
4073         case PBT_APMQUERYSTANDBY
: 
4074         case PBT_APMQUERYSTANDBYFAILED
: 
4075         case PBT_APMSTANDBY
: 
4076         case PBT_APMRESUMESTANDBY
: 
4077         case PBT_APMBATTERYLOW
: 
4078         case PBT_APMPOWERSTATUSCHANGE
: 
4079         case PBT_APMOEMEVENT
: 
4080         case PBT_APMRESUMECRITICAL
: 
4081             evtType 
= wxEVT_NULL
; 
4085     // don't handle unknown messages 
4086     if ( evtType 
== wxEVT_NULL 
) 
4089     // TODO: notify about PBTF_APMRESUMEFROMFAILURE in case of resume events? 
4091     wxPowerEvent 
event(evtType
); 
4092     if ( !GetEventHandler()->ProcessEvent(event
) ) 
4095     *vetoed 
= event
.IsVetoed(); 
4101 bool wxWindowMSW::IsDoubleBuffered() const 
4103     for ( const wxWindowMSW 
*wnd 
= this; 
4104           wnd 
&& !wnd
->IsTopLevel(); wnd 
= 
4107         if ( ::GetWindowLong(GetHwndOf(wnd
), GWL_EXSTYLE
) & WS_EX_COMPOSITED 
) 
4114 // --------------------------------------------------------------------------- 
4115 // owner drawn stuff 
4116 // --------------------------------------------------------------------------- 
4118 #if (wxUSE_OWNER_DRAWN && wxUSE_MENUS_NATIVE) || \ 
4119         (wxUSE_CONTROLS && !defined(__WXUNIVERSAL__)) 
4120     #define WXUNUSED_UNLESS_ODRAWN(param) param 
4122     #define WXUNUSED_UNLESS_ODRAWN(param) 
4126 wxWindowMSW::MSWOnDrawItem(int WXUNUSED_UNLESS_ODRAWN(id
), 
4127                            WXDRAWITEMSTRUCT 
* WXUNUSED_UNLESS_ODRAWN(itemStruct
)) 
4129 #if wxUSE_OWNER_DRAWN 
4131 #if wxUSE_MENUS_NATIVE 
4132     // is it a menu item? 
4133     DRAWITEMSTRUCT 
*pDrawStruct 
= (DRAWITEMSTRUCT 
*)itemStruct
; 
4134     if ( id 
== 0 && pDrawStruct
->CtlType 
== ODT_MENU 
) 
4136         wxMenuItem 
*pMenuItem 
= (wxMenuItem 
*)(pDrawStruct
->itemData
); 
4138         // see comment before the same test in MSWOnMeasureItem() below 
4142         wxCHECK_MSG( wxDynamicCast(pMenuItem
, wxMenuItem
), 
4143                          false, _T("MSWOnDrawItem: bad wxMenuItem pointer") ); 
4145         // prepare to call OnDrawItem(): notice using of wxDCTemp to prevent 
4146         // the DC from being released 
4147         wxDCTemp 
dc((WXHDC
)pDrawStruct
->hDC
); 
4148         wxRect 
rect(pDrawStruct
->rcItem
.left
, pDrawStruct
->rcItem
.top
, 
4149                     pDrawStruct
->rcItem
.right 
- pDrawStruct
->rcItem
.left
, 
4150                     pDrawStruct
->rcItem
.bottom 
- pDrawStruct
->rcItem
.top
); 
4152         return pMenuItem
->OnDrawItem
 
4156                 (wxOwnerDrawn::wxODAction
)pDrawStruct
->itemAction
, 
4157                 (wxOwnerDrawn::wxODStatus
)pDrawStruct
->itemState
 
4160 #endif // wxUSE_MENUS_NATIVE 
4162 #endif // USE_OWNER_DRAWN 
4164 #if wxUSE_CONTROLS && !defined(__WXUNIVERSAL__) 
4166 #if wxUSE_OWNER_DRAWN 
4167     wxControl 
*item 
= wxDynamicCast(FindItem(id
), wxControl
); 
4168 #else // !wxUSE_OWNER_DRAWN 
4169     // we may still have owner-drawn buttons internally because we have to make 
4170     // them owner-drawn to support colour change 
4173                          wxDynamicCast(FindItem(id
), wxButton
) 
4178 #endif // USE_OWNER_DRAWN 
4182         return item
->MSWOnDraw(itemStruct
); 
4185 #endif // wxUSE_CONTROLS 
4191 wxWindowMSW::MSWOnMeasureItem(int id
, WXMEASUREITEMSTRUCT 
*itemStruct
) 
4193 #if wxUSE_OWNER_DRAWN && wxUSE_MENUS_NATIVE 
4194     // is it a menu item? 
4195     MEASUREITEMSTRUCT 
*pMeasureStruct 
= (MEASUREITEMSTRUCT 
*)itemStruct
; 
4196     if ( id 
== 0 && pMeasureStruct
->CtlType 
== ODT_MENU 
) 
4198         wxMenuItem 
*pMenuItem 
= (wxMenuItem 
*)(pMeasureStruct
->itemData
); 
4200         // according to Carsten Fuchs the pointer may be NULL under XP if an 
4201         // MDI child frame is initially maximized, see this for more info: 
4202         // http://article.gmane.org/gmane.comp.lib.wxwidgets.general/27745 
4204         // so silently ignore it instead of asserting 
4208         wxCHECK_MSG( wxDynamicCast(pMenuItem
, wxMenuItem
), 
4209                         false, _T("MSWOnMeasureItem: bad wxMenuItem pointer") ); 
4212         bool rc 
= pMenuItem
->OnMeasureItem(&w
, &h
); 
4214         pMeasureStruct
->itemWidth 
= w
; 
4215         pMeasureStruct
->itemHeight 
= h
; 
4220     wxControl 
*item 
= wxDynamicCast(FindItem(id
), wxControl
); 
4223         return item
->MSWOnMeasure(itemStruct
); 
4227     wxUnusedVar(itemStruct
); 
4228 #endif // wxUSE_OWNER_DRAWN && wxUSE_MENUS_NATIVE 
4233 // --------------------------------------------------------------------------- 
4234 // colours and palettes 
4235 // --------------------------------------------------------------------------- 
4237 bool wxWindowMSW::HandleSysColorChange() 
4239     wxSysColourChangedEvent event
; 
4240     event
.SetEventObject(this); 
4242     (void)GetEventHandler()->ProcessEvent(event
); 
4244     // always let the system carry on the default processing to allow the 
4245     // native controls to react to the colours update 
4249 bool wxWindowMSW::HandleDisplayChange() 
4251     wxDisplayChangedEvent event
; 
4252     event
.SetEventObject(this); 
4254     return GetEventHandler()->ProcessEvent(event
); 
4257 #ifndef __WXMICROWIN__ 
4259 bool wxWindowMSW::HandleCtlColor(WXHBRUSH 
*brush
, WXHDC hDC
, WXHWND hWnd
) 
4261 #if !wxUSE_CONTROLS || defined(__WXUNIVERSAL__) 
4265     wxControl 
*item 
= wxDynamicCast(FindItemByHWND(hWnd
, true), wxControl
); 
4268         *brush 
= item
->MSWControlColor(hDC
, hWnd
); 
4270 #endif // wxUSE_CONTROLS 
4273     return *brush 
!= NULL
; 
4276 #endif // __WXMICROWIN__ 
4278 bool wxWindowMSW::HandlePaletteChanged(WXHWND hWndPalChange
) 
4281     // same as below except we don't respond to our own messages 
4282     if ( hWndPalChange 
!= GetHWND() ) 
4284         // check to see if we our our parents have a custom palette 
4285         wxWindowMSW 
*win 
= this; 
4286         while ( win 
&& !win
->HasCustomPalette() ) 
4288             win 
= win
->GetParent(); 
4291         if ( win 
&& win
->HasCustomPalette() ) 
4293             // realize the palette to see whether redrawing is needed 
4294             HDC hdc 
= ::GetDC((HWND
) hWndPalChange
); 
4295             win
->m_palette
.SetHPALETTE((WXHPALETTE
) 
4296                     ::SelectPalette(hdc
, GetHpaletteOf(win
->m_palette
), FALSE
)); 
4298             int result 
= ::RealizePalette(hdc
); 
4300             // restore the palette (before releasing the DC) 
4301             win
->m_palette
.SetHPALETTE((WXHPALETTE
) 
4302                     ::SelectPalette(hdc
, GetHpaletteOf(win
->m_palette
), FALSE
)); 
4303             ::RealizePalette(hdc
); 
4304             ::ReleaseDC((HWND
) hWndPalChange
, hdc
); 
4306             // now check for the need to redraw 
4308                 ::InvalidateRect((HWND
) hWndPalChange
, NULL
, TRUE
); 
4312 #endif // wxUSE_PALETTE 
4314     wxPaletteChangedEvent 
event(GetId()); 
4315     event
.SetEventObject(this); 
4316     event
.SetChangedWindow(wxFindWinFromHandle(hWndPalChange
)); 
4318     return GetEventHandler()->ProcessEvent(event
); 
4321 bool wxWindowMSW::HandleCaptureChanged(WXHWND hWndGainedCapture
) 
4323     // notify windows on the capture stack about lost capture 
4324     // (see http://sourceforge.net/tracker/index.php?func=detail&aid=1153662&group_id=9863&atid=109863): 
4325     wxWindowBase::NotifyCaptureLost(); 
4327     wxWindow 
*win 
= wxFindWinFromHandle(hWndGainedCapture
); 
4328     wxMouseCaptureChangedEvent 
event(GetId(), win
); 
4329     event
.SetEventObject(this); 
4330     return GetEventHandler()->ProcessEvent(event
); 
4333 bool wxWindowMSW::HandleSettingChange(WXWPARAM wParam
, WXLPARAM lParam
) 
4335     // despite MSDN saying "(This message cannot be sent directly to a window.)" 
4336     // we need to send this to child windows (it is only sent to top-level 
4337     // windows) so {list,tree}ctrls can adjust their font size if necessary 
4338     // this is exactly how explorer does it to enable the font size changes 
4340     wxWindowList::compatibility_iterator node 
= GetChildren().GetFirst(); 
4343         // top-level windows already get this message from the system 
4344         wxWindow 
*win 
= node
->GetData(); 
4345         if ( !win
->IsTopLevel() ) 
4347             ::SendMessage(GetHwndOf(win
), WM_SETTINGCHANGE
, wParam
, lParam
); 
4350         node 
= node
->GetNext(); 
4353     // let the system handle it 
4357 bool wxWindowMSW::HandleQueryNewPalette() 
4361     // check to see if we our our parents have a custom palette 
4362     wxWindowMSW 
*win 
= this; 
4363     while (!win
->HasCustomPalette() && win
->GetParent()) win 
= win
->GetParent(); 
4364     if (win
->HasCustomPalette()) { 
4365         /* realize the palette to see whether redrawing is needed */ 
4366         HDC hdc 
= ::GetDC((HWND
) GetHWND()); 
4367         win
->m_palette
.SetHPALETTE( (WXHPALETTE
) 
4368              ::SelectPalette(hdc
, (HPALETTE
) win
->m_palette
.GetHPALETTE(), FALSE
) ); 
4370         int result 
= ::RealizePalette(hdc
); 
4371         /* restore the palette (before releasing the DC) */ 
4372         win
->m_palette
.SetHPALETTE( (WXHPALETTE
) 
4373              ::SelectPalette(hdc
, (HPALETTE
) win
->m_palette
.GetHPALETTE(), TRUE
) ); 
4374         ::RealizePalette(hdc
); 
4375         ::ReleaseDC((HWND
) GetHWND(), hdc
); 
4376         /* now check for the need to redraw */ 
4378             ::InvalidateRect((HWND
) GetHWND(), NULL
, TRUE
); 
4380 #endif // wxUSE_PALETTE 
4382     wxQueryNewPaletteEvent 
event(GetId()); 
4383     event
.SetEventObject(this); 
4385     return GetEventHandler()->ProcessEvent(event
) && event
.GetPaletteRealized(); 
4388 // Responds to colour changes: passes event on to children. 
4389 void wxWindowMSW::OnSysColourChanged(wxSysColourChangedEvent
& WXUNUSED(event
)) 
4391     // the top level window also reset the standard colour map as it might have 
4392     // changed (there is no need to do it for the non top level windows as we 
4393     // only have to do it once) 
4397         gs_hasStdCmap 
= false; 
4399     wxWindowList::compatibility_iterator node 
= GetChildren().GetFirst(); 
4402         // Only propagate to non-top-level windows because Windows already 
4403         // sends this event to all top-level ones 
4404         wxWindow 
*win 
= node
->GetData(); 
4405         if ( !win
->IsTopLevel() ) 
4407             // we need to send the real WM_SYSCOLORCHANGE and not just trigger 
4408             // EVT_SYS_COLOUR_CHANGED call because the latter wouldn't work for 
4409             // the standard controls 
4410             ::SendMessage(GetHwndOf(win
), WM_SYSCOLORCHANGE
, 0, 0); 
4413         node 
= node
->GetNext(); 
4417 extern wxCOLORMAP 
*wxGetStdColourMap() 
4419     static COLORREF s_stdColours
[wxSTD_COL_MAX
]; 
4420     static wxCOLORMAP s_cmap
[wxSTD_COL_MAX
]; 
4422     if ( !gs_hasStdCmap 
) 
4424         static bool s_coloursInit 
= false; 
4426         if ( !s_coloursInit 
) 
4428             // When a bitmap is loaded, the RGB values can change (apparently 
4429             // because Windows adjusts them to care for the old programs always 
4430             // using 0xc0c0c0 while the transparent colour for the new Windows 
4431             // versions is different). But we do this adjustment ourselves so 
4432             // we want to avoid Windows' "help" and for this we need to have a 
4433             // reference bitmap which can tell us what the RGB values change 
4435             wxLogNull logNo
; // suppress error if we couldn't load the bitmap 
4436             wxBitmap 
stdColourBitmap(_T("wxBITMAP_STD_COLOURS")); 
4437             if ( stdColourBitmap
.Ok() ) 
4439                 // the pixels in the bitmap must correspond to wxSTD_COL_XXX! 
4440                 wxASSERT_MSG( stdColourBitmap
.GetWidth() == wxSTD_COL_MAX
, 
4441                               _T("forgot to update wxBITMAP_STD_COLOURS!") ); 
4444                 memDC
.SelectObject(stdColourBitmap
); 
4447                 for ( size_t i 
= 0; i 
< WXSIZEOF(s_stdColours
); i
++ ) 
4449                     memDC
.GetPixel(i
, 0, &colour
); 
4450                     s_stdColours
[i
] = wxColourToRGB(colour
); 
4453             else // wxBITMAP_STD_COLOURS couldn't be loaded 
4455                 s_stdColours
[0] = RGB(000,000,000);     // black 
4456                 s_stdColours
[1] = RGB(128,128,128);     // dark grey 
4457                 s_stdColours
[2] = RGB(192,192,192);     // light grey 
4458                 s_stdColours
[3] = RGB(255,255,255);     // white 
4459                 //s_stdColours[4] = RGB(000,000,255);     // blue 
4460                 //s_stdColours[5] = RGB(255,000,255);     // magenta 
4463             s_coloursInit 
= true; 
4466         gs_hasStdCmap 
= true; 
4468         // create the colour map 
4469 #define INIT_CMAP_ENTRY(col) \ 
4470             s_cmap[wxSTD_COL_##col].from = s_stdColours[wxSTD_COL_##col]; \ 
4471             s_cmap[wxSTD_COL_##col].to = ::GetSysColor(COLOR_##col) 
4473         INIT_CMAP_ENTRY(BTNTEXT
); 
4474         INIT_CMAP_ENTRY(BTNSHADOW
); 
4475         INIT_CMAP_ENTRY(BTNFACE
); 
4476         INIT_CMAP_ENTRY(BTNHIGHLIGHT
); 
4478 #undef INIT_CMAP_ENTRY 
4484 // --------------------------------------------------------------------------- 
4486 // --------------------------------------------------------------------------- 
4488 bool wxWindowMSW::HandlePaint() 
4490     HRGN hRegion 
= ::CreateRectRgn(0, 0, 0, 0); // Dummy call to get a handle 
4492         wxLogLastError(wxT("CreateRectRgn")); 
4493     if ( ::GetUpdateRgn(GetHwnd(), hRegion
, FALSE
) == ERROR 
) 
4494         wxLogLastError(wxT("GetUpdateRgn")); 
4496     m_updateRegion 
= wxRegion((WXHRGN
) hRegion
); 
4498     wxPaintEvent 
event(m_windowId
); 
4499     event
.SetEventObject(this); 
4501     bool processed 
= GetEventHandler()->ProcessEvent(event
); 
4503     // note that we must generate NC event after the normal one as otherwise 
4504     // BeginPaint() will happily overwrite our decorations with the background 
4506     wxNcPaintEvent 
eventNc(m_windowId
); 
4507     eventNc
.SetEventObject(this); 
4508     GetEventHandler()->ProcessEvent(eventNc
); 
4513 // Can be called from an application's OnPaint handler 
4514 void wxWindowMSW::OnPaint(wxPaintEvent
& event
) 
4516 #ifdef __WXUNIVERSAL__ 
4519     HDC hDC 
= (HDC
) wxPaintDC::FindDCInCache((wxWindow
*) event
.GetEventObject()); 
4522         MSWDefWindowProc(WM_PAINT
, (WPARAM
) hDC
, 0); 
4527 bool wxWindowMSW::HandleEraseBkgnd(WXHDC hdc
) 
4529     wxDCTemp 
dc(hdc
, GetClientSize()); 
4532     dc
.SetWindow((wxWindow 
*)this); 
4534     wxEraseEvent 
event(m_windowId
, &dc
); 
4535     event
.SetEventObject(this); 
4536     bool rc 
= GetEventHandler()->ProcessEvent(event
); 
4538     // must be called manually as ~wxDC doesn't do anything for wxDCTemp 
4539     dc
.SelectOldObjects(hdc
); 
4544 void wxWindowMSW::OnEraseBackground(wxEraseEvent
& event
) 
4546     // standard non top level controls (i.e. except the dialogs) always erase 
4547     // their background themselves in HandleCtlColor() or have some control- 
4548     // specific ways to set the colours (common controls) 
4549     if ( IsOfStandardClass() && !IsTopLevel() ) 
4555     if ( GetBackgroundStyle() == wxBG_STYLE_CUSTOM 
) 
4557         // don't skip the event here, custom background means that the app 
4558         // is drawing it itself in its OnPaint(), so don't draw it at all 
4559         // now to avoid flicker 
4564     // do default background painting 
4565     if ( !DoEraseBackground(GetHdcOf(*event
.GetDC())) ) 
4567         // let the system paint the background 
4572 bool wxWindowMSW::DoEraseBackground(WXHDC hDC
) 
4574     HBRUSH hbr 
= (HBRUSH
)MSWGetBgBrush(hDC
); 
4578     wxFillRect(GetHwnd(), (HDC
)hDC
, hbr
); 
4584 wxWindowMSW::MSWGetBgBrushForChild(WXHDC 
WXUNUSED(hDC
), WXHWND hWnd
) 
4588         // our background colour applies to: 
4589         //  1. this window itself, always 
4590         //  2. all children unless the colour is "not inheritable" 
4591         //  3. even if it is not inheritable, our immediate transparent 
4592         //     children should still inherit it -- but not any transparent 
4593         //     children because it would look wrong if a child of non 
4594         //     transparent child would show our bg colour when the child itself 
4596         wxWindow 
*win 
= wxFindWinFromHandle(hWnd
); 
4599                     (win 
&& win
->HasTransparentBackground() && 
4600                         win
->GetParent() == this) ) 
4602             // draw children with the same colour as the parent 
4604                 brush 
= wxTheBrushList
->FindOrCreateBrush(GetBackgroundColour()); 
4606             return (WXHBRUSH
)GetHbrushOf(*brush
); 
4613 WXHBRUSH 
wxWindowMSW::MSWGetBgBrush(WXHDC hDC
, WXHWND hWndToPaint
) 
4616         hWndToPaint 
= GetHWND(); 
4618     for ( wxWindowMSW 
*win 
= this; win
; win 
= win
->GetParent() ) 
4620         WXHBRUSH hBrush 
= win
->MSWGetBgBrushForChild(hDC
, hWndToPaint
); 
4624         // background is not inherited beyond top level windows 
4625         if ( win
->IsTopLevel() ) 
4632 bool wxWindowMSW::HandlePrintClient(WXHDC hDC
) 
4634     // we receive this message when DrawThemeParentBackground() is 
4635     // called from def window proc of several controls under XP and we 
4636     // must draw properly themed background here 
4638     // note that naively I'd expect filling the client rect with the 
4639     // brush returned by MSWGetBgBrush() work -- but for some reason it 
4640     // doesn't and we have to call parents MSWPrintChild() which is 
4641     // supposed to call DrawThemeBackground() with appropriate params 
4643     // also note that in this case lParam == PRF_CLIENT but we're 
4644     // clearly expected to paint the background and nothing else! 
4646     if ( IsTopLevel() || InheritsBackgroundColour() ) 
4649     // sometimes we don't want the parent to handle it at all, instead 
4650     // return whatever value this window wants 
4651     if ( !MSWShouldPropagatePrintChild() ) 
4652         return MSWPrintChild(hDC
, (wxWindow 
*)this); 
4654     for ( wxWindow 
*win 
= GetParent(); win
; win 
= win
->GetParent() ) 
4656         if ( win
->MSWPrintChild(hDC
, (wxWindow 
*)this) ) 
4659         if ( win
->IsTopLevel() || win
->InheritsBackgroundColour() ) 
4666 // --------------------------------------------------------------------------- 
4667 // moving and resizing 
4668 // --------------------------------------------------------------------------- 
4670 bool wxWindowMSW::HandleMinimize() 
4672     wxIconizeEvent 
event(m_windowId
); 
4673     event
.SetEventObject(this); 
4675     return GetEventHandler()->ProcessEvent(event
); 
4678 bool wxWindowMSW::HandleMaximize() 
4680     wxMaximizeEvent 
event(m_windowId
); 
4681     event
.SetEventObject(this); 
4683     return GetEventHandler()->ProcessEvent(event
); 
4686 bool wxWindowMSW::HandleMove(int x
, int y
) 
4689     wxMoveEvent 
event(point
, m_windowId
); 
4690     event
.SetEventObject(this); 
4692     return GetEventHandler()->ProcessEvent(event
); 
4695 bool wxWindowMSW::HandleMoving(wxRect
& rect
) 
4697     wxMoveEvent 
event(rect
, m_windowId
); 
4698     event
.SetEventObject(this); 
4700     bool rc 
= GetEventHandler()->ProcessEvent(event
); 
4702         rect 
= event
.GetRect(); 
4706 bool wxWindowMSW::HandleEnterSizeMove() 
4708     wxMoveEvent 
event(wxPoint(0,0), m_windowId
); 
4709     event
.SetEventType(wxEVT_MOVE_START
); 
4710     event
.SetEventObject(this); 
4712     return GetEventHandler()->ProcessEvent(event
); 
4715 bool wxWindowMSW::HandleExitSizeMove() 
4717     wxMoveEvent 
event(wxPoint(0,0), m_windowId
); 
4718     event
.SetEventType(wxEVT_MOVE_END
); 
4719     event
.SetEventObject(this); 
4721     return GetEventHandler()->ProcessEvent(event
); 
4724 bool wxWindowMSW::HandleSize(int WXUNUSED(w
), int WXUNUSED(h
), WXUINT wParam
) 
4726 #if USE_DEFERRED_SIZING 
4727     // when we resize this window, its children are probably going to be 
4728     // repositioned as well, prepare to use DeferWindowPos() for them 
4729     int numChildren 
= 0; 
4730     for ( HWND child 
= ::GetWindow(GetHwndOf(this), GW_CHILD
); 
4732           child 
= ::GetWindow(child
, GW_HWNDNEXT
) ) 
4737     // Protect against valid m_hDWP being overwritten 
4738     bool useDefer 
= false; 
4740     if ( numChildren 
> 1 ) 
4744             m_hDWP 
= (WXHANDLE
)::BeginDeferWindowPos(numChildren
); 
4747                 wxLogLastError(_T("BeginDeferWindowPos")); 
4753 #endif // USE_DEFERRED_SIZING 
4755     // update this window size 
4756     bool processed 
= false; 
4760             wxFAIL_MSG( _T("unexpected WM_SIZE parameter") ); 
4761             // fall through nevertheless 
4765             // we're not interested in these messages at all 
4768         case SIZE_MINIMIZED
: 
4769             processed 
= HandleMinimize(); 
4772         case SIZE_MAXIMIZED
: 
4773             /* processed = */ HandleMaximize(); 
4774             // fall through to send a normal size event as well 
4777             // don't use w and h parameters as they specify the client size 
4778             // while according to the docs EVT_SIZE handler is supposed to 
4779             // receive the total size 
4780             wxSizeEvent 
event(GetSize(), m_windowId
); 
4781             event
.SetEventObject(this); 
4783             processed 
= GetEventHandler()->ProcessEvent(event
); 
4786 #if USE_DEFERRED_SIZING 
4787     // and finally change the positions of all child windows at once 
4788     if ( useDefer 
&& m_hDWP 
) 
4790         // reset m_hDWP to NULL so that child windows don't try to use our 
4791         // m_hDWP after we call EndDeferWindowPos() on it (this shouldn't 
4792         // happen anyhow normally but who knows what weird flow of control we 
4793         // may have depending on what the users EVT_SIZE handler does...) 
4794         HDWP hDWP 
= (HDWP
)m_hDWP
; 
4797         // do put all child controls in place at once 
4798         if ( !::EndDeferWindowPos(hDWP
) ) 
4800             wxLogLastError(_T("EndDeferWindowPos")); 
4803         // Reset our children's pending pos/size values. 
4804         for ( wxWindowList::compatibility_iterator node 
= GetChildren().GetFirst(); 
4806               node 
= node
->GetNext() ) 
4808             wxWindowMSW 
*child 
= node
->GetData(); 
4809             child
->m_pendingPosition 
= wxDefaultPosition
; 
4810             child
->m_pendingSize 
= wxDefaultSize
; 
4813 #endif // USE_DEFERRED_SIZING 
4818 bool wxWindowMSW::HandleSizing(wxRect
& rect
) 
4820     wxSizeEvent 
event(rect
, m_windowId
); 
4821     event
.SetEventObject(this); 
4823     bool rc 
= GetEventHandler()->ProcessEvent(event
); 
4825         rect 
= event
.GetRect(); 
4829 bool wxWindowMSW::HandleGetMinMaxInfo(void *WXUNUSED_IN_WINCE(mmInfo
)) 
4834     MINMAXINFO 
*info 
= (MINMAXINFO 
*)mmInfo
; 
4838     int minWidth 
= GetMinWidth(), 
4839         minHeight 
= GetMinHeight(), 
4840         maxWidth 
= GetMaxWidth(), 
4841         maxHeight 
= GetMaxHeight(); 
4843     if ( minWidth 
!= wxDefaultCoord 
) 
4845         info
->ptMinTrackSize
.x 
= minWidth
; 
4849     if ( minHeight 
!= wxDefaultCoord 
) 
4851         info
->ptMinTrackSize
.y 
= minHeight
; 
4855     if ( maxWidth 
!= wxDefaultCoord 
) 
4857         info
->ptMaxTrackSize
.x 
= maxWidth
; 
4861     if ( maxHeight 
!= wxDefaultCoord 
) 
4863         info
->ptMaxTrackSize
.y 
= maxHeight
; 
4871 // --------------------------------------------------------------------------- 
4873 // --------------------------------------------------------------------------- 
4875 bool wxWindowMSW::HandleCommand(WXWORD id
, WXWORD cmd
, WXHWND control
) 
4877 #if wxUSE_MENUS_NATIVE 
4878     if ( !cmd 
&& wxCurrentPopupMenu 
) 
4880         wxMenu 
*popupMenu 
= wxCurrentPopupMenu
; 
4881         wxCurrentPopupMenu 
= NULL
; 
4883         return popupMenu
->MSWCommand(cmd
, id
); 
4885 #endif // wxUSE_MENUS_NATIVE 
4887     wxWindow 
*win 
= NULL
; 
4889     // first try to find it from HWND - this works even with the broken 
4890     // programs using the same ids for different controls 
4893         win 
= wxFindWinFromHandle(control
); 
4899         // must cast to a signed type before comparing with other ids! 
4900         win 
= FindItem((signed short)id
); 
4905         return win
->MSWCommand(cmd
, id
); 
4908     // the messages sent from the in-place edit control used by the treectrl 
4909     // for label editing have id == 0, but they should _not_ be treated as menu 
4910     // messages (they are EN_XXX ones, in fact) so don't translate anything 
4911     // coming from a control to wxEVT_COMMAND_MENU_SELECTED 
4914         // If no child window, it may be an accelerator, e.g. for a popup menu 
4917         wxCommandEvent 
event(wxEVT_COMMAND_MENU_SELECTED
); 
4918         event
.SetEventObject(this); 
4922         return GetEventHandler()->ProcessEvent(event
); 
4926 #if wxUSE_SPINCTRL && !defined(__WXUNIVERSAL__) 
4927         // the text ctrl which is logically part of wxSpinCtrl sends WM_COMMAND 
4928         // notifications to its parent which we want to reflect back to 
4930         wxSpinCtrl 
*spin 
= wxSpinCtrl::GetSpinForTextCtrl(control
); 
4931         if ( spin 
&& spin
->ProcessTextCommand(cmd
, id
) ) 
4933 #endif // wxUSE_SPINCTRL 
4935 #if wxUSE_CHOICE && defined(__SMARTPHONE__) 
4936         // the listbox ctrl which is logically part of wxChoice sends WM_COMMAND 
4937         // notifications to its parent which we want to reflect back to 
4939         wxChoice 
*choice 
= wxChoice::GetChoiceForListBox(control
); 
4940         if ( choice 
&& choice
->MSWCommand(cmd
, id
) ) 
4948 // --------------------------------------------------------------------------- 
4950 // --------------------------------------------------------------------------- 
4952 void wxWindowMSW::InitMouseEvent(wxMouseEvent
& event
, 
4956     // our client coords are not quite the same as Windows ones 
4957     wxPoint pt 
= GetClientAreaOrigin(); 
4958     event
.m_x 
= x 
- pt
.x
; 
4959     event
.m_y 
= y 
- pt
.y
; 
4961     event
.m_shiftDown 
= (flags 
& MK_SHIFT
) != 0; 
4962     event
.m_controlDown 
= (flags 
& MK_CONTROL
) != 0; 
4963     event
.m_leftDown 
= (flags 
& MK_LBUTTON
) != 0; 
4964     event
.m_middleDown 
= (flags 
& MK_MBUTTON
) != 0; 
4965     event
.m_rightDown 
= (flags 
& MK_RBUTTON
) != 0; 
4966 #ifdef wxHAS_XBUTTON 
4967     event
.m_aux1Down 
= (flags 
& MK_XBUTTON1
) != 0; 
4968     event
.m_aux2Down 
= (flags 
& MK_XBUTTON2
) != 0; 
4969 #endif // wxHAS_XBUTTON 
4970     event
.m_altDown 
= ::GetKeyState(VK_MENU
) < 0; 
4973     event
.SetTimestamp(::GetMessageTime()); 
4976     event
.SetEventObject(this); 
4977     event
.SetId(GetId()); 
4979 #if wxUSE_MOUSEEVENT_HACK 
4980     gs_lastMouseEvent
.pos 
= ClientToScreen(wxPoint(x
, y
)); 
4981     gs_lastMouseEvent
.type 
= event
.GetEventType(); 
4982 #endif // wxUSE_MOUSEEVENT_HACK 
4986 // Windows doesn't send the mouse events to the static controls (which are 
4987 // transparent in the sense that their WM_NCHITTEST handler returns 
4988 // HTTRANSPARENT) at all but we want all controls to receive the mouse events 
4989 // and so we manually check if we don't have a child window under mouse and if 
4990 // we do, send the event to it instead of the window Windows had sent WM_XXX 
4993 // Notice that this is not done for the mouse move events because this could 
4994 // (would?) be too slow, but only for clicks which means that the static texts 
4995 // still don't get move, enter nor leave events. 
4996 static wxWindowMSW 
*FindWindowForMouseEvent(wxWindowMSW 
*win
, int *x
, int *y
) 
4998     wxCHECK_MSG( x 
&& y
, win
, _T("NULL pointer in FindWindowForMouseEvent") ); 
5000     // first try to find a non transparent child: this allows us to send events 
5001     // to a static text which is inside a static box, for example 
5002     POINT pt 
= { *x
, *y 
}; 
5003     HWND hwnd 
= GetHwndOf(win
), 
5007     hwndUnderMouse 
= ::ChildWindowFromPoint
 
5013     hwndUnderMouse 
= ::ChildWindowFromPointEx
 
5023     if ( !hwndUnderMouse 
|| hwndUnderMouse 
== hwnd 
) 
5025         // now try any child window at all 
5026         hwndUnderMouse 
= ::ChildWindowFromPoint(hwnd
, pt
); 
5029     // check that we have a child window which is susceptible to receive mouse 
5030     // events: for this it must be shown and enabled 
5031     if ( hwndUnderMouse 
&& 
5032             hwndUnderMouse 
!= hwnd 
&& 
5033                 ::IsWindowVisible(hwndUnderMouse
) && 
5034                     ::IsWindowEnabled(hwndUnderMouse
) ) 
5036         wxWindow 
*winUnderMouse 
= wxFindWinFromHandle((WXHWND
)hwndUnderMouse
); 
5037         if ( winUnderMouse 
) 
5039             // translate the mouse coords to the other window coords 
5040             win
->ClientToScreen(x
, y
); 
5041             winUnderMouse
->ScreenToClient(x
, y
); 
5043             win 
= winUnderMouse
; 
5049 #endif // __WXWINCE__ 
5051 bool wxWindowMSW::HandleMouseEvent(WXUINT msg
, int x
, int y
, WXUINT flags
) 
5053     // the mouse events take consecutive IDs from WM_MOUSEFIRST to 
5054     // WM_MOUSELAST, so it's enough to subtract WM_MOUSEMOVE == WM_MOUSEFIRST 
5055     // from the message id and take the value in the table to get wxWin event 
5057     static const wxEventType eventsMouse
[] = 
5068         wxEVT_MIDDLE_DCLICK
, 
5069         0, // this one is for wxEVT_MOTION which is not used here 
5078 #ifdef wxHAS_XBUTTON 
5079     // the same messages are used for both auxillary mouse buttons so we need 
5080     // to adjust the index manually 
5083         case WM_XBUTTONDOWN
: 
5085         case WM_XBUTTONDBLCLK
: 
5086             if ( flags 
& MK_XBUTTON2 
) 
5087                 msg 
+= wxEVT_AUX2_DOWN 
- wxEVT_AUX1_DOWN
; 
5089 #endif // wxHAS_XBUTTON 
5091     wxMouseEvent 
event(eventsMouse
[msg 
- WM_MOUSEMOVE
]); 
5092     InitMouseEvent(event
, x
, y
, flags
); 
5094     return GetEventHandler()->ProcessEvent(event
); 
5097 bool wxWindowMSW::HandleMouseMove(int x
, int y
, WXUINT flags
) 
5099     if ( !m_mouseInWindow 
) 
5101         // it would be wrong to assume that just because we get a mouse move 
5102         // event that the mouse is inside the window: although this is usually 
5103         // true, it is not if we had captured the mouse, so we need to check 
5104         // the mouse coordinates here 
5105         if ( !HasCapture() || IsMouseInWindow() ) 
5107             // Generate an ENTER event 
5108             m_mouseInWindow 
= true; 
5110 #ifdef HAVE_TRACKMOUSEEVENT 
5111             typedef BOOL (WINAPI 
*_TrackMouseEvent_t
)(LPTRACKMOUSEEVENT
); 
5113             static const _TrackMouseEvent_t
 
5114                 s_pfn_TrackMouseEvent 
= _TrackMouseEvent
; 
5115 #else // !__WXWINCE__ 
5116             static _TrackMouseEvent_t s_pfn_TrackMouseEvent
; 
5117             static bool s_initDone 
= false; 
5122                 wxDynamicLibrary 
dllComCtl32(_T("comctl32.dll"), wxDL_VERBATIM
); 
5123                 if ( dllComCtl32
.IsLoaded() ) 
5125                     s_pfn_TrackMouseEvent 
= (_TrackMouseEvent_t
) 
5126                         dllComCtl32
.GetSymbol(_T("_TrackMouseEvent")); 
5131                 // notice that it's ok to unload comctl32.dll here as it won't 
5132                 // be really unloaded, being still in use because we link to it 
5136             if ( s_pfn_TrackMouseEvent 
) 
5137 #endif // __WXWINCE__/!__WXWINCE__ 
5139                 WinStruct
<TRACKMOUSEEVENT
> trackinfo
; 
5141                 trackinfo
.dwFlags 
= TME_LEAVE
; 
5142                 trackinfo
.hwndTrack 
= GetHwnd(); 
5144                 (*s_pfn_TrackMouseEvent
)(&trackinfo
); 
5146 #endif // HAVE_TRACKMOUSEEVENT 
5148             wxMouseEvent 
event(wxEVT_ENTER_WINDOW
); 
5149             InitMouseEvent(event
, x
, y
, flags
); 
5151             (void)GetEventHandler()->ProcessEvent(event
); 
5154 #ifdef HAVE_TRACKMOUSEEVENT 
5155     else // mouse not in window 
5157         // Check if we need to send a LEAVE event 
5158         // Windows doesn't send WM_MOUSELEAVE if the mouse has been captured so 
5159         // send it here if we are using native mouse leave tracking 
5160         if ( HasCapture() && !IsMouseInWindow() ) 
5162             GenerateMouseLeave(); 
5165 #endif // HAVE_TRACKMOUSEEVENT 
5167 #if wxUSE_MOUSEEVENT_HACK 
5168     // Windows often generates mouse events even if mouse position hasn't 
5169     // changed (http://article.gmane.org/gmane.comp.lib.wxwidgets.devel/66576) 
5171     // Filter this out as it can result in unexpected behaviour compared to 
5173     if ( gs_lastMouseEvent
.type 
== wxEVT_RIGHT_DOWN 
|| 
5174          gs_lastMouseEvent
.type 
== wxEVT_LEFT_DOWN 
|| 
5175          gs_lastMouseEvent
.type 
== wxEVT_MIDDLE_DOWN 
|| 
5176          gs_lastMouseEvent
.type 
== wxEVT_MOTION 
) 
5178         if ( ClientToScreen(wxPoint(x
, y
)) == gs_lastMouseEvent
.pos 
) 
5180             gs_lastMouseEvent
.type 
= wxEVT_MOTION
; 
5185 #endif // wxUSE_MOUSEEVENT_HACK 
5187     return HandleMouseEvent(WM_MOUSEMOVE
, x
, y
, flags
); 
5191 bool wxWindowMSW::HandleMouseWheel(WXWPARAM wParam
, WXLPARAM lParam
) 
5193 #if wxUSE_MOUSEWHEEL 
5194     // notice that WM_MOUSEWHEEL position is in screen coords (as it's 
5195     // forwarded up to the parent by DefWindowProc()) and not in the client 
5196     // ones as all the other messages, translate them to the client coords for 
5199         pt 
= ScreenToClient(wxPoint(GET_X_LPARAM(lParam
), GET_Y_LPARAM(lParam
))); 
5200     wxMouseEvent 
event(wxEVT_MOUSEWHEEL
); 
5201     InitMouseEvent(event
, pt
.x
, pt
.y
, LOWORD(wParam
)); 
5202     event
.m_wheelRotation 
= (short)HIWORD(wParam
); 
5203     event
.m_wheelDelta 
= WHEEL_DELTA
; 
5205     static int s_linesPerRotation 
= -1; 
5206     if ( s_linesPerRotation 
== -1 ) 
5208         if ( !::SystemParametersInfo(SPI_GETWHEELSCROLLLINES
, 0, 
5209                                      &s_linesPerRotation
, 0)) 
5211             // this is not supposed to happen 
5212             wxLogLastError(_T("SystemParametersInfo(GETWHEELSCROLLLINES)")); 
5214             // the default is 3, so use it if SystemParametersInfo() failed 
5215             s_linesPerRotation 
= 3; 
5219     event
.m_linesPerAction 
= s_linesPerRotation
; 
5220     return GetEventHandler()->ProcessEvent(event
); 
5222 #else // !wxUSE_MOUSEWHEEL 
5223     wxUnusedVar(wParam
); 
5224     wxUnusedVar(lParam
); 
5227 #endif // wxUSE_MOUSEWHEEL/!wxUSE_MOUSEWHEEL 
5230 void wxWindowMSW::GenerateMouseLeave() 
5232     m_mouseInWindow 
= false; 
5235     if ( wxIsShiftDown() ) 
5237     if ( wxIsCtrlDown() ) 
5238         state 
|= MK_CONTROL
; 
5240     // Only the high-order bit should be tested 
5241     if ( GetKeyState( VK_LBUTTON 
) & (1<<15) ) 
5242         state 
|= MK_LBUTTON
; 
5243     if ( GetKeyState( VK_MBUTTON 
) & (1<<15) ) 
5244         state 
|= MK_MBUTTON
; 
5245     if ( GetKeyState( VK_RBUTTON 
) & (1<<15) ) 
5246         state 
|= MK_RBUTTON
; 
5250     if ( !::GetCursorPosWinCE(&pt
) ) 
5252     if ( !::GetCursorPos(&pt
) ) 
5255         wxLogLastError(_T("GetCursorPos")); 
5258     // we need to have client coordinates here for symmetry with 
5259     // wxEVT_ENTER_WINDOW 
5260     RECT rect 
= wxGetWindowRect(GetHwnd()); 
5264     wxMouseEvent 
event(wxEVT_LEAVE_WINDOW
); 
5265     InitMouseEvent(event
, pt
.x
, pt
.y
, state
); 
5267     (void)GetEventHandler()->ProcessEvent(event
); 
5270 // --------------------------------------------------------------------------- 
5271 // keyboard handling 
5272 // --------------------------------------------------------------------------- 
5274 // create the key event of the given type for the given key - used by 
5275 // HandleChar and HandleKeyDown/Up 
5276 wxKeyEvent 
wxWindowMSW::CreateKeyEvent(wxEventType evType
, 
5279                                        WXWPARAM wParam
) const 
5281     wxKeyEvent 
event(evType
); 
5282     event
.SetId(GetId()); 
5283     event
.m_shiftDown 
= wxIsShiftDown(); 
5284     event
.m_controlDown 
= wxIsCtrlDown(); 
5285     event
.m_altDown 
= (HIWORD(lParam
) & KF_ALTDOWN
) == KF_ALTDOWN
; 
5287     event
.SetEventObject((wxWindow 
*)this); // const_cast 
5288     event
.m_keyCode 
= id
; 
5290     event
.m_uniChar 
= (wxChar
) wParam
; 
5292     event
.m_rawCode 
= (wxUint32
) wParam
; 
5293     event
.m_rawFlags 
= (wxUint32
) lParam
; 
5295     event
.SetTimestamp(::GetMessageTime()); 
5298     // translate the position to client coords 
5301     GetCursorPosWinCE(&pt
); 
5306     GetWindowRect(GetHwnd(),&rect
); 
5316 // isASCII is true only when we're called from WM_CHAR handler and not from 
5318 bool wxWindowMSW::HandleChar(WXWPARAM wParam
, WXLPARAM lParam
, bool isASCII
) 
5325     else // we're called from WM_KEYDOWN 
5327         // don't pass lParam to wxCharCodeMSWToWX() here because we don't want 
5328         // to get numpad key codes: CHAR events should use the logical keys 
5329         // such as WXK_HOME instead of WXK_NUMPAD_HOME which is for KEY events 
5330         id 
= wxCharCodeMSWToWX(wParam
); 
5333             // it's ASCII and will be processed here only when called from 
5334             // WM_CHAR (i.e. when isASCII = true), don't process it now 
5339     wxKeyEvent 
event(CreateKeyEvent(wxEVT_CHAR
, id
, lParam
, wParam
)); 
5341     // the alphanumeric keys produced by pressing AltGr+something on European 
5342     // keyboards have both Ctrl and Alt modifiers which may confuse the user 
5343     // code as, normally, keys with Ctrl and/or Alt don't result in anything 
5344     // alphanumeric, so pretend that there are no modifiers at all (the 
5345     // KEY_DOWN event would still have the correct modifiers if they're really 
5347     if ( event
.m_controlDown 
&& event
.m_altDown 
&& 
5348             (id 
>= 32 && id 
< 256) ) 
5350         event
.m_controlDown 
= 
5351         event
.m_altDown 
= false; 
5354     return GetEventHandler()->ProcessEvent(event
); 
5357 bool wxWindowMSW::HandleKeyDown(WXWPARAM wParam
, WXLPARAM lParam
) 
5359     int id 
= wxCharCodeMSWToWX(wParam
, lParam
); 
5363         // normal ASCII char 
5367     wxKeyEvent 
event(CreateKeyEvent(wxEVT_KEY_DOWN
, id
, lParam
, wParam
)); 
5368     return GetEventHandler()->ProcessEvent(event
); 
5371 bool wxWindowMSW::HandleKeyUp(WXWPARAM wParam
, WXLPARAM lParam
) 
5373     int id 
= wxCharCodeMSWToWX(wParam
, lParam
); 
5377         // normal ASCII char 
5381     wxKeyEvent 
event(CreateKeyEvent(wxEVT_KEY_UP
, id
, lParam
, wParam
)); 
5382     return GetEventHandler()->ProcessEvent(event
); 
5386 int wxWindowMSW::HandleMenuChar(int WXUNUSED_IN_WINCE(chAccel
), 
5387                                 WXLPARAM 
WXUNUSED_IN_WINCE(lParam
)) 
5389     // FIXME: implement GetMenuItemCount for WinCE, possibly 
5390     // in terms of GetMenuItemInfo 
5392     const HMENU hmenu 
= (HMENU
)lParam
; 
5396     mii
.cbSize 
= sizeof(MENUITEMINFO
); 
5398     // we could use MIIM_FTYPE here as we only need to know if the item is 
5399     // ownerdrawn or not and not dwTypeData which MIIM_TYPE also returns, but 
5400     // MIIM_FTYPE is not supported under Win95 
5401     mii
.fMask 
= MIIM_TYPE 
| MIIM_DATA
; 
5403     // find if we have this letter in any owner drawn item 
5404     const int count 
= ::GetMenuItemCount(hmenu
); 
5405     for ( int i 
= 0; i 
< count
; i
++ ) 
5407         // previous loop iteration could modify it, reset it back before 
5408         // calling GetMenuItemInfo() to prevent it from overflowing dwTypeData 
5411         if ( ::GetMenuItemInfo(hmenu
, i
, TRUE
, &mii
) ) 
5413             if ( mii
.fType 
== MFT_OWNERDRAW 
) 
5415                 //  dwItemData member of the MENUITEMINFO is a 
5416                 //  pointer to the associated wxMenuItem -- see the 
5417                 //  menu creation code 
5418                 wxMenuItem 
*item 
= (wxMenuItem
*)mii
.dwItemData
; 
5420                 const wxChar 
*p 
= wxStrchr(item
->GetItemLabel().wx_str(), _T('&')); 
5423                     if ( *p 
== _T('&') ) 
5425                         // this is not the accel char, find the real one 
5426                         p 
= wxStrchr(p 
+ 1, _T('&')); 
5428                     else // got the accel char 
5430                         // FIXME-UNICODE: this comparison doesn't risk to work 
5431                         // for non ASCII accelerator characters I'm afraid, but 
5433                         if ( (wchar_t)wxToupper(*p
) == (wchar_t)chAccel 
) 
5439                             // this one doesn't match 
5446         else // failed to get the menu text? 
5448             // it's not fatal, so don't show error, but still log it 
5449             wxLogLastError(_T("GetMenuItemInfo")); 
5456 bool wxWindowMSW::HandleClipboardEvent( WXUINT nMsg 
) 
5458     const wxEventType type 
= ( nMsg 
== WM_CUT 
) ? wxEVT_COMMAND_TEXT_CUT 
: 
5459                              ( nMsg 
== WM_COPY 
) ? wxEVT_COMMAND_TEXT_COPY 
: 
5460                            /*( nMsg == WM_PASTE ) ? */ wxEVT_COMMAND_TEXT_PASTE
; 
5461     wxClipboardTextEvent 
evt(type
, GetId()); 
5463     evt
.SetEventObject(this); 
5465     return GetEventHandler()->ProcessEvent(evt
); 
5467 #endif // wxUSE_MENUS 
5469 // --------------------------------------------------------------------------- 
5471 // --------------------------------------------------------------------------- 
5473 bool wxWindowMSW::HandleJoystickEvent(WXUINT msg
, int x
, int y
, WXUINT flags
) 
5477     if ( flags 
& JOY_BUTTON1CHG 
) 
5478         change 
= wxJOY_BUTTON1
; 
5479     if ( flags 
& JOY_BUTTON2CHG 
) 
5480         change 
= wxJOY_BUTTON2
; 
5481     if ( flags 
& JOY_BUTTON3CHG 
) 
5482         change 
= wxJOY_BUTTON3
; 
5483     if ( flags 
& JOY_BUTTON4CHG 
) 
5484         change 
= wxJOY_BUTTON4
; 
5487     if ( flags 
& JOY_BUTTON1 
) 
5488         buttons 
|= wxJOY_BUTTON1
; 
5489     if ( flags 
& JOY_BUTTON2 
) 
5490         buttons 
|= wxJOY_BUTTON2
; 
5491     if ( flags 
& JOY_BUTTON3 
) 
5492         buttons 
|= wxJOY_BUTTON3
; 
5493     if ( flags 
& JOY_BUTTON4 
) 
5494         buttons 
|= wxJOY_BUTTON4
; 
5496     // the event ids aren't consecutive so we can't use table based lookup 
5498     wxEventType eventType
; 
5503             eventType 
= wxEVT_JOY_MOVE
; 
5508             eventType 
= wxEVT_JOY_MOVE
; 
5513             eventType 
= wxEVT_JOY_ZMOVE
; 
5518             eventType 
= wxEVT_JOY_ZMOVE
; 
5521         case MM_JOY1BUTTONDOWN
: 
5523             eventType 
= wxEVT_JOY_BUTTON_DOWN
; 
5526         case MM_JOY2BUTTONDOWN
: 
5528             eventType 
= wxEVT_JOY_BUTTON_DOWN
; 
5531         case MM_JOY1BUTTONUP
: 
5533             eventType 
= wxEVT_JOY_BUTTON_UP
; 
5536         case MM_JOY2BUTTONUP
: 
5538             eventType 
= wxEVT_JOY_BUTTON_UP
; 
5542             wxFAIL_MSG(wxT("no such joystick event")); 
5547     wxJoystickEvent 
event(eventType
, buttons
, joystick
, change
); 
5548     event
.SetPosition(wxPoint(x
, y
)); 
5549     event
.SetEventObject(this); 
5551     return GetEventHandler()->ProcessEvent(event
); 
5561 // --------------------------------------------------------------------------- 
5563 // --------------------------------------------------------------------------- 
5565 bool wxWindowMSW::MSWOnScroll(int orientation
, WXWORD wParam
, 
5566                               WXWORD pos
, WXHWND control
) 
5568     if ( control 
&& control 
!= m_hWnd 
) // Prevent infinite recursion 
5570         wxWindow 
*child 
= wxFindWinFromHandle(control
); 
5572             return child
->MSWOnScroll(orientation
, wParam
, pos
, control
); 
5575     wxScrollWinEvent event
; 
5576     event
.SetPosition(pos
); 
5577     event
.SetOrientation(orientation
); 
5578     event
.SetEventObject(this); 
5583         event
.SetEventType(wxEVT_SCROLLWIN_TOP
); 
5587         event
.SetEventType(wxEVT_SCROLLWIN_BOTTOM
); 
5591         event
.SetEventType(wxEVT_SCROLLWIN_LINEUP
); 
5595         event
.SetEventType(wxEVT_SCROLLWIN_LINEDOWN
); 
5599         event
.SetEventType(wxEVT_SCROLLWIN_PAGEUP
); 
5603         event
.SetEventType(wxEVT_SCROLLWIN_PAGEDOWN
); 
5606     case SB_THUMBPOSITION
: 
5608         // under Win32, the scrollbar range and position are 32 bit integers, 
5609         // but WM_[HV]SCROLL only carry the low 16 bits of them, so we must 
5610         // explicitly query the scrollbar for the correct position (this must 
5611         // be done only for these two SB_ events as they are the only one 
5612         // carrying the scrollbar position) 
5614             WinStruct
<SCROLLINFO
> scrollInfo
; 
5615             scrollInfo
.fMask 
= SIF_TRACKPOS
; 
5617             if ( !::GetScrollInfo(GetHwnd(), 
5618                                   orientation 
== wxHORIZONTAL 
? SB_HORZ
 
5622                 // Not necessarily an error, if there are no scrollbars yet. 
5623                 // wxLogLastError(_T("GetScrollInfo")); 
5626             event
.SetPosition(scrollInfo
.nTrackPos
); 
5629         event
.SetEventType( wParam 
== SB_THUMBPOSITION
 
5630                                 ? wxEVT_SCROLLWIN_THUMBRELEASE
 
5631                                 : wxEVT_SCROLLWIN_THUMBTRACK 
); 
5638     return GetEventHandler()->ProcessEvent(event
); 
5641 // ---------------------------------------------------------------------------- 
5642 // custom message handlers 
5643 // ---------------------------------------------------------------------------- 
5646 wxWindowMSW::MSWRegisterMessageHandler(int msg
, MSWMessageHandler handler
) 
5648     wxCHECK_MSG( gs_messageHandlers
.find(msg
) == gs_messageHandlers
.end(), 
5649                  false, _T("registering handler for the same message twice") ); 
5651     gs_messageHandlers
[msg
] = handler
; 
5656 wxWindowMSW::MSWUnregisterMessageHandler(int msg
, MSWMessageHandler handler
) 
5658     const MSWMessageHandlers::iterator i 
= gs_messageHandlers
.find(msg
); 
5659     wxCHECK_RET( i 
!= gs_messageHandlers
.end() && i
->second 
== handler
, 
5660                  _T("unregistering non-registered handler?") ); 
5662     gs_messageHandlers
.erase(i
); 
5665 // =========================================================================== 
5667 // =========================================================================== 
5669 void wxGetCharSize(WXHWND wnd
, int *x
, int *y
, const wxFont
& the_font
) 
5672     HDC dc 
= ::GetDC((HWND
) wnd
); 
5675     //    the_font.UseResource(); 
5676     //    the_font.RealizeResource(); 
5677     HFONT fnt 
= (HFONT
)the_font
.GetResourceHandle(); // const_cast 
5679         was 
= (HFONT
) SelectObject(dc
,fnt
); 
5681     GetTextMetrics(dc
, &tm
); 
5684         SelectObject(dc
,was
); 
5686     ReleaseDC((HWND
)wnd
, dc
); 
5689         *x 
= tm
.tmAveCharWidth
; 
5691         *y 
= tm
.tmHeight 
+ tm
.tmExternalLeading
; 
5693     //   the_font.ReleaseResource(); 
5696 // use the "extended" bit (24) of lParam to distinguish extended keys 
5697 // from normal keys as the same key is sent 
5699 int ChooseNormalOrExtended(int lParam
, int keyNormal
, int keyExtended
) 
5701     // except that if lParam is 0, it means we don't have real lParam from 
5702     // WM_KEYDOWN but are just translating just a VK constant (e.g. done from 
5703     // msw/treectrl.cpp when processing TVN_KEYDOWN) -- then assume this is a 
5704     // non-numpad (hence extended) key as this is a more common case 
5705     return !lParam 
|| (lParam 
& (1 << 24)) ? keyExtended 
: keyNormal
; 
5708 // this array contains the Windows virtual key codes which map one to one to 
5709 // WXK_xxx constants and is used in wxCharCodeMSWToWX/WXToMSW() below 
5711 // note that keys having a normal and numpad version (e.g. WXK_HOME and 
5712 // WXK_NUMPAD_HOME) are not included in this table as the mapping is not 1-to-1 
5713 static const struct wxKeyMapping
 
5717 } gs_specialKeys
[] = 
5719     { VK_CANCEL
,        WXK_CANCEL 
}, 
5720     { VK_BACK
,          WXK_BACK 
}, 
5721     { VK_TAB
,           WXK_TAB 
}, 
5722     { VK_CLEAR
,         WXK_CLEAR 
}, 
5723     { VK_SHIFT
,         WXK_SHIFT 
}, 
5724     { VK_CONTROL
,       WXK_CONTROL 
}, 
5725     { VK_MENU 
,         WXK_ALT 
}, 
5726     { VK_PAUSE
,         WXK_PAUSE 
}, 
5727     { VK_CAPITAL
,       WXK_CAPITAL 
}, 
5728     { VK_SPACE
,         WXK_SPACE 
}, 
5729     { VK_ESCAPE
,        WXK_ESCAPE 
}, 
5730     { VK_SELECT
,        WXK_SELECT 
}, 
5731     { VK_PRINT
,         WXK_PRINT 
}, 
5732     { VK_EXECUTE
,       WXK_EXECUTE 
}, 
5733     { VK_SNAPSHOT
,      WXK_SNAPSHOT 
}, 
5734     { VK_HELP
,          WXK_HELP 
}, 
5736     { VK_NUMPAD0
,       WXK_NUMPAD0 
}, 
5737     { VK_NUMPAD1
,       WXK_NUMPAD1 
}, 
5738     { VK_NUMPAD2
,       WXK_NUMPAD2 
}, 
5739     { VK_NUMPAD3
,       WXK_NUMPAD3 
}, 
5740     { VK_NUMPAD4
,       WXK_NUMPAD4 
}, 
5741     { VK_NUMPAD5
,       WXK_NUMPAD5 
}, 
5742     { VK_NUMPAD6
,       WXK_NUMPAD6 
}, 
5743     { VK_NUMPAD7
,       WXK_NUMPAD7 
}, 
5744     { VK_NUMPAD8
,       WXK_NUMPAD8 
}, 
5745     { VK_NUMPAD9
,       WXK_NUMPAD9 
}, 
5746     { VK_MULTIPLY
,      WXK_NUMPAD_MULTIPLY 
}, 
5747     { VK_ADD
,           WXK_NUMPAD_ADD 
}, 
5748     { VK_SUBTRACT
,      WXK_NUMPAD_SUBTRACT 
}, 
5749     { VK_DECIMAL
,       WXK_NUMPAD_DECIMAL 
}, 
5750     { VK_DIVIDE
,        WXK_NUMPAD_DIVIDE 
}, 
5761     { VK_F10
,           WXK_F10 
}, 
5762     { VK_F11
,           WXK_F11 
}, 
5763     { VK_F12
,           WXK_F12 
}, 
5764     { VK_F13
,           WXK_F13 
}, 
5765     { VK_F14
,           WXK_F14 
}, 
5766     { VK_F15
,           WXK_F15 
}, 
5767     { VK_F16
,           WXK_F16 
}, 
5768     { VK_F17
,           WXK_F17 
}, 
5769     { VK_F18
,           WXK_F18 
}, 
5770     { VK_F19
,           WXK_F19 
}, 
5771     { VK_F20
,           WXK_F20 
}, 
5772     { VK_F21
,           WXK_F21 
}, 
5773     { VK_F22
,           WXK_F22 
}, 
5774     { VK_F23
,           WXK_F23 
}, 
5775     { VK_F24
,           WXK_F24 
}, 
5777     { VK_NUMLOCK
,       WXK_NUMLOCK 
}, 
5778     { VK_SCROLL
,        WXK_SCROLL 
}, 
5781     { VK_LWIN
,          WXK_WINDOWS_LEFT 
}, 
5782     { VK_RWIN
,          WXK_WINDOWS_RIGHT 
}, 
5783     { VK_APPS
,          WXK_WINDOWS_MENU 
}, 
5784 #endif // VK_APPS defined 
5787 // Returns 0 if was a normal ASCII value, not a special key. This indicates that 
5788 // the key should be ignored by WM_KEYDOWN and processed by WM_CHAR instead. 
5789 int wxCharCodeMSWToWX(int vk
, WXLPARAM lParam
) 
5791     // check the table first 
5792     for ( size_t n 
= 0; n 
< WXSIZEOF(gs_specialKeys
); n
++ ) 
5794         if ( gs_specialKeys
[n
].vk 
== vk 
) 
5795             return gs_specialKeys
[n
].wxk
; 
5798     // keys requiring special handling 
5802         // the mapping for these keys may be incorrect on non-US keyboards so 
5803         // maybe we shouldn't map them to ASCII values at all 
5804         case VK_OEM_1
:      wxk 
= ';'; break; 
5805         case VK_OEM_PLUS
:   wxk 
= '+'; break; 
5806         case VK_OEM_COMMA
:  wxk 
= ','; break; 
5807         case VK_OEM_MINUS
:  wxk 
= '-'; break; 
5808         case VK_OEM_PERIOD
: wxk 
= '.'; break; 
5809         case VK_OEM_2
:      wxk 
= '/'; break; 
5810         case VK_OEM_3
:      wxk 
= '~'; break; 
5811         case VK_OEM_4
:      wxk 
= '['; break; 
5812         case VK_OEM_5
:      wxk 
= '\\'; break; 
5813         case VK_OEM_6
:      wxk 
= ']'; break; 
5814         case VK_OEM_7
:      wxk 
= '\''; break; 
5816         // handle extended keys 
5818             wxk 
= ChooseNormalOrExtended(lParam
, WXK_NUMPAD_PAGEUP
, WXK_PAGEUP
); 
5822             wxk 
= ChooseNormalOrExtended(lParam
, WXK_NUMPAD_PAGEDOWN
, WXK_PAGEDOWN
); 
5826             wxk 
= ChooseNormalOrExtended(lParam
, WXK_NUMPAD_END
, WXK_END
); 
5830             wxk 
= ChooseNormalOrExtended(lParam
, WXK_NUMPAD_HOME
, WXK_HOME
); 
5834             wxk 
= ChooseNormalOrExtended(lParam
, WXK_NUMPAD_LEFT
, WXK_LEFT
); 
5838             wxk 
= ChooseNormalOrExtended(lParam
, WXK_NUMPAD_UP
, WXK_UP
); 
5842             wxk 
= ChooseNormalOrExtended(lParam
, WXK_NUMPAD_RIGHT
, WXK_RIGHT
); 
5846             wxk 
= ChooseNormalOrExtended(lParam
, WXK_NUMPAD_DOWN
, WXK_DOWN
); 
5850             wxk 
= ChooseNormalOrExtended(lParam
, WXK_NUMPAD_INSERT
, WXK_INSERT
); 
5854             wxk 
= ChooseNormalOrExtended(lParam
, WXK_NUMPAD_DELETE
, WXK_DELETE
); 
5858             // don't use ChooseNormalOrExtended() here as the keys are reversed 
5859             // here: numpad enter is the extended one 
5860             wxk 
= lParam 
&& (lParam 
& (1 << 24)) ? WXK_NUMPAD_ENTER 
: WXK_RETURN
; 
5870 WXWORD 
wxCharCodeWXToMSW(int wxk
, bool *isVirtual
) 
5875     // check the table first 
5876     for ( size_t n 
= 0; n 
< WXSIZEOF(gs_specialKeys
); n
++ ) 
5878         if ( gs_specialKeys
[n
].wxk 
== wxk 
) 
5879             return gs_specialKeys
[n
].vk
; 
5882     // and then check for special keys not included in the table 
5887         case WXK_NUMPAD_PAGEUP
: 
5892         case WXK_NUMPAD_PAGEDOWN
: 
5897         case WXK_NUMPAD_END
: 
5902         case WXK_NUMPAD_HOME
: 
5907         case WXK_NUMPAD_LEFT
: 
5917         case WXK_NUMPAD_RIGHT
: 
5922         case WXK_NUMPAD_DOWN
: 
5927         case WXK_NUMPAD_INSERT
: 
5932         case WXK_NUMPAD_DELETE
: 
5946 #ifndef SM_SWAPBUTTON 
5947     #define SM_SWAPBUTTON 23 
5950 // small helper for wxGetKeyState() and wxGetMouseState() 
5951 static inline bool wxIsKeyDown(WXWORD vk
) 
5956             if (GetSystemMetrics(SM_SWAPBUTTON
)) vk 
= VK_RBUTTON
; 
5959             if (GetSystemMetrics(SM_SWAPBUTTON
)) vk 
= VK_LBUTTON
; 
5962     // the low order bit indicates whether the key was pressed since the last 
5963     // call and the high order one indicates whether it is down right now and 
5964     // we only want that one 
5965     return (GetAsyncKeyState(vk
) & (1<<15)) != 0; 
5968 bool wxGetKeyState(wxKeyCode key
) 
5970     // although this does work under Windows, it is not supported under other 
5971     // platforms so don't allow it, you must use wxGetMouseState() instead 
5972     wxASSERT_MSG( key 
!= VK_LBUTTON 
&& 
5973                     key 
!= VK_RBUTTON 
&& 
5975                     wxT("can't use wxGetKeyState() for mouse buttons") ); 
5977     const WXWORD vk 
= wxCharCodeWXToMSW(key
); 
5979     // if the requested key is a LED key, return true if the led is pressed 
5980     if ( key 
== WXK_NUMLOCK 
|| key 
== WXK_CAPITAL 
|| key 
== WXK_SCROLL 
) 
5982         // low order bit means LED is highlighted and high order one means the 
5983         // key is down; for compatibility with the other ports return true if 
5984         // either one is set 
5985         return GetKeyState(vk
) != 0; 
5990         return wxIsKeyDown(vk
); 
5995 wxMouseState 
wxGetMouseState() 
5999     GetCursorPos( &pt 
); 
6003     ms
.SetLeftDown(wxIsKeyDown(VK_LBUTTON
)); 
6004     ms
.SetMiddleDown(wxIsKeyDown(VK_MBUTTON
)); 
6005     ms
.SetRightDown(wxIsKeyDown(VK_RBUTTON
)); 
6006 #ifdef wxHAS_XBUTTON 
6007     ms
.SetAux1Down(wxIsKeyDown(VK_XBUTTON1
)); 
6008     ms
.SetAux2Down(wxIsKeyDown(VK_XBUTTON2
)); 
6009 #endif // wxHAS_XBUTTON 
6011     ms
.SetControlDown(wxIsKeyDown(VK_CONTROL
)); 
6012     ms
.SetShiftDown(wxIsKeyDown(VK_SHIFT
)); 
6013     ms
.SetAltDown(wxIsKeyDown(VK_MENU
)); 
6014 //    ms.SetMetaDown(); 
6020 wxWindow 
*wxGetActiveWindow() 
6022     HWND hWnd 
= GetActiveWindow(); 
6025         return wxFindWinFromHandle((WXHWND
) hWnd
); 
6030 extern wxWindow 
*wxGetWindowFromHWND(WXHWND hWnd
) 
6032     HWND hwnd 
= (HWND
)hWnd
; 
6034     // For a radiobutton, we get the radiobox from GWL_USERDATA (which is set 
6035     // by code in msw/radiobox.cpp), for all the others we just search up the 
6037     wxWindow 
*win 
= (wxWindow 
*)NULL
; 
6040         win 
= wxFindWinFromHandle((WXHWND
)hwnd
); 
6044             // native radiobuttons return DLGC_RADIOBUTTON here and for any 
6045             // wxWindow class which overrides WM_GETDLGCODE processing to 
6046             // do it as well, win would be already non NULL 
6047             if ( ::SendMessage(hwnd
, WM_GETDLGCODE
, 0, 0) & DLGC_RADIOBUTTON 
) 
6049                 win 
= (wxWindow 
*)wxGetWindowUserData(hwnd
); 
6051             //else: it's a wxRadioButton, not a radiobutton from wxRadioBox 
6052 #endif // wxUSE_RADIOBOX 
6054             // spin control text buddy window should be mapped to spin ctrl 
6055             // itself so try it too 
6056 #if wxUSE_SPINCTRL && !defined(__WXUNIVERSAL__) 
6059                 win 
= wxSpinCtrl::GetSpinForTextCtrl((WXHWND
)hwnd
); 
6061 #endif // wxUSE_SPINCTRL 
6065     while ( hwnd 
&& !win 
) 
6067         // this is a really ugly hack needed to avoid mistakenly returning the 
6068         // parent frame wxWindow for the find/replace modeless dialog HWND - 
6069         // this, in turn, is needed to call IsDialogMessage() from 
6070         // wxApp::ProcessMessage() as for this we must return NULL from here 
6072         // FIXME: this is clearly not the best way to do it but I think we'll 
6073         //        need to change HWND <-> wxWindow code more heavily than I can 
6074         //        do it now to fix it 
6075 #ifndef __WXMICROWIN__ 
6076         if ( ::GetWindow(hwnd
, GW_OWNER
) ) 
6078             // it's a dialog box, don't go upwards 
6083         hwnd 
= ::GetParent(hwnd
); 
6084         win 
= wxFindWinFromHandle((WXHWND
)hwnd
); 
6090 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__) 
6092 // Windows keyboard hook. Allows interception of e.g. F1, ESCAPE 
6093 // in active frames and dialogs, regardless of where the focus is. 
6094 static HHOOK wxTheKeyboardHook 
= 0; 
6095 static FARPROC wxTheKeyboardHookProc 
= 0; 
6096 int APIENTRY _EXPORT
 
6097 wxKeyboardHook(int nCode
, WORD wParam
, DWORD lParam
); 
6099 void wxSetKeyboardHook(bool doIt
) 
6103         wxTheKeyboardHookProc 
= MakeProcInstance((FARPROC
) wxKeyboardHook
, wxGetInstance()); 
6104         wxTheKeyboardHook 
= SetWindowsHookEx(WH_KEYBOARD
, (HOOKPROC
) wxTheKeyboardHookProc
, wxGetInstance(), 
6106             GetCurrentThreadId() 
6107         //      (DWORD)GetCurrentProcess()); // This is another possibility. Which is right? 
6112         UnhookWindowsHookEx(wxTheKeyboardHook
); 
6116 int APIENTRY _EXPORT
 
6117 wxKeyboardHook(int nCode
, WORD wParam
, DWORD lParam
) 
6119     DWORD hiWord 
= HIWORD(lParam
); 
6120     if ( nCode 
!= HC_NOREMOVE 
&& ((hiWord 
& KF_UP
) == 0) ) 
6122         int id 
= wxCharCodeMSWToWX(wParam
, lParam
); 
6125             wxKeyEvent 
event(wxEVT_CHAR_HOOK
); 
6126             if ( (HIWORD(lParam
) & KF_ALTDOWN
) == KF_ALTDOWN 
) 
6127                 event
.m_altDown 
= true; 
6129             event
.SetEventObject(NULL
); 
6130             event
.m_keyCode 
= id
; 
6131             event
.m_shiftDown 
= wxIsShiftDown(); 
6132             event
.m_controlDown 
= wxIsCtrlDown(); 
6134             event
.SetTimestamp(::GetMessageTime()); 
6136             wxWindow 
*win 
= wxGetActiveWindow(); 
6137             wxEvtHandler 
*handler
; 
6140                 handler 
= win
->GetEventHandler(); 
6141                 event
.SetId(win
->GetId()); 
6146                 event
.SetId(wxID_ANY
); 
6149             if ( handler 
&& handler
->ProcessEvent(event
) ) 
6157     return (int)CallNextHookEx(wxTheKeyboardHook
, nCode
, wParam
, lParam
); 
6160 #endif // !__WXMICROWIN__ 
6163 const wxChar 
*wxGetMessageName(int message
) 
6167         case 0x0000: return wxT("WM_NULL"); 
6168         case 0x0001: return wxT("WM_CREATE"); 
6169         case 0x0002: return wxT("WM_DESTROY"); 
6170         case 0x0003: return wxT("WM_MOVE"); 
6171         case 0x0005: return wxT("WM_SIZE"); 
6172         case 0x0006: return wxT("WM_ACTIVATE"); 
6173         case 0x0007: return wxT("WM_SETFOCUS"); 
6174         case 0x0008: return wxT("WM_KILLFOCUS"); 
6175         case 0x000A: return wxT("WM_ENABLE"); 
6176         case 0x000B: return wxT("WM_SETREDRAW"); 
6177         case 0x000C: return wxT("WM_SETTEXT"); 
6178         case 0x000D: return wxT("WM_GETTEXT"); 
6179         case 0x000E: return wxT("WM_GETTEXTLENGTH"); 
6180         case 0x000F: return wxT("WM_PAINT"); 
6181         case 0x0010: return wxT("WM_CLOSE"); 
6182         case 0x0011: return wxT("WM_QUERYENDSESSION"); 
6183         case 0x0012: return wxT("WM_QUIT"); 
6184         case 0x0013: return wxT("WM_QUERYOPEN"); 
6185         case 0x0014: return wxT("WM_ERASEBKGND"); 
6186         case 0x0015: return wxT("WM_SYSCOLORCHANGE"); 
6187         case 0x0016: return wxT("WM_ENDSESSION"); 
6188         case 0x0017: return wxT("WM_SYSTEMERROR"); 
6189         case 0x0018: return wxT("WM_SHOWWINDOW"); 
6190         case 0x0019: return wxT("WM_CTLCOLOR"); 
6191         case 0x001A: return wxT("WM_WININICHANGE"); 
6192         case 0x001B: return wxT("WM_DEVMODECHANGE"); 
6193         case 0x001C: return wxT("WM_ACTIVATEAPP"); 
6194         case 0x001D: return wxT("WM_FONTCHANGE"); 
6195         case 0x001E: return wxT("WM_TIMECHANGE"); 
6196         case 0x001F: return wxT("WM_CANCELMODE"); 
6197         case 0x0020: return wxT("WM_SETCURSOR"); 
6198         case 0x0021: return wxT("WM_MOUSEACTIVATE"); 
6199         case 0x0022: return wxT("WM_CHILDACTIVATE"); 
6200         case 0x0023: return wxT("WM_QUEUESYNC"); 
6201         case 0x0024: return wxT("WM_GETMINMAXINFO"); 
6202         case 0x0026: return wxT("WM_PAINTICON"); 
6203         case 0x0027: return wxT("WM_ICONERASEBKGND"); 
6204         case 0x0028: return wxT("WM_NEXTDLGCTL"); 
6205         case 0x002A: return wxT("WM_SPOOLERSTATUS"); 
6206         case 0x002B: return wxT("WM_DRAWITEM"); 
6207         case 0x002C: return wxT("WM_MEASUREITEM"); 
6208         case 0x002D: return wxT("WM_DELETEITEM"); 
6209         case 0x002E: return wxT("WM_VKEYTOITEM"); 
6210         case 0x002F: return wxT("WM_CHARTOITEM"); 
6211         case 0x0030: return wxT("WM_SETFONT"); 
6212         case 0x0031: return wxT("WM_GETFONT"); 
6213         case 0x0037: return wxT("WM_QUERYDRAGICON"); 
6214         case 0x0039: return wxT("WM_COMPAREITEM"); 
6215         case 0x0041: return wxT("WM_COMPACTING"); 
6216         case 0x0044: return wxT("WM_COMMNOTIFY"); 
6217         case 0x0046: return wxT("WM_WINDOWPOSCHANGING"); 
6218         case 0x0047: return wxT("WM_WINDOWPOSCHANGED"); 
6219         case 0x0048: return wxT("WM_POWER"); 
6221         case 0x004A: return wxT("WM_COPYDATA"); 
6222         case 0x004B: return wxT("WM_CANCELJOURNAL"); 
6223         case 0x004E: return wxT("WM_NOTIFY"); 
6224         case 0x0050: return wxT("WM_INPUTLANGCHANGEREQUEST"); 
6225         case 0x0051: return wxT("WM_INPUTLANGCHANGE"); 
6226         case 0x0052: return wxT("WM_TCARD"); 
6227         case 0x0053: return wxT("WM_HELP"); 
6228         case 0x0054: return wxT("WM_USERCHANGED"); 
6229         case 0x0055: return wxT("WM_NOTIFYFORMAT"); 
6230         case 0x007B: return wxT("WM_CONTEXTMENU"); 
6231         case 0x007C: return wxT("WM_STYLECHANGING"); 
6232         case 0x007D: return wxT("WM_STYLECHANGED"); 
6233         case 0x007E: return wxT("WM_DISPLAYCHANGE"); 
6234         case 0x007F: return wxT("WM_GETICON"); 
6235         case 0x0080: return wxT("WM_SETICON"); 
6237         case 0x0081: return wxT("WM_NCCREATE"); 
6238         case 0x0082: return wxT("WM_NCDESTROY"); 
6239         case 0x0083: return wxT("WM_NCCALCSIZE"); 
6240         case 0x0084: return wxT("WM_NCHITTEST"); 
6241         case 0x0085: return wxT("WM_NCPAINT"); 
6242         case 0x0086: return wxT("WM_NCACTIVATE"); 
6243         case 0x0087: return wxT("WM_GETDLGCODE"); 
6244         case 0x00A0: return wxT("WM_NCMOUSEMOVE"); 
6245         case 0x00A1: return wxT("WM_NCLBUTTONDOWN"); 
6246         case 0x00A2: return wxT("WM_NCLBUTTONUP"); 
6247         case 0x00A3: return wxT("WM_NCLBUTTONDBLCLK"); 
6248         case 0x00A4: return wxT("WM_NCRBUTTONDOWN"); 
6249         case 0x00A5: return wxT("WM_NCRBUTTONUP"); 
6250         case 0x00A6: return wxT("WM_NCRBUTTONDBLCLK"); 
6251         case 0x00A7: return wxT("WM_NCMBUTTONDOWN"); 
6252         case 0x00A8: return wxT("WM_NCMBUTTONUP"); 
6253         case 0x00A9: return wxT("WM_NCMBUTTONDBLCLK"); 
6255         case 0x00B0: return wxT("EM_GETSEL"); 
6256         case 0x00B1: return wxT("EM_SETSEL"); 
6257         case 0x00B2: return wxT("EM_GETRECT"); 
6258         case 0x00B3: return wxT("EM_SETRECT"); 
6259         case 0x00B4: return wxT("EM_SETRECTNP"); 
6260         case 0x00B5: return wxT("EM_SCROLL"); 
6261         case 0x00B6: return wxT("EM_LINESCROLL"); 
6262         case 0x00B7: return wxT("EM_SCROLLCARET"); 
6263         case 0x00B8: return wxT("EM_GETMODIFY"); 
6264         case 0x00B9: return wxT("EM_SETMODIFY"); 
6265         case 0x00BA: return wxT("EM_GETLINECOUNT"); 
6266         case 0x00BB: return wxT("EM_LINEINDEX"); 
6267         case 0x00BC: return wxT("EM_SETHANDLE"); 
6268         case 0x00BD: return wxT("EM_GETHANDLE"); 
6269         case 0x00BE: return wxT("EM_GETTHUMB"); 
6270         case 0x00C1: return wxT("EM_LINELENGTH"); 
6271         case 0x00C2: return wxT("EM_REPLACESEL"); 
6272         case 0x00C4: return wxT("EM_GETLINE"); 
6273         case 0x00C5: return wxT("EM_LIMITTEXT/EM_SETLIMITTEXT"); /* ;win40 Name change */ 
6274         case 0x00C6: return wxT("EM_CANUNDO"); 
6275         case 0x00C7: return wxT("EM_UNDO"); 
6276         case 0x00C8: return wxT("EM_FMTLINES"); 
6277         case 0x00C9: return wxT("EM_LINEFROMCHAR"); 
6278         case 0x00CB: return wxT("EM_SETTABSTOPS"); 
6279         case 0x00CC: return wxT("EM_SETPASSWORDCHAR"); 
6280         case 0x00CD: return wxT("EM_EMPTYUNDOBUFFER"); 
6281         case 0x00CE: return wxT("EM_GETFIRSTVISIBLELINE"); 
6282         case 0x00CF: return wxT("EM_SETREADONLY"); 
6283         case 0x00D0: return wxT("EM_SETWORDBREAKPROC"); 
6284         case 0x00D1: return wxT("EM_GETWORDBREAKPROC"); 
6285         case 0x00D2: return wxT("EM_GETPASSWORDCHAR"); 
6286         case 0x00D3: return wxT("EM_SETMARGINS"); 
6287         case 0x00D4: return wxT("EM_GETMARGINS"); 
6288         case 0x00D5: return wxT("EM_GETLIMITTEXT"); 
6289         case 0x00D6: return wxT("EM_POSFROMCHAR"); 
6290         case 0x00D7: return wxT("EM_CHARFROMPOS"); 
6291         case 0x00D8: return wxT("EM_SETIMESTATUS"); 
6292         case 0x00D9: return wxT("EM_GETIMESTATUS"); 
6294         case 0x0100: return wxT("WM_KEYDOWN"); 
6295         case 0x0101: return wxT("WM_KEYUP"); 
6296         case 0x0102: return wxT("WM_CHAR"); 
6297         case 0x0103: return wxT("WM_DEADCHAR"); 
6298         case 0x0104: return wxT("WM_SYSKEYDOWN"); 
6299         case 0x0105: return wxT("WM_SYSKEYUP"); 
6300         case 0x0106: return wxT("WM_SYSCHAR"); 
6301         case 0x0107: return wxT("WM_SYSDEADCHAR"); 
6302         case 0x0108: return wxT("WM_KEYLAST"); 
6304         case 0x010D: return wxT("WM_IME_STARTCOMPOSITION"); 
6305         case 0x010E: return wxT("WM_IME_ENDCOMPOSITION"); 
6306         case 0x010F: return wxT("WM_IME_COMPOSITION"); 
6308         case 0x0110: return wxT("WM_INITDIALOG"); 
6309         case 0x0111: return wxT("WM_COMMAND"); 
6310         case 0x0112: return wxT("WM_SYSCOMMAND"); 
6311         case 0x0113: return wxT("WM_TIMER"); 
6312         case 0x0114: return wxT("WM_HSCROLL"); 
6313         case 0x0115: return wxT("WM_VSCROLL"); 
6314         case 0x0116: return wxT("WM_INITMENU"); 
6315         case 0x0117: return wxT("WM_INITMENUPOPUP"); 
6316         case 0x011F: return wxT("WM_MENUSELECT"); 
6317         case 0x0120: return wxT("WM_MENUCHAR"); 
6318         case 0x0121: return wxT("WM_ENTERIDLE"); 
6320         case 0x0132: return wxT("WM_CTLCOLORMSGBOX"); 
6321         case 0x0133: return wxT("WM_CTLCOLOREDIT"); 
6322         case 0x0134: return wxT("WM_CTLCOLORLISTBOX"); 
6323         case 0x0135: return wxT("WM_CTLCOLORBTN"); 
6324         case 0x0136: return wxT("WM_CTLCOLORDLG"); 
6325         case 0x0137: return wxT("WM_CTLCOLORSCROLLBAR"); 
6326         case 0x0138: return wxT("WM_CTLCOLORSTATIC"); 
6327         case 0x01E1: return wxT("MN_GETHMENU"); 
6329         case 0x0200: return wxT("WM_MOUSEMOVE"); 
6330         case 0x0201: return wxT("WM_LBUTTONDOWN"); 
6331         case 0x0202: return wxT("WM_LBUTTONUP"); 
6332         case 0x0203: return wxT("WM_LBUTTONDBLCLK"); 
6333         case 0x0204: return wxT("WM_RBUTTONDOWN"); 
6334         case 0x0205: return wxT("WM_RBUTTONUP"); 
6335         case 0x0206: return wxT("WM_RBUTTONDBLCLK"); 
6336         case 0x0207: return wxT("WM_MBUTTONDOWN"); 
6337         case 0x0208: return wxT("WM_MBUTTONUP"); 
6338         case 0x0209: return wxT("WM_MBUTTONDBLCLK"); 
6339         case 0x020A: return wxT("WM_MOUSEWHEEL"); 
6340         case 0x020B: return wxT("WM_XBUTTONDOWN"); 
6341         case 0x020C: return wxT("WM_XBUTTONUP"); 
6342         case 0x020D: return wxT("WM_XBUTTONDBLCLK"); 
6343         case 0x0210: return wxT("WM_PARENTNOTIFY"); 
6344         case 0x0211: return wxT("WM_ENTERMENULOOP"); 
6345         case 0x0212: return wxT("WM_EXITMENULOOP"); 
6347         case 0x0213: return wxT("WM_NEXTMENU"); 
6348         case 0x0214: return wxT("WM_SIZING"); 
6349         case 0x0215: return wxT("WM_CAPTURECHANGED"); 
6350         case 0x0216: return wxT("WM_MOVING"); 
6351         case 0x0218: return wxT("WM_POWERBROADCAST"); 
6352         case 0x0219: return wxT("WM_DEVICECHANGE"); 
6354         case 0x0220: return wxT("WM_MDICREATE"); 
6355         case 0x0221: return wxT("WM_MDIDESTROY"); 
6356         case 0x0222: return wxT("WM_MDIACTIVATE"); 
6357         case 0x0223: return wxT("WM_MDIRESTORE"); 
6358         case 0x0224: return wxT("WM_MDINEXT"); 
6359         case 0x0225: return wxT("WM_MDIMAXIMIZE"); 
6360         case 0x0226: return wxT("WM_MDITILE"); 
6361         case 0x0227: return wxT("WM_MDICASCADE"); 
6362         case 0x0228: return wxT("WM_MDIICONARRANGE"); 
6363         case 0x0229: return wxT("WM_MDIGETACTIVE"); 
6364         case 0x0230: return wxT("WM_MDISETMENU"); 
6365         case 0x0233: return wxT("WM_DROPFILES"); 
6367         case 0x0281: return wxT("WM_IME_SETCONTEXT"); 
6368         case 0x0282: return wxT("WM_IME_NOTIFY"); 
6369         case 0x0283: return wxT("WM_IME_CONTROL"); 
6370         case 0x0284: return wxT("WM_IME_COMPOSITIONFULL"); 
6371         case 0x0285: return wxT("WM_IME_SELECT"); 
6372         case 0x0286: return wxT("WM_IME_CHAR"); 
6373         case 0x0290: return wxT("WM_IME_KEYDOWN"); 
6374         case 0x0291: return wxT("WM_IME_KEYUP"); 
6376         case 0x02A0: return wxT("WM_NCMOUSEHOVER"); 
6377         case 0x02A1: return wxT("WM_MOUSEHOVER"); 
6378         case 0x02A2: return wxT("WM_NCMOUSELEAVE"); 
6379         case 0x02A3: return wxT("WM_MOUSELEAVE"); 
6381         case 0x0300: return wxT("WM_CUT"); 
6382         case 0x0301: return wxT("WM_COPY"); 
6383         case 0x0302: return wxT("WM_PASTE"); 
6384         case 0x0303: return wxT("WM_CLEAR"); 
6385         case 0x0304: return wxT("WM_UNDO"); 
6386         case 0x0305: return wxT("WM_RENDERFORMAT"); 
6387         case 0x0306: return wxT("WM_RENDERALLFORMATS"); 
6388         case 0x0307: return wxT("WM_DESTROYCLIPBOARD"); 
6389         case 0x0308: return wxT("WM_DRAWCLIPBOARD"); 
6390         case 0x0309: return wxT("WM_PAINTCLIPBOARD"); 
6391         case 0x030A: return wxT("WM_VSCROLLCLIPBOARD"); 
6392         case 0x030B: return wxT("WM_SIZECLIPBOARD"); 
6393         case 0x030C: return wxT("WM_ASKCBFORMATNAME"); 
6394         case 0x030D: return wxT("WM_CHANGECBCHAIN"); 
6395         case 0x030E: return wxT("WM_HSCROLLCLIPBOARD"); 
6396         case 0x030F: return wxT("WM_QUERYNEWPALETTE"); 
6397         case 0x0310: return wxT("WM_PALETTEISCHANGING"); 
6398         case 0x0311: return wxT("WM_PALETTECHANGED"); 
6399         case 0x0312: return wxT("WM_HOTKEY"); 
6401         case 0x0317: return wxT("WM_PRINT"); 
6402         case 0x0318: return wxT("WM_PRINTCLIENT"); 
6404         // common controls messages - although they're not strictly speaking 
6405         // standard, it's nice to decode them nevertheless 
6408         case 0x1000 + 0: return wxT("LVM_GETBKCOLOR"); 
6409         case 0x1000 + 1: return wxT("LVM_SETBKCOLOR"); 
6410         case 0x1000 + 2: return wxT("LVM_GETIMAGELIST"); 
6411         case 0x1000 + 3: return wxT("LVM_SETIMAGELIST"); 
6412         case 0x1000 + 4: return wxT("LVM_GETITEMCOUNT"); 
6413         case 0x1000 + 5: return wxT("LVM_GETITEMA"); 
6414         case 0x1000 + 75: return wxT("LVM_GETITEMW"); 
6415         case 0x1000 + 6: return wxT("LVM_SETITEMA"); 
6416         case 0x1000 + 76: return wxT("LVM_SETITEMW"); 
6417         case 0x1000 + 7: return wxT("LVM_INSERTITEMA"); 
6418         case 0x1000 + 77: return wxT("LVM_INSERTITEMW"); 
6419         case 0x1000 + 8: return wxT("LVM_DELETEITEM"); 
6420         case 0x1000 + 9: return wxT("LVM_DELETEALLITEMS"); 
6421         case 0x1000 + 10: return wxT("LVM_GETCALLBACKMASK"); 
6422         case 0x1000 + 11: return wxT("LVM_SETCALLBACKMASK"); 
6423         case 0x1000 + 12: return wxT("LVM_GETNEXTITEM"); 
6424         case 0x1000 + 13: return wxT("LVM_FINDITEMA"); 
6425         case 0x1000 + 83: return wxT("LVM_FINDITEMW"); 
6426         case 0x1000 + 14: return wxT("LVM_GETITEMRECT"); 
6427         case 0x1000 + 15: return wxT("LVM_SETITEMPOSITION"); 
6428         case 0x1000 + 16: return wxT("LVM_GETITEMPOSITION"); 
6429         case 0x1000 + 17: return wxT("LVM_GETSTRINGWIDTHA"); 
6430         case 0x1000 + 87: return wxT("LVM_GETSTRINGWIDTHW"); 
6431         case 0x1000 + 18: return wxT("LVM_HITTEST"); 
6432         case 0x1000 + 19: return wxT("LVM_ENSUREVISIBLE"); 
6433         case 0x1000 + 20: return wxT("LVM_SCROLL"); 
6434         case 0x1000 + 21: return wxT("LVM_REDRAWITEMS"); 
6435         case 0x1000 + 22: return wxT("LVM_ARRANGE"); 
6436         case 0x1000 + 23: return wxT("LVM_EDITLABELA"); 
6437         case 0x1000 + 118: return wxT("LVM_EDITLABELW"); 
6438         case 0x1000 + 24: return wxT("LVM_GETEDITCONTROL"); 
6439         case 0x1000 + 25: return wxT("LVM_GETCOLUMNA"); 
6440         case 0x1000 + 95: return wxT("LVM_GETCOLUMNW"); 
6441         case 0x1000 + 26: return wxT("LVM_SETCOLUMNA"); 
6442         case 0x1000 + 96: return wxT("LVM_SETCOLUMNW"); 
6443         case 0x1000 + 27: return wxT("LVM_INSERTCOLUMNA"); 
6444         case 0x1000 + 97: return wxT("LVM_INSERTCOLUMNW"); 
6445         case 0x1000 + 28: return wxT("LVM_DELETECOLUMN"); 
6446         case 0x1000 + 29: return wxT("LVM_GETCOLUMNWIDTH"); 
6447         case 0x1000 + 30: return wxT("LVM_SETCOLUMNWIDTH"); 
6448         case 0x1000 + 31: return wxT("LVM_GETHEADER"); 
6449         case 0x1000 + 33: return wxT("LVM_CREATEDRAGIMAGE"); 
6450         case 0x1000 + 34: return wxT("LVM_GETVIEWRECT"); 
6451         case 0x1000 + 35: return wxT("LVM_GETTEXTCOLOR"); 
6452         case 0x1000 + 36: return wxT("LVM_SETTEXTCOLOR"); 
6453         case 0x1000 + 37: return wxT("LVM_GETTEXTBKCOLOR"); 
6454         case 0x1000 + 38: return wxT("LVM_SETTEXTBKCOLOR"); 
6455         case 0x1000 + 39: return wxT("LVM_GETTOPINDEX"); 
6456         case 0x1000 + 40: return wxT("LVM_GETCOUNTPERPAGE"); 
6457         case 0x1000 + 41: return wxT("LVM_GETORIGIN"); 
6458         case 0x1000 + 42: return wxT("LVM_UPDATE"); 
6459         case 0x1000 + 43: return wxT("LVM_SETITEMSTATE"); 
6460         case 0x1000 + 44: return wxT("LVM_GETITEMSTATE"); 
6461         case 0x1000 + 45: return wxT("LVM_GETITEMTEXTA"); 
6462         case 0x1000 + 115: return wxT("LVM_GETITEMTEXTW"); 
6463         case 0x1000 + 46: return wxT("LVM_SETITEMTEXTA"); 
6464         case 0x1000 + 116: return wxT("LVM_SETITEMTEXTW"); 
6465         case 0x1000 + 47: return wxT("LVM_SETITEMCOUNT"); 
6466         case 0x1000 + 48: return wxT("LVM_SORTITEMS"); 
6467         case 0x1000 + 49: return wxT("LVM_SETITEMPOSITION32"); 
6468         case 0x1000 + 50: return wxT("LVM_GETSELECTEDCOUNT"); 
6469         case 0x1000 + 51: return wxT("LVM_GETITEMSPACING"); 
6470         case 0x1000 + 52: return wxT("LVM_GETISEARCHSTRINGA"); 
6471         case 0x1000 + 117: return wxT("LVM_GETISEARCHSTRINGW"); 
6472         case 0x1000 + 53: return wxT("LVM_SETICONSPACING"); 
6473         case 0x1000 + 54: return wxT("LVM_SETEXTENDEDLISTVIEWSTYLE"); 
6474         case 0x1000 + 55: return wxT("LVM_GETEXTENDEDLISTVIEWSTYLE"); 
6475         case 0x1000 + 56: return wxT("LVM_GETSUBITEMRECT"); 
6476         case 0x1000 + 57: return wxT("LVM_SUBITEMHITTEST"); 
6477         case 0x1000 + 58: return wxT("LVM_SETCOLUMNORDERARRAY"); 
6478         case 0x1000 + 59: return wxT("LVM_GETCOLUMNORDERARRAY"); 
6479         case 0x1000 + 60: return wxT("LVM_SETHOTITEM"); 
6480         case 0x1000 + 61: return wxT("LVM_GETHOTITEM"); 
6481         case 0x1000 + 62: return wxT("LVM_SETHOTCURSOR"); 
6482         case 0x1000 + 63: return wxT("LVM_GETHOTCURSOR"); 
6483         case 0x1000 + 64: return wxT("LVM_APPROXIMATEVIEWRECT"); 
6484         case 0x1000 + 65: return wxT("LVM_SETWORKAREA"); 
6487         case 0x1100 + 0: return wxT("TVM_INSERTITEMA"); 
6488         case 0x1100 + 50: return wxT("TVM_INSERTITEMW"); 
6489         case 0x1100 + 1: return wxT("TVM_DELETEITEM"); 
6490         case 0x1100 + 2: return wxT("TVM_EXPAND"); 
6491         case 0x1100 + 4: return wxT("TVM_GETITEMRECT"); 
6492         case 0x1100 + 5: return wxT("TVM_GETCOUNT"); 
6493         case 0x1100 + 6: return wxT("TVM_GETINDENT"); 
6494         case 0x1100 + 7: return wxT("TVM_SETINDENT"); 
6495         case 0x1100 + 8: return wxT("TVM_GETIMAGELIST"); 
6496         case 0x1100 + 9: return wxT("TVM_SETIMAGELIST"); 
6497         case 0x1100 + 10: return wxT("TVM_GETNEXTITEM"); 
6498         case 0x1100 + 11: return wxT("TVM_SELECTITEM"); 
6499         case 0x1100 + 12: return wxT("TVM_GETITEMA"); 
6500         case 0x1100 + 62: return wxT("TVM_GETITEMW"); 
6501         case 0x1100 + 13: return wxT("TVM_SETITEMA"); 
6502         case 0x1100 + 63: return wxT("TVM_SETITEMW"); 
6503         case 0x1100 + 14: return wxT("TVM_EDITLABELA"); 
6504         case 0x1100 + 65: return wxT("TVM_EDITLABELW"); 
6505         case 0x1100 + 15: return wxT("TVM_GETEDITCONTROL"); 
6506         case 0x1100 + 16: return wxT("TVM_GETVISIBLECOUNT"); 
6507         case 0x1100 + 17: return wxT("TVM_HITTEST"); 
6508         case 0x1100 + 18: return wxT("TVM_CREATEDRAGIMAGE"); 
6509         case 0x1100 + 19: return wxT("TVM_SORTCHILDREN"); 
6510         case 0x1100 + 20: return wxT("TVM_ENSUREVISIBLE"); 
6511         case 0x1100 + 21: return wxT("TVM_SORTCHILDRENCB"); 
6512         case 0x1100 + 22: return wxT("TVM_ENDEDITLABELNOW"); 
6513         case 0x1100 + 23: return wxT("TVM_GETISEARCHSTRINGA"); 
6514         case 0x1100 + 64: return wxT("TVM_GETISEARCHSTRINGW"); 
6515         case 0x1100 + 24: return wxT("TVM_SETTOOLTIPS"); 
6516         case 0x1100 + 25: return wxT("TVM_GETTOOLTIPS"); 
6519         case 0x1200 + 0: return wxT("HDM_GETITEMCOUNT"); 
6520         case 0x1200 + 1: return wxT("HDM_INSERTITEMA"); 
6521         case 0x1200 + 10: return wxT("HDM_INSERTITEMW"); 
6522         case 0x1200 + 2: return wxT("HDM_DELETEITEM"); 
6523         case 0x1200 + 3: return wxT("HDM_GETITEMA"); 
6524         case 0x1200 + 11: return wxT("HDM_GETITEMW"); 
6525         case 0x1200 + 4: return wxT("HDM_SETITEMA"); 
6526         case 0x1200 + 12: return wxT("HDM_SETITEMW"); 
6527         case 0x1200 + 5: return wxT("HDM_LAYOUT"); 
6528         case 0x1200 + 6: return wxT("HDM_HITTEST"); 
6529         case 0x1200 + 7: return wxT("HDM_GETITEMRECT"); 
6530         case 0x1200 + 8: return wxT("HDM_SETIMAGELIST"); 
6531         case 0x1200 + 9: return wxT("HDM_GETIMAGELIST"); 
6532         case 0x1200 + 15: return wxT("HDM_ORDERTOINDEX"); 
6533         case 0x1200 + 16: return wxT("HDM_CREATEDRAGIMAGE"); 
6534         case 0x1200 + 17: return wxT("HDM_GETORDERARRAY"); 
6535         case 0x1200 + 18: return wxT("HDM_SETORDERARRAY"); 
6536         case 0x1200 + 19: return wxT("HDM_SETHOTDIVIDER"); 
6539         case 0x1300 + 2: return wxT("TCM_GETIMAGELIST"); 
6540         case 0x1300 + 3: return wxT("TCM_SETIMAGELIST"); 
6541         case 0x1300 + 4: return wxT("TCM_GETITEMCOUNT"); 
6542         case 0x1300 + 5: return wxT("TCM_GETITEMA"); 
6543         case 0x1300 + 60: return wxT("TCM_GETITEMW"); 
6544         case 0x1300 + 6: return wxT("TCM_SETITEMA"); 
6545         case 0x1300 + 61: return wxT("TCM_SETITEMW"); 
6546         case 0x1300 + 7: return wxT("TCM_INSERTITEMA"); 
6547         case 0x1300 + 62: return wxT("TCM_INSERTITEMW"); 
6548         case 0x1300 + 8: return wxT("TCM_DELETEITEM"); 
6549         case 0x1300 + 9: return wxT("TCM_DELETEALLITEMS"); 
6550         case 0x1300 + 10: return wxT("TCM_GETITEMRECT"); 
6551         case 0x1300 + 11: return wxT("TCM_GETCURSEL"); 
6552         case 0x1300 + 12: return wxT("TCM_SETCURSEL"); 
6553         case 0x1300 + 13: return wxT("TCM_HITTEST"); 
6554         case 0x1300 + 14: return wxT("TCM_SETITEMEXTRA"); 
6555         case 0x1300 + 40: return wxT("TCM_ADJUSTRECT"); 
6556         case 0x1300 + 41: return wxT("TCM_SETITEMSIZE"); 
6557         case 0x1300 + 42: return wxT("TCM_REMOVEIMAGE"); 
6558         case 0x1300 + 43: return wxT("TCM_SETPADDING"); 
6559         case 0x1300 + 44: return wxT("TCM_GETROWCOUNT"); 
6560         case 0x1300 + 45: return wxT("TCM_GETTOOLTIPS"); 
6561         case 0x1300 + 46: return wxT("TCM_SETTOOLTIPS"); 
6562         case 0x1300 + 47: return wxT("TCM_GETCURFOCUS"); 
6563         case 0x1300 + 48: return wxT("TCM_SETCURFOCUS"); 
6564         case 0x1300 + 49: return wxT("TCM_SETMINTABWIDTH"); 
6565         case 0x1300 + 50: return wxT("TCM_DESELECTALL"); 
6568         case WM_USER
+1: return wxT("TB_ENABLEBUTTON"); 
6569         case WM_USER
+2: return wxT("TB_CHECKBUTTON"); 
6570         case WM_USER
+3: return wxT("TB_PRESSBUTTON"); 
6571         case WM_USER
+4: return wxT("TB_HIDEBUTTON"); 
6572         case WM_USER
+5: return wxT("TB_INDETERMINATE"); 
6573         case WM_USER
+9: return wxT("TB_ISBUTTONENABLED"); 
6574         case WM_USER
+10: return wxT("TB_ISBUTTONCHECKED"); 
6575         case WM_USER
+11: return wxT("TB_ISBUTTONPRESSED"); 
6576         case WM_USER
+12: return wxT("TB_ISBUTTONHIDDEN"); 
6577         case WM_USER
+13: return wxT("TB_ISBUTTONINDETERMINATE"); 
6578         case WM_USER
+17: return wxT("TB_SETSTATE"); 
6579         case WM_USER
+18: return wxT("TB_GETSTATE"); 
6580         case WM_USER
+19: return wxT("TB_ADDBITMAP"); 
6581         case WM_USER
+20: return wxT("TB_ADDBUTTONS"); 
6582         case WM_USER
+21: return wxT("TB_INSERTBUTTON"); 
6583         case WM_USER
+22: return wxT("TB_DELETEBUTTON"); 
6584         case WM_USER
+23: return wxT("TB_GETBUTTON"); 
6585         case WM_USER
+24: return wxT("TB_BUTTONCOUNT"); 
6586         case WM_USER
+25: return wxT("TB_COMMANDTOINDEX"); 
6587         case WM_USER
+26: return wxT("TB_SAVERESTOREA"); 
6588         case WM_USER
+76: return wxT("TB_SAVERESTOREW"); 
6589         case WM_USER
+27: return wxT("TB_CUSTOMIZE"); 
6590         case WM_USER
+28: return wxT("TB_ADDSTRINGA"); 
6591         case WM_USER
+77: return wxT("TB_ADDSTRINGW"); 
6592         case WM_USER
+29: return wxT("TB_GETITEMRECT"); 
6593         case WM_USER
+30: return wxT("TB_BUTTONSTRUCTSIZE"); 
6594         case WM_USER
+31: return wxT("TB_SETBUTTONSIZE"); 
6595         case WM_USER
+32: return wxT("TB_SETBITMAPSIZE"); 
6596         case WM_USER
+33: return wxT("TB_AUTOSIZE"); 
6597         case WM_USER
+35: return wxT("TB_GETTOOLTIPS"); 
6598         case WM_USER
+36: return wxT("TB_SETTOOLTIPS"); 
6599         case WM_USER
+37: return wxT("TB_SETPARENT"); 
6600         case WM_USER
+39: return wxT("TB_SETROWS"); 
6601         case WM_USER
+40: return wxT("TB_GETROWS"); 
6602         case WM_USER
+42: return wxT("TB_SETCMDID"); 
6603         case WM_USER
+43: return wxT("TB_CHANGEBITMAP"); 
6604         case WM_USER
+44: return wxT("TB_GETBITMAP"); 
6605         case WM_USER
+45: return wxT("TB_GETBUTTONTEXTA"); 
6606         case WM_USER
+75: return wxT("TB_GETBUTTONTEXTW"); 
6607         case WM_USER
+46: return wxT("TB_REPLACEBITMAP"); 
6608         case WM_USER
+47: return wxT("TB_SETINDENT"); 
6609         case WM_USER
+48: return wxT("TB_SETIMAGELIST"); 
6610         case WM_USER
+49: return wxT("TB_GETIMAGELIST"); 
6611         case WM_USER
+50: return wxT("TB_LOADIMAGES"); 
6612         case WM_USER
+51: return wxT("TB_GETRECT"); 
6613         case WM_USER
+52: return wxT("TB_SETHOTIMAGELIST"); 
6614         case WM_USER
+53: return wxT("TB_GETHOTIMAGELIST"); 
6615         case WM_USER
+54: return wxT("TB_SETDISABLEDIMAGELIST"); 
6616         case WM_USER
+55: return wxT("TB_GETDISABLEDIMAGELIST"); 
6617         case WM_USER
+56: return wxT("TB_SETSTYLE"); 
6618         case WM_USER
+57: return wxT("TB_GETSTYLE"); 
6619         case WM_USER
+58: return wxT("TB_GETBUTTONSIZE"); 
6620         case WM_USER
+59: return wxT("TB_SETBUTTONWIDTH"); 
6621         case WM_USER
+60: return wxT("TB_SETMAXTEXTROWS"); 
6622         case WM_USER
+61: return wxT("TB_GETTEXTROWS"); 
6623         case WM_USER
+41: return wxT("TB_GETBITMAPFLAGS"); 
6626             static wxString s_szBuf
; 
6627             s_szBuf
.Printf(wxT("<unknown message = %d>"), message
); 
6628             return s_szBuf
.c_str(); 
6631 #endif //__WXDEBUG__ 
6633 static TEXTMETRIC 
wxGetTextMetrics(const wxWindowMSW 
*win
) 
6637     HWND hwnd 
= GetHwndOf(win
); 
6638     HDC hdc 
= ::GetDC(hwnd
); 
6640 #if !wxDIALOG_UNIT_COMPATIBILITY 
6641     // and select the current font into it 
6642     HFONT hfont 
= GetHfontOf(win
->GetFont()); 
6645         hfont 
= (HFONT
)::SelectObject(hdc
, hfont
); 
6649     // finally retrieve the text metrics from it 
6650     GetTextMetrics(hdc
, &tm
); 
6652 #if !wxDIALOG_UNIT_COMPATIBILITY 
6656         (void)::SelectObject(hdc
, hfont
); 
6660     ::ReleaseDC(hwnd
, hdc
); 
6665 // Find the wxWindow at the current mouse position, returning the mouse 
6667 wxWindow
* wxFindWindowAtPointer(wxPoint
& pt
) 
6669     pt 
= wxGetMousePosition(); 
6670     return wxFindWindowAtPoint(pt
); 
6673 wxWindow
* wxFindWindowAtPoint(const wxPoint
& pt
) 
6679     HWND hWnd 
= ::WindowFromPoint(pt2
); 
6681     return wxGetWindowFromHWND((WXHWND
)hWnd
); 
6684 // Get the current mouse position. 
6685 wxPoint 
wxGetMousePosition() 
6689     GetCursorPosWinCE(&pt
); 
6691     GetCursorPos( & pt 
); 
6694     return wxPoint(pt
.x
, pt
.y
); 
6699 #if defined(__SMARTPHONE__) || defined(__POCKETPC__) 
6700 static void WinCEUnregisterHotKey(int modifiers
, int id
) 
6702     // Register hotkeys for the hardware buttons 
6704     typedef BOOL (WINAPI 
*UnregisterFunc1Proc
)(UINT
, UINT
); 
6706     UnregisterFunc1Proc procUnregisterFunc
; 
6707     hCoreDll 
= LoadLibrary(_T("coredll.dll")); 
6710         procUnregisterFunc 
= (UnregisterFunc1Proc
)GetProcAddress(hCoreDll
, _T("UnregisterFunc1")); 
6711         if (procUnregisterFunc
) 
6712             procUnregisterFunc(modifiers
, id
); 
6713         FreeLibrary(hCoreDll
); 
6718 bool wxWindowMSW::RegisterHotKey(int hotkeyId
, int modifiers
, int keycode
) 
6720     UINT win_modifiers
=0; 
6721     if ( modifiers 
& wxMOD_ALT 
) 
6722         win_modifiers 
|= MOD_ALT
; 
6723     if ( modifiers 
& wxMOD_SHIFT 
) 
6724         win_modifiers 
|= MOD_SHIFT
; 
6725     if ( modifiers 
& wxMOD_CONTROL 
) 
6726         win_modifiers 
|= MOD_CONTROL
; 
6727     if ( modifiers 
& wxMOD_WIN 
) 
6728         win_modifiers 
|= MOD_WIN
; 
6730 #if defined(__SMARTPHONE__) || defined(__POCKETPC__) 
6731     // Required for PPC and Smartphone hardware buttons 
6732     if (keycode 
>= WXK_SPECIAL1 
&& keycode 
<= WXK_SPECIAL20
) 
6733         WinCEUnregisterHotKey(win_modifiers
, hotkeyId
); 
6736     if ( !::RegisterHotKey(GetHwnd(), hotkeyId
, win_modifiers
, keycode
) ) 
6738         wxLogLastError(_T("RegisterHotKey")); 
6746 bool wxWindowMSW::UnregisterHotKey(int hotkeyId
) 
6748 #if defined(__SMARTPHONE__) || defined(__POCKETPC__) 
6749     WinCEUnregisterHotKey(MOD_WIN
, hotkeyId
); 
6752     if ( !::UnregisterHotKey(GetHwnd(), hotkeyId
) ) 
6754         wxLogLastError(_T("UnregisterHotKey")); 
6764 bool wxWindowMSW::HandleHotKey(WXWPARAM wParam
, WXLPARAM lParam
) 
6766     int hotkeyId 
= wParam
; 
6767     int virtualKey 
= HIWORD(lParam
); 
6768     int win_modifiers 
= LOWORD(lParam
); 
6770     wxKeyEvent 
event(CreateKeyEvent(wxEVT_HOTKEY
, virtualKey
, wParam
, lParam
)); 
6771     event
.SetId(hotkeyId
); 
6772     event
.m_shiftDown 
= (win_modifiers 
& MOD_SHIFT
) != 0; 
6773     event
.m_controlDown 
= (win_modifiers 
& MOD_CONTROL
) != 0; 
6774     event
.m_altDown 
= (win_modifiers 
& MOD_ALT
) != 0; 
6775     event
.m_metaDown 
= (win_modifiers 
& MOD_WIN
) != 0; 
6777     return GetEventHandler()->ProcessEvent(event
); 
6780 #endif // wxUSE_ACCEL 
6782 #endif // wxUSE_HOTKEY 
6784 // Not tested under WinCE 
6787 // this class installs a message hook which really wakes up our idle processing 
6788 // each time a WM_NULL is received (wxWakeUpIdle does this), even if we're 
6789 // sitting inside a local modal loop (e.g. a menu is opened or scrollbar is 
6790 // being dragged or even inside ::MessageBox()) and so don't control message 
6791 // dispatching otherwise 
6792 class wxIdleWakeUpModule 
: public wxModule
 
6795     virtual bool OnInit() 
6797         ms_hMsgHookProc 
= ::SetWindowsHookEx
 
6800                              &wxIdleWakeUpModule::MsgHookProc
, 
6802                              GetCurrentThreadId() 
6805         if ( !ms_hMsgHookProc 
) 
6807             wxLogLastError(_T("SetWindowsHookEx(WH_GETMESSAGE)")); 
6815     virtual void OnExit() 
6817         ::UnhookWindowsHookEx(wxIdleWakeUpModule::ms_hMsgHookProc
); 
6820     static LRESULT CALLBACK 
MsgHookProc(int nCode
, WPARAM wParam
, LPARAM lParam
) 
6822         MSG 
*msg 
= (MSG
*)lParam
; 
6824         // only process the message if it is actually going to be removed from 
6825         // the message queue, this prevents that the same event from being 
6826         // processed multiple times if now someone just called PeekMessage() 
6827         if ( msg
->message 
== WM_NULL 
&& wParam 
== PM_REMOVE 
) 
6829             wxTheApp
->ProcessPendingEvents(); 
6832         return CallNextHookEx(ms_hMsgHookProc
, nCode
, wParam
, lParam
); 
6836     static HHOOK ms_hMsgHookProc
; 
6838     DECLARE_DYNAMIC_CLASS(wxIdleWakeUpModule
) 
6841 HHOOK 
wxIdleWakeUpModule::ms_hMsgHookProc 
= 0; 
6843 IMPLEMENT_DYNAMIC_CLASS(wxIdleWakeUpModule
, wxModule
) 
6845 #endif // __WXWINCE__ 
6850 static void wxAdjustZOrder(wxWindow
* parent
) 
6852     if (parent
->IsKindOf(CLASSINFO(wxStaticBox
))) 
6854         // Set the z-order correctly 
6855         SetWindowPos((HWND
) parent
->GetHWND(), HWND_BOTTOM
, 0, 0, 0, 0, SWP_NOMOVE
|SWP_NOSIZE
); 
6858     wxWindowList::compatibility_iterator current 
= parent
->GetChildren().GetFirst(); 
6861         wxWindow 
*childWin 
= current
->GetData(); 
6862         wxAdjustZOrder(childWin
); 
6863         current 
= current
->GetNext(); 
6868 // We need to adjust the z-order of static boxes in WinCE, to 
6869 // make 'contained' controls visible 
6870 void wxWindowMSW::OnInitDialog( wxInitDialogEvent
& event 
) 
6873     wxAdjustZOrder(this);