1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/msw/windows.cpp 
   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 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  21     #pragma implementation "window.h" 
  24 // For compilers that support precompilation, includes "wx.h". 
  25 #include "wx/wxprec.h" 
  32     #include "wx/msw/wrapwin.h" 
  33     #include "wx/window.h" 
  38     #include "wx/dcclient.h" 
  39     #include "wx/dcmemory.h" 
  42     #include "wx/layout.h" 
  43     #include "wx/dialog.h" 
  45     #include "wx/listbox.h" 
  46     #include "wx/button.h" 
  47     #include "wx/msgdlg.h" 
  48     #include "wx/settings.h" 
  49     #include "wx/statbox.h" 
  53 #if wxUSE_OWNER_DRAWN && !defined(__WXUNIVERSAL__) 
  54     #include "wx/ownerdrw.h" 
  57 #include "wx/evtloop.h" 
  58 #include "wx/module.h" 
  59 #include "wx/sysopt.h" 
  61 #if wxUSE_DRAG_AND_DROP 
  65 #if wxUSE_ACCESSIBILITY 
  66     #include "wx/access.h" 
  70         #define WM_GETOBJECT 0x003D 
  73         #define OBJID_CLIENT 0xFFFFFFFC 
  77 #include "wx/menuitem.h" 
  80 #include "wx/msw/private.h" 
  83     #include "wx/tooltip.h" 
  91     #include "wx/spinctrl.h" 
  92 #endif // wxUSE_SPINCTRL 
  97 #include "wx/textctrl.h" 
  98 #include "wx/notebook.h" 
  99 #include "wx/listctrl.h" 
 103 #if (!defined(__GNUWIN32_OLD__) && !defined(__WXMICROWIN__) /* && !defined(__WXWINCE__) */ ) || defined(__CYGWIN10__) 
 104     #include <shellapi.h> 
 105     #include <mmsystem.h> 
 109     #include <windowsx.h> 
 112 #include <commctrl.h> 
 114 #include "wx/msw/missing.h" 
 116 #if defined(__WXWINCE__) 
 117     #include "wx/msw/wince/missing.h" 
 120 #if defined(TME_LEAVE) && defined(WM_MOUSELEAVE) 
 121     #define HAVE_TRACKMOUSEEVENT 
 122 #endif // everything needed for TrackMouseEvent() 
 124 // if this is set to 1, we use deferred window sizing to reduce flicker when 
 125 // resizing complicated window hierarchies, but this can in theory result in 
 126 // different behaviour than the old code so we keep the possibility to use it 
 127 // by setting this to 0 (in the future this should be removed completely) 
 128 #define USE_DEFERRED_SIZING 1 
 130 // --------------------------------------------------------------------------- 
 132 // --------------------------------------------------------------------------- 
 134 #if wxUSE_MENUS_NATIVE 
 135 wxMenu 
*wxCurrentPopupMenu 
= NULL
; 
 136 #endif // wxUSE_MENUS_NATIVE 
 139 extern       wxChar 
*wxCanvasClassName
; 
 141 extern const wxChar 
*wxCanvasClassName
; 
 144 // true if we had already created the std colour map, used by 
 145 // wxGetStdColourMap() and wxWindow::OnSysColourChanged()           (FIXME-MT) 
 146 static bool gs_hasStdCmap 
= false; 
 148 // --------------------------------------------------------------------------- 
 150 // --------------------------------------------------------------------------- 
 152 // the window proc for all our windows 
 153 LRESULT WXDLLEXPORT APIENTRY _EXPORT 
wxWndProc(HWND hWnd
, UINT message
, 
 154                                    WPARAM wParam
, LPARAM lParam
); 
 158     const wxChar 
*wxGetMessageName(int message
); 
 161 void wxRemoveHandleAssociation(wxWindowMSW 
*win
); 
 162 extern void wxAssociateWinWithHandle(HWND hWnd
, wxWindowMSW 
*win
); 
 163 wxWindow 
*wxFindWinFromHandle(WXHWND hWnd
); 
 165 // get the text metrics for the current font 
 166 static TEXTMETRIC 
wxGetTextMetrics(const wxWindowMSW 
*win
); 
 168 // find the window for the mouse event at the specified position 
 169 static wxWindowMSW 
*FindWindowForMouseEvent(wxWindowMSW 
*win
, int *x
, int *y
); //TW:REQ:Univ 
 171 // wrapper around BringWindowToTop() API 
 172 static inline void wxBringWindowToTop(HWND hwnd
) 
 174 #ifdef __WXMICROWIN__ 
 175     // It seems that MicroWindows brings the _parent_ of the window to the top, 
 176     // which can be the wrong one. 
 178     // activate (set focus to) specified window 
 182     // raise top level parent to top of z order 
 183     if (!::SetWindowPos(hwnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE 
| SWP_NOSIZE
)) 
 185         wxLogLastError(_T("SetWindowPos")); 
 191 // ensure that all our parent windows have WS_EX_CONTROLPARENT style 
 192 static void EnsureParentHasControlParentStyle(wxWindow 
*parent
) 
 195        If we have WS_EX_CONTROLPARENT flag we absolutely *must* set it for our 
 196        parent as well as otherwise several Win32 functions using 
 197        GetNextDlgTabItem() to iterate over all controls such as 
 198        IsDialogMessage() or DefDlgProc() would enter an infinite loop: indeed, 
 199        all of them iterate over all the controls starting from the currently 
 200        focused one and stop iterating when they get back to the focus but 
 201        unless all parents have WS_EX_CONTROLPARENT bit set, they would never 
 202        get back to the initial (focused) window: as we do have this style, 
 203        GetNextDlgTabItem() will leave this window and continue in its parent, 
 204        but if the parent doesn't have it, it wouldn't recurse inside it later 
 205        on and so wouldn't have a chance of getting back to this window neither. 
 207     while ( parent 
&& !parent
->IsTopLevel() ) 
 209         LONG exStyle 
= ::GetWindowLong(GetHwndOf(parent
), GWL_EXSTYLE
); 
 210         if ( !(exStyle 
& WS_EX_CONTROLPARENT
) ) 
 212             // force the parent to have this style 
 213             ::SetWindowLong(GetHwndOf(parent
), GWL_EXSTYLE
, 
 214                             exStyle 
| WS_EX_CONTROLPARENT
); 
 217         parent 
= parent
->GetParent(); 
 221 #endif // !__WXWINCE__ 
 224 // On Windows CE, GetCursorPos can return an error, so use this function 
 226 bool GetCursorPosWinCE(POINT
* pt
) 
 228     if (!GetCursorPos(pt
)) 
 230         DWORD pos 
= GetMessagePos(); 
 238 // --------------------------------------------------------------------------- 
 240 // --------------------------------------------------------------------------- 
 242 // in wxUniv/MSW this class is abstract because it doesn't have DoPopupMenu() 
 244 #ifdef __WXUNIVERSAL__ 
 245     IMPLEMENT_ABSTRACT_CLASS(wxWindowMSW
, wxWindowBase
) 
 247 #if wxUSE_EXTENDED_RTTI 
 249 // windows that are created from a parent window during its Create method, eg. spin controls in a calendar controls 
 250 // must never been streamed out separately otherwise chaos occurs. Right now easiest is to test for negative ids, as 
 251 // windows with negative ids never can be recreated anyway 
 253 bool wxWindowStreamingCallback( const wxObject 
*object
, wxWriter 
* , wxPersister 
* , wxxVariantArray 
& ) 
 255     const wxWindow 
* win 
= dynamic_cast<const wxWindow
*>(object
) ; 
 256     if ( win 
&& win
->GetId() < 0 ) 
 261 IMPLEMENT_DYNAMIC_CLASS_XTI_CALLBACK(wxWindow
, wxWindowBase
,"wx/window.h", wxWindowStreamingCallback
) 
 263 // make wxWindowList known before the property is used 
 265 wxCOLLECTION_TYPE_INFO( wxWindow
* , wxWindowList 
) ; 
 267 template<> void wxCollectionToVariantArray( wxWindowList 
const &theList
, wxxVariantArray 
&value
) 
 269     wxListCollectionToVariantArray
