1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Julian Smart 
   5 // Modified by: VZ on 13.05.99: no more Default(), MSWOnXXX() reorganisation 
   8 // Copyright:   (c) Julian Smart and Markus Holzem 
   9 // Licence:     wxWindows license 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // =========================================================================== 
  14 // =========================================================================== 
  16 // --------------------------------------------------------------------------- 
  18 // --------------------------------------------------------------------------- 
  21     #pragma implementation "window.h" 
  24 // For compilers that support precompilation, includes "wx.h". 
  25 #include "wx/wxprec.h" 
  33     #include "wx/msw/winundef.h" 
  34     #include "wx/window.h" 
  39     #include "wx/dcclient.h" 
  43     #include "wx/layout.h" 
  44     #include "wx/dialog.h" 
  46     #include "wx/listbox.h" 
  47     #include "wx/button.h" 
  48     #include "wx/msgdlg.h" 
  54     #include "wx/ownerdrw.h" 
  57 #if wxUSE_DRAG_AND_DROP 
  61 #include "wx/menuitem.h" 
  64 #include "wx/msw/private.h" 
  67     #include "wx/tooltip.h" 
  77 #include "wx/textctrl.h" 
  78 #include "wx/notebook.h" 
  82 #ifndef __GNUWIN32_OLD__ 
  91 #if !defined(__GNUWIN32_OLD__) && !defined(__TWIN32__) 
  95 #else // broken compiler 
  97         #include "wx/msw/gnuwin32/extra.h" 
 101 // This didn't appear in mingw until 2.95.2 
 103 #define SIF_TRACKPOS 16 
 106 // --------------------------------------------------------------------------- 
 108 // --------------------------------------------------------------------------- 
 110 // the last Windows message we got (MT-UNSAFE) 
 111 extern MSG s_currentMsg
; 
 113 wxMenu 
*wxCurrentPopupMenu 
= NULL
; 
 114 extern wxList WXDLLEXPORT wxPendingDelete
; 
 115 extern const wxChar 
*wxCanvasClassName
; 
 117 // --------------------------------------------------------------------------- 
 119 // --------------------------------------------------------------------------- 
 121 // the window proc for all our windows 
 122 LRESULT WXDLLEXPORT APIENTRY _EXPORT 
wxWndProc(HWND hWnd
, UINT message
, 
 123                                    WPARAM wParam
, LPARAM lParam
); 
 126     const char *wxGetMessageName(int message
); 
 129 void wxRemoveHandleAssociation(wxWindow 
*win
); 
 130 void wxAssociateWinWithHandle(HWND hWnd
, wxWindow 
*win
); 
 131 wxWindow 
*wxFindWinFromHandle(WXHWND hWnd
); 
 133 // this magical function is used to translate VK_APPS key presses to right 
 135 static void TranslateKbdEventToMouse(wxWindow 
*win
, int *x
, int *y
, WPARAM 
*flags
); 
 137 // get the text metrics for the current font 
 138 static TEXTMETRIC 
wxGetTextMetrics(const wxWindow 
*win
); 
 140 // --------------------------------------------------------------------------- 
 142 // --------------------------------------------------------------------------- 
 144 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
) 
 146 BEGIN_EVENT_TABLE(wxWindow
, wxWindowBase
) 
 147     EVT_ERASE_BACKGROUND(wxWindow::OnEraseBackground
) 
 148     EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
) 
 149     EVT_INIT_DIALOG(wxWindow::OnInitDialog
) 
 150     EVT_IDLE(wxWindow::OnIdle
) 
 151     EVT_SET_FOCUS(wxWindow::OnSetFocus
) 
 154 // =========================================================================== 
 156 // =========================================================================== 
 158 // --------------------------------------------------------------------------- 
 159 // wxWindow utility functions 
 160 // --------------------------------------------------------------------------- 
 162 // Find an item given the MS Windows id 
 163 wxWindow 
*wxWindow::FindItem(long id
) const 
 165     wxControl 
*item 
= wxDynamicCast(this, wxControl
); 
 168         // i it we or one of our "internal" children? 
 169         if ( item
->GetId() == id 
|| 
 170              (item
->GetSubcontrols().Index(id
) != wxNOT_FOUND
) ) 
 176     wxWindowList::Node 
*current 
= GetChildren().GetFirst(); 
 179         wxWindow 
*childWin 
= current
->GetData(); 
 181         wxWindow 
*wnd 
= childWin
->FindItem(id
); 
 185         current 
= current
->GetNext(); 
 191 // Find an item given the MS Windows handle 
 192 wxWindow 
*wxWindow::FindItemByHWND(WXHWND hWnd
, bool controlOnly
) const 
 194     wxWindowList::Node 
*current 
= GetChildren().GetFirst(); 
 197         wxWindow 
*parent 
= current
->GetData(); 
 199         // Do a recursive search. 
 200         wxWindow 
*wnd 
= parent
->FindItemByHWND(hWnd
); 
 204         if ( !controlOnly 
|| parent
->IsKindOf(CLASSINFO(wxControl
)) ) 
 206             wxWindow 
*item 
= current
->GetData(); 
 207             if ( item
->GetHWND() == hWnd 
) 
 211                 if ( item
->ContainsHWND(hWnd
) ) 
 216         current 
= current
->GetNext(); 
 221 // Default command handler 
 222 bool wxWindow::MSWCommand(WXUINT 
WXUNUSED(param
), WXWORD 
WXUNUSED(id
)) 
 227 // ---------------------------------------------------------------------------- 
 228 // constructors and such 
 229 // ---------------------------------------------------------------------------- 
 231 void wxWindow::Init() 
 237     m_doubleClickAllowed 
= 0; 
 238     m_winCaptured 
= FALSE
; 
 240     m_isBeingDeleted 
= FALSE
; 
 243     m_mouseInWindow 
= FALSE
; 
 250     // pass WM_GETDLGCODE to DefWindowProc() 
 255     m_backgroundTransparent 
= FALSE
; 
 257     // as all windows are created with WS_VISIBLE style... 
 260 #if wxUSE_MOUSEEVENT_HACK 
 263     m_lastMouseEvent 
= -1; 
 264 #endif // wxUSE_MOUSEEVENT_HACK 
 268 wxWindow::~wxWindow() 
 270     m_isBeingDeleted 
= TRUE
; 
 272     MSWDetachWindowMenu(); 
 275         m_parent
->RemoveChild(this); 
 281         // VZ: test temp removed to understand what really happens here 
 282         //if (::IsWindow(GetHwnd())) 
 284             if ( !::DestroyWindow(GetHwnd()) ) 
 285                 wxLogLastError(wxT("DestroyWindow")); 
 288         // remove hWnd <-> wxWindow association 
 289         wxRemoveHandleAssociation(this); 
 293 // real construction (Init() must have been called before!) 
 294 bool wxWindow::Create(wxWindow 
*parent
, wxWindowID id
, 
 298                       const wxString
& name
) 
 300     wxCHECK_MSG( parent
, FALSE
, wxT("can't create wxWindow without parent") ); 
 302     if ( !CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
) ) 
 305     parent
->AddChild(this); 
 308     if ( style 
& wxBORDER 
) 
 309         msflags 
|= WS_BORDER
; 
 310 /* Not appropriate for non-frame/dialog windows, and 
 311    may clash with other window styles. 
 312     if ( style & wxTHICK_FRAME ) 
 313         msflags |= WS_THICKFRAME; 
 315     //msflags |= WS_CHILD /* | WS_CLIPSIBLINGS */  | WS_VISIBLE; 
 316     msflags 
|= WS_CHILD 
| WS_VISIBLE
; 
 317     if ( style 
& wxCLIP_CHILDREN 
) 
 318         msflags 
|= WS_CLIPCHILDREN
; 
 319     if ( style 
& wxCLIP_SIBLINGS 
) 
 320         msflags 
|= WS_CLIPSIBLINGS
; 
 323     WXDWORD exStyle 
= Determine3DEffects(WS_EX_CLIENTEDGE
, &want3D
); 
 325     // Even with extended styles, need to combine with WS_BORDER 
 326     // for them to look right. 
 327     if ( want3D 
|| (m_windowStyle 
& wxSIMPLE_BORDER
) || (m_windowStyle 
& wxRAISED_BORDER 
) || 
 328         (m_windowStyle 
& wxSUNKEN_BORDER
) || (m_windowStyle 
& wxDOUBLE_BORDER
)) 
 330         msflags 
|= WS_BORDER
; 
 333     // calculate the value to return from WM_GETDLGCODE handler 
 334     if ( GetWindowStyleFlag() & wxWANTS_CHARS 
) 
 336         // want everything: i.e. all keys and WM_CHAR message 
 337         m_lDlgCode 
= DLGC_WANTARROWS 
| DLGC_WANTCHARS 
| 
 338                      DLGC_WANTTAB 
| DLGC_WANTMESSAGE
; 
 341     MSWCreate(m_windowId
, parent
, wxCanvasClassName
, this, NULL
, 
 343               WidthDefault(size
.x
), HeightDefault(size
.y
), 
 344               msflags
, NULL
, exStyle
); 
 349 // --------------------------------------------------------------------------- 
 351 // --------------------------------------------------------------------------- 
 353 void wxWindow::SetFocus() 
 355     HWND hWnd 
= GetHwnd(); 
 360 // Get the window with the focus 
 361 wxWindow 
*wxWindowBase::FindFocus() 
 363     HWND hWnd 
= ::GetFocus(); 
 366         return wxFindWinFromHandle((WXHWND
) hWnd
); 
 372 bool wxWindow::Enable(bool enable
) 
 374     if ( !wxWindowBase::Enable(enable
) ) 
 377     HWND hWnd 
= GetHwnd(); 
 379         ::EnableWindow(hWnd
, (BOOL
)enable
); 
 381     // VZ: no, this is a bad idea: imagine that you have a dialog with some 
 382     //     disabled controls and disable it - you really wouldn't like the 
 383     //     disabled controls eb reenabled too when you reenable the dialog! 
 385     wxWindowList::Node 
*node 
= GetChildren().GetFirst(); 
 388         wxWindow 
*child 
= node
->GetData(); 
 389         child
->Enable(enable
); 
 391         node 
= node
->GetNext(); 
 398 bool wxWindow::Show(bool show
) 
 400     if ( !wxWindowBase::Show(show
) ) 
 403     HWND hWnd 
= GetHwnd(); 
 404     int cshow 
= show 
? SW_SHOW 
: SW_HIDE
; 
 405     ::ShowWindow(hWnd
, cshow
); 
 409         BringWindowToTop(hWnd
); 
 415 // Raise the window to the top of the Z order 
 416 void wxWindow::Raise() 
 418     ::BringWindowToTop(GetHwnd()); 
 421 // Lower the window to the bottom of the Z order 
 422 void wxWindow::Lower() 
 424     ::SetWindowPos(GetHwnd(), HWND_BOTTOM
, 0, 0, 0, 0, 
 425                    SWP_NOMOVE 
| SWP_NOSIZE 
| SWP_NOACTIVATE
); 
 428 void wxWindow::SetTitle( const wxString
& title
) 
 430     SetWindowText(GetHwnd(), title
.c_str()); 
 433 wxString 
wxWindow::GetTitle() const 
 435     return wxGetWindowText(GetHWND()); 
 438 void wxWindow::CaptureMouse() 
 440     HWND hWnd 
= GetHwnd(); 
 441     if ( hWnd 
&& !m_winCaptured 
) 
 444         m_winCaptured 
= TRUE
; 
 448 void wxWindow::ReleaseMouse() 
 453         m_winCaptured 
= FALSE
; 
 457 bool wxWindow::SetFont(const wxFont
& font
) 
 459     if ( !wxWindowBase::SetFont(font
) ) 
 465     HWND hWnd 
= GetHwnd(); 
 468         WXHANDLE hFont 
= m_font
.GetResourceHandle(); 
 470         wxASSERT_MSG( hFont
, wxT("should have valid font") ); 
 472         ::SendMessage(hWnd
, WM_SETFONT
, (WPARAM
)hFont
, MAKELPARAM(TRUE
, 0)); 
 477 bool wxWindow::SetCursor(const wxCursor
& cursor
) 
 479     if ( !wxWindowBase::SetCursor(cursor
) ) 
 487         HWND hWnd 
= GetHwnd(); 
 489         // Change the cursor NOW if we're within the correct window 
 491         ::GetCursorPos(&point
); 
 494         ::GetWindowRect(hWnd
, &rect
); 
 496         if ( ::PtInRect(&rect
, point
) && !wxIsBusy() ) 
 497             ::SetCursor(GetHcursorOf(m_cursor
)); 
 503 void wxWindow::WarpPointer (int x_pos
, int y_pos
) 
 505     // Move the pointer to (x_pos,y_pos) coordinates. They are expressed in 
 506     // pixel coordinates, relatives to the canvas -- So, we first need to 
 507     // substract origin of the window, then convert to screen position 
 509     int x 
= x_pos
; int y 
= y_pos
; 
 511     GetWindowRect (GetHwnd(), &rect
); 
 519 #if WXWIN_COMPATIBILITY 
 520 void wxWindow::MSWDeviceToLogical (float *x
, float *y
) const 
 523 #endif // WXWIN_COMPATIBILITY 
 525 // --------------------------------------------------------------------------- 
 527 // --------------------------------------------------------------------------- 
 529 #if WXWIN_COMPATIBILITY 
 530 void wxWindow::SetScrollRange(int orient
, int range
, bool refresh
) 
 532 #if defined(__WIN95__) 
 536     // Try to adjust the range to cope with page size > 1 
 537     // - a Windows API quirk 
 538     int pageSize 
= GetScrollPage(orient
); 
 539     if ( pageSize 
> 1 && range 
> 0) 
 541         range1 
