Skip to content

Commit

Permalink
Completed Remember Click
Browse files Browse the repository at this point in the history
Finished the implementation of the Remember Click functionality.
  • Loading branch information
ryandw11 committed Dec 29, 2021
1 parent c3a24a4 commit d7cc262
Show file tree
Hide file tree
Showing 5 changed files with 258 additions and 1 deletion.
107 changes: 107 additions & 0 deletions AutoClickerDL/AutoClickerDL.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ HWND saveRecordingButton;
UINT_PTR autoClickerTimer = NULL;
time_t startClickerTime;

// The timer used for the remember click play timer.
UINT_PTR rememberClickTimer = NULL;

// Keep track of the state of a recording.
RecordingState recordingState;

Expand Down Expand Up @@ -381,6 +384,82 @@ LRESULT CALLBACK RememberProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam
SetFocus(mainWindowHandle);
}
}
else if (cmd == BN_CLICKED) {
int id = LOWORD(wParam);
if (id == REMEMBER_LOAD_RECORDING) {
if (!(recordingState.state == REC_STATE_LOADED || recordingState.state == REC_STATE_NONE)) {
break;
}
OPENFILENAME ofn;
TCHAR szFile[260] = { 0 };
ZeroMemory(&ofn, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = mainWindowHandle;
ofn.lpstrFile = szFile;
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = L"AutoClickerDL File (.acdl)\0*.acdl\0";
ofn.nFilterIndex = 0;
ofn.lpstrDefExt = L"acdl";
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
if (GetOpenFileName(&ofn)) {
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);
SetWindowText(rememberClickStatus, str);
}
else {
MessageBox(mainWindowHandle, L"Could not load remember click file, the file might be corrupted or in the incorrect format.", L"Error While Loading", MB_ICONERROR);
SetWindowText(rememberClickStatus, L"Load or create a Remember Click recording.");
EnableWindow(saveRecordingButton, FALSE);
InitRecordingState(&recordingState);
}
}
}
else if (id == REMEMBER_SAVE_RECORDING) {
if (recordingState.state != REC_STATE_LOADED) {
break;
}
OPENFILENAME ofn;
TCHAR szFile[260] = { 0 };
ZeroMemory(&ofn, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = mainWindowHandle;
ofn.lpstrFile = szFile;
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = L"AutoClickerDL File (.acdl)\0*.acdl\0";
ofn.nFilterIndex = 0;
ofn.lpstrDefExt = L"acdl";
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
if (GetSaveFileName(&ofn)) {
if (SaveRecordingState(&recordingState, ofn.lpstrFile)) {
MessageBox(mainWindowHandle, L"Successfully saved the remember click file!", L"Successful Save", MB_ICONINFORMATION);
}
else {
MessageBox(mainWindowHandle, L"Could not save remember click file. Does this program have permission to the location where you are trying to save?", L"Error While Saving", MB_ICONERROR);
}
}
}
}
}
break;
case WM_TIMER:
{
MouseClick* 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));
}
recordingState.prevoiusSystemTime = GetTickCount();
NextMouseClick(&recordingState);
}
break;
default:
Expand Down Expand Up @@ -493,6 +572,10 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
return;
}
if (recordingState.state == REC_STATE_NONE || recordingState.state == REC_STATE_LOADED) {
if (recordingState.state == REC_STATE_LOADED) {
DeleteRecordingState(&recordingState);
InitRecordingState(&recordingState);
}
// Set the program to record.
recordingState.state = REC_STATE_RECORDING;
// Set the previous system time to the current number of milliseconds since the system started.
Expand All @@ -515,7 +598,31 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
break;
case REMEMBER_PLAY_HOTKEY:
{
if (isHotkeyControlInFocus()) {
return;
}
if (autoClickerTimer != NULL) {
return;
}
if (recordingState.state == REC_STATE_LOADED) {
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);
SetWindowText(rememberClickStatus, str);

recordingState.previousClick = recordingState.startOfRecording;
rememberClickTimer = SetTimer(rememberClickDisplayArea, 1002, USER_TIMER_MINIMUM, (TIMERPROC)NULL);
}
else if (recordingState.state = REC_STATE_PLAYING) {
KillTimer(rememberClickDisplayArea, rememberClickTimer);
recordingState.state = REC_STATE_LOADED;
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);
SetWindowText(rememberClickStatus, str);
}
}
break;
}
Expand Down
108 changes: 108 additions & 0 deletions AutoClickerDL/General.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
#include <Windows.h>
#include <Commctrl.h>
#include <Shlobj.h>
#include <stdio.h>

#include "General.h"
#include "IO.h"

