Files
wxWidgets/src/msw/uiaction.cpp
Vadim Zeitlin cfc1681b4c Virtualize wxUIActionSimulator implementation
Extract platform-specific code in a wxUIActionSimulatorImpl-derived class
instead of keeping it in wxUIActionSimulator itself.

This will allow determining which implementation to use dynamically (i.e. at
run-time and not compile-time) to use later and already allows to get rid of
an __WXOSX__ #ifdef in common code.
2016-05-23 03:00:49 +02:00

140 lines
3.8 KiB
C++

/////////////////////////////////////////////////////////////////////////////
// Name: src/msw/uiaction.cpp
// Purpose: wxUIActionSimulator implementation
// Author: Kevin Ollivier, Steven Lamerton, Vadim Zeitlin
// Modified by:
// Created: 2010-03-06
// Copyright: (c) Kevin Ollivier
// (c) 2010 Steven Lamerton
// (c) 2010 Vadim Zeitlin
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#include "wx/wxprec.h"
#if wxUSE_UIACTIONSIMULATOR
#ifndef WX_PRECOMP
#include "wx/msw/private.h" // For wxGetCursorPosMSW()
#endif
#include "wx/uiaction.h"
#include "wx/private/uiaction.h"
#include "wx/msw/wrapwin.h"
#include "wx/msw/private/keyboard.h"
#include "wx/math.h"
namespace
{
class wxUIActionSimulatorMSWImpl : public wxUIActionSimulatorImpl
{
public:
// Returns a pointer to the global simulator object: as it's stateless, we
// can reuse the same one without having to allocate it on the heap all the
// time.
static wxUIActionSimulatorMSWImpl* Get()
{
static wxUIActionSimulatorMSWImpl s_impl;
return &s_impl;
}
virtual bool MouseMove(long x, long y) wxOVERRIDE;
virtual bool MouseDown(int button = wxMOUSE_BTN_LEFT) wxOVERRIDE;
virtual bool MouseUp(int button = wxMOUSE_BTN_LEFT) wxOVERRIDE;
virtual bool DoKey(int keycode, int modifiers, bool isDown) wxOVERRIDE;
private:
// This class has no public ctors, use Get() instead.
wxUIActionSimulatorMSWImpl() { }
wxDECLARE_NO_COPY_CLASS(wxUIActionSimulatorMSWImpl);
};
DWORD EventTypeForMouseButton(int button, bool isDown)
{
switch (button)
{
case wxMOUSE_BTN_LEFT:
return isDown ? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_LEFTUP;
case wxMOUSE_BTN_RIGHT:
return isDown ? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_RIGHTUP;
case wxMOUSE_BTN_MIDDLE:
return isDown ? MOUSEEVENTF_MIDDLEDOWN : MOUSEEVENTF_MIDDLEUP;
default:
wxFAIL_MSG("Unsupported button passed in.");
return (DWORD)-1;
}
}
} // anonymous namespace
bool wxUIActionSimulatorMSWImpl::MouseDown(int button)
{
POINT p;
wxGetCursorPosMSW(&p);
mouse_event(EventTypeForMouseButton(button, true), p.x, p.y, 0, 0);
return true;
}
bool wxUIActionSimulatorMSWImpl::MouseMove(long x, long y)
{
// Because MOUSEEVENTF_ABSOLUTE takes measurements scaled between 0 & 65535
// we need to scale our input too
int displayx, displayy;
wxDisplaySize(&displayx, &displayy);
// Casts are safe because x and y are supposed to be less than the display
// size, so there is no danger of overflow.
DWORD scaledx = static_cast<DWORD>(ceil(x * 65535.0 / (displayx-1)));
DWORD scaledy = static_cast<DWORD>(ceil(y * 65535.0 / (displayy-1)));
mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, scaledx, scaledy, 0, 0);
return true;
}
bool wxUIActionSimulatorMSWImpl::MouseUp(int button)
{
POINT p;
wxGetCursorPosMSW(&p);
mouse_event(EventTypeForMouseButton(button, false), p.x, p.y, 0, 0);
return true;
}
bool
wxUIActionSimulatorMSWImpl::DoKey(int keycode, int WXUNUSED(modifiers), bool isDown)
{
bool isExtended;
DWORD vkkeycode = wxMSWKeyboard::WXToVK(keycode, &isExtended);
DWORD flags = 0;
if ( isExtended )
flags |= KEYEVENTF_EXTENDEDKEY;
if ( !isDown )
flags |= KEYEVENTF_KEYUP;
keybd_event(vkkeycode, 0, flags, 0);
return true;
}
wxUIActionSimulator::wxUIActionSimulator()
: m_impl(wxUIActionSimulatorMSWImpl::Get())
{
}
wxUIActionSimulator::~wxUIActionSimulator()
{
// We can use a static wxUIActionSimulatorMSWImpl object because it's
// stateless, so no need to delete it.
}
#endif // wxUSE_UIACTIONSIMULATOR