+= (pageSize 
- 1); 
 547     if ( orient 
== wxHORIZONTAL 
) { 
 553     info
.cbSize 
= sizeof(SCROLLINFO
); 
 554     info
.nPage 
= pageSize
; // Have to set this, or scrollbar goes awry 
 558     info
.fMask 
= SIF_RANGE 
| SIF_PAGE
; 
 560     HWND hWnd 
= GetHwnd(); 
 562         ::SetScrollInfo(hWnd
, dir
, &info
, refresh
); 
 565     if ( orient 
== wxHORIZONTAL 
) 
 570     HWND hWnd 
= GetHwnd(); 
 572         ::SetScrollRange(hWnd
, wOrient
, 0, range
, refresh
); 
 576 void wxWindow::SetScrollPage(int orient
, int page
, bool refresh
) 
 578 #if defined(__WIN95__) 
 582     if ( orient 
== wxHORIZONTAL 
) { 
 590     info
.cbSize 
= sizeof(SCROLLINFO
); 
 593     info
.fMask 
= SIF_PAGE
; 
 595     HWND hWnd 
= GetHwnd(); 
 597         ::SetScrollInfo(hWnd
, dir
, &info
, refresh
); 
 599     if ( orient 
== wxHORIZONTAL 
) 
 606 int wxWindow::OldGetScrollRange(int orient
) const 
 609     if ( orient 
== wxHORIZONTAL 
) 
 614 #if __WATCOMC__ && defined(__WINDOWS_386__) 
 615     short minPos
, maxPos
; 
 619     HWND hWnd 
= GetHwnd(); 
 622         ::GetScrollRange(hWnd
, wOrient
, &minPos
, &maxPos
); 
 623 #if defined(__WIN95__) 
 624         // Try to adjust the range to cope with page size > 1 
 625         // - a Windows API quirk 
 626         int pageSize 
= GetScrollPage(orient
); 
 629             maxPos 
-= (pageSize 
- 1); 
 638 int wxWindow::GetScrollPage(int orient
) const 
 640     if ( orient 
== wxHORIZONTAL 
) 
 646 #endif // WXWIN_COMPATIBILITY 
 648 int wxWindow::GetScrollPos(int orient
) const 
 651     if ( orient 
== wxHORIZONTAL 
) 
 655     HWND hWnd 
= GetHwnd(); 
 658         return ::GetScrollPos(hWnd
, wOrient
); 
 664 // This now returns the whole range, not just the number 
 665 // of positions that we can scroll. 
 666 int wxWindow::GetScrollRange(int orient
) const 
 669     if ( orient 
== wxHORIZONTAL 
) 
 674 #if __WATCOMC__ && defined(__WINDOWS_386__) 
 675     short minPos
, maxPos
; 
 679     HWND hWnd 
= GetHwnd(); 
 682         ::GetScrollRange(hWnd
, wOrient
, &minPos
, &maxPos
); 
 683 #if defined(__WIN95__) 
 684         // Try to adjust the range to cope with page size > 1 
 685         // - a Windows API quirk 
 686         int pageSize 
= GetScrollThumb(orient
); 
 689             maxPos 
-= (pageSize 
- 1); 
 691         // October 10th: new range concept. 
 701 int wxWindow::GetScrollThumb(int orient
) const 
 703     if ( orient 
== wxHORIZONTAL 
) 
 709 void wxWindow::SetScrollPos(int orient
, int pos
, bool refresh
) 
 711 #if defined(__WIN95__) 
 715     if ( orient 
== wxHORIZONTAL 
) { 
 721     info
.cbSize 
= sizeof(SCROLLINFO
); 
 725     info
.fMask 
= SIF_POS
; 
 727     HWND hWnd 
= GetHwnd(); 
 729         ::SetScrollInfo(hWnd
, dir
, &info
, refresh
); 
 732     if ( orient 
== wxHORIZONTAL 
) 
 737     HWND hWnd 
= GetHwnd(); 
 739         ::SetScrollPos(hWnd
, wOrient
, pos
, refresh
); 
 743 // New function that will replace some of the above. 
 744 void wxWindow::SetScrollbar(int orient
, int pos
, int thumbVisible
, 
 745                             int range
, bool refresh
) 
 747 #if defined(__WIN95__) 
 748     int oldRange 
= range 
- thumbVisible
; 
 750     int range1 
= oldRange
; 
 752     // Try to adjust the range to cope with page size > 1 
 753     // - a Windows API quirk 
 754     int pageSize 
= thumbVisible
; 
 755     if ( pageSize 
> 1 && range 
> 0) 
 757         range1 
+= (pageSize 
- 1); 
 763     if ( orient 
== wxHORIZONTAL 
) { 
 769     info
.cbSize 
= sizeof(SCROLLINFO
); 
 770     info
.nPage 
= pageSize
; // Have to set this, or scrollbar goes awry 
 774     info
.fMask 
= SIF_RANGE 
| SIF_PAGE 
| SIF_POS
; 
 776     HWND hWnd 
= GetHwnd(); 
 778         ::SetScrollInfo(hWnd
, dir
, &info
, refresh
); 
 781     if ( orient 
== wxHORIZONTAL 
) 
 786     HWND hWnd 
= GetHwnd(); 
 789         ::SetScrollRange(hWnd
, wOrient
, 0, range
, FALSE
); 
 790         ::SetScrollPos(hWnd
, wOrient
, pos
, refresh
); 
 793     if ( orient 
== wxHORIZONTAL 
) { 
 794         m_xThumbSize 
= thumbVisible
; 
 796         m_yThumbSize 
= thumbVisible
; 
 800 void wxWindow::ScrollWindow(int dx
, int dy
, const wxRect 
*rect
) 
 805         rect2
.left 
= rect
->x
; 
 807         rect2
.right 
= rect
->x 
+ rect
->width
; 
 808         rect2
.bottom 
= rect
->y 
+ rect
->height
; 
 812         ::ScrollWindow(GetHwnd(), dx
, dy
, &rect2
, NULL
); 
 814         ::ScrollWindow(GetHwnd(), dx
, dy
, NULL
, NULL
); 
 817 // --------------------------------------------------------------------------- 
 819 // --------------------------------------------------------------------------- 
 821 void wxWindow::SubclassWin(WXHWND hWnd
) 
 823     wxASSERT_MSG( !m_oldWndProc
, wxT("subclassing window twice?") ); 
 825     HWND hwnd 
= (HWND
)hWnd
; 
 826     wxCHECK_RET( ::IsWindow(hwnd
), wxT("invalid HWND in SubclassWin") ); 
 828     wxAssociateWinWithHandle(hwnd
, this); 
 830     m_oldWndProc 
= (WXFARPROC
) GetWindowLong(hwnd
, GWL_WNDPROC
); 
 831     SetWindowLong(hwnd
, GWL_WNDPROC
, (LONG
) wxWndProc
); 
 834 void wxWindow::UnsubclassWin() 
 836     wxRemoveHandleAssociation(this); 
 838     // Restore old Window proc 
 839     HWND hwnd 
= GetHwnd(); 
 844         wxCHECK_RET( ::IsWindow(hwnd
), wxT("invalid HWND in UnsubclassWin") ); 
 846         FARPROC farProc 
= (FARPROC
) GetWindowLong(hwnd
, GWL_WNDPROC
); 
 847         if ( (m_oldWndProc 
!= 0) && (farProc 
!= (FARPROC
) m_oldWndProc
) ) 
 849             SetWindowLong(hwnd
, GWL_WNDPROC
, (LONG
) m_oldWndProc
); 
 855 // Make a Windows extended style from the given wxWindows window style 
 856 WXDWORD 
wxWindow::MakeExtendedStyle(long style
, bool eliminateBorders
) 
 859     if ( style 
& wxTRANSPARENT_WINDOW 
) 
 860         exStyle 
|= WS_EX_TRANSPARENT
; 
 862     if ( !eliminateBorders 
) 
 864         if ( style 
& wxSUNKEN_BORDER 
) 
 865             exStyle 
|= WS_EX_CLIENTEDGE
; 
 866         if ( style 
& wxDOUBLE_BORDER 
) 
 867             exStyle 
|= WS_EX_DLGMODALFRAME
; 
 868 #if defined(__WIN95__) 
 869         if ( style 
& wxRAISED_BORDER 
) 
 870             exStyle 
|= WS_EX_WINDOWEDGE
; 
 871         if ( style 
& wxSTATIC_BORDER 
) 
 872             exStyle 
|= WS_EX_STATICEDGE
; 
 878 // Determines whether native 3D effects or CTL3D should be used, 
 879 // applying a default border style if required, and returning an extended 
 880 // style to pass to CreateWindowEx. 
 881 WXDWORD 
wxWindow::Determine3DEffects(WXDWORD defaultBorderStyle
, 
 884     // If matches certain criteria, then assume no 3D effects 
 885     // unless specifically requested (dealt with in MakeExtendedStyle) 
 886     if ( !GetParent() || !IsKindOf(CLASSINFO(wxControl
)) || (m_windowStyle 
& wxNO_BORDER
) ) 
 889         return MakeExtendedStyle(m_windowStyle
, FALSE
); 
 892     // Determine whether we should be using 3D effects or not. 
 893     bool nativeBorder 
= FALSE
; // by default, we don't want a Win95 effect 
 895     // 1) App can specify global 3D effects 
 896     *want3D 
= wxTheApp
->GetAuto3D(); 
 898     // 2) If the parent is being drawn with user colours, or simple border specified, 
 899     // switch effects off. TODO: replace wxUSER_COLOURS with wxNO_3D 
 900     if ( GetParent() && (GetParent()->GetWindowStyleFlag() & wxUSER_COLOURS
) || (m_windowStyle 
& wxSIMPLE_BORDER
) ) 
 903     // 3) Control can override this global setting by defining 
 904     // a border style, e.g. wxSUNKEN_BORDER 
 905     if ( m_windowStyle 
& wxSUNKEN_BORDER  
) 
 908     // 4) If it's a special border, CTL3D can't cope so we want a native border 
 909     if ( (m_windowStyle 
& wxDOUBLE_BORDER
) || (m_windowStyle 
& wxRAISED_BORDER
) || 
 910         (m_windowStyle 
& wxSTATIC_BORDER
) ) 
 916     // 5) If this isn't a Win95 app, and we are using CTL3D, remove border 
 917     // effects from extended style 
 920         nativeBorder 
= FALSE
; 
 923     DWORD exStyle 
= MakeExtendedStyle(m_windowStyle
, !nativeBorder
); 
 925     // If we want 3D, but haven't specified a border here, 
 926     // apply the default border style specified. 
 927     // TODO what about non-Win95 WIN32? Does it have borders? 
 928 #if defined(__WIN95__) && !wxUSE_CTL3D 
 929     if ( defaultBorderStyle 
&& (*want3D
) && ! ((m_windowStyle 
& wxDOUBLE_BORDER
) || (m_windowStyle 
& wxRAISED_BORDER 
) || 
 930         (m_windowStyle 
& wxSTATIC_BORDER
) || (m_windowStyle 
& wxSIMPLE_BORDER
) )) 
 931         exStyle 
|= defaultBorderStyle
; // WS_EX_CLIENTEDGE; 
 937 #if WXWIN_COMPATIBILITY 
 938 // If nothing defined for this, try the parent. 
 939 // E.g. we may be a button loaded from a resource, with no callback function 
 941 void wxWindow::OnCommand(wxWindow
& win
, wxCommandEvent
& event
) 
 943     if ( GetEventHandler()->ProcessEvent(event
)  ) 
 946         m_parent
->GetEventHandler()->OnCommand(win
, event
); 
 948 #endif // WXWIN_COMPATIBILITY_2 
 950 #if WXWIN_COMPATIBILITY 
 951 wxObject
* wxWindow::GetChild(int number
) const 
 953     // Return a pointer to the Nth object in the Panel 
 954     wxNode 
*node 
= GetChildren().First(); 
 960         wxObject 
*obj 
= (wxObject 
*)node
->Data(); 
 966 #endif // WXWIN_COMPATIBILITY 
 968 // Setup background and foreground colours correctly 
 969 void wxWindow::SetupColours() 
 972         SetBackgroundColour(GetParent()->GetBackgroundColour()); 
 975 void wxWindow::OnIdle(wxIdleEvent
& event
) 
 977     // Check if we need to send a LEAVE event 
 978     if ( m_mouseInWindow 
) 
 982         if ( ::WindowFromPoint(pt
) != GetHwnd() ) 
 984             // Generate a LEAVE event 
 985             m_mouseInWindow 
= FALSE
; 
 987             // Unfortunately the mouse button and keyboard state may have changed 
 988             // by the time the OnIdle function is called, so 'state' may be 
 991             if ( wxIsShiftDown() ) 
 993             if ( wxIsCtrlDown() ) 
 995             if ( GetKeyState( VK_LBUTTON 
) ) 
 997             if ( GetKeyState( VK_MBUTTON 
) ) 
 999             if ( GetKeyState( VK_RBUTTON 
) ) 
1000                 state 
|= MK_RBUTTON
; 
1002             wxMouseEvent 
event(wxEVT_LEAVE_WINDOW
); 
1003             InitMouseEvent(event
, pt
.x
, pt
.y
, state
); 
1005             (void)GetEventHandler()->ProcessEvent(event
); 
1012 // Set this window to be the child of 'parent'. 
1013 bool wxWindow::Reparent(wxWindow 
*parent
) 
1015     if ( !wxWindowBase::Reparent(parent
) ) 
1018     HWND hWndChild 
= GetHwnd(); 
1019     HWND hWndParent 
= GetParent() ? GetWinHwnd(GetParent()) : (HWND
)0; 
1021     ::SetParent(hWndChild
, hWndParent
); 
1026 void wxWindow::Clear() 
1028     wxClientDC 
dc(this); 
1029     wxBrush 
brush(GetBackgroundColour(), wxSOLID
); 
1030     dc
.SetBackground(brush
); 
1034 void wxWindow::Refresh(bool eraseBack
, const wxRect 
*rect
) 
1036     HWND hWnd 
= GetHwnd(); 
1042             mswRect
.left 
= rect
->x
; 
1043             mswRect
.top 
= rect
->y
; 
1044             mswRect
.right 
= rect
->x 
+ rect
->width
; 
1045             mswRect
.bottom 
= rect
->y 
+ rect
->height
; 
1047             ::InvalidateRect(hWnd
, &mswRect
, eraseBack
); 
1050             ::InvalidateRect(hWnd
, NULL
, eraseBack
); 
1054 // --------------------------------------------------------------------------- 
1056 // --------------------------------------------------------------------------- 
1058 #if wxUSE_DRAG_AND_DROP 
1060 void wxWindow::SetDropTarget(wxDropTarget 
*pDropTarget
) 
1062     if ( m_dropTarget 
!= 0 ) { 
1063         m_dropTarget
->Revoke(m_hWnd
); 
1064         delete m_dropTarget
; 
1067     m_dropTarget 
= pDropTarget
; 
1068     if ( m_dropTarget 
!= 0 ) 
1069         m_dropTarget
->Register(m_hWnd
); 
1072 #endif // wxUSE_DRAG_AND_DROP 
1074 // old style file-manager drag&drop support: we retain the old-style 
1075 // DragAcceptFiles in parallel with SetDropTarget. 
1076 void wxWindow::DragAcceptFiles(bool accept
) 
1078     HWND hWnd 
= GetHwnd(); 
1080         ::DragAcceptFiles(hWnd
, (BOOL
)accept
); 
1083 // ---------------------------------------------------------------------------- 
1085 // ---------------------------------------------------------------------------- 
1089 void wxWindow::DoSetToolTip(wxToolTip 
*tooltip
) 
1091     wxWindowBase::DoSetToolTip(tooltip
); 
1094         m_tooltip
->SetWindow(this); 
1097 #endif // wxUSE_TOOLTIPS 
1099 // --------------------------------------------------------------------------- 
1100 // moving and resizing 
1101 // --------------------------------------------------------------------------- 
1104 void wxWindow::DoGetSize(int *x
, int *y
) const 
1106     HWND hWnd 
= GetHwnd(); 
1109     ::GetWindowRect(hWnd
, &rect
); 
1111     if ( !::GetWindowRect(hWnd
, &rect
) ) 
1113         wxLogLastError(_T("GetWindowRect")); 
1117         *x 
= rect
.right 
- rect
.left
; 
1119         *y 
= rect
.bottom 
- rect
.top
; 
1122 void wxWindow::DoGetPosition(int *x
, int *y
) const 
1124     HWND hWnd 
= GetHwnd(); 
1127     GetWindowRect(hWnd
, &rect
); 
1130     point
.x 
= rect
.left
; 
1133     // we do the adjustments with respect to the parent only for the "real" 
1134     // children, not for the dialogs/frames 
1135     if ( !IsTopLevel() ) 
1137         HWND hParentWnd 
= 0; 
1138         wxWindow 
*parent 
= GetParent(); 
1140             hParentWnd 
= GetWinHwnd(parent
); 
1142         // Since we now have the absolute screen coords, if there's a parent we 
1143         // must subtract its top left corner 
1146             ::ScreenToClient(hParentWnd
, &point
); 
1149         // We may be faking the client origin. So a window that's really at (0, 
1150         // 30) may appear (to wxWin apps) to be at (0, 0). 
1151         wxPoint 
pt(parent
->GetClientAreaOrigin()); 
1162 void wxWindow::DoScreenToClient(int *x
, int *y
) const 
1170     HWND hWnd 
= GetHwnd(); 
1171     ::ScreenToClient(hWnd
, &pt
); 
1179 void wxWindow::DoClientToScreen(int *x
, int *y
) const 
1187     HWND hWnd 
= GetHwnd(); 
1188     ::ClientToScreen(hWnd
, &pt
); 
1196 // Get size *available for subwindows* i.e. excluding menu bar etc. 
1197 void wxWindow::DoGetClientSize(int *x
, int *y
) const 
1199     HWND hWnd 
= GetHwnd(); 
1201     ::GetClientRect(hWnd
, &rect
); 
1208 void wxWindow::DoMoveWindow(int x
, int y
, int width
, int height
) 
1210     if ( !::MoveWindow(GetHwnd(), x
, y
, width
, height
, TRUE
) ) 
1212         wxLogLastError(wxT("MoveWindow")); 
1216 // set the size of the window: if the dimensions are positive, just use them, 
1217 // but if any of them is equal to -1, it means that we must find the value for 
1218 // it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in 
1219 // which case -1 is a valid value for x and y) 
1221 // If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate 
1222 // the width/height to best suit our contents, otherwise we reuse the current 
1224 void wxWindow::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
) 
1226     // get the current size and position... 
1227     int currentX
, currentY
; 
1228     GetPosition(¤tX
, ¤tY
); 
1229     int currentW
,currentH
; 
1230     GetSize(¤tW
, ¤tH
); 
1232     // ... and don't do anything (avoiding flicker) if it's already ok 
1233     if ( x 
== currentX 
&& y 
== currentY 
&& 
1234          width 
== currentW 
&& height 
== currentH 
) 
1239     if ( x 
== -1 && !(sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
) ) 
1241     if ( y 
== -1 && !(sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
) ) 
1244     AdjustForParentClientOrigin(x
, y
, sizeFlags
); 
1246     wxSize 
size(-1, -1); 
1249         if ( sizeFlags 
& wxSIZE_AUTO_WIDTH 
) 
1251             size 
= DoGetBestSize(); 
1256             // just take the current one 
1263         if ( sizeFlags 
& wxSIZE_AUTO_HEIGHT 
) 
1267                 size 
= DoGetBestSize(); 
1269             //else: already called DoGetBestSize() above 
1275             // just take the current one 
1280     DoMoveWindow(x
, y
, width
, height
); 
1283 void wxWindow::DoSetClientSize(int width
, int height
) 
1285     wxWindow 
*parent 
= GetParent(); 
1286     HWND hWnd 
= GetHwnd(); 
1287     HWND hParentWnd 
= (HWND
) 0; 
1289         hParentWnd 
= (HWND
) parent
->GetHWND(); 
1292     ::GetClientRect(hWnd
, &rect
); 
1295     GetWindowRect(hWnd
, &rect2
); 
1297     // Find the difference between the entire window (title bar and all) 
1298     // and the client area; add this to the new client size to move the 
1300     int actual_width 
= rect2
.right 
- rect2
.left 
- rect
.right 
+ width
; 
1301     int actual_height 
= rect2
.bottom 
- rect2
.top 
- rect
.bottom 
+ height
; 
1303     // If there's a parent, must subtract the parent's top left corner 
1304     // since MoveWindow moves relative to the parent 
1307     point
.x 
= rect2
.left
; 
1308     point
.y 
= rect2
.top
; 
1311         ::ScreenToClient(hParentWnd
, &point
); 
1314     DoMoveWindow(point
.x
, point
.y
, actual_width
, actual_height
); 
1316     wxSizeEvent 
event(wxSize(width
, height
), m_windowId
); 
1317     event
.SetEventObject(this); 
1318     GetEventHandler()->ProcessEvent(event
); 
1321 // For implementation purposes - sometimes decorations make the client area 
1323 wxPoint 
wxWindow::GetClientAreaOrigin() const 
1325     return wxPoint(0, 0); 
1328 // Makes an adjustment to the window position (for example, a frame that has 
1329 // a toolbar that it manages itself). 
1330 void wxWindow::AdjustForParentClientOrigin(int& x
, int& y
, int sizeFlags
) 
1332     // don't do it for the dialogs/frames - they float independently of their 
1334     if ( !IsTopLevel() ) 
1336         wxWindow 
*parent 
= GetParent(); 
1337         if ( !(sizeFlags 
& wxSIZE_NO_ADJUSTMENTS
) && parent 
) 
1339             wxPoint 
pt(parent
->GetClientAreaOrigin()); 
1340             x 
+= pt
.x
; y 
+= pt
.y
; 
1345 // --------------------------------------------------------------------------- 
1347 // --------------------------------------------------------------------------- 
1349 int wxWindow::GetCharHeight() const 
1351     return wxGetTextMetrics(this).tmHeight
; 
1354 int wxWindow::GetCharWidth() const 
1356     // +1 is needed because Windows apparently adds it when calculating the 
1357     // dialog units size in pixels 
1358 #if wxDIALOG_UNIT_COMPATIBILITY 
1359     return wxGetTextMetrics(this).tmAveCharWidth 
; 
1361     return wxGetTextMetrics(this).tmAveCharWidth 
+ 1; 
1365 void wxWindow::GetTextExtent(const wxString
& string
, 
1367                              int *descent
, int *externalLeading
, 
1368                              const wxFont 
*theFont
) const 
1370     const wxFont 
*fontToUse 
= theFont
; 
1372         fontToUse 
= &m_font
; 
1374     HWND hWnd 
= GetHwnd(); 
1375     HDC dc 
= ::GetDC(hWnd
); 
1379     if ( fontToUse 
&& fontToUse
->Ok() ) 
1381         fnt 
= (HFONT
)((wxFont 
*)fontToUse
)->GetResourceHandle(); // const_cast 
1383             hfontOld 
= (HFONT
)SelectObject(dc
,fnt
); 
1388     GetTextExtentPoint(dc
, string
, (int)string
.Length(), &sizeRect
); 
1389     GetTextMetrics(dc
, &tm
); 
1391     if ( fontToUse 
&& fnt 
&& hfontOld 
) 
1392         SelectObject(dc
, hfontOld
); 
1394     ReleaseDC(hWnd
, dc
); 
1401         *descent 
= tm
.tmDescent
; 
1402     if ( externalLeading 
) 
1403         *externalLeading 
= tm
.tmExternalLeading
; 
1406 #if wxUSE_CARET && WXWIN_COMPATIBILITY 
1407 // --------------------------------------------------------------------------- 
1408 // Caret manipulation 
1409 // --------------------------------------------------------------------------- 
1411 void wxWindow::CreateCaret(int w
, int h
) 
1413     SetCaret(new wxCaret(this, w
, h
)); 
1416 void wxWindow::CreateCaret(const wxBitmap 
*WXUNUSED(bitmap
)) 
1418     wxFAIL_MSG("not implemented"); 
1421 void wxWindow::ShowCaret(bool show
) 
1423     wxCHECK_RET( m_caret
, "no caret to show" ); 
1425     m_caret
->Show(show
); 
1428 void wxWindow::DestroyCaret() 
1433 void wxWindow::SetCaretPos(int x
, int y
) 
1435     wxCHECK_RET( m_caret
, "no caret to move" ); 
1437     m_caret
->Move(x
, y
); 
1440 void wxWindow::GetCaretPos(int *x
, int *y
) const 
1442     wxCHECK_RET( m_caret
, "no caret to get position of" ); 
1444     m_caret
->GetPosition(x
, y
); 
1446 #endif // wxUSE_CARET 
1448 // --------------------------------------------------------------------------- 
1450 // --------------------------------------------------------------------------- 
1452 bool wxWindow::DoPopupMenu(wxMenu 
*menu
, int x
, int y
) 
1454     menu
->SetInvokingWindow(this); 
1457     HWND hWnd 
= GetHwnd(); 
1458     HMENU hMenu 
= GetHmenuOf(menu
); 
1462     ::ClientToScreen(hWnd
, &point
); 
1463     wxCurrentPopupMenu 
= menu
; 
1464     ::TrackPopupMenu(hMenu
, TPM_RIGHTBUTTON
, point
.x
, point
.y
, 0, hWnd
, NULL
); 
1466     wxCurrentPopupMenu 
= NULL
; 
1468     menu
->SetInvokingWindow(NULL
); 
1473 // =========================================================================== 
1474 // pre/post message processing 
1475 // =========================================================================== 
1477 long wxWindow::MSWDefWindowProc(WXUINT nMsg
, WXWPARAM wParam
, WXLPARAM lParam
) 
1480         return ::CallWindowProc(CASTWNDPROC m_oldWndProc
, GetHwnd(), (UINT
) nMsg
, (WPARAM
) wParam
, (LPARAM
) lParam
); 
1482         return ::DefWindowProc(GetHwnd(), nMsg
, wParam
, lParam
); 
1485 bool wxWindow::MSWProcessMessage(WXMSG
* pMsg
) 
1487     if ( m_hWnd 
!= 0 && (GetWindowStyleFlag() & wxTAB_TRAVERSAL
) ) 
1489         // intercept dialog navigation keys 
1490         MSG 
*msg 
= (MSG 
*)pMsg
; 
1492         // here we try to do all the job which ::IsDialogMessage() usually does 
1495         bool bProcess 
= TRUE
; 
1496         if ( msg
->message 
!= WM_KEYDOWN 
) 
1499         if ( bProcess 
&& (HIWORD(msg
->lParam
) & KF_ALTDOWN
) == KF_ALTDOWN 
) 
1504             bool bCtrlDown 
= wxIsCtrlDown(); 
1505             bool bShiftDown 
= wxIsShiftDown(); 
1507             // WM_GETDLGCODE: ask the control if it wants the key for itself, 
1508             // don't process it if it's the case (except for Ctrl-Tab/Enter 
1509             // combinations which are always processed) 
1513                 lDlgCode 
= ::SendMessage(msg
->hwnd
, WM_GETDLGCODE
, 0, 0); 
1516             bool bForward 
= TRUE
, 
1517                  bWindowChange 
= FALSE
; 
1519             switch ( msg
->wParam 
) 
1522                     // assume that nobody wants Shift-TAB for himself - if we 
1523                     // don't do it there is no easy way for a control to grab 
1524                     // TABs but still let Shift-TAB work as navugation key 
1525                     if ( (lDlgCode 
& DLGC_WANTTAB
) && !bShiftDown 
) { 
1529                         // Ctrl-Tab cycles thru notebook pages 
1530                         bWindowChange 
= bCtrlDown
; 
1531                         bForward 
= !bShiftDown
; 
1537                     if ( (lDlgCode 
& DLGC_WANTARROWS
) || bCtrlDown 
) 
1545                     if ( (lDlgCode 
& DLGC_WANTARROWS
) || bCtrlDown 
) 
1551                         if ( (lDlgCode 
& DLGC_WANTMESSAGE
) && !bCtrlDown 
) 
1553                             // control wants to process Enter itself, don't 
1554                             // call IsDialogMessage() which would interpret 
1558                         else if ( lDlgCode 
& DLGC_BUTTON 
) 
1560                             // buttons want process Enter themselevs 
1565                             wxPanel 
*panel 
= wxDynamicCast(this, wxPanel
); 
1566                             wxButton 
*btn 
= NULL
; 
1569                                 // panel may have a default button which should 
1570                                 // be activated by Enter 
1571                                 btn 
= panel
->GetDefaultItem(); 
1574                             if ( btn 
&& btn
->IsEnabled() ) 
1576                                 // if we do have a default button, do press it 
1577                                 btn
->MSWCommand(BN_CLICKED
, 0 /* unused */); 
1581                             // else: but if it does not it makes sense to make 
1582                             //       it work like a TAB - and that's what we do. 
1583                             //       Note that Ctrl-Enter always works this way. 
1594                 wxNavigationKeyEvent event
; 
1595                 event
.SetDirection(bForward
); 
1596                 event
.SetWindowChange(bWindowChange
); 
1597                 event
.SetEventObject(this); 
1599                 if ( GetEventHandler()->ProcessEvent(event
) ) 
1601                     wxButton 
*btn 
= wxDynamicCast(FindFocus(), wxButton
); 
1604                         // the button which has focus should be default 
1613         // let ::IsDialogMessage() do almost everything and handle just the 
1614         // things it doesn't here: Ctrl-TAB for switching notebook pages 
1615         if ( msg
->message 
== WM_KEYDOWN 
) 
1617             // don't process system keys here 
1618             if ( !(HIWORD(msg
->lParam
) & KF_ALTDOWN
) ) 
1620                 if ( (msg
->wParam 
== VK_TAB
) && wxIsCtrlDown() ) 
1622                     // find the first notebook parent and change its page 
1623                     wxWindow 
*win 
= this; 
1624                     wxNotebook 
*nbook 
= NULL
; 
1625                     while ( win 
&& !nbook 
) 
1627                         nbook 
= wxDynamicCast(win
, wxNotebook
); 
1628                         win 
= win
->GetParent(); 
1633                         bool forward 
= !wxIsShiftDown(); 
1635                         nbook
->AdvanceSelection(forward
); 
1642         if ( ::IsDialogMessage(GetHwnd(), msg
) ) 
1644             // IsDialogMessage() did something... 
1652         // relay mouse move events to the tooltip control 
1653         MSG 
*msg 
= (MSG 
*)pMsg
; 
1654         if ( msg
->message 
== WM_MOUSEMOVE 
) 
1655             m_tooltip
->RelayEvent(pMsg
); 
1657 #endif // wxUSE_TOOLTIPS 
1662 bool wxWindow::MSWTranslateMessage(WXMSG
* pMsg
) 
1664     return m_acceleratorTable
.Translate(this, pMsg
); 
1667 // --------------------------------------------------------------------------- 
1668 // message params unpackers (different for Win16 and Win32) 
1669 // --------------------------------------------------------------------------- 
1673 void wxWindow::UnpackCommand(WXWPARAM wParam
, WXLPARAM lParam
, 
1674                              WORD 
*id
, WXHWND 
*hwnd
, WORD 
*cmd
) 
1676     *id 
= LOWORD(wParam
); 
1677     *hwnd 
= (WXHWND
)lParam
; 
1678     *cmd 
= HIWORD(wParam
); 
1681 void wxWindow::UnpackActivate(WXWPARAM wParam
, WXLPARAM lParam
, 
1682                               WXWORD 
*state
, WXWORD 
*minimized
, WXHWND 
*hwnd
) 
1684     *state 
= LOWORD(wParam
); 
1685     *minimized 
= HIWORD(wParam
); 
1686     *hwnd 
= (WXHWND
)lParam
; 
1689 void wxWindow::UnpackScroll(WXWPARAM wParam
, WXLPARAM lParam
, 
1690                             WXWORD 
*code
, WXWORD 
*pos
, WXHWND 
*hwnd
) 
1692     *code 
= LOWORD(wParam
); 
1693     *pos 
= HIWORD(wParam
); 
1694     *hwnd 
= (WXHWND
)lParam
; 
1697 void wxWindow::UnpackCtlColor(WXWPARAM wParam
, WXLPARAM lParam
, 
1698                               WXWORD 
*nCtlColor
, WXHDC 
*hdc
, WXHWND 
*hwnd
) 
1700     *nCtlColor 
= CTLCOLOR_BTN
; 
1701     *hwnd 
= (WXHWND
)lParam
; 
1702     *hdc 
= (WXHDC
)wParam
; 
1705 void wxWindow::UnpackMenuSelect(WXWPARAM wParam
, WXLPARAM lParam
, 
1706                                 WXWORD 
*item
, WXWORD 
*flags
, WXHMENU 
*hmenu
) 
1708     *item 
= (WXWORD
)wParam
; 
1709     *flags 
= HIWORD(wParam
); 
1710     *hmenu 
= (WXHMENU
)lParam
; 
1715 void wxWindow::UnpackCommand(WXWPARAM wParam
, WXLPARAM lParam
, 
1716                              WXWORD 
*id
, WXHWND 
*hwnd
, WXWORD 
*cmd
) 
1718     *id 
= (WXWORD
)wParam
; 
1719     *hwnd 
= (WXHWND
)LOWORD(lParam
); 
1720     *cmd 
= HIWORD(lParam
); 
1723 void wxWindow::UnpackActivate(WXWPARAM wParam
, WXLPARAM lParam
, 
1724                               WXWORD 
*state
, WXWORD 
*minimized
, WXHWND 
*hwnd
) 
1726     *state 
= (WXWORD
)wParam
; 
1727     *minimized 
= LOWORD(lParam
); 
1728     *hwnd 
= (WXHWND
)HIWORD(lParam
); 
1731 void wxWindow::UnpackScroll(WXWPARAM wParam
, WXLPARAM lParam
, 
1732                             WXWORD 
*code
, WXWORD 
*pos
, WXHWND 
*hwnd
) 
1734     *code 
= (WXWORD
)wParam
; 
1735     *pos 
= LOWORD(lParam
); 
1736     *hwnd 
= (WXHWND
)HIWORD(lParam
); 
1739 void wxWindow::UnpackCtlColor(WXWPARAM wParam
, WXLPARAM lParam
, 
1740                               WXWORD 
*nCtlColor
, WXHDC 
*hdc
, WXHWND 
*hwnd
) 
1742     *hwnd 
= (WXHWND
)LOWORD(lParam
); 
1743     *nCtlColor 
= (int)HIWORD(lParam
); 
1744     *hdc 
= (WXHDC
)wParam
; 
1747 void wxWindow::UnpackMenuSelect(WXWPARAM wParam
, WXLPARAM lParam
, 
1748                                 WXWORD 
*item
, WXWORD 
*flags
, WXHMENU 
*hmenu
) 
1750     *item 
= (WXWORD
)wParam
; 
1751     *flags 
= LOWORD(lParam
); 
1752     *hmenu 
= (WXHMENU
)HIWORD(lParam
); 
1757 // --------------------------------------------------------------------------- 
1758 // Main wxWindows window proc and the window proc for wxWindow 
1759 // --------------------------------------------------------------------------- 
1761 // Hook for new window just as it's being created, when the window isn't yet 
1762 // associated with the handle 
1763 wxWindow 
*wxWndHook 
= NULL
; 
1766 LRESULT WXDLLEXPORT APIENTRY _EXPORT 
wxWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
) 
1768     // trace all messages - useful for the debugging 
1770     wxLogTrace(wxTraceMessages
, wxT("Processing %s(wParam=%8lx, lParam=%8lx)"), 
1771                wxGetMessageName(message
), wParam
, lParam
); 
1772 #endif // __WXDEBUG__ 
1774     wxWindow 
*wnd 
= wxFindWinFromHandle((WXHWND
) hWnd
); 
1776     // when we get the first message for the HWND we just created, we associate 
1777     // it with wxWindow stored in wxWndHook 
1778     if ( !wnd 
&& wxWndHook 
) 
1780 #if 0 // def __WXDEBUG__ 
1782         ::GetClassNameA((HWND
) hWnd
, buf
, 512); 
1783         wxString 
className(buf
); 
1786         wxAssociateWinWithHandle(hWnd
, wxWndHook
); 
1789         wnd
->SetHWND((WXHWND
)hWnd
); 
1794     // Stop right here if we don't have a valid handle in our wxWindow object. 
1795     if ( wnd 
&& !wnd
->GetHWND() ) 
1797         // FIXME: why do we do this? 
1798         wnd
->SetHWND((WXHWND
) hWnd
); 
1799         rc 
= wnd
->MSWDefWindowProc(message
, wParam
, lParam 
); 
1805             rc 
= wnd
->MSWWindowProc(message
, wParam
, lParam
); 
1807             rc 
= DefWindowProc( hWnd
, message
, wParam
, lParam 
); 
1813 long wxWindow::MSWWindowProc(WXUINT message
, WXWPARAM wParam
, WXLPARAM lParam
) 
1815     // did we process the message? 
1816     bool processed 
= FALSE
; 
1827     // for most messages we should return 0 when we do process the message 
1835                 processed 
= HandleCreate((WXLPCREATESTRUCT
)lParam
, &mayCreate
); 
1838                     // return 0 to allow window creation 
1839                     rc
.result 
= mayCreate 
? 0 : -1; 
1845             processed 
= HandleDestroy(); 
1849             processed 
= HandleMove(LOWORD(lParam
), HIWORD(lParam
)); 
1853             processed 
= HandleSize(LOWORD(lParam
), HIWORD(lParam
), wParam
); 
1858                 WXWORD state
, minimized
; 
1860                 UnpackActivate(wParam
, lParam
, &state
, &minimized
, &hwnd
); 
1862                 processed 
= HandleActivate(state
, minimized 
!= 0, (WXHWND
)hwnd
); 
1867             processed 
= HandleSetFocus((WXHWND
)(HWND
)wParam
); 
1871             processed 
= HandleKillFocus((WXHWND
)(HWND
)wParam
); 
1875             processed 
= HandlePaint(); 
1879             // don't let the DefWindowProc() destroy our window - we'll do it 
1880             // ourselves in ~wxWindow 
1886             processed 
= HandleShow(wParam 
!= 0, (int)lParam
); 
1891                 short x 
= LOWORD(lParam
); 
1892                 short y 
= HIWORD(lParam
); 
1894                 processed 
= HandleMouseMove(x
, y
, wParam
); 
1898         case WM_LBUTTONDOWN
: 
1899            // set focus to this window 
1905         case WM_LBUTTONDBLCLK
: 
1906         case WM_RBUTTONDOWN
: 
1908         case WM_RBUTTONDBLCLK
: 
1909         case WM_MBUTTONDOWN
: 
1911         case WM_MBUTTONDBLCLK
: 
1913                 short x 
= LOWORD(lParam
); 
1914                 short y 
= HIWORD(lParam
); 
1916                 processed 
= HandleMouseEvent(message
, x
, y
, wParam
); 
1924         case MM_JOY1BUTTONDOWN
: 
1925         case MM_JOY2BUTTONDOWN
: 
1926         case MM_JOY1BUTTONUP
: 
1927         case MM_JOY2BUTTONUP
: 
1929                 int x 
= LOWORD(lParam
); 
1930                 int y 
= HIWORD(lParam
); 
1932                 processed 
= HandleJoystickEvent(message
, x
, y
, wParam
); 
1937             processed 
= HandleSysCommand(wParam
, lParam
); 
1944                 UnpackCommand(wParam
, lParam
, &id
, &hwnd
, &cmd
); 
1946                 processed 
= HandleCommand(id
, cmd
, hwnd
); 
1952             processed 
= HandleNotify((int)wParam
, lParam
, &rc
.result
); 
1956             // for these messages we must return TRUE if process the message 
1958         case WM_MEASUREITEM
: 
1960                 int idCtrl 
= (UINT
)wParam
; 
1961                 if ( message 
== WM_DRAWITEM 
) 
1963                     processed 
= MSWOnDrawItem(idCtrl
, 
1964                                               (WXDRAWITEMSTRUCT 
*)lParam
); 
1968                     processed 
= MSWOnMeasureItem(idCtrl
, 
1969                                                  (WXMEASUREITEMSTRUCT 
*)lParam
); 
1980                 rc
.result 
= m_lDlgCode
; 
1983             //else: get the dlg code from the DefWindowProc() 
1988             // If this has been processed by an event handler, 
1989             // return 0 now (we've handled it). 
1990             if ( HandleKeyDown((WORD
) wParam
, lParam
) ) 
1997             // we consider these message "not interesting" to OnChar 
1998             if ( wParam 
== VK_SHIFT 
|| wParam 
== VK_CONTROL 
) 
2007                 // avoid duplicate messages to OnChar for these ASCII keys: they 
2008                 // will be translated by TranslateMessage() and received in WM_CHAR 
2016                     // but set processed to FALSE, not TRUE to still pass them to 
2017                     // the control's default window proc - otherwise built-in 
2018                     // keyboard handling won't work 
2024                 // special case of VK_APPS: treat it the same as right mouse 
2025                 // click because both usually pop up a context menu 
2031                         TranslateKbdEventToMouse(this, &x
, &y
, &flags
); 
2032                         processed 
= HandleMouseEvent(WM_RBUTTONDOWN
, x
, y
, flags
); 
2042                     processed 
= HandleChar((WORD
)wParam
, lParam
); 
2049             // special case of VK_APPS: treat it the same as right mouse button 
2050             if ( wParam 
== VK_APPS 
) 
2055                 TranslateKbdEventToMouse(this, &x
, &y
, &flags
); 
2056                 processed 
= HandleMouseEvent(WM_RBUTTONUP
, x
, y
, flags
); 
2061                 processed 
= HandleKeyUp((WORD
) wParam
, lParam
); 
2066         case WM_CHAR
: // Always an ASCII character 
2067             processed 
= HandleChar((WORD
)wParam
, lParam
, TRUE
); 
2075                 UnpackScroll(wParam
, lParam
, &code
, &pos
, &hwnd
); 
2077                 processed 
= MSWOnScroll(message 
== WM_HSCROLL 
? wxHORIZONTAL
 
2083         // CTLCOLOR messages are sent by children to query the parent for their 
2086         case WM_CTLCOLORMSGBOX
: 
2087         case WM_CTLCOLOREDIT
: 
2088         case WM_CTLCOLORLISTBOX
: 
2089         case WM_CTLCOLORBTN
: 
2090         case WM_CTLCOLORDLG
: 
2091         case WM_CTLCOLORSCROLLBAR
: 
2092         case WM_CTLCOLORSTATIC
: 
2100                 UnpackCtlColor(wParam
, lParam
, &nCtlColor
, &hdc
, &hwnd
); 
2102                 processed 
= HandleCtlColor(&rc
.hBrush
, 
2112             // the return value for this message is ignored 
2113         case WM_SYSCOLORCHANGE
: 
2114             processed 
= HandleSysColorChange(); 
2117         case WM_PALETTECHANGED
: 
2118             processed 
= HandlePaletteChanged((WXHWND
) (HWND
) wParam
); 
2121         case WM_QUERYNEWPALETTE
: 
2122             processed 
= HandleQueryNewPalette(); 
2126             processed 
= HandleEraseBkgnd((WXHDC
)(HDC
)wParam
); 
2129                 // we processed the message, i.e. erased the background 
2135             processed 
= HandleDropFiles(wParam
); 
2139             processed 
= HandleInitDialog((WXHWND
)(HWND
)wParam
); 
2143                 // we never set focus from here 
2148         case WM_QUERYENDSESSION
: 
2149             processed 
= HandleQueryEndSession(lParam
, &rc
.allow
); 
2153             processed 
= HandleEndSession(wParam 
!= 0, lParam
); 
2156         case WM_GETMINMAXINFO
: 
2157             processed 
= HandleGetMinMaxInfo((MINMAXINFO
*)lParam
); 
2161             processed 
= HandleSetCursor((WXHWND
)(HWND
)wParam
, 
2162                                         LOWORD(lParam
),     // hit test 
2163                                         HIWORD(lParam
));    // mouse msg 
2167                 // returning TRUE stops the DefWindowProc() from further 
2168                 // processing this message - exactly what we need because we've 
2169                 // just set the cursor. 
2176             HELPINFO
* info 
= (HELPINFO
*) lParam
; 
2177             // Don't yet process menu help events, just windows 
2178             if (info
->iContextType 
== HELPINFO_WINDOW
) 
2180                 wxWindow
* subjectOfHelp 
= this; 
2181                 bool eventProcessed 
= FALSE
; 
2182                 while (subjectOfHelp 
&& !eventProcessed
) 
2184                     wxHelpEvent 
helpEvent(wxEVT_HELP
, subjectOfHelp
->GetId(), wxPoint(info
->MousePos
.x
, info
->MousePos
.y
) ) ; // info->iCtrlId); 
2185                     helpEvent
.SetEventObject(this); 
2186                     eventProcessed 
= GetEventHandler()->ProcessEvent(helpEvent
); 
2188                     // Go up the window hierarchy until the event is handled (or not) 
2189                     subjectOfHelp 
= subjectOfHelp
->GetParent(); 
2191                 processed 
= eventProcessed
; 
2193             else if (info
->iContextType 
== HELPINFO_MENUITEM
) 
2195                 wxHelpEvent 
helpEvent(wxEVT_HELP
, info
->iCtrlId
) ; 
2196                 helpEvent
.SetEventObject(this); 
2197                 processed 
= GetEventHandler()->ProcessEvent(helpEvent
); 
2199             else processed 
= FALSE
; 
2208         wxLogTrace(wxTraceMessages
, wxT("Forwarding %s to DefWindowProc."), 
2209                    wxGetMessageName(message
)); 
2210 #endif // __WXDEBUG__ 
2211         rc
.result 
= MSWDefWindowProc(message
, wParam
, lParam
); 
2217 // Dialog window proc 
2218 LONG APIENTRY _EXPORT
 
2219 wxDlgProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
) 
2221     if ( message 
== WM_INITDIALOG 
) 
2223         // for this message, returning TRUE tells system to set focus to the 
2224         // first control in the dialog box 
2229         // for all the other ones, FALSE means that we didn't process the 
2235 wxList 
*wxWinHandleList 
= NULL
; 
2236 wxWindow 
*wxFindWinFromHandle(WXHWND hWnd
) 
2238     wxNode 
*node 
= wxWinHandleList
->Find((long)hWnd
); 
2241     return (wxWindow 
*)node
->Data(); 
2244 #if 0 // def __WXDEBUG__ 
2245 static int gs_AssociationCount 
= 0; 
2248 void wxAssociateWinWithHandle(HWND hWnd
, wxWindow 
*win
) 
2250     // adding NULL hWnd is (first) surely a result of an error and 
2251     // (secondly) breaks menu command processing 
2252     wxCHECK_RET( hWnd 
!= (HWND
)NULL
, 
2253                  wxT("attempt to add a NULL hWnd to window list ignored") ); 
2256     wxWindow 
*oldWin 
= wxFindWinFromHandle((WXHWND
) hWnd
); 
2257     if ( oldWin 
&& (oldWin 
!= win
) ) 
2259         wxString 
str(win
->GetClassInfo()->GetClassName()); 
2260         wxLogError(wxT("Bug! Found existing HWND %X for new window of class %s"), (int) hWnd
, (const wxChar
*) str
); 
2264 #if 0 // def __WXDEBUG__ 
2265         gs_AssociationCount 
++; 
2266         wxLogDebug("+ Association %d", gs_AssociationCount
); 
2269         wxWinHandleList
->Append((long)hWnd
, win
); 
2273 void wxRemoveHandleAssociation(wxWindow 
*win
) 
2275 #if 0 // def __WXDEBUG__ 
2276     if (wxWinHandleList
->Member(win
)) 
2278         wxLogDebug("- Association %d", gs_AssociationCount
); 
2279         gs_AssociationCount 
--; 
2282     wxWinHandleList
->DeleteObject(win
); 
2285 // Default destroyer - override if you destroy it in some other way 
2286 // (e.g. with MDI child windows) 
2287 void wxWindow::MSWDestroyWindow() 
2291 void wxWindow::MSWDetachWindowMenu() 
2295         HMENU hMenu 
= (HMENU
)m_hMenu
; 
2297         int N 
= ::GetMenuItemCount(hMenu
); 
2299         for (i 
= 0; i 
< N
; i
++) 
2302             int chars 
= GetMenuString(hMenu
, i
, buf
, 100, MF_BYPOSITION
); 
2305                 wxLogLastError(wxT("GetMenuString")); 
2310             if ( wxStrcmp(buf
, wxT("&Window")) == 0 ) 
2312                 RemoveMenu(hMenu
, i
, MF_BYPOSITION
); 
2320 bool wxWindow::MSWCreate(int id
, 
2322                          const wxChar 
*wclass
, 
2324                          const wxChar 
*title
, 
2330                          const wxChar 
*dialog_template
, 
2331                          WXDWORD extendedStyle
) 
2333     int x1 
= CW_USEDEFAULT
; 
2335     int width1 
= CW_USEDEFAULT
; 
2338     // Find parent's size, if it exists, to set up a possible default 
2339     // panel size the size of the parent window 
2343         ::GetClientRect((HWND
) parent
->GetHWND(), &parent_rect
); 
2345         width1 
= parent_rect
.right 
- parent_rect
.left
; 
2346         height1 
= parent_rect
.bottom 
- parent_rect
.top
; 
2349     if ( x 
> -1 ) x1 
= x
; 
2350     if ( y 
> -1 ) y1 
= y
; 
2351     if ( width 
> -1 ) width1 
= width
; 
2352     if ( height 
> -1 ) height1 
= height
; 
2354     // unfortunately, setting WS_EX_CONTROLPARENT only for some windows in the 
2355     // hierarchy with several embedded panels (and not all of them) causes the 
2356     // program to hang during the next call to IsDialogMessage() due to the bug 
2357     // in this function (at least in Windows NT 4.0, it seems to work ok in 
2360     // if we have wxTAB_TRAVERSAL style, we want WS_EX_CONTROLPARENT or 
2361     // IsDialogMessage() won't work for us 
2362     if ( GetWindowStyleFlag() & wxTAB_TRAVERSAL 
) 
2364         extendedStyle 
|= WS_EX_CONTROLPARENT
; 
2368     HWND hParent 
= (HWND
)NULL
; 
2370         hParent 
= (HWND
) parent
->GetHWND(); 
2374     if ( dialog_template 
) 
2376         m_hWnd 
= (WXHWND
)::CreateDialog(wxGetInstance(), 
2379                                         (DLGPROC
)wxDlgProc
); 
2383             wxLogError(_("Can't find dummy dialog template!\nCheck resource include path for finding wx.rc.")); 
2387         if (extendedStyle 
!= 0) 
2389             ::SetWindowLong(GetHwnd(), GWL_EXSTYLE
, extendedStyle
); 
2390             ::SetWindowPos(GetHwnd(), NULL
, 0, 0, 0, 0, 
2391                 SWP_NOSIZE 
| SWP_NOMOVE 
| SWP_NOZORDER 
| SWP_NOACTIVATE
); 
2393 #if defined(__WIN95__) 
2394         // For some reason, the system menu is activated when we use the 
2395         // WS_EX_CONTEXTHELP style, so let's set a reasonable icon 
2396         if (extendedStyle 
& WS_EX_CONTEXTHELP
) 
2398             if (wxTheApp
->GetTopWindow() && (wxTheApp
->GetTopWindow()->IsKindOf(CLASSINFO(wxFrame
)))) 
2400                 wxIcon icon 
= ((wxFrame
*)wxTheApp
->GetTopWindow())->GetIcon(); 
2402                     SendMessage(GetHwnd(), WM_SETICON
, 
2403                         (WPARAM
)TRUE
, (LPARAM
)(HICON
) icon
.GetHICON()); 
2409         // JACS: is the following still necessary? The above seems to work. 
2411         // ::SetWindowLong(GWL_EXSTYLE) doesn't work for the dialogs, so try 
2412         // to take care of (at least some) extended style flags ourselves 
2413         if ( extendedStyle 
& WS_EX_TOPMOST 
) 
2415             if ( !::SetWindowPos(GetHwnd(), HWND_TOPMOST
, 0, 0, 0, 0, 
2416                                  SWP_NOSIZE 
| SWP_NOMOVE
) ) 
2418                 wxLogLastError(wxT("SetWindowPos")); 
2422         // move the dialog to its initial position without forcing repainting 
2423         if ( !::MoveWindow(GetHwnd(), x1
, y1
, width1
, height1
, FALSE
) ) 
2425             wxLogLastError(wxT("MoveWindow")); 
2431         if ( style 
& WS_CHILD 
) 
2434             // all child windows should clip their siblings 
2435             // style |= /* WS_CLIPSIBLINGS */ ; 
2438         wxString 
className(wclass
); 
2439         if ( GetWindowStyleFlag() & wxNO_FULL_REPAINT_ON_RESIZE 
) 
2441             className 
+= wxT("NR"); 
2444         m_hWnd 
= (WXHWND
)CreateWindowEx(extendedStyle
, 
2446                                         title 
? title 
: wxT(""), 
2450                                         hParent
, (HMENU
)controlId
, 
2456             wxLogError(_("Can't create window of class %s!\nPossible Windows 3.x compatibility problem?"), 
2465     wxNode
* node 
= wxWinHandleList
->Member(this); 
2468         HWND hWnd 
= (HWND
) node
->GetKeyInteger(); 
2469         if (hWnd 
!= (HWND
) m_hWnd
) 
2471             wxLogError(wxT("A second HWND association is being added for the same window!")); 
2475     wxAssociateWinWithHandle((HWND
) m_hWnd
, this); 
2480 // =========================================================================== 
2481 // MSW message handlers 
2482 // =========================================================================== 
2484 // --------------------------------------------------------------------------- 
2486 // --------------------------------------------------------------------------- 
2489 // FIXME: VZ: I'm not sure at all that the order of processing is correct 
2490 bool wxWindow::HandleNotify(int idCtrl
, WXLPARAM lParam
, WXLPARAM 
*result
) 
2492     LPNMHDR hdr 
= (LPNMHDR
)lParam
; 
2493     HWND hWnd 
= hdr
->hwndFrom
; 
2494     wxWindow 
*win 
= wxFindWinFromHandle((WXHWND
)hWnd
); 
2496     // is this one of our windows? 
2499         return win
->MSWOnNotify(idCtrl
, lParam
, result
); 
2502     // try all our children 
2503     wxWindowList::Node 
*node 
= GetChildren().GetFirst(); 
2506         wxWindow 
*child 
= node
->GetData(); 
2507         if ( child
->MSWOnNotify(idCtrl
, lParam
, result
) ) 
2512         node 
= node
->GetNext(); 
2515     // finally try this window too (catches toolbar case) 
2516     return MSWOnNotify(idCtrl
, lParam
, result
); 
2519 bool wxWindow::MSWOnNotify(int WXUNUSED(idCtrl
), 
2521                            WXLPARAM
* WXUNUSED(result
)) 
2524     NMHDR
* hdr 
= (NMHDR 
*)lParam
; 
2525     if ( (int)hdr
->code 
== TTN_NEEDTEXT 
&& m_tooltip 
) 
2527         TOOLTIPTEXT 
*ttt 
= (TOOLTIPTEXT 
*)lParam
; 
2528         ttt
->lpszText 
= (wxChar 
*)m_tooltip
->GetTip().c_str(); 
2533 #endif // wxUSE_TOOLTIPS 
2539 // --------------------------------------------------------------------------- 
2540 // end session messages 
2541 // --------------------------------------------------------------------------- 
2543 bool wxWindow::HandleQueryEndSession(long logOff
, bool *mayEnd
) 
2545     wxCloseEvent 
event(wxEVT_QUERY_END_SESSION
, -1); 
2546     event
.SetEventObject(wxTheApp
); 
2547     event
.SetCanVeto(TRUE
); 
2548     event
.SetLoggingOff(logOff 
== (long)ENDSESSION_LOGOFF
); 
2550     bool rc 
= wxTheApp
->ProcessEvent(event
); 
2554         // we may end only if the app didn't veto session closing (double 
2556         *mayEnd 
= !event
.GetVeto(); 
2562 bool wxWindow::HandleEndSession(bool endSession
, long logOff
) 
2564     // do nothing if the session isn't ending 
2568     wxCloseEvent 
event(wxEVT_END_SESSION
, -1); 
2569     event
.SetEventObject(wxTheApp
); 
2570     event
.SetCanVeto(FALSE
); 
2571     event
.SetLoggingOff( (logOff 
== (long)ENDSESSION_LOGOFF
) ); 
2572     if ( (this == wxTheApp
->GetTopWindow()) && // Only send once 
2573         wxTheApp
->ProcessEvent(event
)) 
2579 // --------------------------------------------------------------------------- 
2580 // window creation/destruction 
2581 // --------------------------------------------------------------------------- 
2583 bool wxWindow::HandleCreate(WXLPCREATESTRUCT cs
, bool *mayCreate
) 
2585     // TODO: should generate this event from WM_NCCREATE 
2586     wxWindowCreateEvent 
event(this); 
2587     (void)GetEventHandler()->ProcessEvent(event
); 
2594 bool wxWindow::HandleDestroy() 
2596     wxWindowDestroyEvent 
event(this); 
2597     (void)GetEventHandler()->ProcessEvent(event
); 
2599     // delete our drop target if we've got one 
2600 #if wxUSE_DRAG_AND_DROP 
2601     if ( m_dropTarget 
!= NULL 
) 
2603         m_dropTarget
->Revoke(m_hWnd
); 
2605         delete m_dropTarget
; 
2606         m_dropTarget 
= NULL
; 
2608 #endif // wxUSE_DRAG_AND_DROP 
2610     // WM_DESTROY handled 
2614 // --------------------------------------------------------------------------- 
2616 // --------------------------------------------------------------------------- 
2618 void wxWindow::OnSetFocus(wxFocusEvent
& event
) 
2620     // panel wants to track the window which was the last to have focus in it, 
2621     // so we want to set ourselves as the window which last had focus 
2623     // notice that it's also important to do it upwards the tree becaus 
2624     // otherwise when the top level panel gets focus, it won't set it back to 
2625     // us, but to some other sibling 
2626     wxWindow 
*win 
= this; 
2629         wxWindow 
*parent 
= win
->GetParent(); 
2630         wxPanel 
*panel 
= wxDynamicCast(parent
, wxPanel
); 
2633             panel
->SetLastFocus(win
); 
2639     wxLogTrace(_T("focus"), _T("%s (0x%08x) gets focus"), 
2640                GetClassInfo()->GetClassName(), GetHandle()); 
2645 bool wxWindow::HandleActivate(int state
, 
2646                               bool WXUNUSED(minimized
), 
2647                               WXHWND 
WXUNUSED(activate
)) 
2649     wxActivateEvent 
event(wxEVT_ACTIVATE
, 
2650                           (state 
== WA_ACTIVE
) || (state 
== WA_CLICKACTIVE
), 
2652     event
.SetEventObject(this); 
2654     return GetEventHandler()->ProcessEvent(event
); 
2657 bool wxWindow::HandleSetFocus(WXHWND 
WXUNUSED(hwnd
)) 
2663         m_caret
->OnSetFocus(); 
2665 #endif // wxUSE_CARET 
2667     wxFocusEvent 
event(wxEVT_SET_FOCUS
, m_windowId
); 
2668     event
.SetEventObject(this); 
2670     return GetEventHandler()->ProcessEvent(event
); 
2673 bool wxWindow::HandleKillFocus(WXHWND 
WXUNUSED(hwnd
)) 
2679         m_caret
->OnKillFocus(); 
2681 #endif // wxUSE_CARET 
2683     wxFocusEvent 
event(wxEVT_KILL_FOCUS
, m_windowId
); 
2684     event
.SetEventObject(this); 
2686     return GetEventHandler()->ProcessEvent(event
); 
2689 // --------------------------------------------------------------------------- 
2691 // --------------------------------------------------------------------------- 
2693 bool wxWindow::HandleShow(bool show
, int status
) 
2695     wxShowEvent 
event(GetId(), show
); 
2696     event
.m_eventObject 
= this; 
2698     return GetEventHandler()->ProcessEvent(event
); 
2701 bool wxWindow::HandleInitDialog(WXHWND 
WXUNUSED(hWndFocus
)) 
2703     wxInitDialogEvent 
event(GetId()); 
2704     event
.m_eventObject 
= this; 
2706     return GetEventHandler()->ProcessEvent(event
); 
2709 bool wxWindow::HandleDropFiles(WXWPARAM wParam
) 
2711     HDROP hFilesInfo 
= (HDROP
) wParam
; 
2713     DragQueryPoint(hFilesInfo
, (LPPOINT
) &dropPoint
); 
2715     // Get the total number of files dropped 
2716     WORD gwFilesDropped 
= (WORD
)::DragQueryFile
 
2724     wxString 
*files 
= new wxString
[gwFilesDropped
]; 
2726     for (wIndex
=0; wIndex 
< (int)gwFilesDropped
; wIndex
++) 
2728         DragQueryFile (hFilesInfo
, wIndex
, (LPTSTR
) wxBuffer
, 1000); 
2729         files
[wIndex
] = wxBuffer
; 
2731     DragFinish (hFilesInfo
); 
2733     wxDropFilesEvent 
event(wxEVT_DROP_FILES
, gwFilesDropped
, files
); 
2734     event
.m_eventObject 
= this; 
2735     event
.m_pos
.x 
= dropPoint
.x
; event
.m_pos
.x 
= dropPoint
.y
; 
2737     bool rc 
= GetEventHandler()->ProcessEvent(event
); 
2744 bool wxWindow::HandleSetCursor(WXHWND hWnd
, 
2746                                int WXUNUSED(mouseMsg
)) 
2748     // the logic is as follows: 
2749     // -1. don't set cursor for non client area, including but not limited to 
2750     //     the title bar, scrollbars, &c 
2751     //  0. allow the user to override default behaviour by using EVT_SET_CURSOR 
2752     //  1. if we have the cursor set it unless wxIsBusy() 
2753     //  2. if we're a top level window, set some cursor anyhow 
2754     //  3. if wxIsBusy(), set the busy cursor, otherwise the global one 
2756     if ( nHitTest 
!= HTCLIENT 
) 
2761     HCURSOR hcursor 
= 0; 
2763     // first ask the user code - it may wish to set the cursor in some very 
2764     // specific way (for example, depending on the current position) 
2767     if ( !::GetCursorPos(&pt
) ) 
2769         wxLogLastError(wxT("GetCursorPos")); 
2772     // In WIN16 it doesn't return a value. 
2773     ::GetCursorPos(&pt
); 
2778     ScreenToClient(&x
, &y
); 
2779     wxSetCursorEvent 
event(x
, y
); 
2781     bool processedEvtSetCursor 
= GetEventHandler()->ProcessEvent(event
); 
2782     if ( processedEvtSetCursor 
&& event
.HasCursor() ) 
2784         hcursor 
= GetHcursorOf(event
.GetCursor()); 
2789         bool isBusy 
= wxIsBusy(); 
2791         // the test for processedEvtSetCursor is here to prevent using m_cursor 
2792         // if the user code caught EVT_SET_CURSOR() and returned nothing from 
2793         // it - this is a way to say that our cursor shouldn't be used for this 
2795         if ( !processedEvtSetCursor 
&& m_cursor
.Ok() ) 
2797             hcursor 
= GetHcursorOf(m_cursor
); 
2804                 hcursor 
= wxGetCurrentBusyCursor(); 
2806             else if ( !hcursor 
) 
2808                 const wxCursor 
*cursor 
= wxGetGlobalCursor(); 
2809                 if ( cursor 
&& cursor
->Ok() ) 
2811                     hcursor 
= GetHcursorOf(*cursor
); 
2819         ::SetCursor(hcursor
); 
2821         // cursor set, stop here 
2825     // pass up the window chain 
2829 // --------------------------------------------------------------------------- 
2830 // owner drawn stuff 
2831 // --------------------------------------------------------------------------- 
2833 bool wxWindow::MSWOnDrawItem(int id
, WXDRAWITEMSTRUCT 
*itemStruct
) 
2835 #if wxUSE_OWNER_DRAWN 
2836     // is it a menu item? 
2839         DRAWITEMSTRUCT 
*pDrawStruct 
= (DRAWITEMSTRUCT 
*)itemStruct
; 
2840         wxMenuItem 
*pMenuItem 
= (wxMenuItem 
*)(pDrawStruct
->itemData
); 
2842         wxCHECK( pMenuItem
->IsKindOf(CLASSINFO(wxMenuItem
)), FALSE 
); 
2844         // prepare to call OnDrawItem() 
2846         dc
.SetHDC((WXHDC
)pDrawStruct
->hDC
, FALSE
); 
2847         wxRect 
rect(pDrawStruct
->rcItem
.left
, pDrawStruct
->rcItem
.top
, 
2848                     pDrawStruct
->rcItem
.right 
- pDrawStruct
->rcItem
.left
, 
2849                     pDrawStruct
->rcItem
.bottom 
- pDrawStruct
->rcItem
.top
); 
2851         return pMenuItem
->OnDrawItem
 
2854                             (wxOwnerDrawn::wxODAction
)pDrawStruct
->itemAction
, 
2855                             (wxOwnerDrawn::wxODStatus
)pDrawStruct
->itemState
 
2859     wxWindow 
*item 
= FindItem(id
); 
2860     if ( item 
&& item
->IsKindOf(CLASSINFO(wxControl
)) ) 
2862         return ((wxControl 
*)item
)->MSWOnDraw(itemStruct
); 
2864 #endif // USE_OWNER_DRAWN 
2869 bool wxWindow::MSWOnMeasureItem(int id
, WXMEASUREITEMSTRUCT 
*itemStruct
) 
2871 #if wxUSE_OWNER_DRAWN 
2872     // is it a menu item? 
2875         MEASUREITEMSTRUCT 
*pMeasureStruct 
= (MEASUREITEMSTRUCT 
*)itemStruct
; 
2876         wxMenuItem 
*pMenuItem 
= (wxMenuItem 
*)(pMeasureStruct
->itemData
); 
2878         wxCHECK( pMenuItem
->IsKindOf(CLASSINFO(wxMenuItem
)), FALSE 
); 
2880         return pMenuItem
->OnMeasureItem(&pMeasureStruct
->itemWidth
, 
2881                                         &pMeasureStruct
->itemHeight
); 
2884     wxWindow 
*item 
= FindItem(id
); 
2885     if ( item 
&& item
->IsKindOf(CLASSINFO(wxControl
)) ) 
2887         return ((wxControl 
*)item
)->MSWOnMeasure(itemStruct
); 
2889 #endif  // owner-drawn menus 
2893 // --------------------------------------------------------------------------- 
2894 // colours and palettes 
2895 // --------------------------------------------------------------------------- 
2897 bool wxWindow::HandleSysColorChange() 
2899     wxSysColourChangedEvent event
; 
2900     event
.SetEventObject(this); 
2902     return GetEventHandler()->ProcessEvent(event
); 
2905 bool wxWindow::HandleCtlColor(WXHBRUSH 
*brush
, 
2913     WXHBRUSH hBrush 
= 0; 
2915     if ( nCtlColor 
== CTLCOLOR_DLG 
) 
2917         hBrush 
= OnCtlColor(pDC
, pWnd
, nCtlColor
, message
, wParam
, lParam
); 
2921         wxControl 
*item 
= (wxControl 
*)FindItemByHWND(pWnd
, TRUE
); 
2923             hBrush 
= item
->OnCtlColor(pDC
, pWnd
, nCtlColor
, message
, wParam
, lParam
); 
2932 // Define for each class of dialog and control 
2933 WXHBRUSH 
wxWindow::OnCtlColor(WXHDC hDC
, 
2943 bool wxWindow::HandlePaletteChanged(WXHWND hWndPalChange
) 
2945     wxPaletteChangedEvent 
event(GetId()); 
2946     event
.SetEventObject(this); 
2947     event
.SetChangedWindow(wxFindWinFromHandle(hWndPalChange
)); 
2949     return GetEventHandler()->ProcessEvent(event
); 
2952 bool wxWindow::HandleQueryNewPalette() 
2954     wxQueryNewPaletteEvent 
event(GetId()); 
2955     event
.SetEventObject(this); 
2957     return GetEventHandler()->ProcessEvent(event
) && event
.GetPaletteRealized(); 
2960 // Responds to colour changes: passes event on to children. 
2961 void wxWindow::OnSysColourChanged(wxSysColourChangedEvent
& event
) 
2963     wxNode 
*node 
= GetChildren().First(); 
2966         // Only propagate to non-top-level windows 
2967         wxWindow 
*win 
= (wxWindow 
*)node
->Data(); 
2968         if ( win
->GetParent() ) 
2970             wxSysColourChangedEvent event2
; 
2971             event
.m_eventObject 
= win
; 
2972             win
->GetEventHandler()->ProcessEvent(event2
); 
2975         node 
= node
->Next(); 
2979 // --------------------------------------------------------------------------- 
2981 // --------------------------------------------------------------------------- 
2983 bool wxWindow::HandlePaint() 
2986     HRGN hRegion 
= ::CreateRectRgn(0, 0, 0, 0); // Dummy call to get a handle 
2988         wxLogLastError(wxT("CreateRectRgn")); 
2989     if ( ::GetUpdateRgn(GetHwnd(), hRegion
, FALSE
) == ERROR 
) 
2990         wxLogLastError(wxT("GetUpdateRgn")); 
2992     m_updateRegion 
= wxRegion((WXHRGN
) hRegion
); 
2995     ::GetUpdateRect(GetHwnd(), & updateRect
, FALSE
); 
2997     m_updateRegion 
= wxRegion(updateRect
.left
, updateRect
.top
, 
2998                               updateRect
.right 
- updateRect
.left
, 
2999                               updateRect
.bottom 
- updateRect
.top
); 
3002     wxPaintEvent 
event(m_windowId
); 
3003     event
.SetEventObject(this); 
3005     return GetEventHandler()->ProcessEvent(event
); 
3008 // Can be called from an application's OnPaint handler 
3009 void wxWindow::OnPaint(wxPaintEvent
& event
) 
3011     HDC hDC 
= (HDC
) wxPaintDC::FindDCInCache((wxWindow
*) event
.GetEventObject()); 
3014         MSWDefWindowProc(WM_PAINT
, (WPARAM
) hDC
, 0); 
3018 bool wxWindow::HandleEraseBkgnd(WXHDC hdc
) 
3020     // Prevents flicker when dragging 
3021     if ( ::IsIconic(GetHwnd()) ) 
3030     wxEraseEvent 
event(m_windowId
, &dc
); 
3031     event
.SetEventObject(this); 
3032     bool rc 
= GetEventHandler()->ProcessEvent(event
); 
3035     dc
.SelectOldObjects(hdc
); 
3036     dc
.SetHDC((WXHDC
) NULL
); 
3041 void wxWindow::OnEraseBackground(wxEraseEvent
& event
) 
3044     ::GetClientRect(GetHwnd(), &rect
); 
3046     COLORREF ref 
= PALETTERGB(m_backgroundColour
.Red(), 
3047                               m_backgroundColour
.Green(), 
3048                               m_backgroundColour
.Blue()); 
3049     HBRUSH hBrush 
= ::CreateSolidBrush(ref
); 
3051         wxLogLastError(wxT("CreateSolidBrush")); 
3053     HDC hdc 
= (HDC
)event
.GetDC()->GetHDC(); 
3055     int mode 
= ::SetMapMode(hdc
, MM_TEXT
); 
3057     ::FillRect(hdc
, &rect
, hBrush
); 
3058     ::DeleteObject(hBrush
); 
3059     ::SetMapMode(hdc
, mode
); 
3062 // --------------------------------------------------------------------------- 
3063 // moving and resizing 
3064 // --------------------------------------------------------------------------- 
3066 bool wxWindow::HandleMinimize() 
3068     wxIconizeEvent 
event(m_windowId
); 
3069     event
.SetEventObject(this); 
3071     return GetEventHandler()->ProcessEvent(event
); 
3074 bool wxWindow::HandleMaximize() 
3076     wxMaximizeEvent 
event(m_windowId
); 
3077     event
.SetEventObject(this); 
3079     return GetEventHandler()->ProcessEvent(event
); 
3082 bool wxWindow::HandleMove(int x
, int y
) 
3084     wxMoveEvent 
event(wxPoint(x
, y
), m_windowId
); 
3085     event
.SetEventObject(this); 
3087     return GetEventHandler()->ProcessEvent(event
); 
3090 bool wxWindow::HandleSize(int w
, int h
, WXUINT 
WXUNUSED(flag
)) 
3092     wxSizeEvent 
event(wxSize(w
, h
), m_windowId
); 
3093     event
.SetEventObject(this); 
3095     return GetEventHandler()->ProcessEvent(event
); 
3098 bool wxWindow::HandleGetMinMaxInfo(void *mmInfo
) 
3100     MINMAXINFO 
*info 
= (MINMAXINFO 
*)mmInfo
; 
3104     if ( m_minWidth 
!= -1 ) 
3106         info
->ptMinTrackSize
.x 
= m_minWidth
; 
3110     if ( m_minHeight 
!= -1 ) 
3112         info
->ptMinTrackSize
.y 
= m_minHeight
; 
3116     if ( m_maxWidth 
!= -1 ) 
3118         info
->ptMaxTrackSize
.x 
= m_maxWidth
; 
3122     if ( m_maxHeight 
!= -1 ) 
3124         info
->ptMaxTrackSize
.y 
= m_maxHeight
; 
3131 // generate an artificial resize event 
3132 void wxWindow::SendSizeEvent() 
3136     ::GetWindowRect(GetHwnd(), &r
); 
3138     if ( !::GetWindowRect(GetHwnd(), &r
) ) 
3140         wxLogLastError(_T("GetWindowRect")); 
3144     (void)::PostMessage(GetHwnd(), WM_SIZE
, SIZE_RESTORED
, 
3145                         MAKELPARAM(r
.right 
- r
.left
, r
.bottom 
- r
.top
)); 
3148 // --------------------------------------------------------------------------- 
3150 // --------------------------------------------------------------------------- 
3152 bool wxWindow::HandleCommand(WXWORD id
, WXWORD cmd
, WXHWND control
) 
3154     if ( wxCurrentPopupMenu 
) 
3156         wxMenu 
*popupMenu 
= wxCurrentPopupMenu
; 
3157         wxCurrentPopupMenu 
= NULL
; 
3159         return popupMenu
->MSWCommand(cmd
, id
); 
3162     wxWindow 
*win 
= (wxWindow
*) NULL
; 
3163     if ( cmd 
== 0 || cmd 
== 1 ) // menu or accel - use id 
3165         // must cast to a signed type before comparing with other ids! 
3166         win 
= FindItem((signed short)id
); 
3169     if (!win 
&& control
) 
3171         // find it from HWND - this works even with the broken programs using 
3172         // the same ids for different controls 
3173         win 
= wxFindWinFromHandle(control
); 
3178         return win
->MSWCommand(cmd
, id
); 
3181     // the messages sent from the in-place edit control used by the treectrl 
3182     // for label editing have id == 0, but they should _not_ be treated as menu 
3183     // messages (they are EN_XXX ones, in fact) so don't translate anything 
3184     // coming from a control to wxEVT_COMMAND_MENU_SELECTED 
3187         // If no child window, it may be an accelerator, e.g. for a popup menu 
3190         wxCommandEvent 
event(wxEVT_COMMAND_MENU_SELECTED
); 
3191         event
.SetEventObject(this); 
3195         return GetEventHandler()->ProcessEvent(event
); 
3201 bool wxWindow::HandleSysCommand(WXWPARAM wParam
, WXLPARAM lParam
) 
3203     // 4 bits are reserved 
3204     switch ( wParam 
& 0xFFFFFFF0 ) 
3207             return HandleMaximize(); 
3210             return HandleMinimize(); 
3216 // --------------------------------------------------------------------------- 
3218 // --------------------------------------------------------------------------- 
3220 void wxWindow::InitMouseEvent(wxMouseEvent
& event
, int x
, int y
, WXUINT flags
) 
3224     event
.m_shiftDown 
= ((flags 
& MK_SHIFT
) != 0); 
3225     event
.m_controlDown 
= ((flags 
& MK_CONTROL
) != 0); 
3226     event
.m_leftDown 
= ((flags 
& MK_LBUTTON
) != 0); 
3227     event
.m_middleDown 
= ((flags 
& MK_MBUTTON
) != 0); 
3228     event
.m_rightDown 
= ((flags 
& MK_RBUTTON
) != 0); 
3229     event
.m_altDown 
= (::GetKeyState(VK_MENU
) & 0x80000000) != 0; 
3230     event
.SetTimestamp(s_currentMsg
.time
); 
3231     event
.m_eventObject 
= this; 
3233 #if wxUSE_MOUSEEVENT_HACK 
3236     m_lastMouseEvent 
= event
.GetEventType(); 
3237 #endif // wxUSE_MOUSEEVENT_HACK 
3241 bool wxWindow::HandleMouseEvent(WXUINT msg
, int x
, int y
, WXUINT flags
) 
3243     // the mouse events take consecutive IDs from WM_MOUSEFIRST to 
3244     // WM_MOUSELAST, so it's enough to substract WM_MOUSEMOVE == WM_MOUSEFIRST 
3245     // from the message id and take the value in the table to get wxWin event 
3247     static const wxEventType eventsMouse
[] = 
3261     wxMouseEvent 
event(eventsMouse
[msg 
- WM_MOUSEMOVE
]); 
3262     InitMouseEvent(event
, x
, y
, flags
); 
3264     return GetEventHandler()->ProcessEvent(event
); 
3267 bool wxWindow::HandleMouseMove(int x
, int y
, WXUINT flags
) 
3269     if ( !m_mouseInWindow 
) 
3271         // Generate an ENTER event 
3272         m_mouseInWindow 
= TRUE
; 
3274         wxMouseEvent 
event(wxEVT_ENTER_WINDOW
); 
3275         InitMouseEvent(event
, x
, y
, flags
); 
3277         (void)GetEventHandler()->ProcessEvent(event
); 
3280 #if wxUSE_MOUSEEVENT_HACK 
3281     // Window gets a click down message followed by a mouse move message even 
3282     // if position isn't changed!  We want to discard the trailing move event 
3283     // if x and y are the same. 
3284     if ( (m_lastMouseEvent 
== wxEVT_RIGHT_DOWN 
|| 
3285           m_lastMouseEvent 
== wxEVT_LEFT_DOWN 
|| 
3286           m_lastMouseEvent 
== wxEVT_MIDDLE_DOWN
) && 
3287          (m_lastMouseX 
== event
.m_x 
&& m_lastMouseY 
== event
.m_y
) ) 
3289         m_lastMouseEvent 
= wxEVT_MOTION
; 
3293 #endif // wxUSE_MOUSEEVENT_HACK 
3295     return HandleMouseEvent(WM_MOUSEMOVE
, x
, y
, flags
); 
3298 // --------------------------------------------------------------------------- 
3299 // keyboard handling 
3300 // --------------------------------------------------------------------------- 
3302 // create the key event of the given type for the given key - used by 
3303 // HandleChar and HandleKeyDown/Up 
3304 wxKeyEvent 
wxWindow::CreateKeyEvent(wxEventType evType
, 
3306                                     WXLPARAM lParam
) const 
3308     wxKeyEvent 
event(evType
); 
3309     event
.SetId(GetId()); 
3310     event
.m_shiftDown 
= wxIsShiftDown(); 
3311     event
.m_controlDown 
= wxIsCtrlDown(); 
3312     event
.m_altDown 
= (HIWORD(lParam
) & KF_ALTDOWN
) == KF_ALTDOWN
; 
3314     event
.m_eventObject 
= (wxWindow 
*)this; // const_cast 
3315     event
.m_keyCode 
= id
; 
3316     event
.SetTimestamp(s_currentMsg
.time
); 
3318     // translate the position to client coords 
3322     GetWindowRect(GetHwnd(),&rect
); 
3332 // isASCII is TRUE only when we're called from WM_CHAR handler and not from 
3334 bool wxWindow::HandleChar(WXWORD wParam
, WXLPARAM lParam
, bool isASCII
) 
3336     bool ctrlDown 
= FALSE
; 
3341         // If 1 -> 26, translate to CTRL plus a letter. 
3343         if ( (id 
> 0) && (id 
< 27) ) 
3365     else if ( (id 
= wxCharCodeMSWToWX(wParam
)) == 0 ) 
3367         // it's ASCII and will be processed here only when called from 
3368         // WM_CHAR (i.e. when isASCII = TRUE), don't process it now 
3374         wxKeyEvent 
event(CreateKeyEvent(wxEVT_CHAR
, id
, lParam
)); 
3377             event
.m_controlDown 
= TRUE
; 
3380         if ( GetEventHandler()->ProcessEvent(event
) ) 
3387 bool wxWindow::HandleKeyDown(WXWORD wParam
, WXLPARAM lParam
) 
3389     int id 
= wxCharCodeMSWToWX(wParam
); 
3393         // normal ASCII char 
3397     if ( id 
!= -1 ) // VZ: does this ever happen (FIXME)? 
3399         wxKeyEvent 
event(CreateKeyEvent(wxEVT_KEY_DOWN
, id
, lParam
)); 
3400         if ( GetEventHandler()->ProcessEvent(event
) ) 
3409 bool wxWindow::HandleKeyUp(WXWORD wParam
, WXLPARAM lParam
) 
3411     int id 
= wxCharCodeMSWToWX(wParam
); 
3415         // normal ASCII char 
3419     if ( id 
!= -1 ) // VZ: does this ever happen (FIXME)? 
3421         wxKeyEvent 
event(CreateKeyEvent(wxEVT_KEY_UP
, id
, lParam
)); 
3422         if ( GetEventHandler()->ProcessEvent(event
) ) 
3429 // --------------------------------------------------------------------------- 
3431 // --------------------------------------------------------------------------- 
3433 bool wxWindow::HandleJoystickEvent(WXUINT msg
, int x
, int y
, WXUINT flags
) 
3436     if ( flags 
& JOY_BUTTON1CHG 
) 
3437         change 
= wxJOY_BUTTON1
; 
3438     if ( flags 
& JOY_BUTTON2CHG 
) 
3439         change 
= wxJOY_BUTTON2
; 
3440     if ( flags 
& JOY_BUTTON3CHG 
) 
3441         change 
= wxJOY_BUTTON3
; 
3442     if ( flags 
& JOY_BUTTON4CHG 
) 
3443         change 
= wxJOY_BUTTON4
; 
3446     if ( flags 
& JOY_BUTTON1 
) 
3447         buttons 
|= wxJOY_BUTTON1
; 
3448     if ( flags 
& JOY_BUTTON2 
) 
3449         buttons 
|= wxJOY_BUTTON2
; 
3450     if ( flags 
& JOY_BUTTON3 
) 
3451         buttons 
|= wxJOY_BUTTON3
; 
3452     if ( flags 
& JOY_BUTTON4 
) 
3453         buttons 
|= wxJOY_BUTTON4
; 
3455     // the event ids aren't consecutive so we can't use table based lookup 
3457     wxEventType eventType
; 
3462             eventType 
= wxEVT_JOY_MOVE
; 
3467             eventType 
= wxEVT_JOY_MOVE
; 
3472             eventType 
= wxEVT_JOY_ZMOVE
; 
3477             eventType 
= wxEVT_JOY_ZMOVE
; 
3480         case MM_JOY1BUTTONDOWN
: 
3482             eventType 
= wxEVT_JOY_BUTTON_DOWN
; 
3485         case MM_JOY2BUTTONDOWN
: 
3487             eventType 
= wxEVT_JOY_BUTTON_DOWN
; 
3490         case MM_JOY1BUTTONUP
: 
3492             eventType 
= wxEVT_JOY_BUTTON_UP
; 
3495         case MM_JOY2BUTTONUP
: 
3497             eventType 
= wxEVT_JOY_BUTTON_UP
; 
3501             wxFAIL_MSG(wxT("no such joystick event")); 
3506     wxJoystickEvent 
event(eventType
, buttons
, joystick
, change
); 
3507     event
.SetPosition(wxPoint(x
, y
)); 
3508     event
.SetEventObject(this); 
3510     return GetEventHandler()->ProcessEvent(event
); 
3513 // --------------------------------------------------------------------------- 
3515 // --------------------------------------------------------------------------- 
3517 bool wxWindow::MSWOnScroll(int orientation
, WXWORD wParam
, 
3518                            WXWORD pos
, WXHWND control
) 
3522         wxWindow 
*child 
= wxFindWinFromHandle(control
); 
3524             return child
->MSWOnScroll(orientation
, wParam
, pos
, control
); 
3527     wxScrollWinEvent event
; 
3528     event
.SetPosition(pos
); 
3529     event
.SetOrientation(orientation
); 
3530     event
.m_eventObject 
= this; 
3535         event
.m_eventType 
= wxEVT_SCROLLWIN_TOP
; 
3539         event
.m_eventType 
= wxEVT_SCROLLWIN_BOTTOM
; 
3543         event
.m_eventType 
= wxEVT_SCROLLWIN_LINEUP
; 
3547         event
.m_eventType 
= wxEVT_SCROLLWIN_LINEDOWN
; 
3551         event
.m_eventType 
= wxEVT_SCROLLWIN_PAGEUP
; 
3555         event
.m_eventType 
= wxEVT_SCROLLWIN_PAGEDOWN
; 
3558     case SB_THUMBPOSITION
: 
3561         // under Win32, the scrollbar range and position are 32 bit integers, 
3562         // but WM_[HV]SCROLL only carry the low 16 bits of them, so we must 
3563         // explicitly query the scrollbar for the correct position (this must 
3564         // be done only for these two SB_ events as they are the only one 
3565         // carrying the scrollbar position) 
3567             SCROLLINFO scrollInfo
; 
3568             wxZeroMemory(scrollInfo
); 
3569             scrollInfo
.cbSize 
= sizeof(SCROLLINFO
); 
3570             scrollInfo
.fMask 
= SIF_TRACKPOS
; 
3572             if ( !::GetScrollInfo(GetHwnd(), 
3573                                   orientation 
== wxHORIZONTAL 
? SB_HORZ
 
3577                 wxLogLastError(_T("GetScrollInfo")); 
3580             event
.SetPosition(scrollInfo
.nTrackPos
); 
3584         event
.m_eventType 
= wParam 
== SB_THUMBPOSITION
 
3585                                 ? wxEVT_SCROLLWIN_THUMBRELEASE
 
3586                                 : wxEVT_SCROLLWIN_THUMBTRACK
; 
3593     return GetEventHandler()->ProcessEvent(event
); 
3596 // =========================================================================== 
3598 // =========================================================================== 
3600 void wxGetCharSize(WXHWND wnd
, int *x
, int *y
, const wxFont 
*the_font
) 
3603     HDC dc 
= ::GetDC((HWND
) wnd
); 
3608         //    the_font->UseResource(); 
3609         //    the_font->RealizeResource(); 
3610         fnt 
= (HFONT
)((wxFont 
*)the_font
)->GetResourceHandle(); // const_cast 
3612             was 
= (HFONT
) SelectObject(dc
,fnt
); 
3614     GetTextMetrics(dc
, &tm
); 
3615     if ( the_font 
&& fnt 
&& was 
) 
3617         SelectObject(dc
,was
); 
3619     ReleaseDC((HWND
)wnd
, dc
); 
3622         *x 
= tm
.tmAveCharWidth
; 
3624         *y 
= tm
.tmHeight 
+ tm
.tmExternalLeading
; 
3627     //    the_font->ReleaseResource(); 
3630 // Returns 0 if was a normal ASCII value, not a special key. This indicates that 
3631 // the key should be ignored by WM_KEYDOWN and processed by WM_CHAR instead. 
3632 int wxCharCodeMSWToWX(int keySym
) 
3637         case VK_CANCEL
:     id 
= WXK_CANCEL
; break; 
3638         case VK_BACK
:       id 
= WXK_BACK
; break; 
3639         case VK_TAB
:        id 
= WXK_TAB
; break; 
3640         case VK_CLEAR
:      id 
= WXK_CLEAR
; break; 
3641         case VK_RETURN
:     id 
= WXK_RETURN
; break; 
3642         case VK_SHIFT
:      id 
= WXK_SHIFT
; break; 
3643         case VK_CONTROL
:    id 
= WXK_CONTROL
; break; 
3644         case VK_MENU 
:      id 
= WXK_MENU
; break; 
3645         case VK_PAUSE
:      id 
= WXK_PAUSE
; break; 
3646         case VK_SPACE
:      id 
= WXK_SPACE
; break; 
3647         case VK_ESCAPE
:     id 
= WXK_ESCAPE
; break; 
3648         case VK_PRIOR
:      id 
= WXK_PRIOR
; break; 
3649         case VK_NEXT 
:      id 
= WXK_NEXT
; break; 
3650         case VK_END
:        id 
= WXK_END
; break; 
3651         case VK_HOME 
:      id 
= WXK_HOME
; break; 
3652         case VK_LEFT 
:      id 
= WXK_LEFT
; break; 
3653         case VK_UP
:         id 
= WXK_UP
; break; 
3654         case VK_RIGHT
:      id 
= WXK_RIGHT
; break; 
3655         case VK_DOWN 
:      id 
= WXK_DOWN
; break; 
3656         case VK_SELECT
:     id 
= WXK_SELECT
; break; 
3657         case VK_PRINT
:      id 
= WXK_PRINT
; break; 
3658         case VK_EXECUTE
:    id 
= WXK_EXECUTE
; break; 
3659         case VK_INSERT
:     id 
= WXK_INSERT
; break; 
3660         case VK_DELETE
:     id 
= WXK_DELETE
; break; 
3661         case VK_HELP 
:      id 
= WXK_HELP
; break; 
3662         case VK_NUMPAD0
:    id 
= WXK_NUMPAD0
; break; 
3663         case VK_NUMPAD1
:    id 
= WXK_NUMPAD1
; break; 
3664         case VK_NUMPAD2
:    id 
= WXK_NUMPAD2
; break; 
3665         case VK_NUMPAD3
:    id 
= WXK_NUMPAD3
; break; 
3666         case VK_NUMPAD4
:    id 
= WXK_NUMPAD4
; break; 
3667         case VK_NUMPAD5
:    id 
= WXK_NUMPAD5
; break; 
3668         case VK_NUMPAD6
:    id 
= WXK_NUMPAD6
; break; 
3669         case VK_NUMPAD7
:    id 
= WXK_NUMPAD7
; break; 
3670         case VK_NUMPAD8
:    id 
= WXK_NUMPAD8
; break; 
3671         case VK_NUMPAD9
:    id 
= WXK_NUMPAD9
; break; 
3672         case VK_MULTIPLY
:   id 
= WXK_MULTIPLY
; break; 
3673         case 0xBB: // VK_OEM_PLUS 
3674         case VK_ADD
:        id 
= WXK_ADD
; break; 
3675         case 0xBD: // VK_OEM_MINUS 
3676         case VK_SUBTRACT
:   id 
= WXK_SUBTRACT
; break; 
3677         case 0xBE: // VK_OEM_PERIOD 
3678         case VK_DECIMAL
:    id 
= WXK_DECIMAL
; break; 
3679         case VK_DIVIDE
:     id 
= WXK_DIVIDE
; break; 
3680         case VK_F1
:         id 
= WXK_F1
; break; 
3681         case VK_F2
:         id 
= WXK_F2
; break; 
3682         case VK_F3
:         id 
= WXK_F3
; break; 
3683         case VK_F4
:         id 
= WXK_F4
; break; 
3684         case VK_F5
:         id 
= WXK_F5
; break; 
3685         case VK_F6
:         id 
= WXK_F6
; break; 
3686         case VK_F7
:         id 
= WXK_F7
; break; 
3687         case VK_F8
:         id 
= WXK_F8
; break; 
3688         case VK_F9
:         id 
= WXK_F9
; break; 
3689         case VK_F10
:        id 
= WXK_F10
; break; 
3690         case VK_F11
:        id 
= WXK_F11
; break; 
3691         case VK_F12
:        id 
= WXK_F12
; break; 
3692         case VK_F13
:        id 
= WXK_F13
; break; 
3693         case VK_F14
:        id 
= WXK_F14
; break; 
3694         case VK_F15
:        id 
= WXK_F15
; break; 
3695         case VK_F16
:        id 
= WXK_F16
; break; 
3696         case VK_F17
:        id 
= WXK_F17
; break; 
3697         case VK_F18
:        id 
= WXK_F18
; break; 
3698         case VK_F19
:        id 
= WXK_F19
; break; 
3699         case VK_F20
:        id 
= WXK_F20
; break; 
3700         case VK_F21
:        id 
= WXK_F21
; break; 
3701         case VK_F22
:        id 
= WXK_F22
; break; 
3702         case VK_F23
:        id 
= WXK_F23
; break; 
3703         case VK_F24
:        id 
= WXK_F24
; break; 
3704         case VK_NUMLOCK
:    id 
= WXK_NUMLOCK
; break; 
3705         case VK_SCROLL
:     id 
= WXK_SCROLL
; break; 
3713 int wxCharCodeWXToMSW(int id
, bool *isVirtual
) 
3719     case WXK_CANCEL
:    keySym 
= VK_CANCEL
; break; 
3720     case WXK_CLEAR
:     keySym 
= VK_CLEAR
; break; 
3721     case WXK_SHIFT
:     keySym 
= VK_SHIFT
; break; 
3722     case WXK_CONTROL
:   keySym 
= VK_CONTROL
; break; 
3723     case WXK_MENU 
:     keySym 
= VK_MENU
; break; 
3724     case WXK_PAUSE
:     keySym 
= VK_PAUSE
; break; 
3725     case WXK_PRIOR
:     keySym 
= VK_PRIOR
; break; 
3726     case WXK_NEXT 
:     keySym 
= VK_NEXT
; break; 
3727     case WXK_END
:       keySym 
= VK_END
; break; 
3728     case WXK_HOME 
:     keySym 
= VK_HOME
; break; 
3729     case WXK_LEFT 
:     keySym 
= VK_LEFT
; break; 
3730     case WXK_UP
:        keySym 
= VK_UP
; break; 
3731     case WXK_RIGHT
:     keySym 
= VK_RIGHT
; break; 
3732     case WXK_DOWN 
:     keySym 
= VK_DOWN
; break; 
3733     case WXK_SELECT
:    keySym 
= VK_SELECT
; break; 
3734     case WXK_PRINT
:     keySym 
= VK_PRINT
; break; 
3735     case WXK_EXECUTE
:   keySym 
= VK_EXECUTE
; break; 
3736     case WXK_INSERT
:    keySym 
= VK_INSERT
; break; 
3737     case WXK_DELETE
:    keySym 
= VK_DELETE
; break; 
3738     case WXK_HELP 
:     keySym 
= VK_HELP
; break; 
3739     case WXK_NUMPAD0
:   keySym 
= VK_NUMPAD0
; break; 
3740     case WXK_NUMPAD1
:   keySym 
= VK_NUMPAD1
; break; 
3741     case WXK_NUMPAD2
:   keySym 
= VK_NUMPAD2
; break; 
3742     case WXK_NUMPAD3
:   keySym 
= VK_NUMPAD3
; break; 
3743     case WXK_NUMPAD4
:   keySym 
= VK_NUMPAD4
; break; 
3744     case WXK_NUMPAD5
:   keySym 
= VK_NUMPAD5
; break; 
3745     case WXK_NUMPAD6
:   keySym 
= VK_NUMPAD6
; break; 
3746     case WXK_NUMPAD7
:   keySym 
= VK_NUMPAD7
; break; 
3747     case WXK_NUMPAD8
:   keySym 
= VK_NUMPAD8
; break; 
3748     case WXK_NUMPAD9
:   keySym 
= VK_NUMPAD9
; break; 
3749     case WXK_MULTIPLY
:  keySym 
= VK_MULTIPLY
; break; 
3750     case WXK_ADD
:       keySym 
= VK_ADD
; break; 
3751     case WXK_SUBTRACT
:  keySym 
= VK_SUBTRACT
; break; 
3752     case WXK_DECIMAL
:   keySym 
= VK_DECIMAL
; break; 
3753     case WXK_DIVIDE
:    keySym 
= VK_DIVIDE
; break; 
3754     case WXK_F1
:        keySym 
= VK_F1
; break; 
3755     case WXK_F2
:        keySym 
= VK_F2
; break; 
3756     case WXK_F3
:        keySym 
= VK_F3
; break; 
3757     case WXK_F4
:        keySym 
= VK_F4
; break; 
3758     case WXK_F5
:        keySym 
= VK_F5
; break; 
3759     case WXK_F6
:        keySym 
= VK_F6
; break; 
3760     case WXK_F7
:        keySym 
= VK_F7
; break; 
3761     case WXK_F8
:        keySym 
= VK_F8
; break; 
3762     case WXK_F9
:        keySym 
= VK_F9
; break; 
3763     case WXK_F10
:       keySym 
= VK_F10
; break; 
3764     case WXK_F11
:       keySym 
= VK_F11
; break; 
3765     case WXK_F12
:       keySym 
= VK_F12
; break; 
3766     case WXK_F13
:       keySym 
= VK_F13
; break; 
3767     case WXK_F14
:       keySym 
= VK_F14
; break; 
3768     case WXK_F15
:       keySym 
= VK_F15
; break; 
3769     case WXK_F16
:       keySym 
= VK_F16
; break; 
3770     case WXK_F17
:       keySym 
= VK_F17
; break; 
3771     case WXK_F18
:       keySym 
= VK_F18
; break; 
3772     case WXK_F19
:       keySym 
= VK_F19
; break; 
3773     case WXK_F20
:       keySym 
= VK_F20
; break; 
3774     case WXK_F21
:       keySym 
= VK_F21
; break; 
3775     case WXK_F22
:       keySym 
= VK_F22
; break; 
3776     case WXK_F23
:       keySym 
= VK_F23
; break; 
3777     case WXK_F24
:       keySym 
= VK_F24
; break; 
3778     case WXK_NUMLOCK
:   keySym 
= VK_NUMLOCK
; break; 
3779     case WXK_SCROLL
:    keySym 
= VK_SCROLL
; break; 
3790 wxWindow 
*wxGetActiveWindow() 
3792     HWND hWnd 
= GetActiveWindow(); 
3795         return wxFindWinFromHandle((WXHWND
) hWnd
); 
3800 extern wxWindow 
*wxGetWindowFromHWND(WXHWND hWnd
) 
3802     HWND hwnd 
= (HWND
)hWnd
; 
3804     // For a radiobutton, we get the radiobox from GWL_USERDATA (which is set 
3805     // by code in msw/radiobox.cpp), for all the others we just search up the 
3807     wxWindow 
*win 
= (wxWindow 
*)NULL
; 
3810         win 
= wxFindWinFromHandle((WXHWND
)hwnd
); 
3813             // the radiobox pointer is stored in GWL_USERDATA only under Win32 
3815             // native radiobuttons return DLGC_RADIOBUTTON here and for any 
3816             // wxWindow class which overrides WM_GETDLGCODE processing to 
3817             // do it as well, win would be already non NULL 
3818             if ( ::SendMessage((HWND
)hwnd
, WM_GETDLGCODE
, 
3819                                0, 0) & DLGC_RADIOBUTTON 
) 
3821                 win 
= (wxWindow 
*)::GetWindowLong(hwnd
, GWL_USERDATA
); 
3826                 // hwnd is not a wxWindow, try its parent next below 
3827                 hwnd 
= ::GetParent(hwnd
); 
3830         //else: it's a wxRadioButton, not a radiobutton from wxRadioBox 
3833     while ( hwnd 
&& !win 
) 
3835         win 
= wxFindWinFromHandle((WXHWND
)hwnd
); 
3836         hwnd 
= ::GetParent(hwnd
); 
3842 // Windows keyboard hook. Allows interception of e.g. F1, ESCAPE 
3843 // in active frames and dialogs, regardless of where the focus is. 
3844 static HHOOK wxTheKeyboardHook 
= 0; 
3845 static FARPROC wxTheKeyboardHookProc 
= 0; 
3846 int APIENTRY _EXPORT
 
3847 wxKeyboardHook(int nCode
, WORD wParam
, DWORD lParam
); 
3849 void wxSetKeyboardHook(bool doIt
) 
3853         wxTheKeyboardHookProc 
= MakeProcInstance((FARPROC
) wxKeyboardHook
, wxGetInstance()); 
3854         wxTheKeyboardHook 
= SetWindowsHookEx(WH_KEYBOARD
, (HOOKPROC
) wxTheKeyboardHookProc
, wxGetInstance(), 
3856 #if defined(__WIN32__) && !defined(__TWIN32__) 
3857             GetCurrentThreadId() 
3858         //      (DWORD)GetCurrentProcess()); // This is another possibility. Which is right? 
3866         UnhookWindowsHookEx(wxTheKeyboardHook
); 
3867         // avoids mingw warning about statement with no effect (FreeProcInstance 
3868         // doesn't do anything under Win32) 
3870         FreeProcInstance(wxTheKeyboardHookProc
); 
3875 int APIENTRY _EXPORT
 
3876 wxKeyboardHook(int nCode
, WORD wParam
, DWORD lParam
) 
3878     DWORD hiWord 
= HIWORD(lParam
); 
3879     if ( nCode 
!= HC_NOREMOVE 
&& ((hiWord 
& KF_UP
) == 0) ) 
3881         int id 
= wxCharCodeMSWToWX(wParam
); 
3884             wxKeyEvent 
event(wxEVT_CHAR_HOOK
); 
3885             if ( (HIWORD(lParam
) & KF_ALTDOWN
) == KF_ALTDOWN 
) 
3886                 event
.m_altDown 
= TRUE
; 
3888             event
.m_eventObject 
= NULL
; 
3889             event
.m_keyCode 
= id
; 
3890             event
.m_shiftDown 
= wxIsShiftDown(); 
3891             event
.m_controlDown 
= wxIsCtrlDown(); 
3892             event
.SetTimestamp(s_currentMsg
.time
); 
3894             wxWindow 
*win 
= wxGetActiveWindow(); 
3895             wxEvtHandler 
*handler
; 
3898                 handler 
= win
->GetEventHandler(); 
3899                 event
.SetId(win
->GetId()); 
3907             if ( handler 
&& handler
->ProcessEvent(event
) ) 
3915     return (int)CallNextHookEx(wxTheKeyboardHook
, nCode
, wParam
, lParam
); 
3919 const char *wxGetMessageName(int message
) 
3923         case 0x0000: return "WM_NULL"; 
3924         case 0x0001: return "WM_CREATE"; 
3925         case 0x0002: return "WM_DESTROY"; 
3926         case 0x0003: return "WM_MOVE"; 
3927         case 0x0005: return "WM_SIZE"; 
3928         case 0x0006: return "WM_ACTIVATE"; 
3929         case 0x0007: return "WM_SETFOCUS"; 
3930         case 0x0008: return "WM_KILLFOCUS"; 
3931         case 0x000A: return "WM_ENABLE"; 
3932         case 0x000B: return "WM_SETREDRAW"; 
3933         case 0x000C: return "WM_SETTEXT"; 
3934         case 0x000D: return "WM_GETTEXT"; 
3935         case 0x000E: return "WM_GETTEXTLENGTH"; 
3936         case 0x000F: return "WM_PAINT"; 
3937         case 0x0010: return "WM_CLOSE"; 
3938         case 0x0011: return "WM_QUERYENDSESSION"; 
3939         case 0x0012: return "WM_QUIT"; 
3940         case 0x0013: return "WM_QUERYOPEN"; 
3941         case 0x0014: return "WM_ERASEBKGND"; 
3942         case 0x0015: return "WM_SYSCOLORCHANGE"; 
3943         case 0x0016: return "WM_ENDSESSION"; 
3944         case 0x0017: return "WM_SYSTEMERROR"; 
3945         case 0x0018: return "WM_SHOWWINDOW"; 
3946         case 0x0019: return "WM_CTLCOLOR"; 
3947         case 0x001A: return "WM_WININICHANGE"; 
3948         case 0x001B: return "WM_DEVMODECHANGE"; 
3949         case 0x001C: return "WM_ACTIVATEAPP"; 
3950         case 0x001D: return "WM_FONTCHANGE"; 
3951         case 0x001E: return "WM_TIMECHANGE"; 
3952         case 0x001F: return "WM_CANCELMODE"; 
3953         case 0x0020: return "WM_SETCURSOR"; 
3954         case 0x0021: return "WM_MOUSEACTIVATE"; 
3955         case 0x0022: return "WM_CHILDACTIVATE"; 
3956         case 0x0023: return "WM_QUEUESYNC"; 
3957         case 0x0024: return "WM_GETMINMAXINFO"; 
3958         case 0x0026: return "WM_PAINTICON"; 
3959         case 0x0027: return "WM_ICONERASEBKGND"; 
3960         case 0x0028: return "WM_NEXTDLGCTL"; 
3961         case 0x002A: return "WM_SPOOLERSTATUS"; 
3962         case 0x002B: return "WM_DRAWITEM"; 
3963         case 0x002C: return "WM_MEASUREITEM"; 
3964         case 0x002D: return "WM_DELETEITEM"; 
3965         case 0x002E: return "WM_VKEYTOITEM"; 
3966         case 0x002F: return "WM_CHARTOITEM"; 
3967         case 0x0030: return "WM_SETFONT"; 
3968         case 0x0031: return "WM_GETFONT"; 
3969         case 0x0037: return "WM_QUERYDRAGICON"; 
3970         case 0x0039: return "WM_COMPAREITEM"; 
3971         case 0x0041: return "WM_COMPACTING"; 
3972         case 0x0044: return "WM_COMMNOTIFY"; 
3973         case 0x0046: return "WM_WINDOWPOSCHANGING"; 
3974         case 0x0047: return "WM_WINDOWPOSCHANGED"; 
3975         case 0x0048: return "WM_POWER"; 
3978         case 0x004A: return "WM_COPYDATA"; 
3979         case 0x004B: return "WM_CANCELJOURNAL"; 
3980         case 0x004E: return "WM_NOTIFY"; 
3981         case 0x0050: return "WM_INPUTLANGCHANGEREQUEST"; 
3982         case 0x0051: return "WM_INPUTLANGCHANGE"; 
3983         case 0x0052: return "WM_TCARD"; 
3984         case 0x0053: return "WM_HELP"; 
3985         case 0x0054: return "WM_USERCHANGED"; 
3986         case 0x0055: return "WM_NOTIFYFORMAT"; 
3987         case 0x007B: return "WM_CONTEXTMENU"; 
3988         case 0x007C: return "WM_STYLECHANGING"; 
3989         case 0x007D: return "WM_STYLECHANGED"; 
3990         case 0x007E: return "WM_DISPLAYCHANGE"; 
3991         case 0x007F: return "WM_GETICON"; 
3992         case 0x0080: return "WM_SETICON"; 
3995         case 0x0081: return "WM_NCCREATE"; 
3996         case 0x0082: return "WM_NCDESTROY"; 
3997         case 0x0083: return "WM_NCCALCSIZE"; 
3998         case 0x0084: return "WM_NCHITTEST"; 
3999         case 0x0085: return "WM_NCPAINT"; 
4000         case 0x0086: return "WM_NCACTIVATE"; 
4001         case 0x0087: return "WM_GETDLGCODE"; 
4002         case 0x00A0: return "WM_NCMOUSEMOVE"; 
4003         case 0x00A1: return "WM_NCLBUTTONDOWN"; 
4004         case 0x00A2: return "WM_NCLBUTTONUP"; 
4005         case 0x00A3: return "WM_NCLBUTTONDBLCLK"; 
4006         case 0x00A4: return "WM_NCRBUTTONDOWN"; 
4007         case 0x00A5: return "WM_NCRBUTTONUP"; 
4008         case 0x00A6: return "WM_NCRBUTTONDBLCLK"; 
4009         case 0x00A7: return "WM_NCMBUTTONDOWN"; 
4010         case 0x00A8: return "WM_NCMBUTTONUP"; 
4011         case 0x00A9: return "WM_NCMBUTTONDBLCLK"; 
4012         case 0x0100: return "WM_KEYDOWN"; 
4013         case 0x0101: return "WM_KEYUP"; 
4014         case 0x0102: return "WM_CHAR"; 
4015         case 0x0103: return "WM_DEADCHAR"; 
4016         case 0x0104: return "WM_SYSKEYDOWN"; 
4017         case 0x0105: return "WM_SYSKEYUP"; 
4018         case 0x0106: return "WM_SYSCHAR"; 
4019         case 0x0107: return "WM_SYSDEADCHAR"; 
4020         case 0x0108: return "WM_KEYLAST"; 
4023         case 0x010D: return "WM_IME_STARTCOMPOSITION"; 
4024         case 0x010E: return "WM_IME_ENDCOMPOSITION"; 
4025         case 0x010F: return "WM_IME_COMPOSITION"; 
4028         case 0x0110: return "WM_INITDIALOG"; 
4029         case 0x0111: return "WM_COMMAND"; 
4030         case 0x0112: return "WM_SYSCOMMAND"; 
4031         case 0x0113: return "WM_TIMER"; 
4032         case 0x0114: return "WM_HSCROLL"; 
4033         case 0x0115: return "WM_VSCROLL"; 
4034         case 0x0116: return "WM_INITMENU"; 
4035         case 0x0117: return "WM_INITMENUPOPUP"; 
4036         case 0x011F: return "WM_MENUSELECT"; 
4037         case 0x0120: return "WM_MENUCHAR"; 
4038         case 0x0121: return "WM_ENTERIDLE"; 
4039         case 0x0200: return "WM_MOUSEMOVE"; 
4040         case 0x0201: return "WM_LBUTTONDOWN"; 
4041         case 0x0202: return "WM_LBUTTONUP"; 
4042         case 0x0203: return "WM_LBUTTONDBLCLK"; 
4043         case 0x0204: return "WM_RBUTTONDOWN"; 
4044         case 0x0205: return "WM_RBUTTONUP"; 
4045         case 0x0206: return "WM_RBUTTONDBLCLK"; 
4046         case 0x0207: return "WM_MBUTTONDOWN"; 
4047         case 0x0208: return "WM_MBUTTONUP"; 
4048         case 0x0209: return "WM_MBUTTONDBLCLK"; 
4049         case 0x0210: return "WM_PARENTNOTIFY"; 
4050         case 0x0211: return "WM_ENTERMENULOOP"; 
4051         case 0x0212: return "WM_EXITMENULOOP"; 
4054         case 0x0213: return "WM_NEXTMENU"; 
4055         case 0x0214: return "WM_SIZING"; 
4056         case 0x0215: return "WM_CAPTURECHANGED"; 
4057         case 0x0216: return "WM_MOVING"; 
4058         case 0x0218: return "WM_POWERBROADCAST"; 
4059         case 0x0219: return "WM_DEVICECHANGE"; 
4062         case 0x0220: return "WM_MDICREATE"; 
4063         case 0x0221: return "WM_MDIDESTROY"; 
4064         case 0x0222: return "WM_MDIACTIVATE"; 
4065         case 0x0223: return "WM_MDIRESTORE"; 
4066         case 0x0224: return "WM_MDINEXT"; 
4067         case 0x0225: return "WM_MDIMAXIMIZE"; 
4068         case 0x0226: return "WM_MDITILE"; 
4069         case 0x0227: return "WM_MDICASCADE"; 
4070         case 0x0228: return "WM_MDIICONARRANGE"; 
4071         case 0x0229: return "WM_MDIGETACTIVE"; 
4072         case 0x0230: return "WM_MDISETMENU"; 
4073         case 0x0233: return "WM_DROPFILES"; 
4076         case 0x0281: return "WM_IME_SETCONTEXT"; 
4077         case 0x0282: return "WM_IME_NOTIFY"; 
4078         case 0x0283: return "WM_IME_CONTROL"; 
4079         case 0x0284: return "WM_IME_COMPOSITIONFULL"; 
4080         case 0x0285: return "WM_IME_SELECT"; 
4081         case 0x0286: return "WM_IME_CHAR"; 
4082         case 0x0290: return "WM_IME_KEYDOWN"; 
4083         case 0x0291: return "WM_IME_KEYUP"; 
4086         case 0x0300: return "WM_CUT"; 
4087         case 0x0301: return "WM_COPY"; 
4088         case 0x0302: return "WM_PASTE"; 
4089         case 0x0303: return "WM_CLEAR"; 
4090         case 0x0304: return "WM_UNDO"; 
4091         case 0x0305: return "WM_RENDERFORMAT"; 
4092         case 0x0306: return "WM_RENDERALLFORMATS"; 
4093         case 0x0307: return "WM_DESTROYCLIPBOARD"; 
4094         case 0x0308: return "WM_DRAWCLIPBOARD"; 
4095         case 0x0309: return "WM_PAINTCLIPBOARD"; 
4096         case 0x030A: return "WM_VSCROLLCLIPBOARD"; 
4097         case 0x030B: return "WM_SIZECLIPBOARD"; 
4098         case 0x030C: return "WM_ASKCBFORMATNAME"; 
4099         case 0x030D: return "WM_CHANGECBCHAIN"; 
4100         case 0x030E: return "WM_HSCROLLCLIPBOARD"; 
4101         case 0x030F: return "WM_QUERYNEWPALETTE"; 
4102         case 0x0310: return "WM_PALETTEISCHANGING"; 
4103         case 0x0311: return "WM_PALETTECHANGED"; 
4106         // common controls messages - although they're not strictly speaking 
4107         // standard, it's nice to decode them nevertheless 
4110         case 0x1000 + 0: return "LVM_GETBKCOLOR"; 
4111         case 0x1000 + 1: return "LVM_SETBKCOLOR"; 
4112         case 0x1000 + 2: return "LVM_GETIMAGELIST"; 
4113         case 0x1000 + 3: return "LVM_SETIMAGELIST"; 
4114         case 0x1000 + 4: return "LVM_GETITEMCOUNT"; 
4115         case 0x1000 + 5: return "LVM_GETITEMA"; 
4116         case 0x1000 + 75: return "LVM_GETITEMW"; 
4117         case 0x1000 + 6: return "LVM_SETITEMA"; 
4118         case 0x1000 + 76: return "LVM_SETITEMW"; 
4119         case 0x1000 + 7: return "LVM_INSERTITEMA"; 
4120         case 0x1000 + 77: return "LVM_INSERTITEMW"; 
4121         case 0x1000 + 8: return "LVM_DELETEITEM"; 
4122         case 0x1000 + 9: return "LVM_DELETEALLITEMS"; 
4123         case 0x1000 + 10: return "LVM_GETCALLBACKMASK"; 
4124         case 0x1000 + 11: return "LVM_SETCALLBACKMASK"; 
4125         case 0x1000 + 12: return "LVM_GETNEXTITEM"; 
4126         case 0x1000 + 13: return "LVM_FINDITEMA"; 
4127         case 0x1000 + 83: return "LVM_FINDITEMW"; 
4128         case 0x1000 + 14: return "LVM_GETITEMRECT"; 
4129         case 0x1000 + 15: return "LVM_SETITEMPOSITION"; 
4130         case 0x1000 + 16: return "LVM_GETITEMPOSITION"; 
4131         case 0x1000 + 17: return "LVM_GETSTRINGWIDTHA"; 
4132         case 0x1000 + 87: return "LVM_GETSTRINGWIDTHW"; 
4133         case 0x1000 + 18: return "LVM_HITTEST"; 
4134         case 0x1000 + 19: return "LVM_ENSUREVISIBLE"; 
4135         case 0x1000 + 20: return "LVM_SCROLL"; 
4136         case 0x1000 + 21: return "LVM_REDRAWITEMS"; 
4137         case 0x1000 + 22: return "LVM_ARRANGE"; 
4138         case 0x1000 + 23: return "LVM_EDITLABELA"; 
4139         case 0x1000 + 118: return "LVM_EDITLABELW"; 
4140         case 0x1000 + 24: return "LVM_GETEDITCONTROL"; 
4141         case 0x1000 + 25: return "LVM_GETCOLUMNA"; 
4142         case 0x1000 + 95: return "LVM_GETCOLUMNW"; 
4143         case 0x1000 + 26: return "LVM_SETCOLUMNA"; 
4144         case 0x1000 + 96: return "LVM_SETCOLUMNW"; 
4145         case 0x1000 + 27: return "LVM_INSERTCOLUMNA"; 
4146         case 0x1000 + 97: return "LVM_INSERTCOLUMNW"; 
4147         case 0x1000 + 28: return "LVM_DELETECOLUMN"; 
4148         case 0x1000 + 29: return "LVM_GETCOLUMNWIDTH"; 
4149         case 0x1000 + 30: return "LVM_SETCOLUMNWIDTH"; 
4150         case 0x1000 + 31: return "LVM_GETHEADER"; 
4151         case 0x1000 + 33: return "LVM_CREATEDRAGIMAGE"; 
4152         case 0x1000 + 34: return "LVM_GETVIEWRECT"; 
4153         case 0x1000 + 35: return "LVM_GETTEXTCOLOR"; 
4154         case 0x1000 + 36: return "LVM_SETTEXTCOLOR"; 
4155         case 0x1000 + 37: return "LVM_GETTEXTBKCOLOR"; 
4156         case 0x1000 + 38: return "LVM_SETTEXTBKCOLOR"; 
4157         case 0x1000 + 39: return "LVM_GETTOPINDEX"; 
4158         case 0x1000 + 40: return "LVM_GETCOUNTPERPAGE"; 
4159         case 0x1000 + 41: return "LVM_GETORIGIN"; 
4160         case 0x1000 + 42: return "LVM_UPDATE"; 
4161         case 0x1000 + 43: return "LVM_SETITEMSTATE"; 
4162         case 0x1000 + 44: return "LVM_GETITEMSTATE"; 
4163         case 0x1000 + 45: return "LVM_GETITEMTEXTA"; 
4164         case 0x1000 + 115: return "LVM_GETITEMTEXTW"; 
4165         case 0x1000 + 46: return "LVM_SETITEMTEXTA"; 
4166         case 0x1000 + 116: return "LVM_SETITEMTEXTW"; 
4167         case 0x1000 + 47: return "LVM_SETITEMCOUNT"; 
4168         case 0x1000 + 48: return "LVM_SORTITEMS"; 
4169         case 0x1000 + 49: return "LVM_SETITEMPOSITION32"; 
4170         case 0x1000 + 50: return "LVM_GETSELECTEDCOUNT"; 
4171         case 0x1000 + 51: return "LVM_GETITEMSPACING"; 
4172         case 0x1000 + 52: return "LVM_GETISEARCHSTRINGA"; 
4173         case 0x1000 + 117: return "LVM_GETISEARCHSTRINGW"; 
4174         case 0x1000 + 53: return "LVM_SETICONSPACING"; 
4175         case 0x1000 + 54: return "LVM_SETEXTENDEDLISTVIEWSTYLE"; 
4176         case 0x1000 + 55: return "LVM_GETEXTENDEDLISTVIEWSTYLE"; 
4177         case 0x1000 + 56: return "LVM_GETSUBITEMRECT"; 
4178         case 0x1000 + 57: return "LVM_SUBITEMHITTEST"; 
4179         case 0x1000 + 58: return "LVM_SETCOLUMNORDERARRAY"; 
4180         case 0x1000 + 59: return "LVM_GETCOLUMNORDERARRAY"; 
4181         case 0x1000 + 60: return "LVM_SETHOTITEM"; 
4182         case 0x1000 + 61: return "LVM_GETHOTITEM"; 
4183         case 0x1000 + 62: return "LVM_SETHOTCURSOR"; 
4184         case 0x1000 + 63: return "LVM_GETHOTCURSOR"; 
4185         case 0x1000 + 64: return "LVM_APPROXIMATEVIEWRECT"; 
4186         case 0x1000 + 65: return "LVM_SETWORKAREA"; 
4189         case 0x1100 + 0: return "TVM_INSERTITEMA"; 
4190         case 0x1100 + 50: return "TVM_INSERTITEMW"; 
4191         case 0x1100 + 1: return "TVM_DELETEITEM"; 
4192         case 0x1100 + 2: return "TVM_EXPAND"; 
4193         case 0x1100 + 4: return "TVM_GETITEMRECT"; 
4194         case 0x1100 + 5: return "TVM_GETCOUNT"; 
4195         case 0x1100 + 6: return "TVM_GETINDENT"; 
4196         case 0x1100 + 7: return "TVM_SETINDENT"; 
4197         case 0x1100 + 8: return "TVM_GETIMAGELIST"; 
4198         case 0x1100 + 9: return "TVM_SETIMAGELIST"; 
4199         case 0x1100 + 10: return "TVM_GETNEXTITEM"; 
4200         case 0x1100 + 11: return "TVM_SELECTITEM"; 
4201         case 0x1100 + 12: return "TVM_GETITEMA"; 
4202         case 0x1100 + 62: return "TVM_GETITEMW"; 
4203         case 0x1100 + 13: return "TVM_SETITEMA"; 
4204         case 0x1100 + 63: return "TVM_SETITEMW"; 
4205         case 0x1100 + 14: return "TVM_EDITLABELA"; 
4206         case 0x1100 + 65: return "TVM_EDITLABELW"; 
4207         case 0x1100 + 15: return "TVM_GETEDITCONTROL"; 
4208         case 0x1100 + 16: return "TVM_GETVISIBLECOUNT"; 
4209         case 0x1100 + 17: return "TVM_HITTEST"; 
4210         case 0x1100 + 18: return "TVM_CREATEDRAGIMAGE"; 
4211         case 0x1100 + 19: return "TVM_SORTCHILDREN"; 
4212         case 0x1100 + 20: return "TVM_ENSUREVISIBLE"; 
4213         case 0x1100 + 21: return "TVM_SORTCHILDRENCB"; 
4214         case 0x1100 + 22: return "TVM_ENDEDITLABELNOW"; 
4215         case 0x1100 + 23: return "TVM_GETISEARCHSTRINGA"; 
4216         case 0x1100 + 64: return "TVM_GETISEARCHSTRINGW"; 
4217         case 0x1100 + 24: return "TVM_SETTOOLTIPS"; 
4218         case 0x1100 + 25: return "TVM_GETTOOLTIPS"; 
4221         case 0x1200 + 0: return "HDM_GETITEMCOUNT"; 
4222         case 0x1200 + 1: return "HDM_INSERTITEMA"; 
4223         case 0x1200 + 10: return "HDM_INSERTITEMW"; 
4224         case 0x1200 + 2: return "HDM_DELETEITEM"; 
4225         case 0x1200 + 3: return "HDM_GETITEMA"; 
4226         case 0x1200 + 11: return "HDM_GETITEMW"; 
4227         case 0x1200 + 4: return "HDM_SETITEMA"; 
4228         case 0x1200 + 12: return "HDM_SETITEMW"; 
4229         case 0x1200 + 5: return "HDM_LAYOUT"; 
4230         case 0x1200 + 6: return "HDM_HITTEST"; 
4231         case 0x1200 + 7: return "HDM_GETITEMRECT"; 
4232         case 0x1200 + 8: return "HDM_SETIMAGELIST"; 
4233         case 0x1200 + 9: return "HDM_GETIMAGELIST"; 
4234         case 0x1200 + 15: return "HDM_ORDERTOINDEX"; 
4235         case 0x1200 + 16: return "HDM_CREATEDRAGIMAGE"; 
4236         case 0x1200 + 17: return "HDM_GETORDERARRAY"; 
4237         case 0x1200 + 18: return "HDM_SETORDERARRAY"; 
4238         case 0x1200 + 19: return "HDM_SETHOTDIVIDER"; 
4241         case 0x1300 + 2: return "TCM_GETIMAGELIST"; 
4242         case 0x1300 + 3: return "TCM_SETIMAGELIST"; 
4243         case 0x1300 + 4: return "TCM_GETITEMCOUNT"; 
4244         case 0x1300 + 5: return "TCM_GETITEMA"; 
4245         case 0x1300 + 60: return "TCM_GETITEMW"; 
4246         case 0x1300 + 6: return "TCM_SETITEMA"; 
4247         case 0x1300 + 61: return "TCM_SETITEMW"; 
4248         case 0x1300 + 7: return "TCM_INSERTITEMA"; 
4249         case 0x1300 + 62: return "TCM_INSERTITEMW"; 
4250         case 0x1300 + 8: return "TCM_DELETEITEM"; 
4251         case 0x1300 + 9: return "TCM_DELETEALLITEMS"; 
4252         case 0x1300 + 10: return "TCM_GETITEMRECT"; 
4253         case 0x1300 + 11: return "TCM_GETCURSEL"; 
4254         case 0x1300 + 12: return "TCM_SETCURSEL"; 
4255         case 0x1300 + 13: return "TCM_HITTEST"; 
4256         case 0x1300 + 14: return "TCM_SETITEMEXTRA"; 
4257         case 0x1300 + 40: return "TCM_ADJUSTRECT"; 
4258         case 0x1300 + 41: return "TCM_SETITEMSIZE"; 
4259         case 0x1300 + 42: return "TCM_REMOVEIMAGE"; 
4260         case 0x1300 + 43: return "TCM_SETPADDING"; 
4261         case 0x1300 + 44: return "TCM_GETROWCOUNT"; 
4262         case 0x1300 + 45: return "TCM_GETTOOLTIPS"; 
4263         case 0x1300 + 46: return "TCM_SETTOOLTIPS"; 
4264         case 0x1300 + 47: return "TCM_GETCURFOCUS"; 
4265         case 0x1300 + 48: return "TCM_SETCURFOCUS"; 
4266         case 0x1300 + 49: return "TCM_SETMINTABWIDTH"; 
4267         case 0x1300 + 50: return "TCM_DESELECTALL"; 
4270         case WM_USER
+1: return "TB_ENABLEBUTTON"; 
4271         case WM_USER
+2: return "TB_CHECKBUTTON"; 
4272         case WM_USER
+3: return "TB_PRESSBUTTON"; 
4273         case WM_USER
+4: return "TB_HIDEBUTTON"; 
4274         case WM_USER
+5: return "TB_INDETERMINATE"; 
4275         case WM_USER
+9: return "TB_ISBUTTONENABLED"; 
4276         case WM_USER
+10: return "TB_ISBUTTONCHECKED"; 
4277         case WM_USER
+11: return "TB_ISBUTTONPRESSED"; 
4278         case WM_USER
+12: return "TB_ISBUTTONHIDDEN"; 
4279         case WM_USER
+13: return "TB_ISBUTTONINDETERMINATE"; 
4280         case WM_USER
+17: return "TB_SETSTATE"; 
4281         case WM_USER
+18: return "TB_GETSTATE"; 
4282         case WM_USER
+19: return "TB_ADDBITMAP"; 
4283         case WM_USER
+20: return "TB_ADDBUTTONS"; 
4284         case WM_USER
+21: return "TB_INSERTBUTTON"; 
4285         case WM_USER
+22: return "TB_DELETEBUTTON"; 
4286         case WM_USER
+23: return "TB_GETBUTTON"; 
4287         case WM_USER
+24: return "TB_BUTTONCOUNT"; 
4288         case WM_USER
+25: return "TB_COMMANDTOINDEX"; 
4289         case WM_USER
+26: return "TB_SAVERESTOREA"; 
4290         case WM_USER
+76: return "TB_SAVERESTOREW"; 
4291         case WM_USER
+27: return "TB_CUSTOMIZE"; 
4292         case WM_USER
+28: return "TB_ADDSTRINGA"; 
4293         case WM_USER
+77: return "TB_ADDSTRINGW"; 
4294         case WM_USER
+29: return "TB_GETITEMRECT"; 
4295         case WM_USER
+30: return "TB_BUTTONSTRUCTSIZE"; 
4296         case WM_USER
+31: return "TB_SETBUTTONSIZE"; 
4297         case WM_USER
+32: return "TB_SETBITMAPSIZE"; 
4298         case WM_USER
+33: return "TB_AUTOSIZE"; 
4299         case WM_USER
+35: return "TB_GETTOOLTIPS"; 
4300         case WM_USER
+36: return "TB_SETTOOLTIPS"; 
4301         case WM_USER
+37: return "TB_SETPARENT"; 
4302         case WM_USER
+39: return "TB_SETROWS"; 
4303         case WM_USER
+40: return "TB_GETROWS"; 
4304         case WM_USER
+42: return "TB_SETCMDID"; 
4305         case WM_USER
+43: return "TB_CHANGEBITMAP"; 
4306         case WM_USER
+44: return "TB_GETBITMAP"; 
4307         case WM_USER
+45: return "TB_GETBUTTONTEXTA"; 
4308         case WM_USER
+75: return "TB_GETBUTTONTEXTW"; 
4309         case WM_USER
+46: return "TB_REPLACEBITMAP"; 
4310         case WM_USER
+47: return "TB_SETINDENT"; 
4311         case WM_USER
+48: return "TB_SETIMAGELIST"; 
4312         case WM_USER
+49: return "TB_GETIMAGELIST"; 
4313         case WM_USER
+50: return "TB_LOADIMAGES"; 
4314         case WM_USER
+51: return "TB_GETRECT"; 
4315         case WM_USER
+52: return "TB_SETHOTIMAGELIST"; 
4316         case WM_USER
+53: return "TB_GETHOTIMAGELIST"; 
4317         case WM_USER
+54: return "TB_SETDISABLEDIMAGELIST"; 
4318         case WM_USER
+55: return "TB_GETDISABLEDIMAGELIST"; 
4319         case WM_USER
+56: return "TB_SETSTYLE"; 
4320         case WM_USER
+57: return "TB_GETSTYLE"; 
4321         case WM_USER
+58: return "TB_GETBUTTONSIZE"; 
4322         case WM_USER
+59: return "TB_SETBUTTONWIDTH"; 
4323         case WM_USER
+60: return "TB_SETMAXTEXTROWS"; 
4324         case WM_USER
+61: return "TB_GETTEXTROWS"; 
4325         case WM_USER
+41: return "TB_GETBITMAPFLAGS"; 
4330             static char s_szBuf
[128]; 
4331             sprintf(s_szBuf
, "<unknown message = %d>", message
); 
4335 #endif //__WXDEBUG__ 
4337 static void TranslateKbdEventToMouse(wxWindow 
*win
, int *x
, int *y
, WPARAM 
*flags
) 
4339     // construct the key mask 
4340     WPARAM
& fwKeys 
= *flags
; 
4342     fwKeys 
= MK_RBUTTON
; 
4343     if ( wxIsCtrlDown() ) 
4344         fwKeys 
|= MK_CONTROL
; 
4345     if ( wxIsShiftDown() ) 
4348     // simulate right mouse button click 
4349     DWORD dwPos 
= ::GetMessagePos(); 
4350     *x 
= GET_X_LPARAM(dwPos
); 
4351     *y 
= GET_Y_LPARAM(dwPos
); 
4353     win
->ScreenToClient(x
, y
); 
4356 static TEXTMETRIC 
wxGetTextMetrics(const wxWindow 
*win
) 
4360     HWND hwnd 
= GetHwndOf(win
); 
4361     HDC hdc 
= ::GetDC(hwnd
); 
4363 #if !wxDIALOG_UNIT_COMPATIBILITY 
4364     // and select the current font into it 
4365     HFONT hfont 
= GetHfontOf(win
->GetFont()); 
4368         hfont 
= (HFONT
)::SelectObject(hdc
, hfont
); 
4372     // finally retrieve the text metrics from it 
4373     GetTextMetrics(hdc
, &tm
); 
4375 #if !wxDIALOG_UNIT_COMPATIBILITY 
4379         (void)::SelectObject(hdc
, hfont
); 
4383     ::ReleaseDC(hwnd
, hdc
); 
4388 // Find the wxWindow at the current mouse position, returning the mouse 
4390 wxWindow
* wxFindWindowAtPointer(wxPoint
& pt
) 
4392     // Use current message to find last mouse position 
4393     extern MSG s_currentMsg
; 
4394     HWND hWndHit 
= ::WindowFromPoint(s_currentMsg
.pt
); 
4396     wxWindow
* win 
= wxFindWinFromHandle((WXHWND
) hWndHit
) ; 
4397     HWND hWnd 
= hWndHit
; 
4399     // Try to find a window with a wxWindow associated with it 
4400     while (!win 
&& (hWnd 
!= 0)) 
4402         hWnd 
= ::GetParent(hWnd
); 
4403         win 
= wxFindWinFromHandle((WXHWND
) hWnd
) ; 
4408 // Get the current mouse position. 
4409 wxPoint 
wxGetMousePosition() 
4411     extern MSG s_currentMsg
; 
4412     return wxPoint(s_currentMsg
.pt
.x
, s_currentMsg
.pt
.y
);