From ad6b3acab87622b5074cfba2a3432181aac2ea52 Mon Sep 17 00:00:00 2001 From: Ryandw11 <6239385+ryandw11@users.noreply.github.com> Date: Sat, 23 Jul 2022 21:14:31 -0700 Subject: [PATCH] Finished Key Presser Update --- AutoClickerDL/AutoClickerDL.c | 292 ++++++++++++++++++++++++++++------ AutoClickerDL/General.c | 109 ++++++++++--- AutoClickerDL/General.h | 51 +++++- AutoClickerDL/IO.c | 111 ++++++++++--- AutoClickerDL/IO.h | 2 + 5 files changed, 463 insertions(+), 102 deletions(-) diff --git a/AutoClickerDL/AutoClickerDL.c b/AutoClickerDL/AutoClickerDL.c index 82dd2eb..8e8a185 100644 --- a/AutoClickerDL/AutoClickerDL.c +++ b/AutoClickerDL/AutoClickerDL.c @@ -32,6 +32,10 @@ processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") #define REMEMBER_HOTKEY 6 #define REMEMBER_PLAY_HOTKEY 7 #define PRESS_KEY_HOTKEY 8 +#define MODE_BUTTON_GROUP 9 +#define RADIO_BUTTON_AUTO_CLICK 10 +#define RADIO_BUTTON_AUTO_PRESS 11 +#define SETTINGS_PRESS_UP_CHECK_BOX 12 // The handle to the main window. HWND mainWindowHandle; @@ -49,6 +53,8 @@ HWND mouseButtonComboBoxHWD; HWND rememberClickStatus; // Buttons HWND saveRecordingButton; +// Radio Buttons +HWND autoClickRadioButton, autoPressRadioButton; // The timer used by the clicker. Not null when enabled, NULL when not enabled. UINT_PTR autoClickerTimer = NULL; @@ -64,17 +70,24 @@ RecordingState recordingState; Settings currentSettings; // The hook handle for the mouse hook. -HHOOK mouseHook; +HHOOK mouseHook, keyHook; // The normal and activated icons. HICON normalIcon, clickActivatedIcon; // Process callbacks. LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +LRESULT CALLBACK GeneralProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT CALLBACK SettingsProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT CALLBACK RememberProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); // Hook Callback LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam); +LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam); + +// Helper Functions +int GetAutoMode(); +void UpdateAutoModeWindows(int); + /* This is the main method for the program. @@ -131,11 +144,11 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine tabItem.pszText = L"Remember Click"; TabCtrl_InsertItem(tabControl, 2, &tabItem); - generalDisplayArea = CreateWindow(WC_STATIC, L"", WS_CHILD | WS_VISIBLE | WS_BORDER, - 0, 23, WIDTH, HEIGHT-23, tabControl, NULL, hInstance, NULL); + generalDisplayArea = CreateTabDisplayArea(tabControl, hInstance, L"GeneralDisplayArea", 0, 23, WIDTH, HEIGHT - 23, GeneralProc); settingsDisplayArea = CreateTabDisplayArea(tabControl, hInstance, L"SettingsDisplayArea", 0, 23, WIDTH, HEIGHT - 23, SettingsProc); rememberClickDisplayArea = CreateTabDisplayArea(tabControl, hInstance, L"RememberDisplayArea", 0, 23, WIDTH, HEIGHT - 23, RememberProc); + ShowWindow(generalDisplayArea, TRUE); Settings loadedSettings = { 0 }; loadSettings("settings.acdl", &loadedSettings); @@ -197,15 +210,26 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine pressPerSecondSpinner.labelSize = 0; pressPerSecondSpinner.rangeMin = 1; pressPerSecondSpinner.rangeMax = 80; - //itowc(cps) - //pressPerSecondSpinner.defaultValue = cps; - pressPerSecondSpinner.defaultValue = L"20"; + itowc(pps) + pressPerSecondSpinner.defaultValue = pps; ppsSpinnerHWD = CreateSpinner(generalDisplayArea, hInstance, pressPerSecondSpinner); + // Press Hot Key HWND pressKeyLabel = CreateWindow(WC_STATIC, L"Key:", WS_VISIBLE | WS_CHILD | SS_CENTER, 100, 270, 30, 20, generalDisplayArea, NULL, hInstance, NULL); pressHotKey = CreateWindow(HOTKEY_CLASS, L"KeyToPress", WS_VISIBLE | WS_CHILD, 140, 270, 100, 20, generalDisplayArea, PRESS_KEY_HOTKEY, hInstance, NULL); + SendMessage(pressHotKey, HKM_SETHOTKEY, MAKEWORD(LOBYTE(loadedSettings.autoPressKey), HIBYTE(loadedSettings.autoPressKey)), 0); + + // Mode Radio Buttons + autoClickRadioButton = CreateWindow(L"BUTTON", L"Mouse Clicker", WS_VISIBLE | WS_CHILD | WS_GROUP | WS_TABSTOP | BS_AUTORADIOBUTTON, + 80, 350, 110, 20, generalDisplayArea, RADIO_BUTTON_AUTO_CLICK, hInstance, NULL); + autoPressRadioButton = CreateWindow(L"BUTTON", L"Key Presser", WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON, + 200, 350, 100, 20, generalDisplayArea, RADIO_BUTTON_AUTO_PRESS, hInstance, NULL); + + CheckDlgButton(generalDisplayArea, RADIO_BUTTON_AUTO_CLICK, loadedSettings.mode == MODE_AUTO_CLICK ? 1 : 0); + CheckDlgButton(generalDisplayArea, RADIO_BUTTON_AUTO_PRESS, loadedSettings.mode == MODE_AUTO_PRESS ? 1 : 0); + UpdateAutoModeWindows(loadedSettings.mode); /* @@ -252,6 +276,10 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine delayClickSpinner.defaultValue = delayTime; delaySpinnerHWD = CreateSpinner(settingsDisplayArea, hInstance, delayClickSpinner); + HWND keyUpCheckbox = CreateWindow(WC_BUTTON, L"Trigger Key Up", WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX, + 10, 180, 200, 20, settingsDisplayArea, SETTINGS_PRESS_UP_CHECK_BOX, hInstance, NULL); + CheckDlgButton(settingsDisplayArea, SETTINGS_PRESS_UP_CHECK_BOX, loadedSettings.pressKeyUp); + HWND saveButton = CreateWindow(WC_BUTTON, L"Save Settings", WS_CHILD | WS_VISIBLE | WS_TABSTOP, WIDTH / 2 - (80), HEIGHT - 120, 130, 35, settingsDisplayArea, SETTINGS_SAVE_BUTTON, hInstance, NULL); @@ -313,10 +341,14 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine */ void updateCurrentSettings(Settings* settings) { settings->cps = SendMessage(cpsSpinnerHWD, UDM_GETPOS32, NULL, NULL); + settings->mouseClickType = SendMessage(mouseButtonComboBoxHWD, CB_GETCURSEL, NULL, NULL); + settings->pps = SendMessage(ppsSpinnerHWD, UDM_GETPOS32, NULL, NULL); + settings->autoPressKey = SendMessage(pressHotKey, HKM_GETHOTKEY, NULL, NULL); + settings->mode = GetAutoMode(); settings->timedAutoClick = IsDlgButtonChecked(settingsDisplayArea, SETTINGS_TIMED_CHECK_BOX); settings->timedAutoClickValue = SendMessage(timedAutoSpinnerHWD, UDM_GETPOS32, NULL, NULL); settings->delayTime = SendMessage(delaySpinnerHWD, UDM_GETPOS32, NULL, NULL); - settings->mouseClickType = SendMessage(mouseButtonComboBoxHWD, CB_GETCURSEL, NULL, NULL); + settings->pressKeyUp = IsDlgButtonChecked(settingsDisplayArea, SETTINGS_PRESS_UP_CHECK_BOX); settings->hotkey = SendMessage(startStopHotKey, HKM_GETHOTKEY, NULL, NULL); settings->rmbStartHotkey = SendMessage(rmbClkRecordHK, HKM_GETHOTKEY, NULL, NULL); settings->rmbPlayHotKey = SendMessage(rmbClkRecordPlayHK, HKM_GETHOTKEY, NULL, NULL); @@ -335,6 +367,44 @@ BOOL isHotkeyControlInFocus() { return FALSE; } +/* + This is the callback for the messages of the general display background. +*/ +LRESULT CALLBACK GeneralProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { + switch (uMsg) { + case WM_COMMAND: + { + int cmd = HIWORD(wParam); + // Hot key selector change. + if (cmd == EN_CHANGE) { + int loword = LOWORD(wParam); + + if (loword == PRESS_KEY_HOTKEY) { + // Unregister and re-register global hot key with the change. + int result = SendMessage(pressHotKey, HKM_GETHOTKEY, NULL, NULL); + if (LOBYTE(result) != 0) + SetFocus(mainWindowHandle); + } + } + else if (cmd == BN_CLICKED) { + int button = LOWORD(wParam); + + if (button == RADIO_BUTTON_AUTO_CLICK) { + UpdateAutoModeWindows(MODE_AUTO_CLICK); + } + else if (button == RADIO_BUTTON_AUTO_PRESS) { + UpdateAutoModeWindows(MODE_AUTO_PRESS); + } + } + } + break; + break; + default: + break; + } + return DefWindowProc(hwnd, uMsg, wParam, lParam); +} + /* This is the callback for the messages of the settings display background. */ @@ -443,7 +513,7 @@ LRESULT CALLBACK RememberProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam if (LoadRecordingState(&recordingState, ofn.lpstrFile)) { MessageBox(mainWindowHandle, L"Successfully loaded the remember click file!", L"Successful Load", MB_ICONINFORMATION); wchar_t str[200] = { 0 }; - swprintf(str, 200, L"Recording loaded with %d mouse clicks!\0", recordingState.numberOfClicks); + swprintf(str, 200, L"Recording loaded with %d inputs!\0", recordingState.numberOfClicks); SetWindowText(rememberClickStatus, str); } else { @@ -487,18 +557,36 @@ LRESULT CALLBACK RememberProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam { // This timer is triggered by the remember click play hotkey. - MouseClick* currentClick = recordingState.previousClick; + RememberClick* currentClick = recordingState.previousClick; if (GetTickCount() - recordingState.prevoiusSystemTime < currentClick->delay) { break; } - int mouseClickType = MCToEventMouse(currentClick->type); - if (mouseClickType != MC_TYPE_ERROR) { - INPUT input = { 0 }; - // Move the cursor first. - SetCursorPos(currentClick->x, currentClick->y); - input.type = INPUT_MOUSE; - input.mi.dwFlags = MOUSEEVENTF_MOVE | mouseClickType; - SendInput(1, &input, sizeof(INPUT)); + if (currentClick->type == RC_MOUSE_CLICK) { + int mouseClickType = MCToEventMouse(currentClick->mi.type); + if (mouseClickType != MC_TYPE_ERROR) { + INPUT input = { 0 }; + // Move the cursor first. + SetCursorPos(currentClick->mi.x, currentClick->mi.y); + input.type = INPUT_MOUSE; + input.mi.dwFlags = MOUSEEVENTF_MOVE | mouseClickType; + SendInput(1, &input, sizeof(INPUT)); + } + } + else if (currentClick->type == RC_KEY_PRESS) { + int keyClickType = KBToEventKey(currentClick->ki.type); + if (keyClickType != 0) { + INPUT input = { 0 }; + input.type = INPUT_KEYBOARD; + input.ki.dwFlags = keyClickType; + input.ki.wVk = currentClick->ki.key; + SendInput(1, &input, sizeof(INPUT)); + } + else { + INPUT input = { 0 }; + input.type = INPUT_KEYBOARD; + input.ki.wVk = currentClick->ki.key; + SendInput(1, &input, sizeof(INPUT)); + } } recordingState.prevoiusSystemTime = GetTickCount(); NextMouseClick(&recordingState); @@ -604,6 +692,15 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) KillTimer(hwnd, autoClickerTimer); autoClickerTimer = NULL; SetClassLong(hwnd, GCL_HICON, normalIcon); + + // Send a key up event if needed. + if (GetAutoMode() == MODE_AUTO_PRESS && !IsDlgButtonChecked(settingsDisplayArea, SETTINGS_PRESS_UP_CHECK_BOX)) { + INPUT input = { 0 }; + input.type = INPUT_KEYBOARD; + input.ki.wVk = SendMessage(pressHotKey, HKM_GETHOTKEY, NULL, NULL); + input.ki.dwFlags = KEYEVENTF_KEYUP; + SendInput(1, &input, sizeof(INPUT)); + } } } break; @@ -629,7 +726,8 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) // Set the previous system time to the current number of milliseconds since the system started. recordingState.prevoiusSystemTime = GetTickCount(); mouseHook = SetWindowsHookEx(WH_MOUSE_LL, LowLevelMouseProc, GetModuleHandle(NULL), 0); - SetWindowText(rememberClickStatus, L"Recording clicks..."); + keyHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0); + SetWindowText(rememberClickStatus, L"Recording inputs..."); // Change the icon to gray. SetClassLong(hwnd, GCL_HICON, clickActivatedIcon); } @@ -640,10 +738,12 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) recordingState.previousClick = recordingState.startOfRecording; // Unhook the mouse hook to prevent lag if an error were to occur. UnhookWindowsHookEx(mouseHook); + UnhookWindowsHookEx(keyHook); mouseHook = NULL; + keyHook = NULL; EnableWindow(saveRecordingButton, TRUE); wchar_t str[200] = {0}; - swprintf(str, 200, L"Recording loaded with %d mouse clicks!\0", recordingState.numberOfClicks); + swprintf(str, 200, L"Recording loaded with %d inputs!\0", recordingState.numberOfClicks); SetWindowText(rememberClickStatus, str); // Change the icon back to normal. SetClassLong(hwnd, GCL_HICON, normalIcon); @@ -664,7 +764,7 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) recordingState.state = REC_STATE_PLAYING; recordingState.prevoiusSystemTime = GetTickCount(); wchar_t str[200] = { 0 }; - swprintf(str, 200, L"Playing recording with %d mouse clicks!\0", recordingState.numberOfClicks); + swprintf(str, 200, L"Playing recording with %d inputs!\0", recordingState.numberOfClicks); SetWindowText(rememberClickStatus, str); recordingState.previousClick = recordingState.startOfRecording; @@ -678,7 +778,7 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) recordingState.prevoiusSystemTime = 0; recordingState.previousClick = recordingState.startOfRecording; wchar_t str[200] = { 0 }; - swprintf(str, 200, L"Recording loaded with %d mouse clicks!\0", recordingState.numberOfClicks); + swprintf(str, 200, L"Recording loaded with %d inputs!\0", recordingState.numberOfClicks); SetWindowText(rememberClickStatus, str); SetClassLong(hwnd, GCL_HICON, normalIcon); } @@ -692,36 +792,74 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) // This timer is for the normal auto clicker. case WM_TIMER: { - int up = 0; - int down = 0; - getMouseFromSettings(&up, &down, ¤tSettings); - if (currentSettings.delayTime == 0) { - // When the timmer is triggered, send a click event. - INPUT inputs[2] = { 0 }; - - inputs[0].type = INPUT_MOUSE; - inputs[0].mi.dwFlags = MOUSEEVENTF_MOVE | down; - inputs[1].type = INPUT_MOUSE; - inputs[1].mi.dwFlags = MOUSEEVENTF_MOVE | up; - SendInput(2, &inputs, sizeof(INPUT)); + if (GetAutoMode() == MODE_AUTO_CLICK) { + int up = 0; + int down = 0; + getMouseFromSettings(&up, &down, ¤tSettings); + if (currentSettings.delayTime == 0) { + // When the timmer is triggered, send a click event. + INPUT inputs[2] = { 0 }; + + inputs[0].type = INPUT_MOUSE; + inputs[0].mi.dwFlags = MOUSEEVENTF_MOVE | down; + inputs[1].type = INPUT_MOUSE; + inputs[1].mi.dwFlags = MOUSEEVENTF_MOVE | up; + SendInput(2, &inputs, sizeof(INPUT)); + } + else { + INPUT inputOne = { 0 }; + INPUT inputTwo = { 0 }; + + inputOne.type = INPUT_MOUSE; + inputOne.mi.dwFlags = MOUSEEVENTF_MOVE | down; + inputTwo.type = INPUT_MOUSE; + inputTwo.mi.dwFlags = MOUSEEVENTF_MOVE | up; + SendInput(1, &inputOne, sizeof(INPUT)); + Sleep(currentSettings.delayTime); + SendInput(1, &inputTwo, sizeof(INPUT)); + } } - else { - INPUT inputOne = { 0 }; - INPUT inputTwo = { 0 }; - - inputOne.type = INPUT_MOUSE; - inputOne.mi.dwFlags = MOUSEEVENTF_MOVE | down; - inputTwo.type = INPUT_MOUSE; - inputTwo.mi.dwFlags = MOUSEEVENTF_MOVE | up; - SendInput(1, &inputOne, sizeof(INPUT)); - Sleep(currentSettings.delayTime); - SendInput(1, &inputTwo, sizeof(INPUT)); + else if (GetAutoMode() == MODE_AUTO_PRESS) { + BOOL triggerKeyUp = IsDlgButtonChecked(settingsDisplayArea, SETTINGS_PRESS_UP_CHECK_BOX); + if (currentSettings.delayTime == 0) { + // When the timmer is triggered, send a press event. + INPUT inputs[2] = { 0 }; + + inputs[0].type = INPUT_KEYBOARD; + inputs[0].ki.wVk = SendMessage(pressHotKey, HKM_GETHOTKEY, NULL, NULL); + inputs[1].type = INPUT_KEYBOARD; + inputs[1].ki.wVk = SendMessage(pressHotKey, HKM_GETHOTKEY, NULL, NULL); + inputs[1].ki.dwFlags = KEYEVENTF_KEYUP; + SendInput(triggerKeyUp ? 2 : 1, &inputs, sizeof(INPUT)); + } + else { + INPUT inputOne = { 0 }; + INPUT inputTwo = { 0 }; + + inputOne.type = INPUT_KEYBOARD; + inputOne.ki.wVk = SendMessage(pressHotKey, HKM_GETHOTKEY, NULL, NULL); + inputTwo.type = INPUT_KEYBOARD; + inputTwo.ki.wVk = SendMessage(pressHotKey, HKM_GETHOTKEY, NULL, NULL); + inputTwo.ki.dwFlags = KEYEVENTF_KEYUP; + SendInput(1, &inputOne, sizeof(INPUT)); + Sleep(currentSettings.delayTime); + if(triggerKeyUp) + SendInput(1, &inputTwo, sizeof(INPUT)); + } } // If timer mode is enabled, shut off the timer if over time. if (IsDlgButtonChecked(settingsDisplayArea, SETTINGS_TIMED_CHECK_BOX) && time(NULL) - startClickerTime >= SendMessage(timedAutoSpinnerHWD, UDM_GETPOS32, NULL, NULL)) { KillTimer(hwnd, autoClickerTimer); autoClickerTimer = NULL; + + if (GetAutoMode() == MODE_AUTO_PRESS && !IsDlgButtonChecked(settingsDisplayArea, SETTINGS_PRESS_UP_CHECK_BOX)) { + INPUT input = { 0 }; + input.type = INPUT_KEYBOARD; + input.ki.wVk = SendMessage(pressHotKey, HKM_GETHOTKEY, NULL, NULL); + input.ki.dwFlags = KEYEVENTF_KEYUP; + SendInput(1, &input, sizeof(INPUT)); + } } } break; @@ -741,17 +879,69 @@ LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam) { // Unknown / unwanted action, skip. if(mcType == 0) return CallNextHookEx(NULL, nCode, wParam, lParam); - MouseClick mc = { 0 }; - mc.nextClick = NULL; - mc.type = mcType; - mc.delay = GetTickCount() - recordingState.prevoiusSystemTime; + RememberClick rc = { 0 }; + rc.next = NULL; + rc.type = RC_MOUSE_CLICK; + rc.delay = GetTickCount() - recordingState.prevoiusSystemTime; // Set the previous system time to the current number of milliseconds since the system started. recordingState.prevoiusSystemTime = GetTickCount(); + rc.mi.type = mcType; POINT p = { 0 }; GetCursorPos(&p); - mc.x = p.x; - mc.y = p.y; - AddMouseClickToState(&recordingState, mc); + rc.mi.x = p.x; + rc.mi.y = p.y; + AddRememberClickToState(&recordingState, rc); return CallNextHookEx(NULL, nCode, wParam, lParam); +} + +LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { + if (nCode < 0 || recordingState.state != REC_STATE_RECORDING) + return CallNextHookEx(NULL, nCode, wParam, lParam); + + int kbType = WMToKB(wParam); + if(kbType == 0) + return CallNextHookEx(NULL, nCode, wParam, lParam); + RememberClick rc = { 0 }; + rc.next = NULL; + rc.type = RC_KEY_PRESS; + rc.delay = GetTickCount() - recordingState.prevoiusSystemTime; + recordingState.prevoiusSystemTime = GetTickCount(); + rc.ki.type = kbType; + LPKBDLLHOOKSTRUCT kb = (LPKBDLLHOOKSTRUCT) lParam; + rc.ki.key = kb->vkCode; + + AddRememberClickToState(&recordingState, rc); + + return CallNextHookEx(NULL, nCode, wParam, lParam); +} + +/** +* Get the current auto mode. +* +* @return MODE_AUTO_CLICK, MODE_AUTO_PRESS, or MODE_ERROR +*/ +int GetAutoMode() { + if (IsDlgButtonChecked(generalDisplayArea, RADIO_BUTTON_AUTO_CLICK)) return MODE_AUTO_CLICK; + else if (IsDlgButtonChecked(generalDisplayArea, RADIO_BUTTON_AUTO_PRESS)) return MODE_AUTO_PRESS; + else return MODE_ERROR; +} + +void UpdateAutoModeWindows( int mode ) { + if (mode == MODE_AUTO_CLICK) { + EnableWindow(cpsSpinnerHWD, TRUE); + EnableWindow((HWND)SendMessage(cpsSpinnerHWD, UDM_GETBUDDY, NULL, NULL), TRUE); + EnableWindow(mouseButtonComboBoxHWD, TRUE); + EnableWindow(pressHotKey, FALSE); + EnableWindow(ppsSpinnerHWD, FALSE); + EnableWindow((HWND)SendMessage(ppsSpinnerHWD, UDM_GETBUDDY, NULL, NULL), FALSE); + } + else if (mode == MODE_AUTO_PRESS) { + EnableWindow(cpsSpinnerHWD, FALSE); + EnableWindow((HWND)SendMessage(cpsSpinnerHWD, UDM_GETBUDDY, NULL, NULL), FALSE); + EnableWindow(mouseButtonComboBoxHWD, FALSE); + EnableWindow(pressHotKey, TRUE); + EnableWindow(ppsSpinnerHWD, TRUE); + EnableWindow((HWND)SendMessage(ppsSpinnerHWD, UDM_GETBUDDY, NULL, NULL), TRUE); + } } \ No newline at end of file diff --git a/AutoClickerDL/General.c b/AutoClickerDL/General.c index 1022d6c..a29065e 100644 --- a/AutoClickerDL/General.c +++ b/AutoClickerDL/General.c @@ -88,6 +88,27 @@ int WMToMC(int wParam) { return 0; } +/** + Convert Windows Keyboard (provided from windows keyboard hook) value into the Keyboard Click Type value. + + @param wParam the WM value (Example: WM_KEYDOWN) + @returns The KB value (example: KB_TYPE_KEYDOWN). (Returns KB_TYPE_ERROR if not valid). +*/ +int WMToKB(int wParam) { + switch (wParam) + { + case WM_KEYDOWN: + return KB_TYPE_KEYDOWN; + case WM_KEYUP: + return KB_TYPE_KEYUP; + case WM_SYSKEYDOWN: + return KB_TYPE_SYSKEYDOWN; + case WM_SYSKEYUP: + return KB_TYPE_SYSKEYUP; + } + return 0; +} + /* Convert a MC Type to a Mouse Event Type. @@ -113,6 +134,15 @@ int MCToEventMouse(int mc) { } } +int KBToEventKey(int kb) { + switch (kb) { + case KB_TYPE_SYSKEYDOWN: + case KB_TYPE_KEYUP: + return KEYEVENTF_KEYUP; + } + return 0; +} + /** Initalize the recording state. (Note: the default state is NONE). @@ -127,18 +157,28 @@ void InitRecordingState(RecordingState* state) { } /** - Add a mouse click the recording. (This will take care of every case and increment the numberOfClicks field). + Add a remember click the recording. (This will take care of every case and increment the numberOfClicks field). @param recState The pointer to the recording state to add the mouse click to. - @param mouseClick The mouse click struct to add. (Note: mouseClick.nextClick does not need to be set). + @param rememberClick The remember click struct to add. (Note: rememberClick.next does not need to be set). */ -void AddMouseClickToState(RecordingState* recState, MouseClick mouseClick) { - MouseClick* permElem = (MouseClick*)malloc(sizeof(MouseClick)); - permElem->type = mouseClick.type; - permElem->delay = mouseClick.delay; - permElem->nextClick = NULL; - permElem->x = mouseClick.x; - permElem->y = mouseClick.y; +void AddRememberClickToState(RecordingState* recState, RememberClick rememberClick) { + RememberClick* permElem = (RememberClick*)malloc(sizeof(RememberClick)); + if (permElem == NULL) return; + + permElem->delay = rememberClick.delay; + permElem->type = rememberClick.type; + permElem->next = NULL; + + if (rememberClick.type == RC_MOUSE_CLICK) { + permElem->mi.type = rememberClick.mi.type; + permElem->mi.x = rememberClick.mi.x; + permElem->mi.y = rememberClick.mi.y; + } + else if(rememberClick.type = RC_KEY_PRESS) { + permElem->ki.type = rememberClick.ki.type; + permElem->ki.key = rememberClick.ki.key; + } if (recState->numberOfClicks == 0) { recState->startOfRecording = permElem; @@ -146,19 +186,19 @@ void AddMouseClickToState(RecordingState* recState, MouseClick mouseClick) { recState->numberOfClicks = 1; return; } - recState->previousClick->nextClick = permElem; + recState->previousClick->next = permElem; recState->previousClick = permElem; recState->numberOfClicks++; } /** Get the next mouse click for the recording state. (If the end of the recording is reached, it will look back to the begining). - Get the pointer to the MouseClick struct from `recState.prevoiusClick`. + Get the pointer to the RememberClick struct from `recState.prevoiusClick`. @param recState The recording state to get the next mouse click from. */ void NextMouseClick(RecordingState* recState) { - recState->previousClick = recState->previousClick->nextClick == NULL ? recState->startOfRecording : recState->previousClick->nextClick; + recState->previousClick = recState->previousClick->next == NULL ? recState->startOfRecording : recState->previousClick->next; } /** @@ -170,8 +210,8 @@ void DeleteRecordingState(RecordingState* state) { if (state->numberOfClicks == 0) return; state->previousClick = state->startOfRecording; while (state->previousClick != NULL) { - MouseClick* current = state->previousClick; - state->previousClick = state->previousClick->nextClick; + RememberClick* current = state->previousClick; + state->previousClick = state->previousClick->next; free(current); } state->previousClick = NULL; @@ -202,12 +242,19 @@ BOOL SaveRecordingState(RecordingState* state, LPCWSTR location) { fputc(IO_ACDL_RECORDING_FILE, outputFile); fputi(outputFile, state->numberOfClicks); while (state->previousClick != NULL) { - MouseClick* currentClick = state->previousClick; + RememberClick* currentClick = state->previousClick; fputi(outputFile, currentClick->type); fputi(outputFile, currentClick->delay); - fputl(outputFile, currentClick->x); - fputl(outputFile, currentClick->y); - state->previousClick = state->previousClick->nextClick; + if (currentClick->type == RC_MOUSE_CLICK) { + fputi(outputFile, currentClick->mi.type); + fputl(outputFile, currentClick->mi.x); + fputl(outputFile, currentClick->mi.y); + } + else { + fputi(outputFile, currentClick->ki.type); + fputi(outputFile, currentClick->ki.key); + } + state->previousClick = state->previousClick->next; } fclose(outputFile); @@ -252,14 +299,32 @@ BOOL LoadRecordingState(RecordingState* state, LPCWSTR location) { int i = 0; for (i = 0; i < count; i++) { - MouseClick mouseClick = { 0 }; - if (!fgeti(inputFile, &mouseClick.type) || !fgeti(inputFile, &mouseClick.delay) - || !fgetl(inputFile, &mouseClick.x) || !fgetl(inputFile, &mouseClick.y)) { + RememberClick rememberClick = { 0 }; + if (!fgeti(inputFile, &rememberClick.type) || !fgeti(inputFile, &rememberClick.delay)) { + DeleteRecordingState(state); + fclose(inputFile); + return FALSE; + } + if (rememberClick.type == RC_MOUSE_CLICK) { + if (!fgeti(inputFile, &rememberClick.mi.type) || !fgetl(inputFile, &rememberClick.mi.x) || !fgetl(inputFile, &rememberClick.mi.y)) { + DeleteRecordingState(state); + fclose(inputFile); + return FALSE; + } + } + else if (rememberClick.type = RC_KEY_PRESS) { + if (!fgeti(inputFile, &rememberClick.ki.type) || !fgeti(inputFile, &rememberClick.ki.key)) { + DeleteRecordingState(state); + fclose(inputFile); + return FALSE; + } + } + else { DeleteRecordingState(state); fclose(inputFile); return FALSE; } - AddMouseClickToState(state, mouseClick); + AddRememberClickToState(state, rememberClick); } state->previousClick = state->startOfRecording; fclose(inputFile); diff --git a/AutoClickerDL/General.h b/AutoClickerDL/General.h index 4a4d18a..ea45642 100644 --- a/AutoClickerDL/General.h +++ b/AutoClickerDL/General.h @@ -13,27 +13,56 @@ #define MC_TYPE_MIDDLE_UP 5 #define MC_TYPE_RIGHT_UP 6 +#define KB_TYPE_ERROR 0 +#define KB_TYPE_KEYUP 1 +#define KB_TYPE_KEYDOWN 2 +#define KB_TYPE_SYSKEYUP 3 +#define KB_TYPE_SYSKEYDOWN 4 + #define REC_STATE_NONE 1 #define REC_STATE_LOADED 2 #define REC_STATE_RECORDING 3 #define REC_STATE_PLAYING 4 +#define MODE_ERROR 0 +#define MODE_AUTO_CLICK 1 +#define MODE_AUTO_PRESS 2 + +#define RC_MOUSE_CLICK 0 +#define RC_KEY_PRESS 1 + /* The representation of a MouseClick for use with the Remeber Click feature. */ typedef struct { // The type of click (denoted by MC_TYPE_ macros). int type; - // The delay (in milliseconds) from the previous click. - int delay; // The x position. LONG x; // The y position. LONG y; - // The pointer to the next click in the recording. - struct MouseClick* nextClick; } MouseClick; +typedef struct { + // The type of click (denoted by KB_TYPE_ macros). + int type; + // The key. + int key; +} KeyPress; + +typedef struct { + // The type of the RememberClick (RC_MOUSE_CLICK or RC_KEY_PRESS). + int type; + // The delay (in milliseconds) from the previous click. + int delay; + union { + MouseClick mi; + KeyPress ki; + }; + // The pointer to the next click in the recording. + struct RememberClick* next; +} RememberClick; + /* The current state of the recording system for the Remember Click feature. */ @@ -41,9 +70,9 @@ typedef struct { // The current state (denoted by REC_STATE_ macros). int state; // The first click in a recording. - MouseClick* startOfRecording; + RememberClick* startOfRecording; // The previous click that was done in a recording. - MouseClick* previousClick; + RememberClick* previousClick; // The previous system time in milliseconds. DWORD prevoiusSystemTime; // The number of clicks stored. @@ -55,10 +84,14 @@ typedef struct { */ typedef struct { int cps; + int mouseClickType; + int pps; + int autoPressKey; + int mode; BOOL timedAutoClick; int timedAutoClickValue; int delayTime; - int mouseClickType; + int pressKeyUp; int hotkey; int rmbStartHotkey; int rmbPlayHotKey; @@ -84,9 +117,11 @@ HWND CreateCheckBox(HWND parent, HINSTANCE hInstance, LPCWSTR text, int x, int y int WMToMC(int wParam); int MCToEventMouse(int mc); +int WMToKB(int wParam); +int KBToEventKey(int kb); void InitRecordingState(RecordingState*); -void AddMouseClickToState(RecordingState*, MouseClick); +void AddRememberClickToState(RecordingState*, RememberClick); void NextMouseClick(RecordingState*); void DeleteRecordingState(RecordingState*); diff --git a/AutoClickerDL/IO.c b/AutoClickerDL/IO.c index 3e96e3a..ec3302c 100644 --- a/AutoClickerDL/IO.c +++ b/AutoClickerDL/IO.c @@ -6,6 +6,29 @@ #pragma warning(disable: 4996) +void applyDefaultSettings(Settings* settings) { + settings->cps = 20; + settings->mouseClickType = 0; + settings->pps = 20; + settings->autoPressKey = 0; + settings->mode = 1; + settings->timedAutoClick = 0; + settings->timedAutoClickValue = 5; + settings->delayTime = 0; + settings->pressKeyUp = 1; + settings->hotkey = 112; + settings->rmbStartHotkey = VK_F2; + settings->rmbPlayHotKey = VK_F3; +} + +void modifySuccess(BOOL* succ, int output, int expected) { + if (output == expected) { + *succ = TRUE; + return; + } + *succ = FALSE; +} + /** Load settings from a file. Note: If an error occurs, the settings will be set to the default. @@ -18,29 +41,61 @@ void loadSettings(const char* fileName, Settings* settings) { if (inputFile == NULL) { // Unable to open file. - settings->cps = 2; - settings->timedAutoClick = 0; - settings->timedAutoClickValue = 5; - settings->delayTime = 0; - settings->hotkey = 112; - settings->rmbStartHotkey = VK_F2; - settings->rmbPlayHotKey = VK_F3; + applyDefaultSettings(settings); return; } - char hotkey[5] = { 0 }, rmbStartHotkey[5] = { 0 }, rmbStopHotkey[5] = { 0 }, rmbPlayHotkey[5] = {0}; - char ver; - char cps, timedAutoClick, timedAutoClickValue, delayTime, mouseClickType; - int output = fscanf(inputFile, "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c", &ver, &cps, &timedAutoClick, &timedAutoClickValue, &delayTime, &mouseClickType, + BOOL success = TRUE; + + char autoPressKey[5] = { 0 }, hotkey[5] = { 0 }, rmbStartHotkey[5] = { 0 }, rmbStopHotkey[5] = { 0 }, rmbPlayHotkey[5] = { 0 }; + char ver, mode; + char cps, mouseClickType, pps, timedAutoClick, timedAutoClickValue, delayTime, pressKeyUp; + + int output = fscanf(inputFile, "%c", &ver); + modifySuccess(&success, output, 1); + + output = fscanf(inputFile, "%c%c", &cps, &mouseClickType); + modifySuccess(&success, output, 2); + + output = fscanf(inputFile, "%c%c%c%c%c", &pps, &autoPressKey[0], &autoPressKey[1], &autoPressKey[2], &autoPressKey[3]); + modifySuccess(&success, output, 5); + + output = fscanf(inputFile, "%c", &mode); + modifySuccess(&success, output, 1); + + output = fscanf(inputFile, "%c%c%c%c", &timedAutoClick, &timedAutoClickValue, &delayTime, &pressKeyUp); + modifySuccess(&success, output, 4); + + output = fscanf(inputFile, "%c%c%c%c", &hotkey[0], &hotkey[1], &hotkey[2], &hotkey[3]); + modifySuccess(&success, output, 4); + + output = fscanf(inputFile, "%c%c%c%c", &rmbStartHotkey[0], &rmbStartHotkey[1], &rmbStartHotkey[2], &rmbStartHotkey[3]); + modifySuccess(&success, output, 4); + + output = fscanf(inputFile, "%c%c%c%c", &rmbPlayHotkey[0], &rmbPlayHotkey[1], &rmbPlayHotkey[2], &rmbPlayHotkey[3]); + modifySuccess(&success, output, 4); + + /*int output = fscanf(inputFile, "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c", &ver, &cps, &mouseClickType, &timedAutoClick, &timedAutoClickValue, &delayTime, &hotkey[0], &hotkey[1], &hotkey[2], &hotkey[3], &rmbStartHotkey[0], &rmbStartHotkey[1], &rmbStartHotkey[2], &rmbStartHotkey[3], &rmbPlayHotkey[0], &rmbPlayHotkey[1], &rmbPlayHotkey[2], &rmbPlayHotkey[3] - ); + );*/ + + if (success == FALSE) { + fclose(inputFile); + applyDefaultSettings(settings); + return; + } + settings->cps = cps; + settings->mouseClickType = mouseClickType; + settings->pps = pps; + settings->autoPressKey = atoi(autoPressKey); + settings->mode = mode; settings->timedAutoClick = timedAutoClick; settings->timedAutoClickValue = timedAutoClickValue; settings->delayTime = delayTime; - settings->mouseClickType = mouseClickType; + settings->pressKeyUp = pressKeyUp; int hotkeyI = atoi(hotkey); settings->hotkey = hotkeyI; @@ -50,8 +105,8 @@ void loadSettings(const char* fileName, Settings* settings) { } // FILE FORMAT:: -// (1 bytes vernum) - (1 bytes CPS) - (1 byte bool) - (1 bytes - timedAutoClickerValue) - (1 bytes - delay time) - (1 bytes - mouse click type) - (4 bytes - hotkey) - -// (4 bytes - start recording hotkey) - (4 bytes - play recording hotkey) +// (1 bytes vernum) - (1 bytes CPS) - (1 bytes - mouse click type) - (1 bytes PPS) - (4 bytes - auto press key) - (1 byte bool) - (1 bytes - timedAutoClickerValue) - (1 bytes - delay time) - (1 bytes - press key up) +// (4 bytes - hotkey) - (4 bytes - start recording hotkey) - (4 bytes - play recording hotkey) /** Save settings to a file. @@ -67,15 +122,29 @@ int saveSettings(const char* fileName, Settings* settings) { // Unable to open file. return -1; } - char hotkey[5] = { 0 }, rmbStartHotkey[5] = { 0 }, rmbPlayHotkey[5] = { 0 }; - itoa(settings->hotkey, hotkey, 10); - itoa(settings->rmbStartHotkey, rmbStartHotkey, 10); - itoa(settings->rmbPlayHotKey, rmbPlayHotkey, 10); - fprintf(outputFile, "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c", IO_ACDL_SETTINGS_FILE, settings->cps, settings->timedAutoClick, settings->timedAutoClickValue, settings->delayTime, settings->mouseClickType, + char autoPressKey[5] = { 0 }; + itoa(settings->autoPressKey, autoPressKey, 10); + + fprintf(outputFile, "%c", IO_ACDL_SETTINGS_FILE); + + fprintf(outputFile, "%c%c", settings->cps, settings->mouseClickType); + + fprintf(outputFile, "%c%c%c%c%c", settings->pps, autoPressKey[0], autoPressKey[1], autoPressKey[2], autoPressKey[3]); + + fprintf(outputFile, "%c", settings->mode); + + fprintf(outputFile, "%c%c%c%c", settings->timedAutoClick, settings->timedAutoClickValue, settings->delayTime, settings->pressKeyUp); + + fputi(outputFile, settings->hotkey); + + fputi(outputFile, settings->rmbStartHotkey); + + fputi(outputFile, settings->rmbPlayHotKey); + /*fprintf(outputFile, "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c", IO_ACDL_SETTINGS_FILE, settings->cps, settings->timedAutoClick, settings->timedAutoClickValue, settings->delayTime, settings->mouseClickType, hotkey[0],hotkey[1],hotkey[2],hotkey[3], rmbStartHotkey[0], rmbStartHotkey[1], rmbStartHotkey[2], rmbStartHotkey[3], rmbPlayHotkey[0], rmbPlayHotkey[1], rmbPlayHotkey[2], rmbPlayHotkey[3] - ); + );*/ fclose(outputFile); return 0; } diff --git a/AutoClickerDL/IO.h b/AutoClickerDL/IO.h index 70e19ae..b9cbefa 100644 --- a/AutoClickerDL/IO.h +++ b/AutoClickerDL/IO.h @@ -7,6 +7,8 @@ #define IO_ACDL_SETTINGS_FILE 1 #define IO_ACDL_RECORDING_FILE 2 +void applyDefaultSettings(Settings* settings); + void loadSettings(Settings* settings); int saveSettings(const char* fileName, Settings* settings);