mirror of https://github.com/adamdruppe/arsd.git
Windows hotkey basics
This commit is contained in:
parent
20c3c49d66
commit
9c04174573
127
simpledisplay.d
127
simpledisplay.d
|
@ -249,11 +249,74 @@ version(X11) {
|
||||||
window.impl.getSelectionHandler = handler;
|
window.impl.getSelectionHandler = handler;
|
||||||
|
|
||||||
auto target = XA_STRING;
|
auto target = XA_STRING;
|
||||||
// or auto target = GetAtom!"UTF8_STRING"(display)
|
//auto target = GetAtom!"UTF8_STRING"(display);
|
||||||
|
|
||||||
|
// SDD_DATA is "simpledisplay.d data"
|
||||||
XConvertSelection(display, atom, target, GetAtom!("SDD_DATA", true)(display), window.impl.window, 0 /*CurrentTime*/);
|
XConvertSelection(display, atom, target, GetAtom!("SDD_DATA", true)(display), window.impl.window, 0 /*CurrentTime*/);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
version(Windows) {
|
||||||
|
void sendSyntheticInput(wstring s) {
|
||||||
|
INPUT[] inputs;
|
||||||
|
inputs.reserve(s.length * 2);
|
||||||
|
|
||||||
|
foreach(wchar c; s) {
|
||||||
|
INPUT input;
|
||||||
|
input.type = INPUT_KEYBOARD;
|
||||||
|
input.ki.wScan = c;
|
||||||
|
input.ki.dwFlags = KEYEVENTF_UNICODE;
|
||||||
|
inputs ~= input;
|
||||||
|
|
||||||
|
input.ki.dwFlags |= KEYEVENTF_KEYUP;
|
||||||
|
inputs ~= input;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(SendInput(inputs.length, inputs.ptr, INPUT.sizeof) != inputs.length) {
|
||||||
|
throw new Exception("SendInput failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// global hotkey helper function
|
||||||
|
|
||||||
|
void registerHotKey(SimpleWindow window, UINT modifiers, UINT vk, void delegate() handler) {
|
||||||
|
static int hotkeyId = 0;
|
||||||
|
int id = ++hotkeyId;
|
||||||
|
if(!RegisterHotKey(window.impl.hwnd, id, modifiers, vk))
|
||||||
|
throw new Exception("RegisterHotKey failed");
|
||||||
|
|
||||||
|
static void delegate()[int][HWND] handlers;
|
||||||
|
|
||||||
|
handlers[window.impl.hwnd][id] = handler;
|
||||||
|
|
||||||
|
int delegate(HWND, UINT, WPARAM, LPARAM) oldHandler;
|
||||||
|
|
||||||
|
auto nativeEventHandler = delegate int(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
||||||
|
switch(msg) {
|
||||||
|
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646279%28v=vs.85%29.aspx
|
||||||
|
case WM_HOTKEY:
|
||||||
|
if(auto list = hwnd in handlers) {
|
||||||
|
if(auto h = wParam in *list) {
|
||||||
|
(*h)();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
goto default;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
if(oldHandler)
|
||||||
|
return oldHandler(hwnd, msg, wParam, lParam);
|
||||||
|
return 1; // pass it on
|
||||||
|
};
|
||||||
|
|
||||||
|
if(window.handleNativeEvent.funcptr !is nativeEventHandler.funcptr) {
|
||||||
|
oldHandler = window.handleNativeEvent;
|
||||||
|
window.handleNativeEvent = nativeEventHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
enum RasterOp {
|
enum RasterOp {
|
||||||
|
@ -1522,9 +1585,12 @@ class SimpleWindow {
|
||||||
impl.dispose();
|
impl.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool closed;
|
||||||
|
|
||||||
/// Closes the window and terminates it's event loop.
|
/// Closes the window and terminates it's event loop.
|
||||||
void close() {
|
void close() {
|
||||||
impl.closeWindow();
|
impl.closeWindow();
|
||||||
|
closed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets your event handlers, without entering the event loop. Useful if you
|
/// Sets your event handlers, without entering the event loop. Useful if you
|
||||||
|
@ -2392,7 +2458,7 @@ version(Windows) {
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!done && handlePulse !is null)
|
if(!done && !closed && handlePulse !is null)
|
||||||
handlePulse();
|
handlePulse();
|
||||||
SleepEx(cast(DWORD) pulseTimeout, true);
|
SleepEx(cast(DWORD) pulseTimeout, true);
|
||||||
}
|
}
|
||||||
|
@ -3107,7 +3173,7 @@ version(X11) {
|
||||||
{
|
{
|
||||||
done = doXNextEvent(this.display);
|
done = doXNextEvent(this.display);
|
||||||
}
|
}
|
||||||
if(!done && pulseTimeout !=0) {
|
if(!done && !closed && pulseTimeout !=0) {
|
||||||
if(handlePulse !is null)
|
if(handlePulse !is null)
|
||||||
handlePulse();
|
handlePulse();
|
||||||
Thread.sleep(dur!"msecs"(pulseTimeout));
|
Thread.sleep(dur!"msecs"(pulseTimeout));
|
||||||
|
@ -3598,6 +3664,61 @@ nothrow:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Input fabrication functions
|
||||||
|
|
||||||
|
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646309%28v=vs.85%29.aspx
|
||||||
|
extern(Windows) BOOL RegisterHotKey(HWND, int, UINT, UINT);
|
||||||
|
// http://msdn.microsoft.com/en-us/library/ms646310%28v=vs.85%29.aspx
|
||||||
|
extern(Windows) UINT SendInput(UINT, INPUT*, int);
|
||||||
|
|
||||||
|
struct INPUT {
|
||||||
|
DWORD type;
|
||||||
|
union {
|
||||||
|
MOUSEINPUT mi;
|
||||||
|
KEYBDINPUT ki;
|
||||||
|
HARDWAREINPUT hi;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MOUSEINPUT {
|
||||||
|
LONG dx;
|
||||||
|
LONG dy;
|
||||||
|
DWORD mouseData;
|
||||||
|
DWORD dwFlags;
|
||||||
|
DWORD time;
|
||||||
|
ULONG_PTR dwExtraInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct KEYBDINPUT {
|
||||||
|
WORD wVk;
|
||||||
|
WORD wScan;
|
||||||
|
DWORD dwFlags;
|
||||||
|
DWORD time;
|
||||||
|
ULONG_PTR dwExtraInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct HARDWAREINPUT {
|
||||||
|
DWORD uMsg;
|
||||||
|
WORD wParamL;
|
||||||
|
WORD wParamH;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum INPUT_MOUSE = 0;
|
||||||
|
enum INPUT_KEYBOARD = 1;
|
||||||
|
enum INPUT_HARDWARE = 2;
|
||||||
|
|
||||||
|
enum MOD_ALT = 0x1;
|
||||||
|
enum MOD_CONTROL = 0x2;
|
||||||
|
enum MOD_NOREPEAT = 0x4000; // unsupported
|
||||||
|
enum MOD_SHIFT = 0x4;
|
||||||
|
enum MOD_WIN = 0x8; // reserved
|
||||||
|
|
||||||
|
enum WM_HOTKEY = 0x0312;
|
||||||
|
|
||||||
|
enum KEYEVENTF_EXTENDEDKEY = 0x1;
|
||||||
|
enum KEYEVENTF_KEYUP = 0x2;
|
||||||
|
enum KEYEVENTF_SCANCODE = 0x8;
|
||||||
|
enum KEYEVENTF_UNICODE = 0x4;
|
||||||
}
|
}
|
||||||
|
|
||||||
else version(X11) {
|
else version(X11) {
|
||||||
|
|
Loading…
Reference in New Issue