<wxWindowList::compatibility_iterator
>( theList 
, value 
) ; 
 272 WX_DEFINE_FLAGS( wxWindowStyle 
) 
 274 wxBEGIN_FLAGS( wxWindowStyle 
) 
 275     // new style border flags, we put them first to 
 276     // use them for streaming out 
 278     wxFLAGS_MEMBER(wxBORDER_SIMPLE
) 
 279     wxFLAGS_MEMBER(wxBORDER_SUNKEN
) 
 280     wxFLAGS_MEMBER(wxBORDER_DOUBLE
) 
 281     wxFLAGS_MEMBER(wxBORDER_RAISED
) 
 282     wxFLAGS_MEMBER(wxBORDER_STATIC
) 
 283     wxFLAGS_MEMBER(wxBORDER_NONE
) 
 285     // old style border flags 
 286     wxFLAGS_MEMBER(wxSIMPLE_BORDER
) 
 287     wxFLAGS_MEMBER(wxSUNKEN_BORDER
) 
 288     wxFLAGS_MEMBER(wxDOUBLE_BORDER
) 
 289     wxFLAGS_MEMBER(wxRAISED_BORDER
) 
 290     wxFLAGS_MEMBER(wxSTATIC_BORDER
) 
 291     wxFLAGS_MEMBER(wxBORDER
) 
 293     // standard window styles 
 294     wxFLAGS_MEMBER(wxTAB_TRAVERSAL
) 
 295     wxFLAGS_MEMBER(wxCLIP_CHILDREN
) 
 296     wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW
) 
 297     wxFLAGS_MEMBER(wxWANTS_CHARS
) 
 298     wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE
) 
 299     wxFLAGS_MEMBER(wxALWAYS_SHOW_SB 
) 
 300     wxFLAGS_MEMBER(wxVSCROLL
) 
 301     wxFLAGS_MEMBER(wxHSCROLL
) 
 303 wxEND_FLAGS( wxWindowStyle 
) 
 305 wxBEGIN_PROPERTIES_TABLE(wxWindow
) 
 306     wxEVENT_PROPERTY( Close 
, wxEVT_CLOSE_WINDOW 
, wxCloseEvent
) 
 307     wxEVENT_PROPERTY( Create 
, wxEVT_CREATE 
, wxWindowCreateEvent 
) 
 308     wxEVENT_PROPERTY( Destroy 
, wxEVT_DESTROY 
, wxWindowDestroyEvent 
) 
 309     // Always constructor Properties first 
 311     wxREADONLY_PROPERTY( Parent
,wxWindow
*, GetParent
, EMPTY_MACROVALUE 
, 0 /*flags*/ , wxT("Helpstring") , wxT("group")) 
 312     wxPROPERTY( Id
,wxWindowID
, SetId
, GetId
, -1 /*wxID_ANY*/ , 0 /*flags*/ , wxT("Helpstring") , wxT("group") ) 
 313     wxPROPERTY( Position
,wxPoint
, SetPosition 
, GetPosition
, wxDefaultPosition 
, 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // pos 
 314     wxPROPERTY( Size
,wxSize
, SetSize
, GetSize
, wxDefaultSize 
, 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // size 
 315     wxPROPERTY( WindowStyle 
, long , SetWindowStyleFlag 
, GetWindowStyleFlag 
, EMPTY_MACROVALUE 
, 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style 
 317     // Then all relations of the object graph 
 319     wxREADONLY_PROPERTY_COLLECTION( Children 
, wxWindowList 
, wxWindowBase
* , GetWindowChildren 
, wxPROP_OBJECT_GRAPH 
/*flags*/ , wxT("Helpstring") , wxT("group")) 
 321    // and finally all other properties 
 323     wxPROPERTY( ExtraStyle 
, long , SetExtraStyle 
, GetExtraStyle 
, EMPTY_MACROVALUE 
, 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // extstyle 
 324     wxPROPERTY( BackgroundColour 
, wxColour 
, SetBackgroundColour 
, GetBackgroundColour 
, EMPTY_MACROVALUE 
, 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // bg 
 325     wxPROPERTY( ForegroundColour 
, wxColour 
, SetForegroundColour 
, GetForegroundColour 
, EMPTY_MACROVALUE 
, 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // fg 
 326     wxPROPERTY( Enabled 
, bool , Enable 
, IsEnabled 
, wxxVariant((bool)true) , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) 
 327     wxPROPERTY( Shown 
, bool , Show 
, IsShown 
, wxxVariant((bool)true) , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) 
 329     // possible property candidates (not in xrc) or not valid in all subclasses 
 330     wxPROPERTY( Title
,wxString
, SetTitle
, GetTitle
, wxEmptyString 
) 
 331     wxPROPERTY( Font 
, wxFont 
, SetFont 
, GetWindowFont  
, ) 
 332     wxPROPERTY( Label
,wxString
, SetLabel
, GetLabel
, wxEmptyString 
) 
 333     // MaxHeight, Width , MinHeight , Width 
 334     // TODO switch label to control and title to toplevels 
 336     wxPROPERTY( ThemeEnabled 
, bool , SetThemeEnabled 
, GetThemeEnabled 
, ) 
 337     //wxPROPERTY( Cursor , wxCursor , SetCursor , GetCursor , ) 
 338     // wxPROPERTY( ToolTip , wxString , SetToolTip , GetToolTipText , ) 
 339     wxPROPERTY( AutoLayout 
, bool , SetAutoLayout 
, GetAutoLayout 
, ) 
 344 wxEND_PROPERTIES_TABLE() 
 346 wxBEGIN_HANDLERS_TABLE(wxWindow
) 
 347 wxEND_HANDLERS_TABLE() 
 349 wxCONSTRUCTOR_DUMMY(wxWindow
) 
 352     IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
) 
 354 #endif // __WXUNIVERSAL__/__WXMSW__ 
 356 BEGIN_EVENT_TABLE(wxWindowMSW
, wxWindowBase
) 
 357     EVT_SYS_COLOUR_CHANGED(wxWindowMSW::OnSysColourChanged
) 
 358     EVT_ERASE_BACKGROUND(wxWindowMSW::OnEraseBackground
) 
 360     EVT_INIT_DIALOG(wxWindowMSW::OnInitDialog
) 
 364 // =========================================================================== 
 366 // =========================================================================== 
 368 // --------------------------------------------------------------------------- 
 369 // wxWindow utility functions 
 370 // --------------------------------------------------------------------------- 
 372 // Find an item given the MS Windows id 
 373 wxWindow 
*wxWindowMSW::FindItem(long id
) const 
 376     wxControl 
*item 
= wxDynamicCastThis(wxControl
); 
 379         // is it we or one of our "internal" children? 
 380         if ( item
->GetId() == id
 
 381 #ifndef __WXUNIVERSAL__ 
 382                 || (item
->GetSubcontrols().Index(id
) != wxNOT_FOUND
) 
 383 #endif // __WXUNIVERSAL__ 
 389 #endif // wxUSE_CONTROLS 
 391     wxWindowList::compatibility_iterator current 
= GetChildren().GetFirst(); 
 394         wxWindow 
*childWin 
= current
->GetData(); 
 396         wxWindow 
*wnd 
= childWin
->FindItem(id
); 
 400         current 
= current
->GetNext(); 
 406 // Find an item given the MS Windows handle 
 407 wxWindow 
*wxWindowMSW::FindItemByHWND(WXHWND hWnd
, bool controlOnly
) const 
 409     wxWindowList::compatibility_iterator current 
= GetChildren().GetFirst(); 
 412         wxWindow 
*parent 
= current
->GetData(); 
 414         // Do a recursive search. 
 415         wxWindow 
*wnd 
= parent
->FindItemByHWND(hWnd
); 
 421                 || parent
->IsKindOf(CLASSINFO(wxControl
)) 
 422 #endif // wxUSE_CONTROLS 
 425             wxWindow 
*item 
= current
->GetData(); 
 426             if ( item
->GetHWND() == hWnd 
) 
 430                 if ( item
->ContainsHWND(hWnd
) ) 
 435         current 
= current
->GetNext(); 
 440 // Default command handler 
 441 bool wxWindowMSW::MSWCommand(WXUINT 
WXUNUSED(param
), WXWORD 
WXUNUSED(id
)) 
 446 // ---------------------------------------------------------------------------- 
 447 // constructors and such 
 448 // ---------------------------------------------------------------------------- 
 450 void wxWindowMSW::Init() 
 453     m_isBeingDeleted 
= false; 
 455     m_mouseInWindow 
= false; 
 456     m_lastKeydownProcessed 
= false; 
 458     m_childrenDisabled 
= NULL
; 
 467 #if wxUSE_MOUSEEVENT_HACK 
 470     m_lastMouseEvent 
= -1; 
 471 #endif // wxUSE_MOUSEEVENT_HACK 
 473     m_pendingPosition 
= wxDefaultPosition
; 
 474     m_pendingSize 
= wxDefaultSize
; 
 478 wxWindowMSW::~wxWindowMSW() 
 480     m_isBeingDeleted 
= true; 
 482 #ifndef __WXUNIVERSAL__ 
 483     // VS: make sure there's no wxFrame with last focus set to us: 
 484     for ( wxWindow 
*win 
= GetParent(); win
; win 
= win
->GetParent() ) 
 486         wxTopLevelWindow 
*frame 
= wxDynamicCast(win
, wxTopLevelWindow
); 
 489             if ( frame
->GetLastFocus() == this ) 
 491                 frame
->SetLastFocus(NULL
); 
 494             // apparently sometimes we can end up with our grand parent 
 495             // pointing to us as well: this is surely a bug in focus handling 
 496             // code but it's not clear where it happens so for now just try to 
 497             // fix it here by not breaking out of the loop 
 501 #endif // __WXUNIVERSAL__ 
 503     // VS: destroy children first and _then_ detach *this from its parent. 
 504     //     If we'd do it the other way around, children wouldn't be able 
 505     //     find their parent frame (see above). 
 510         // VZ: test temp removed to understand what really happens here 
 511         //if (::IsWindow(GetHwnd())) 
 513             if ( !::DestroyWindow(GetHwnd()) ) 
 514                 wxLogLastError(wxT("DestroyWindow")); 
 517         // remove hWnd <-> wxWindow association 
 518         wxRemoveHandleAssociation(this); 
 521     delete m_childrenDisabled
; 
 525 // real construction (Init() must have been called before!) 
 526 bool wxWindowMSW::Create(wxWindow 
*parent
, 
 531                          const wxString
& name
) 
 533     wxCHECK_MSG( parent
, false, wxT("can't create wxWindow without parent") ); 
 535     if ( !CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
) ) 
 538     parent
->AddChild(this); 
 541     DWORD msflags 
= MSWGetCreateWindowFlags(&exstyle
); 
 543 #ifdef __WXUNIVERSAL__ 
 544     // no borders, we draw them ourselves 
 545     exstyle 
&= ~(WS_EX_DLGMODALFRAME 
| 
 549     msflags 
&= ~WS_BORDER
; 
 550 #endif // wxUniversal 
 554         msflags 
|= WS_VISIBLE
; 
 557     if ( !MSWCreate(wxCanvasClassName
, NULL
, pos
, size
, msflags
, exstyle
) ) 
 565 // --------------------------------------------------------------------------- 
 567 // --------------------------------------------------------------------------- 
 569 void wxWindowMSW::SetFocus() 
 571     HWND hWnd 
= GetHwnd(); 
 572     wxCHECK_RET( hWnd
, _T("can't set focus to invalid window") ); 
 574 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__) 
 578     if ( !::SetFocus(hWnd
) ) 
 580 #if defined(__WXDEBUG__) && !defined(__WXMICROWIN__) 
 581         // was there really an error? 
 582         DWORD dwRes 
= ::GetLastError(); 
 585             HWND hwndFocus 
= ::GetFocus(); 
 586             if ( hwndFocus 
!= hWnd 
) 
 588                 wxLogApiError(_T("SetFocus"), dwRes
); 
 595 void wxWindowMSW::SetFocusFromKbd() 
 597     // when the focus is given to the control with DLGC_HASSETSEL style from 
 598     // keyboard its contents should be entirely selected: this is what 
 599     // ::IsDialogMessage() does and so we should do it as well to provide the 
 600     // same LNF as the native programs 
 601     if ( ::SendMessage(GetHwnd(), WM_GETDLGCODE
, 0, 0) & DLGC_HASSETSEL 
) 
 603         ::SendMessage(GetHwnd(), EM_SETSEL
, 0, -1); 
 606     // do this after (maybe) setting the selection as like this when 
 607     // wxEVT_SET_FOCUS handler is called, the selection would have been already 
 608     // set correctly -- this may be important 
 609     wxWindowBase::SetFocusFromKbd(); 
 612 // Get the window with the focus 
 613 wxWindow 
*wxWindowBase::DoFindFocus() 
 615     HWND hWnd 
= ::GetFocus(); 
 618         return wxGetWindowFromHWND((WXHWND
)hWnd
); 
 624 bool wxWindowMSW::Enable(bool enable
) 
 626     if ( !wxWindowBase::Enable(enable
) ) 
 629     HWND hWnd 
= GetHwnd(); 
 631         ::EnableWindow(hWnd
, (BOOL
)enable
); 
 633     // the logic below doesn't apply to the top level windows -- otherwise 
 634     // showing a modal dialog would result in total greying out (and ungreying 
 635     // out later) of everything which would be really ugly 
 639     // when the parent is disabled, all of its children should be disabled as 
 640     // well but when it is enabled back, only those of the children which 
 641     // hadn't been already disabled in the beginning should be enabled again, 
 642     // so we have to keep the list of those children 
 643     for ( wxWindowList::compatibility_iterator node 
= GetChildren().GetFirst(); 
 645           node 
= node
->GetNext() ) 
 647         wxWindow 
*child 
= node
->GetData(); 
 648         if ( child
->IsTopLevel() ) 
 650             // the logic below doesn't apply to top level children 
 656             // enable the child back unless it had been disabled before us 
 657             if ( !m_childrenDisabled 
|| !m_childrenDisabled
->Find(child
) ) 
 660         else // we're being disabled 
 662             if ( child
->IsEnabled() ) 
 664                 // disable it as children shouldn't stay enabled while the 
 668             else // child already disabled, remember it 
 670                 // have we created the list of disabled children already? 
 671                 if ( !m_childrenDisabled 
) 
 672                     m_childrenDisabled 
= new wxWindowList
; 
 674                 m_childrenDisabled
->Append(child
); 
 679     if ( enable 
&& m_childrenDisabled 
) 
 681         // we don't need this list any more, don't keep unused memory 
 682         delete m_childrenDisabled
; 
 683         m_childrenDisabled 
= NULL
; 
 689 bool wxWindowMSW::Show(bool show
) 
 691     if ( !wxWindowBase::Show(show
) ) 
 694     HWND hWnd 
= GetHwnd(); 
 695     int cshow 
= show 
? SW_SHOW 
: SW_HIDE
; 
 696     ::ShowWindow(hWnd
, cshow
); 
 698     if ( show 
&& IsTopLevel() ) 
 700         wxBringWindowToTop(hWnd
); 
 706 // Raise the window to the top of the Z order 
 707 void wxWindowMSW::Raise() 
 709     wxBringWindowToTop(GetHwnd()); 
 712 // Lower the window to the bottom of the Z order 
 713 void wxWindowMSW::Lower() 
 715     ::SetWindowPos(GetHwnd(), HWND_BOTTOM
, 0, 0, 0, 0, 
 716                    SWP_NOMOVE 
| SWP_NOSIZE 
| SWP_NOACTIVATE
); 
 719 void wxWindowMSW::SetTitle( const wxString
& title
) 
 721     SetWindowText(GetHwnd(), title
.c_str()); 
 724 wxString 
wxWindowMSW::GetTitle() const 
 726     return wxGetWindowText(GetHWND()); 
 729 void wxWindowMSW::DoCaptureMouse() 
 731     HWND hWnd 
= GetHwnd(); 
 738 void wxWindowMSW::DoReleaseMouse() 
 740     if ( !::ReleaseCapture() ) 
 742         wxLogLastError(_T("ReleaseCapture")); 
 746 /* static */ wxWindow 
*wxWindowBase::GetCapture() 
 748     HWND hwnd 
= ::GetCapture(); 
 749     return hwnd 
? wxFindWinFromHandle((WXHWND
)hwnd
) : (wxWindow 
*)NULL
; 
 752 bool wxWindowMSW::SetFont(const wxFont
& font
) 
 754     if ( !wxWindowBase::SetFont(font
) ) 
 760     HWND hWnd 
= GetHwnd(); 
 763         WXHANDLE hFont 
= m_font
.GetResourceHandle(); 
 765         wxASSERT_MSG( hFont
, wxT("should have valid font") ); 
 767         ::SendMessage(hWnd
, WM_SETFONT
, (WPARAM
)hFont
, MAKELPARAM(TRUE
, 0)); 
 772 bool wxWindowMSW::SetCursor(const wxCursor
& cursor
) 
 774     if ( !wxWindowBase::SetCursor(cursor
) ) 
 782         HWND hWnd 
= GetHwnd(); 
 784         // Change the cursor NOW if we're within the correct window 
 787         ::GetCursorPosWinCE(&point
); 
 789         ::GetCursorPos(&point
); 
 792         RECT rect 
= wxGetWindowRect(hWnd
); 
 794         if ( ::PtInRect(&rect
, point
) && !wxIsBusy() ) 
 795             ::SetCursor(GetHcursorOf(m_cursor
)); 
 801 void wxWindowMSW::WarpPointer (int x
, int y
) 
 803     ClientToScreen(&x
, &y
); 
 805     if ( !::SetCursorPos(x
, y
) ) 
 807         wxLogLastError(_T("SetCursorPos")); 
 811 // --------------------------------------------------------------------------- 
 813 // --------------------------------------------------------------------------- 
 815 inline int GetScrollPosition(HWND hWnd
, int wOrient
) 
 817 #ifdef __WXMICROWIN__ 
 818     return ::GetScrollPosWX(hWnd
, wOrient
); 
 820     WinStruct
<SCROLLINFO
> scrollInfo
; 
 821     scrollInfo
.cbSize 
= sizeof(SCROLLINFO
); 
 822     scrollInfo
.fMask 
= SIF_POS
; 
 823     if ( !::GetScrollInfo(hWnd
, 
 827         // Not necessarily an error, if there are no scrollbars yet. 
 828         // wxLogLastError(_T("GetScrollInfo")); 
 830     return scrollInfo
.nPos
; 
 831 //    return ::GetScrollPos(hWnd, wOrient); 
 835 int wxWindowMSW::GetScrollPos(int orient
) const 
 837     HWND hWnd 
= GetHwnd(); 
 838     wxCHECK_MSG( hWnd
, 0, _T("no HWND in GetScrollPos") ); 
 840     return GetScrollPosition(hWnd
, orient 
== wxHORIZONTAL 
? SB_HORZ 
: SB_VERT
); 
 843 // This now returns the whole range, not just the number 
 844 // of positions that we can scroll. 
 845 int wxWindowMSW::GetScrollRange(int orient
) const 
 848     HWND hWnd 
= GetHwnd(); 
 852     ::GetScrollRange(hWnd
, orient 
== wxHORIZONTAL 
? SB_HORZ 
: SB_VERT
, 
 855     WinStruct
<SCROLLINFO
> scrollInfo
; 
 856     scrollInfo
.fMask 
= SIF_RANGE
; 
 857     if ( !::GetScrollInfo(hWnd
, 
 858                           orient 
== wxHORIZONTAL 
? SB_HORZ 
: SB_VERT
, 
 861         // Most of the time this is not really an error, since the return 
 862         // value can also be zero when there is no scrollbar yet. 
 863         // wxLogLastError(_T("GetScrollInfo")); 
 865     maxPos 
= scrollInfo
.nMax
; 
 867     // undo "range - 1" done in SetScrollbar() 
 871 int wxWindowMSW::GetScrollThumb(int orient
) const 
 873     return orient 
== wxHORIZONTAL 
? m_xThumbSize 
: m_yThumbSize
; 
 876 void wxWindowMSW::SetScrollPos(int orient
, int pos
, bool refresh
) 
 878     HWND hWnd 
= GetHwnd(); 
 879     wxCHECK_RET( hWnd
, _T("SetScrollPos: no HWND") ); 
 881     WinStruct
<SCROLLINFO
> info
; 
 885     info
.fMask 
= SIF_POS
; 
 886     if ( HasFlag(wxALWAYS_SHOW_SB
) ) 
 888         // disable scrollbar instead of removing it then 
 889         info
.fMask 
|= SIF_DISABLENOSCROLL
; 
 892     ::SetScrollInfo(hWnd
, orient 
== wxHORIZONTAL 
? SB_HORZ 
: SB_VERT
, 
 896 // New function that will replace some of the above. 
 897 void wxWindowMSW::SetScrollbar(int orient
, 
 903     WinStruct
<SCROLLINFO
> info
; 
 904     info
.nPage 
= pageSize
; 
 905     info
.nMin 
= 0;              // range is nMax - nMin + 1 
 906     info
.nMax 
= range 
- 1;      //  as both nMax and nMax are inclusive 
 908     info
.fMask 
= SIF_RANGE 
| SIF_PAGE 
| SIF_POS
; 
 909     if ( HasFlag(wxALWAYS_SHOW_SB
) ) 
 911         // disable scrollbar instead of removing it then 
 912         info
.fMask 
|= SIF_DISABLENOSCROLL
; 
 915     HWND hWnd 
= GetHwnd(); 
 918         ::SetScrollInfo(hWnd
, orient 
== wxHORIZONTAL 
? SB_HORZ 
: SB_VERT
, 
 922     *(orient 
== wxHORIZONTAL 
? &m_xThumbSize 
: &m_yThumbSize
) = pageSize
; 
 925 void wxWindowMSW::ScrollWindow(int dx
, int dy
, const wxRect 
*prect
) 
 931         rect
.left 
= prect
->x
; 
 933         rect
.right 
= prect
->x 
+ prect
->width
; 
 934         rect
.bottom 
= prect
->y 
+ prect
->height
; 
 944     // FIXME: is this the exact equivalent of the line below? 
 945     ::ScrollWindowEx(GetHwnd(), dx
, dy
, pr
, pr
, 0, 0, SW_SCROLLCHILDREN
|SW_ERASE
|SW_INVALIDATE
); 
 947     ::ScrollWindow(GetHwnd(), dx
, dy
, pr
, pr
); 
 951 static bool ScrollVertically(HWND hwnd
, int kind
, int count
) 
 953     int posStart 
= GetScrollPosition(hwnd
, SB_VERT
); 
 956     for ( int n 
= 0; n 
< count
; n
++ ) 
 958         ::SendMessage(hwnd
, WM_VSCROLL
, kind
, 0); 
 960         int posNew 
= GetScrollPosition(hwnd
, SB_VERT
); 
 963             // don't bother to continue, we're already at top/bottom 
 970     return pos 
!= posStart
; 
 973 bool wxWindowMSW::ScrollLines(int lines
) 
 975     bool down 
= lines 
> 0; 
 977     return ScrollVertically(GetHwnd(), 
 978                             down 
? SB_LINEDOWN 
: SB_LINEUP
, 
 979                             down 
? lines 
: -lines
); 
 982 bool wxWindowMSW::ScrollPages(int pages
) 
 984     bool down 
= pages 
> 0; 
 986     return ScrollVertically(GetHwnd(), 
 987                             down 
? SB_PAGEDOWN 
: SB_PAGEUP
, 
 988                             down 
? pages 
: -pages
); 
 991 // --------------------------------------------------------------------------- 
 993 // --------------------------------------------------------------------------- 
 995 void wxWindowMSW::SubclassWin(WXHWND hWnd
) 
 997     wxASSERT_MSG( !m_oldWndProc
, wxT("subclassing window twice?") ); 
 999     HWND hwnd 
= (HWND
)hWnd
; 
1000     wxCHECK_RET( ::IsWindow(hwnd
), wxT("invalid HWND in SubclassWin") ); 
1002     wxAssociateWinWithHandle(hwnd
, this); 
1004     m_oldWndProc 
= (WXFARPROC
)wxGetWindowProc((HWND
)hWnd
); 
1006     // we don't need to subclass the window of our own class (in the Windows 
1007     // sense of the word) 
1008     if ( !wxCheckWindowWndProc(hWnd
, (WXFARPROC
)wxWndProc
) ) 
1010         wxSetWindowProc(hwnd
, wxWndProc
); 
1014         // don't bother restoring it neither: this also makes it easy to 
1015         // implement IsOfStandardClass() method which returns true for the 
1016         // standard controls and false for the wxWidgets own windows as it can 
1017         // simply check m_oldWndProc 
1018         m_oldWndProc 
= NULL
; 
1022 void wxWindowMSW::UnsubclassWin() 
1024     wxRemoveHandleAssociation(this); 
1026     // Restore old Window proc 
1027     HWND hwnd 
= GetHwnd(); 
1032         wxCHECK_RET( ::IsWindow(hwnd
), wxT("invalid HWND in UnsubclassWin") ); 
1036             if ( !wxCheckWindowWndProc((WXHWND
)hwnd
, m_oldWndProc
) ) 
1038                 wxSetWindowProc(hwnd
, (WNDPROC
)m_oldWndProc
); 
1041             m_oldWndProc 
= NULL
; 
1046 void wxWindowMSW::AssociateHandle(WXWidget handle
) 
1050       if ( !::DestroyWindow(GetHwnd()) ) 
1051         wxLogLastError(wxT("DestroyWindow")); 
1054     WXHWND wxhwnd 
= (WXHWND
)handle
; 
1057     SubclassWin(wxhwnd
); 
1060 void wxWindowMSW::DissociateHandle() 
1062     // this also calls SetHWND(0) for us 
1067 bool wxCheckWindowWndProc(WXHWND hWnd
, 
1068                           WXFARPROC 
WXUNUSED_IN_WINCE(wndProc
)) 
1070     // Unicows note: the code below works, but only because WNDCLASS contains 
1071     // original window handler rather that the unicows fake one. This may not 
1072     // be on purpose, though; if it stops working with future versions of 
1073     // unicows.dll, we can override unicows hooks by setting 
1074     // Unicows_{Set,Get}WindowLong and Unicows_RegisterClass to our own 
1075     // versions that keep track of fake<->real wnd proc mapping. 
1077     // On WinCE (at least), the wndproc comparison doesn't work, 
1078     // so have to use something like this. 
1080     extern       wxChar 
*wxCanvasClassName
; 
1081     extern       wxChar 
*wxCanvasClassNameNR
; 
1082     extern const wxChar 
*wxMDIFrameClassName
; 
1083     extern const wxChar 
*wxMDIFrameClassNameNoRedraw
; 
1084     extern const wxChar 
*wxMDIChildFrameClassName
; 
1085     extern const wxChar 
*wxMDIChildFrameClassNameNoRedraw
; 
1086     wxString 
str(wxGetWindowClass(hWnd
)); 
1087     if (str 
== wxCanvasClassName 
|| 
1088         str 
== wxCanvasClassNameNR 
|| 
1089         str 
== wxMDIFrameClassName 
|| 
1090         str 
== wxMDIFrameClassNameNoRedraw 
|| 
1091         str 
== wxMDIChildFrameClassName 
|| 
1092         str 
== wxMDIChildFrameClassNameNoRedraw 
|| 
1093         str 
== _T("wxTLWHiddenParent")) 
1094         return true; // Effectively means don't subclass 
1099     if ( !::GetClassInfo(wxGetInstance(), wxGetWindowClass(hWnd
), &cls
) ) 
1101         wxLogLastError(_T("GetClassInfo")); 
1106     return wndProc 
== (WXFARPROC
)cls
.lpfnWndProc
; 
1110 // ---------------------------------------------------------------------------- 
1112 // ---------------------------------------------------------------------------- 
1114 void wxWindowMSW::SetWindowStyleFlag(long flags
) 
1116     long flagsOld 
= GetWindowStyleFlag(); 
1117     if ( flags 
== flagsOld 
) 
1120     // update the internal variable 
1121     wxWindowBase::SetWindowStyleFlag(flags
); 
1123     // now update the Windows style as well if needed - and if the window had 
1124     // been already created 
1128     WXDWORD exstyle
, exstyleOld
; 
1129     long style 
= MSWGetStyle(flags
, &exstyle
), 
1130          styleOld 
= MSWGetStyle(flagsOld
, &exstyleOld
); 
1132     if ( style 
!= styleOld 
) 
1134         // some flags (e.g. WS_VISIBLE or WS_DISABLED) should not be changed by 
1135         // this function so instead of simply setting the style to the new 
1136         // value we clear the bits which were set in styleOld but are set in 
1137         // the new one and set the ones which were not set before 
1138         long styleReal 
= ::GetWindowLong(GetHwnd(), GWL_STYLE
); 
1139         styleReal 
&= ~styleOld
; 
1142         ::SetWindowLong(GetHwnd(), GWL_STYLE
, styleReal
); 
1145     // and the extended style 
1146     if ( exstyle 
!= exstyleOld 
) 
1148         long exstyleReal 
= ::GetWindowLong(GetHwnd(), GWL_EXSTYLE
); 
1149         exstyleReal 
&= ~exstyleOld
; 
1150         exstyleReal 
|= exstyle
; 
1152         ::SetWindowLong(GetHwnd(), GWL_EXSTYLE
, exstyleReal
); 
1154         // we must call SetWindowPos() to flush the cached extended style and 
1155         // also to make the change to wxSTAY_ON_TOP style take effect: just 
1156         // setting the style simply doesn't work 
1157         if ( !::SetWindowPos(GetHwnd(), 
1158                              exstyleReal 
& WS_EX_TOPMOST 
? HWND_TOPMOST
 
1161                              SWP_NOMOVE 
| SWP_NOSIZE
) ) 
1163             wxLogLastError(_T("SetWindowPos")); 
1168 WXDWORD 
wxWindowMSW::MSWGetStyle(long flags
, WXDWORD 
*exstyle
) const 
1170     // translate common wxWidgets styles to Windows ones 
1172     // most of windows are child ones, those which are not (such as 
1173     // wxTopLevelWindow) should remove WS_CHILD in their MSWGetStyle() 
1174     WXDWORD style 
= WS_CHILD
; 
1176     // using this flag results in very significant reduction in flicker, 
1177     // especially with controls inside the static boxes (as the interior of the 
1178     // box is not redrawn twice).but sometimes results in redraw problems, so 
1179     // optionally allow the old code to continue to use it provided a special 
1180     // system option is turned on 
1181     if ( !wxSystemOptions::GetOptionInt(wxT("msw.window.no-clip-children")) 
1182             || (flags 
& wxCLIP_CHILDREN
) ) 
1183         style 
|= WS_CLIPCHILDREN
; 
1185     // it doesn't seem useful to use WS_CLIPSIBLINGS here as we officially 
1186     // don't support overlapping windows and it only makes sense for them and, 
1187     // presumably, gives the system some extra work (to manage more clipping 
1188     // regions), so avoid it alltogether 
1191     if ( flags 
& wxVSCROLL 
) 
1192         style 
|= WS_VSCROLL
; 
1194     if ( flags 
& wxHSCROLL 
) 
1195         style 
|= WS_HSCROLL
; 
1197     const wxBorder border 
= GetBorder(flags
); 
1199     // WS_BORDER is only required for wxBORDER_SIMPLE 
1200     if ( border 
== wxBORDER_SIMPLE 
) 
1203     // now deal with ext style if the caller wants it 
1209         if ( flags 
& wxTRANSPARENT_WINDOW 
) 
1210             *exstyle 
|= WS_EX_TRANSPARENT
; 
1216             case wxBORDER_DEFAULT
: 
1217                 wxFAIL_MSG( _T("unknown border style") ); 
1221             case wxBORDER_SIMPLE
: 
1224             case wxBORDER_STATIC
: 
1225                 *exstyle 
|= WS_EX_STATICEDGE
; 
1228             case wxBORDER_RAISED
: 
1229                 *exstyle 
|= WS_EX_DLGMODALFRAME
; 
1232             case wxBORDER_SUNKEN
: 
1233                 *exstyle 
|= WS_EX_CLIENTEDGE
; 
1234                 style 
&= ~WS_BORDER
; 
1237             case wxBORDER_DOUBLE
: 
1238                 *exstyle 
|= WS_EX_DLGMODALFRAME
; 
1242         // wxUniv doesn't use Windows dialog navigation functions at all 
1243 #if !defined(__WXUNIVERSAL__) && !defined(__WXWINCE__) 
1244         // to make the dialog navigation work with the nested panels we must 
1245         // use this style (top level windows such as dialogs don't need it) 
1246         if ( (flags 
& wxTAB_TRAVERSAL
) && !IsTopLevel() ) 
1248             *exstyle 
|= WS_EX_CONTROLPARENT
; 
1250 #endif // __WXUNIVERSAL__ 
1256 // Setup background and foreground colours correctly 
1257 void wxWindowMSW::SetupColours() 
1260         SetBackgroundColour(GetParent()->GetBackgroundColour()); 
1263 bool wxWindowMSW::IsMouseInWindow() const 
1265     // get the mouse position 
1268     ::GetCursorPosWinCE(&pt
); 
1270     ::GetCursorPos(&pt
); 
1273     // find the window which currently has the cursor and go up the window 
1274     // chain until we find this window - or exhaust it 
1275     HWND hwnd 
= ::WindowFromPoint(pt
); 
1276     while ( hwnd 
&& (hwnd 
!= GetHwnd()) ) 
1277         hwnd 
= ::GetParent(hwnd
); 
1279     return hwnd 
!= NULL
; 
1282 void wxWindowMSW::OnInternalIdle() 
1284 #ifndef HAVE_TRACKMOUSEEVENT 
1285     // Check if we need to send a LEAVE event 
1286     if ( m_mouseInWindow 
) 
1288         // note that we should generate the leave event whether the window has 
1289         // or doesn't have mouse capture 
1290         if ( !IsMouseInWindow() ) 
1292             GenerateMouseLeave(); 
1295 #endif // !HAVE_TRACKMOUSEEVENT 
1297     if (wxUpdateUIEvent::CanUpdate(this)) 
1298         UpdateWindowUI(wxUPDATE_UI_FROMIDLE
); 
1301 // Set this window to be the child of 'parent'. 
1302 bool wxWindowMSW::Reparent(wxWindowBase 
*parent
) 
1304     if ( !wxWindowBase::Reparent(parent
) ) 
1307     HWND hWndChild 
= GetHwnd(); 
1308     HWND hWndParent 
= GetParent() ? GetWinHwnd(GetParent()) : (HWND
)0; 
1310     ::SetParent(hWndChild
, hWndParent
); 
1313     if ( ::GetWindowLong(hWndChild
, GWL_EXSTYLE
) & WS_EX_CONTROLPARENT 
) 
1315         EnsureParentHasControlParentStyle(GetParent()); 
1317 #endif // !__WXWINCE__ 
1322 static inline void SendSetRedraw(HWND hwnd
, bool on
) 
1324 #ifndef __WXMICROWIN__ 
1325     ::SendMessage(hwnd
, WM_SETREDRAW
, (WPARAM
)on
, 0); 
1329 void wxWindowMSW::Freeze() 
1331     if ( !m_frozenness
++ ) 
1334             SendSetRedraw(GetHwnd(), false); 
1338 void wxWindowMSW::Thaw() 
1340     wxASSERT_MSG( m_frozenness 
> 0, _T("Thaw() without matching Freeze()") ); 
1342     if ( !--m_frozenness 
) 
1346             SendSetRedraw(GetHwnd(), true); 
1348             // we need to refresh everything or otherwise the invalidated area 
1349             // is not going to be repainted 
1355 void wxWindowMSW::Refresh(bool eraseBack
, const wxRect 
*rect
) 
1357     HWND hWnd 
= GetHwnd(); 
1364             mswRect
.left 
= rect
->x
; 
1365             mswRect
.top 
= rect
->y
; 
1366             mswRect
.right 
= rect
->x 
+ rect
->width
; 
1367             mswRect
.bottom 
= rect
->y 
+ rect
->height
; 
1376         // RedrawWindow not available on SmartPhone or eVC++ 3 
1377 #if !defined(__SMARTPHONE__) && !(defined(_WIN32_WCE) && _WIN32_WCE < 400) 
1378         UINT flags 
= RDW_INVALIDATE 
| RDW_ALLCHILDREN
; 
1382         ::RedrawWindow(hWnd
, pRect
, NULL
, flags
); 
1384         ::InvalidateRect(hWnd
, pRect
, eraseBack
); 
1389 void wxWindowMSW::Update() 
1391     if ( !::UpdateWindow(GetHwnd()) ) 
1393         wxLogLastError(_T("UpdateWindow")); 
1396 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__) 
1397     // just calling UpdateWindow() is not enough, what we did in our WM_PAINT 
1398     // handler needs to be really drawn right now 
1403 // --------------------------------------------------------------------------- 
1405 // --------------------------------------------------------------------------- 
1408 #if wxUSE_DRAG_AND_DROP 
1409 void wxWindowMSW::SetDropTarget(wxDropTarget 
*pDropTarget
) 
1411     if ( m_dropTarget 
!= 0 ) { 
1412         m_dropTarget
->Revoke(m_hWnd
); 
1413         delete m_dropTarget
; 
1416     m_dropTarget 
= pDropTarget
; 
1417     if ( m_dropTarget 
!= 0 ) 
1418         m_dropTarget
->Register(m_hWnd
); 
1420 #endif // wxUSE_DRAG_AND_DROP 
1422 // old style file-manager drag&drop support: we retain the old-style 
1423 // DragAcceptFiles in parallel with SetDropTarget. 
1424 void wxWindowMSW::DragAcceptFiles(bool WXUNUSED_IN_WINCE(accept
)) 
1427     HWND hWnd 
= GetHwnd(); 
1429         ::DragAcceptFiles(hWnd
, (BOOL
)accept
); 
1433 // ---------------------------------------------------------------------------- 
1435 // ---------------------------------------------------------------------------- 
1439 void wxWindowMSW::DoSetToolTip(wxToolTip 
*tooltip
) 
1441     wxWindowBase::DoSetToolTip(tooltip
); 
1444         m_tooltip
->SetWindow((wxWindow 
*)this); 
1447 #endif // wxUSE_TOOLTIPS 
1449 // --------------------------------------------------------------------------- 
1450 // moving and resizing 
1451 // --------------------------------------------------------------------------- 
1453 bool wxWindowMSW::IsSizeDeferred() const 
1455 #if USE_DEFERRED_SIZING 
1456     if ( m_pendingPosition 
!= wxDefaultPosition 
|| 
1457          m_pendingSize     
!= wxDefaultSize 
) 
1459 #endif // USE_DEFERRED_SIZING 
1465 void wxWindowMSW::DoGetSize(int *x
, int *y
) const 
1467     // if SetSize() had been called at wx level but not realized at Windows 
1468     // level yet (i.e. EndDeferWindowPos() not called), we still should return 
1469     // the new and not the old position to the other wx code 
1470     if ( m_pendingSize 
!= wxDefaultSize 
) 
1473             *x 
= m_pendingSize
.x
; 
1475             *y 
= m_pendingSize
.y
; 
1477     else // use current size 
1479         RECT rect 
= wxGetWindowRect(GetHwnd()); 
1482             *x 
= rect
.right 
- rect
.left
; 
1484             *y 
= rect
.bottom 
- rect
.top
; 
1488 // Get size *available for subwindows* i.e. excluding menu bar etc. 
1489 void wxWindowMSW::DoGetClientSize(int *x
, int *y
) const 
1491     // this is only for top level windows whose resizing is never deferred, so 
1492     // we can safely use the current size here 
1493     RECT rect 
= wxGetClientRect(GetHwnd()); 
1501 void wxWindowMSW::DoGetPosition(int *x
, int *y
) const 
1503     wxWindow 
* const parent 
= GetParent(); 
1506     if ( m_pendingPosition 
!= wxDefaultPosition 
) 
1508         pos 
= m_pendingPosition
; 
1510     else // use current position 
1512         RECT rect 
= wxGetWindowRect(GetHwnd()); 
1515         point
.x 
= rect
.left
; 
1518         // we do the adjustments with respect to the parent only for the "real" 
1519         // children, not for the dialogs/frames 
1520         if ( !IsTopLevel() ) 
1522             // Since we now have the absolute screen coords, if there's a 
1523             // parent we must subtract its top left corner 
1526                 ::ScreenToClient(GetHwndOf(parent
), &point
); 
1534     // we also must adjust by the client area offset: a control which is just 
1535     // under a toolbar could be at (0, 30) in Windows but at (0, 0) in wx 
1536     if ( parent 
&& !IsTopLevel() ) 
1538         const wxPoint 
pt(parent
->GetClientAreaOrigin()); 
1549 void wxWindowMSW::DoScreenToClient(int *x
, int *y
) const 
1557     ::ScreenToClient(GetHwnd(), &pt
); 
1565 void wxWindowMSW::DoClientToScreen(int *x
, int *y
) const 
1573     ::ClientToScreen(GetHwnd(), &pt
); 
1582 wxWindowMSW::DoMoveSibling(WXHWND hwnd
, int x
, int y
, int width
, int height
) 
1584 #if USE_DEFERRED_SIZING 
1585     // if our parent had prepared a defer window handle for us, use it (unless 
1586     // we are a top level window) 
1587     wxWindowMSW 
* const parent 
= IsTopLevel() ? NULL 
: GetParent(); 
1589     HDWP hdwp 
= parent 
? (HDWP
)parent
->m_hDWP 
: NULL
; 
1592         hdwp 
= ::DeferWindowPos(hdwp
, (HWND
)hwnd
, NULL
, x
, y
, width
, height
, 
1596             wxLogLastError(_T("DeferWindowPos")); 
1602         // hdwp must be updated as it may have been changed 
1603         parent
->m_hDWP 
= (WXHANDLE
)hdwp
; 
1608         // did deferred move, remember new coordinates of the window as they're 
1609         // different from what Windows would return for it 
1613     // otherwise (or if deferring failed) move the window in place immediately 
1614 #endif // USE_DEFERRED_SIZING 
1615     if ( !::MoveWindow((HWND
)hwnd
, x
, y
, width
, height
, IsShown()) ) 
1617         wxLogLastError(wxT("MoveWindow")); 
1620     // if USE_DEFERRED_SIZING, indicates that we didn't use deferred move, 
1621     // ignored otherwise 
1625 void wxWindowMSW::DoMoveWindow(int x
, int y
, int width
, int height
) 
1627     // TODO: is this consistent with other platforms? 
1628     // Still, negative width or height shouldn't be allowed 
1634     if ( DoMoveSibling(m_hWnd
, x
, y
, width
, height
) ) 
1636 #if USE_DEFERRED_SIZING 
1637         m_pendingPosition 
= wxPoint(x
, y
); 
1638         m_pendingSize 
= wxSize(width
, height
); 
1639 #endif // USE_DEFERRED_SIZING 
1643 // set the size of the window: if the dimensions are positive, just use them, 
1644 // but if any of them is equal to -1, it means that we must find the value for 
1645 // it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in 
1646 // which case -1 is a valid value for x and y) 
1648 // If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate 
1649 // the width/height to best suit our contents, otherwise we reuse the current 
1651 void wxWindowMSW::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
) 
1653     // get the current size and position... 
1654     int currentX
, currentY
; 
1655     int currentW
, currentH
; 
1657     GetPosition(¤tX
, ¤tY
); 
1658     GetSize(¤tW
, ¤tH
); 
1660     // ... and don't do anything (avoiding flicker) if it's already ok unless 
1661     // we're forced to resize the window 
1662     if ( x 
== currentX 
&& y 
== currentY 
&& 
1663          width 
== currentW 
&& height 
== currentH 
&& 
1664             !(sizeFlags 
& wxSIZE_FORCE
) ) 
1669     if ( x 
== wxDefaultCoord 
&& !(sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
) ) 
1671     if ( y 
== wxDefaultCoord 
&& !(sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
) ) 
1674     AdjustForParentClientOrigin(x
, y
, sizeFlags
); 
1676     wxSize size 
= wxDefaultSize
; 
1677     if ( width 
== wxDefaultCoord 
) 
1679         if ( sizeFlags 
& wxSIZE_AUTO_WIDTH 
) 
1681             size 
= DoGetBestSize(); 
1686             // just take the current one 
1691     if ( height 
== wxDefaultCoord 
) 
1693         if ( sizeFlags 
& wxSIZE_AUTO_HEIGHT 
) 
1695             if ( size
.x 
== wxDefaultCoord 
) 
1697                 size 
= DoGetBestSize(); 
1699             //else: already called DoGetBestSize() above 
1705             // just take the current one 
1710     DoMoveWindow(x
, y
, width
, height
); 
1713 void wxWindowMSW::DoSetClientSize(int width
, int height
) 
1715     // setting the client size is less obvious than it it could have been 
1716     // because in the result of changing the total size the window scrollbar 
1717     // may [dis]appear and/or its menubar may [un]wrap and so the client size 
1718     // will not be correct as the difference between the total and client size 
1719     // changes - so we keep changing it until we get it right 
1721     // normally this loop shouldn't take more than 3 iterations (usually 1 but 
1722     // if scrollbars [dis]appear as the result of the first call, then 2 and it 
1723     // may become 3 if the window had 0 size originally and so we didn't 
1724     // calculate the scrollbar correction correctly during the first iteration) 
1725     // but just to be on the safe side we check for it instead of making it an 
1726     // "infinite" loop (i.e. leaving break inside as the only way to get out) 
1727     for ( int i 
= 0; i 
< 4; i
++ ) 
1730         ::GetClientRect(GetHwnd(), &rectClient
); 
1732         // if the size is already ok, stop here (NB: rectClient.left = top = 0) 
1733         if ( (rectClient
.right 
== width 
|| width 
== wxDefaultCoord
) && 
1734              (rectClient
.bottom 
== height 
|| height 
== wxDefaultCoord
) ) 
1739         // Find the difference between the entire window (title bar and all) 
1740         // and the client area; add this to the new client size to move the 
1743         ::GetWindowRect(GetHwnd(), &rectWin
); 
1745         const int widthWin 
= rectWin
.right 
- rectWin
.left
, 
1746                   heightWin 
= rectWin
.bottom 
- rectWin
.top
; 
1748         // MoveWindow positions the child windows relative to the parent, so 
1749         // adjust if necessary 
1750         if ( !IsTopLevel() ) 
1752             wxWindow 
*parent 
= GetParent(); 
1755                 ::ScreenToClient(GetHwndOf(parent
), (POINT 
*)&rectWin
); 
1759         // don't call DoMoveWindow() because we want to move window immediately 
1760         // and not defer it here 
1761         if ( !::MoveWindow(GetHwnd(), 
1764                            width 
+ widthWin 
- rectClient
.right
, 
1765                            height 
+ heightWin 
- rectClient
.bottom
, 
1768             wxLogLastError(_T("MoveWindow")); 
1773 // --------------------------------------------------------------------------- 
1775 // --------------------------------------------------------------------------- 
1777 int wxWindowMSW::GetCharHeight() const 
1779     return wxGetTextMetrics(this).tmHeight
; 
1782 int wxWindowMSW::GetCharWidth() const 
1784     // +1 is needed because Windows apparently adds it when calculating the 
1785     // dialog units size in pixels 
1786 #if wxDIALOG_UNIT_COMPATIBILITY 
1787     return wxGetTextMetrics(this).tmAveCharWidth
; 
1789     return wxGetTextMetrics(this).tmAveCharWidth 
+ 1; 
1793 void wxWindowMSW::GetTextExtent(const wxString
& string
, 
1795                              int *descent
, int *externalLeading
, 
1796                              const wxFont 
*theFont
) const 
1798     wxASSERT_MSG( !theFont 
|| theFont
->Ok(), 
1799                     _T("invalid font in GetTextExtent()") ); 
1803         fontToUse 
= *theFont
; 
1805         fontToUse 
= GetFont(); 
1807     WindowHDC 
hdc(GetHwnd()); 
1808     SelectInHDC 
selectFont(hdc
, GetHfontOf(fontToUse
)); 
1812     ::GetTextExtentPoint32(hdc
, string
, string
.length(), &sizeRect
); 
1813     GetTextMetrics(hdc
, &tm
); 
1820         *descent 
= tm
.tmDescent
; 
1821     if ( externalLeading 
) 
1822         *externalLeading 
= tm
.tmExternalLeading
; 
1825 // --------------------------------------------------------------------------- 
1827 // --------------------------------------------------------------------------- 
1829 #if wxUSE_MENUS_NATIVE 
1831 // yield for WM_COMMAND events only, i.e. process all WM_COMMANDs in the queue 
1832 // immediately, without waiting for the next event loop iteration 
1834 // NB: this function should probably be made public later as it can almost 
1835 //     surely replace wxYield() elsewhere as well 
1836 static void wxYieldForCommandsOnly() 
1838     // peek all WM_COMMANDs (it will always return WM_QUIT too but we don't 
1839     // want to process it here) 
1841     while ( ::PeekMessage(&msg
, (HWND
)0, WM_COMMAND
, WM_COMMAND
, PM_REMOVE
) ) 
1843         if ( msg
.message 
== WM_QUIT 
) 
1845             // if we retrieved a WM_QUIT, insert back into the message queue. 
1846             ::PostQuitMessage(0); 
1850         // luckily (as we don't have access to wxEventLoopImpl method from here 
1851         // anyhow...) we don't need to pre process WM_COMMANDs so dispatch it 
1853         ::TranslateMessage(&msg
); 
1854         ::DispatchMessage(&msg
); 
1858 bool wxWindowMSW::DoPopupMenu(wxMenu 
*menu
, int x
, int y
) 
1860     menu
->SetInvokingWindow(this); 
1863     if ( x 
== wxDefaultCoord 
&& y 
== wxDefaultCoord 
) 
1865         wxPoint mouse 
= ScreenToClient(wxGetMousePosition()); 
1866         x 
= mouse
.x
; y 
= mouse
.y
; 
1869     HWND hWnd 
= GetHwnd(); 
1870     HMENU hMenu 
= GetHmenuOf(menu
); 
1874     ::ClientToScreen(hWnd
, &point
); 
1875     wxCurrentPopupMenu 
= menu
; 
1876 #if defined(__WXWINCE__) 
1879     UINT flags 
= TPM_RIGHTBUTTON
; 
1881     ::TrackPopupMenu(hMenu
, flags
, point
.x
, point
.y
, 0, hWnd
, NULL
); 
1883     // we need to do it righ now as otherwise the events are never going to be 
1884     // sent to wxCurrentPopupMenu from HandleCommand() 
1886     // note that even eliminating (ugly) wxCurrentPopupMenu global wouldn't 
1887     // help and we'd still need wxYieldForCommandsOnly() as the menu may be 
1888     // destroyed as soon as we return (it can be a local variable in the caller 
1889     // for example) and so we do need to process the event immediately 
1890     wxYieldForCommandsOnly(); 
1892     wxCurrentPopupMenu 
= NULL
; 
1894     menu
->SetInvokingWindow(NULL
); 
1899 #endif // wxUSE_MENUS_NATIVE 
1901 // =========================================================================== 
1902 // pre/post message processing 
1903 // =========================================================================== 
1905 WXLRESULT 
wxWindowMSW::MSWDefWindowProc(WXUINT nMsg
, WXWPARAM wParam
, WXLPARAM lParam
) 
1908         return ::CallWindowProc(CASTWNDPROC m_oldWndProc
, GetHwnd(), (UINT
) nMsg
, (WPARAM
) wParam
, (LPARAM
) lParam
); 
1910         return ::DefWindowProc(GetHwnd(), nMsg
, wParam
, lParam
); 
1913 bool wxWindowMSW::MSWProcessMessage(WXMSG
* pMsg
) 
1915     // wxUniversal implements tab traversal itself 
1916 #ifndef __WXUNIVERSAL__ 
1917     if ( m_hWnd 
!= 0 && (GetWindowStyleFlag() & wxTAB_TRAVERSAL
) ) 
1919         // intercept dialog navigation keys 
1920         MSG 
*msg 
= (MSG 
*)pMsg
; 
1922         // here we try to do all the job which ::IsDialogMessage() usually does 
1924         if ( msg
->message 
== WM_KEYDOWN 
) 
1926             bool bCtrlDown 
= wxIsCtrlDown(); 
1927             bool bShiftDown 
= wxIsShiftDown(); 
1929             // WM_GETDLGCODE: ask the control if it wants the key for itself, 
1930             // don't process it if it's the case (except for Ctrl-Tab/Enter 
1931             // combinations which are always processed) 
1935                 lDlgCode 
= ::SendMessage(msg
->hwnd
, WM_GETDLGCODE
, 0, 0); 
1937                 // surprizingly, DLGC_WANTALLKEYS bit mask doesn't contain the 
1938                 // DLGC_WANTTAB nor DLGC_WANTARROWS bits although, logically, 
1939                 // it, of course, implies them 
1940                 if ( lDlgCode 
& DLGC_WANTALLKEYS 
) 
1942                     lDlgCode 
|= DLGC_WANTTAB 
| DLGC_WANTARROWS
; 
1946             bool bForward 
= true, 
1947                  bWindowChange 
= false, 
1950             // should we process this message specially? 
1951             bool bProcess 
= true; 
1952             switch ( msg
->wParam 
) 
1955                     if ( lDlgCode 
& DLGC_WANTTAB 
) { 
1959                         // Ctrl-Tab cycles thru notebook pages 
1960                         bWindowChange 
= bCtrlDown
; 
1961                         bForward 
= !bShiftDown
; 
1968                     if ( (lDlgCode 
& DLGC_WANTARROWS
) || bCtrlDown 
) 
1976                     if ( (lDlgCode 
& DLGC_WANTARROWS
) || bCtrlDown 
) 
1982                         if ( (lDlgCode 
& DLGC_WANTMESSAGE
) && !bCtrlDown 
) 
1984                             // control wants to process Enter itself, don't 
1985                             // call IsDialogMessage() which would interpret 
1990                         // currently active button should get enter press even 
1991                         // if there is a default button elsewhere 
1992                         if ( lDlgCode 
& DLGC_DEFPUSHBUTTON 
) 
1994                             // let IsDialogMessage() handle this for all 
1995                             // buttons except the owner-drawn ones which it 
1996                             // just seems to ignore 
1997                             long style 
= ::GetWindowLong(msg
->hwnd
, GWL_STYLE
); 
1998                             if ( (style 
& BS_OWNERDRAW
) == BS_OWNERDRAW 
) 
2000                                 // emulate the button click 
2002                                     btn 
= wxFindWinFromHandle((WXHWND
)msg
->hwnd
); 
2004                                     btn
->MSWCommand(BN_CLICKED
, 0 /* unused */); 
2009                         else // not a button itself 
2012                             wxButton 
*btn 
= wxDynamicCast(GetDefaultItem(), 
2014                             if ( btn 
&& btn
->IsEnabled() ) 
2016                                 // if we do have a default button, do press it 
2017                                 btn
->MSWCommand(BN_CLICKED
, 0 /* unused */); 
2021                             else // no default button 
2022 #endif // wxUSE_BUTTON 
2024                                 // this is a quick and dirty test for a text 
2026                                 if ( !(lDlgCode 
& DLGC_HASSETSEL
) ) 
2028                                     // don't process Enter, the control might 
2029                                     // need it for itself and don't let 
2030                                     // ::IsDialogMessage() have it as it can 
2031                                     // eat the Enter events sometimes 
2034                                 else if (!IsTopLevel()) 
2036                                     // if not a top level window, let parent 
2040                                 //else: treat Enter as TAB: pass to the next 
2041                                 //      control as this is the best thing to do 
2042                                 //      if the text doesn't handle Enter itself 
2054                 wxNavigationKeyEvent event
; 
2055                 event
.SetDirection(bForward
); 
2056                 event
.SetWindowChange(bWindowChange
); 
2057                 event
.SetFromTab(bFromTab
); 
2058                 event
.SetEventObject(this); 
2060                 if ( GetEventHandler()->ProcessEvent(event
) ) 
2067         // don't let IsDialogMessage() get VK_ESCAPE as it _always_ eats the 
2068         // message even when there is no cancel button and when the message is 
2069         // needed by the control itself: in particular, it prevents the tree in 
2070         // place edit control from being closed with Escape in a dialog 
2071         if ( msg
->message 
!= WM_KEYDOWN 
|| msg
->wParam 
!= VK_ESCAPE 
) 
2073             // ::IsDialogMessage() is broken and may sometimes hang the 
2074             // application by going into an infinite loop, so we try to detect 
2075             // [some of] the situatations when this may happen and not call it 
2078             // assume we can call it by default 
2079             bool canSafelyCallIsDlgMsg 
= true; 
2081             HWND hwndFocus 
= ::GetFocus(); 
2083             // if the currently focused window itself has WS_EX_CONTROLPARENT style, ::IsDialogMessage() will also enter 
2084             // an infinite loop, because it will recursively check the child 
2085             // windows but not the window itself and so if none of the children 
2086             // accepts focus it loops forever (as it only stops when it gets 
2087             // back to the window it started from) 
2089             // while it is very unusual that a window with WS_EX_CONTROLPARENT 
2090             // style has the focus, it can happen. One such possibility is if 
2091             // all windows are either toplevel, wxDialog, wxPanel or static 
2092             // controls and no window can actually accept keyboard input. 
2093 #if !defined(__WXWINCE__) 
2094             if ( ::GetWindowLong(hwndFocus
, GWL_EXSTYLE
) & WS_EX_CONTROLPARENT 
) 
2096                 // passimistic by default 
2097                 canSafelyCallIsDlgMsg 
= false; 
2098                 for ( wxWindowList::compatibility_iterator node 
= GetChildren().GetFirst(); 
2100                       node 
= node
->GetNext() ) 
2102                     wxWindow 
* const win 
= node
->GetData(); 
2103                     if ( win
->AcceptsFocus() && 
2104                             !(::GetWindowLong(GetHwndOf(win
), GWL_EXSTYLE
) & 
2105                                 WS_EX_CONTROLPARENT
) ) 
2107                         // it shouldn't hang... 
2108                         canSafelyCallIsDlgMsg 
= true; 
2114 #endif // !__WXWINCE__ 
2116             if ( canSafelyCallIsDlgMsg 
) 
2118                 // ::IsDialogMessage() can enter in an infinite loop when the 
2119                 // currently focused window is disabled or hidden and its 
2120                 // parent has WS_EX_CONTROLPARENT style, so don't call it in 
2124                     if ( !::IsWindowEnabled(hwndFocus
) || 
2125                             !::IsWindowVisible(hwndFocus
) ) 
2127                         // it would enter an infinite loop if we do this! 
2128                         canSafelyCallIsDlgMsg 
= false; 
2133                     if ( !(::GetWindowLong(hwndFocus
, GWL_STYLE
) & WS_CHILD
) ) 
2135                         // it's a top level window, don't go further -- e.g. even 
2136                         // if the parent of a dialog is disabled, this doesn't 
2137                         // break navigation inside the dialog 
2141                     hwndFocus 
= ::GetParent(hwndFocus
); 
2145             // let IsDialogMessage() have the message if it's safe to call it 
2146             if ( canSafelyCallIsDlgMsg 
&& ::IsDialogMessage(GetHwnd(), msg
) ) 
2148                 // IsDialogMessage() did something... 
2153 #endif // __WXUNIVERSAL__ 
2158         // relay mouse move events to the tooltip control 
2159         MSG 
*msg 
= (MSG 
*)pMsg
; 
2160         if ( msg
->message 
== WM_MOUSEMOVE 
) 
2161             m_tooltip
->RelayEvent(pMsg
); 
2163 #endif // wxUSE_TOOLTIPS 
2168 bool wxWindowMSW::MSWTranslateMessage(WXMSG
* pMsg
) 
2170 #if wxUSE_ACCEL && !defined(__WXUNIVERSAL__) 
2171     return m_acceleratorTable
.Translate(this, pMsg
); 
2175 #endif // wxUSE_ACCEL 
2178 bool wxWindowMSW::MSWShouldPreProcessMessage(WXMSG
* WXUNUSED(pMsg
)) 
2180     // preprocess all messages by default 
2184 // --------------------------------------------------------------------------- 
2185 // message params unpackers 
2186 // --------------------------------------------------------------------------- 
2188 void wxWindowMSW::UnpackCommand(WXWPARAM wParam
, WXLPARAM lParam
, 
2189                              WORD 
*id
, WXHWND 
*hwnd
, WORD 
*cmd
) 
2191     *id 
= LOWORD(wParam
); 
2192     *hwnd 
= (WXHWND
)lParam
; 
2193     *cmd 
= HIWORD(wParam
); 
2196 void wxWindowMSW::UnpackActivate(WXWPARAM wParam
, WXLPARAM lParam
, 
2197                               WXWORD 
*state
, WXWORD 
*minimized
, WXHWND 
*hwnd
) 
2199     *state 
= LOWORD(wParam
); 
2200     *minimized 
= HIWORD(wParam
); 
2201     *hwnd 
= (WXHWND
)lParam
; 
2204 void wxWindowMSW::UnpackScroll(WXWPARAM wParam
, WXLPARAM lParam
, 
2205                             WXWORD 
*code
, WXWORD 
*pos
, WXHWND 
*hwnd
) 
2207     *code 
= LOWORD(wParam
); 
2208     *pos 
= HIWORD(wParam
); 
2209     *hwnd 
= (WXHWND
)lParam
; 
2212 void wxWindowMSW::UnpackCtlColor(WXWPARAM wParam
, WXLPARAM lParam
, 
2213                                  WXHDC 
*hdc
, WXHWND 
*hwnd
) 
2215     *hwnd 
= (WXHWND
)lParam
; 
2216     *hdc 
= (WXHDC
)wParam
; 
2219 void wxWindowMSW::UnpackMenuSelect(WXWPARAM wParam
, WXLPARAM lParam
, 
2220                                 WXWORD 
*item
, WXWORD 
*flags
, WXHMENU 
*hmenu
) 
2222     *item 
= (WXWORD
)wParam
; 
2223     *flags 
= HIWORD(wParam
); 
2224     *hmenu 
= (WXHMENU
)lParam
; 
2227 // --------------------------------------------------------------------------- 
2228 // Main wxWidgets window proc and the window proc for wxWindow 
2229 // --------------------------------------------------------------------------- 
2231 // Hook for new window just as it's being created, when the window isn't yet 
2232 // associated with the handle 
2233 static wxWindowMSW 
*gs_winBeingCreated 
= NULL
; 
2235 // implementation of wxWindowCreationHook class: it just sets gs_winBeingCreated to the 
2236 // window being created and insures that it's always unset back later 
2237 wxWindowCreationHook::wxWindowCreationHook(wxWindowMSW 
*winBeingCreated
) 
2239     gs_winBeingCreated 
= winBeingCreated
; 
2242 wxWindowCreationHook::~wxWindowCreationHook() 
2244     gs_winBeingCreated 
= NULL
; 
2248 LRESULT WXDLLEXPORT APIENTRY _EXPORT 
wxWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
) 
2250     // trace all messages - useful for the debugging 
2252     wxLogTrace(wxTraceMessages
, 
2253                wxT("Processing %s(hWnd=%08lx, wParam=%8lx, lParam=%8lx)"), 
2254                wxGetMessageName(message
), (long)hWnd
, (long)wParam
, lParam
); 
2255 #endif // __WXDEBUG__ 
2257     wxWindowMSW 
*wnd 
= wxFindWinFromHandle((WXHWND
) hWnd
); 
2259     // when we get the first message for the HWND we just created, we associate 
2260     // it with wxWindow stored in gs_winBeingCreated 
2261     if ( !wnd 
&& gs_winBeingCreated 
) 
2263         wxAssociateWinWithHandle(hWnd
, gs_winBeingCreated
); 
2264         wnd 
= gs_winBeingCreated
; 
2265         gs_winBeingCreated 
= NULL
; 
2266         wnd
->SetHWND((WXHWND
)hWnd
); 
2271     if ( wnd 
&& wxEventLoop::AllowProcessing(wnd
) ) 
2272         rc 
= wnd
->MSWWindowProc(message
, wParam
, lParam
); 
2274         rc 
= ::DefWindowProc(hWnd
, message
, wParam
, lParam
); 
2279 WXLRESULT 
wxWindowMSW::MSWWindowProc(WXUINT message
, WXWPARAM wParam
, WXLPARAM lParam
) 
2281     // did we process the message? 
2282     bool processed 
= false; 
2292     // for most messages we should return 0 when we do process the message 
2300                 processed 
= HandleCreate((WXLPCREATESTRUCT
)lParam
, &mayCreate
); 
2303                     // return 0 to allow window creation 
2304                     rc
.result 
= mayCreate 
? 0 : -1; 
2310             // never set processed to true and *always* pass WM_DESTROY to 
2311             // DefWindowProc() as Windows may do some internal cleanup when 
2312             // processing it and failing to pass the message along may cause 
2313             // memory and resource leaks! 
2314             (void)HandleDestroy(); 
2318             processed 
= HandleSize(LOWORD(lParam
), HIWORD(lParam
), wParam
); 
2322             processed 
= HandleMove(GET_X_LPARAM(lParam
), GET_Y_LPARAM(lParam
)); 
2325 #if !defined(__WXWINCE__) 
2328                 LPRECT pRect 
= (LPRECT
)lParam
; 
2330                 rc
.SetLeft(pRect
->left
); 
2331                 rc
.SetTop(pRect
->top
); 
2332                 rc
.SetRight(pRect
->right
); 
2333                 rc
.SetBottom(pRect
->bottom
); 
2334                 processed 
= HandleMoving(rc
); 
2336                     pRect
->left 
= rc
.GetLeft(); 
2337                     pRect
->top 
= rc
.GetTop(); 
2338                     pRect
->right 
= rc
.GetRight(); 
2339                     pRect
->bottom 
= rc
.GetBottom(); 
2346                 LPRECT pRect 
= (LPRECT
)lParam
; 
2348                 rc
.SetLeft(pRect
->left
); 
2349                 rc
.SetTop(pRect
->top
); 
2350                 rc
.SetRight(pRect
->right
); 
2351                 rc
.SetBottom(pRect
->bottom
); 
2352                 processed 
= HandleSizing(rc
); 
2354                     pRect
->left 
= rc
.GetLeft(); 
2355                     pRect
->top 
= rc
.GetTop(); 
2356                     pRect
->right 
= rc
.GetRight(); 
2357                     pRect
->bottom 
= rc
.GetBottom(); 
2361 #endif // !__WXWINCE__ 
2363 #if !(defined(_WIN32_WCE) && _WIN32_WCE < 400) 
2364         case WM_WINDOWPOSCHANGED
: 
2366                 WINDOWPOS 
*lpPos 
= (WINDOWPOS 
*)lParam
; 
2368                 if ( !(lpPos
->flags 
& SWP_NOSIZE
) ) 
2371                     ::GetClientRect(GetHwnd(), &rc
); 
2373                     AutoHRGN 
hrgnClient(::CreateRectRgnIndirect(&rc
)); 
2374                     AutoHRGN 
hrgnNew(::CreateRectRgn(lpPos
->x
,  lpPos
->y
, 
2375                                                      lpPos
->cx
, lpPos
->cy
)); 
2377                     // we need to invalidate any new exposed areas here 
2378                     // to force them to repaint 
2379                     if ( ::CombineRgn(hrgnNew
, hrgnNew
, hrgnClient
, RGN_DIFF
) != NULLREGION 
) 
2380                         ::InvalidateRgn(GetHwnd(), hrgnNew
, TRUE
); 
2385 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__) 
2386         case WM_ACTIVATEAPP
: 
2387             // This implicitly sends a wxEVT_ACTIVATE_APP event 
2388             wxTheApp
->SetActive(wParam 
!= 0, FindFocus()); 
2394                 WXWORD state
, minimized
; 
2396                 UnpackActivate(wParam
, lParam
, &state
, &minimized
, &hwnd
); 
2398                 processed 
= HandleActivate(state
, minimized 
!= 0, (WXHWND
)hwnd
); 
2403             processed 
= HandleSetFocus((WXHWND
)(HWND
)wParam
); 
2407             processed 
= HandleKillFocus((WXHWND
)(HWND
)wParam
); 
2410         case WM_PRINTCLIENT
: 
2411             processed 
= HandlePrintClient((WXHDC
)wParam
); 
2417                 wxPaintDCEx 
dc((wxWindow 
*)this, (WXHDC
)wParam
); 
2419                 processed 
= HandlePaint(); 
2423                 processed 
= HandlePaint(); 
2428 #ifdef __WXUNIVERSAL__ 
2429             // Universal uses its own wxFrame/wxDialog, so we don't receive 
2430             // close events unless we have this. 
2432 #endif // __WXUNIVERSAL__ 
2434             // don't let the DefWindowProc() destroy our window - we'll do it 
2435             // ourselves in ~wxWindow 
2441             processed 
= HandleShow(wParam 
!= 0, (int)lParam
); 
2445             processed 
= HandleMouseMove(GET_X_LPARAM(lParam
), 
2446                                         GET_Y_LPARAM(lParam
), 
2450 #ifdef HAVE_TRACKMOUSEEVENT 
2452             // filter out excess WM_MOUSELEAVE events sent after PopupMenu() (on XP at least) 
2453             if ( m_mouseInWindow 
) 
2455                 GenerateMouseLeave(); 
2458             // always pass processed back as false, this allows the window 
2459             // manager to process the message too.  This is needed to 
2460             // ensure windows XP themes work properly as the mouse moves 
2461             // over widgets like buttons. So don't set processed to true here. 
2463 #endif // HAVE_TRACKMOUSEEVENT 
2465 #if wxUSE_MOUSEWHEEL 
2467             processed 
= HandleMouseWheel(wParam
, lParam
); 
2471         case WM_LBUTTONDOWN
: 
2473         case WM_LBUTTONDBLCLK
: 
2474         case WM_RBUTTONDOWN
: 
2476         case WM_RBUTTONDBLCLK
: 
2477         case WM_MBUTTONDOWN
: 
2479         case WM_MBUTTONDBLCLK
: 
2481 #ifdef __WXMICROWIN__ 
2482                 // MicroWindows seems to ignore the fact that a window is 
2483                 // disabled. So catch mouse events and throw them away if 
2485                 wxWindowMSW
* win 
= this; 
2488                     if (!win
->IsEnabled()) 
2494                     win 
= win
->GetParent(); 
2495                     if ( !win 
|| win
->IsTopLevel() ) 
2502 #endif // __WXMICROWIN__ 
2503                 int x 
= GET_X_LPARAM(lParam
), 
2504                     y 
= GET_Y_LPARAM(lParam
); 
2506                 // redirect the event to a static control if necessary by 
2507                 // finding one under mouse 
2509                 if ( GetCapture() == this ) 
2511                     // but don't do it if the mouse is captured by this window 
2512                     // because then it should really get this event itself 
2517                     win 
= FindWindowForMouseEvent(this, &x
, &y
); 
2519                     // this should never happen 
2520                     wxCHECK_MSG( win
, 0, 
2521                                  _T("FindWindowForMouseEvent() returned NULL") ); 
2524                 processed 
= win
->HandleMouseEvent(message
, x
, y
, wParam
); 
2526                 // if the app didn't eat the event, handle it in the default 
2527                 // way, that is by giving this window the focus 
2530                     // for the standard classes their WndProc sets the focus to 
2531                     // them anyhow and doing it from here results in some weird 
2532                     // problems, so don't do it for them (unnecessary anyhow) 
2533                     if ( !win
->IsOfStandardClass() ) 
2535                         if ( message 
== WM_LBUTTONDOWN 
&& win
->AcceptsFocus() ) 
2547         case MM_JOY1BUTTONDOWN
: 
2548         case MM_JOY2BUTTONDOWN
: 
2549         case MM_JOY1BUTTONUP
: 
2550         case MM_JOY2BUTTONUP
: 
2551             processed 
= HandleJoystickEvent(message
, 
2552                                             GET_X_LPARAM(lParam
), 
2553                                             GET_Y_LPARAM(lParam
), 
2556 #endif // __WXMICROWIN__ 
2562                 UnpackCommand(wParam
, lParam
, &id
, &hwnd
, &cmd
); 
2564                 processed 
= HandleCommand(id
, cmd
, hwnd
); 
2569             processed 
= HandleNotify((int)wParam
, lParam
, &rc
.result
); 
2572         // we only need to reply to WM_NOTIFYFORMAT manually when using MSLU, 
2573         // otherwise DefWindowProc() does it perfectly fine for us, but MSLU 
2574         // apparently doesn't always behave properly and needs some help 
2575 #if wxUSE_UNICODE_MSLU && defined(NF_QUERY) 
2576         case WM_NOTIFYFORMAT
: 
2577             if ( lParam 
== NF_QUERY 
) 
2580                 rc
.result 
= NFR_UNICODE
; 
2583 #endif // wxUSE_UNICODE_MSLU 
2585             // for these messages we must return true if process the message 
2588         case WM_MEASUREITEM
: 
2590                 int idCtrl 
= (UINT
)wParam
; 
2591                 if ( message 
== WM_DRAWITEM 
) 
2593                     processed 
= MSWOnDrawItem(idCtrl
, 
2594                                               (WXDRAWITEMSTRUCT 
*)lParam
); 
2598                     processed 
= MSWOnMeasureItem(idCtrl
, 
2599                                                  (WXMEASUREITEMSTRUCT 
*)lParam
); 
2606 #endif // defined(WM_DRAWITEM) 
2609             if ( !IsOfStandardClass() ) 
2611                 // we always want to get the char events 
2612                 rc
.result 
= DLGC_WANTCHARS
; 
2614                 if ( GetWindowStyleFlag() & wxWANTS_CHARS 
) 
2616                     // in fact, we want everything 
2617                     rc
.result 
|= DLGC_WANTARROWS 
| 
2624             //else: get the dlg code from the DefWindowProc() 
2629             // If this has been processed by an event handler, return 0 now 
2630             // (we've handled it). 
2631             m_lastKeydownProcessed 
= HandleKeyDown((WORD
) wParam
, lParam
); 
2632             if ( m_lastKeydownProcessed 
) 
2641                     // we consider these message "not interesting" to OnChar, so 
2642                     // just don't do anything more with them 
2652                     // avoid duplicate messages to OnChar for these ASCII keys: 
2653                     // they will be translated by TranslateMessage() and received 
2675                         // but set processed to false, not true to still pass them 
2676                         // to the control's default window proc - otherwise 
2677                         // built-in keyboard handling won't work 
2682                     // special case of VK_APPS: treat it the same as right mouse 
2683                     // click because both usually pop up a context menu 
2685                         processed 
= HandleMouseEvent(WM_RBUTTONDOWN
, -1, -1, 0); 
2690                         // do generate a CHAR event 
2691                         processed 
= HandleChar((WORD
)wParam
, lParam
); 
2694             if (message 
== WM_SYSKEYDOWN
)  // Let Windows still handle the SYSKEYs 
2701             // special case of VK_APPS: treat it the same as right mouse button 
2702             if ( wParam 
== VK_APPS 
) 
2704                 processed 
= HandleMouseEvent(WM_RBUTTONUP
, -1, -1, 0); 
2709                 processed 
= HandleKeyUp((WORD
) wParam
, lParam
); 
2714         case WM_CHAR
: // Always an ASCII character 
2715             if ( m_lastKeydownProcessed 
) 
2717                 // The key was handled in the EVT_KEY_DOWN and handling 
2718                 // a key in an EVT_KEY_DOWN handler is meant, by 
2719                 // design, to prevent EVT_CHARs from happening 
2720                 m_lastKeydownProcessed 
= false; 
2725                 processed 
= HandleChar((WORD
)wParam
, lParam
, true); 
2731             processed 
= HandleHotKey((WORD
)wParam
, lParam
); 
2733 #endif // wxUSE_HOTKEY 
2740                 UnpackScroll(wParam
, lParam
, &code
, &pos
, &hwnd
); 
2742                 processed 
= MSWOnScroll(message 
== WM_HSCROLL 
? wxHORIZONTAL
 
2748         // CTLCOLOR messages are sent by children to query the parent for their 
2750 #ifndef __WXMICROWIN__ 
2751         case WM_CTLCOLORMSGBOX
: 
2752         case WM_CTLCOLOREDIT
: 
2753         case WM_CTLCOLORLISTBOX
: 
2754         case WM_CTLCOLORBTN
: 
2755         case WM_CTLCOLORDLG
: 
2756         case WM_CTLCOLORSCROLLBAR
: 
2757         case WM_CTLCOLORSTATIC
: 
2761                 UnpackCtlColor(wParam
, lParam
, &hdc
, &hwnd
); 
2763                 processed 
= HandleCtlColor(&rc
.hBrush
, (WXHDC
)hdc
, (WXHWND
)hwnd
); 
2766 #endif // !__WXMICROWIN__ 
2768         case WM_SYSCOLORCHANGE
: 
2769             // the return value for this message is ignored 
2770             processed 
= HandleSysColorChange(); 
2773 #if !defined(__WXWINCE__) 
2774         case WM_DISPLAYCHANGE
: 
2775             processed 
= HandleDisplayChange(); 
2779         case WM_PALETTECHANGED
: 
2780             processed 
= HandlePaletteChanged((WXHWND
) (HWND
) wParam
); 
2783         case WM_CAPTURECHANGED
: 
2784             processed 
= HandleCaptureChanged((WXHWND
) (HWND
) lParam
); 
2787         case WM_QUERYNEWPALETTE
: 
2788             processed 
= HandleQueryNewPalette(); 
2792             processed 
= HandleEraseBkgnd((WXHDC
)(HDC
)wParam
); 
2795                 // we processed the message, i.e. erased the background 
2800 #if !defined(__WXWINCE__) 
2802             processed 
= HandleDropFiles(wParam
); 
2807             processed 
= HandleInitDialog((WXHWND
)(HWND
)wParam
); 
2811                 // we never set focus from here 
2816 #if !defined(__WXWINCE__) 
2817         case WM_QUERYENDSESSION
: 
2818             processed 
= HandleQueryEndSession(lParam
, &rc
.allow
); 
2822             processed 
= HandleEndSession(wParam 
!= 0, lParam
); 
2825         case WM_GETMINMAXINFO
: 
2826             processed 
= HandleGetMinMaxInfo((MINMAXINFO
*)lParam
); 
2831             processed 
= HandleSetCursor((WXHWND
)(HWND
)wParam
, 
2832                                         LOWORD(lParam
),     // hit test 
2833                                         HIWORD(lParam
));    // mouse msg 
2837                 // returning TRUE stops the DefWindowProc() from further 
2838                 // processing this message - exactly what we need because we've 
2839                 // just set the cursor. 
2844 #if wxUSE_ACCESSIBILITY 
2847                 //WPARAM dwFlags = (WPARAM) (DWORD) wParam; 
2848                 LPARAM dwObjId 
= (LPARAM
) (DWORD
) lParam
; 
2850                 if (dwObjId 
== (LPARAM
)OBJID_CLIENT 
&& GetOrCreateAccessible()) 
2852                     return LresultFromObject(IID_IAccessible
, wParam
, (IUnknown
*) GetAccessible()->GetIAccessible()); 
2858 #if defined(WM_HELP) 
2861                 // HELPINFO doesn't seem to be supported on WinCE. 
2863                 HELPINFO
* info 
= (HELPINFO
*) lParam
; 
2864                 // Don't yet process menu help events, just windows 
2865                 if (info
->iContextType 
== HELPINFO_WINDOW
) 
2868                     wxWindowMSW
* subjectOfHelp 
= this; 
2869                     bool eventProcessed 
= false; 
2870                     while (subjectOfHelp 
&& !eventProcessed
) 
2872                         wxHelpEvent 
helpEvent(wxEVT_HELP
, 
2873                                               subjectOfHelp
->GetId(), 
2877                                               wxPoint(info
->MousePos
.x
, info
->MousePos
.y
) 
2881                         helpEvent
.SetEventObject(this); 
2883                             GetEventHandler()->ProcessEvent(helpEvent
); 
2885                         // Go up the window hierarchy until the event is 
2887                         subjectOfHelp 
= subjectOfHelp
->GetParent(); 
2890                     processed 
= eventProcessed
; 
2893                 else if (info
->iContextType 
== HELPINFO_MENUITEM
) 
2895                     wxHelpEvent 
helpEvent(wxEVT_HELP
, info
->iCtrlId
); 
2896                     helpEvent
.SetEventObject(this); 
2897                     processed 
= GetEventHandler()->ProcessEvent(helpEvent
); 
2900                 //else: processed is already false 
2906 #if !defined(__WXWINCE__) 
2907         case WM_CONTEXTMENU
: 
2909                 // we don't convert from screen to client coordinates as 
2910                 // the event may be handled by a parent window 
2911                 wxPoint 
pt(GET_X_LPARAM(lParam
), GET_Y_LPARAM(lParam
)); 
2913                 wxContextMenuEvent 
evtCtx(wxEVT_CONTEXT_MENU
, GetId(), pt
); 
2915                 // we could have got an event from our child, reflect it back 
2916                 // to it if this is the case 
2917                 wxWindowMSW 
*win 
= NULL
; 
2918                 if ( (WXHWND
)wParam 
!= m_hWnd 
) 
2920                     win 
= FindItemByHWND((WXHWND
)wParam
); 
2926                 evtCtx
.SetEventObject(win
); 
2927                 processed 
= win
->GetEventHandler()->ProcessEvent(evtCtx
); 
2933             // we're only interested in our own menus, not MF_SYSMENU 
2934             if ( HIWORD(wParam
) == MF_POPUP 
) 
2936                 // handle menu chars for ownerdrawn menu items 
2937                 int i 
= HandleMenuChar(toupper(LOWORD(wParam
)), lParam
); 
2938                 if ( i 
!= wxNOT_FOUND 
) 
2940                     rc
.result 
= MAKELRESULT(i
, MNC_EXECUTE
); 
2950         wxLogTrace(wxTraceMessages
, wxT("Forwarding %s to DefWindowProc."), 
2951                    wxGetMessageName(message
)); 
2952 #endif // __WXDEBUG__ 
2953         rc
.result 
= MSWDefWindowProc(message
, wParam
, lParam
); 
2959 // ---------------------------------------------------------------------------- 
2960 // wxWindow <-> HWND map 
2961 // ---------------------------------------------------------------------------- 
2963 wxWinHashTable 
*wxWinHandleHash 
= NULL
; 
2965 wxWindow 
*wxFindWinFromHandle(WXHWND hWnd
) 
2967     return (wxWindow
*)wxWinHandleHash
->Get((long)hWnd
); 
2970 void wxAssociateWinWithHandle(HWND hWnd
, wxWindowMSW 
*win
) 
2972     // adding NULL hWnd is (first) surely a result of an error and 
2973     // (secondly) breaks menu command processing 
2974     wxCHECK_RET( hWnd 
!= (HWND
)NULL
, 
2975                  wxT("attempt to add a NULL hWnd to window list ignored") ); 
2977     wxWindow 
*oldWin 
= wxFindWinFromHandle((WXHWND
) hWnd
); 
2979     if ( oldWin 
&& (oldWin 
!= win
) ) 
2981         wxLogDebug(wxT("HWND %X already associated with another window (%s)"), 
2982                    (int) hWnd
, win
->GetClassInfo()->GetClassName()); 
2985 #endif // __WXDEBUG__ 
2988         wxWinHandleHash
->Put((long)hWnd
, (wxWindow 
*)win
); 
2992 void wxRemoveHandleAssociation(wxWindowMSW 
*win
) 
2994     wxWinHandleHash
->Delete((long)win
->GetHWND()); 
2997 // ---------------------------------------------------------------------------- 
2998 // various MSW speciic class dependent functions 
2999 // ---------------------------------------------------------------------------- 
3001 // Default destroyer - override if you destroy it in some other way 
3002 // (e.g. with MDI child windows) 
3003 void wxWindowMSW::MSWDestroyWindow() 
3007 bool wxWindowMSW::MSWGetCreateWindowCoords(const wxPoint
& pos
, 
3010                                            int& w
, int& h
) const 
3012     // yes, those are just some arbitrary hardcoded numbers 
3013     static const int DEFAULT_Y 
= 200; 
3015     bool nonDefault 
= false; 
3017     if ( pos
.x 
== wxDefaultCoord 
) 
3019         // if x is set to CW_USEDEFAULT, y parameter is ignored anyhow so we 
3020         // can just as well set it to CW_USEDEFAULT as well 
3026         // OTOH, if x is not set to CW_USEDEFAULT, y shouldn't be set to it 
3027         // neither because it is not handled as a special value by Windows then 
3028         // and so we have to choose some default value for it 
3030         y 
= pos
.y 
== wxDefaultCoord 
? DEFAULT_Y 
: pos
.y
; 
3036       NB: there used to be some code here which set the initial size of the 
3037           window to the client size of the parent if no explicit size was 
3038           specified. This was wrong because wxWidgets programs often assume 
3039           that they get a WM_SIZE (EVT_SIZE) upon creation, however this broke 
3040           it. To see why, you should understand that Windows sends WM_SIZE from 
3041           inside ::CreateWindow() anyhow. However, ::CreateWindow() is called 
3042           from some base class ctor and so this WM_SIZE is not processed in the 
3043           real class' OnSize() (because it's not fully constructed yet and the 
3044           event goes to some base class OnSize() instead). So the WM_SIZE we 
3045           rely on is the one sent when the parent frame resizes its children 
3046           but here is the problem: if the child already has just the right 
3047           size, nothing will happen as both wxWidgets and Windows check for 
3048           this and ignore any attempts to change the window size to the size it 
3049           already has - so no WM_SIZE would be sent. 
3053     // we don't use CW_USEDEFAULT here for several reasons: 
3055     //  1. it results in huge frames on modern screens (1000*800 is not 
3056     //     uncommon on my 1280*1024 screen) which is way too big for a half 
3057     //     empty frame of most of wxWidgets samples for example) 
3059     //  2. it is buggy for frames with wxFRAME_TOOL_WINDOW style for which 
3060     //     the default is for whatever reason 8*8 which breaks client <-> 
3061     //     window size calculations (it would be nice if it didn't, but it 
3062     //     does and the simplest way to fix it seemed to change the broken 
3063     //     default size anyhow) 
3065     //  3. there is just no advantage in doing it: with x and y it is 
3066     //     possible that [future versions of] Windows position the new top 
3067     //     level window in some smart way which we can't do, but we can 
3068     //     guess a reasonably good size for a new window just as well 
3071     // However, on PocketPC devices, we must use the default 
3072     // size if possible. 
3074     if (size
.x 
== wxDefaultCoord
) 
3078     if (size
.y 
== wxDefaultCoord
) 
3083     if ( size
.x 
== wxDefaultCoord 
|| size
.y 
== wxDefaultCoord
) 
3087     w 
= WidthDefault(size
.x
); 
3088     h 
= HeightDefault(size
.y
); 
3091     AdjustForParentClientOrigin(x
, y
); 
3096 WXHWND 
wxWindowMSW::MSWGetParent() const 
3098     return m_parent 
? m_parent
->GetHWND() : WXHWND(NULL
); 
3101 bool wxWindowMSW::MSWCreate(const wxChar 
*wclass
, 
3102                             const wxChar 
*title
, 
3106                             WXDWORD extendedStyle
) 
3108     // choose the position/size for the new window 
3110     (void)MSWGetCreateWindowCoords(pos
, size
, x
, y
, w
, h
); 
3112     // controlId is menu handle for the top level windows, so set it to 0 
3113     // unless we're creating a child window 
3114     int controlId 
= style 
& WS_CHILD 
? GetId() : 0; 
3116     // for each class "Foo" we have we also have "FooNR" ("no repaint") class 
3117     // which is the same but without CS_[HV]REDRAW class styles so using it 
3118     // ensures that the window is not fully repainted on each resize 
3119     wxString 
className(wclass
); 
3120     if ( !HasFlag(wxFULL_REPAINT_ON_RESIZE
) ) 
3122         className 
+= wxT("NR"); 
3125     // do create the window 
3126     wxWindowCreationHook 
hook(this); 
3128     m_hWnd 
= (WXHWND
)::CreateWindowEx
 
3132                         title 
? title 
: m_windowName
.c_str(), 
3135                         (HWND
)MSWGetParent(), 
3138                         NULL                        
// no extra data 
3143         wxLogSysError(_("Can't create window of class %s"), className
.c_str()); 
3148     SubclassWin(m_hWnd
); 
3153 // =========================================================================== 
3154 // MSW message handlers 
3155 // =========================================================================== 
3157 // --------------------------------------------------------------------------- 
3159 // --------------------------------------------------------------------------- 
3163 bool wxWindowMSW::HandleNotify(int idCtrl
, WXLPARAM lParam
, WXLPARAM 
*result
) 
3165 #ifndef __WXMICROWIN__ 
3166     LPNMHDR hdr 
= (LPNMHDR
)lParam
; 
3167     HWND hWnd 
= hdr
->hwndFrom
; 
3168     wxWindow 
*win 
= wxFindWinFromHandle((WXHWND
)hWnd
); 
3170     // if the control is one of our windows, let it handle the message itself 
3173         return win
->MSWOnNotify(idCtrl
, lParam
, result
); 
3176     // VZ: why did we do it? normally this is unnecessary and, besides, it 
3177     //     breaks the message processing for the toolbars because the tooltip 
3178     //     notifications were being forwarded to the toolbar child controls 
3179     //     (if it had any) before being passed to the toolbar itself, so in my 
3180     //     example the tooltip for the combobox was always shown instead of the 
3181     //     correct button tooltips 
3183     // try all our children 
3184     wxWindowList::compatibility_iterator node 
= GetChildren().GetFirst(); 
3187         wxWindow 
*child 
= node
->GetData(); 
3188         if ( child
->MSWOnNotify(idCtrl
, lParam
, result
) ) 
3193         node 
= node
->GetNext(); 
3197     // by default, handle it ourselves 
3198     return MSWOnNotify(idCtrl
, lParam
, result
); 
3199 #else // __WXMICROWIN__ 
3206 bool wxWindowMSW::HandleTooltipNotify(WXUINT code
, 
3208                                       const wxString
& ttip
) 
3210     // I don't know why it happens, but the versions of comctl32.dll starting 
3211     // from 4.70 sometimes send TTN_NEEDTEXTW even to ANSI programs (normally, 
3212     // this message is supposed to be sent to Unicode programs only) -- hence 
3213     // we need to handle it as well, otherwise no tooltips will be shown in 
3216     if ( !(code 
== (WXUINT
) TTN_NEEDTEXTA 
|| code 
== (WXUINT
) TTN_NEEDTEXTW
) 
3219         // not a tooltip message or no tooltip to show anyhow 
3224     LPTOOLTIPTEXT ttText 
= (LPTOOLTIPTEXT
)lParam
; 
3226     // We don't want to use the szText buffer because it has a limit of 80 
3227     // bytes and this is not enough, especially for Unicode build where it 
3228     // limits the tooltip string length to only 40 characters 
3230     // The best would be, of course, to not impose any length limitations at 
3231     // all but then the buffer would have to be dynamic and someone would have 
3232     // to free it and we don't have the tooltip owner object here any more, so 
3233     // for now use our own static buffer with a higher fixed max length. 
3235     // Note that using a static buffer should not be a problem as only a single 
3236     // tooltip can be shown at the same time anyhow. 
3238     if ( code 
== (WXUINT
) TTN_NEEDTEXTW 
) 
3240         // We need to convert tooltip from multi byte to Unicode on the fly. 
3241         static wchar_t buf
[513]; 
3243         // Truncate tooltip length if needed as otherwise we might not have 
3244         // enough space for it in the buffer and MultiByteToWideChar() would 
3246         size_t tipLength 
= wxMin(ttip
.Len(), WXSIZEOF(buf
) - 1); 
3248         // Convert to WideChar without adding the NULL character. The NULL 
3249         // character is added afterwards (this is more efficient). 
3250         int len 
= ::MultiByteToWideChar
 
3262             wxLogLastError(_T("MultiByteToWideChar()")); 
3266         ttText
->lpszText 
= (LPSTR
) buf
; 
3268     else // TTN_NEEDTEXTA 
3269 #endif // !wxUSE_UNICODE 
3271         // we get here if we got TTN_NEEDTEXTA (only happens in ANSI build) or 
3272         // if we got TTN_NEEDTEXTW in Unicode build: in this case we just have 
3273         // to copy the string we have into the buffer 
3274         static wxChar buf
[513]; 
3275         wxStrncpy(buf
, ttip
.c_str(), WXSIZEOF(buf
) - 1); 
3276         buf
[WXSIZEOF(buf
) - 1] = _T('\0'); 
3277         ttText
->lpszText 
= buf
; 
3283 #endif // wxUSE_TOOLTIPS 
3285 bool wxWindowMSW::MSWOnNotify(int WXUNUSED(idCtrl
), 
3287                               WXLPARAM
* WXUNUSED(result
)) 
3292         NMHDR
* hdr 
= (NMHDR 
*)lParam
; 
3293         if ( HandleTooltipNotify(hdr
->code
, lParam
, m_tooltip
->GetTip())) 
3300     wxUnusedVar(lParam
); 
3301 #endif // wxUSE_TOOLTIPS 
3308 // --------------------------------------------------------------------------- 
3309 // end session messages 
3310 // --------------------------------------------------------------------------- 
3312 bool wxWindowMSW::HandleQueryEndSession(long logOff
, bool *mayEnd
) 
3314 #ifdef ENDSESSION_LOGOFF 
3315     wxCloseEvent 
event(wxEVT_QUERY_END_SESSION
, wxID_ANY
); 
3316     event
.SetEventObject(wxTheApp
); 
3317     event
.SetCanVeto(true); 
3318     event
.SetLoggingOff(logOff 
== (long)ENDSESSION_LOGOFF
); 
3320     bool rc 
= wxTheApp
->ProcessEvent(event
); 
3324         // we may end only if the app didn't veto session closing (double 
3326         *mayEnd 
= !event
.GetVeto(); 
3331     wxUnusedVar(logOff
); 
3332     wxUnusedVar(mayEnd
); 
3337 bool wxWindowMSW::HandleEndSession(bool endSession
, long logOff
) 
3339 #ifdef ENDSESSION_LOGOFF 
3340     // do nothing if the session isn't ending 
3345     if ( (this != wxTheApp
->GetTopWindow()) ) 
3348     wxCloseEvent 
event(wxEVT_END_SESSION
, wxID_ANY
); 
3349     event
.SetEventObject(wxTheApp
); 
3350     event
.SetCanVeto(false); 
3351     event
.SetLoggingOff( (logOff 
== (long)ENDSESSION_LOGOFF
) ); 
3353     return wxTheApp
->ProcessEvent(event
); 
3355     wxUnusedVar(endSession
); 
3356     wxUnusedVar(logOff
); 
3361 // --------------------------------------------------------------------------- 
3362 // window creation/destruction 
3363 // --------------------------------------------------------------------------- 
3365 bool wxWindowMSW::HandleCreate(WXLPCREATESTRUCT 
WXUNUSED_IN_WINCE(cs
), 
3368     // VZ: why is this commented out for WinCE? If it doesn't support 
3369     //     WS_EX_CONTROLPARENT at all it should be somehow handled globally, 
3370     //     not with multiple #ifdef's! 
3372     if ( ((CREATESTRUCT 
*)cs
)->dwExStyle 
& WS_EX_CONTROLPARENT 
) 
3373         EnsureParentHasControlParentStyle(GetParent()); 
3374 #endif // !__WXWINCE__ 
3376     // TODO: should generate this event from WM_NCCREATE 
3377     wxWindowCreateEvent 
event((wxWindow 
*)this); 
3378     (void)GetEventHandler()->ProcessEvent(event
); 
3385 bool wxWindowMSW::HandleDestroy() 
3389     // delete our drop target if we've got one 
3390 #if wxUSE_DRAG_AND_DROP 
3391     if ( m_dropTarget 
!= NULL 
) 
3393         m_dropTarget
->Revoke(m_hWnd
); 
3395         delete m_dropTarget
; 
3396         m_dropTarget 
= NULL
; 
3398 #endif // wxUSE_DRAG_AND_DROP 
3400     // WM_DESTROY handled 
3404 // --------------------------------------------------------------------------- 
3406 // --------------------------------------------------------------------------- 
3408 bool wxWindowMSW::HandleActivate(int state
, 
3409                               bool WXUNUSED(minimized
), 
3410                               WXHWND 
WXUNUSED(activate
)) 
3412     wxActivateEvent 
event(wxEVT_ACTIVATE
, 
3413                           (state 
== WA_ACTIVE
) || (state 
== WA_CLICKACTIVE
), 
3415     event
.SetEventObject(this); 
3417     return GetEventHandler()->ProcessEvent(event
); 
3420 bool wxWindowMSW::HandleSetFocus(WXHWND hwnd
) 
3422     // Strangly enough, some controls get set focus events when they are being 
3423     // deleted, even if they already had focus before. 
3424     if ( m_isBeingDeleted 
) 
3429     // notify the parent keeping track of focus for the kbd navigation 
3430     // purposes that we got it 
3431     wxChildFocusEvent 
eventFocus((wxWindow 
*)this); 
3432     (void)GetEventHandler()->ProcessEvent(eventFocus
); 
3438         m_caret
->OnSetFocus(); 
3440 #endif // wxUSE_CARET 
3443     // If it's a wxTextCtrl don't send the event as it will be done 
3444     // after the control gets to process it from EN_FOCUS handler 
3445     if ( wxDynamicCastThis(wxTextCtrl
) ) 
3449 #endif // wxUSE_TEXTCTRL 
3451     wxFocusEvent 
event(wxEVT_SET_FOCUS
, m_windowId
); 
3452     event
.SetEventObject(this); 
3454     // wxFindWinFromHandle() may return NULL, it is ok 
3455     event
.SetWindow(wxFindWinFromHandle(hwnd
)); 
3457     return GetEventHandler()->ProcessEvent(event
); 
3460 bool wxWindowMSW::HandleKillFocus(WXHWND hwnd
) 
3466         m_caret
->OnKillFocus(); 
3468 #endif // wxUSE_CARET 
3471     // If it's a wxTextCtrl don't send the event as it will be done 
3472     // after the control gets to process it. 
3473     wxTextCtrl 
*ctrl 
= wxDynamicCastThis(wxTextCtrl
); 
3480     // Don't send the event when in the process of being deleted.  This can 
3481     // only cause problems if the event handler tries to access the object. 
3482     if ( m_isBeingDeleted 
) 
3487     wxFocusEvent 
event(wxEVT_KILL_FOCUS
, m_windowId
); 
3488     event
.SetEventObject(this); 
3490     // wxFindWinFromHandle() may return NULL, it is ok 
3491     event
.SetWindow(wxFindWinFromHandle(hwnd
)); 
3493     return GetEventHandler()->ProcessEvent(event
); 
3496 // --------------------------------------------------------------------------- 
3498 // --------------------------------------------------------------------------- 
3500 bool wxWindowMSW::HandleShow(bool show
, int WXUNUSED(status
)) 
3502     wxShowEvent 
event(GetId(), show
); 
3503     event
.SetEventObject(this); 
3505     return GetEventHandler()->ProcessEvent(event
); 
3508 bool wxWindowMSW::HandleInitDialog(WXHWND 
WXUNUSED(hWndFocus
)) 
3510     wxInitDialogEvent 
event(GetId()); 
3511     event
.SetEventObject(this); 
3513     return GetEventHandler()->ProcessEvent(event
); 
3516 bool wxWindowMSW::HandleDropFiles(WXWPARAM wParam
) 
3518 #if defined (__WXMICROWIN__) || defined(__WXWINCE__) 
3519     wxUnusedVar(wParam
); 
3521 #else // __WXMICROWIN__ 
3522     HDROP hFilesInfo 
= (HDROP
) wParam
; 
3524     // Get the total number of files dropped 
3525     UINT gwFilesDropped 
= ::DragQueryFile
 
3533     wxString 
*files 
= new wxString
[gwFilesDropped
]; 
3534     for ( UINT wIndex 
= 0; wIndex 
< gwFilesDropped
; wIndex
++ ) 
3536         // first get the needed buffer length (+1 for terminating NUL) 
3537         size_t len 
= ::DragQueryFile(hFilesInfo
, wIndex
, NULL
, 0) + 1; 
3539         // and now get the file name 
3540         ::DragQueryFile(hFilesInfo
, wIndex
, 
3541                         wxStringBuffer(files
[wIndex
], len
), len
); 
3543     DragFinish (hFilesInfo
); 
3545     wxDropFilesEvent 
event(wxEVT_DROP_FILES
, gwFilesDropped
, files
); 
3546     event
.SetEventObject(this); 
3549     DragQueryPoint(hFilesInfo
, (LPPOINT
) &dropPoint
); 
3550     event
.m_pos
.x 
= dropPoint
.x
; 
3551     event
.m_pos
.y 
= dropPoint
.y
; 
3553     return GetEventHandler()->ProcessEvent(event
); 
3558 bool wxWindowMSW::HandleSetCursor(WXHWND 
WXUNUSED(hWnd
), 
3560                                   int WXUNUSED(mouseMsg
)) 
3562 #ifndef __WXMICROWIN__ 
3563     // the logic is as follows: 
3564     // -1. don't set cursor for non client area, including but not limited to 
3565     //     the title bar, scrollbars, &c 
3566     //  0. allow the user to override default behaviour by using EVT_SET_CURSOR 
3567     //  1. if we have the cursor set it unless wxIsBusy() 
3568     //  2. if we're a top level window, set some cursor anyhow 
3569     //  3. if wxIsBusy(), set the busy cursor, otherwise the global one 
3571     if ( nHitTest 
!= HTCLIENT 
) 
3576     HCURSOR hcursor 
= 0; 
3578     // first ask the user code - it may wish to set the cursor in some very 
3579     // specific way (for example, depending on the current position) 
3582     if ( !::GetCursorPosWinCE(&pt
)) 
3584     if ( !::GetCursorPos(&pt
) ) 
3587         wxLogLastError(wxT("GetCursorPos")); 
3592     ScreenToClient(&x
, &y
); 
3593     wxSetCursorEvent 
event(x
, y
); 
3595     bool processedEvtSetCursor 
= GetEventHandler()->ProcessEvent(event
); 
3596     if ( processedEvtSetCursor 
&& event
.HasCursor() ) 
3598         hcursor 
= GetHcursorOf(event
.GetCursor()); 
3603         bool isBusy 
= wxIsBusy(); 
3605         // the test for processedEvtSetCursor is here to prevent using m_cursor 
3606         // if the user code caught EVT_SET_CURSOR() and returned nothing from 
3607         // it - this is a way to say that our cursor shouldn't be used for this 
3609         if ( !processedEvtSetCursor 
&& m_cursor
.Ok() ) 
3611             hcursor 
= GetHcursorOf(m_cursor
); 
3618                 hcursor 
= wxGetCurrentBusyCursor(); 
3620             else if ( !hcursor 
) 
3622                 const wxCursor 
*cursor 
= wxGetGlobalCursor(); 
3623                 if ( cursor 
&& cursor
->Ok() ) 
3625                     hcursor 
= GetHcursorOf(*cursor
); 
3633 //        wxLogDebug("HandleSetCursor: Setting cursor %ld", (long) hcursor); 
3635         ::SetCursor(hcursor
); 
3637         // cursor set, stop here 
3640 #endif // __WXMICROWIN__ 
3642     // pass up the window chain 
3646 // --------------------------------------------------------------------------- 
3647 // owner drawn stuff 
3648 // --------------------------------------------------------------------------- 
3650 #if (wxUSE_OWNER_DRAWN && wxUSE_MENUS_NATIVE) || \ 
3651         (wxUSE_CONTROLS && !defined(__WXUNIVERSAL__)) 
3652     #define WXUNUSED_UNLESS_ODRAWN(param) param 
3654     #define WXUNUSED_UNLESS_ODRAWN(param) 
3658 wxWindowMSW::MSWOnDrawItem(int WXUNUSED_UNLESS_ODRAWN(id
), 
3659                            WXDRAWITEMSTRUCT 
* WXUNUSED_UNLESS_ODRAWN(itemStruct
)) 
3661 #if wxUSE_OWNER_DRAWN 
3663 #if wxUSE_MENUS_NATIVE 
3664     // is it a menu item? 
3665     DRAWITEMSTRUCT 
*pDrawStruct 
= (DRAWITEMSTRUCT 
*)itemStruct
; 
3666     if ( id 
== 0 && pDrawStruct
->CtlType 
== ODT_MENU 
) 
3668         wxMenuItem 
*pMenuItem 
= (wxMenuItem 
*)(pDrawStruct
->itemData
); 
3670         // see comment before the same test in MSWOnMeasureItem() below 
3674         wxCHECK_MSG( wxDynamicCast(pMenuItem
, wxMenuItem
), 
3675                          false, _T("MSWOnDrawItem: bad wxMenuItem pointer") ); 
3677         // prepare to call OnDrawItem(): notice using of wxDCTemp to prevent 
3678         // the DC from being released 
3679         wxDCTemp 
dc((WXHDC
)pDrawStruct
->hDC
); 
3680         wxRect 
rect(pDrawStruct
->rcItem
.left
, pDrawStruct
->rcItem
.top
, 
3681                     pDrawStruct
->rcItem
.right 
- pDrawStruct
->rcItem
.left
, 
3682                     pDrawStruct
->rcItem
.bottom 
- pDrawStruct
->rcItem
.top
); 
3684         return pMenuItem
->OnDrawItem
 
3688                 (wxOwnerDrawn::wxODAction
)pDrawStruct
->itemAction
, 
3689                 (wxOwnerDrawn::wxODStatus
)pDrawStruct
->itemState
 
3692 #endif // wxUSE_MENUS_NATIVE 
3694 #endif // USE_OWNER_DRAWN 
3696 #if wxUSE_CONTROLS && !defined(__WXUNIVERSAL__) 
3698 #if wxUSE_OWNER_DRAWN 
3699     wxControl 
*item 
= wxDynamicCast(FindItem(id
), wxControl
); 
3700 #else // !wxUSE_OWNER_DRAWN 
3701     // we may still have owner-drawn buttons internally because we have to make 
3702     // them owner-drawn to support colour change 
3705                          wxDynamicCast(FindItem(id
), wxButton
) 
3710 #endif // USE_OWNER_DRAWN 
3714         return item
->MSWOnDraw(itemStruct
); 
3717 #endif // wxUSE_CONTROLS 
3723 wxWindowMSW::MSWOnMeasureItem(int id
, WXMEASUREITEMSTRUCT 
*itemStruct
) 
3725 #if wxUSE_OWNER_DRAWN && wxUSE_MENUS_NATIVE 
3726     // is it a menu item? 
3727     MEASUREITEMSTRUCT 
*pMeasureStruct 
= (MEASUREITEMSTRUCT 
*)itemStruct
; 
3728     if ( id 
== 0 && pMeasureStruct
->CtlType 
== ODT_MENU 
) 
3730         wxMenuItem 
*pMenuItem 
= (wxMenuItem 
*)(pMeasureStruct
->itemData
); 
3732         // according to Carsten Fuchs the pointer may be NULL under XP if an 
3733         // MDI child frame is initially maximized, see this for more info: 
3734         // http://article.gmane.org/gmane.comp.lib.wxwidgets.general/27745 
3736         // so silently ignore it instead of asserting 
3740         wxCHECK_MSG( wxDynamicCast(pMenuItem
, wxMenuItem
), 
3741                         false, _T("MSWOnMeasureItem: bad wxMenuItem pointer") ); 
3744         bool rc 
= pMenuItem
->OnMeasureItem(&w
, &h
); 
3746         pMeasureStruct
->itemWidth 
= w
; 
3747         pMeasureStruct
->itemHeight 
= h
; 
3752     wxControl 
*item 
= wxDynamicCast(FindItem(id
), wxControl
); 
3755         return item
->MSWOnMeasure(itemStruct
); 
3759     wxUnusedVar(itemStruct
); 
3760 #endif // wxUSE_OWNER_DRAWN && wxUSE_MENUS_NATIVE 
3765 // --------------------------------------------------------------------------- 
3766 // colours and palettes 
3767 // --------------------------------------------------------------------------- 
3769 bool wxWindowMSW::HandleSysColorChange() 
3771     wxSysColourChangedEvent event
; 
3772     event
.SetEventObject(this); 
3774     (void)GetEventHandler()->ProcessEvent(event
); 
3776     // always let the system carry on the default processing to allow the 
3777     // native controls to react to the colours update 
3781 bool wxWindowMSW::HandleDisplayChange() 
3783     wxDisplayChangedEvent event
; 
3784     event
.SetEventObject(this); 
3786     return GetEventHandler()->ProcessEvent(event
); 
3789 #ifndef __WXMICROWIN__ 
3791 bool wxWindowMSW::HandleCtlColor(WXHBRUSH 
*brush
, WXHDC hDC
, WXHWND hWnd
) 
3793 #if !wxUSE_CONTROLS || defined(__WXUNIVERSAL__) 
3797     wxControl 
*item 
= wxDynamicCast(FindItemByHWND(hWnd
, true), wxControl
); 
3800         *brush 
= item
->MSWControlColor(hDC
, hWnd
); 
3802 #endif // wxUSE_CONTROLS 
3805     return *brush 
!= NULL
; 
3808 #endif // __WXMICROWIN__ 
3810 bool wxWindowMSW::HandlePaletteChanged(WXHWND hWndPalChange
) 
3813     // same as below except we don't respond to our own messages 
3814     if ( hWndPalChange 
!= GetHWND() ) 
3816         // check to see if we our our parents have a custom palette 
3817         wxWindowMSW 
*win 
= this; 
3818         while ( win 
&& !win
->HasCustomPalette() ) 
3820             win 
= win
->GetParent(); 
3823         if ( win 
&& win
->HasCustomPalette() ) 
3825             // realize the palette to see whether redrawing is needed 
3826             HDC hdc 
= ::GetDC((HWND
) hWndPalChange
); 
3827             win
->m_palette
.SetHPALETTE((WXHPALETTE
) 
3828                     ::SelectPalette(hdc
, GetHpaletteOf(win
->m_palette
), FALSE
)); 
3830             int result 
= ::RealizePalette(hdc
); 
3832             // restore the palette (before releasing the DC) 
3833             win
->m_palette
.SetHPALETTE((WXHPALETTE
) 
3834                     ::SelectPalette(hdc
, GetHpaletteOf(win
->m_palette
), FALSE
)); 
3835             ::RealizePalette(hdc
); 
3836             ::ReleaseDC((HWND
) hWndPalChange
, hdc
); 
3838             // now check for the need to redraw 
3840                 ::InvalidateRect((HWND
) hWndPalChange
, NULL
, TRUE
); 
3844 #endif // wxUSE_PALETTE 
3846     wxPaletteChangedEvent 
event(GetId()); 
3847     event
.SetEventObject(this); 
3848     event
.SetChangedWindow(wxFindWinFromHandle(hWndPalChange
)); 
3850     return GetEventHandler()->ProcessEvent(event
); 
3853 bool wxWindowMSW::HandleCaptureChanged(WXHWND hWndGainedCapture
) 
3855     wxMouseCaptureChangedEvent 
event(GetId(), wxFindWinFromHandle(hWndGainedCapture
)); 
3856     event
.SetEventObject(this); 
3858     return GetEventHandler()->ProcessEvent(event
); 
3861 bool wxWindowMSW::HandleQueryNewPalette() 
3865     // check to see if we our our parents have a custom palette 
3866     wxWindowMSW 
*win 
= this; 
3867     while (!win
->HasCustomPalette() && win
->GetParent()) win 
= win
->GetParent(); 
3868     if (win
->HasCustomPalette()) { 
3869         /* realize the palette to see whether redrawing is needed */ 
3870         HDC hdc 
= ::GetDC((HWND
) GetHWND()); 
3871         win
->m_palette
.SetHPALETTE( (WXHPALETTE
) 
3872              ::SelectPalette(hdc
, (HPALETTE
) win
->m_palette
.GetHPALETTE(), FALSE
) ); 
3874         int result 
= ::RealizePalette(hdc
); 
3875         /* restore the palette (before releasing the DC) */ 
3876         win
->m_palette
.SetHPALETTE( (WXHPALETTE
) 
3877              ::SelectPalette(hdc
, (HPALETTE
) win
->m_palette
.GetHPALETTE(), TRUE
) ); 
3878         ::RealizePalette(hdc
); 
3879         ::ReleaseDC((HWND
) GetHWND(), hdc
); 
3880         /* now check for the need to redraw */ 
3882             ::InvalidateRect((HWND
) GetHWND(), NULL
, TRUE
); 
3884 #endif // wxUSE_PALETTE 
3886     wxQueryNewPaletteEvent 
event(GetId()); 
3887     event
.SetEventObject(this); 
3889     return GetEventHandler()->ProcessEvent(event
) && event
.GetPaletteRealized(); 
3892 // Responds to colour changes: passes event on to children. 
3893 void wxWindowMSW::OnSysColourChanged(wxSysColourChangedEvent
& WXUNUSED(event
)) 
3895     // the top level window also reset the standard colour map as it might have 
3896     // changed (there is no need to do it for the non top level windows as we 
3897     // only have to do it once) 
3901         gs_hasStdCmap 
= false; 
3903     wxWindowList::compatibility_iterator node 
= GetChildren().GetFirst(); 
3906         // Only propagate to non-top-level windows because Windows already 
3907         // sends this event to all top-level ones 
3908         wxWindow 
*win 
= node
->GetData(); 
3909         if ( !win
->IsTopLevel() ) 
3911             // we need to send the real WM_SYSCOLORCHANGE and not just trigger 
3912             // EVT_SYS_COLOUR_CHANGED call because the latter wouldn't work for 
3913             // the standard controls 
3914             ::SendMessage(GetHwndOf(win
), WM_SYSCOLORCHANGE
, 0, 0); 
3917         node 
= node
->GetNext(); 
3921 extern wxCOLORMAP 
*wxGetStdColourMap() 
3923     static COLORREF s_stdColours
[wxSTD_COL_MAX
]; 
3924     static wxCOLORMAP s_cmap
[wxSTD_COL_MAX
]; 
3926     if ( !gs_hasStdCmap 
) 
3928         static bool s_coloursInit 
= false; 
3930         if ( !s_coloursInit 
) 
3932             // When a bitmap is loaded, the RGB values can change (apparently 
3933             // because Windows adjusts them to care for the old programs always 
3934             // using 0xc0c0c0 while the transparent colour for the new Windows 
3935             // versions is different). But we do this adjustment ourselves so 
3936             // we want to avoid Windows' "help" and for this we need to have a 
3937             // reference bitmap which can tell us what the RGB values change 
3939             wxLogNull logNo
; // suppress error if we couldn't load the bitmap 
3940             wxBitmap 
stdColourBitmap(_T("wxBITMAP_STD_COLOURS")); 
3941             if ( stdColourBitmap
.Ok() ) 
3943                 // the pixels in the bitmap must correspond to wxSTD_COL_XXX! 
3944                 wxASSERT_MSG( stdColourBitmap
.GetWidth() == wxSTD_COL_MAX
, 
3945                               _T("forgot to update wxBITMAP_STD_COLOURS!") ); 
3948                 memDC
.SelectObject(stdColourBitmap
); 
3951                 for ( size_t i 
= 0; i 
< WXSIZEOF(s_stdColours
); i
++ ) 
3953                     memDC
.GetPixel(i
, 0, &colour
); 
3954                     s_stdColours
[i
] = wxColourToRGB(colour
); 
3957             else // wxBITMAP_STD_COLOURS couldn't be loaded 
3959                 s_stdColours
[0] = RGB(000,000,000);     // black 
3960                 s_stdColours
[1] = RGB(128,128,128);     // dark grey 
3961                 s_stdColours
[2] = RGB(192,192,192);     // light grey 
3962                 s_stdColours
[3] = RGB(255,255,255);     // white 
3963                 //s_stdColours[4] = RGB(000,000,255);     // blue 
3964                 //s_stdColours[5] = RGB(255,000,255);     // magenta 
3967             s_coloursInit 
= true; 
3970         gs_hasStdCmap 
= true; 
3972         // create the colour map 
3973 #define INIT_CMAP_ENTRY(col) \ 
3974             s_cmap[wxSTD_COL_##col].from = s_stdColours[wxSTD_COL_##col]; \ 
3975             s_cmap[wxSTD_COL_##col].to = ::GetSysColor(COLOR_##col) 
3977         INIT_CMAP_ENTRY(BTNTEXT
); 
3978         INIT_CMAP_ENTRY(BTNSHADOW
); 
3979         INIT_CMAP_ENTRY(BTNFACE
); 
3980         INIT_CMAP_ENTRY(BTNHIGHLIGHT
); 
3982 #undef INIT_CMAP_ENTRY 
3988 // --------------------------------------------------------------------------- 
3990 // --------------------------------------------------------------------------- 
3992 bool wxWindowMSW::HandlePaint() 
3994     HRGN hRegion 
= ::CreateRectRgn(0, 0, 0, 0); // Dummy call to get a handle 
3996         wxLogLastError(wxT("CreateRectRgn")); 
3997     if ( ::GetUpdateRgn(GetHwnd(), hRegion
, FALSE
) == ERROR 
) 
3998         wxLogLastError(wxT("GetUpdateRgn")); 
4000     m_updateRegion 
= wxRegion((WXHRGN
) hRegion
); 
4002     wxPaintEvent 
event(m_windowId
); 
4003     event
.SetEventObject(this); 
4005     bool processed 
= GetEventHandler()->ProcessEvent(event
); 
4007     // note that we must generate NC event after the normal one as otherwise 
4008     // BeginPaint() will happily overwrite our decorations with the background 
4010     wxNcPaintEvent 
eventNc(m_windowId
); 
4011     eventNc
.SetEventObject(this); 
4012     GetEventHandler()->ProcessEvent(eventNc
); 
4017 // Can be called from an application's OnPaint handler 
4018 void wxWindowMSW::OnPaint(wxPaintEvent
& event
) 
4020 #ifdef __WXUNIVERSAL__ 
4023     HDC hDC 
= (HDC
) wxPaintDC::FindDCInCache((wxWindow
*) event
.GetEventObject()); 
4026         MSWDefWindowProc(WM_PAINT
, (WPARAM
) hDC
, 0); 
4031 bool wxWindowMSW::HandleEraseBkgnd(WXHDC hdc
) 
4036     dc
.SetWindow((wxWindow 
*)this); 
4039     wxEraseEvent 
event(m_windowId
, &dc
); 
4040     event
.SetEventObject(this); 
4041     bool rc 
= GetEventHandler()->ProcessEvent(event
); 
4045     // must be called manually as ~wxDC doesn't do anything for wxDCTemp 
4046     dc
.SelectOldObjects(hdc
); 
4051 void wxWindowMSW::OnEraseBackground(wxEraseEvent
& event
) 
4053     // standard non top level controls (i.e. except the dialogs) always erase 
4054     // their background themselves in HandleCtlColor() or have some control- 
4055     // specific ways to set the colours (common controls) 
4056     if ( IsOfStandardClass() && !IsTopLevel() ) 
4062     if ( GetBackgroundStyle() == wxBG_STYLE_CUSTOM 
) 
4064         // don't skip the event here, custom background means that the app 
4065         // is drawing it itself in its OnPaint(), so don't draw it at all 
4066         // now to avoid flicker 
4071     // do default background painting 
4072     if ( !DoEraseBackground(GetHdcOf(*event
.GetDC())) ) 
4074         // let the system paint the background 
4079 bool wxWindowMSW::DoEraseBackground(WXHDC hDC
) 
4081     HBRUSH hbr 
= (HBRUSH
)MSWGetBgBrush(hDC
); 
4085     wxFillRect(GetHwnd(), (HDC
)hDC
, hbr
); 
4091 wxWindowMSW::MSWGetBgBrushForChild(WXHDC 
WXUNUSED(hDC
), WXHWND hWnd
) 
4095         // our background colour applies to: 
4096         //  1. this window itself, always 
4097         //  2. all children unless the colour is "not inheritable" 
4098         //  3. even if it is not inheritable, our immediate transparent 
4099         //     children should still inherit it -- but not any transparent 
4100         //     children because it would look wrong if a child of non 
4101         //     transparent child would show our bg colour when the child itself 
4103         wxWindow 
*win 
= wxFindWinFromHandle(hWnd
); 
4106                     (win 
&& win
->HasTransparentBackground() && 
4107                         win
->GetParent() == this) ) 
4109             // draw children with the same colour as the parent 
4111                 brush 
= wxTheBrushList
->FindOrCreateBrush(GetBackgroundColour()); 
4113             return (WXHBRUSH
)GetHbrushOf(*brush
); 
4120 WXHBRUSH 
wxWindowMSW::MSWGetBgBrush(WXHDC hDC
, WXHWND hWndToPaint
) 
4123         hWndToPaint 
= GetHWND(); 
4125     for ( wxWindowMSW 
*win 
= this; win
; win 
= win
->GetParent() ) 
4127         WXHBRUSH hBrush 
= win
->MSWGetBgBrushForChild(hDC
, hWndToPaint
); 
4131         // background is not inherited beyond top level windows 
4132         if ( win
->IsTopLevel() ) 
4139 bool wxWindowMSW::HandlePrintClient(WXHDC hDC
) 
4141     // we receive this message when DrawThemeParentBackground() is 
4142     // called from def window proc of several controls under XP and we 
4143     // must draw properly themed background here 
4145     // note that naively I'd expect filling the client rect with the 
4146     // brush returned by MSWGetBgBrush() work -- but for some reason it 
4147     // doesn't and we have to call parents MSWPrintChild() which is 
4148     // supposed to call DrawThemeBackground() with appropriate params 
4150     // also note that in this case lParam == PRF_CLIENT but we're 
4151     // clearly expected to paint the background and nothing else! 
4153     if ( IsTopLevel() || InheritsBackgroundColour() ) 
4156     // sometimes we don't want the parent to handle it at all, instead 
4157     // return whatever value this window wants 
4158     if ( !MSWShouldPropagatePrintChild() ) 
4159         return MSWPrintChild(hDC
, (wxWindow 
*)this); 
4161     for ( wxWindow 
*win 
= GetParent(); win
; win 
= win
->GetParent() ) 
4163         if ( win
->MSWPrintChild(hDC
, (wxWindow 
*)this) ) 
4166         if ( win
->IsTopLevel() || win
->InheritsBackgroundColour() ) 
4173 // --------------------------------------------------------------------------- 
4174 // moving and resizing 
4175 // --------------------------------------------------------------------------- 
4177 bool wxWindowMSW::HandleMinimize() 
4179     wxIconizeEvent 
event(m_windowId
); 
4180     event
.SetEventObject(this); 
4182     return GetEventHandler()->ProcessEvent(event
); 
4185 bool wxWindowMSW::HandleMaximize() 
4187     wxMaximizeEvent 
event(m_windowId
); 
4188     event
.SetEventObject(this); 
4190     return GetEventHandler()->ProcessEvent(event
); 
4193 bool wxWindowMSW::HandleMove(int x
, int y
) 
4196     wxMoveEvent 
event(point
, m_windowId
); 
4197     event
.SetEventObject(this); 
4199     return GetEventHandler()->ProcessEvent(event
); 
4202 bool wxWindowMSW::HandleMoving(wxRect
& rect
) 
4204     wxMoveEvent 
event(rect
, m_windowId
); 
4205     event
.SetEventObject(this); 
4207     bool rc 
= GetEventHandler()->ProcessEvent(event
); 
4209         rect 
= event
.GetRect(); 
4213 bool wxWindowMSW::HandleSize(int WXUNUSED(w
), int WXUNUSED(h
), WXUINT wParam
) 
4215 #if USE_DEFERRED_SIZING 
4216     // when we resize this window, its children are probably going to be 
4217     // repositioned as well, prepare to use DeferWindowPos() for them 
4218     int numChildren 
= 0; 
4219     for ( HWND child 
= ::GetWindow(GetHwndOf(this), GW_CHILD
); 
4221           child 
= ::GetWindow(child
, GW_HWNDNEXT
) ) 
4226     // Protect against valid m_hDWP being overwritten 
4227     bool useDefer 
= false; 
4229     if ( numChildren 
> 1 ) 
4233             m_hDWP 
= (WXHANDLE
)::BeginDeferWindowPos(numChildren
); 
4236                 wxLogLastError(_T("BeginDeferWindowPos")); 
4242 #endif // USE_DEFERRED_SIZING 
4244     // update this window size 
4245     bool processed 
= false; 
4249             wxFAIL_MSG( _T("unexpected WM_SIZE parameter") ); 
4250             // fall through nevertheless 
4254             // we're not interested in these messages at all 
4257         case SIZE_MINIMIZED
: 
4258             processed 
= HandleMinimize(); 
4261         case SIZE_MAXIMIZED
: 
4262             /* processed = */ HandleMaximize(); 
4263             // fall through to send a normal size event as well 
4266             // don't use w and h parameters as they specify the client size 
4267             // while according to the docs EVT_SIZE handler is supposed to 
4268             // receive the total size 
4269             wxSizeEvent 
event(GetSize(), m_windowId
); 
4270             event
.SetEventObject(this); 
4272             processed 
= GetEventHandler()->ProcessEvent(event
); 
4275 #if USE_DEFERRED_SIZING 
4276     // and finally change the positions of all child windows at once 
4277     if ( useDefer 
&& m_hDWP 
) 
4279         // reset m_hDWP to NULL so that child windows don't try to use our 
4280         // m_hDWP after we call EndDeferWindowPos() on it (this shouldn't 
4281         // happen anyhow normally but who knows what weird flow of control we 
4282         // may have depending on what the users EVT_SIZE handler does...) 
4283         HDWP hDWP 
= (HDWP
)m_hDWP
; 
4286         // do put all child controls in place at once 
4287         if ( !::EndDeferWindowPos(hDWP
) ) 
4289             wxLogLastError(_T("EndDeferWindowPos")); 
4292         // Reset our children's pending pos/size values. 
4293         for ( wxWindowList::compatibility_iterator node 
= GetChildren().GetFirst(); 
4295               node 
= node
->GetNext() ) 
4297             wxWindowMSW 
*child 
= node
->GetData(); 
4298             child
->m_pendingPosition 
= wxDefaultPosition
; 
4299             child
->m_pendingSize 
= wxDefaultSize
; 
4302 #endif // USE_DEFERRED_SIZING 
4307 bool wxWindowMSW::HandleSizing(wxRect
& rect
) 
4309     wxSizeEvent 
event(rect
, m_windowId
); 
4310     event
.SetEventObject(this); 
4312     bool rc 
= GetEventHandler()->ProcessEvent(event
); 
4314         rect 
= event
.GetRect(); 
4318 bool wxWindowMSW::HandleGetMinMaxInfo(void *WXUNUSED_IN_WINCE(mmInfo
)) 
4323     MINMAXINFO 
*info 
= (MINMAXINFO 
*)mmInfo
; 
4327     int minWidth 
= GetMinWidth(), 
4328         minHeight 
= GetMinHeight(), 
4329         maxWidth 
= GetMaxWidth(), 
4330         maxHeight 
= GetMaxHeight(); 
4332     if ( minWidth 
!= wxDefaultCoord 
) 
4334         info
->ptMinTrackSize
.x 
= minWidth
; 
4338     if ( minHeight 
!= wxDefaultCoord 
) 
4340         info
->ptMinTrackSize
.y 
= minHeight
; 
4344     if ( maxWidth 
!= wxDefaultCoord 
) 
4346         info
->ptMaxTrackSize
.x 
= maxWidth
; 
4350     if ( maxHeight 
!= wxDefaultCoord 
) 
4352         info
->ptMaxTrackSize
.y 
= maxHeight
; 
4360 // --------------------------------------------------------------------------- 
4362 // --------------------------------------------------------------------------- 
4364 bool wxWindowMSW::HandleCommand(WXWORD id
, WXWORD cmd
, WXHWND control
) 
4366 #if wxUSE_MENUS_NATIVE 
4367     if ( !cmd 
&& wxCurrentPopupMenu 
) 
4369         wxMenu 
*popupMenu 
= wxCurrentPopupMenu
; 
4370         wxCurrentPopupMenu 
= NULL
; 
4372         return popupMenu
->MSWCommand(cmd
, id
); 
4374 #endif // wxUSE_MENUS_NATIVE 
4376     wxWindow 
*win 
= NULL
; 
4378     // first try to find it from HWND - this works even with the broken 
4379     // programs using the same ids for different controls 
4382         win 
= wxFindWinFromHandle(control
); 
4388         // must cast to a signed type before comparing with other ids! 
4389         win 
= FindItem((signed short)id
); 
4394         return win
->MSWCommand(cmd
, id
); 
4397     // the messages sent from the in-place edit control used by the treectrl 
4398     // for label editing have id == 0, but they should _not_ be treated as menu 
4399     // messages (they are EN_XXX ones, in fact) so don't translate anything 
4400     // coming from a control to wxEVT_COMMAND_MENU_SELECTED 
4403         // If no child window, it may be an accelerator, e.g. for a popup menu 
4406         wxCommandEvent 
event(wxEVT_COMMAND_MENU_SELECTED
); 
4407         event
.SetEventObject(this); 
4411         return GetEventHandler()->ProcessEvent(event
); 
4415 #if wxUSE_SPINCTRL && !defined(__WXUNIVERSAL__) 
4416         // the text ctrl which is logically part of wxSpinCtrl sends WM_COMMAND 
4417         // notifications to its parent which we want to reflect back to 
4419         wxSpinCtrl 
*spin 
= wxSpinCtrl::GetSpinForTextCtrl(control
); 
4420         if ( spin 
&& spin
->ProcessTextCommand(cmd
, id
) ) 
4422 #endif // wxUSE_SPINCTRL 
4424 #if wxUSE_CHOICE && defined(__SMARTPHONE__) 
4425         // the listbox ctrl which is logically part of wxChoice sends WM_COMMAND 
4426         // notifications to its parent which we want to reflect back to 
4428         wxChoice 
*choice 
= wxChoice::GetChoiceForListBox(control
); 
4429         if ( choice 
&& choice
->MSWCommand(cmd
, id
) ) 
4437 // --------------------------------------------------------------------------- 
4439 // --------------------------------------------------------------------------- 
4441 void wxWindowMSW::InitMouseEvent(wxMouseEvent
& event
, 
4445     // our client coords are not quite the same as Windows ones 
4446     wxPoint pt 
= GetClientAreaOrigin(); 
4447     event
.m_x 
= x 
- pt
.x
; 
4448     event
.m_y 
= y 
- pt
.y
; 
4450     event
.m_shiftDown 
= (flags 
& MK_SHIFT
) != 0; 
4451     event
.m_controlDown 
= (flags 
& MK_CONTROL
) != 0; 
4452     event
.m_leftDown 
= (flags 
& MK_LBUTTON
) != 0; 
4453     event
.m_middleDown 
= (flags 
& MK_MBUTTON
) != 0; 
4454     event
.m_rightDown 
= (flags 
& MK_RBUTTON
) != 0; 
4455     event
.m_altDown 
= ::GetKeyState(VK_MENU
) < 0; 
4458     event
.SetTimestamp(::GetMessageTime()); 
4461     event
.SetEventObject(this); 
4462     event
.SetId(GetId()); 
4464 #if wxUSE_MOUSEEVENT_HACK 
4467     m_lastMouseEvent 
= event
.GetEventType(); 
4468 #endif // wxUSE_MOUSEEVENT_HACK 
4471 // Windows doesn't send the mouse events to the static controls (which are 
4472 // transparent in the sense that their WM_NCHITTEST handler returns 
4473 // HTTRANSPARENT) at all but we want all controls to receive the mouse events 
4474 // and so we manually check if we don't have a child window under mouse and if 
4475 // we do, send the event to it instead of the window Windows had sent WM_XXX 
4478 // Notice that this is not done for the mouse move events because this could 
4479 // (would?) be too slow, but only for clicks which means that the static texts 
4480 // still don't get move, enter nor leave events. 
4481 static wxWindowMSW 
*FindWindowForMouseEvent(wxWindowMSW 
*win
, int *x
, int *y
) //TW:REQ:Univ 
4483     wxCHECK_MSG( x 
&& y
, win
, _T("NULL pointer in FindWindowForMouseEvent") ); 
4485     // first try to find a non transparent child: this allows us to send events 
4486     // to a static text which is inside a static box, for example 
4487     POINT pt 
= { *x
, *y 
}; 
4488     HWND hwnd 
= GetHwndOf(win
), 
4492     hwndUnderMouse 
= ::ChildWindowFromPoint
 
4498     hwndUnderMouse 
= ::ChildWindowFromPointEx
 
4508     if ( !hwndUnderMouse 
|| hwndUnderMouse 
== hwnd 
) 
4510         // now try any child window at all 
4511         hwndUnderMouse 
= ::ChildWindowFromPoint(hwnd
, pt
); 
4514     // check that we have a child window which is susceptible to receive mouse 
4515     // events: for this it must be shown and enabled 
4516     if ( hwndUnderMouse 
&& 
4517             hwndUnderMouse 
!= hwnd 
&& 
4518                 ::IsWindowVisible(hwndUnderMouse
) && 
4519                     ::IsWindowEnabled(hwndUnderMouse
) ) 
4521         wxWindow 
*winUnderMouse 
= wxFindWinFromHandle((WXHWND
)hwndUnderMouse
); 
4522         if ( winUnderMouse 
) 
4524             // translate the mouse coords to the other window coords 
4525             win
->ClientToScreen(x
, y
); 
4526             winUnderMouse
->ScreenToClient(x
, y
); 
4528             win 
= winUnderMouse
; 
4535 bool wxWindowMSW::HandleMouseEvent(WXUINT msg
, int x
, int y
, WXUINT flags
) 
4537     // the mouse events take consecutive IDs from WM_MOUSEFIRST to 
4538     // WM_MOUSELAST, so it's enough to subtract WM_MOUSEMOVE == WM_MOUSEFIRST 
4539     // from the message id and take the value in the table to get wxWin event 
4541     static const wxEventType eventsMouse
[] = 
4555     wxMouseEvent 
event(eventsMouse
[msg 
- WM_MOUSEMOVE
]); 
4556     InitMouseEvent(event
, x
, y
, flags
); 
4558     return GetEventHandler()->ProcessEvent(event
); 
4561 bool wxWindowMSW::HandleMouseMove(int x
, int y
, WXUINT flags
) 
4563     if ( !m_mouseInWindow 
) 
4565         // it would be wrong to assume that just because we get a mouse move 
4566         // event that the mouse is inside the window: although this is usually 
4567         // true, it is not if we had captured the mouse, so we need to check 
4568         // the mouse coordinates here 
4569         if ( !HasCapture() || IsMouseInWindow() ) 
4571             // Generate an ENTER event 
4572             m_mouseInWindow 
= true; 
4574 #ifdef HAVE_TRACKMOUSEEVENT 
4575             WinStruct
<TRACKMOUSEEVENT
> trackinfo
; 
4577             trackinfo
.dwFlags 
= TME_LEAVE
; 
4578             trackinfo
.hwndTrack 
= GetHwnd(); 
4580             // Use the commctrl.h _TrackMouseEvent(), which will call the real 
4581             // TrackMouseEvent() if available or emulate it 
4582             _TrackMouseEvent(&trackinfo
); 
4583 #endif // HAVE_TRACKMOUSEEVENT 
4585             wxMouseEvent 
event(wxEVT_ENTER_WINDOW
); 
4586             InitMouseEvent(event
, x
, y
, flags
); 
4588             (void)GetEventHandler()->ProcessEvent(event
); 
4592 #if wxUSE_MOUSEEVENT_HACK 
4593     // Window gets a click down message followed by a mouse move message even 
4594     // if position isn't changed!  We want to discard the trailing move event 
4595     // if x and y are the same. 
4596     if ( (m_lastMouseEvent 
== wxEVT_RIGHT_DOWN 
|| 
4597           m_lastMouseEvent 
== wxEVT_LEFT_DOWN 
|| 
4598           m_lastMouseEvent 
== wxEVT_MIDDLE_DOWN
) && 
4599          (m_lastMouseX 
== x 
&& m_lastMouseY 
== y
) ) 
4601         m_lastMouseEvent 
= wxEVT_MOTION
; 
4605 #endif // wxUSE_MOUSEEVENT_HACK 
4607     return HandleMouseEvent(WM_MOUSEMOVE
, x
, y
, flags
); 
4611 bool wxWindowMSW::HandleMouseWheel(WXWPARAM wParam
, WXLPARAM lParam
) 
4613 #if wxUSE_MOUSEWHEEL 
4614     // notice that WM_MOUSEWHEEL position is in screen coords (as it's 
4615     // forwarded up to the parent by DefWindowProc()) and not in the client 
4616     // ones as all the other messages, translate them to the client coords for 
4619         pt 
= ScreenToClient(wxPoint(GET_X_LPARAM(lParam
), GET_Y_LPARAM(lParam
))); 
4620     wxMouseEvent 
event(wxEVT_MOUSEWHEEL
); 
4621     InitMouseEvent(event
, pt
.x
, pt
.y
, LOWORD(wParam
)); 
4622     event
.m_wheelRotation 
= (short)HIWORD(wParam
); 
4623     event
.m_wheelDelta 
= WHEEL_DELTA
; 
4625     static int s_linesPerRotation 
= -1; 
4626     if ( s_linesPerRotation 
== -1 ) 
4628         if ( !::SystemParametersInfo(SPI_GETWHEELSCROLLLINES
, 0, 
4629                                      &s_linesPerRotation
, 0)) 
4631             // this is not supposed to happen 
4632             wxLogLastError(_T("SystemParametersInfo(GETWHEELSCROLLLINES)")); 
4634             // the default is 3, so use it if SystemParametersInfo() failed 
4635             s_linesPerRotation 
= 3; 
4639     event
.m_linesPerAction 
= s_linesPerRotation
; 
4640     return GetEventHandler()->ProcessEvent(event
); 
4642 #else // !wxUSE_MOUSEWHEEL 
4643     wxUnusedVar(wParam
); 
4644     wxUnusedVar(lParam
); 
4647 #endif // wxUSE_MOUSEWHEEL/!wxUSE_MOUSEWHEEL 
4650 void wxWindowMSW::GenerateMouseLeave() 
4652     m_mouseInWindow 
= false; 
4655     if ( wxIsShiftDown() ) 
4657     if ( wxIsCtrlDown() ) 
4658         state 
|= MK_CONTROL
; 
4660     // Only the high-order bit should be tested 
4661     if ( GetKeyState( VK_LBUTTON 
) & (1<<15) ) 
4662         state 
|= MK_LBUTTON
; 
4663     if ( GetKeyState( VK_MBUTTON 
) & (1<<15) ) 
4664         state 
|= MK_MBUTTON
; 
4665     if ( GetKeyState( VK_RBUTTON 
) & (1<<15) ) 
4666         state 
|= MK_RBUTTON
; 
4670     if ( !::GetCursorPosWinCE(&pt
) ) 
4672     if ( !::GetCursorPos(&pt
) ) 
4675         wxLogLastError(_T("GetCursorPos")); 
4678     // we need to have client coordinates here for symmetry with 
4679     // wxEVT_ENTER_WINDOW 
4680     RECT rect 
= wxGetWindowRect(GetHwnd()); 
4684     wxMouseEvent 
event(wxEVT_LEAVE_WINDOW
); 
4685     InitMouseEvent(event
, pt
.x
, pt
.y
, state
); 
4687     (void)GetEventHandler()->ProcessEvent(event
); 
4690 // --------------------------------------------------------------------------- 
4691 // keyboard handling 
4692 // --------------------------------------------------------------------------- 
4694 // create the key event of the given type for the given key - used by 
4695 // HandleChar and HandleKeyDown/Up 
4696 wxKeyEvent 
wxWindowMSW::CreateKeyEvent(wxEventType evType
, 
4699                                        WXWPARAM wParam
) const 
4701     wxKeyEvent 
event(evType
); 
4702     event
.SetId(GetId()); 
4703     event
.m_shiftDown 
= wxIsShiftDown(); 
4704     event
.m_controlDown 
= wxIsCtrlDown(); 
4705     event
.m_altDown 
= (HIWORD(lParam
) & KF_ALTDOWN
) == KF_ALTDOWN
; 
4707     event
.SetEventObject((wxWindow 
*)this); // const_cast 
4708     event
.m_keyCode 
= id
; 
4710     event
.m_uniChar 
= (wxChar
) wParam
; 
4712     event
.m_rawCode 
= (wxUint32
) wParam
; 
4713     event
.m_rawFlags 
= (wxUint32
) lParam
; 
4715     event
.SetTimestamp(::GetMessageTime()); 
4718     // translate the position to client coords 
4721     GetCursorPosWinCE(&pt
); 
4726     GetWindowRect(GetHwnd(),&rect
); 
4736 // isASCII is true only when we're called from WM_CHAR handler and not from 
4738 bool wxWindowMSW::HandleChar(WXWPARAM wParam
, WXLPARAM lParam
, bool isASCII
) 
4743         // If 1 -> 26, translate to either special keycode or just set 
4744         // ctrlDown.  IOW, Ctrl-C should result in keycode == 3 and 
4745         // ControlDown() == true. 
4747         if ( (id 
> 0) && (id 
< 27) ) 
4769     else // we're called from WM_KEYDOWN 
4771         id 
= wxCharCodeMSWToWX(wParam
, lParam
); 
4774             // it's ASCII and will be processed here only when called from 
4775             // WM_CHAR (i.e. when isASCII = true), don't process it now 
4780     wxKeyEvent 
event(CreateKeyEvent(wxEVT_CHAR
, id
, lParam
, wParam
)); 
4782     // the alphanumeric keys produced by pressing AltGr+something on European 
4783     // keyboards have both Ctrl and Alt modifiers which may confuse the user 
4784     // code as, normally, keys with Ctrl and/or Alt don't result in anything 
4785     // alphanumeric, so pretend that there are no modifiers at all (the 
4786     // KEY_DOWN event would still have the correct modifiers if they're really 
4788     if ( event
.m_controlDown 
&& event
.m_altDown 
&& 
4789             (id 
>= 32 && id 
< 256) ) 
4791         event
.m_controlDown 
= 
4792         event
.m_altDown 
= false; 
4795     return GetEventHandler()->ProcessEvent(event
); 
4798 bool wxWindowMSW::HandleKeyDown(WXWPARAM wParam
, WXLPARAM lParam
) 
4800     int id 
= wxCharCodeMSWToWX(wParam
, lParam
); 
4804         // normal ASCII char 
4808     if ( id 
!= -1 ) // VZ: does this ever happen (FIXME)? 
4810         wxKeyEvent 
event(CreateKeyEvent(wxEVT_KEY_DOWN
, id
, lParam
, wParam
)); 
4811         if ( GetEventHandler()->ProcessEvent(event
) ) 
4820 bool wxWindowMSW::HandleKeyUp(WXWPARAM wParam
, WXLPARAM lParam
) 
4822     int id 
= wxCharCodeMSWToWX(wParam
, lParam
); 
4826         // normal ASCII char 
4830     if ( id 
!= -1 ) // VZ: does this ever happen (FIXME)? 
4832         wxKeyEvent 
event(CreateKeyEvent(wxEVT_KEY_UP
, id
, lParam
, wParam
)); 
4833         if ( GetEventHandler()->ProcessEvent(event
) ) 
4840 int wxWindowMSW::HandleMenuChar(int WXUNUSED_IN_WINCE(chAccel
), 
4841                                 WXLPARAM 
WXUNUSED_IN_WINCE(lParam
)) 
4843     // FIXME: implement GetMenuItemCount for WinCE, possibly 
4844     // in terms of GetMenuItemInfo 
4846     const HMENU hmenu 
= (HMENU
)lParam
; 
4850     mii
.cbSize 
= sizeof(MENUITEMINFO
); 
4851     mii
.fMask 
= MIIM_TYPE 
| MIIM_DATA
; 
4853     // find if we have this letter in any owner drawn item 
4854     const int count 
= ::GetMenuItemCount(hmenu
); 
4855     for ( int i 
= 0; i 
< count
; i
++ ) 
4857         if ( ::GetMenuItemInfo(hmenu
, i
, TRUE
, &mii
) ) 
4859             if ( mii
.fType 
== MFT_OWNERDRAW 
) 
4861                 //  dwItemData member of the MENUITEMINFO is a 
4862                 //  pointer to the associated wxMenuItem -- see the 
4863                 //  menu creation code 
4864                 wxMenuItem 
*item 
= (wxMenuItem
*)mii
.dwItemData
; 
4866                 const wxChar 
*p 
= wxStrchr(item
->GetText(), _T('&')); 
4869                     if ( *p 
== _T('&') ) 
4871                         // this is not the accel char, find the real one 
4872                         p 
= wxStrchr(p 
+ 1, _T('&')); 
4874                     else // got the accel char 
4876                         // FIXME-UNICODE: this comparison doesn't risk to work 
4877                         // for non ASCII accelerator characters I'm afraid, but 
4879                         if ( (wchar_t)wxToupper(*p
) == (wchar_t)chAccel 
) 
4885                             // this one doesn't match 
4892         else // failed to get the menu text? 
4894             // it's not fatal, so don't show error, but still log 
4896             wxLogLastError(_T("GetMenuItemInfo")); 
4903 // --------------------------------------------------------------------------- 
4905 // --------------------------------------------------------------------------- 
4907 bool wxWindowMSW::HandleJoystickEvent(WXUINT msg
, int x
, int y
, WXUINT flags
) 
4911     if ( flags 
& JOY_BUTTON1CHG 
) 
4912         change 
= wxJOY_BUTTON1
; 
4913     if ( flags 
& JOY_BUTTON2CHG 
) 
4914         change 
= wxJOY_BUTTON2
; 
4915     if ( flags 
& JOY_BUTTON3CHG 
) 
4916         change 
= wxJOY_BUTTON3
; 
4917     if ( flags 
& JOY_BUTTON4CHG 
) 
4918         change 
= wxJOY_BUTTON4
; 
4921     if ( flags 
& JOY_BUTTON1 
) 
4922         buttons 
|= wxJOY_BUTTON1
; 
4923     if ( flags 
& JOY_BUTTON2 
) 
4924         buttons 
|= wxJOY_BUTTON2
; 
4925     if ( flags 
& JOY_BUTTON3 
) 
4926         buttons 
|= wxJOY_BUTTON3
; 
4927     if ( flags 
& JOY_BUTTON4 
) 
4928         buttons 
|= wxJOY_BUTTON4
; 
4930     // the event ids aren't consecutive so we can't use table based lookup 
4932     wxEventType eventType
; 
4937             eventType 
= wxEVT_JOY_MOVE
; 
4942             eventType 
= wxEVT_JOY_MOVE
; 
4947             eventType 
= wxEVT_JOY_ZMOVE
; 
4952             eventType 
= wxEVT_JOY_ZMOVE
; 
4955         case MM_JOY1BUTTONDOWN
: 
4957             eventType 
= wxEVT_JOY_BUTTON_DOWN
; 
4960         case MM_JOY2BUTTONDOWN
: 
4962             eventType 
= wxEVT_JOY_BUTTON_DOWN
; 
4965         case MM_JOY1BUTTONUP
: 
4967             eventType 
= wxEVT_JOY_BUTTON_UP
; 
4970         case MM_JOY2BUTTONUP
: 
4972             eventType 
= wxEVT_JOY_BUTTON_UP
; 
4976             wxFAIL_MSG(wxT("no such joystick event")); 
4981     wxJoystickEvent 
event(eventType
, buttons
, joystick
, change
); 
4982     event
.SetPosition(wxPoint(x
, y
)); 
4983     event
.SetEventObject(this); 
4985     return GetEventHandler()->ProcessEvent(event
); 
4995 // --------------------------------------------------------------------------- 
4997 // --------------------------------------------------------------------------- 
4999 bool wxWindowMSW::MSWOnScroll(int orientation
, WXWORD wParam
, 
5000                               WXWORD pos
, WXHWND control
) 
5002     if ( control 
&& control 
!= m_hWnd 
) // Prevent infinite recursion 
5004         wxWindow 
*child 
= wxFindWinFromHandle(control
); 
5006             return child
->MSWOnScroll(orientation
, wParam
, pos
, control
); 
5009     wxScrollWinEvent event
; 
5010     event
.SetPosition(pos
); 
5011     event
.SetOrientation(orientation
); 
5012     event
.SetEventObject(this); 
5017         event
.SetEventType(wxEVT_SCROLLWIN_TOP
); 
5021         event
.SetEventType(wxEVT_SCROLLWIN_BOTTOM
); 
5025         event
.SetEventType(wxEVT_SCROLLWIN_LINEUP
); 
5029         event
.SetEventType(wxEVT_SCROLLWIN_LINEDOWN
); 
5033         event
.SetEventType(wxEVT_SCROLLWIN_PAGEUP
); 
5037         event
.SetEventType(wxEVT_SCROLLWIN_PAGEDOWN
); 
5040     case SB_THUMBPOSITION
: 
5042         // under Win32, the scrollbar range and position are 32 bit integers, 
5043         // but WM_[HV]SCROLL only carry the low 16 bits of them, so we must 
5044         // explicitly query the scrollbar for the correct position (this must 
5045         // be done only for these two SB_ events as they are the only one 
5046         // carrying the scrollbar position) 
5048             WinStruct
<SCROLLINFO
> scrollInfo
; 
5049             scrollInfo
.fMask 
= SIF_TRACKPOS
; 
5051             if ( !::GetScrollInfo(GetHwnd(), 
5052                                   orientation 
== wxHORIZONTAL 
? SB_HORZ
 
5056                 // Not necessarily an error, if there are no scrollbars yet. 
5057                 // wxLogLastError(_T("GetScrollInfo")); 
5060             event
.SetPosition(scrollInfo
.nTrackPos
); 
5063         event
.SetEventType( wParam 
== SB_THUMBPOSITION
 
5064                                 ? wxEVT_SCROLLWIN_THUMBRELEASE
 
5065                                 : wxEVT_SCROLLWIN_THUMBTRACK 
); 
5072     return GetEventHandler()->ProcessEvent(event
); 
5075 // =========================================================================== 
5077 // =========================================================================== 
5079 void wxGetCharSize(WXHWND wnd
, int *x
, int *y
, const wxFont
& the_font
) 
5082     HDC dc 
= ::GetDC((HWND
) wnd
); 
5085     //    the_font.UseResource(); 
5086     //    the_font.RealizeResource(); 
5087     HFONT fnt 
= (HFONT
)the_font
.GetResourceHandle(); // const_cast 
5089         was 
= (HFONT
) SelectObject(dc
,fnt
); 
5091     GetTextMetrics(dc
, &tm
); 
5094         SelectObject(dc
,was
); 
5096     ReleaseDC((HWND
)wnd
, dc
); 
5099         *x 
= tm
.tmAveCharWidth
; 
5101         *y 
= tm
.tmHeight 
+ tm
.tmExternalLeading
; 
5103     //   the_font.ReleaseResource(); 
5106 // Returns 0 if was a normal ASCII value, not a special key. This indicates that 
5107 // the key should be ignored by WM_KEYDOWN and processed by WM_CHAR instead. 
5108 int wxCharCodeMSWToWX(int keySym
, WXLPARAM lParam
) 
5113         case VK_CANCEL
:     id 
= WXK_CANCEL
; break; 
5114         case VK_BACK
:       id 
= WXK_BACK
; break; 
5115         case VK_TAB
:        id 
= WXK_TAB
; break; 
5116         case VK_CLEAR
:      id 
= WXK_CLEAR
; break; 
5117         case VK_SHIFT
:      id 
= WXK_SHIFT
; break; 
5118         case VK_CONTROL
:    id 
= WXK_CONTROL
; break; 
5119         case VK_MENU 
:      id 
= WXK_ALT
; break; 
5120         case VK_PAUSE
:      id 
= WXK_PAUSE
; break; 
5121         case VK_CAPITAL
:    id 
= WXK_CAPITAL
; break; 
5122         case VK_SPACE
:      id 
= WXK_SPACE
; break; 
5123         case VK_ESCAPE
:     id 
= WXK_ESCAPE
; break; 
5124         case VK_PRIOR
:      id 
= WXK_PRIOR
; break; 
5125         case VK_NEXT 
:      id 
= WXK_NEXT
; break; 
5126         case VK_END
:        id 
= WXK_END
; break; 
5127         case VK_HOME 
:      id 
= WXK_HOME
; break; 
5128         case VK_LEFT 
:      id 
= WXK_LEFT
; break; 
5129         case VK_UP
:         id 
= WXK_UP
; break; 
5130         case VK_RIGHT
:      id 
= WXK_RIGHT
; break; 
5131         case VK_DOWN 
:      id 
= WXK_DOWN
; break; 
5132         case VK_SELECT
:     id 
= WXK_SELECT
; break; 
5133         case VK_PRINT
:      id 
= WXK_PRINT
; break; 
5134         case VK_EXECUTE
:    id 
= WXK_EXECUTE
; break; 
5135         case VK_INSERT
:     id 
= WXK_INSERT
; break; 
5136         case VK_DELETE
:     id 
= WXK_DELETE
; break; 
5137         case VK_HELP 
:      id 
= WXK_HELP
; break; 
5138         case VK_NUMPAD0
:    id 
= WXK_NUMPAD0
; break; 
5139         case VK_NUMPAD1
:    id 
= WXK_NUMPAD1
; break; 
5140         case VK_NUMPAD2
:    id 
= WXK_NUMPAD2
; break; 
5141         case VK_NUMPAD3
:    id 
= WXK_NUMPAD3
; break; 
5142         case VK_NUMPAD4
:    id 
= WXK_NUMPAD4
; break; 
5143         case VK_NUMPAD5
:    id 
= WXK_NUMPAD5
; break; 
5144         case VK_NUMPAD6
:    id 
= WXK_NUMPAD6
; break; 
5145         case VK_NUMPAD7
:    id 
= WXK_NUMPAD7
; break; 
5146         case VK_NUMPAD8
:    id 
= WXK_NUMPAD8
; break; 
5147         case VK_NUMPAD9
:    id 
= WXK_NUMPAD9
; break; 
5148         case VK_MULTIPLY
:   id 
= WXK_NUMPAD_MULTIPLY
; break; 
5149         case VK_ADD
:        id 
= WXK_NUMPAD_ADD
; break; 
5150         case VK_SUBTRACT
:   id 
= WXK_NUMPAD_SUBTRACT
; break; 
5151         case VK_DECIMAL
:    id 
= WXK_NUMPAD_DECIMAL
; break; 
5152         case VK_DIVIDE
:     id 
= WXK_NUMPAD_DIVIDE
; break; 
5153         case VK_F1
:         id 
= WXK_F1
; break; 
5154         case VK_F2
:         id 
= WXK_F2
; break; 
5155         case VK_F3
:         id 
= WXK_F3
; break; 
5156         case VK_F4
:         id 
= WXK_F4
; break; 
5157         case VK_F5
:         id 
= WXK_F5
; break; 
5158         case VK_F6
:         id 
= WXK_F6
; break; 
5159         case VK_F7
:         id 
= WXK_F7
; break; 
5160         case VK_F8
:         id 
= WXK_F8
; break; 
5161         case VK_F9
:         id 
= WXK_F9
; break; 
5162         case VK_F10
:        id 
= WXK_F10
; break; 
5163         case VK_F11
:        id 
= WXK_F11
; break; 
5164         case VK_F12
:        id 
= WXK_F12
; break; 
5165         case VK_F13
:        id 
= WXK_F13
; break; 
5166         case VK_F14
:        id 
= WXK_F14
; break; 
5167         case VK_F15
:        id 
= WXK_F15
; break; 
5168         case VK_F16
:        id 
= WXK_F16
; break; 
5169         case VK_F17
:        id 
= WXK_F17
; break; 
5170         case VK_F18
:        id 
= WXK_F18
; break; 
5171         case VK_F19
:        id 
= WXK_F19
; break; 
5172         case VK_F20
:        id 
= WXK_F20
; break; 
5173         case VK_F21
:        id 
= WXK_F21
; break; 
5174         case VK_F22
:        id 
= WXK_F22
; break; 
5175         case VK_F23
:        id 
= WXK_F23
; break; 
5176         case VK_F24
:        id 
= WXK_F24
; break; 
5177         case VK_NUMLOCK
:    id 
= WXK_NUMLOCK
; break; 
5178         case VK_SCROLL
:     id 
= WXK_SCROLL
; break; 
5180         // the mapping for these keys may be incorrect on non-US keyboards so 
5181         // maybe we shouldn't map them to ASCII values at all 
5182         case VK_OEM_1
:      id 
= ';'; break; 
5183         case VK_OEM_PLUS
:   id 
= '+'; break; 
5184         case VK_OEM_COMMA
:  id 
= ','; break; 
5185         case VK_OEM_MINUS
:  id 
= '-'; break; 
5186         case VK_OEM_PERIOD
: id 
= '.'; break; 
5187         case VK_OEM_2
:      id 
= '/'; break; 
5188         case VK_OEM_3
:      id 
= '~'; break; 
5189         case VK_OEM_4
:      id 
= '['; break; 
5190         case VK_OEM_5
:      id 
= '\\'; break; 
5191         case VK_OEM_6
:      id 
= ']'; break; 
5192         case VK_OEM_7
:      id 
= '\''; break; 
5195         case VK_LWIN
:       id 
= WXK_WINDOWS_LEFT
; break; 
5196         case VK_RWIN
:       id 
= WXK_WINDOWS_RIGHT
; break; 
5197         case VK_APPS
:       id 
= WXK_WINDOWS_MENU
; break; 
5198 #endif // VK_APPS defined 
5201             // the same key is sent for both the "return" key on the main 
5202             // keyboard and the numeric keypad but we want to distinguish 
5203             // between them: we do this using the "extended" bit (24) of lParam 
5204             id 
= lParam 
& (1 << 24) ? WXK_NUMPAD_ENTER 
: WXK_RETURN
; 
5214 WXWORD 
wxCharCodeWXToMSW(int id
, bool *isVirtual
) 
5220     case WXK_CANCEL
:    keySym 
= VK_CANCEL
; break; 
5221     case WXK_CLEAR
:     keySym 
= VK_CLEAR
; break; 
5222     case WXK_SHIFT
:     keySym 
= VK_SHIFT
; break; 
5223     case WXK_CONTROL
:   keySym 
= VK_CONTROL
; break; 
5224     case WXK_ALT
:       keySym 
= VK_MENU
; break; 
5225     case WXK_PAUSE
:     keySym 
= VK_PAUSE
; break; 
5226     case WXK_CAPITAL
:   keySym 
= VK_CAPITAL
; break; 
5227     case WXK_PRIOR
:     keySym 
= VK_PRIOR
; break; 
5228     case WXK_NEXT 
:     keySym 
= VK_NEXT
; break; 
5229     case WXK_END
:       keySym 
= VK_END
; break; 
5230     case WXK_HOME 
:     keySym 
= VK_HOME
; break; 
5231     case WXK_LEFT 
:     keySym 
= VK_LEFT
; break; 
5232     case WXK_UP
:        keySym 
= VK_UP
; break; 
5233     case WXK_RIGHT
:     keySym 
= VK_RIGHT
; break; 
5234     case WXK_DOWN 
:     keySym 
= VK_DOWN
; break; 
5235     case WXK_SELECT
:    keySym 
= VK_SELECT
; break; 
5236     case WXK_PRINT
:     keySym 
= VK_PRINT
; break; 
5237     case WXK_EXECUTE
:   keySym 
= VK_EXECUTE
; break; 
5238     case WXK_INSERT
:    keySym 
= VK_INSERT
; break; 
5239     case WXK_DELETE
:    keySym 
= VK_DELETE
; break; 
5240     case WXK_HELP 
:     keySym 
= VK_HELP
; break; 
5241     case WXK_NUMPAD0
:   keySym 
= VK_NUMPAD0
; break; 
5242     case WXK_NUMPAD1
:   keySym 
= VK_NUMPAD1
; break; 
5243     case WXK_NUMPAD2
:   keySym 
= VK_NUMPAD2
; break; 
5244     case WXK_NUMPAD3
:   keySym 
= VK_NUMPAD3
; break; 
5245     case WXK_NUMPAD4
:   keySym 
= VK_NUMPAD4
; break; 
5246     case WXK_NUMPAD5
:   keySym 
= VK_NUMPAD5
; break; 
5247     case WXK_NUMPAD6
:   keySym 
= VK_NUMPAD6
; break; 
5248     case WXK_NUMPAD7
:   keySym 
= VK_NUMPAD7
; break; 
5249     case WXK_NUMPAD8
:   keySym 
= VK_NUMPAD8
; break; 
5250     case WXK_NUMPAD9
:   keySym 
= VK_NUMPAD9
; break; 
5251     case WXK_NUMPAD_MULTIPLY
:  keySym 
= VK_MULTIPLY
; break; 
5252     case WXK_NUMPAD_ADD
:       keySym 
= VK_ADD
; break; 
5253     case WXK_NUMPAD_SUBTRACT
:  keySym 
= VK_SUBTRACT
; break; 
5254     case WXK_NUMPAD_DECIMAL
:   keySym 
= VK_DECIMAL
; break; 
5255     case WXK_NUMPAD_DIVIDE
:    keySym 
= VK_DIVIDE
; break; 
5256     case WXK_F1
:        keySym 
= VK_F1
; break; 
5257     case WXK_F2
:        keySym 
= VK_F2
; break; 
5258     case WXK_F3
:        keySym 
= VK_F3
; break; 
5259     case WXK_F4
:        keySym 
= VK_F4
; break; 
5260     case WXK_F5
:        keySym 
= VK_F5
; break; 
5261     case WXK_F6
:        keySym 
= VK_F6
; break; 
5262     case WXK_F7
:        keySym 
= VK_F7
; break; 
5263     case WXK_F8
:        keySym 
= VK_F8
; break; 
5264     case WXK_F9
:        keySym 
= VK_F9
; break; 
5265     case WXK_F10
:       keySym 
= VK_F10
; break; 
5266     case WXK_F11
:       keySym 
= VK_F11
; break; 
5267     case WXK_F12
:       keySym 
= VK_F12
; break; 
5268     case WXK_F13
:       keySym 
= VK_F13
; break; 
5269     case WXK_F14
:       keySym 
= VK_F14
; break; 
5270     case WXK_F15
:       keySym 
= VK_F15
; break; 
5271     case WXK_F16
:       keySym 
= VK_F16
; break; 
5272     case WXK_F17
:       keySym 
= VK_F17
; break; 
5273     case WXK_F18
:       keySym 
= VK_F18
; break; 
5274     case WXK_F19
:       keySym 
= VK_F19
; break; 
5275     case WXK_F20
:       keySym 
= VK_F20
; break; 
5276     case WXK_F21
:       keySym 
= VK_F21
; break; 
5277     case WXK_F22
:       keySym 
= VK_F22
; break; 
5278     case WXK_F23
:       keySym 
= VK_F23
; break; 
5279     case WXK_F24
:       keySym 
= VK_F24
; break; 
5280     case WXK_NUMLOCK
:   keySym 
= VK_NUMLOCK
; break; 
5281     case WXK_SCROLL
:    keySym 
= VK_SCROLL
; break; 
5292 bool wxGetKeyState(wxKeyCode key
) 
5296     wxASSERT_MSG(key 
!= WXK_LBUTTON 
&& key 
!= WXK_RBUTTON 
&& key 
!= 
5297         WXK_MBUTTON
, wxT("can't use wxGetKeyState() for mouse buttons")); 
5299 //High order with GetAsyncKeyState only available on WIN32 
5301     //If the requested key is a LED key, return 
5302     //true if the led is pressed 
5303     if (key 
== WXK_NUMLOCK 
|| 
5304         key 
== WXK_CAPITAL 
|| 
5308         //low order bit means LED is highlighted, 
5309         //high order means key is down 
5310         //Here, for compat with other ports we want both 
5311         return GetKeyState( wxCharCodeWXToMSW(key
, &bVirtual
) ) != 0; 
5318         //low order bit means key pressed since last call 
5319         //high order means key is down 
5320         //We want only the high order bit - the key may not be down if only low order 
5321         return ( GetAsyncKeyState( wxCharCodeWXToMSW(key
, &bVirtual
) ) & (1<<15) ) != 0; 
5326 wxWindow 
*wxGetActiveWindow() 
5328     HWND hWnd 
= GetActiveWindow(); 
5331         return wxFindWinFromHandle((WXHWND
) hWnd
); 
5336 extern wxWindow 
*wxGetWindowFromHWND(WXHWND hWnd
) 
5338     HWND hwnd 
= (HWND
)hWnd
; 
5340     // For a radiobutton, we get the radiobox from GWL_USERDATA (which is set 
5341     // by code in msw/radiobox.cpp), for all the others we just search up the 
5343     wxWindow 
*win 
= (wxWindow 
*)NULL
; 
5346         win 
= wxFindWinFromHandle((WXHWND
)hwnd
); 
5350             // native radiobuttons return DLGC_RADIOBUTTON here and for any 
5351             // wxWindow class which overrides WM_GETDLGCODE processing to 
5352             // do it as well, win would be already non NULL 
5353             if ( ::SendMessage(hwnd
, WM_GETDLGCODE
, 0, 0) & DLGC_RADIOBUTTON 
) 
5355                 win 
= (wxWindow 
*)wxGetWindowUserData(hwnd
); 
5357             //else: it's a wxRadioButton, not a radiobutton from wxRadioBox 
5358 #endif // wxUSE_RADIOBOX 
5360             // spin control text buddy window should be mapped to spin ctrl 
5361             // itself so try it too 
5362 #if wxUSE_SPINCTRL && !defined(__WXUNIVERSAL__) 
5365                 win 
= wxSpinCtrl::GetSpinForTextCtrl((WXHWND
)hwnd
); 
5367 #endif // wxUSE_SPINCTRL 
5371     while ( hwnd 
&& !win 
) 
5373         // this is a really ugly hack needed to avoid mistakenly returning the 
5374         // parent frame wxWindow for the find/replace modeless dialog HWND - 
5375         // this, in turn, is needed to call IsDialogMessage() from 
5376         // wxApp::ProcessMessage() as for this we must return NULL from here 
5378         // FIXME: this is clearly not the best way to do it but I think we'll 
5379         //        need to change HWND <-> wxWindow code more heavily than I can 
5380         //        do it now to fix it 
5381 #ifndef __WXMICROWIN__ 
5382         if ( ::GetWindow(hwnd
, GW_OWNER
) ) 
5384             // it's a dialog box, don't go upwards 
5389         hwnd 
= ::GetParent(hwnd
); 
5390         win 
= wxFindWinFromHandle((WXHWND
)hwnd
); 
5396 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__) 
5398 // Windows keyboard hook. Allows interception of e.g. F1, ESCAPE 
5399 // in active frames and dialogs, regardless of where the focus is. 
5400 static HHOOK wxTheKeyboardHook 
= 0; 
5401 static FARPROC wxTheKeyboardHookProc 
= 0; 
5402 int APIENTRY _EXPORT
 
5403 wxKeyboardHook(int nCode
, WORD wParam
, DWORD lParam
); 
5405 void wxSetKeyboardHook(bool doIt
) 
5409         wxTheKeyboardHookProc 
= MakeProcInstance((FARPROC
) wxKeyboardHook
, wxGetInstance()); 
5410         wxTheKeyboardHook 
= SetWindowsHookEx(WH_KEYBOARD
, (HOOKPROC
) wxTheKeyboardHookProc
, wxGetInstance(), 
5412             GetCurrentThreadId() 
5413         //      (DWORD)GetCurrentProcess()); // This is another possibility. Which is right? 
5418         UnhookWindowsHookEx(wxTheKeyboardHook
); 
5422 int APIENTRY _EXPORT
 
5423 wxKeyboardHook(int nCode
, WORD wParam
, DWORD lParam
) 
5425     DWORD hiWord 
= HIWORD(lParam
); 
5426     if ( nCode 
!= HC_NOREMOVE 
&& ((hiWord 
& KF_UP
) == 0) ) 
5428         int id 
= wxCharCodeMSWToWX(wParam
, lParam
); 
5431             wxKeyEvent 
event(wxEVT_CHAR_HOOK
); 
5432             if ( (HIWORD(lParam
) & KF_ALTDOWN
) == KF_ALTDOWN 
) 
5433                 event
.m_altDown 
= true; 
5435             event
.SetEventObject(NULL
); 
5436             event
.m_keyCode 
= id
; 
5437             event
.m_shiftDown 
= wxIsShiftDown(); 
5438             event
.m_controlDown 
= wxIsCtrlDown(); 
5440             event
.SetTimestamp(::GetMessageTime()); 
5442             wxWindow 
*win 
= wxGetActiveWindow(); 
5443             wxEvtHandler 
*handler
; 
5446                 handler 
= win
->GetEventHandler(); 
5447                 event
.SetId(win
->GetId()); 
5452                 event
.SetId(wxID_ANY
); 
5455             if ( handler 
&& handler
->ProcessEvent(event
) ) 
5463     return (int)CallNextHookEx(wxTheKeyboardHook
, nCode
, wParam
, lParam
); 
5466 #endif // !__WXMICROWIN__ 
5469 const wxChar 
*wxGetMessageName(int message
) 
5473         case 0x0000: return wxT("WM_NULL"); 
5474         case 0x0001: return wxT("WM_CREATE"); 
5475         case 0x0002: return wxT("WM_DESTROY"); 
5476         case 0x0003: return wxT("WM_MOVE"); 
5477         case 0x0005: return wxT("WM_SIZE"); 
5478         case 0x0006: return wxT("WM_ACTIVATE"); 
5479         case 0x0007: return wxT("WM_SETFOCUS"); 
5480         case 0x0008: return wxT("WM_KILLFOCUS"); 
5481         case 0x000A: return wxT("WM_ENABLE"); 
5482         case 0x000B: return wxT("WM_SETREDRAW"); 
5483         case 0x000C: return wxT("WM_SETTEXT"); 
5484         case 0x000D: return wxT("WM_GETTEXT"); 
5485         case 0x000E: return wxT("WM_GETTEXTLENGTH"); 
5486         case 0x000F: return wxT("WM_PAINT"); 
5487         case 0x0010: return wxT("WM_CLOSE"); 
5488         case 0x0011: return wxT("WM_QUERYENDSESSION"); 
5489         case 0x0012: return wxT("WM_QUIT"); 
5490         case 0x0013: return wxT("WM_QUERYOPEN"); 
5491         case 0x0014: return wxT("WM_ERASEBKGND"); 
5492         case 0x0015: return wxT("WM_SYSCOLORCHANGE"); 
5493         case 0x0016: return wxT("WM_ENDSESSION"); 
5494         case 0x0017: return wxT("WM_SYSTEMERROR"); 
5495         case 0x0018: return wxT("WM_SHOWWINDOW"); 
5496         case 0x0019: return wxT("WM_CTLCOLOR"); 
5497         case 0x001A: return wxT("WM_WININICHANGE"); 
5498         case 0x001B: return wxT("WM_DEVMODECHANGE"); 
5499         case 0x001C: return wxT("WM_ACTIVATEAPP"); 
5500         case 0x001D: return wxT("WM_FONTCHANGE"); 
5501         case 0x001E: return wxT("WM_TIMECHANGE"); 
5502         case 0x001F: return wxT("WM_CANCELMODE"); 
5503         case 0x0020: return wxT("WM_SETCURSOR"); 
5504         case 0x0021: return wxT("WM_MOUSEACTIVATE"); 
5505         case 0x0022: return wxT("WM_CHILDACTIVATE"); 
5506         case 0x0023: return wxT("WM_QUEUESYNC"); 
5507         case 0x0024: return wxT("WM_GETMINMAXINFO"); 
5508         case 0x0026: return wxT("WM_PAINTICON"); 
5509         case 0x0027: return wxT("WM_ICONERASEBKGND"); 
5510         case 0x0028: return wxT("WM_NEXTDLGCTL"); 
5511         case 0x002A: return wxT("WM_SPOOLERSTATUS"); 
5512         case 0x002B: return wxT("WM_DRAWITEM"); 
5513         case 0x002C: return wxT("WM_MEASUREITEM"); 
5514         case 0x002D: return wxT("WM_DELETEITEM"); 
5515         case 0x002E: return wxT("WM_VKEYTOITEM"); 
5516         case 0x002F: return wxT("WM_CHARTOITEM"); 
5517         case 0x0030: return wxT("WM_SETFONT"); 
5518         case 0x0031: return wxT("WM_GETFONT"); 
5519         case 0x0037: return wxT("WM_QUERYDRAGICON"); 
5520         case 0x0039: return wxT("WM_COMPAREITEM"); 
5521         case 0x0041: return wxT("WM_COMPACTING"); 
5522         case 0x0044: return wxT("WM_COMMNOTIFY"); 
5523         case 0x0046: return wxT("WM_WINDOWPOSCHANGING"); 
5524         case 0x0047: return wxT("WM_WINDOWPOSCHANGED"); 
5525         case 0x0048: return wxT("WM_POWER"); 
5527         case 0x004A: return wxT("WM_COPYDATA"); 
5528         case 0x004B: return wxT("WM_CANCELJOURNAL"); 
5529         case 0x004E: return wxT("WM_NOTIFY"); 
5530         case 0x0050: return wxT("WM_INPUTLANGCHANGEREQUEST"); 
5531         case 0x0051: return wxT("WM_INPUTLANGCHANGE"); 
5532         case 0x0052: return wxT("WM_TCARD"); 
5533         case 0x0053: return wxT("WM_HELP"); 
5534         case 0x0054: return wxT("WM_USERCHANGED"); 
5535         case 0x0055: return wxT("WM_NOTIFYFORMAT"); 
5536         case 0x007B: return wxT("WM_CONTEXTMENU"); 
5537         case 0x007C: return wxT("WM_STYLECHANGING"); 
5538         case 0x007D: return wxT("WM_STYLECHANGED"); 
5539         case 0x007E: return wxT("WM_DISPLAYCHANGE"); 
5540         case 0x007F: return wxT("WM_GETICON"); 
5541         case 0x0080: return wxT("WM_SETICON"); 
5543         case 0x0081: return wxT("WM_NCCREATE"); 
5544         case 0x0082: return wxT("WM_NCDESTROY"); 
5545         case 0x0083: return wxT("WM_NCCALCSIZE"); 
5546         case 0x0084: return wxT("WM_NCHITTEST"); 
5547         case 0x0085: return wxT("WM_NCPAINT"); 
5548         case 0x0086: return wxT("WM_NCACTIVATE"); 
5549         case 0x0087: return wxT("WM_GETDLGCODE"); 
5550         case 0x00A0: return wxT("WM_NCMOUSEMOVE"); 
5551         case 0x00A1: return wxT("WM_NCLBUTTONDOWN"); 
5552         case 0x00A2: return wxT("WM_NCLBUTTONUP"); 
5553         case 0x00A3: return wxT("WM_NCLBUTTONDBLCLK"); 
5554         case 0x00A4: return wxT("WM_NCRBUTTONDOWN"); 
5555         case 0x00A5: return wxT("WM_NCRBUTTONUP"); 
5556         case 0x00A6: return wxT("WM_NCRBUTTONDBLCLK"); 
5557         case 0x00A7: return wxT("WM_NCMBUTTONDOWN"); 
5558         case 0x00A8: return wxT("WM_NCMBUTTONUP"); 
5559         case 0x00A9: return wxT("WM_NCMBUTTONDBLCLK"); 
5560         case 0x0100: return wxT("WM_KEYDOWN"); 
5561         case 0x0101: return wxT("WM_KEYUP"); 
5562         case 0x0102: return wxT("WM_CHAR"); 
5563         case 0x0103: return wxT("WM_DEADCHAR"); 
5564         case 0x0104: return wxT("WM_SYSKEYDOWN"); 
5565         case 0x0105: return wxT("WM_SYSKEYUP"); 
5566         case 0x0106: return wxT("WM_SYSCHAR"); 
5567         case 0x0107: return wxT("WM_SYSDEADCHAR"); 
5568         case 0x0108: return wxT("WM_KEYLAST"); 
5570         case 0x010D: return wxT("WM_IME_STARTCOMPOSITION"); 
5571         case 0x010E: return wxT("WM_IME_ENDCOMPOSITION"); 
5572         case 0x010F: return wxT("WM_IME_COMPOSITION"); 
5574         case 0x0110: return wxT("WM_INITDIALOG"); 
5575         case 0x0111: return wxT("WM_COMMAND"); 
5576         case 0x0112: return wxT("WM_SYSCOMMAND"); 
5577         case 0x0113: return wxT("WM_TIMER"); 
5578         case 0x0114: return wxT("WM_HSCROLL"); 
5579         case 0x0115: return wxT("WM_VSCROLL"); 
5580         case 0x0116: return wxT("WM_INITMENU"); 
5581         case 0x0117: return wxT("WM_INITMENUPOPUP"); 
5582         case 0x011F: return wxT("WM_MENUSELECT"); 
5583         case 0x0120: return wxT("WM_MENUCHAR"); 
5584         case 0x0121: return wxT("WM_ENTERIDLE"); 
5585         case 0x0200: return wxT("WM_MOUSEMOVE"); 
5586         case 0x0201: return wxT("WM_LBUTTONDOWN"); 
5587         case 0x0202: return wxT("WM_LBUTTONUP"); 
5588         case 0x0203: return wxT("WM_LBUTTONDBLCLK"); 
5589         case 0x0204: return wxT("WM_RBUTTONDOWN"); 
5590         case 0x0205: return wxT("WM_RBUTTONUP"); 
5591         case 0x0206: return wxT("WM_RBUTTONDBLCLK"); 
5592         case 0x0207: return wxT("WM_MBUTTONDOWN"); 
5593         case 0x0208: return wxT("WM_MBUTTONUP"); 
5594         case 0x0209: return wxT("WM_MBUTTONDBLCLK"); 
5595         case 0x020A: return wxT("WM_MOUSEWHEEL"); 
5596         case 0x0210: return wxT("WM_PARENTNOTIFY"); 
5597         case 0x0211: return wxT("WM_ENTERMENULOOP"); 
5598         case 0x0212: return wxT("WM_EXITMENULOOP"); 
5600         case 0x0213: return wxT("WM_NEXTMENU"); 
5601         case 0x0214: return wxT("WM_SIZING"); 
5602         case 0x0215: return wxT("WM_CAPTURECHANGED"); 
5603         case 0x0216: return wxT("WM_MOVING"); 
5604         case 0x0218: return wxT("WM_POWERBROADCAST"); 
5605         case 0x0219: return wxT("WM_DEVICECHANGE"); 
5607         case 0x0220: return wxT("WM_MDICREATE"); 
5608         case 0x0221: return wxT("WM_MDIDESTROY"); 
5609         case 0x0222: return wxT("WM_MDIACTIVATE"); 
5610         case 0x0223: return wxT("WM_MDIRESTORE"); 
5611         case 0x0224: return wxT("WM_MDINEXT"); 
5612         case 0x0225: return wxT("WM_MDIMAXIMIZE"); 
5613         case 0x0226: return wxT("WM_MDITILE"); 
5614         case 0x0227: return wxT("WM_MDICASCADE"); 
5615         case 0x0228: return wxT("WM_MDIICONARRANGE"); 
5616         case 0x0229: return wxT("WM_MDIGETACTIVE"); 
5617         case 0x0230: return wxT("WM_MDISETMENU"); 
5618         case 0x0233: return wxT("WM_DROPFILES"); 
5620         case 0x0281: return wxT("WM_IME_SETCONTEXT"); 
5621         case 0x0282: return wxT("WM_IME_NOTIFY"); 
5622         case 0x0283: return wxT("WM_IME_CONTROL"); 
5623         case 0x0284: return wxT("WM_IME_COMPOSITIONFULL"); 
5624         case 0x0285: return wxT("WM_IME_SELECT"); 
5625         case 0x0286: return wxT("WM_IME_CHAR"); 
5626         case 0x0290: return wxT("WM_IME_KEYDOWN"); 
5627         case 0x0291: return wxT("WM_IME_KEYUP"); 
5629         case 0x0300: return wxT("WM_CUT"); 
5630         case 0x0301: return wxT("WM_COPY"); 
5631         case 0x0302: return wxT("WM_PASTE"); 
5632         case 0x0303: return wxT("WM_CLEAR"); 
5633         case 0x0304: return wxT("WM_UNDO"); 
5634         case 0x0305: return wxT("WM_RENDERFORMAT"); 
5635         case 0x0306: return wxT("WM_RENDERALLFORMATS"); 
5636         case 0x0307: return wxT("WM_DESTROYCLIPBOARD"); 
5637         case 0x0308: return wxT("WM_DRAWCLIPBOARD"); 
5638         case 0x0309: return wxT("WM_PAINTCLIPBOARD"); 
5639         case 0x030A: return wxT("WM_VSCROLLCLIPBOARD"); 
5640         case 0x030B: return wxT("WM_SIZECLIPBOARD"); 
5641         case 0x030C: return wxT("WM_ASKCBFORMATNAME"); 
5642         case 0x030D: return wxT("WM_CHANGECBCHAIN"); 
5643         case 0x030E: return wxT("WM_HSCROLLCLIPBOARD"); 
5644         case 0x030F: return wxT("WM_QUERYNEWPALETTE"); 
5645         case 0x0310: return wxT("WM_PALETTEISCHANGING"); 
5646         case 0x0311: return wxT("WM_PALETTECHANGED"); 
5648         case 0x0312: return wxT("WM_HOTKEY"); 
5651         // common controls messages - although they're not strictly speaking 
5652         // standard, it's nice to decode them nevertheless 
5655         case 0x1000 + 0: return wxT("LVM_GETBKCOLOR"); 
5656         case 0x1000 + 1: return wxT("LVM_SETBKCOLOR"); 
5657         case 0x1000 + 2: return wxT("LVM_GETIMAGELIST"); 
5658         case 0x1000 + 3: return wxT("LVM_SETIMAGELIST"); 
5659         case 0x1000 + 4: return wxT("LVM_GETITEMCOUNT"); 
5660         case 0x1000 + 5: return wxT("LVM_GETITEMA"); 
5661         case 0x1000 + 75: return wxT("LVM_GETITEMW"); 
5662         case 0x1000 + 6: return wxT("LVM_SETITEMA"); 
5663         case 0x1000 + 76: return wxT("LVM_SETITEMW"); 
5664         case 0x1000 + 7: return wxT("LVM_INSERTITEMA"); 
5665         case 0x1000 + 77: return wxT("LVM_INSERTITEMW"); 
5666         case 0x1000 + 8: return wxT("LVM_DELETEITEM"); 
5667         case 0x1000 + 9: return wxT("LVM_DELETEALLITEMS"); 
5668         case 0x1000 + 10: return wxT("LVM_GETCALLBACKMASK"); 
5669         case 0x1000 + 11: return wxT("LVM_SETCALLBACKMASK"); 
5670         case 0x1000 + 12: return wxT("LVM_GETNEXTITEM"); 
5671         case 0x1000 + 13: return wxT("LVM_FINDITEMA"); 
5672         case 0x1000 + 83: return wxT("LVM_FINDITEMW"); 
5673         case 0x1000 + 14: return wxT("LVM_GETITEMRECT"); 
5674         case 0x1000 + 15: return wxT("LVM_SETITEMPOSITION"); 
5675         case 0x1000 + 16: return wxT("LVM_GETITEMPOSITION"); 
5676         case 0x1000 + 17: return wxT("LVM_GETSTRINGWIDTHA"); 
5677         case 0x1000 + 87: return wxT("LVM_GETSTRINGWIDTHW"); 
5678         case 0x1000 + 18: return wxT("LVM_HITTEST"); 
5679         case 0x1000 + 19: return wxT("LVM_ENSUREVISIBLE"); 
5680         case 0x1000 + 20: return wxT("LVM_SCROLL"); 
5681         case 0x1000 + 21: return wxT("LVM_REDRAWITEMS"); 
5682         case 0x1000 + 22: return wxT("LVM_ARRANGE"); 
5683         case 0x1000 + 23: return wxT("LVM_EDITLABELA"); 
5684         case 0x1000 + 118: return wxT("LVM_EDITLABELW"); 
5685         case 0x1000 + 24: return wxT("LVM_GETEDITCONTROL"); 
5686         case 0x1000 + 25: return wxT("LVM_GETCOLUMNA"); 
5687         case 0x1000 + 95: return wxT("LVM_GETCOLUMNW"); 
5688         case 0x1000 + 26: return wxT("LVM_SETCOLUMNA"); 
5689         case 0x1000 + 96: return wxT("LVM_SETCOLUMNW"); 
5690         case 0x1000 + 27: return wxT("LVM_INSERTCOLUMNA"); 
5691         case 0x1000 + 97: return wxT("LVM_INSERTCOLUMNW"); 
5692         case 0x1000 + 28: return wxT("LVM_DELETECOLUMN"); 
5693         case 0x1000 + 29: return wxT("LVM_GETCOLUMNWIDTH"); 
5694         case 0x1000 + 30: return wxT("LVM_SETCOLUMNWIDTH"); 
5695         case 0x1000 + 31: return wxT("LVM_GETHEADER"); 
5696         case 0x1000 + 33: return wxT("LVM_CREATEDRAGIMAGE"); 
5697         case 0x1000 + 34: return wxT("LVM_GETVIEWRECT"); 
5698         case 0x1000 + 35: return wxT("LVM_GETTEXTCOLOR"); 
5699         case 0x1000 + 36: return wxT("LVM_SETTEXTCOLOR"); 
5700         case 0x1000 + 37: return wxT("LVM_GETTEXTBKCOLOR"); 
5701         case 0x1000 + 38: return wxT("LVM_SETTEXTBKCOLOR"); 
5702         case 0x1000 + 39: return wxT("LVM_GETTOPINDEX"); 
5703         case 0x1000 + 40: return wxT("LVM_GETCOUNTPERPAGE"); 
5704         case 0x1000 + 41: return wxT("LVM_GETORIGIN"); 
5705         case 0x1000 + 42: return wxT("LVM_UPDATE"); 
5706         case 0x1000 + 43: return wxT("LVM_SETITEMSTATE"); 
5707         case 0x1000 + 44: return wxT("LVM_GETITEMSTATE"); 
5708         case 0x1000 + 45: return wxT("LVM_GETITEMTEXTA"); 
5709         case 0x1000 + 115: return wxT("LVM_GETITEMTEXTW"); 
5710         case 0x1000 + 46: return wxT("LVM_SETITEMTEXTA"); 
5711         case 0x1000 + 116: return wxT("LVM_SETITEMTEXTW"); 
5712         case 0x1000 + 47: return wxT("LVM_SETITEMCOUNT"); 
5713         case 0x1000 + 48: return wxT("LVM_SORTITEMS"); 
5714         case 0x1000 + 49: return wxT("LVM_SETITEMPOSITION32"); 
5715         case 0x1000 + 50: return wxT("LVM_GETSELECTEDCOUNT"); 
5716         case 0x1000 + 51: return wxT("LVM_GETITEMSPACING"); 
5717         case 0x1000 + 52: return wxT("LVM_GETISEARCHSTRINGA"); 
5718         case 0x1000 + 117: return wxT("LVM_GETISEARCHSTRINGW"); 
5719         case 0x1000 + 53: return wxT("LVM_SETICONSPACING"); 
5720         case 0x1000 + 54: return wxT("LVM_SETEXTENDEDLISTVIEWSTYLE"); 
5721         case 0x1000 + 55: return wxT("LVM_GETEXTENDEDLISTVIEWSTYLE"); 
5722         case 0x1000 + 56: return wxT("LVM_GETSUBITEMRECT"); 
5723         case 0x1000 + 57: return wxT("LVM_SUBITEMHITTEST"); 
5724         case 0x1000 + 58: return wxT("LVM_SETCOLUMNORDERARRAY"); 
5725         case 0x1000 + 59: return wxT("LVM_GETCOLUMNORDERARRAY"); 
5726         case 0x1000 + 60: return wxT("LVM_SETHOTITEM"); 
5727         case 0x1000 + 61: return wxT("LVM_GETHOTITEM"); 
5728         case 0x1000 + 62: return wxT("LVM_SETHOTCURSOR"); 
5729         case 0x1000 + 63: return wxT("LVM_GETHOTCURSOR"); 
5730         case 0x1000 + 64: return wxT("LVM_APPROXIMATEVIEWRECT"); 
5731         case 0x1000 + 65: return wxT("LVM_SETWORKAREA"); 
5734         case 0x1100 + 0: return wxT("TVM_INSERTITEMA"); 
5735         case 0x1100 + 50: return wxT("TVM_INSERTITEMW"); 
5736         case 0x1100 + 1: return wxT("TVM_DELETEITEM"); 
5737         case 0x1100 + 2: return wxT("TVM_EXPAND"); 
5738         case 0x1100 + 4: return wxT("TVM_GETITEMRECT"); 
5739         case 0x1100 + 5: return wxT("TVM_GETCOUNT"); 
5740         case 0x1100 + 6: return wxT("TVM_GETINDENT"); 
5741         case 0x1100 + 7: return wxT("TVM_SETINDENT"); 
5742         case 0x1100 + 8: return wxT("TVM_GETIMAGELIST"); 
5743         case 0x1100 + 9: return wxT("TVM_SETIMAGELIST"); 
5744         case 0x1100 + 10: return wxT("TVM_GETNEXTITEM"); 
5745         case 0x1100 + 11: return wxT("TVM_SELECTITEM"); 
5746         case 0x1100 + 12: return wxT("TVM_GETITEMA"); 
5747         case 0x1100 + 62: return wxT("TVM_GETITEMW"); 
5748         case 0x1100 + 13: return wxT("TVM_SETITEMA"); 
5749         case 0x1100 + 63: return wxT("TVM_SETITEMW"); 
5750         case 0x1100 + 14: return wxT("TVM_EDITLABELA"); 
5751         case 0x1100 + 65: return wxT("TVM_EDITLABELW"); 
5752         case 0x1100 + 15: return wxT("TVM_GETEDITCONTROL"); 
5753         case 0x1100 + 16: return wxT("TVM_GETVISIBLECOUNT"); 
5754         case 0x1100 + 17: return wxT("TVM_HITTEST"); 
5755         case 0x1100 + 18: return wxT("TVM_CREATEDRAGIMAGE"); 
5756         case 0x1100 + 19: return wxT("TVM_SORTCHILDREN"); 
5757         case 0x1100 + 20: return wxT("TVM_ENSUREVISIBLE"); 
5758         case 0x1100 + 21: return wxT("TVM_SORTCHILDRENCB"); 
5759         case 0x1100 + 22: return wxT("TVM_ENDEDITLABELNOW"); 
5760         case 0x1100 + 23: return wxT("TVM_GETISEARCHSTRINGA"); 
5761         case 0x1100 + 64: return wxT("TVM_GETISEARCHSTRINGW"); 
5762         case 0x1100 + 24: return wxT("TVM_SETTOOLTIPS"); 
5763         case 0x1100 + 25: return wxT("TVM_GETTOOLTIPS"); 
5766         case 0x1200 + 0: return wxT("HDM_GETITEMCOUNT"); 
5767         case 0x1200 + 1: return wxT("HDM_INSERTITEMA"); 
5768         case 0x1200 + 10: return wxT("HDM_INSERTITEMW"); 
5769         case 0x1200 + 2: return wxT("HDM_DELETEITEM"); 
5770         case 0x1200 + 3: return wxT("HDM_GETITEMA"); 
5771         case 0x1200 + 11: return wxT("HDM_GETITEMW"); 
5772         case 0x1200 + 4: return wxT("HDM_SETITEMA"); 
5773         case 0x1200 + 12: return wxT("HDM_SETITEMW"); 
5774         case 0x1200 + 5: return wxT("HDM_LAYOUT"); 
5775         case 0x1200 + 6: return wxT("HDM_HITTEST"); 
5776         case 0x1200 + 7: return wxT("HDM_GETITEMRECT"); 
5777         case 0x1200 + 8: return wxT("HDM_SETIMAGELIST"); 
5778         case 0x1200 + 9: return wxT("HDM_GETIMAGELIST"); 
5779         case 0x1200 + 15: return wxT("HDM_ORDERTOINDEX"); 
5780         case 0x1200 + 16: return wxT("HDM_CREATEDRAGIMAGE"); 
5781         case 0x1200 + 17: return wxT("HDM_GETORDERARRAY"); 
5782         case 0x1200 + 18: return wxT("HDM_SETORDERARRAY"); 
5783         case 0x1200 + 19: return wxT("HDM_SETHOTDIVIDER"); 
5786         case 0x1300 + 2: return wxT("TCM_GETIMAGELIST"); 
5787         case 0x1300 + 3: return wxT("TCM_SETIMAGELIST"); 
5788         case 0x1300 + 4: return wxT("TCM_GETITEMCOUNT"); 
5789         case 0x1300 + 5: return wxT("TCM_GETITEMA"); 
5790         case 0x1300 + 60: return wxT("TCM_GETITEMW"); 
5791         case 0x1300 + 6: return wxT("TCM_SETITEMA"); 
5792         case 0x1300 + 61: return wxT("TCM_SETITEMW"); 
5793         case 0x1300 + 7: return wxT("TCM_INSERTITEMA"); 
5794         case 0x1300 + 62: return wxT("TCM_INSERTITEMW"); 
5795         case 0x1300 + 8: return wxT("TCM_DELETEITEM"); 
5796         case 0x1300 + 9: return wxT("TCM_DELETEALLITEMS"); 
5797         case 0x1300 + 10: return wxT("TCM_GETITEMRECT"); 
5798         case 0x1300 + 11: return wxT("TCM_GETCURSEL"); 
5799         case 0x1300 + 12: return wxT("TCM_SETCURSEL"); 
5800         case 0x1300 + 13: return wxT("TCM_HITTEST"); 
5801         case 0x1300 + 14: return wxT("TCM_SETITEMEXTRA"); 
5802         case 0x1300 + 40: return wxT("TCM_ADJUSTRECT"); 
5803         case 0x1300 + 41: return wxT("TCM_SETITEMSIZE"); 
5804         case 0x1300 + 42: return wxT("TCM_REMOVEIMAGE"); 
5805         case 0x1300 + 43: return wxT("TCM_SETPADDING"); 
5806         case 0x1300 + 44: return wxT("TCM_GETROWCOUNT"); 
5807         case 0x1300 + 45: return wxT("TCM_GETTOOLTIPS"); 
5808         case 0x1300 + 46: return wxT("TCM_SETTOOLTIPS"); 
5809         case 0x1300 + 47: return wxT("TCM_GETCURFOCUS"); 
5810         case 0x1300 + 48: return wxT("TCM_SETCURFOCUS"); 
5811         case 0x1300 + 49: return wxT("TCM_SETMINTABWIDTH"); 
5812         case 0x1300 + 50: return wxT("TCM_DESELECTALL"); 
5815         case WM_USER
+1: return wxT("TB_ENABLEBUTTON"); 
5816         case WM_USER
+2: return wxT("TB_CHECKBUTTON"); 
5817         case WM_USER
+3: return wxT("TB_PRESSBUTTON"); 
5818         case WM_USER
+4: return wxT("TB_HIDEBUTTON"); 
5819         case WM_USER
+5: return wxT("TB_INDETERMINATE"); 
5820         case WM_USER
+9: return wxT("TB_ISBUTTONENABLED"); 
5821         case WM_USER
+10: return wxT("TB_ISBUTTONCHECKED"); 
5822         case WM_USER
+11: return wxT("TB_ISBUTTONPRESSED"); 
5823         case WM_USER
+12: return wxT("TB_ISBUTTONHIDDEN"); 
5824         case WM_USER
+13: return wxT("TB_ISBUTTONINDETERMINATE"); 
5825         case WM_USER
+17: return wxT("TB_SETSTATE"); 
5826         case WM_USER
+18: return wxT("TB_GETSTATE"); 
5827         case WM_USER
+19: return wxT("TB_ADDBITMAP"); 
5828         case WM_USER
+20: return wxT("TB_ADDBUTTONS"); 
5829         case WM_USER
+21: return wxT("TB_INSERTBUTTON"); 
5830         case WM_USER
+22: return wxT("TB_DELETEBUTTON"); 
5831         case WM_USER
+23: return wxT("TB_GETBUTTON"); 
5832         case WM_USER
+24: return wxT("TB_BUTTONCOUNT"); 
5833         case WM_USER
+25: return wxT("TB_COMMANDTOINDEX"); 
5834         case WM_USER
+26: return wxT("TB_SAVERESTOREA"); 
5835         case WM_USER
+76: return wxT("TB_SAVERESTOREW"); 
5836         case WM_USER
+27: return wxT("TB_CUSTOMIZE"); 
5837         case WM_USER
+28: return wxT("TB_ADDSTRINGA"); 
5838         case WM_USER
+77: return wxT("TB_ADDSTRINGW"); 
5839         case WM_USER
+29: return wxT("TB_GETITEMRECT"); 
5840         case WM_USER
+30: return wxT("TB_BUTTONSTRUCTSIZE"); 
5841         case WM_USER
+31: return wxT("TB_SETBUTTONSIZE"); 
5842         case WM_USER
+32: return wxT("TB_SETBITMAPSIZE"); 
5843         case WM_USER
+33: return wxT("TB_AUTOSIZE"); 
5844         case WM_USER
+35: return wxT("TB_GETTOOLTIPS"); 
5845         case WM_USER
+36: return wxT("TB_SETTOOLTIPS"); 
5846         case WM_USER
+37: return wxT("TB_SETPARENT"); 
5847         case WM_USER
+39: return wxT("TB_SETROWS"); 
5848         case WM_USER
+40: return wxT("TB_GETROWS"); 
5849         case WM_USER
+42: return wxT("TB_SETCMDID"); 
5850         case WM_USER
+43: return wxT("TB_CHANGEBITMAP"); 
5851         case WM_USER
+44: return wxT("TB_GETBITMAP"); 
5852         case WM_USER
+45: return wxT("TB_GETBUTTONTEXTA"); 
5853         case WM_USER
+75: return wxT("TB_GETBUTTONTEXTW"); 
5854         case WM_USER
+46: return wxT("TB_REPLACEBITMAP"); 
5855         case WM_USER
+47: return wxT("TB_SETINDENT"); 
5856         case WM_USER
+48: return wxT("TB_SETIMAGELIST"); 
5857         case WM_USER
+49: return wxT("TB_GETIMAGELIST"); 
5858         case WM_USER
+50: return wxT("TB_LOADIMAGES"); 
5859         case WM_USER
+51: return wxT("TB_GETRECT"); 
5860         case WM_USER
+52: return wxT("TB_SETHOTIMAGELIST"); 
5861         case WM_USER
+53: return wxT("TB_GETHOTIMAGELIST"); 
5862         case WM_USER
+54: return wxT("TB_SETDISABLEDIMAGELIST"); 
5863         case WM_USER
+55: return wxT("TB_GETDISABLEDIMAGELIST"); 
5864         case WM_USER
+56: return wxT("TB_SETSTYLE"); 
5865         case WM_USER
+57: return wxT("TB_GETSTYLE"); 
5866         case WM_USER
+58: return wxT("TB_GETBUTTONSIZE"); 
5867         case WM_USER
+59: return wxT("TB_SETBUTTONWIDTH"); 
5868         case WM_USER
+60: return wxT("TB_SETMAXTEXTROWS"); 
5869         case WM_USER
+61: return wxT("TB_GETTEXTROWS"); 
5870         case WM_USER
+41: return wxT("TB_GETBITMAPFLAGS"); 
5873             static wxString s_szBuf
; 
5874             s_szBuf
.Printf(wxT("<unknown message = %d>"), message
); 
5875             return s_szBuf
.c_str(); 
5878 #endif //__WXDEBUG__ 
5880 static TEXTMETRIC 
wxGetTextMetrics(const wxWindowMSW 
*win
) 
5884     HWND hwnd 
= GetHwndOf(win
); 
5885     HDC hdc 
= ::GetDC(hwnd
); 
5887 #if !wxDIALOG_UNIT_COMPATIBILITY 
5888     // and select the current font into it 
5889     HFONT hfont 
= GetHfontOf(win
->GetFont()); 
5892         hfont 
= (HFONT
)::SelectObject(hdc
, hfont
); 
5896     // finally retrieve the text metrics from it 
5897     GetTextMetrics(hdc
, &tm
); 
5899 #if !wxDIALOG_UNIT_COMPATIBILITY 
5903         (void)::SelectObject(hdc
, hfont
); 
5907     ::ReleaseDC(hwnd
, hdc
); 
5912 // Find the wxWindow at the current mouse position, returning the mouse 
5914 wxWindow
* wxFindWindowAtPointer(wxPoint
& pt
) 
5916     pt 
= wxGetMousePosition(); 
5917     return wxFindWindowAtPoint(pt
); 
5920 wxWindow
* wxFindWindowAtPoint(const wxPoint
& pt
) 
5925     HWND hWndHit 
= ::WindowFromPoint(pt2
); 
5927     wxWindow
* win 
= wxFindWinFromHandle((WXHWND
) hWndHit
) ; 
5928     HWND hWnd 
= hWndHit
; 
5930     // Try to find a window with a wxWindow associated with it 
5931     while (!win 
&& (hWnd 
!= 0)) 
5933         hWnd 
= ::GetParent(hWnd
); 
5934         win 
= wxFindWinFromHandle((WXHWND
) hWnd
) ; 
5939 // Get the current mouse position. 
5940 wxPoint 
wxGetMousePosition() 
5944     GetCursorPosWinCE(&pt
); 
5946     GetCursorPos( & pt 
); 
5949     return wxPoint(pt
.x
, pt
.y
); 
5954 #if defined(__SMARTPHONE__) || defined(__POCKETPC__) 
5955 static void WinCEUnregisterHotKey(int modifiers
, int id
) 
5957     // Register hotkeys for the hardware buttons 
5959     typedef BOOL (WINAPI 
*UnregisterFunc1Proc
)(UINT
, UINT
); 
5961     UnregisterFunc1Proc procUnregisterFunc
; 
5962     hCoreDll 
= LoadLibrary(_T("coredll.dll")); 
5965         procUnregisterFunc 
= (UnregisterFunc1Proc
)GetProcAddress(hCoreDll
, _T("UnregisterFunc1")); 
5966         if (procUnregisterFunc
) 
5967             procUnregisterFunc(modifiers
, id
); 
5968         FreeLibrary(hCoreDll
); 
5973 bool wxWindowMSW::RegisterHotKey(int hotkeyId
, int modifiers
, int keycode
) 
5975     UINT win_modifiers
=0; 
5976     if ( modifiers 
& wxMOD_ALT 
) 
5977         win_modifiers 
|= MOD_ALT
; 
5978     if ( modifiers 
& wxMOD_SHIFT 
) 
5979         win_modifiers 
|= MOD_SHIFT
; 
5980     if ( modifiers 
& wxMOD_CONTROL 
) 
5981         win_modifiers 
|= MOD_CONTROL
; 
5982     if ( modifiers 
& wxMOD_WIN 
) 
5983         win_modifiers 
|= MOD_WIN
; 
5985 #if defined(__SMARTPHONE__) || defined(__POCKETPC__) 
5986     // Required for PPC and Smartphone hardware buttons 
5987     if (keycode 
>= WXK_SPECIAL1 
&& keycode 
<= WXK_SPECIAL20
) 
5988         WinCEUnregisterHotKey(win_modifiers
, hotkeyId
); 
5991     if ( !::RegisterHotKey(GetHwnd(), hotkeyId
, win_modifiers
, keycode
) ) 
5993         wxLogLastError(_T("RegisterHotKey")); 
6001 bool wxWindowMSW::UnregisterHotKey(int hotkeyId
) 
6003 #if defined(__SMARTPHONE__) || defined(__POCKETPC__) 
6004     WinCEUnregisterHotKey(MOD_WIN
, hotkeyId
); 
6007     if ( !::UnregisterHotKey(GetHwnd(), hotkeyId
) ) 
6009         wxLogLastError(_T("UnregisterHotKey")); 
6019 bool wxWindowMSW::HandleHotKey(WXWPARAM wParam
, WXLPARAM lParam
) 
6021     int hotkeyId 
= wParam
; 
6022     int virtualKey 
= HIWORD(lParam
); 
6023     int win_modifiers 
= LOWORD(lParam
); 
6025     wxKeyEvent 
event(CreateKeyEvent(wxEVT_HOTKEY
, virtualKey
, wParam
, lParam
)); 
6026     event
.SetId(hotkeyId
); 
6027     event
.m_shiftDown 
= (win_modifiers 
& MOD_SHIFT
) != 0; 
6028     event
.m_controlDown 
= (win_modifiers 
& MOD_CONTROL
) != 0; 
6029     event
.m_altDown 
= (win_modifiers 
& MOD_ALT
) != 0; 
6030     event
.m_metaDown 
= (win_modifiers 
& MOD_WIN
) != 0; 
6032     return GetEventHandler()->ProcessEvent(event
); 
6035 #endif // wxUSE_ACCEL 
6037 #endif // wxUSE_HOTKEY 
6039 // Not tested under WinCE 
6042 // this class installs a message hook which really wakes up our idle processing 
6043 // each time a WM_NULL is received (wxWakeUpIdle does this), even if we're 
6044 // sitting inside a local modal loop (e.g. a menu is opened or scrollbar is 
6045 // being dragged or even inside ::MessageBox()) and so don't control message 
6046 // dispatching otherwise 
6047 class wxIdleWakeUpModule 
: public wxModule
 
6050     virtual bool OnInit() 
6052         ms_hMsgHookProc 
= ::SetWindowsHookEx
 
6055                              &wxIdleWakeUpModule::MsgHookProc
, 
6057                              GetCurrentThreadId() 
6060         if ( !ms_hMsgHookProc 
) 
6062             wxLogLastError(_T("SetWindowsHookEx(WH_GETMESSAGE)")); 
6070     virtual void OnExit() 
6072         ::UnhookWindowsHookEx(wxIdleWakeUpModule::ms_hMsgHookProc
); 
6075     static LRESULT CALLBACK 
MsgHookProc(int nCode
, WPARAM wParam
, LPARAM lParam
) 
6077         MSG 
*msg 
= (MSG
*)lParam
; 
6079         // only process the message if it is actually going to be removed from 
6080         // the message queue, this prevents that the same event from being 
6081         // processed multiple times if now someone just called PeekMessage() 
6082         if ( msg
->message 
== WM_NULL 
&& wParam 
== PM_REMOVE 
) 
6084             wxTheApp
->ProcessPendingEvents(); 
6087         return CallNextHookEx(ms_hMsgHookProc
, nCode
, wParam
, lParam
); 
6091     static HHOOK ms_hMsgHookProc
; 
6093     DECLARE_DYNAMIC_CLASS(wxIdleWakeUpModule
) 
6096 HHOOK 
wxIdleWakeUpModule::ms_hMsgHookProc 
= 0; 
6098 IMPLEMENT_DYNAMIC_CLASS(wxIdleWakeUpModule
, wxModule
) 
6100 #endif // __WXWINCE__ 
6105 static void wxAdjustZOrder(wxWindow
* parent
) 
6107     if (parent
->IsKindOf(CLASSINFO(wxStaticBox
))) 
6109         // Set the z-order correctly 
6110         SetWindowPos((HWND
) parent
->GetHWND(), HWND_BOTTOM
, 0, 0, 0, 0, SWP_NOMOVE
|SWP_NOSIZE
); 
6113     wxWindowList::compatibility_iterator current 
= parent
->GetChildren().GetFirst(); 
6116         wxWindow 
*childWin 
= current
->GetData(); 
6117         wxAdjustZOrder(childWin
); 
6118         current 
= current
->GetNext(); 
6123 // We need to adjust the z-order of static boxes in WinCE, to 
6124 // make 'contained' controls visible 
6125 void wxWindowMSW::OnInitDialog( wxInitDialogEvent
& event 
) 
6128     wxAdjustZOrder(this);