/*
Create a display area for the tab. (This create a seperate window class for each tab display area.)
Expand Down Expand Up @@ -80,6 +82,24 @@ int WMToMC(int wParam) {
return 0;
}

int MCToEventMouse(int mc) {
switch (mc) {
case MC_TYPE_LEFT_DOWN:
return MOUSEEVENTF_LEFTDOWN;
case MC_TYPE_LEFT_UP:
return MOUSEEVENTF_LEFTUP;
case MC_TYPE_RIGHT_DOWN:
return MOUSEEVENTF_RIGHTDOWN;
case MC_TYPE_RIGHT_UP:
return MOUSEEVENTF_RIGHTUP;
case MC_TYPE_MIDDLE_DOWN:
return MOUSEEVENTF_MIDDLEDOWN;
case MC_TYPE_MIDDLE_UP:
return MOUSEEVENTF_MIDDLEUP;
default:
return 0;
}
}

void InitRecordingState(RecordingState* state) {
state->numberOfClicks = 0;
Expand All @@ -106,4 +126,92 @@ void AddMouseClickToState(RecordingState* recState, MouseClick mouseClick) {
recState->previousClick->nextClick = permElem;
recState->previousClick = permElem;
recState->numberOfClicks++;
}

void NextMouseClick(RecordingState* recState) {
recState->previousClick = recState->previousClick->nextClick == NULL ? recState->startOfRecording : recState->previousClick->nextClick;
}

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;
free(current);
}
state->previousClick = NULL;
state->startOfRecording = NULL;
state->numberOfClicks = 0;
state->state = REC_STATE_NONE;
}

BOOL SaveRecordingState(RecordingState* state, LPCWSTR location) {
#pragma warning(disable: 4996)

if (state->numberOfClicks == 0) {
return FALSE;
}
state->previousClick = state->startOfRecording;

FILE* outputFile = _wfopen(location, L"w");
if (outputFile == NULL) return FALSE;
fputc(IO_ACDL_RECORDING_FILE, outputFile);
fputi(outputFile, state->numberOfClicks);
while (state->previousClick != NULL) {
MouseClick* currentClick = state->previousClick;
fputi(outputFile, currentClick->type);
fputi(outputFile, currentClick->delay);
fputl(outputFile, currentClick->x);
fputl(outputFile, currentClick->y);
state->previousClick = state->previousClick->nextClick;
}

fclose(outputFile);

state->previousClick = state->startOfRecording;

return TRUE;
}

BOOL LoadRecordingState(RecordingState* state, LPCWSTR location) {
#pragma warning(disable: 4996)
DeleteRecordingState(state);

InitRecordingState(state);

FILE* inputFile = _wfopen(location, L"r");
if (inputFile == NULL) return FALSE;
int type = fgetc(inputFile);
if (type != IO_ACDL_RECORDING_FILE) {
fclose(inputFile);
return FALSE;
}
int count = 0;
if (!fgeti(inputFile, &count)) {
fclose(inputFile);
return FALSE;
}

if (count <= 0) {
fclose(inputFile);
return FALSE;
}

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)) {
DeleteRecordingState(state);
fclose(inputFile);
return FALSE;
}
AddMouseClickToState(state, mouseClick);
}
state->previousClick = state->startOfRecording;
fclose(inputFile);
state->state = REC_STATE_LOADED;

return TRUE;
}
7 changes: 7 additions & 0 deletions AutoClickerDL/General.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#define AutoClickerDL_VER_NUM 1

#define MC_TYPE_ERROR 0
#define MC_TYPE_LEFT_DOWN 1
#define MC_TYPE_MIDDLE_DOWN 2
#define MC_TYPE_RIGHT_DOWN 3
Expand Down Expand Up @@ -60,8 +61,14 @@ HWND CreateSpinner(HWND parent, HINSTANCE hInstance, Spinner spinner);
HWND CreateCheckBox(HWND parent, HINSTANCE hInstance, LPCWSTR text, int x, int y, int width, int height, WNDPROC procCallback);

int WMToMC(int wParam);
int MCToEventMouse(int mc);

void InitRecordingState(RecordingState*);
void AddMouseClickToState(RecordingState*, MouseClick);
void NextMouseClick(RecordingState*);
void DeleteRecordingState(RecordingState*);

BOOL SaveRecordingState(RecordingState*, LPCWSTR);
BOOL LoadRecordingState(RecordingState*, LPCWSTR);

#endif
28 changes: 27 additions & 1 deletion AutoClickerDL/IO.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,37 @@ int saveSettings(const char* fileName, Settings* settings) {
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", 1, settings->cps, settings->timedAutoClick, settings->timedAutoClickValue, settings->delayTime, settings->mouseClickType,
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;
}

void fputi(FILE* file, int input) {
char charr[5] = { 0 };
itoa(input, charr, 10);
fprintf(file, "%c%c%c%c", charr[0], charr[1], charr[2], charr[3]);
}

void fputl(FILE* file, LONG input) {
char charr[9] = { 0 };
ltoa(input, charr, 10);
fprintf(file, "%c%c%c%c%c%c%c%c", charr[0], charr[1], charr[2], charr[3], charr[4], charr[5], charr[6], charr[7]);
}

BOOL fgeti(FILE* file, int* output) {
char charr[5] = { 0 };
int opt = fscanf(file, "%c%c%c%c", &charr[0], &charr[1], &charr[2], &charr[3]);
*output = atoi(charr);
return opt != 4 ? FALSE : TRUE;
}

BOOL fgetl(FILE* file, LONG* output) {
char charr[9] = { 0 };
int opt = fscanf(file, "%c%c%c%c%c%c%c%c", &charr[0], &charr[1], &charr[2], &charr[3], &charr[4], &charr[5], &charr[6], &charr[7]);
*output = atol(charr);
return opt != 8 ? FALSE : TRUE;
}
9 changes: 9 additions & 0 deletions AutoClickerDL/IO.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,16 @@

#include "General.h"

#define IO_ACDL_SETTINGS_FILE 1
#define IO_ACDL_RECORDING_FILE 2

void loadSettings(Settings* settings);
int saveSettings(const char* fileName, Settings* settings);

void fputi(FILE*, int);
void fputl(FILE*, LONG);

BOOL fgeti(FILE*, int*);
BOOL fgetl(FILE*, LONG*);

#endif

0 comments on commit d7cc262

Please sign in to comment.