1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/windows.cpp
4 // Author: Julian Smart
5 // Modified by: VZ on 13.05.99: no more Default(), MSWOnXXX() reorganisation
8 // Copyright: (c) Julian Smart 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"
42 #include "wx/layout.h"
43 #include "wx/dialog.h"
45 #include "wx/listbox.h"
46 #include "wx/button.h"
47 #include "wx/msgdlg.h"
48 #include "wx/settings.h"
49 #include "wx/statbox.h"
53 #include "wx/ownerdrw.h"
56 #if wxUSE_DRAG_AND_DROP
60 #include "wx/menuitem.h"
63 #include "wx/msw/private.h"
66 #include "wx/tooltip.h"
74 #include "wx/spinctrl.h"
75 #endif // wxUSE_SPINCTRL
80 #include "wx/textctrl.h"
81 #include "wx/notebook.h"
85 #if (!defined(__GNUWIN32_OLD__) && !defined(__WXMICROWIN__)) || defined(__CYGWIN10__)
94 #if (!defined(__GNUWIN32_OLD__) && !defined(__TWIN32__) && !defined(__WXMICROWIN__)) || defined(__CYGWIN10__)
98 #elif !defined(__WXMICROWIN__) // broken compiler
100 #include "wx/msw/gnuwin32/extra.h"
104 // This didn't appear in mingw until 2.95.2
106 #define SIF_TRACKPOS 16
110 #ifndef WM_MOUSEWHEEL
111 #define WM_MOUSEWHEEL 0x020A
114 #define WHEEL_DELTA 120
116 #ifndef SPI_GETWHEELSCROLLLINES
117 #define SPI_GETWHEELSCROLLLINES 104
121 // ---------------------------------------------------------------------------
123 // ---------------------------------------------------------------------------
125 // the last Windows message we got (MT-UNSAFE)
126 extern MSG s_currentMsg
;
128 #if wxUSE_MENUS_NATIVE
129 wxMenu
*wxCurrentPopupMenu
= NULL
;
130 #endif // wxUSE_MENUS_NATIVE
132 extern const wxChar
*wxCanvasClassName
;
134 // ---------------------------------------------------------------------------
136 // ---------------------------------------------------------------------------
138 // the window proc for all our windows
139 LRESULT WXDLLEXPORT APIENTRY _EXPORT
wxWndProc(HWND hWnd
, UINT message
,
140 WPARAM wParam
, LPARAM lParam
);
143 const char *wxGetMessageName(int message
);
146 void wxRemoveHandleAssociation(wxWindowMSW
*win
);
147 void wxAssociateWinWithHandle(HWND hWnd
, wxWindowMSW
*win
);
148 wxWindow
*wxFindWinFromHandle(WXHWND hWnd
);
150 // this magical function is used to translate VK_APPS key presses to right
152 static void TranslateKbdEventToMouse(wxWindowMSW
*win
,
153 int *x
, int *y
, WPARAM
*flags
);
155 // get the text metrics for the current font
156 static TEXTMETRIC
wxGetTextMetrics(const wxWindowMSW
*win
);
158 // wrapper around BringWindowToTop() API
159 static inline void wxBringWindowToTop(HWND hwnd
)
161 #ifdef __WXMICROWIN__
162 // It seems that MicroWindows brings the _parent_ of the window to the top,
163 // which can be the wrong one.
165 // activate (set focus to) specified window
168 // raise top level parent to top of z order
169 ::SetWindowPos(hwnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
);
170 #else // !__WXMICROWIN__
171 if ( !::BringWindowToTop(hwnd
) )
173 wxLogLastError(_T("BringWindowToTop"));
175 #endif // __WXMICROWIN__/!__WXMICROWIN__
178 // ---------------------------------------------------------------------------
180 // ---------------------------------------------------------------------------
182 // in wxUniv/MSW this class is abstract because it doesn't have DoPopupMenu()
184 #ifdef __WXUNIVERSAL__
185 IMPLEMENT_ABSTRACT_CLASS(wxWindowMSW
, wxWindowBase
)
187 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
)
188 #endif // __WXUNIVERSAL__/__WXMSW__
190 BEGIN_EVENT_TABLE(wxWindowMSW
, wxWindowBase
)
191 EVT_ERASE_BACKGROUND(wxWindowMSW::OnEraseBackground
)
192 EVT_SYS_COLOUR_CHANGED(wxWindowMSW::OnSysColourChanged
)
193 EVT_INIT_DIALOG(wxWindowMSW::OnInitDialog
)
194 EVT_IDLE(wxWindowMSW::OnIdle
)
197 // ===========================================================================
199 // ===========================================================================
201 // ---------------------------------------------------------------------------
202 // wxWindow utility functions
203 // ---------------------------------------------------------------------------
205 // Find an item given the MS Windows id
206 wxWindow
*wxWindowMSW::FindItem(long id
) const
209 wxControl
*item
= wxDynamicCastThis(wxControl
);
212 // is it we or one of our "internal" children?
213 if ( item
->GetId() == id
214 #ifndef __WXUNIVERSAL__
215 || (item
->GetSubcontrols().Index(id
) != wxNOT_FOUND
)
216 #endif // __WXUNIVERSAL__
222 #endif // wxUSE_CONTROLS
224 wxWindowList::Node
*current
= GetChildren().GetFirst();
227 wxWindow
*childWin
= current
->GetData();
229 wxWindow
*wnd
= childWin
->FindItem(id
);
233 current
= current
->GetNext();
239 // Find an item given the MS Windows handle
240 wxWindow
*wxWindowMSW::FindItemByHWND(WXHWND hWnd
, bool controlOnly
) const
242 wxWindowList::Node
*current
= GetChildren().GetFirst();
245 wxWindow
*parent
= current
->GetData();
247 // Do a recursive search.
248 wxWindow
*wnd
= parent
->FindItemByHWND(hWnd
);
254 || parent
->IsKindOf(CLASSINFO(wxControl
))
255 #endif // wxUSE_CONTROLS
258 wxWindow
*item
= current
->GetData();
259 if ( item
->GetHWND() == hWnd
)
263 if ( item
->ContainsHWND(hWnd
) )
268 current
= current
->GetNext();
273 // Default command handler
274 bool wxWindowMSW::MSWCommand(WXUINT
WXUNUSED(param
), WXWORD
WXUNUSED(id
))
279 // ----------------------------------------------------------------------------
280 // constructors and such
281 // ----------------------------------------------------------------------------
283 void wxWindowMSW::Init()
289 m_doubleClickAllowed
= 0;
291 m_isBeingDeleted
= FALSE
;
294 m_mouseInWindow
= FALSE
;
301 // pass WM_GETDLGCODE to DefWindowProc()
306 m_backgroundTransparent
= FALSE
;
308 // as all windows are created with WS_VISIBLE style...
311 #if wxUSE_MOUSEEVENT_HACK
314 m_lastMouseEvent
= -1;
315 #endif // wxUSE_MOUSEEVENT_HACK
319 wxWindowMSW::~wxWindowMSW()
321 m_isBeingDeleted
= TRUE
;
323 MSWDetachWindowMenu();
325 #ifndef __WXUNIVERSAL__
326 // VS: make sure there's no wxFrame with last focus set to us:
327 for ( wxWindow
*win
= GetParent(); win
; win
= win
->GetParent() )
329 wxFrame
*frame
= wxDynamicCast(win
, wxFrame
);
332 if ( frame
->GetLastFocus() == this )
334 frame
->SetLastFocus((wxWindow
*)NULL
);
339 #endif // __WXUNIVERSAL__
341 // VS: destroy children first and _then_ detach *this from its parent.
342 // If we'd do it the other way around, children wouldn't be able
343 // find their parent frame (see above).
347 m_parent
->RemoveChild(this);
351 // VZ: test temp removed to understand what really happens here
352 //if (::IsWindow(GetHwnd()))
354 if ( !::DestroyWindow(GetHwnd()) )
355 wxLogLastError(wxT("DestroyWindow"));
358 // remove hWnd <-> wxWindow association
359 wxRemoveHandleAssociation(this);
363 // real construction (Init() must have been called before!)
364 bool wxWindowMSW::Create(wxWindow
*parent
,
369 const wxString
& name
)
371 wxCHECK_MSG( parent
, FALSE
, wxT("can't create wxWindow without parent") );
374 // wxGTK doesn't allow to create controls with static box as the parent so
375 // this will result in a crash when the program is ported to wxGTK - warn
378 // the correct solution is to create the controls as siblings of the
380 wxASSERT_MSG( !wxDynamicCastThis(wxStaticBox
),
381 _T("wxStaticBox can't be used as a window parent!") );
382 #endif // wxUSE_STATBOX
384 if ( !CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
) )
387 parent
->AddChild(this);
389 // all windows are created visible
390 DWORD msflags
= WS_CHILD
| WS_VISIBLE
;
392 #ifdef __WXUNIVERSAL__
393 // no 3d effects, we draw them ourselves
395 #else // !wxUniversal
396 if ( style
& wxCLIP_CHILDREN
)
397 msflags
|= WS_CLIPCHILDREN
;
398 if ( style
& wxCLIP_SIBLINGS
)
399 msflags
|= WS_CLIPSIBLINGS
;
402 WXDWORD exStyle
= Determine3DEffects(WS_EX_CLIENTEDGE
, &want3D
);
404 // Even with extended styles, need to combine with WS_BORDER
405 // for them to look right.
407 (m_windowStyle
& (wxBORDER
|
413 msflags
|= WS_BORDER
;
416 // calculate the value to return from WM_GETDLGCODE handler
417 if ( GetWindowStyleFlag() & wxWANTS_CHARS
)
419 // want everything: i.e. all keys and WM_CHAR message
420 m_lDlgCode
= DLGC_WANTARROWS
| DLGC_WANTCHARS
|
421 DLGC_WANTTAB
| DLGC_WANTMESSAGE
;
423 #endif // wxUniversal/!wxUniversal
425 if ( style
& wxPOPUP_WINDOW
)
427 // a popup window floats on top of everything
428 exStyle
|= WS_EX_TOPMOST
| WS_EX_TOOLWINDOW
;
430 // it is also created hidden as other top level windows
431 msflags
&= ~WS_VISIBLE
;
435 return MSWCreate(wxCanvasClassName
, NULL
, pos
, size
, msflags
, exStyle
);
438 // ---------------------------------------------------------------------------
440 // ---------------------------------------------------------------------------
442 void wxWindowMSW::SetFocus()
444 HWND hWnd
= GetHwnd();
445 wxCHECK_RET( hWnd
, _T("can't set focus to invalid window") );
447 #ifndef __WXMICROWIN__
451 if ( !::SetFocus(hWnd
) )
453 // was there really an error?
454 #ifndef __WXMICROWIN__
455 DWORD dwRes
= ::GetLastError();
462 wxLogApiError(_T("SetFocus"), dwRes
);
465 // VZ: just why does this happen sometimes?? any idea?
467 HWND hwndFocus
= ::GetFocus();
468 wxASSERT_MSG( hwndFocus
== hWnd
, _T("SetFocus() didn't work?") );
473 // Get the window with the focus
474 wxWindow
*wxWindowBase::FindFocus()
476 HWND hWnd
= ::GetFocus();
479 return wxGetWindowFromHWND((WXHWND
)hWnd
);
485 bool wxWindowMSW::Enable(bool enable
)
487 if ( !wxWindowBase::Enable(enable
) )
490 HWND hWnd
= GetHwnd();
492 ::EnableWindow(hWnd
, (BOOL
)enable
);
494 // VZ: no, this is a bad idea: imagine that you have a dialog with some
495 // disabled controls and disable it - you really wouldn't like the
496 // disabled controls be reenabled too when you reenable the dialog!
498 wxWindowList::Node
*node
= GetChildren().GetFirst();
501 wxWindow
*child
= node
->GetData();
502 child
->Enable(enable
);
504 node
= node
->GetNext();
511 bool wxWindowMSW::Show(bool show
)
513 if ( !wxWindowBase::Show(show
) )
516 HWND hWnd
= GetHwnd();
517 int cshow
= show
? SW_SHOW
: SW_HIDE
;
518 ::ShowWindow(hWnd
, cshow
);
522 wxBringWindowToTop(hWnd
);
528 // Raise the window to the top of the Z order
529 void wxWindowMSW::Raise()
531 wxBringWindowToTop(GetHwnd());
534 // Lower the window to the bottom of the Z order
535 void wxWindowMSW::Lower()
537 ::SetWindowPos(GetHwnd(), HWND_BOTTOM
, 0, 0, 0, 0,
538 SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOACTIVATE
);
541 void wxWindowMSW::SetTitle( const wxString
& title
)
543 SetWindowText(GetHwnd(), title
.c_str());
546 wxString
wxWindowMSW::GetTitle() const
548 return wxGetWindowText(GetHWND());
551 void wxWindowMSW::CaptureMouse()
553 HWND hWnd
= GetHwnd();
560 void wxWindowMSW::ReleaseMouse()
562 if ( !::ReleaseCapture() )
564 wxLogLastError(_T("ReleaseCapture"));
568 /* static */ wxWindow
*wxWindowBase::GetCapture()
570 HWND hwnd
= ::GetCapture();
571 return hwnd
? wxFindWinFromHandle((WXHWND
)hwnd
) : (wxWindow
*)NULL
;
574 bool wxWindowMSW::SetFont(const wxFont
& font
)
576 if ( !wxWindowBase::SetFont(font
) )
582 HWND hWnd
= GetHwnd();
585 WXHANDLE hFont
= m_font
.GetResourceHandle();
587 wxASSERT_MSG( hFont
, wxT("should have valid font") );
589 ::SendMessage(hWnd
, WM_SETFONT
, (WPARAM
)hFont
, MAKELPARAM(TRUE
, 0));
594 bool wxWindowMSW::SetCursor(const wxCursor
& cursor
)
596 if ( !wxWindowBase::SetCursor(cursor
) )
604 HWND hWnd
= GetHwnd();
606 // Change the cursor NOW if we're within the correct window
608 ::GetCursorPos(&point
);
610 RECT rect
= wxGetWindowRect(hWnd
);
612 if ( ::PtInRect(&rect
, point
) && !wxIsBusy() )
613 ::SetCursor(GetHcursorOf(m_cursor
));
619 void wxWindowMSW::WarpPointer (int x
, int y
)
621 ClientToScreen(&x
, &y
);
623 if ( !::SetCursorPos(x
, y
) )
625 wxLogLastError(_T("SetCursorPos"));
629 #if WXWIN_COMPATIBILITY
630 void wxWindowMSW::MSWDeviceToLogical (float *x
, float *y
) const
633 #endif // WXWIN_COMPATIBILITY
635 // ---------------------------------------------------------------------------
637 // ---------------------------------------------------------------------------
639 #if WXWIN_COMPATIBILITY
640 void wxWindowMSW::SetScrollRange(int orient
, int range
, bool refresh
)
642 #if defined(__WIN95__)
646 // Try to adjust the range to cope with page size > 1
647 // - a Windows API quirk
648 int pageSize
= GetScrollPage(orient
);
649 if ( pageSize
> 1 && range
> 0)
651 range1
+= (pageSize
- 1);
657 if ( orient
== wxHORIZONTAL
) {
663 info
.cbSize
= sizeof(SCROLLINFO
);
664 info
.nPage
= pageSize
; // Have to set this, or scrollbar goes awry
668 info
.fMask
= SIF_RANGE
| SIF_PAGE
;
670 HWND hWnd
= GetHwnd();
672 ::SetScrollInfo(hWnd
, dir
, &info
, refresh
);
675 if ( orient
== wxHORIZONTAL
)
680 HWND hWnd
= GetHwnd();
682 ::SetScrollRange(hWnd
, wOrient
, 0, range
, refresh
);
686 void wxWindowMSW::SetScrollPage(int orient
, int page
, bool refresh
)
688 #if defined(__WIN95__)
692 if ( orient
== wxHORIZONTAL
) {
700 info
.cbSize
= sizeof(SCROLLINFO
);
703 info
.fMask
= SIF_PAGE
;
705 HWND hWnd
= GetHwnd();
707 ::SetScrollInfo(hWnd
, dir
, &info
, refresh
);
709 if ( orient
== wxHORIZONTAL
)
716 int wxWindowMSW::OldGetScrollRange(int orient
) const
719 if ( orient
== wxHORIZONTAL
)
724 #if __WATCOMC__ && defined(__WINDOWS_386__)
725 short minPos
, maxPos
;
729 HWND hWnd
= GetHwnd();
732 ::GetScrollRange(hWnd
, wOrient
, &minPos
, &maxPos
);
733 #if defined(__WIN95__)
734 // Try to adjust the range to cope with page size > 1
735 // - a Windows API quirk
736 int pageSize
= GetScrollPage(orient
);
739 maxPos
-= (pageSize
- 1);
748 int wxWindowMSW::GetScrollPage(int orient
) const
750 if ( orient
== wxHORIZONTAL
)
756 #endif // WXWIN_COMPATIBILITY
758 inline int GetScrollPosition(HWND hWnd
, int wOrient
)
760 #ifdef __WXMICROWIN__
761 return ::GetScrollPosWX(hWnd
, wOrient
);
763 return ::GetScrollPos(hWnd
, wOrient
);
767 int wxWindowMSW::GetScrollPos(int orient
) const
770 if ( orient
== wxHORIZONTAL
)
775 HWND hWnd
= GetHwnd();
776 wxCHECK_MSG( hWnd
, 0, _T("no HWND in GetScrollPos") );
778 return GetScrollPosition(hWnd
, wOrient
);
781 // This now returns the whole range, not just the number
782 // of positions that we can scroll.
783 int wxWindowMSW::GetScrollRange(int orient
) const
786 if ( orient
== wxHORIZONTAL
)
791 #if __WATCOMC__ && defined(__WINDOWS_386__)
792 short minPos
, maxPos
;
796 HWND hWnd
= GetHwnd();
799 ::GetScrollRange(hWnd
, wOrient
, &minPos
, &maxPos
);
800 #if defined(__WIN95__)
801 // Try to adjust the range to cope with page size > 1
802 // - a Windows API quirk
803 int pageSize
= GetScrollThumb(orient
);
806 maxPos
-= (pageSize
- 1);
808 // October 10th: new range concept.
818 int wxWindowMSW::GetScrollThumb(int orient
) const
820 if ( orient
== wxHORIZONTAL
)
826 void wxWindowMSW::SetScrollPos(int orient
, int pos
, bool refresh
)
828 HWND hWnd
= GetHwnd();
829 wxCHECK_RET( hWnd
, _T("SetScrollPos: no HWND") );
831 int dir
= orient
== wxHORIZONTAL
? SB_HORZ
: SB_VERT
;
833 #if defined(__WIN95__)
835 info
.cbSize
= sizeof(SCROLLINFO
);
839 info
.fMask
= SIF_POS
;
841 ::SetScrollInfo(hWnd
, dir
, &info
, refresh
);
843 ::SetScrollPos(hWnd
, dir
, pos
, refresh
);
844 #endif // __WIN95__/!__WIN95__
847 // New function that will replace some of the above.
848 void wxWindowMSW::SetScrollbar(int orient
, int pos
, int thumbVisible
,
849 int range
, bool refresh
)
851 #if defined(__WIN95__)
852 int oldRange
= range
- thumbVisible
;
854 int range1
= oldRange
;
856 // Try to adjust the range to cope with page size > 1
857 // - a Windows API quirk
858 int pageSize
= thumbVisible
;
859 if ( pageSize
> 1 && range
> 0)
861 range1
+= (pageSize
- 1);
867 if ( orient
== wxHORIZONTAL
) {
873 info
.cbSize
= sizeof(SCROLLINFO
);
874 info
.nPage
= pageSize
; // Have to set this, or scrollbar goes awry
878 info
.fMask
= SIF_RANGE
| SIF_PAGE
| SIF_POS
;
880 HWND hWnd
= GetHwnd();
882 ::SetScrollInfo(hWnd
, dir
, &info
, refresh
);
885 if ( orient
== wxHORIZONTAL
)
890 HWND hWnd
= GetHwnd();
893 ::SetScrollRange(hWnd
, wOrient
, 0, range
, FALSE
);
894 ::SetScrollPos(hWnd
, wOrient
, pos
, refresh
);
897 if ( orient
== wxHORIZONTAL
) {
898 m_xThumbSize
= thumbVisible
;
900 m_yThumbSize
= thumbVisible
;
904 void wxWindowMSW::ScrollWindow(int dx
, int dy
, const wxRect
*prect
)
909 rect
.left
= prect
->x
;
911 rect
.right
= prect
->x
+ prect
->width
;
912 rect
.bottom
= prect
->y
+ prect
->height
;
915 ::ScrollWindow(GetHwnd(), dx
, dy
, prect
? &rect
: NULL
, NULL
);
918 static bool ScrollVertically(HWND hwnd
, int kind
, int count
)
920 int posStart
= GetScrollPosition(hwnd
, SB_VERT
);
923 for ( int n
= 0; n
< count
; n
++ )
925 ::SendMessage(hwnd
, WM_VSCROLL
, kind
, 0);
927 int posNew
= GetScrollPosition(hwnd
, SB_VERT
);
930 // don't bother to continue, we're already at top/bottom
937 return pos
!= posStart
;
940 bool wxWindowMSW::ScrollLines(int lines
)
942 bool down
= lines
> 0;
944 return ScrollVertically(GetHwnd(),
945 down
? SB_LINEDOWN
: SB_LINEUP
,
946 down
? lines
: -lines
);
949 bool wxWindowMSW::ScrollPages(int pages
)
951 bool down
= pages
> 0;
953 return ScrollVertically(GetHwnd(),
954 down
? SB_PAGEDOWN
: SB_PAGEUP
,
955 down
? pages
: -pages
);
958 // ---------------------------------------------------------------------------
960 // ---------------------------------------------------------------------------
962 void wxWindowMSW::SubclassWin(WXHWND hWnd
)
964 wxASSERT_MSG( !m_oldWndProc
, wxT("subclassing window twice?") );
966 HWND hwnd
= (HWND
)hWnd
;
967 wxCHECK_RET( ::IsWindow(hwnd
), wxT("invalid HWND in SubclassWin") );
969 wxAssociateWinWithHandle(hwnd
, this);
971 m_oldWndProc
= (WXFARPROC
)::GetWindowLong(hwnd
, GWL_WNDPROC
);
973 // we don't need to subclass the window of our own class (in the Windows
974 // sense of the word)
975 if ( (WXFARPROC
) m_oldWndProc
!= (WXFARPROC
) wxWndProc
)
977 ::SetWindowLong(hwnd
, GWL_WNDPROC
, (LONG
) wxWndProc
);
981 // don't bother restoring it neither
986 void wxWindowMSW::UnsubclassWin()
988 wxRemoveHandleAssociation(this);
990 // Restore old Window proc
991 HWND hwnd
= GetHwnd();
996 wxCHECK_RET( ::IsWindow(hwnd
), wxT("invalid HWND in UnsubclassWin") );
1000 FARPROC wndProc
= (FARPROC
)::GetWindowLong(hwnd
, GWL_WNDPROC
);
1001 if ( wndProc
!= (FARPROC
) m_oldWndProc
)
1003 ::SetWindowLong(hwnd
, GWL_WNDPROC
, (LONG
) m_oldWndProc
);
1006 m_oldWndProc
= NULL
;
1011 // Make a Windows extended style from the given wxWindows window style
1012 WXDWORD
wxWindowMSW::MakeExtendedStyle(long style
, bool eliminateBorders
)
1014 WXDWORD exStyle
= 0;
1015 if ( style
& wxTRANSPARENT_WINDOW
)
1016 exStyle
|= WS_EX_TRANSPARENT
;
1018 if ( !eliminateBorders
)
1020 if ( style
& wxSUNKEN_BORDER
)
1021 exStyle
|= WS_EX_CLIENTEDGE
;
1022 if ( style
& wxDOUBLE_BORDER
)
1023 exStyle
|= WS_EX_DLGMODALFRAME
;
1024 #if defined(__WIN95__)
1025 if ( style
& wxRAISED_BORDER
)
1026 // It seems that WS_EX_WINDOWEDGE doesn't work, but WS_EX_DLGMODALFRAME does
1027 exStyle
|= WS_EX_DLGMODALFRAME
; /* WS_EX_WINDOWEDGE */;
1028 if ( style
& wxSTATIC_BORDER
)
1029 exStyle
|= WS_EX_STATICEDGE
;
1036 // Determines whether native 3D effects or CTL3D should be used,
1037 // applying a default border style if required, and returning an extended
1038 // style to pass to CreateWindowEx.
1039 WXDWORD
wxWindowMSW::Determine3DEffects(WXDWORD defaultBorderStyle
,
1042 // If matches certain criteria, then assume no 3D effects
1043 // unless specifically requested (dealt with in MakeExtendedStyle)
1046 || !IsKindOf(CLASSINFO(wxControl
))
1047 #endif // wxUSE_CONTROLS
1048 || (m_windowStyle
& wxNO_BORDER
) )
1051 return MakeExtendedStyle(m_windowStyle
);
1054 // Determine whether we should be using 3D effects or not.
1055 bool nativeBorder
= FALSE
; // by default, we don't want a Win95 effect
1057 // 1) App can specify global 3D effects
1058 *want3D
= wxTheApp
->GetAuto3D();
1060 // 2) If the parent is being drawn with user colours, or simple border specified,
1061 // switch effects off. TODO: replace wxUSER_COLOURS with wxNO_3D
1062 if ( GetParent() && (GetParent()->GetWindowStyleFlag() & wxUSER_COLOURS
) || (m_windowStyle
& wxSIMPLE_BORDER
) )
1065 // 3) Control can override this global setting by defining
1066 // a border style, e.g. wxSUNKEN_BORDER
1067 if ( m_windowStyle
& wxSUNKEN_BORDER
)
1070 // 4) If it's a special border, CTL3D can't cope so we want a native border
1071 if ( (m_windowStyle
& wxDOUBLE_BORDER
) || (m_windowStyle
& wxRAISED_BORDER
) ||
1072 (m_windowStyle
& wxSTATIC_BORDER
) )
1075 nativeBorder
= TRUE
;
1078 // 5) If this isn't a Win95 app, and we are using CTL3D, remove border
1079 // effects from extended style
1082 nativeBorder
= FALSE
;
1085 DWORD exStyle
= MakeExtendedStyle(m_windowStyle
, !nativeBorder
);
1087 // If we want 3D, but haven't specified a border here,
1088 // apply the default border style specified.
1089 // TODO what about non-Win95 WIN32? Does it have borders?
1090 #if defined(__WIN95__) && !wxUSE_CTL3D
1091 if ( defaultBorderStyle
&& (*want3D
) && ! ((m_windowStyle
& wxDOUBLE_BORDER
) || (m_windowStyle
& wxRAISED_BORDER
) ||
1092 (m_windowStyle
& wxSTATIC_BORDER
) || (m_windowStyle
& wxSIMPLE_BORDER
) ))
1093 exStyle
|= defaultBorderStyle
; // WS_EX_CLIENTEDGE;
1099 #if WXWIN_COMPATIBILITY
1100 // If nothing defined for this, try the parent.
1101 // E.g. we may be a button loaded from a resource, with no callback function
1103 void wxWindowMSW::OnCommand(wxWindow
& win
, wxCommandEvent
& event
)
1105 if ( GetEventHandler()->ProcessEvent(event
) )
1108 m_parent
->GetEventHandler()->OnCommand(win
, event
);
1110 #endif // WXWIN_COMPATIBILITY_2
1112 #if WXWIN_COMPATIBILITY
1113 wxObject
* wxWindowMSW::GetChild(int number
) const
1115 // Return a pointer to the Nth object in the Panel
1116 wxNode
*node
= GetChildren().First();
1119 node
= node
->Next();
1122 wxObject
*obj
= (wxObject
*)node
->Data();
1128 #endif // WXWIN_COMPATIBILITY
1130 // Setup background and foreground colours correctly
1131 void wxWindowMSW::SetupColours()
1134 SetBackgroundColour(GetParent()->GetBackgroundColour());
1137 bool wxWindowMSW::IsMouseInWindow() const
1139 // get the mouse position
1141 ::GetCursorPos(&pt
);
1143 // find the window which currently has the cursor and go up the window
1144 // chain until we find this window - or exhaust it
1145 HWND hwnd
= ::WindowFromPoint(pt
);
1146 while ( hwnd
&& (hwnd
!= GetHwnd()) )
1147 hwnd
= ::GetParent(hwnd
);
1149 return hwnd
!= NULL
;
1152 void wxWindowMSW::OnIdle(wxIdleEvent
& WXUNUSED(event
))
1154 // Check if we need to send a LEAVE event
1155 if ( m_mouseInWindow
)
1157 if ( !IsMouseInWindow() )
1159 // Generate a LEAVE event
1160 m_mouseInWindow
= FALSE
;
1162 // Unfortunately the mouse button and keyboard state may have
1163 // changed by the time the OnIdle function is called, so 'state'
1164 // may be meaningless.
1166 if ( wxIsShiftDown() )
1168 if ( wxIsCtrlDown() )
1169 state
|= MK_CONTROL
;
1170 if ( GetKeyState( VK_LBUTTON
) )
1171 state
|= MK_LBUTTON
;
1172 if ( GetKeyState( VK_MBUTTON
) )
1173 state
|= MK_MBUTTON
;
1174 if ( GetKeyState( VK_RBUTTON
) )
1175 state
|= MK_RBUTTON
;
1178 if ( !::GetCursorPos(&pt
) )
1180 wxLogLastError(_T("GetCursorPos"));
1183 // we need to have client coordinates here for symmetry with
1184 // wxEVT_ENTER_WINDOW
1185 RECT rect
= wxGetWindowRect(GetHwnd());
1189 wxMouseEvent
event2(wxEVT_LEAVE_WINDOW
);
1190 InitMouseEvent(event2
, pt
.x
, pt
.y
, state
);
1192 (void)GetEventHandler()->ProcessEvent(event2
);
1199 // Set this window to be the child of 'parent'.
1200 bool wxWindowMSW::Reparent(wxWindowBase
*parent
)
1202 if ( !wxWindowBase::Reparent(parent
) )
1205 HWND hWndChild
= GetHwnd();
1206 HWND hWndParent
= GetParent() ? GetWinHwnd(GetParent()) : (HWND
)0;
1208 ::SetParent(hWndChild
, hWndParent
);
1213 void wxWindowMSW::Clear()
1215 wxClientDC
dc((wxWindow
*)this);
1216 wxBrush
brush(GetBackgroundColour(), wxSOLID
);
1217 dc
.SetBackground(brush
);
1221 static inline void SendSetRedraw(HWND hwnd
, bool on
)
1223 #ifndef __WXMICROWIN__
1224 ::SendMessage(hwnd
, WM_SETREDRAW
, (WPARAM
)on
, 0);
1228 void wxWindowMSW::Freeze()
1230 SendSetRedraw(GetHwnd(), FALSE
);
1233 void wxWindowMSW::Thaw()
1235 SendSetRedraw(GetHwnd(), TRUE
);
1237 // we need to refresh everything or otherwise he invalidated area is not
1242 void wxWindowMSW::Refresh(bool eraseBack
, const wxRect
*rect
)
1244 HWND hWnd
= GetHwnd();
1250 mswRect
.left
= rect
->x
;
1251 mswRect
.top
= rect
->y
;
1252 mswRect
.right
= rect
->x
+ rect
->width
;
1253 mswRect
.bottom
= rect
->y
+ rect
->height
;
1255 ::InvalidateRect(hWnd
, &mswRect
, eraseBack
);
1258 ::InvalidateRect(hWnd
, NULL
, eraseBack
);
1262 void wxWindowMSW::Update()
1264 if ( !::UpdateWindow(GetHwnd()) )
1266 wxLogLastError(_T("UpdateWindow"));
1269 #if defined(__WIN32__) && !defined(__WXMICROWIN__)
1270 // just calling UpdateWindow() is not enough, what we did in our WM_PAINT
1271 // handler needs to be really drawn right now
1276 // ---------------------------------------------------------------------------
1278 // ---------------------------------------------------------------------------
1280 #if wxUSE_DRAG_AND_DROP
1282 void wxWindowMSW::SetDropTarget(wxDropTarget
*pDropTarget
)
1284 if ( m_dropTarget
!= 0 ) {
1285 m_dropTarget
->Revoke(m_hWnd
);
1286 delete m_dropTarget
;
1289 m_dropTarget
= pDropTarget
;
1290 if ( m_dropTarget
!= 0 )
1291 m_dropTarget
->Register(m_hWnd
);
1294 #endif // wxUSE_DRAG_AND_DROP
1296 // old style file-manager drag&drop support: we retain the old-style
1297 // DragAcceptFiles in parallel with SetDropTarget.
1298 void wxWindowMSW::DragAcceptFiles(bool accept
)
1300 HWND hWnd
= GetHwnd();
1302 ::DragAcceptFiles(hWnd
, (BOOL
)accept
);
1305 // ----------------------------------------------------------------------------
1307 // ----------------------------------------------------------------------------
1311 void wxWindowMSW::DoSetToolTip(wxToolTip
*tooltip
)
1313 wxWindowBase::DoSetToolTip(tooltip
);
1316 m_tooltip
->SetWindow(this);
1319 #endif // wxUSE_TOOLTIPS
1321 // ---------------------------------------------------------------------------
1322 // moving and resizing
1323 // ---------------------------------------------------------------------------
1326 void wxWindowMSW::DoGetSize(int *x
, int *y
) const
1328 RECT rect
= wxGetWindowRect(GetHwnd());
1331 *x
= rect
.right
- rect
.left
;
1333 *y
= rect
.bottom
- rect
.top
;
1336 // Get size *available for subwindows* i.e. excluding menu bar etc.
1337 void wxWindowMSW::DoGetClientSize(int *x
, int *y
) const
1339 RECT rect
= wxGetClientRect(GetHwnd());
1347 void wxWindowMSW::DoGetPosition(int *x
, int *y
) const
1349 RECT rect
= wxGetWindowRect(GetHwnd());
1352 point
.x
= rect
.left
;
1355 // we do the adjustments with respect to the parent only for the "real"
1356 // children, not for the dialogs/frames
1357 if ( !IsTopLevel() )
1359 HWND hParentWnd
= 0;
1360 wxWindow
*parent
= GetParent();
1362 hParentWnd
= GetWinHwnd(parent
);
1364 // Since we now have the absolute screen coords, if there's a parent we
1365 // must subtract its top left corner
1368 ::ScreenToClient(hParentWnd
, &point
);
1373 // We may be faking the client origin. So a window that's really at (0,
1374 // 30) may appear (to wxWin apps) to be at (0, 0).
1375 wxPoint
pt(parent
->GetClientAreaOrigin());
1387 void wxWindowMSW::DoScreenToClient(int *x
, int *y
) const
1395 ::ScreenToClient(GetHwnd(), &pt
);
1403 void wxWindowMSW::DoClientToScreen(int *x
, int *y
) const
1411 ::ClientToScreen(GetHwnd(), &pt
);
1419 void wxWindowMSW::DoMoveWindow(int x
, int y
, int width
, int height
)
1421 if ( !::MoveWindow(GetHwnd(), x
, y
, width
, height
, TRUE
) )
1423 wxLogLastError(wxT("MoveWindow"));
1427 // set the size of the window: if the dimensions are positive, just use them,
1428 // but if any of them is equal to -1, it means that we must find the value for
1429 // it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
1430 // which case -1 is a valid value for x and y)
1432 // If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate
1433 // the width/height to best suit our contents, otherwise we reuse the current
1435 void wxWindowMSW::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
)
1437 // get the current size and position...
1438 int currentX
, currentY
;
1439 GetPosition(¤tX
, ¤tY
);
1440 int currentW
,currentH
;
1441 GetSize(¤tW
, ¤tH
);
1443 // ... and don't do anything (avoiding flicker) if it's already ok
1444 if ( x
== currentX
&& y
== currentY
&&
1445 width
== currentW
&& height
== currentH
)
1450 if ( x
== -1 && !(sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) )
1452 if ( y
== -1 && !(sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) )
1455 AdjustForParentClientOrigin(x
, y
, sizeFlags
);
1457 wxSize
size(-1, -1);
1460 if ( sizeFlags
& wxSIZE_AUTO_WIDTH
)
1462 size
= DoGetBestSize();
1467 // just take the current one
1474 if ( sizeFlags
& wxSIZE_AUTO_HEIGHT
)
1478 size
= DoGetBestSize();
1480 //else: already called DoGetBestSize() above
1486 // just take the current one
1491 DoMoveWindow(x
, y
, width
, height
);
1494 void wxWindowMSW::DoSetClientSize(int width
, int height
)
1496 wxWindow
*parent
= GetParent();
1497 HWND hWnd
= GetHwnd();
1498 HWND hParentWnd
= (HWND
) 0;
1500 hParentWnd
= (HWND
) parent
->GetHWND();
1503 ::GetClientRect(hWnd
, &rect
);
1506 GetWindowRect(hWnd
, &rect2
);
1508 // Find the difference between the entire window (title bar and all)
1509 // and the client area; add this to the new client size to move the
1511 int actual_width
= rect2
.right
- rect2
.left
- rect
.right
+ width
;
1512 int actual_height
= rect2
.bottom
- rect2
.top
- rect
.bottom
+ height
;
1514 // If there's a parent, must subtract the parent's top left corner
1515 // since MoveWindow moves relative to the parent
1518 point
.x
= rect2
.left
;
1519 point
.y
= rect2
.top
;
1522 ::ScreenToClient(hParentWnd
, &point
);
1525 DoMoveWindow(point
.x
, point
.y
, actual_width
, actual_height
);
1527 wxSizeEvent
event(wxSize(width
, height
), m_windowId
);
1528 event
.SetEventObject(this);
1529 GetEventHandler()->ProcessEvent(event
);
1532 // For implementation purposes - sometimes decorations make the client area
1534 wxPoint
wxWindowMSW::GetClientAreaOrigin() const
1536 return wxPoint(0, 0);
1539 // ---------------------------------------------------------------------------
1541 // ---------------------------------------------------------------------------
1543 int wxWindowMSW::GetCharHeight() const
1545 return wxGetTextMetrics(this).tmHeight
;
1548 int wxWindowMSW::GetCharWidth() const
1550 // +1 is needed because Windows apparently adds it when calculating the
1551 // dialog units size in pixels
1552 #if wxDIALOG_UNIT_COMPATIBILITY
1553 return wxGetTextMetrics(this).tmAveCharWidth
;
1555 return wxGetTextMetrics(this).tmAveCharWidth
+ 1;
1559 void wxWindowMSW::GetTextExtent(const wxString
& string
,
1561 int *descent
, int *externalLeading
,
1562 const wxFont
*theFont
) const
1564 const wxFont
*fontToUse
= theFont
;
1566 fontToUse
= &m_font
;
1568 HWND hWnd
= GetHwnd();
1569 HDC dc
= ::GetDC(hWnd
);
1573 if ( fontToUse
&& fontToUse
->Ok() )
1575 fnt
= (HFONT
)((wxFont
*)fontToUse
)->GetResourceHandle(); // const_cast
1577 hfontOld
= (HFONT
)SelectObject(dc
,fnt
);
1582 GetTextExtentPoint(dc
, string
, (int)string
.Length(), &sizeRect
);
1583 GetTextMetrics(dc
, &tm
);
1585 if ( fontToUse
&& fnt
&& hfontOld
)
1586 SelectObject(dc
, hfontOld
);
1588 ReleaseDC(hWnd
, dc
);
1595 *descent
= tm
.tmDescent
;
1596 if ( externalLeading
)
1597 *externalLeading
= tm
.tmExternalLeading
;
1600 #if wxUSE_CARET && WXWIN_COMPATIBILITY
1601 // ---------------------------------------------------------------------------
1602 // Caret manipulation
1603 // ---------------------------------------------------------------------------
1605 void wxWindowMSW::CreateCaret(int w
, int h
)
1607 SetCaret(new wxCaret(this, w
, h
));
1610 void wxWindowMSW::CreateCaret(const wxBitmap
*WXUNUSED(bitmap
))
1612 wxFAIL_MSG("not implemented");
1615 void wxWindowMSW::ShowCaret(bool show
)
1617 wxCHECK_RET( m_caret
, "no caret to show" );
1619 m_caret
->Show(show
);
1622 void wxWindowMSW::DestroyCaret()
1627 void wxWindowMSW::SetCaretPos(int x
, int y
)
1629 wxCHECK_RET( m_caret
, "no caret to move" );
1631 m_caret
->Move(x
, y
);
1634 void wxWindowMSW::GetCaretPos(int *x
, int *y
) const
1636 wxCHECK_RET( m_caret
, "no caret to get position of" );
1638 m_caret
->GetPosition(x
, y
);
1640 #endif // wxUSE_CARET
1642 // ---------------------------------------------------------------------------
1644 // ---------------------------------------------------------------------------
1646 #if wxUSE_MENUS_NATIVE
1648 // yield for WM_COMMAND events only, i.e. process all WM_COMMANDs in the queue
1649 // immediately, without waiting for the next event loop iteration
1651 // NB: this function should probably be made public later as it can almost
1652 // surely replace wxYield() elsewhere as well
1653 static void wxYieldForCommandsOnly()
1655 // peek all WM_COMMANDs (it will always return WM_QUIT too but we don't
1656 // want to process it here)
1658 while ( ::PeekMessage(&msg
, (HWND
)0, WM_COMMAND
, WM_COMMAND
, PM_REMOVE
)
1659 && msg
.message
!= WM_QUIT
)
1661 wxTheApp
->DoMessage((WXMSG
*)&msg
);
1665 bool wxWindowMSW::DoPopupMenu(wxMenu
*menu
, int x
, int y
)
1667 menu
->SetInvokingWindow(this);
1670 HWND hWnd
= GetHwnd();
1671 HMENU hMenu
= GetHmenuOf(menu
);
1675 ::ClientToScreen(hWnd
, &point
);
1676 wxCurrentPopupMenu
= menu
;
1677 ::TrackPopupMenu(hMenu
, TPM_RIGHTBUTTON
, point
.x
, point
.y
, 0, hWnd
, NULL
);
1679 // we need to do it righ now as otherwise the events are never going to be
1680 // sent to wxCurrentPopupMenu from HandleCommand()
1682 // note that even eliminating (ugly) wxCurrentPopupMenu global wouldn't
1683 // help and we'd still need wxYieldForCommandsOnly() as the menu may be
1684 // destroyed as soon as we return (it can be a local variable in the caller
1685 // for example) and so we do need to process the event immediately
1686 wxYieldForCommandsOnly();
1688 wxCurrentPopupMenu
= NULL
;
1690 menu
->SetInvokingWindow(NULL
);
1695 #endif // wxUSE_MENUS_NATIVE
1697 // ===========================================================================
1698 // pre/post message processing
1699 // ===========================================================================
1701 long wxWindowMSW::MSWDefWindowProc(WXUINT nMsg
, WXWPARAM wParam
, WXLPARAM lParam
)
1704 return ::CallWindowProc(CASTWNDPROC m_oldWndProc
, GetHwnd(), (UINT
) nMsg
, (WPARAM
) wParam
, (LPARAM
) lParam
);
1706 return ::DefWindowProc(GetHwnd(), nMsg
, wParam
, lParam
);
1709 bool wxWindowMSW::MSWProcessMessage(WXMSG
* pMsg
)
1711 // wxUniversal implements tab traversal itself
1712 #ifndef __WXUNIVERSAL__
1713 if ( m_hWnd
!= 0 && (GetWindowStyleFlag() & wxTAB_TRAVERSAL
) )
1715 // intercept dialog navigation keys
1716 MSG
*msg
= (MSG
*)pMsg
;
1718 // here we try to do all the job which ::IsDialogMessage() usually does
1721 bool bProcess
= TRUE
;
1722 if ( msg
->message
!= WM_KEYDOWN
)
1725 if ( bProcess
&& (HIWORD(msg
->lParam
) & KF_ALTDOWN
) == KF_ALTDOWN
)
1730 bool bCtrlDown
= wxIsCtrlDown();
1731 bool bShiftDown
= wxIsShiftDown();
1733 // WM_GETDLGCODE: ask the control if it wants the key for itself,
1734 // don't process it if it's the case (except for Ctrl-Tab/Enter
1735 // combinations which are always processed)
1739 lDlgCode
= ::SendMessage(msg
->hwnd
, WM_GETDLGCODE
, 0, 0);
1742 bool bForward
= TRUE
,
1743 bWindowChange
= FALSE
;
1745 switch ( msg
->wParam
)
1748 // assume that nobody wants Shift-TAB for himself - if we
1749 // don't do it there is no easy way for a control to grab
1750 // TABs but still let Shift-TAB work as navugation key
1751 if ( (lDlgCode
& DLGC_WANTTAB
) && !bShiftDown
) {
1755 // Ctrl-Tab cycles thru notebook pages
1756 bWindowChange
= bCtrlDown
;
1757 bForward
= !bShiftDown
;
1763 if ( (lDlgCode
& DLGC_WANTARROWS
) || bCtrlDown
)
1771 if ( (lDlgCode
& DLGC_WANTARROWS
) || bCtrlDown
)
1777 if ( (lDlgCode
& DLGC_WANTMESSAGE
) && !bCtrlDown
)
1779 // control wants to process Enter itself, don't
1780 // call IsDialogMessage() which would interpret
1784 else if ( lDlgCode
& DLGC_BUTTON
)
1786 // let IsDialogMessage() handle this for all
1787 // buttons except the owner-drawn ones which it
1788 // just seems to ignore
1789 long style
= ::GetWindowLong(msg
->hwnd
, GWL_STYLE
);
1790 if ( (style
& BS_OWNERDRAW
) == BS_OWNERDRAW
)
1792 // emulate the button click
1793 wxWindow
*btn
= wxFindWinFromHandle((WXHWND
)msg
->hwnd
);
1795 btn
->MSWCommand(BN_CLICKED
, 0 /* unused */);
1800 // FIXME: this should be handled by
1801 // wxNavigationKeyEvent handler and not here!!
1805 wxButton
*btn
= wxDynamicCast(GetDefaultItem(),
1807 if ( btn
&& btn
->IsEnabled() )
1809 // if we do have a default button, do press it
1810 btn
->MSWCommand(BN_CLICKED
, 0 /* unused */);
1814 else // no default button
1815 #endif // wxUSE_BUTTON
1817 // no special function for enter and don't even
1818 // let IsDialogMessage() have it: it seems to
1819 // do something really strange with it
1832 wxNavigationKeyEvent event
;
1833 event
.SetDirection(bForward
);
1834 event
.SetWindowChange(bWindowChange
);
1835 event
.SetEventObject(this);
1837 if ( GetEventHandler()->ProcessEvent(event
) )
1844 // let ::IsDialogMessage() do almost everything and handle just the
1845 // things it doesn't here: Ctrl-TAB for switching notebook pages
1846 if ( msg
->message
== WM_KEYDOWN
)
1848 // don't process system keys here
1849 if ( !(HIWORD(msg
->lParam
) & KF_ALTDOWN
) )
1851 if ( (msg
->wParam
== VK_TAB
) && wxIsCtrlDown() )
1853 // find the first notebook parent and change its page
1854 wxWindow
*win
= this;
1855 wxNotebook
*nbook
= NULL
;
1856 while ( win
&& !nbook
)
1858 nbook
= wxDynamicCast(win
, wxNotebook
);
1859 win
= win
->GetParent();
1864 bool forward
= !wxIsShiftDown();
1866 nbook
->AdvanceSelection(forward
);
1873 if ( ::IsDialogMessage(GetHwnd(), msg
) )
1875 // IsDialogMessage() did something...
1879 #endif // __WXUNIVERSAL__
1884 // relay mouse move events to the tooltip control
1885 MSG
*msg
= (MSG
*)pMsg
;
1886 if ( msg
->message
== WM_MOUSEMOVE
)
1887 m_tooltip
->RelayEvent(pMsg
);
1889 #endif // wxUSE_TOOLTIPS
1894 bool wxWindowMSW::MSWTranslateMessage(WXMSG
* pMsg
)
1896 #if wxUSE_ACCEL && !defined(__WXUNIVERSAL__)
1897 return m_acceleratorTable
.Translate(this, pMsg
);
1900 #endif // wxUSE_ACCEL
1903 bool wxWindowMSW::MSWShouldPreProcessMessage(WXMSG
* pMsg
)
1905 // preprocess all messages by default
1909 // ---------------------------------------------------------------------------
1910 // message params unpackers (different for Win16 and Win32)
1911 // ---------------------------------------------------------------------------
1915 void wxWindowMSW::UnpackCommand(WXWPARAM wParam
, WXLPARAM lParam
,
1916 WORD
*id
, WXHWND
*hwnd
, WORD
*cmd
)
1918 *id
= LOWORD(wParam
);
1919 *hwnd
= (WXHWND
)lParam
;
1920 *cmd
= HIWORD(wParam
);
1923 void wxWindowMSW::UnpackActivate(WXWPARAM wParam
, WXLPARAM lParam
,
1924 WXWORD
*state
, WXWORD
*minimized
, WXHWND
*hwnd
)
1926 *state
= LOWORD(wParam
);
1927 *minimized
= HIWORD(wParam
);
1928 *hwnd
= (WXHWND
)lParam
;
1931 void wxWindowMSW::UnpackScroll(WXWPARAM wParam
, WXLPARAM lParam
,
1932 WXWORD
*code
, WXWORD
*pos
, WXHWND
*hwnd
)
1934 *code
= LOWORD(wParam
);
1935 *pos
= HIWORD(wParam
);
1936 *hwnd
= (WXHWND
)lParam
;
1939 void wxWindowMSW::UnpackCtlColor(WXWPARAM wParam
, WXLPARAM lParam
,
1940 WXWORD
*nCtlColor
, WXHDC
*hdc
, WXHWND
*hwnd
)
1942 #ifndef __WXMICROWIN__
1943 *nCtlColor
= CTLCOLOR_BTN
;
1944 *hwnd
= (WXHWND
)lParam
;
1945 *hdc
= (WXHDC
)wParam
;
1949 void wxWindowMSW::UnpackMenuSelect(WXWPARAM wParam
, WXLPARAM lParam
,
1950 WXWORD
*item
, WXWORD
*flags
, WXHMENU
*hmenu
)
1952 *item
= (WXWORD
)wParam
;
1953 *flags
= HIWORD(wParam
);
1954 *hmenu
= (WXHMENU
)lParam
;
1959 void wxWindowMSW::UnpackCommand(WXWPARAM wParam
, WXLPARAM lParam
,
1960 WXWORD
*id
, WXHWND
*hwnd
, WXWORD
*cmd
)
1962 *id
= (WXWORD
)wParam
;
1963 *hwnd
= (WXHWND
)LOWORD(lParam
);
1964 *cmd
= HIWORD(lParam
);
1967 void wxWindowMSW::UnpackActivate(WXWPARAM wParam
, WXLPARAM lParam
,
1968 WXWORD
*state
, WXWORD
*minimized
, WXHWND
*hwnd
)
1970 *state
= (WXWORD
)wParam
;
1971 *minimized
= LOWORD(lParam
);
1972 *hwnd
= (WXHWND
)HIWORD(lParam
);
1975 void wxWindowMSW::UnpackScroll(WXWPARAM wParam
, WXLPARAM lParam
,
1976 WXWORD
*code
, WXWORD
*pos
, WXHWND
*hwnd
)
1978 *code
= (WXWORD
)wParam
;
1979 *pos
= LOWORD(lParam
);
1980 *hwnd
= (WXHWND
)HIWORD(lParam
);
1983 void wxWindowMSW::UnpackCtlColor(WXWPARAM wParam
, WXLPARAM lParam
,
1984 WXWORD
*nCtlColor
, WXHDC
*hdc
, WXHWND
*hwnd
)
1986 *hwnd
= (WXHWND
)LOWORD(lParam
);
1987 *nCtlColor
= (int)HIWORD(lParam
);
1988 *hdc
= (WXHDC
)wParam
;
1991 void wxWindowMSW::UnpackMenuSelect(WXWPARAM wParam
, WXLPARAM lParam
,
1992 WXWORD
*item
, WXWORD
*flags
, WXHMENU
*hmenu
)
1994 *item
= (WXWORD
)wParam
;
1995 *flags
= LOWORD(lParam
);
1996 *hmenu
= (WXHMENU
)HIWORD(lParam
);
2001 // ---------------------------------------------------------------------------
2002 // Main wxWindows window proc and the window proc for wxWindow
2003 // ---------------------------------------------------------------------------
2005 // Hook for new window just as it's being created, when the window isn't yet
2006 // associated with the handle
2007 static wxWindowMSW
*gs_winBeingCreated
= NULL
;
2009 // implementation of wxWindowCreationHook class: it just sets gs_winBeingCreated to the
2010 // window being created and insures that it's always unset back later
2011 wxWindowCreationHook::wxWindowCreationHook(wxWindowMSW
*winBeingCreated
)
2013 gs_winBeingCreated
= winBeingCreated
;
2016 wxWindowCreationHook::~wxWindowCreationHook()
2018 gs_winBeingCreated
= NULL
;
2022 LRESULT WXDLLEXPORT APIENTRY _EXPORT
wxWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
2024 // trace all messages - useful for the debugging
2026 wxLogTrace(wxTraceMessages
, wxT("Processing %s(wParam=%8lx, lParam=%8lx)"),
2027 wxGetMessageName(message
), wParam
, lParam
);
2028 #endif // __WXDEBUG__
2030 wxWindowMSW
*wnd
= wxFindWinFromHandle((WXHWND
) hWnd
);
2032 // when we get the first message for the HWND we just created, we associate
2033 // it with wxWindow stored in gs_winBeingCreated
2034 if ( !wnd
&& gs_winBeingCreated
)
2036 wxAssociateWinWithHandle(hWnd
, gs_winBeingCreated
);
2037 wnd
= gs_winBeingCreated
;
2038 gs_winBeingCreated
= NULL
;
2039 wnd
->SetHWND((WXHWND
)hWnd
);
2045 rc
= wnd
->MSWWindowProc(message
, wParam
, lParam
);
2047 rc
= ::DefWindowProc(hWnd
, message
, wParam
, lParam
);
2052 long wxWindowMSW::MSWWindowProc(WXUINT message
, WXWPARAM wParam
, WXLPARAM lParam
)
2054 // did we process the message?
2055 bool processed
= FALSE
;
2066 // for most messages we should return 0 when we do process the message
2074 processed
= HandleCreate((WXLPCREATESTRUCT
)lParam
, &mayCreate
);
2077 // return 0 to allow window creation
2078 rc
.result
= mayCreate
? 0 : -1;
2084 // never set processed to TRUE and *always* pass WM_DESTROY to
2085 // DefWindowProc() as Windows may do some internal cleanup when
2086 // processing it and failing to pass the message along may cause
2087 // memory and resource leaks!
2088 (void)HandleDestroy();
2092 processed
= HandleMove(GET_X_LPARAM(lParam
), GET_Y_LPARAM(lParam
));
2100 // we're not interested in these messages at all
2103 case SIZE_MINIMIZED
:
2104 // we shouldn't send sizev events for these messages as the
2105 // client size may be negative which breaks existing code
2107 // OTOH we might send another (wxMinimizedEvent?) one or
2108 // add an additional parameter to wxSizeEvent if this is
2109 // useful to anybody
2113 wxFAIL_MSG( _T("unexpected WM_SIZE parameter") );
2114 // fall through nevertheless
2116 case SIZE_MAXIMIZED
:
2118 processed
= HandleSize(LOWORD(lParam
), HIWORD(lParam
),
2123 #ifndef __WXMICROWIN__
2124 case WM_ACTIVATEAPP
:
2125 wxTheApp
->SetActive(wParam
!= 0, FindFocus());
2131 WXWORD state
, minimized
;
2133 UnpackActivate(wParam
, lParam
, &state
, &minimized
, &hwnd
);
2135 processed
= HandleActivate(state
, minimized
!= 0, (WXHWND
)hwnd
);
2140 processed
= HandleSetFocus((WXHWND
)(HWND
)wParam
);
2144 processed
= HandleKillFocus((WXHWND
)(HWND
)wParam
);
2148 processed
= HandlePaint();
2152 // don't let the DefWindowProc() destroy our window - we'll do it
2153 // ourselves in ~wxWindow
2159 processed
= HandleShow(wParam
!= 0, (int)lParam
);
2163 processed
= HandleMouseMove(GET_X_LPARAM(lParam
),
2164 GET_Y_LPARAM(lParam
),
2168 #if wxUSE_MOUSEWHEEL
2170 processed
= HandleMouseWheel(wParam
, lParam
);
2174 case WM_LBUTTONDOWN
:
2176 case WM_LBUTTONDBLCLK
:
2177 case WM_RBUTTONDOWN
:
2179 case WM_RBUTTONDBLCLK
:
2180 case WM_MBUTTONDOWN
:
2182 case WM_MBUTTONDBLCLK
:
2185 #ifdef __WXMICROWIN__
2186 // MicroWindows seems to ignore the fact that a window is
2187 // disabled. So catch mouse events and throw them away if
2189 wxWindowMSW
* win
= this;
2192 if (!win
->IsEnabled())
2197 win
= win
->GetParent();
2198 if (win
&& win
->IsTopLevel())
2201 #endif // __WXMICROWIN__
2204 if (message
== WM_LBUTTONDOWN
&& AcceptsFocus())
2206 processed
= HandleMouseEvent(message
,
2207 GET_X_LPARAM(lParam
),
2208 GET_Y_LPARAM(lParam
),
2214 #ifdef __WXMICROWIN__
2215 case WM_NCLBUTTONDOWN
:
2216 case WM_NCLBUTTONUP
:
2217 case WM_NCLBUTTONDBLCLK
:
2218 case WM_NCRBUTTONDOWN
:
2219 case WM_NCRBUTTONUP
:
2220 case WM_NCRBUTTONDBLCLK
:
2222 case WM_NCMBUTTONDOWN
:
2223 case WM_NCMBUTTONUP
:
2224 case WM_NCMBUTTONDBLCLK
:
2227 // MicroWindows seems to ignore the fact that a window
2228 // is disabled. So catch mouse events and throw them away if necessary.
2230 wxWindowMSW
* win
= this;
2233 if (!win
->IsEnabled())
2238 win
= win
->GetParent();
2239 if (win
&& win
->IsTopLevel())
2244 #endif // __WXMICROWIN__
2251 case MM_JOY1BUTTONDOWN
:
2252 case MM_JOY2BUTTONDOWN
:
2253 case MM_JOY1BUTTONUP
:
2254 case MM_JOY2BUTTONUP
:
2255 processed
= HandleJoystickEvent(message
,
2256 GET_X_LPARAM(lParam
),
2257 GET_Y_LPARAM(lParam
),
2260 #endif // __WXMICROWIN__
2263 processed
= HandleSysCommand(wParam
, lParam
);
2270 UnpackCommand(wParam
, lParam
, &id
, &hwnd
, &cmd
);
2272 processed
= HandleCommand(id
, cmd
, hwnd
);
2278 processed
= HandleNotify((int)wParam
, lParam
, &rc
.result
);
2282 // for these messages we must return TRUE if process the message
2285 case WM_MEASUREITEM
:
2287 int idCtrl
= (UINT
)wParam
;
2288 if ( message
== WM_DRAWITEM
)
2290 processed
= MSWOnDrawItem(idCtrl
,
2291 (WXDRAWITEMSTRUCT
*)lParam
);
2295 processed
= MSWOnMeasureItem(idCtrl
,
2296 (WXMEASUREITEMSTRUCT
*)lParam
);
2303 #endif // defined(WM_DRAWITEM)
2308 rc
.result
= m_lDlgCode
;
2311 //else: get the dlg code from the DefWindowProc()
2316 // If this has been processed by an event handler,
2317 // return 0 now (we've handled it).
2318 if ( HandleKeyDown((WORD
) wParam
, lParam
) )
2325 // we consider these message "not interesting" to OnChar
2326 if ( wParam
== VK_SHIFT
|| wParam
== VK_CONTROL
)
2335 // avoid duplicate messages to OnChar for these ASCII keys: they
2336 // will be translated by TranslateMessage() and received in WM_CHAR
2344 // but set processed to FALSE, not TRUE to still pass them to
2345 // the control's default window proc - otherwise built-in
2346 // keyboard handling won't work
2352 // special case of VK_APPS: treat it the same as right mouse
2353 // click because both usually pop up a context menu
2359 TranslateKbdEventToMouse(this, &x
, &y
, &flags
);
2360 processed
= HandleMouseEvent(WM_RBUTTONDOWN
, x
, y
, flags
);
2370 processed
= HandleChar((WORD
)wParam
, lParam
);
2377 // special case of VK_APPS: treat it the same as right mouse button
2378 if ( wParam
== VK_APPS
)
2383 TranslateKbdEventToMouse(this, &x
, &y
, &flags
);
2384 processed
= HandleMouseEvent(WM_RBUTTONUP
, x
, y
, flags
);
2389 processed
= HandleKeyUp((WORD
) wParam
, lParam
);
2394 case WM_CHAR
: // Always an ASCII character
2395 processed
= HandleChar((WORD
)wParam
, lParam
, TRUE
);
2403 UnpackScroll(wParam
, lParam
, &code
, &pos
, &hwnd
);
2405 processed
= MSWOnScroll(message
== WM_HSCROLL
? wxHORIZONTAL
2411 // CTLCOLOR messages are sent by children to query the parent for their
2412 // colors#ifndef __WXMICROWIN__
2413 #ifndef __WXMICROWIN__
2415 case WM_CTLCOLORMSGBOX
:
2416 case WM_CTLCOLOREDIT
:
2417 case WM_CTLCOLORLISTBOX
:
2418 case WM_CTLCOLORBTN
:
2419 case WM_CTLCOLORDLG
:
2420 case WM_CTLCOLORSCROLLBAR
:
2421 case WM_CTLCOLORSTATIC
:
2429 UnpackCtlColor(wParam
, lParam
, &nCtlColor
, &hdc
, &hwnd
);
2431 processed
= HandleCtlColor(&rc
.hBrush
,
2440 #endif // !__WXMICROWIN__
2442 // the return value for this message is ignored
2443 case WM_SYSCOLORCHANGE
:
2444 processed
= HandleSysColorChange();
2447 case WM_PALETTECHANGED
:
2448 processed
= HandlePaletteChanged((WXHWND
) (HWND
) wParam
);
2451 case WM_QUERYNEWPALETTE
:
2452 processed
= HandleQueryNewPalette();
2456 processed
= HandleEraseBkgnd((WXHDC
)(HDC
)wParam
);
2459 // we processed the message, i.e. erased the background
2465 processed
= HandleDropFiles(wParam
);
2469 processed
= HandleInitDialog((WXHWND
)(HWND
)wParam
);
2473 // we never set focus from here
2478 case WM_QUERYENDSESSION
:
2479 processed
= HandleQueryEndSession(lParam
, &rc
.allow
);
2483 processed
= HandleEndSession(wParam
!= 0, lParam
);
2486 case WM_GETMINMAXINFO
:
2487 processed
= HandleGetMinMaxInfo((MINMAXINFO
*)lParam
);
2491 processed
= HandleSetCursor((WXHWND
)(HWND
)wParam
,
2492 LOWORD(lParam
), // hit test
2493 HIWORD(lParam
)); // mouse msg
2497 // returning TRUE stops the DefWindowProc() from further
2498 // processing this message - exactly what we need because we've
2499 // just set the cursor.
2504 #if defined(__WIN32__) && defined(WM_HELP)
2507 HELPINFO
* info
= (HELPINFO
*) lParam
;
2508 // Don't yet process menu help events, just windows
2509 if (info
->iContextType
== HELPINFO_WINDOW
)
2511 wxWindowMSW
* subjectOfHelp
= this;
2512 bool eventProcessed
= FALSE
;
2513 while (subjectOfHelp
&& !eventProcessed
)
2515 wxHelpEvent
helpEvent(wxEVT_HELP
,
2516 subjectOfHelp
->GetId(),
2517 wxPoint(info
->MousePos
.x
,
2518 info
->MousePos
.y
) );
2519 helpEvent
.SetEventObject(this);
2521 GetEventHandler()->ProcessEvent(helpEvent
);
2523 // Go up the window hierarchy until the event is
2525 subjectOfHelp
= subjectOfHelp
->GetParent();
2528 processed
= eventProcessed
;
2530 else if (info
->iContextType
== HELPINFO_MENUITEM
)
2532 wxHelpEvent
helpEvent(wxEVT_HELP
, info
->iCtrlId
);
2533 helpEvent
.SetEventObject(this);
2534 processed
= GetEventHandler()->ProcessEvent(helpEvent
);
2537 //else: processed is already FALSE
2541 case WM_CONTEXTMENU
:
2543 // we don't convert from screen to client coordinates as
2544 // the event may be handled by a parent window
2545 wxPoint
pt(GET_X_LPARAM(lParam
), GET_Y_LPARAM(lParam
));
2547 wxContextMenuEvent
evtCtx(wxEVT_CONTEXT_MENU
, GetId(), pt
);
2548 processed
= GetEventHandler()->ProcessEvent(evtCtx
);
2553 // unfortunately this doesn't really work as then window which
2554 // doesn't accept focus doesn't get any mouse events neither which
2555 // means it can't get any input at all
2556 #if 0 //def __WXUNIVERSAL__
2558 // we shouldn't allow the windows which don't want to get focus to
2560 if ( !AcceptsFocus() )
2562 rc
.result
= HTTRANSPARENT
;
2566 #endif // __WXUNIVERSAL__
2572 wxLogTrace(wxTraceMessages
, wxT("Forwarding %s to DefWindowProc."),
2573 wxGetMessageName(message
));
2574 #endif // __WXDEBUG__
2575 rc
.result
= MSWDefWindowProc(message
, wParam
, lParam
);
2581 // ----------------------------------------------------------------------------
2582 // wxWindow <-> HWND map
2583 // ----------------------------------------------------------------------------
2585 wxWinHashTable
*wxWinHandleHash
= NULL
;
2587 wxWindow
*wxFindWinFromHandle(WXHWND hWnd
)
2589 return wxWinHandleHash
->Get((long)hWnd
);
2592 void wxAssociateWinWithHandle(HWND hWnd
, wxWindowMSW
*win
)
2594 // adding NULL hWnd is (first) surely a result of an error and
2595 // (secondly) breaks menu command processing
2596 wxCHECK_RET( hWnd
!= (HWND
)NULL
,
2597 wxT("attempt to add a NULL hWnd to window list ignored") );
2599 wxWindow
*oldWin
= wxFindWinFromHandle((WXHWND
) hWnd
);
2601 if ( oldWin
&& (oldWin
!= win
) )
2603 wxLogDebug(wxT("HWND %X already associated with another window (%s)"),
2604 hWnd
, win
->GetClassInfo()->GetClassName());
2607 #endif // __WXDEBUG__
2610 wxWinHandleHash
->Put((long)hWnd
, (wxWindow
*)win
);
2614 void wxRemoveHandleAssociation(wxWindowMSW
*win
)
2616 wxWinHandleHash
->Delete((long)win
->GetHWND());
2619 // ----------------------------------------------------------------------------
2620 // various MSW speciic class dependent functions
2621 // ----------------------------------------------------------------------------
2623 // Default destroyer - override if you destroy it in some other way
2624 // (e.g. with MDI child windows)
2625 void wxWindowMSW::MSWDestroyWindow()
2629 void wxWindowMSW::MSWDetachWindowMenu()
2631 #ifndef __WXUNIVERSAL__
2635 HMENU hMenu
= (HMENU
)m_hMenu
;
2637 int N
= ::GetMenuItemCount(hMenu
);
2638 for ( int i
= 0; i
< N
; i
++ )
2640 if ( !::GetMenuString(hMenu
, i
, buf
, WXSIZEOF(buf
), MF_BYPOSITION
) )
2642 wxLogLastError(wxT("GetMenuString"));
2647 if ( wxStrcmp(buf
, _("&Window")) == 0 )
2649 if ( !::RemoveMenu(hMenu
, i
, MF_BYPOSITION
) )
2651 wxLogLastError(wxT("RemoveMenu"));
2658 #endif // __WXUNIVERSAL__
2661 bool wxWindowMSW::MSWGetCreateWindowCoords(const wxPoint
& pos
,
2664 int& w
, int& h
) const
2666 bool nonDefault
= FALSE
;
2670 // if set x to CW_USEDEFAULT, y parameter is ignored anyhow so we can
2671 // just as well set it to CW_USEDEFAULT as well
2678 y
= pos
.y
== -1 ? CW_USEDEFAULT
: pos
.y
;
2684 NB: there used to be some code here which set the initial size of the
2685 window to the client size of the parent if no explicit size was
2686 specified. This was wrong because wxWindows programs often assume
2687 that they get a WM_SIZE (EVT_SIZE) upon creation, however this broke
2688 it. To see why, you should understand that Windows sends WM_SIZE from
2689 inside ::CreateWindow() anyhow. However, ::CreateWindow() is called
2690 from some base class ctor and so this WM_SIZE is not processed in the
2691 real class' OnSize() (because it's not fully constructed yet and the
2692 event goes to some base class OnSize() instead). So the WM_SIZE we
2693 rely on is the one sent when the parent frame resizes its children
2694 but here is the problem: if the child already has just the right
2695 size, nothing will happen as both wxWindows and Windows check for
2696 this and ignore any attempts to change the window size to the size it
2697 already has - so no WM_SIZE would be sent.
2701 // as abobe, h is not used at all in this case anyhow
2708 h
= size
.y
== -1 ? CW_USEDEFAULT
: size
.y
;
2716 bool wxWindowMSW::MSWCreate(const wxChar
*wclass
,
2717 const wxChar
*title
,
2721 WXDWORD extendedStyle
)
2723 // choose the position/size for the new window
2725 (void)MSWGetCreateWindowCoords(pos
, size
, x
, y
, w
, h
);
2727 // find the correct parent HWND
2728 wxWindow
*parent
= GetParent();
2729 bool isChild
= (style
& WS_CHILD
) != 0;
2731 if ( GetWindowStyleFlag() & wxPOPUP_WINDOW
)
2733 // popup windows should have desktop as parent because they shouldn't
2734 // be limited to the parents client area as child windows usually are
2735 hParent
= ::GetDesktopWindow();
2739 if ( (isChild
|| HasFlag(wxFRAME_TOOL_WINDOW
)) && parent
)
2741 // this is either a normal child window or a top level window with
2742 // wxFRAME_TOOL_WINDOW style (see below)
2743 hParent
= GetHwndOf(parent
);
2747 // this is either a window for which no parent was specified (not
2748 // much we can do then) or a frame without wxFRAME_TOOL_WINDOW
2749 // style: we should use NULL parent HWND for it or it would be
2750 // always on top of its parent which is not what we usually want
2751 // (in fact, we only want it for frames with the special
2752 // wxFRAME_TOOL_WINDOW as above)
2758 // controlId is menu handle for the top level windows, so set it to 0
2759 // unless we're creating a child window
2763 controlId
= GetId();
2765 if ( GetWindowStyleFlag() & wxCLIP_SIBLINGS
)
2767 style
|= WS_CLIPSIBLINGS
;
2775 // for each class "Foo" we have we also have "FooNR" ("no repaint") class
2776 // which is the same but without CS_[HV]REDRAW class styles so using it
2777 // ensures that the window is not fully repainted on each resize
2778 wxString
className(wclass
);
2779 if ( GetWindowStyleFlag() & wxNO_FULL_REPAINT_ON_RESIZE
)
2781 className
+= wxT("NR");
2784 // do create the window
2785 wxWindowCreationHook
hook(this);
2787 m_hWnd
= (WXHWND
)::CreateWindowEx
2791 title
? title
: wxT(""),
2797 NULL
// no extra data
2802 wxLogSysError(_("Can't create window of class %s"), wclass
);
2807 SubclassWin(m_hWnd
);
2809 SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT
));
2814 // ===========================================================================
2815 // MSW message handlers
2816 // ===========================================================================
2818 // ---------------------------------------------------------------------------
2820 // ---------------------------------------------------------------------------
2823 // FIXME: VZ: I'm not sure at all that the order of processing is correct
2824 bool wxWindowMSW::HandleNotify(int idCtrl
, WXLPARAM lParam
, WXLPARAM
*result
)
2826 #ifndef __WXMICROWIN__
2827 LPNMHDR hdr
= (LPNMHDR
)lParam
;
2828 HWND hWnd
= hdr
->hwndFrom
;
2829 wxWindow
*win
= wxFindWinFromHandle((WXHWND
)hWnd
);
2831 // is this one of our windows?
2834 return win
->MSWOnNotify(idCtrl
, lParam
, result
);
2837 // try all our children
2838 wxWindowList::Node
*node
= GetChildren().GetFirst();
2841 wxWindow
*child
= node
->GetData();
2842 if ( child
->MSWOnNotify(idCtrl
, lParam
, result
) )
2847 node
= node
->GetNext();
2850 // finally try this window too (catches toolbar case)
2851 return MSWOnNotify(idCtrl
, lParam
, result
);
2852 #else // __WXMICROWIN__
2857 bool wxWindowMSW::MSWOnNotify(int WXUNUSED(idCtrl
),
2859 WXLPARAM
* WXUNUSED(result
))
2862 NMHDR
* hdr
= (NMHDR
*)lParam
;
2863 if ( (int)hdr
->code
== TTN_NEEDTEXT
&& m_tooltip
)
2865 TOOLTIPTEXT
*ttt
= (TOOLTIPTEXT
*)lParam
;
2866 ttt
->lpszText
= (wxChar
*)m_tooltip
->GetTip().c_str();
2871 #endif // wxUSE_TOOLTIPS
2877 // ---------------------------------------------------------------------------
2878 // end session messages
2879 // ---------------------------------------------------------------------------
2881 bool wxWindowMSW::HandleQueryEndSession(long logOff
, bool *mayEnd
)
2883 wxCloseEvent
event(wxEVT_QUERY_END_SESSION
, -1);
2884 event
.SetEventObject(wxTheApp
);
2885 event
.SetCanVeto(TRUE
);
2886 event
.SetLoggingOff(logOff
== (long)ENDSESSION_LOGOFF
);
2888 bool rc
= wxTheApp
->ProcessEvent(event
);
2892 // we may end only if the app didn't veto session closing (double
2894 *mayEnd
= !event
.GetVeto();
2900 bool wxWindowMSW::HandleEndSession(bool endSession
, long logOff
)
2902 // do nothing if the session isn't ending
2907 if ( (this != wxTheApp
->GetTopWindow()) )
2910 wxCloseEvent
event(wxEVT_END_SESSION
, -1);
2911 event
.SetEventObject(wxTheApp
);
2912 event
.SetCanVeto(FALSE
);
2913 event
.SetLoggingOff( (logOff
== (long)ENDSESSION_LOGOFF
) );
2915 return wxTheApp
->ProcessEvent(event
);
2918 // ---------------------------------------------------------------------------
2919 // window creation/destruction
2920 // ---------------------------------------------------------------------------
2922 bool wxWindowMSW::HandleCreate(WXLPCREATESTRUCT
WXUNUSED(cs
), bool *mayCreate
)
2924 // TODO: should generate this event from WM_NCCREATE
2925 wxWindowCreateEvent
event((wxWindow
*)this);
2926 (void)GetEventHandler()->ProcessEvent(event
);
2933 bool wxWindowMSW::HandleDestroy()
2935 wxWindowDestroyEvent
event((wxWindow
*)this);
2936 (void)GetEventHandler()->ProcessEvent(event
);
2938 // delete our drop target if we've got one
2939 #if wxUSE_DRAG_AND_DROP
2940 if ( m_dropTarget
!= NULL
)
2942 m_dropTarget
->Revoke(m_hWnd
);
2944 delete m_dropTarget
;
2945 m_dropTarget
= NULL
;
2947 #endif // wxUSE_DRAG_AND_DROP
2949 // WM_DESTROY handled
2953 // ---------------------------------------------------------------------------
2955 // ---------------------------------------------------------------------------
2957 bool wxWindowMSW::HandleActivate(int state
,
2958 bool WXUNUSED(minimized
),
2959 WXHWND
WXUNUSED(activate
))
2961 wxActivateEvent
event(wxEVT_ACTIVATE
,
2962 (state
== WA_ACTIVE
) || (state
== WA_CLICKACTIVE
),
2964 event
.SetEventObject(this);
2966 return GetEventHandler()->ProcessEvent(event
);
2969 bool wxWindowMSW::HandleSetFocus(WXHWND hwnd
)
2971 // notify the parent keeping track of focus for the kbd navigation
2972 // purposes that we got it
2973 wxChildFocusEvent
eventFocus((wxWindow
*)this);
2974 (void)GetEventHandler()->ProcessEvent(eventFocus
);
2980 m_caret
->OnSetFocus();
2982 #endif // wxUSE_CARET
2985 // If it's a wxTextCtrl don't send the event as it will be done
2986 // after the control gets to process it from EN_FOCUS handler
2987 if ( wxDynamicCastThis(wxTextCtrl
) )
2991 #endif // wxUSE_TEXTCTRL
2993 wxFocusEvent
event(wxEVT_SET_FOCUS
, m_windowId
);
2994 event
.SetEventObject(this);
2996 // wxFindWinFromHandle() may return NULL, it is ok
2997 event
.SetWindow(wxFindWinFromHandle(hwnd
));
2999 return GetEventHandler()->ProcessEvent(event
);
3002 bool wxWindowMSW::HandleKillFocus(WXHWND hwnd
)
3008 m_caret
->OnKillFocus();
3010 #endif // wxUSE_CARET
3013 // If it's a wxTextCtrl don't send the event as it will be done
3014 // after the control gets to process it.
3015 wxTextCtrl
*ctrl
= wxDynamicCastThis(wxTextCtrl
);
3022 wxFocusEvent
event(wxEVT_KILL_FOCUS
, m_windowId
);
3023 event
.SetEventObject(this);
3025 // wxFindWinFromHandle() may return NULL, it is ok
3026 event
.SetWindow(wxFindWinFromHandle(hwnd
));
3028 return GetEventHandler()->ProcessEvent(event
);
3031 // ---------------------------------------------------------------------------
3033 // ---------------------------------------------------------------------------
3035 bool wxWindowMSW::HandleShow(bool show
, int WXUNUSED(status
))
3037 wxShowEvent
event(GetId(), show
);
3038 event
.m_eventObject
= this;
3040 return GetEventHandler()->ProcessEvent(event
);
3043 bool wxWindowMSW::HandleInitDialog(WXHWND
WXUNUSED(hWndFocus
))
3045 wxInitDialogEvent
event(GetId());
3046 event
.m_eventObject
= this;
3048 return GetEventHandler()->ProcessEvent(event
);
3051 bool wxWindowMSW::HandleDropFiles(WXWPARAM wParam
)
3053 #ifndef __WXMICROWIN__
3054 HDROP hFilesInfo
= (HDROP
) wParam
;
3056 // Get the total number of files dropped
3057 UINT gwFilesDropped
= ::DragQueryFile
3065 wxString
*files
= new wxString
[gwFilesDropped
];
3066 for ( UINT wIndex
= 0; wIndex
< gwFilesDropped
; wIndex
++ )
3068 // first get the needed buffer length (+1 for terminating NUL)
3069 size_t len
= ::DragQueryFile(hFilesInfo
, wIndex
, NULL
, 0) + 1;
3071 // and now get the file name
3072 ::DragQueryFile(hFilesInfo
, wIndex
,
3073 files
[wIndex
].GetWriteBuf(len
), len
);
3075 files
[wIndex
].UngetWriteBuf();
3077 DragFinish (hFilesInfo
);
3079 wxDropFilesEvent
event(wxEVT_DROP_FILES
, gwFilesDropped
, files
);
3080 event
.m_eventObject
= this;
3083 DragQueryPoint(hFilesInfo
, (LPPOINT
) &dropPoint
);
3084 event
.m_pos
.x
= dropPoint
.x
;
3085 event
.m_pos
.y
= dropPoint
.y
;
3087 return GetEventHandler()->ProcessEvent(event
);
3088 #else // __WXMICROWIN__
3093 bool wxWindowMSW::HandleSetCursor(WXHWND
WXUNUSED(hWnd
),
3095 int WXUNUSED(mouseMsg
))
3097 #ifndef __WXMICROWIN__
3098 // the logic is as follows:
3099 // -1. don't set cursor for non client area, including but not limited to
3100 // the title bar, scrollbars, &c
3101 // 0. allow the user to override default behaviour by using EVT_SET_CURSOR
3102 // 1. if we have the cursor set it unless wxIsBusy()
3103 // 2. if we're a top level window, set some cursor anyhow
3104 // 3. if wxIsBusy(), set the busy cursor, otherwise the global one
3106 if ( nHitTest
!= HTCLIENT
)
3111 HCURSOR hcursor
= 0;
3113 // first ask the user code - it may wish to set the cursor in some very
3114 // specific way (for example, depending on the current position)
3117 if ( !::GetCursorPos(&pt
) )
3119 wxLogLastError(wxT("GetCursorPos"));
3122 // In WIN16 it doesn't return a value.
3123 ::GetCursorPos(&pt
);
3128 ScreenToClient(&x
, &y
);
3129 wxSetCursorEvent
event(x
, y
);
3131 bool processedEvtSetCursor
= GetEventHandler()->ProcessEvent(event
);
3132 if ( processedEvtSetCursor
&& event
.HasCursor() )
3134 hcursor
= GetHcursorOf(event
.GetCursor());
3139 bool isBusy
= wxIsBusy();
3141 // the test for processedEvtSetCursor is here to prevent using m_cursor
3142 // if the user code caught EVT_SET_CURSOR() and returned nothing from
3143 // it - this is a way to say that our cursor shouldn't be used for this
3145 if ( !processedEvtSetCursor
&& m_cursor
.Ok() )
3147 hcursor
= GetHcursorOf(m_cursor
);
3154 hcursor
= wxGetCurrentBusyCursor();
3156 else if ( !hcursor
)
3158 const wxCursor
*cursor
= wxGetGlobalCursor();
3159 if ( cursor
&& cursor
->Ok() )
3161 hcursor
= GetHcursorOf(*cursor
);
3169 ::SetCursor(hcursor
);
3171 // cursor set, stop here
3174 #endif // __WXMICROWIN__
3176 // pass up the window chain
3180 // ---------------------------------------------------------------------------
3181 // owner drawn stuff
3182 // ---------------------------------------------------------------------------
3184 bool wxWindowMSW::MSWOnDrawItem(int id
, WXDRAWITEMSTRUCT
*itemStruct
)
3186 #if wxUSE_OWNER_DRAWN
3188 #if wxUSE_MENUS_NATIVE
3189 // is it a menu item?
3190 DRAWITEMSTRUCT
*pDrawStruct
= (DRAWITEMSTRUCT
*)itemStruct
;
3191 if ( id
== 0 && pDrawStruct
->CtlType
== ODT_MENU
)
3193 wxMenuItem
*pMenuItem
= (wxMenuItem
*)(pDrawStruct
->itemData
);
3195 wxCHECK( pMenuItem
->IsKindOf(CLASSINFO(wxMenuItem
)), FALSE
);
3197 // prepare to call OnDrawItem(): notice using of wxDCTemp to prevent
3198 // the DC from being released
3199 wxDCTemp
dc((WXHDC
)pDrawStruct
->hDC
);
3200 wxRect
rect(pDrawStruct
->rcItem
.left
, pDrawStruct
->rcItem
.top
,
3201 pDrawStruct
->rcItem
.right
- pDrawStruct
->rcItem
.left
,
3202 pDrawStruct
->rcItem
.bottom
- pDrawStruct
->rcItem
.top
);
3204 return pMenuItem
->OnDrawItem
3208 (wxOwnerDrawn::wxODAction
)pDrawStruct
->itemAction
,
3209 (wxOwnerDrawn::wxODStatus
)pDrawStruct
->itemState
3212 #endif // wxUSE_MENUS_NATIVE
3215 wxWindow
*item
= FindItem(id
);
3216 if ( item
&& item
->IsKindOf(CLASSINFO(wxControl
)) )
3218 return ((wxControl
*)item
)->MSWOnDraw(itemStruct
);
3220 #endif // wxUSE_CONTROLS
3222 #endif // USE_OWNER_DRAWN
3227 bool wxWindowMSW::MSWOnMeasureItem(int id
, WXMEASUREITEMSTRUCT
*itemStruct
)
3229 #if wxUSE_OWNER_DRAWN
3230 // is it a menu item?
3231 MEASUREITEMSTRUCT
*pMeasureStruct
= (MEASUREITEMSTRUCT
*)itemStruct
;
3232 if ( id
== 0 && pMeasureStruct
->CtlType
== ODT_MENU
)
3234 wxMenuItem
*pMenuItem
= (wxMenuItem
*)(pMeasureStruct
->itemData
);
3236 wxCHECK( pMenuItem
->IsKindOf(CLASSINFO(wxMenuItem
)), FALSE
);
3238 return pMenuItem
->OnMeasureItem(&pMeasureStruct
->itemWidth
,
3239 &pMeasureStruct
->itemHeight
);
3242 wxWindow
*item
= FindItem(id
);
3243 if ( item
&& item
->IsKindOf(CLASSINFO(wxControl
)) )
3245 return ((wxControl
*)item
)->MSWOnMeasure(itemStruct
);
3247 #endif // owner-drawn menus
3251 // ---------------------------------------------------------------------------
3252 // colours and palettes
3253 // ---------------------------------------------------------------------------
3255 bool wxWindowMSW::HandleSysColorChange()
3257 wxSysColourChangedEvent event
;
3258 event
.SetEventObject(this);
3260 return GetEventHandler()->ProcessEvent(event
);
3263 bool wxWindowMSW::HandleCtlColor(WXHBRUSH
*brush
,
3271 #ifndef __WXMICROWIN__
3272 WXHBRUSH hBrush
= 0;
3274 if ( nCtlColor
== CTLCOLOR_DLG
)
3276 hBrush
= OnCtlColor(pDC
, pWnd
, nCtlColor
, message
, wParam
, lParam
);
3281 wxControl
*item
= (wxControl
*)FindItemByHWND(pWnd
, TRUE
);
3283 hBrush
= item
->OnCtlColor(pDC
, pWnd
, nCtlColor
, message
, wParam
, lParam
);
3285 #endif // wxUSE_CONTROLS
3291 #else // __WXMICROWIN__
3296 // Define for each class of dialog and control
3297 WXHBRUSH
wxWindowMSW::OnCtlColor(WXHDC
WXUNUSED(hDC
),
3298 WXHWND
WXUNUSED(hWnd
),
3299 WXUINT
WXUNUSED(nCtlColor
),
3300 WXUINT
WXUNUSED(message
),
3301 WXWPARAM
WXUNUSED(wParam
),
3302 WXLPARAM
WXUNUSED(lParam
))
3307 bool wxWindowMSW::HandlePaletteChanged(WXHWND hWndPalChange
)
3309 wxPaletteChangedEvent
event(GetId());
3310 event
.SetEventObject(this);
3311 event
.SetChangedWindow(wxFindWinFromHandle(hWndPalChange
));
3313 return GetEventHandler()->ProcessEvent(event
);
3316 bool wxWindowMSW::HandleQueryNewPalette()
3318 wxQueryNewPaletteEvent
event(GetId());
3319 event
.SetEventObject(this);
3321 return GetEventHandler()->ProcessEvent(event
) && event
.GetPaletteRealized();
3324 // Responds to colour changes: passes event on to children.
3325 void wxWindowMSW::OnSysColourChanged(wxSysColourChangedEvent
& event
)
3327 wxNode
*node
= GetChildren().First();
3330 // Only propagate to non-top-level windows
3331 wxWindow
*win
= (wxWindow
*)node
->Data();
3332 if ( win
->GetParent() )
3334 wxSysColourChangedEvent event2
;
3335 event
.m_eventObject
= win
;
3336 win
->GetEventHandler()->ProcessEvent(event2
);
3339 node
= node
->Next();
3343 // ---------------------------------------------------------------------------
3345 // ---------------------------------------------------------------------------
3347 bool wxWindowMSW::HandlePaint()
3350 HRGN hRegion
= ::CreateRectRgn(0, 0, 0, 0); // Dummy call to get a handle
3352 wxLogLastError(wxT("CreateRectRgn"));
3353 if ( ::GetUpdateRgn(GetHwnd(), hRegion
, FALSE
) == ERROR
)
3354 wxLogLastError(wxT("GetUpdateRgn"));
3356 m_updateRegion
= wxRegion((WXHRGN
) hRegion
);
3359 ::GetUpdateRect(GetHwnd(), &updateRect
, FALSE
);
3361 m_updateRegion
= wxRegion(updateRect
.left
, updateRect
.top
,
3362 updateRect
.right
- updateRect
.left
,
3363 updateRect
.bottom
- updateRect
.top
);
3366 wxPaintEvent
event(m_windowId
);
3367 event
.SetEventObject(this);
3369 bool processed
= GetEventHandler()->ProcessEvent(event
);
3371 // note that we must generate NC event after the normal one as otherwise
3372 // BeginPaint() will happily overwrite our decorations with the background
3374 wxNcPaintEvent
eventNc(m_windowId
);
3375 eventNc
.SetEventObject(this);
3376 GetEventHandler()->ProcessEvent(eventNc
);
3381 // Can be called from an application's OnPaint handler
3382 void wxWindowMSW::OnPaint(wxPaintEvent
& event
)
3384 #ifdef __WXUNIVERSAL__
3387 HDC hDC
= (HDC
) wxPaintDC::FindDCInCache((wxWindow
*) event
.GetEventObject());
3390 MSWDefWindowProc(WM_PAINT
, (WPARAM
) hDC
, 0);
3395 bool wxWindowMSW::HandleEraseBkgnd(WXHDC hdc
)
3397 // Prevents flicker when dragging
3398 if ( ::IsIconic(GetHwnd()) )
3404 dc
.SetWindow((wxWindow
*)this);
3407 wxEraseEvent
event(m_windowId
, &dc
);
3408 event
.SetEventObject(this);
3409 bool rc
= GetEventHandler()->ProcessEvent(event
);
3413 // must be called manually as ~wxDC doesn't do anything for wxDCTemp
3414 dc
.SelectOldObjects(hdc
);
3419 void wxWindowMSW::OnEraseBackground(wxEraseEvent
& event
)
3422 ::GetClientRect(GetHwnd(), &rect
);
3424 COLORREF ref
= PALETTERGB(m_backgroundColour
.Red(),
3425 m_backgroundColour
.Green(),
3426 m_backgroundColour
.Blue());
3427 HBRUSH hBrush
= ::CreateSolidBrush(ref
);
3429 wxLogLastError(wxT("CreateSolidBrush"));
3431 HDC hdc
= (HDC
)event
.GetDC()->GetHDC();
3433 int mode
= ::SetMapMode(hdc
, MM_TEXT
);
3435 ::FillRect(hdc
, &rect
, hBrush
);
3436 ::DeleteObject(hBrush
);
3437 ::SetMapMode(hdc
, mode
);
3440 // ---------------------------------------------------------------------------
3441 // moving and resizing
3442 // ---------------------------------------------------------------------------
3444 bool wxWindowMSW::HandleMinimize()
3446 wxIconizeEvent
event(m_windowId
);
3447 event
.SetEventObject(this);
3449 return GetEventHandler()->ProcessEvent(event
);
3452 bool wxWindowMSW::HandleMaximize()
3454 wxMaximizeEvent
event(m_windowId
);
3455 event
.SetEventObject(this);
3457 return GetEventHandler()->ProcessEvent(event
);
3460 bool wxWindowMSW::HandleMove(int x
, int y
)
3462 wxMoveEvent
event(wxPoint(x
, y
), m_windowId
);
3463 event
.SetEventObject(this);
3465 return GetEventHandler()->ProcessEvent(event
);
3468 bool wxWindowMSW::HandleSize(int w
, int h
, WXUINT
WXUNUSED(flag
))
3470 wxSizeEvent
event(wxSize(w
, h
), m_windowId
);
3471 event
.SetEventObject(this);
3473 return GetEventHandler()->ProcessEvent(event
);
3476 bool wxWindowMSW::HandleGetMinMaxInfo(void *mmInfo
)
3478 MINMAXINFO
*info
= (MINMAXINFO
*)mmInfo
;
3482 if ( m_minWidth
!= -1 )
3484 info
->ptMinTrackSize
.x
= m_minWidth
;
3488 if ( m_minHeight
!= -1 )
3490 info
->ptMinTrackSize
.y
= m_minHeight
;
3494 if ( m_maxWidth
!= -1 )
3496 info
->ptMaxTrackSize
.x
= m_maxWidth
;
3500 if ( m_maxHeight
!= -1 )
3502 info
->ptMaxTrackSize
.y
= m_maxHeight
;
3509 // ---------------------------------------------------------------------------
3511 // ---------------------------------------------------------------------------
3513 bool wxWindowMSW::HandleCommand(WXWORD id
, WXWORD cmd
, WXHWND control
)
3515 #if wxUSE_MENUS_NATIVE
3516 if ( !cmd
&& wxCurrentPopupMenu
)
3518 wxMenu
*popupMenu
= wxCurrentPopupMenu
;
3519 wxCurrentPopupMenu
= NULL
;
3521 return popupMenu
->MSWCommand(cmd
, id
);
3523 #endif // wxUSE_MENUS_NATIVE
3525 wxWindow
*win
= NULL
;
3527 // first try to find it from HWND - this works even with the broken
3528 // programs using the same ids for different controls
3531 win
= wxFindWinFromHandle(control
);
3537 // must cast to a signed type before comparing with other ids!
3538 win
= FindItem((signed short)id
);
3543 return win
->MSWCommand(cmd
, id
);
3546 // the messages sent from the in-place edit control used by the treectrl
3547 // for label editing have id == 0, but they should _not_ be treated as menu
3548 // messages (they are EN_XXX ones, in fact) so don't translate anything
3549 // coming from a control to wxEVT_COMMAND_MENU_SELECTED
3552 // If no child window, it may be an accelerator, e.g. for a popup menu
3555 wxCommandEvent
event(wxEVT_COMMAND_MENU_SELECTED
);
3556 event
.SetEventObject(this);
3560 return GetEventHandler()->ProcessEvent(event
);
3562 #if wxUSE_SPINCTRL && !defined(__WXUNIVERSAL__)
3565 // the text ctrl which is logically part of wxSpinCtrl sends WM_COMMAND
3566 // notifications to its parent which we want to reflect back to
3568 wxSpinCtrl
*spin
= wxSpinCtrl::GetSpinForTextCtrl(control
);
3569 if ( spin
&& spin
->ProcessTextCommand(cmd
, id
) )
3572 #endif // wxUSE_SPINCTRL
3577 bool wxWindowMSW::HandleSysCommand(WXWPARAM wParam
, WXLPARAM
WXUNUSED(lParam
))
3579 // 4 bits are reserved
3580 switch ( wParam
& 0xFFFFFFF0 )
3583 return HandleMaximize();
3586 return HandleMinimize();
3592 // ---------------------------------------------------------------------------
3594 // ---------------------------------------------------------------------------
3596 void wxWindowMSW::InitMouseEvent(wxMouseEvent
& event
,
3600 // our client coords are not quite the same as Windows ones
3601 wxPoint pt
= GetClientAreaOrigin();
3602 event
.m_x
= x
- pt
.x
;
3603 event
.m_y
= y
- pt
.y
;
3605 event
.m_shiftDown
= (flags
& MK_SHIFT
) != 0;
3606 event
.m_controlDown
= (flags
& MK_CONTROL
) != 0;
3607 event
.m_leftDown
= (flags
& MK_LBUTTON
) != 0;
3608 event
.m_middleDown
= (flags
& MK_MBUTTON
) != 0;
3609 event
.m_rightDown
= (flags
& MK_RBUTTON
) != 0;
3610 event
.m_altDown
= (::GetKeyState(VK_MENU
) & 0x80000000) != 0;
3612 event
.SetTimestamp(s_currentMsg
.time
);
3613 event
.m_eventObject
= this;
3615 #if wxUSE_MOUSEEVENT_HACK
3618 m_lastMouseEvent
= event
.GetEventType();
3619 #endif // wxUSE_MOUSEEVENT_HACK
3622 bool wxWindowMSW::HandleMouseEvent(WXUINT msg
, int x
, int y
, WXUINT flags
)
3624 // the mouse events take consecutive IDs from WM_MOUSEFIRST to
3625 // WM_MOUSELAST, so it's enough to substract WM_MOUSEMOVE == WM_MOUSEFIRST
3626 // from the message id and take the value in the table to get wxWin event
3628 static const wxEventType eventsMouse
[] =
3642 wxMouseEvent
event(eventsMouse
[msg
- WM_MOUSEMOVE
]);
3643 InitMouseEvent(event
, x
, y
, flags
);
3645 return GetEventHandler()->ProcessEvent(event
);
3648 bool wxWindowMSW::HandleMouseMove(int x
, int y
, WXUINT flags
)
3650 if ( !m_mouseInWindow
)
3652 // it would be wrong to assume that just because we get a mouse move
3653 // event that the mouse is inside the window: although this is usually
3654 // true, it is not if we had captured the mouse, so we need to check
3655 // the mouse coordinates here
3656 if ( !HasCapture() || IsMouseInWindow() )
3658 // Generate an ENTER event
3659 m_mouseInWindow
= TRUE
;
3661 wxMouseEvent
event(wxEVT_ENTER_WINDOW
);
3662 InitMouseEvent(event
, x
, y
, flags
);
3664 (void)GetEventHandler()->ProcessEvent(event
);
3668 #if wxUSE_MOUSEEVENT_HACK
3669 // Window gets a click down message followed by a mouse move message even
3670 // if position isn't changed! We want to discard the trailing move event
3671 // if x and y are the same.
3672 if ( (m_lastMouseEvent
== wxEVT_RIGHT_DOWN
||
3673 m_lastMouseEvent
== wxEVT_LEFT_DOWN
||
3674 m_lastMouseEvent
== wxEVT_MIDDLE_DOWN
) &&
3675 (m_lastMouseX
== x
&& m_lastMouseY
== y
) )
3677 m_lastMouseEvent
= wxEVT_MOTION
;
3681 #endif // wxUSE_MOUSEEVENT_HACK
3683 return HandleMouseEvent(WM_MOUSEMOVE
, x
, y
, flags
);
3687 bool wxWindowMSW::HandleMouseWheel(WXWPARAM wParam
, WXLPARAM lParam
)
3689 #if wxUSE_MOUSEWHEEL
3690 wxMouseEvent
event(wxEVT_MOUSEWHEEL
);
3691 InitMouseEvent(event
,
3692 GET_X_LPARAM(lParam
),
3693 GET_Y_LPARAM(lParam
),
3695 event
.m_wheelRotation
= (short)HIWORD(wParam
);
3696 event
.m_wheelDelta
= WHEEL_DELTA
;
3699 static int s_linesPerRotation
= -1;
3700 if ( s_linesPerRotation
== -1 )
3702 if ( !::SystemParametersInfo(SPI_GETWHEELSCROLLLINES
, 0,
3703 &s_linesPerRotation
, 0))
3705 // this is not supposed to happen
3706 wxLogLastError(_T("SystemParametersInfo(GETWHEELSCROLLLINES)"));
3708 // the default is 3, so use it if SystemParametersInfo() failed
3709 s_linesPerRotation
= 3;
3713 // no SystemParametersInfo() under Win16
3714 static const int s_linesPerRotation
= 3;
3717 event
.m_linesPerAction
= s_linesPerRotation
;
3718 return GetEventHandler()->ProcessEvent(event
);
3729 // ---------------------------------------------------------------------------
3730 // keyboard handling
3731 // ---------------------------------------------------------------------------
3733 // create the key event of the given type for the given key - used by
3734 // HandleChar and HandleKeyDown/Up
3735 wxKeyEvent
wxWindowMSW::CreateKeyEvent(wxEventType evType
,
3737 WXLPARAM lParam
) const
3739 wxKeyEvent
event(evType
);
3740 event
.SetId(GetId());
3741 event
.m_shiftDown
= wxIsShiftDown();
3742 event
.m_controlDown
= wxIsCtrlDown();
3743 event
.m_altDown
= (HIWORD(lParam
) & KF_ALTDOWN
) == KF_ALTDOWN
;
3745 event
.m_eventObject
= (wxWindow
*)this; // const_cast
3746 event
.m_keyCode
= id
;
3747 event
.SetTimestamp(s_currentMsg
.time
);
3749 // translate the position to client coords
3753 GetWindowRect(GetHwnd(),&rect
);
3763 // isASCII is TRUE only when we're called from WM_CHAR handler and not from
3765 bool wxWindowMSW::HandleChar(WXWPARAM wParam
, WXLPARAM lParam
, bool isASCII
)
3767 bool ctrlDown
= FALSE
;
3772 // If 1 -> 26, translate to CTRL plus a letter.
3774 if ( (id
> 0) && (id
< 27) )
3796 else if ( (id
= wxCharCodeMSWToWX(wParam
)) == 0 )
3798 // it's ASCII and will be processed here only when called from
3799 // WM_CHAR (i.e. when isASCII = TRUE), don't process it now
3805 wxKeyEvent
event(CreateKeyEvent(wxEVT_CHAR
, id
, lParam
));
3808 event
.m_controlDown
= TRUE
;
3811 if ( GetEventHandler()->ProcessEvent(event
) )
3818 bool wxWindowMSW::HandleKeyDown(WXWPARAM wParam
, WXLPARAM lParam
)
3820 int id
= wxCharCodeMSWToWX(wParam
);
3824 // normal ASCII char
3828 if ( id
!= -1 ) // VZ: does this ever happen (FIXME)?
3830 wxKeyEvent
event(CreateKeyEvent(wxEVT_KEY_DOWN
, id
, lParam
));
3831 if ( GetEventHandler()->ProcessEvent(event
) )
3840 bool wxWindowMSW::HandleKeyUp(WXWPARAM wParam
, WXLPARAM lParam
)
3842 int id
= wxCharCodeMSWToWX(wParam
);
3846 // normal ASCII char
3850 if ( id
!= -1 ) // VZ: does this ever happen (FIXME)?
3852 wxKeyEvent
event(CreateKeyEvent(wxEVT_KEY_UP
, id
, lParam
));
3853 if ( GetEventHandler()->ProcessEvent(event
) )
3860 // ---------------------------------------------------------------------------
3862 // ---------------------------------------------------------------------------
3864 bool wxWindowMSW::HandleJoystickEvent(WXUINT msg
, int x
, int y
, WXUINT flags
)
3868 if ( flags
& JOY_BUTTON1CHG
)
3869 change
= wxJOY_BUTTON1
;
3870 if ( flags
& JOY_BUTTON2CHG
)
3871 change
= wxJOY_BUTTON2
;
3872 if ( flags
& JOY_BUTTON3CHG
)
3873 change
= wxJOY_BUTTON3
;
3874 if ( flags
& JOY_BUTTON4CHG
)
3875 change
= wxJOY_BUTTON4
;
3878 if ( flags
& JOY_BUTTON1
)
3879 buttons
|= wxJOY_BUTTON1
;
3880 if ( flags
& JOY_BUTTON2
)
3881 buttons
|= wxJOY_BUTTON2
;
3882 if ( flags
& JOY_BUTTON3
)
3883 buttons
|= wxJOY_BUTTON3
;
3884 if ( flags
& JOY_BUTTON4
)
3885 buttons
|= wxJOY_BUTTON4
;
3887 // the event ids aren't consecutive so we can't use table based lookup
3889 wxEventType eventType
;
3894 eventType
= wxEVT_JOY_MOVE
;
3899 eventType
= wxEVT_JOY_MOVE
;
3904 eventType
= wxEVT_JOY_ZMOVE
;
3909 eventType
= wxEVT_JOY_ZMOVE
;
3912 case MM_JOY1BUTTONDOWN
:
3914 eventType
= wxEVT_JOY_BUTTON_DOWN
;
3917 case MM_JOY2BUTTONDOWN
:
3919 eventType
= wxEVT_JOY_BUTTON_DOWN
;
3922 case MM_JOY1BUTTONUP
:
3924 eventType
= wxEVT_JOY_BUTTON_UP
;
3927 case MM_JOY2BUTTONUP
:
3929 eventType
= wxEVT_JOY_BUTTON_UP
;
3933 wxFAIL_MSG(wxT("no such joystick event"));
3938 wxJoystickEvent
event(eventType
, buttons
, joystick
, change
);
3939 event
.SetPosition(wxPoint(x
, y
));
3940 event
.SetEventObject(this);
3942 return GetEventHandler()->ProcessEvent(event
);
3948 // ---------------------------------------------------------------------------
3950 // ---------------------------------------------------------------------------
3952 bool wxWindowMSW::MSWOnScroll(int orientation
, WXWORD wParam
,
3953 WXWORD pos
, WXHWND control
)
3957 wxWindow
*child
= wxFindWinFromHandle(control
);
3959 return child
->MSWOnScroll(orientation
, wParam
, pos
, control
);
3962 wxScrollWinEvent event
;
3963 event
.SetPosition(pos
);
3964 event
.SetOrientation(orientation
);
3965 event
.m_eventObject
= this;
3970 event
.m_eventType
= wxEVT_SCROLLWIN_TOP
;
3974 event
.m_eventType
= wxEVT_SCROLLWIN_BOTTOM
;
3978 event
.m_eventType
= wxEVT_SCROLLWIN_LINEUP
;
3982 event
.m_eventType
= wxEVT_SCROLLWIN_LINEDOWN
;
3986 event
.m_eventType
= wxEVT_SCROLLWIN_PAGEUP
;
3990 event
.m_eventType
= wxEVT_SCROLLWIN_PAGEDOWN
;
3993 case SB_THUMBPOSITION
:
3996 // under Win32, the scrollbar range and position are 32 bit integers,
3997 // but WM_[HV]SCROLL only carry the low 16 bits of them, so we must
3998 // explicitly query the scrollbar for the correct position (this must
3999 // be done only for these two SB_ events as they are the only one
4000 // carrying the scrollbar position)
4002 SCROLLINFO scrollInfo
;
4003 wxZeroMemory(scrollInfo
);
4004 scrollInfo
.cbSize
= sizeof(SCROLLINFO
);
4005 scrollInfo
.fMask
= SIF_TRACKPOS
;
4007 if ( !::GetScrollInfo(GetHwnd(),
4008 orientation
== wxHORIZONTAL
? SB_HORZ
4012 wxLogLastError(_T("GetScrollInfo"));
4015 event
.SetPosition(scrollInfo
.nTrackPos
);
4019 event
.m_eventType
= wParam
== SB_THUMBPOSITION
4020 ? wxEVT_SCROLLWIN_THUMBRELEASE
4021 : wxEVT_SCROLLWIN_THUMBTRACK
;
4028 return GetEventHandler()->ProcessEvent(event
);
4031 // ===========================================================================
4033 // ===========================================================================
4035 void wxGetCharSize(WXHWND wnd
, int *x
, int *y
, const wxFont
*the_font
)
4038 HDC dc
= ::GetDC((HWND
) wnd
);
4043 // the_font->UseResource();
4044 // the_font->RealizeResource();
4045 fnt
= (HFONT
)((wxFont
*)the_font
)->GetResourceHandle(); // const_cast
4047 was
= (HFONT
) SelectObject(dc
,fnt
);
4049 GetTextMetrics(dc
, &tm
);
4050 if ( the_font
&& fnt
&& was
)
4052 SelectObject(dc
,was
);
4054 ReleaseDC((HWND
)wnd
, dc
);
4057 *x
= tm
.tmAveCharWidth
;
4059 *y
= tm
.tmHeight
+ tm
.tmExternalLeading
;
4062 // the_font->ReleaseResource();
4065 // Returns 0 if was a normal ASCII value, not a special key. This indicates that
4066 // the key should be ignored by WM_KEYDOWN and processed by WM_CHAR instead.
4067 int wxCharCodeMSWToWX(int keySym
)
4072 case VK_CANCEL
: id
= WXK_CANCEL
; break;
4073 case VK_BACK
: id
= WXK_BACK
; break;
4074 case VK_TAB
: id
= WXK_TAB
; break;
4075 case VK_CLEAR
: id
= WXK_CLEAR
; break;
4076 case VK_RETURN
: id
= WXK_RETURN
; break;
4077 case VK_SHIFT
: id
= WXK_SHIFT
; break;
4078 case VK_CONTROL
: id
= WXK_CONTROL
; break;
4079 case VK_MENU
: id
= WXK_MENU
; break;
4080 case VK_PAUSE
: id
= WXK_PAUSE
; break;
4081 case VK_SPACE
: id
= WXK_SPACE
; break;
4082 case VK_ESCAPE
: id
= WXK_ESCAPE
; break;
4083 case VK_PRIOR
: id
= WXK_PRIOR
; break;
4084 case VK_NEXT
: id
= WXK_NEXT
; break;
4085 case VK_END
: id
= WXK_END
; break;
4086 case VK_HOME
: id
= WXK_HOME
; break;
4087 case VK_LEFT
: id
= WXK_LEFT
; break;
4088 case VK_UP
: id
= WXK_UP
; break;
4089 case VK_RIGHT
: id
= WXK_RIGHT
; break;
4090 case VK_DOWN
: id
= WXK_DOWN
; break;
4091 case VK_SELECT
: id
= WXK_SELECT
; break;
4092 case VK_PRINT
: id
= WXK_PRINT
; break;
4093 case VK_EXECUTE
: id
= WXK_EXECUTE
; break;
4094 case VK_INSERT
: id
= WXK_INSERT
; break;
4095 case VK_DELETE
: id
= WXK_DELETE
; break;
4096 case VK_HELP
: id
= WXK_HELP
; break;
4097 case VK_NUMPAD0
: id
= WXK_NUMPAD0
; break;
4098 case VK_NUMPAD1
: id
= WXK_NUMPAD1
; break;
4099 case VK_NUMPAD2
: id
= WXK_NUMPAD2
; break;
4100 case VK_NUMPAD3
: id
= WXK_NUMPAD3
; break;
4101 case VK_NUMPAD4
: id
= WXK_NUMPAD4
; break;
4102 case VK_NUMPAD5
: id
= WXK_NUMPAD5
; break;
4103 case VK_NUMPAD6
: id
= WXK_NUMPAD6
; break;
4104 case VK_NUMPAD7
: id
= WXK_NUMPAD7
; break;
4105 case VK_NUMPAD8
: id
= WXK_NUMPAD8
; break;
4106 case VK_NUMPAD9
: id
= WXK_NUMPAD9
; break;
4107 case VK_MULTIPLY
: id
= WXK_NUMPAD_MULTIPLY
; break;
4108 case VK_ADD
: id
= WXK_NUMPAD_ADD
; break;
4109 case VK_SUBTRACT
: id
= WXK_NUMPAD_SUBTRACT
; break;
4110 case VK_DECIMAL
: id
= WXK_NUMPAD_DECIMAL
; break;
4111 case VK_DIVIDE
: id
= WXK_NUMPAD_DIVIDE
; break;
4112 case VK_F1
: id
= WXK_F1
; break;
4113 case VK_F2
: id
= WXK_F2
; break;
4114 case VK_F3
: id
= WXK_F3
; break;
4115 case VK_F4
: id
= WXK_F4
; break;
4116 case VK_F5
: id
= WXK_F5
; break;
4117 case VK_F6
: id
= WXK_F6
; break;
4118 case VK_F7
: id
= WXK_F7
; break;
4119 case VK_F8
: id
= WXK_F8
; break;
4120 case VK_F9
: id
= WXK_F9
; break;
4121 case VK_F10
: id
= WXK_F10
; break;
4122 case VK_F11
: id
= WXK_F11
; break;
4123 case VK_F12
: id
= WXK_F12
; break;
4124 case VK_F13
: id
= WXK_F13
; break;
4125 case VK_F14
: id
= WXK_F14
; break;
4126 case VK_F15
: id
= WXK_F15
; break;
4127 case VK_F16
: id
= WXK_F16
; break;
4128 case VK_F17
: id
= WXK_F17
; break;
4129 case VK_F18
: id
= WXK_F18
; break;
4130 case VK_F19
: id
= WXK_F19
; break;
4131 case VK_F20
: id
= WXK_F20
; break;
4132 case VK_F21
: id
= WXK_F21
; break;
4133 case VK_F22
: id
= WXK_F22
; break;
4134 case VK_F23
: id
= WXK_F23
; break;
4135 case VK_F24
: id
= WXK_F24
; break;
4136 case VK_NUMLOCK
: id
= WXK_NUMLOCK
; break;
4137 case VK_SCROLL
: id
= WXK_SCROLL
; break;
4145 int wxCharCodeWXToMSW(int id
, bool *isVirtual
)
4151 case WXK_CANCEL
: keySym
= VK_CANCEL
; break;
4152 case WXK_CLEAR
: keySym
= VK_CLEAR
; break;
4153 case WXK_SHIFT
: keySym
= VK_SHIFT
; break;
4154 case WXK_CONTROL
: keySym
= VK_CONTROL
; break;
4155 case WXK_MENU
: keySym
= VK_MENU
; break;
4156 case WXK_PAUSE
: keySym
= VK_PAUSE
; break;
4157 case WXK_PRIOR
: keySym
= VK_PRIOR
; break;
4158 case WXK_NEXT
: keySym
= VK_NEXT
; break;
4159 case WXK_END
: keySym
= VK_END
; break;
4160 case WXK_HOME
: keySym
= VK_HOME
; break;
4161 case WXK_LEFT
: keySym
= VK_LEFT
; break;
4162 case WXK_UP
: keySym
= VK_UP
; break;
4163 case WXK_RIGHT
: keySym
= VK_RIGHT
; break;
4164 case WXK_DOWN
: keySym
= VK_DOWN
; break;
4165 case WXK_SELECT
: keySym
= VK_SELECT
; break;
4166 case WXK_PRINT
: keySym
= VK_PRINT
; break;
4167 case WXK_EXECUTE
: keySym
= VK_EXECUTE
; break;
4168 case WXK_INSERT
: keySym
= VK_INSERT
; break;
4169 case WXK_DELETE
: keySym
= VK_DELETE
; break;
4170 case WXK_HELP
: keySym
= VK_HELP
; break;
4171 case WXK_NUMPAD0
: keySym
= VK_NUMPAD0
; break;
4172 case WXK_NUMPAD1
: keySym
= VK_NUMPAD1
; break;
4173 case WXK_NUMPAD2
: keySym
= VK_NUMPAD2
; break;
4174 case WXK_NUMPAD3
: keySym
= VK_NUMPAD3
; break;
4175 case WXK_NUMPAD4
: keySym
= VK_NUMPAD4
; break;
4176 case WXK_NUMPAD5
: keySym
= VK_NUMPAD5
; break;
4177 case WXK_NUMPAD6
: keySym
= VK_NUMPAD6
; break;
4178 case WXK_NUMPAD7
: keySym
= VK_NUMPAD7
; break;
4179 case WXK_NUMPAD8
: keySym
= VK_NUMPAD8
; break;
4180 case WXK_NUMPAD9
: keySym
= VK_NUMPAD9
; break;
4181 case WXK_NUMPAD_MULTIPLY
: keySym
= VK_MULTIPLY
; break;
4182 case WXK_NUMPAD_ADD
: keySym
= VK_ADD
; break;
4183 case WXK_NUMPAD_SUBTRACT
: keySym
= VK_SUBTRACT
; break;
4184 case WXK_NUMPAD_DECIMAL
: keySym
= VK_DECIMAL
; break;
4185 case WXK_NUMPAD_DIVIDE
: keySym
= VK_DIVIDE
; break;
4186 case WXK_F1
: keySym
= VK_F1
; break;
4187 case WXK_F2
: keySym
= VK_F2
; break;
4188 case WXK_F3
: keySym
= VK_F3
; break;
4189 case WXK_F4
: keySym
= VK_F4
; break;
4190 case WXK_F5
: keySym
= VK_F5
; break;
4191 case WXK_F6
: keySym
= VK_F6
; break;
4192 case WXK_F7
: keySym
= VK_F7
; break;
4193 case WXK_F8
: keySym
= VK_F8
; break;
4194 case WXK_F9
: keySym
= VK_F9
; break;
4195 case WXK_F10
: keySym
= VK_F10
; break;
4196 case WXK_F11
: keySym
= VK_F11
; break;
4197 case WXK_F12
: keySym
= VK_F12
; break;
4198 case WXK_F13
: keySym
= VK_F13
; break;
4199 case WXK_F14
: keySym
= VK_F14
; break;
4200 case WXK_F15
: keySym
= VK_F15
; break;
4201 case WXK_F16
: keySym
= VK_F16
; break;
4202 case WXK_F17
: keySym
= VK_F17
; break;
4203 case WXK_F18
: keySym
= VK_F18
; break;
4204 case WXK_F19
: keySym
= VK_F19
; break;
4205 case WXK_F20
: keySym
= VK_F20
; break;
4206 case WXK_F21
: keySym
= VK_F21
; break;
4207 case WXK_F22
: keySym
= VK_F22
; break;
4208 case WXK_F23
: keySym
= VK_F23
; break;
4209 case WXK_F24
: keySym
= VK_F24
; break;
4210 case WXK_NUMLOCK
: keySym
= VK_NUMLOCK
; break;
4211 case WXK_SCROLL
: keySym
= VK_SCROLL
; break;
4222 wxWindow
*wxGetActiveWindow()
4224 HWND hWnd
= GetActiveWindow();
4227 return wxFindWinFromHandle((WXHWND
) hWnd
);
4232 extern wxWindow
*wxGetWindowFromHWND(WXHWND hWnd
)
4234 HWND hwnd
= (HWND
)hWnd
;
4236 // For a radiobutton, we get the radiobox from GWL_USERDATA (which is set
4237 // by code in msw/radiobox.cpp), for all the others we just search up the
4239 wxWindow
*win
= (wxWindow
*)NULL
;
4242 win
= wxFindWinFromHandle((WXHWND
)hwnd
);
4245 // all these hacks only work under Win32 anyhow
4249 // native radiobuttons return DLGC_RADIOBUTTON here and for any
4250 // wxWindow class which overrides WM_GETDLGCODE processing to
4251 // do it as well, win would be already non NULL
4252 if ( ::SendMessage(hwnd
, WM_GETDLGCODE
, 0, 0) & DLGC_RADIOBUTTON
)
4254 win
= (wxWindow
*)::GetWindowLong(hwnd
, GWL_USERDATA
);
4256 //else: it's a wxRadioButton, not a radiobutton from wxRadioBox
4257 #endif // wxUSE_RADIOBOX
4259 // spin control text buddy window should be mapped to spin ctrl
4260 // itself so try it too
4261 #if wxUSE_SPINCTRL && !defined(__WXUNIVERSAL__)
4264 win
= wxSpinCtrl::GetSpinForTextCtrl((WXHWND
)hwnd
);
4266 #endif // wxUSE_SPINCTRL
4272 while ( hwnd
&& !win
)
4274 // this is a really ugly hack needed to avoid mistakenly returning the
4275 // parent frame wxWindow for the find/replace modeless dialog HWND -
4276 // this, in turn, is needed to call IsDialogMessage() from
4277 // wxApp::ProcessMessage() as for this we must return NULL from here
4279 // FIXME: this is clearly not the best way to do it but I think we'll
4280 // need to change HWND <-> wxWindow code more heavily than I can
4281 // do it now to fix it
4282 #ifndef __WXMICROWIN__
4283 if ( ::GetWindow(hwnd
, GW_OWNER
) )
4285 // it's a dialog box, don't go upwards
4290 hwnd
= ::GetParent(hwnd
);
4291 win
= wxFindWinFromHandle((WXHWND
)hwnd
);
4297 #ifndef __WXMICROWIN__
4299 // Windows keyboard hook. Allows interception of e.g. F1, ESCAPE
4300 // in active frames and dialogs, regardless of where the focus is.
4301 static HHOOK wxTheKeyboardHook
= 0;
4302 static FARPROC wxTheKeyboardHookProc
= 0;
4303 int APIENTRY _EXPORT
4304 wxKeyboardHook(int nCode
, WORD wParam
, DWORD lParam
);
4306 void wxSetKeyboardHook(bool doIt
)
4310 wxTheKeyboardHookProc
= MakeProcInstance((FARPROC
) wxKeyboardHook
, wxGetInstance());
4311 wxTheKeyboardHook
= SetWindowsHookEx(WH_KEYBOARD
, (HOOKPROC
) wxTheKeyboardHookProc
, wxGetInstance(),
4313 #if defined(__WIN32__) && !defined(__TWIN32__)
4314 GetCurrentThreadId()
4315 // (DWORD)GetCurrentProcess()); // This is another possibility. Which is right?
4323 UnhookWindowsHookEx(wxTheKeyboardHook
);
4325 // avoids warning about statement with no effect (FreeProcInstance
4326 // doesn't do anything under Win32)
4327 #if !defined(WIN32) && !defined(_WIN32) && !defined(__WIN32__) && !defined(__NT__) && !defined(__GNUWIN32__)
4328 FreeProcInstance(wxTheKeyboardHookProc
);
4333 int APIENTRY _EXPORT
4334 wxKeyboardHook(int nCode
, WORD wParam
, DWORD lParam
)
4336 DWORD hiWord
= HIWORD(lParam
);
4337 if ( nCode
!= HC_NOREMOVE
&& ((hiWord
& KF_UP
) == 0) )
4339 int id
= wxCharCodeMSWToWX(wParam
);
4342 wxKeyEvent
event(wxEVT_CHAR_HOOK
);
4343 if ( (HIWORD(lParam
) & KF_ALTDOWN
) == KF_ALTDOWN
)
4344 event
.m_altDown
= TRUE
;
4346 event
.m_eventObject
= NULL
;
4347 event
.m_keyCode
= id
;
4348 event
.m_shiftDown
= wxIsShiftDown();
4349 event
.m_controlDown
= wxIsCtrlDown();
4350 event
.SetTimestamp(s_currentMsg
.time
);
4352 wxWindow
*win
= wxGetActiveWindow();
4353 wxEvtHandler
*handler
;
4356 handler
= win
->GetEventHandler();
4357 event
.SetId(win
->GetId());
4365 if ( handler
&& handler
->ProcessEvent(event
) )
4373 return (int)CallNextHookEx(wxTheKeyboardHook
, nCode
, wParam
, lParam
);
4376 #endif // !__WXMICROWIN__
4379 const char *wxGetMessageName(int message
)
4383 case 0x0000: return "WM_NULL";
4384 case 0x0001: return "WM_CREATE";
4385 case 0x0002: return "WM_DESTROY";
4386 case 0x0003: return "WM_MOVE";
4387 case 0x0005: return "WM_SIZE";
4388 case 0x0006: return "WM_ACTIVATE";
4389 case 0x0007: return "WM_SETFOCUS";
4390 case 0x0008: return "WM_KILLFOCUS";
4391 case 0x000A: return "WM_ENABLE";
4392 case 0x000B: return "WM_SETREDRAW";
4393 case 0x000C: return "WM_SETTEXT";
4394 case 0x000D: return "WM_GETTEXT";
4395 case 0x000E: return "WM_GETTEXTLENGTH";
4396 case 0x000F: return "WM_PAINT";
4397 case 0x0010: return "WM_CLOSE";
4398 case 0x0011: return "WM_QUERYENDSESSION";
4399 case 0x0012: return "WM_QUIT";
4400 case 0x0013: return "WM_QUERYOPEN";
4401 case 0x0014: return "WM_ERASEBKGND";
4402 case 0x0015: return "WM_SYSCOLORCHANGE";
4403 case 0x0016: return "WM_ENDSESSION";
4404 case 0x0017: return "WM_SYSTEMERROR";
4405 case 0x0018: return "WM_SHOWWINDOW";
4406 case 0x0019: return "WM_CTLCOLOR";
4407 case 0x001A: return "WM_WININICHANGE";
4408 case 0x001B: return "WM_DEVMODECHANGE";
4409 case 0x001C: return "WM_ACTIVATEAPP";
4410 case 0x001D: return "WM_FONTCHANGE";
4411 case 0x001E: return "WM_TIMECHANGE";
4412 case 0x001F: return "WM_CANCELMODE";
4413 case 0x0020: return "WM_SETCURSOR";
4414 case 0x0021: return "WM_MOUSEACTIVATE";
4415 case 0x0022: return "WM_CHILDACTIVATE";
4416 case 0x0023: return "WM_QUEUESYNC";
4417 case 0x0024: return "WM_GETMINMAXINFO";
4418 case 0x0026: return "WM_PAINTICON";
4419 case 0x0027: return "WM_ICONERASEBKGND";
4420 case 0x0028: return "WM_NEXTDLGCTL";
4421 case 0x002A: return "WM_SPOOLERSTATUS";
4422 case 0x002B: return "WM_DRAWITEM";
4423 case 0x002C: return "WM_MEASUREITEM";
4424 case 0x002D: return "WM_DELETEITEM";
4425 case 0x002E: return "WM_VKEYTOITEM";
4426 case 0x002F: return "WM_CHARTOITEM";
4427 case 0x0030: return "WM_SETFONT";
4428 case 0x0031: return "WM_GETFONT";
4429 case 0x0037: return "WM_QUERYDRAGICON";
4430 case 0x0039: return "WM_COMPAREITEM";
4431 case 0x0041: return "WM_COMPACTING";
4432 case 0x0044: return "WM_COMMNOTIFY";
4433 case 0x0046: return "WM_WINDOWPOSCHANGING";
4434 case 0x0047: return "WM_WINDOWPOSCHANGED";
4435 case 0x0048: return "WM_POWER";
4438 case 0x004A: return "WM_COPYDATA";
4439 case 0x004B: return "WM_CANCELJOURNAL";
4440 case 0x004E: return "WM_NOTIFY";
4441 case 0x0050: return "WM_INPUTLANGCHANGEREQUEST";
4442 case 0x0051: return "WM_INPUTLANGCHANGE";
4443 case 0x0052: return "WM_TCARD";
4444 case 0x0053: return "WM_HELP";
4445 case 0x0054: return "WM_USERCHANGED";
4446 case 0x0055: return "WM_NOTIFYFORMAT";
4447 case 0x007B: return "WM_CONTEXTMENU";
4448 case 0x007C: return "WM_STYLECHANGING";
4449 case 0x007D: return "WM_STYLECHANGED";
4450 case 0x007E: return "WM_DISPLAYCHANGE";
4451 case 0x007F: return "WM_GETICON";
4452 case 0x0080: return "WM_SETICON";
4455 case 0x0081: return "WM_NCCREATE";
4456 case 0x0082: return "WM_NCDESTROY";
4457 case 0x0083: return "WM_NCCALCSIZE";
4458 case 0x0084: return "WM_NCHITTEST";
4459 case 0x0085: return "WM_NCPAINT";
4460 case 0x0086: return "WM_NCACTIVATE";
4461 case 0x0087: return "WM_GETDLGCODE";
4462 case 0x00A0: return "WM_NCMOUSEMOVE";
4463 case 0x00A1: return "WM_NCLBUTTONDOWN";
4464 case 0x00A2: return "WM_NCLBUTTONUP";
4465 case 0x00A3: return "WM_NCLBUTTONDBLCLK";
4466 case 0x00A4: return "WM_NCRBUTTONDOWN";
4467 case 0x00A5: return "WM_NCRBUTTONUP";
4468 case 0x00A6: return "WM_NCRBUTTONDBLCLK";
4469 case 0x00A7: return "WM_NCMBUTTONDOWN";
4470 case 0x00A8: return "WM_NCMBUTTONUP";
4471 case 0x00A9: return "WM_NCMBUTTONDBLCLK";
4472 case 0x0100: return "WM_KEYDOWN";
4473 case 0x0101: return "WM_KEYUP";
4474 case 0x0102: return "WM_CHAR";
4475 case 0x0103: return "WM_DEADCHAR";
4476 case 0x0104: return "WM_SYSKEYDOWN";
4477 case 0x0105: return "WM_SYSKEYUP";
4478 case 0x0106: return "WM_SYSCHAR";
4479 case 0x0107: return "WM_SYSDEADCHAR";
4480 case 0x0108: return "WM_KEYLAST";
4483 case 0x010D: return "WM_IME_STARTCOMPOSITION";
4484 case 0x010E: return "WM_IME_ENDCOMPOSITION";
4485 case 0x010F: return "WM_IME_COMPOSITION";
4488 case 0x0110: return "WM_INITDIALOG";
4489 case 0x0111: return "WM_COMMAND";
4490 case 0x0112: return "WM_SYSCOMMAND";
4491 case 0x0113: return "WM_TIMER";
4492 case 0x0114: return "WM_HSCROLL";
4493 case 0x0115: return "WM_VSCROLL";
4494 case 0x0116: return "WM_INITMENU";
4495 case 0x0117: return "WM_INITMENUPOPUP";
4496 case 0x011F: return "WM_MENUSELECT";
4497 case 0x0120: return "WM_MENUCHAR";
4498 case 0x0121: return "WM_ENTERIDLE";
4499 case 0x0200: return "WM_MOUSEMOVE";
4500 case 0x0201: return "WM_LBUTTONDOWN";
4501 case 0x0202: return "WM_LBUTTONUP";
4502 case 0x0203: return "WM_LBUTTONDBLCLK";
4503 case 0x0204: return "WM_RBUTTONDOWN";
4504 case 0x0205: return "WM_RBUTTONUP";
4505 case 0x0206: return "WM_RBUTTONDBLCLK";
4506 case 0x0207: return "WM_MBUTTONDOWN";
4507 case 0x0208: return "WM_MBUTTONUP";
4508 case 0x0209: return "WM_MBUTTONDBLCLK";
4509 case 0x020A: return "WM_MOUSEWHEEL";
4510 case 0x0210: return "WM_PARENTNOTIFY";
4511 case 0x0211: return "WM_ENTERMENULOOP";
4512 case 0x0212: return "WM_EXITMENULOOP";
4515 case 0x0213: return "WM_NEXTMENU";
4516 case 0x0214: return "WM_SIZING";
4517 case 0x0215: return "WM_CAPTURECHANGED";
4518 case 0x0216: return "WM_MOVING";
4519 case 0x0218: return "WM_POWERBROADCAST";
4520 case 0x0219: return "WM_DEVICECHANGE";
4523 case 0x0220: return "WM_MDICREATE";
4524 case 0x0221: return "WM_MDIDESTROY";
4525 case 0x0222: return "WM_MDIACTIVATE";
4526 case 0x0223: return "WM_MDIRESTORE";
4527 case 0x0224: return "WM_MDINEXT";
4528 case 0x0225: return "WM_MDIMAXIMIZE";
4529 case 0x0226: return "WM_MDITILE";
4530 case 0x0227: return "WM_MDICASCADE";
4531 case 0x0228: return "WM_MDIICONARRANGE";
4532 case 0x0229: return "WM_MDIGETACTIVE";
4533 case 0x0230: return "WM_MDISETMENU";
4534 case 0x0233: return "WM_DROPFILES";
4537 case 0x0281: return "WM_IME_SETCONTEXT";
4538 case 0x0282: return "WM_IME_NOTIFY";
4539 case 0x0283: return "WM_IME_CONTROL";
4540 case 0x0284: return "WM_IME_COMPOSITIONFULL";
4541 case 0x0285: return "WM_IME_SELECT";
4542 case 0x0286: return "WM_IME_CHAR";
4543 case 0x0290: return "WM_IME_KEYDOWN";
4544 case 0x0291: return "WM_IME_KEYUP";
4547 case 0x0300: return "WM_CUT";
4548 case 0x0301: return "WM_COPY";
4549 case 0x0302: return "WM_PASTE";
4550 case 0x0303: return "WM_CLEAR";
4551 case 0x0304: return "WM_UNDO";
4552 case 0x0305: return "WM_RENDERFORMAT";
4553 case 0x0306: return "WM_RENDERALLFORMATS";
4554 case 0x0307: return "WM_DESTROYCLIPBOARD";
4555 case 0x0308: return "WM_DRAWCLIPBOARD";
4556 case 0x0309: return "WM_PAINTCLIPBOARD";
4557 case 0x030A: return "WM_VSCROLLCLIPBOARD";
4558 case 0x030B: return "WM_SIZECLIPBOARD";
4559 case 0x030C: return "WM_ASKCBFORMATNAME";
4560 case 0x030D: return "WM_CHANGECBCHAIN";
4561 case 0x030E: return "WM_HSCROLLCLIPBOARD";
4562 case 0x030F: return "WM_QUERYNEWPALETTE";
4563 case 0x0310: return "WM_PALETTEISCHANGING";
4564 case 0x0311: return "WM_PALETTECHANGED";
4567 // common controls messages - although they're not strictly speaking
4568 // standard, it's nice to decode them nevertheless
4571 case 0x1000 + 0: return "LVM_GETBKCOLOR";
4572 case 0x1000 + 1: return "LVM_SETBKCOLOR";
4573 case 0x1000 + 2: return "LVM_GETIMAGELIST";
4574 case 0x1000 + 3: return "LVM_SETIMAGELIST";
4575 case 0x1000 + 4: return "LVM_GETITEMCOUNT";
4576 case 0x1000 + 5: return "LVM_GETITEMA";
4577 case 0x1000 + 75: return "LVM_GETITEMW";
4578 case 0x1000 + 6: return "LVM_SETITEMA";
4579 case 0x1000 + 76: return "LVM_SETITEMW";
4580 case 0x1000 + 7: return "LVM_INSERTITEMA";
4581 case 0x1000 + 77: return "LVM_INSERTITEMW";
4582 case 0x1000 + 8: return "LVM_DELETEITEM";
4583 case 0x1000 + 9: return "LVM_DELETEALLITEMS";
4584 case 0x1000 + 10: return "LVM_GETCALLBACKMASK";
4585 case 0x1000 + 11: return "LVM_SETCALLBACKMASK";
4586 case 0x1000 + 12: return "LVM_GETNEXTITEM";
4587 case 0x1000 + 13: return "LVM_FINDITEMA";
4588 case 0x1000 + 83: return "LVM_FINDITEMW";
4589 case 0x1000 + 14: return "LVM_GETITEMRECT";
4590 case 0x1000 + 15: return "LVM_SETITEMPOSITION";
4591 case 0x1000 + 16: return "LVM_GETITEMPOSITION";
4592 case 0x1000 + 17: return "LVM_GETSTRINGWIDTHA";
4593 case 0x1000 + 87: return "LVM_GETSTRINGWIDTHW";
4594 case 0x1000 + 18: return "LVM_HITTEST";
4595 case 0x1000 + 19: return "LVM_ENSUREVISIBLE";
4596 case 0x1000 + 20: return "LVM_SCROLL";
4597 case 0x1000 + 21: return "LVM_REDRAWITEMS";
4598 case 0x1000 + 22: return "LVM_ARRANGE";
4599 case 0x1000 + 23: return "LVM_EDITLABELA";
4600 case 0x1000 + 118: return "LVM_EDITLABELW";
4601 case 0x1000 + 24: return "LVM_GETEDITCONTROL";
4602 case 0x1000 + 25: return "LVM_GETCOLUMNA";
4603 case 0x1000 + 95: return "LVM_GETCOLUMNW";
4604 case 0x1000 + 26: return "LVM_SETCOLUMNA";
4605 case 0x1000 + 96: return "LVM_SETCOLUMNW";
4606 case 0x1000 + 27: return "LVM_INSERTCOLUMNA";
4607 case 0x1000 + 97: return "LVM_INSERTCOLUMNW";
4608 case 0x1000 + 28: return "LVM_DELETECOLUMN";
4609 case 0x1000 + 29: return "LVM_GETCOLUMNWIDTH";
4610 case 0x1000 + 30: return "LVM_SETCOLUMNWIDTH";
4611 case 0x1000 + 31: return "LVM_GETHEADER";
4612 case 0x1000 + 33: return "LVM_CREATEDRAGIMAGE";
4613 case 0x1000 + 34: return "LVM_GETVIEWRECT";
4614 case 0x1000 + 35: return "LVM_GETTEXTCOLOR";
4615 case 0x1000 + 36: return "LVM_SETTEXTCOLOR";
4616 case 0x1000 + 37: return "LVM_GETTEXTBKCOLOR";
4617 case 0x1000 + 38: return "LVM_SETTEXTBKCOLOR";
4618 case 0x1000 + 39: return "LVM_GETTOPINDEX";
4619 case 0x1000 + 40: return "LVM_GETCOUNTPERPAGE";
4620 case 0x1000 + 41: return "LVM_GETORIGIN";
4621 case 0x1000 + 42: return "LVM_UPDATE";
4622 case 0x1000 + 43: return "LVM_SETITEMSTATE";
4623 case 0x1000 + 44: return "LVM_GETITEMSTATE";
4624 case 0x1000 + 45: return "LVM_GETITEMTEXTA";
4625 case 0x1000 + 115: return "LVM_GETITEMTEXTW";
4626 case 0x1000 + 46: return "LVM_SETITEMTEXTA";
4627 case 0x1000 + 116: return "LVM_SETITEMTEXTW";
4628 case 0x1000 + 47: return "LVM_SETITEMCOUNT";
4629 case 0x1000 + 48: return "LVM_SORTITEMS";
4630 case 0x1000 + 49: return "LVM_SETITEMPOSITION32";
4631 case 0x1000 + 50: return "LVM_GETSELECTEDCOUNT";
4632 case 0x1000 + 51: return "LVM_GETITEMSPACING";
4633 case 0x1000 + 52: return "LVM_GETISEARCHSTRINGA";
4634 case 0x1000 + 117: return "LVM_GETISEARCHSTRINGW";
4635 case 0x1000 + 53: return "LVM_SETICONSPACING";
4636 case 0x1000 + 54: return "LVM_SETEXTENDEDLISTVIEWSTYLE";
4637 case 0x1000 + 55: return "LVM_GETEXTENDEDLISTVIEWSTYLE";
4638 case 0x1000 + 56: return "LVM_GETSUBITEMRECT";
4639 case 0x1000 + 57: return "LVM_SUBITEMHITTEST";
4640 case 0x1000 + 58: return "LVM_SETCOLUMNORDERARRAY";
4641 case 0x1000 + 59: return "LVM_GETCOLUMNORDERARRAY";
4642 case 0x1000 + 60: return "LVM_SETHOTITEM";
4643 case 0x1000 + 61: return "LVM_GETHOTITEM";
4644 case 0x1000 + 62: return "LVM_SETHOTCURSOR";
4645 case 0x1000 + 63: return "LVM_GETHOTCURSOR";
4646 case 0x1000 + 64: return "LVM_APPROXIMATEVIEWRECT";
4647 case 0x1000 + 65: return "LVM_SETWORKAREA";
4650 case 0x1100 + 0: return "TVM_INSERTITEMA";
4651 case 0x1100 + 50: return "TVM_INSERTITEMW";
4652 case 0x1100 + 1: return "TVM_DELETEITEM";
4653 case 0x1100 + 2: return "TVM_EXPAND";
4654 case 0x1100 + 4: return "TVM_GETITEMRECT";
4655 case 0x1100 + 5: return "TVM_GETCOUNT";
4656 case 0x1100 + 6: return "TVM_GETINDENT";
4657 case 0x1100 + 7: return "TVM_SETINDENT";
4658 case 0x1100 + 8: return "TVM_GETIMAGELIST";
4659 case 0x1100 + 9: return "TVM_SETIMAGELIST";
4660 case 0x1100 + 10: return "TVM_GETNEXTITEM";
4661 case 0x1100 + 11: return "TVM_SELECTITEM";
4662 case 0x1100 + 12: return "TVM_GETITEMA";
4663 case 0x1100 + 62: return "TVM_GETITEMW";
4664 case 0x1100 + 13: return "TVM_SETITEMA";
4665 case 0x1100 + 63: return "TVM_SETITEMW";
4666 case 0x1100 + 14: return "TVM_EDITLABELA";
4667 case 0x1100 + 65: return "TVM_EDITLABELW";
4668 case 0x1100 + 15: return "TVM_GETEDITCONTROL";
4669 case 0x1100 + 16: return "TVM_GETVISIBLECOUNT";
4670 case 0x1100 + 17: return "TVM_HITTEST";
4671 case 0x1100 + 18: return "TVM_CREATEDRAGIMAGE";
4672 case 0x1100 + 19: return "TVM_SORTCHILDREN";
4673 case 0x1100 + 20: return "TVM_ENSUREVISIBLE";
4674 case 0x1100 + 21: return "TVM_SORTCHILDRENCB";
4675 case 0x1100 + 22: return "TVM_ENDEDITLABELNOW";
4676 case 0x1100 + 23: return "TVM_GETISEARCHSTRINGA";
4677 case 0x1100 + 64: return "TVM_GETISEARCHSTRINGW";
4678 case 0x1100 + 24: return "TVM_SETTOOLTIPS";
4679 case 0x1100 + 25: return "TVM_GETTOOLTIPS";
4682 case 0x1200 + 0: return "HDM_GETITEMCOUNT";
4683 case 0x1200 + 1: return "HDM_INSERTITEMA";
4684 case 0x1200 + 10: return "HDM_INSERTITEMW";
4685 case 0x1200 + 2: return "HDM_DELETEITEM";
4686 case 0x1200 + 3: return "HDM_GETITEMA";
4687 case 0x1200 + 11: return "HDM_GETITEMW";
4688 case 0x1200 + 4: return "HDM_SETITEMA";
4689 case 0x1200 + 12: return "HDM_SETITEMW";
4690 case 0x1200 + 5: return "HDM_LAYOUT";
4691 case 0x1200 + 6: return "HDM_HITTEST";
4692 case 0x1200 + 7: return "HDM_GETITEMRECT";
4693 case 0x1200 + 8: return "HDM_SETIMAGELIST";
4694 case 0x1200 + 9: return "HDM_GETIMAGELIST";
4695 case 0x1200 + 15: return "HDM_ORDERTOINDEX";
4696 case 0x1200 + 16: return "HDM_CREATEDRAGIMAGE";
4697 case 0x1200 + 17: return "HDM_GETORDERARRAY";
4698 case 0x1200 + 18: return "HDM_SETORDERARRAY";
4699 case 0x1200 + 19: return "HDM_SETHOTDIVIDER";
4702 case 0x1300 + 2: return "TCM_GETIMAGELIST";
4703 case 0x1300 + 3: return "TCM_SETIMAGELIST";
4704 case 0x1300 + 4: return "TCM_GETITEMCOUNT";
4705 case 0x1300 + 5: return "TCM_GETITEMA";
4706 case 0x1300 + 60: return "TCM_GETITEMW";
4707 case 0x1300 + 6: return "TCM_SETITEMA";
4708 case 0x1300 + 61: return "TCM_SETITEMW";
4709 case 0x1300 + 7: return "TCM_INSERTITEMA";
4710 case 0x1300 + 62: return "TCM_INSERTITEMW";
4711 case 0x1300 + 8: return "TCM_DELETEITEM";
4712 case 0x1300 + 9: return "TCM_DELETEALLITEMS";
4713 case 0x1300 + 10: return "TCM_GETITEMRECT";
4714 case 0x1300 + 11: return "TCM_GETCURSEL";
4715 case 0x1300 + 12: return "TCM_SETCURSEL";
4716 case 0x1300 + 13: return "TCM_HITTEST";
4717 case 0x1300 + 14: return "TCM_SETITEMEXTRA";
4718 case 0x1300 + 40: return "TCM_ADJUSTRECT";
4719 case 0x1300 + 41: return "TCM_SETITEMSIZE";
4720 case 0x1300 + 42: return "TCM_REMOVEIMAGE";
4721 case 0x1300 + 43: return "TCM_SETPADDING";
4722 case 0x1300 + 44: return "TCM_GETROWCOUNT";
4723 case 0x1300 + 45: return "TCM_GETTOOLTIPS";
4724 case 0x1300 + 46: return "TCM_SETTOOLTIPS";
4725 case 0x1300 + 47: return "TCM_GETCURFOCUS";
4726 case 0x1300 + 48: return "TCM_SETCURFOCUS";
4727 case 0x1300 + 49: return "TCM_SETMINTABWIDTH";
4728 case 0x1300 + 50: return "TCM_DESELECTALL";
4731 case WM_USER
+1: return "TB_ENABLEBUTTON";
4732 case WM_USER
+2: return "TB_CHECKBUTTON";
4733 case WM_USER
+3: return "TB_PRESSBUTTON";
4734 case WM_USER
+4: return "TB_HIDEBUTTON";
4735 case WM_USER
+5: return "TB_INDETERMINATE";
4736 case WM_USER
+9: return "TB_ISBUTTONENABLED";
4737 case WM_USER
+10: return "TB_ISBUTTONCHECKED";
4738 case WM_USER
+11: return "TB_ISBUTTONPRESSED";
4739 case WM_USER
+12: return "TB_ISBUTTONHIDDEN";
4740 case WM_USER
+13: return "TB_ISBUTTONINDETERMINATE";
4741 case WM_USER
+17: return "TB_SETSTATE";
4742 case WM_USER
+18: return "TB_GETSTATE";
4743 case WM_USER
+19: return "TB_ADDBITMAP";
4744 case WM_USER
+20: return "TB_ADDBUTTONS";
4745 case WM_USER
+21: return "TB_INSERTBUTTON";
4746 case WM_USER
+22: return "TB_DELETEBUTTON";
4747 case WM_USER
+23: return "TB_GETBUTTON";
4748 case WM_USER
+24: return "TB_BUTTONCOUNT";
4749 case WM_USER
+25: return "TB_COMMANDTOINDEX";
4750 case WM_USER
+26: return "TB_SAVERESTOREA";
4751 case WM_USER
+76: return "TB_SAVERESTOREW";
4752 case WM_USER
+27: return "TB_CUSTOMIZE";
4753 case WM_USER
+28: return "TB_ADDSTRINGA";
4754 case WM_USER
+77: return "TB_ADDSTRINGW";
4755 case WM_USER
+29: return "TB_GETITEMRECT";
4756 case WM_USER
+30: return "TB_BUTTONSTRUCTSIZE";
4757 case WM_USER
+31: return "TB_SETBUTTONSIZE";
4758 case WM_USER
+32: return "TB_SETBITMAPSIZE";
4759 case WM_USER
+33: return "TB_AUTOSIZE";
4760 case WM_USER
+35: return "TB_GETTOOLTIPS";
4761 case WM_USER
+36: return "TB_SETTOOLTIPS";
4762 case WM_USER
+37: return "TB_SETPARENT";
4763 case WM_USER
+39: return "TB_SETROWS";
4764 case WM_USER
+40: return "TB_GETROWS";
4765 case WM_USER
+42: return "TB_SETCMDID";
4766 case WM_USER
+43: return "TB_CHANGEBITMAP";
4767 case WM_USER
+44: return "TB_GETBITMAP";
4768 case WM_USER
+45: return "TB_GETBUTTONTEXTA";
4769 case WM_USER
+75: return "TB_GETBUTTONTEXTW";
4770 case WM_USER
+46: return "TB_REPLACEBITMAP";
4771 case WM_USER
+47: return "TB_SETINDENT";
4772 case WM_USER
+48: return "TB_SETIMAGELIST";
4773 case WM_USER
+49: return "TB_GETIMAGELIST";
4774 case WM_USER
+50: return "TB_LOADIMAGES";
4775 case WM_USER
+51: return "TB_GETRECT";
4776 case WM_USER
+52: return "TB_SETHOTIMAGELIST";
4777 case WM_USER
+53: return "TB_GETHOTIMAGELIST";
4778 case WM_USER
+54: return "TB_SETDISABLEDIMAGELIST";
4779 case WM_USER
+55: return "TB_GETDISABLEDIMAGELIST";
4780 case WM_USER
+56: return "TB_SETSTYLE";
4781 case WM_USER
+57: return "TB_GETSTYLE";
4782 case WM_USER
+58: return "TB_GETBUTTONSIZE";
4783 case WM_USER
+59: return "TB_SETBUTTONWIDTH";
4784 case WM_USER
+60: return "TB_SETMAXTEXTROWS";
4785 case WM_USER
+61: return "TB_GETTEXTROWS";
4786 case WM_USER
+41: return "TB_GETBITMAPFLAGS";
4791 static char s_szBuf
[128];
4792 sprintf(s_szBuf
, "<unknown message = %d>", message
);
4796 #endif //__WXDEBUG__
4798 static void TranslateKbdEventToMouse(wxWindowMSW
*win
,
4799 int *x
, int *y
, WPARAM
*flags
)
4801 // construct the key mask
4802 WPARAM
& fwKeys
= *flags
;
4804 fwKeys
= MK_RBUTTON
;
4805 if ( wxIsCtrlDown() )
4806 fwKeys
|= MK_CONTROL
;
4807 if ( wxIsShiftDown() )
4810 // simulate right mouse button click
4811 DWORD dwPos
= ::GetMessagePos();
4812 *x
= GET_X_LPARAM(dwPos
);
4813 *y
= GET_Y_LPARAM(dwPos
);
4815 win
->ScreenToClient(x
, y
);
4818 static TEXTMETRIC
wxGetTextMetrics(const wxWindowMSW
*win
)
4822 HWND hwnd
= GetHwndOf(win
);
4823 HDC hdc
= ::GetDC(hwnd
);
4825 #if !wxDIALOG_UNIT_COMPATIBILITY
4826 // and select the current font into it
4827 HFONT hfont
= GetHfontOf(win
->GetFont());
4830 hfont
= (HFONT
)::SelectObject(hdc
, hfont
);
4834 // finally retrieve the text metrics from it
4835 GetTextMetrics(hdc
, &tm
);
4837 #if !wxDIALOG_UNIT_COMPATIBILITY
4841 (void)::SelectObject(hdc
, hfont
);
4845 ::ReleaseDC(hwnd
, hdc
);
4850 // Find the wxWindow at the current mouse position, returning the mouse
4852 wxWindow
* wxFindWindowAtPointer(wxPoint
& WXUNUSED(pt
))
4854 return wxFindWindowAtPoint(wxGetMousePosition());
4857 wxWindow
* wxFindWindowAtPoint(const wxPoint
& pt
)
4862 HWND hWndHit
= ::WindowFromPoint(pt2
);
4864 wxWindow
* win
= wxFindWinFromHandle((WXHWND
) hWndHit
) ;
4865 HWND hWnd
= hWndHit
;
4867 // Try to find a window with a wxWindow associated with it
4868 while (!win
&& (hWnd
!= 0))
4870 hWnd
= ::GetParent(hWnd
);
4871 win
= wxFindWinFromHandle((WXHWND
) hWnd
) ;
4876 // Get the current mouse position.
4877 wxPoint
wxGetMousePosition()
4880 GetCursorPos( & pt
);
4881 return wxPoint(pt
.x
, pt
.y
);