#include "wx/ownerdrw.h"
#endif
+#include "wx/module.h"
+
#if wxUSE_DRAG_AND_DROP
#include "wx/dnd.h"
#endif
#include "wx/msw/gnuwin32/extra.h"
#endif
-#if defined(__GNUG__)
#include "wx/msw/missing.h"
-#endif
#if defined(__WXWINCE__)
#include "wx/msw/wince/missing.h"
#endif
-// ----------------------------------------------------------------------------
-// standard constants not available with all compilers/headers
-// ----------------------------------------------------------------------------
-
-// This didn't appear in mingw until 2.95.2
-#ifndef SIF_TRACKPOS
-#define SIF_TRACKPOS 16
-#endif
-
-#if wxUSE_MOUSEWHEEL
- #ifndef WM_MOUSEWHEEL
- #define WM_MOUSEWHEEL 0x020A
- #endif
- #ifndef WHEEL_DELTA
- #define WHEEL_DELTA 120
- #endif
- #ifndef SPI_GETWHEELSCROLLLINES
- #define SPI_GETWHEELSCROLLLINES 104
- #endif
-#endif // wxUSE_MOUSEWHEEL
-
-#ifndef VK_OEM_1
- #define VK_OEM_1 0xBA
- #define VK_OEM_2 0xBF
- #define VK_OEM_3 0xC0
- #define VK_OEM_4 0xDB
- #define VK_OEM_5 0xDC
- #define VK_OEM_6 0xDD
- #define VK_OEM_7 0xDE
-#endif
-
-#ifndef VK_OEM_COMMA
- #define VK_OEM_PLUS 0xBB
- #define VK_OEM_COMMA 0xBC
- #define VK_OEM_MINUS 0xBD
- #define VK_OEM_PERIOD 0xBE
-#endif
-
// ---------------------------------------------------------------------------
// global variables
// ---------------------------------------------------------------------------
-// the last Windows message we got (FIXME-MT)
-extern MSG s_currentMsg;
-
#if wxUSE_MENUS_NATIVE
wxMenu *wxCurrentPopupMenu = NULL;
#endif // wxUSE_MENUS_NATIVE
wxFLAGS_MEMBER(wxDOUBLE_BORDER)
wxFLAGS_MEMBER(wxRAISED_BORDER)
wxFLAGS_MEMBER(wxSTATIC_BORDER)
- wxFLAGS_MEMBER(wxNO_BORDER)
+ wxFLAGS_MEMBER(wxBORDER)
// standard window styles
wxFLAGS_MEMBER(wxTAB_TRAVERSAL)
wxFLAGS_MEMBER(wxCLIP_CHILDREN)
wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW)
wxFLAGS_MEMBER(wxWANTS_CHARS)
- wxFLAGS_MEMBER(wxNO_FULL_REPAINT_ON_RESIZE)
+ wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE)
wxFLAGS_MEMBER(wxALWAYS_SHOW_SB )
wxFLAGS_MEMBER(wxVSCROLL)
wxFLAGS_MEMBER(wxHSCROLL)
void wxWindowMSW::Init()
{
- // generic
- InitBase();
-
// MSW specific
m_isBeingDeleted = FALSE;
m_oldWndProc = NULL;
// peek all WM_COMMANDs (it will always return WM_QUIT too but we don't
// want to process it here)
MSG msg;
- while ( ::PeekMessage(&msg, (HWND)0, WM_COMMAND, WM_COMMAND, PM_REMOVE)
- && msg.message != WM_QUIT )
+ while ( ::PeekMessage(&msg, (HWND)0, WM_COMMAND, WM_COMMAND, PM_REMOVE) )
{
- wxTheApp->DoMessage((WXMSG *)&msg);
- }
+ if ( msg.message == WM_QUIT )
+ {
+ // if we retrieved a WM_QUIT, insert back into the message queue.
+ ::PostQuitMessage(0);
+ break;
+ }
- // If we retrieved a WM_QUIT, insert back into the message queue.
- if (msg.message == WM_QUIT)
- ::PostQuitMessage(0);
+ // luckily (as we don't have access to wxEventLoopImpl method from here
+ // anyhow...) we don't need to pre process WM_COMMANDs so dispatch it
+ // immediately
+ ::TranslateMessage(&msg);
+ ::DispatchMessage(&msg);
+ }
}
bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y)
wParam);
break;
+ // Seems to be broken currently
+#if 0 // ndef __WXWINCE__
+ case WM_MOUSELEAVE:
+ {
+ wxASSERT_MSG( !m_mouseInWindow, wxT("the mouse should be in a window to generate this event!") );
+
+ // only process this message if the mouse is not in the window,
+ // This can also check for children in composite windows.
+ // however, this may mean the the wxEVT_LEAVE_WINDOW is never sent
+ // if the mouse does not enter the window from it's child before
+ // leaving the scope of the window. ( perhaps this can be picked
+ // up in the OnIdle code as before, for this special case )
+ if ( /*IsComposite() && */ !IsMouseInWindow() )
+ {
+ m_mouseInWindow = FALSE;
+
+ // Unfortunately no mouse state is passed with a WM_MOUSE_LEAVE
+ int state = 0;
+ if ( wxIsShiftDown() )
+ state |= MK_SHIFT;
+ if ( wxIsCtrlDown() )
+ state |= MK_CONTROL;
+ if ( GetKeyState( VK_LBUTTON ) )
+ state |= MK_LBUTTON;
+ if ( GetKeyState( VK_MBUTTON ) )
+ state |= MK_MBUTTON;
+ if ( GetKeyState( VK_RBUTTON ) )
+ state |= MK_RBUTTON;
+
+ POINT pt;
+ if ( !::GetCursorPos(&pt) )
+ {
+ wxLogLastError(_T("GetCursorPos"));
+ }
+
+ // we need to have client coordinates here for symmetry with
+ // wxEVT_ENTER_WINDOW
+ RECT rect = wxGetWindowRect(GetHwnd());
+ pt.x -= rect.left;
+ pt.y -= rect.top;
+
+ wxMouseEvent event2(wxEVT_LEAVE_WINDOW);
+ InitMouseEvent(event2, pt.x, pt.y, state);
+
+ (void)GetEventHandler()->ProcessEvent(event2);
+ }
+ // always pass processed back as false, this allows the window
+ // manager to process the message too. This is needed to ensure
+ // windows XP themes work properly as the mouse moves over widgets
+ // like buttons.
+ processed = false;
+ }
+ break;
+#endif
+ // __WXWINCE__
+
#if wxUSE_MOUSEWHEEL
case WM_MOUSEWHEEL:
processed = HandleMouseWheel(wParam, lParam);
//WPARAM dwFlags = (WPARAM) (DWORD) wParam;
LPARAM dwObjId = (LPARAM) (DWORD) lParam;
- if (dwObjId == OBJID_CLIENT && GetOrCreateAccessible())
+ if (dwObjId == (LPARAM)OBJID_CLIENT && GetOrCreateAccessible())
{
return LresultFromObject(IID_IAccessible, wParam, (IUnknown*) GetAccessible()->GetIAccessible());
}
wxPoint pt(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
wxContextMenuEvent evtCtx(wxEVT_CONTEXT_MENU, GetId(), pt);
+ evtCtx.SetEventObject(this);
processed = GetEventHandler()->ProcessEvent(evtCtx);
}
break;
nonDefault = TRUE;
}
+ AdjustForParentClientOrigin(x, y);
+
return nonDefault;
}
// which is the same but without CS_[HV]REDRAW class styles so using it
// ensures that the window is not fully repainted on each resize
wxString className(wclass);
- if ( GetWindowStyleFlag() & wxNO_FULL_REPAINT_ON_RESIZE )
+ if ( !HasFlag(wxFULL_REPAINT_ON_RESIZE) )
{
className += wxT("NR");
}
// so simply test for negative value.
event.m_altDown = ::GetKeyState(VK_MENU) < 0;
- event.SetTimestamp(s_currentMsg.time);
+#ifndef __WXWINCE__
+ event.SetTimestamp(::GetMessageTime());
+#endif
+
event.m_eventObject = this;
event.SetId(GetId());
{
// Generate an ENTER event
m_mouseInWindow = TRUE;
-
+#if _WIN32_WINNT >= 0x0400
+#ifndef __WXWINCE__
+ TRACKMOUSEEVENT trackinfo;
+
+ trackinfo.cbSize = sizeof(trackinfo);
+ trackinfo.dwFlags = TME_LEAVE;
+ trackinfo.hwndTrack = GetHwnd();
+ //Use the commctrl.h _TrackMouseEvent, which will call the
+ // appropriate TrackMouseEvent or emulate it ( win95 )
+ // else we need _WIN32_WINNT >= 0x0400
+ _TrackMouseEvent(&trackinfo);
+#endif
+#endif
wxMouseEvent event(wxEVT_ENTER_WINDOW);
InitMouseEvent(event, x, y, flags);
event.m_keyCode = id;
event.m_rawCode = (wxUint32) wParam;
event.m_rawFlags = (wxUint32) lParam;
- event.SetTimestamp(s_currentMsg.time);
+#ifndef __WXWINCE__
+ event.SetTimestamp(::GetMessageTime());
+#endif
// translate the position to client coords
POINT pt;
int wxCharCodeWXToMSW(int id, bool *isVirtual)
{
*isVirtual = TRUE;
- int keySym = 0;
+ int keySym;
switch (id)
{
case WXK_CANCEL: keySym = VK_CANCEL; break;
return keySym;
}
+bool wxGetKeyState(wxKeyCode key)
+{
+ bool bVirtual;
+ int vkey = wxCharCodeWXToMSW(key, &bVirtual);
+
+ //there aren't WXK_ macros for non-virtual key codes
+ if (bVirtual == false)
+ return false;
+
+ return GetKeyState(vkey) < 0;
+}
+
wxWindow *wxGetActiveWindow()
{
HWND hWnd = GetActiveWindow();
event.m_keyCode = id;
event.m_shiftDown = wxIsShiftDown();
event.m_controlDown = wxIsCtrlDown();
- event.SetTimestamp(s_currentMsg.time);
-
+#ifndef __WXWINCE__
+ event.SetTimestamp(::GetMessageTime());
+#endif
wxWindow *win = wxGetActiveWindow();
wxEvtHandler *handler;
if ( win )
#endif // wxUSE_HOTKEY
+// Not verified for WinCE
+#ifndef __WXWINCE__
+/*
+ * wxEventFixModule (needs a better name) allows message handling to continute while a menu
+ * is being shown - ie, to continue processing messages from a worker thread.
+ *
+ * Code originally by Jason W. from wx-dev, reworked into a wxModule by Chris Mellon
+ */
+
+class wxEventFixModule : public wxModule {
+public:
+ //base class virtuals
+ virtual bool OnInit() {
+ wxEventFixModule::s_hMsgHookProc = SetWindowsHookEx(
+ WH_GETMESSAGE,
+ &wxEventFixModule::MsgHookProc,
+ NULL,
+ GetCurrentThreadId());
+ wxLogDebug(_T("Loaded event fix module"));
+ return true;
+ };
+ virtual void OnExit() {
+ UnhookWindowsHookEx(wxEventFixModule::s_hMsgHookProc);
+
+ };
+ static LRESULT CALLBACK MsgHookProc(int nCode, WPARAM wParam, LPARAM lParam) {
+ MSG *msg = (MSG*)lParam;
+ switch (msg->message)
+ {
+ case WM_NULL:
+ static bool bInHookProc = false;
+ if (!bInHookProc)
+ {
+ bInHookProc = true;
+ wxTheApp->ProcessPendingEvents();
+ bInHookProc = false;
+ }
+ break;
+ }
+ return CallNextHookEx(wxEventFixModule::s_hMsgHookProc, nCode, wParam, lParam);
+ };
+private:
+ static HHOOK s_hMsgHookProc;
+DECLARE_DYNAMIC_CLASS(wxEventFixModule)
+};
+HHOOK wxEventFixModule::s_hMsgHookProc = 0;
+
+IMPLEMENT_DYNAMIC_CLASS(wxEventFixModule, wxModule)
+#endif
+ // __WXWINCE__
+