Skip to content

Instantly share code, notes, and snippets.

@Himmler
Last active July 31, 2018 01:26
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save Himmler/9df5ffa344527511ee268170e9a36c87 to your computer and use it in GitHub Desktop.
Save Himmler/9df5ffa344527511ee268170e9a36c87 to your computer and use it in GitHub Desktop.
#include "windows.h"
/*
Command line options:
mouse buttons:
/L - left
/M - middle
/R - right
modes:
/H - hold
/T - trigger
parameters:
/P:20 - period=20 ms
/K:18 - keycode=18 ("Alt" key)
*/
#define IDC_BTN_LEFT MOUSEEVENTF_LEFTDOWN
#define IDC_BTN_MIDDLE MOUSEEVENTF_MIDDLEDOWN
#define IDC_BTN_RIGHT MOUSEEVENTF_RIGHTDOWN
#define IDC_BTN_HOLD 100
#define IDC_BTN_TRIGGER 101
#define IDC_EDIT_PERIOD 102
#define IDC_EDIT_KEY 103
#define IDC_BTN_EXIT 104
#define LBL_BTN_LEFT L"LEFT"
#define LBL_BTN_MIDDLE L"MIDDLE"
#define LBL_BTN_RIGHT L"RIGHT"
#define LBL_BTN_TRIGGER L"TRIGGER"
#define LBL_BTN_HOLD L"HOLD"
#define LBL_BTN_EXIT L"X"
#define LBL_STC_PERIOD L"PERIOD(ms)"
#define LBL_EDIT_PERIOD L"16"
#define LBL_STC_KEY L"KEY"
#define LBL_EDIT_KEY L"18"
#define WND_CX 280
#define WND_CY 110
#define TOTAL_CONTROLS 10
#define NUMCHARS(p) (sizeof(p)/sizeof((p)[0]))
#define DLGCTL(a) struct{DWORD style; DWORD exStyle; short x; short y; short cx; short cy; WORD id; WORD sysClass; WORD idClass; WCHAR wszTitle[NUMCHARS(a)]; WORD cbCreationData;}
#define BUTTON(x,y,cx,cy,id,title) {WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON|BS_MULTILINE, 0,(x)/2, (y)/2, (cx)/2, (cy)/2, id, 0xFFFF, 0x0080, title, 0}
#define RADIO(x,y,cx,cy,id,title) {WS_VISIBLE|WS_CHILD|BS_RADIOBUTTON, 0, (x)/2, (y)/2, (cx)/2, (cy)/2, id, 0xFFFF, 0x0080, title, 0}
#define STATIC(x,y,cx,cy,title) {WS_CHILD|WS_VISIBLE,WS_EX_TRANSPARENT, (x)/2, (y)/2, (cx)/2, (cy)/2, 0, 0xFFFF, 0x0082, title, 0}
#define EDIT(x,y,cx,cy,id,title) {WS_CHILD|WS_VISIBLE,WS_EX_CLIENTEDGE, (x)/2, (y)/2, (cx)/2, (cy)/2, id, 0xFFFF, 0x0081, title, 0}
#define LABELED_EDIT(x,y,cx,cy,id,label,value) STATIC(x,y,cx,cy,label), EDIT(x+90,y,cx,cy,id,value)
INPUT input[2];
#pragma data_seg("Dlg")
static struct
{
DWORD style; DWORD dwExtendedStyle; WORD ccontrols; short x; short y; short cx; short cy; WORD menu; WORD windowClass;
DLGCTL(LBL_BTN_LEFT) button_left;
DLGCTL(LBL_BTN_MIDDLE) button_middle;
DLGCTL(LBL_BTN_RIGHT) button_right;
DLGCTL(LBL_BTN_HOLD) button_hold;
DLGCTL(LBL_BTN_TRIGGER) button_trigger;
DLGCTL(LBL_BTN_EXIT) button_exit;
DLGCTL(LBL_STC_PERIOD) static_period; DLGCTL(LBL_EDIT_PERIOD) edit_period;
DLGCTL(LBL_STC_KEY) static_key; DLGCTL(LBL_EDIT_KEY) edit_key;
} Dlg =
{
WS_VISIBLE|WS_POPUP|WS_BORDER, 0, TOTAL_CONTROLS, 50/2, 50/2, WND_CX/2, WND_CY/2, 0, 0,
RADIO( 10, 0, 80, 30, IDC_BTN_LEFT, LBL_BTN_LEFT),
RADIO( 100, 0, 80, 30, IDC_BTN_MIDDLE, LBL_BTN_MIDDLE),
RADIO( 190, 0, 68, 30, IDC_BTN_RIGHT, LBL_BTN_RIGHT),
RADIO( 10, 50, 80, 30, IDC_BTN_HOLD, LBL_BTN_HOLD),
RADIO( 190, 50, 80, 30, IDC_BTN_TRIGGER, LBL_BTN_TRIGGER),
BUTTON( WND_CX-22, 2, 20, 20, IDC_BTN_EXIT, LBL_BTN_EXIT),
LABELED_EDIT( 10, 30, 80, 20, IDC_EDIT_PERIOD, LBL_STC_PERIOD, LBL_EDIT_PERIOD),
LABELED_EDIT( 10, 80, 80, 20, IDC_EDIT_KEY, LBL_STC_KEY, LBL_EDIT_KEY)
};
HWND hWnd;
char tmp[MAX_PATH];
unsigned char trigger_mode;
unsigned char key = 18;
unsigned int period;
LRESULT CALLBACK WinProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch(msg)
{
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_BTN_LEFT:
case IDC_BTN_MIDDLE:
case IDC_BTN_RIGHT:
input[0].mi.dwFlags = wParam;
input[1].mi.dwFlags = (wParam<<1);
CheckRadioButton(hWnd,IDC_BTN_LEFT,IDC_BTN_MIDDLE,wParam);
break;
case IDC_BTN_HOLD:
case IDC_BTN_TRIGGER:
trigger_mode = (wParam==IDC_BTN_TRIGGER);
CheckRadioButton(hWnd,IDC_BTN_HOLD,IDC_BTN_TRIGGER,wParam);
break;
case IDC_EDIT_PERIOD:
period = GetDlgItemInt(hWnd,IDC_EDIT_PERIOD,(BOOL*)&tmp[0],0);
break;
case IDC_BTN_EXIT:
exit(0);
}
break;
}
return DefWindowProc(hWnd,msg,wParam,lParam);
}
DWORD WINAPI InputThread(LPVOID argument_pointer)
{
unsigned int active = 0;
unsigned int key_state;
unsigned int prev_key_state;
while(1)
{
key_state = (GetAsyncKeyState(key)>>1);
if (trigger_mode)
{
if ((key_state)&&(key_state!=prev_key_state))
active^= 1;
prev_key_state = key_state;
}
else
active = key_state;
if (active)
SendInput(2,(LPINPUT)&input,sizeof(INPUT));
Sleep(period);
}
return 0;
}
int WINAPI entry(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR lpCmdLine,int nShowCmd)
{
MSG msg;
HWND key_hWnd;
static ACTCTX actCtx = {sizeof(ACTCTX),ACTCTX_FLAG_RESOURCE_NAME_VALID|ACTCTX_FLAG_SET_PROCESS_DEFAULT|ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID,"shell32.dll",0,0,tmp,(LPCTSTR)124,0,0};
static unsigned int arg_to_cmd[] = {IDC_BTN_HOLD,0,0,IDC_EDIT_KEY,IDC_BTN_LEFT,IDC_BTN_MIDDLE,0,0,IDC_EDIT_PERIOD,0,IDC_BTN_RIGHT,0,IDC_BTN_TRIGGER};
char* i;
unsigned int t;
//enable visual styles
GetSystemDirectory(tmp,sizeof(tmp));
LoadLibrary("shell32.dll");
ActivateActCtx(CreateActCtx(&actCtx),(ULONG_PTR*)&tmp);
//create and init main dialog
hWnd=CreateDialogIndirect(0,(LPCDLGTEMPLATEW)&Dlg,0,(DLGPROC)&WinProc);
SendMessage(hWnd,WM_COMMAND,IDC_BTN_LEFT,0);
SendMessage(hWnd,WM_COMMAND,IDC_BTN_HOLD,0);
//parse command line
i = (char*)GetCommandLine();
while(*i)
{
if (*(i++)=='/')//looking for argument
switch(*i)
{
case 'L':
case 'M':
case 'R':
case 'H':
case 'T':
SendMessage(hWnd,WM_COMMAND,arg_to_cmd[*i-'H'],0);//send button command
break;
case 'P':
case 'K':
t = atoi(i+2);
SetDlgItemInt(hWnd,arg_to_cmd[*i-'H'],t,0);
if(*i=='P')
period = t;
else
key = t;
break;
}
}
key_hWnd = GetDlgItem(hWnd,IDC_EDIT_KEY);
CreateThread(0,0,InputThread,0,0,0);
while(GetMessage(&msg,0,0,0))
{
//hook keyboard events from IDC_EDIT_KEY
if ((msg.hwnd==key_hWnd)&&
((msg.message==WM_KEYDOWN)||
(msg.message==WM_KEYUP)||
(msg.message==WM_SYSKEYDOWN)||
(msg.message==WM_SYSKEYUP)))
{
key = msg.wParam;
SetDlgItemInt(hWnd,IDC_EDIT_KEY,key,0);
continue;//cancel message dispatch
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment