This is my first program ever made in C. Before that I programmed just a little bit in C++ (didn't touch OOP so I did only structural programming). This is my second "project" ever made, the first "project" was even bigger joke. I am new to programming.
The project is nowhere near to be finished. However, it somehow works, and I don't want to add new features until this mess is cleaned up. I feel like for me the bigger the mess is, the harder it is to find small mistakes.
That's why I come here: would you please be able to take a look at my code and tell me what's wrong with it? Especially program structure-wise.
Program features:
- after execution immedietely starts recording cursor's movements and cursor/keyboard keystrokes
- if 'W' is pressed the recording stops
- and 5 seconds later the recording is played-back, simulating what has been recorded
Basically during the recording phase it snapshots the keyboard and mouse state every ~10 miliseconds.
Few things to mention:
- doubly linked list is not freed yet. I will handle the memory leaks.
- the program does not and probably will not support simulating multiple keypresses at the same time
- I will make it more user-friendly and such after I fix this mess
Here is link to the github containing all the code: https://github.com/Wenox/WinAuto
For example, I wonder if such function:
POINT get_cursor(void)
{
POINT P = {};
GetCursorPos(&P);
return P;
}
deserves its own input_cursor.c
file?
The main thing I am curious about is the recording.c
file containing:
#include ..bunch of files..
#define _GETCURSOR 1
#define _GETKEY 2
#define _SLEEP 3
/** adds cursor's position to the functions queue */
void add_cursor(struct f_queue **head, struct f_queue **tail, POINT P[2])
{
P[1] = get_cursor();
if (P[0].x != P[1].x || P[0].y != P[1].y) { // if current cursor pos != previous
add_function(head, tail, _GETCURSOR, P[1].x, P[1].y); // add it to the queue
P[0] = P[1];
}
}
/** adds latest keystroke's description to the functions queue */
void add_keystroke(struct f_queue **head, struct f_queue **tail, int key_buff[2])
{
key_buff[1] = get_keystroke();
if (key_buff[1] != key_buff[0] && key_buff[1] != 0) // if there was keystroke
add_function(head, tail, _GETKEY, key_buff[1], -1); // then add it to the queue
key_buff[0] = key_buff[1];
}
/** returns true if newly added node is function of sleep type, false otherwise */
bool is_prev_sleep_func(struct f_queue **head)
{
return (*head)->f_type == _SLEEP;
}
/** adds sleep to functions queue */
void add_sleep(struct f_queue **head, struct f_queue **tail, const int sleep_dur)
{
Sleep(sleep_dur);
if (!is_prev_sleep_func(head))
add_function(head, tail, _SLEEP, sleep_dur, -1);
else
(*head)->f_args[0] += sleep_dur; // increment the node rather than add new one
}
/** keyboard/mouse recording engine */
void record(struct f_queue **head, struct f_queue **tail, const int sleep_dur)
{
int key_buff[2] = {-1, -1}; // buffer for curr and prev pressed key
POINT cursor_buff[2] = {0}; // buffer for curr and prev cursor position
while(key_buff[1] != KEY_W) { // stop recording when '3' is pressed
add_cursor(head, tail, cursor_buff);
add_keystroke(head, tail, key_buff);
add_sleep(head, tail, sleep_dur);
}
}
and the play_recording()
function from replay.c
file:
/** function replays the recording */
void play_recording(struct f_queue *tail)
{
while (tail) {
if (tail->f_type == _GETCURSOR)
SetCursorPos(tail->f_args[0], tail->f_args[1]);
else if (tail->f_type == _GETKEY)
send_input(tail->f_args[0]);
else if (tail->f_type == _SLEEP)
Sleep(tail->f_args[0]);
tail = tail->prev;
}
}
if it looks neat/readable/understandable to a person who reads it for the first time, and if something is clearly wrong/could be improved/is a bad practice.
For all suggestions/advices on any kind of improvements I am gladly thankful. Many thanks.