@BlacKow's answer works well on Mac, but Mathematica cannot handle special keys (s.a. F2 or PAUSE) on Windows. Thus,
Here is a Windows workaround:
The idea is to create a dynamic link library that runs in a separate thread, as explained here. In this separate thread, the keyboard status is continuously tested. Once the specified key is pressed, an event is raised to the MMA kernel. The following code requires a working C-compiler on a Windows PC:
Needs["CCompilerDriver`GenericCCompiler`"];
keyListen[keycode_, action_] := With[{
libMain = First@FileNames["async-examples-libmain.c", {$InstallationDirectory}, Infinity],
src = "
#include <stdlib.h>
#include \"WolframLibrary.h\"
#include \"WolframCompileLibrary.h\"
#include \"WolframStreamsLibrary.h\"
#include \"windows.h\" // for GetAsyncKeyState()
/**********************************************************/
typedef struct keyTrackerArgs_st
{
WolframIOLibrary_Functions ioLibrary;
mint key;
}* keyTrackerArgs;
static void key_tracker(mint asyncObjID, void* vtarg)
{
keyTrackerArgs targ = (keyTrackerArgs)vtarg;
WolframIOLibrary_Functions ioLibrary = targ->ioLibrary;
const mint key = targ->key;
free(targ);
while(ioLibrary->asynchronousTaskAliveQ(asyncObjID))
{
if(GetAsyncKeyState(key) & 0x0001) {
ioLibrary->raiseAsyncEvent(asyncObjID, \"KeyPress\", NULL);
}
}
}
DLLEXPORT int start_key_tracker(WolframLibraryData libData,
mint Argc, MArgument *Args, MArgument Res)
{
mint asyncObjID;
WolframIOLibrary_Functions ioLibrary = libData->ioLibraryFunctions;
keyTrackerArgs threadArg = (keyTrackerArgs)malloc(sizeof(struct keyTrackerArgs_st));
if(Argc != 1)
return LIBRARY_FUNCTION_ERROR;
threadArg->ioLibrary = ioLibrary;
threadArg->key = MArgument_getInteger(Args[0]);
asyncObjID = ioLibrary->createAsynchronousTaskWithThread(key_tracker, threadArg);
MArgument_setInteger(Res, asyncObjID);
return LIBRARY_NO_ERROR;
}
"
},
Module[{srcFile},
srcFile = CreateFile["src.c"];
WriteString[srcFile, src];
Close[srcFile];
lib = CreateLibrary[{srcFile, libMain}, "keyLib", "IncludeDirectories" -> {DirectoryName[libMain]}];
DeleteFile[srcFile];
keyListener = LibraryFunctionLoad[lib, "start_key_tracker", {Integer}, Integer];
Internal`CreateAsynchronousTask[keyListener, {keycode}, action];
]
]
Let's say we want to make a sound (Beep[]
) every time the "PAUSE" key is hit. Then we evaluate
keyListen[19, Beep[] &]
where 19 is the code for "VK_PAUSE". Here are all the Windows key codes, in case you need them:
virtualKeyList = {"VK_LBUTTON" -> 1, "VK_RBUTTON" -> 2,
"VK_CANCEL" -> 3, "VK_MBUTTON" -> 4, "VK_XBUTTON1" -> 5,
"VK_XBUTTON2" -> 6, "VK_BACK" -> 8, "VK_TAB" -> 9,
"VK_CLEAR" -> 12, "VK_RETURN" -> 13, "VK_SHIFT" -> 16,
"VK_CONTROL" -> 17, "VK_MENU" -> 18, "VK_PAUSE" -> 19,
"VK_CAPITAL" -> 20, "VK_KANA" -> 21, "VK_HANGUEL" -> 21,
"VK_HANGUL" -> 21, "VK_JUNJA" -> 23, "VK_FINAL" -> 24,
"VK_HANJA" -> 25, "VK_KANJI" -> 25, "VK_ESCAPE" -> 27,
"VK_CONVERT" -> 28, "VK_NONCONVERT" -> 29, "VK_ACCEPT" -> 30,
"VK_MODECHANGE" -> 31, "VK_SPACE" -> 32, "VK_PRIOR" -> 33,
"VK_NEXT" -> 34, "VK_END" -> 35, "VK_HOME" -> 36, "VK_LEFT" -> 37,
"VK_UP" -> 38, "VK_RIGHT" -> 39, "VK_DOWN" -> 40,
"VK_SELECT" -> 41, "VK_PRINT" -> 42, "VK_EXECUTE" -> 43,
"VK_SNAPSHOT" -> 44, "VK_INSERT" -> 45, "VK_DELETE" -> 46,
"VK_HELP" -> 47, "VK_LWIN" -> 91, "VK_RWIN" -> 92, "VK_APPS" -> 93,
"VK_SLEEP" -> 95, "VK_NUMPAD0" -> 96, "VK_NUMPAD1" -> 97,
"VK_NUMPAD2" -> 98, "VK_NUMPAD3" -> 99, "VK_NUMPAD4" -> 100,
"VK_NUMPAD5" -> 101, "VK_NUMPAD6" -> 102, "VK_NUMPAD7" -> 103,
"VK_NUMPAD8" -> 104, "VK_NUMPAD9" -> 105, "VK_MULTIPLY" -> 106,
"VK_ADD" -> 107, "VK_SEPARATOR" -> 108, "VK_SUBTRACT" -> 109,
"VK_DECIMAL" -> 110, "VK_DIVIDE" -> 111, "VK_F1" -> 112,
"VK_F2" -> 113, "VK_F3" -> 114, "VK_F4" -> 115, "VK_F5" -> 116,
"VK_F6" -> 117, "VK_F7" -> 118, "VK_F8" -> 119, "VK_F9" -> 120,
"VK_F10" -> 121, "VK_F11" -> 122, "VK_F12" -> 123, "VK_F13" -> 124,
"VK_F14" -> 125, "VK_F15" -> 126, "VK_F16" -> 127,
"VK_F17" -> 128, "VK_F18" -> 129, "VK_F19" -> 130, "VK_F20" -> 131,
"VK_F21" -> 132, "VK_F22" -> 133, "VK_F23" -> 134,
"VK_F24" -> 135, "VK_NUMLOCK" -> 144, "VK_SCROLL" -> 145,
"VK_OEM_PLUS" -> 187, "VK_OEM_COMMA" -> 188, "VK_OEM_MINUS" -> 189,
"VK_OEM_PERIOD" -> 190, "VK_OEM_2" -> 191, "VK_OEM_5" -> 220,
"VK_OEM_8" -> 223, "VK_PACKET" -> 231};
"BackspaceKeyDown"
option forEventHandler
. Maybe try to contact tech support there. They'd be the final authority. $\endgroup$"MouseMoved"
and"MouseDragged"
. If you mean a mouse-wheel scroll on Windows I'm not sure how to get that. $\endgroup$