#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Define global variables for the handles of the controls
HWND hwndLabel;
HWND hwndButtonStart;
HWND hwndButtonEnd;
HWND hwndListBox;
HWND hwndTextBox;
HWND hwndMain; // Handle of the main window
// Timer ID for mouse movement and actions
#define MOUSE_MOVE_TIMER_ID 2
// Structure to hold mouse coordinates
typedef struct {
int x;
int y;
} COORDINATE;
// Global array to store coordinates from the textbox
COORDINATE coordinates[100]; // Assuming a maximum of 100 coordinate pairs
int coordinateCount = 0;
int currentCoordinateIndex = 0;
BOOL isMoving = FALSE;
int repetitionCount = 0;
int currentRepetition = 0;
// Function to trim leading and trailing whitespace from a string
char *trim(char *str) {
char *end;
// Trim leading space
while (*str == ' ' || *str == '\t' || *str == '\n' || *str == '\r') {
str++;
}
if (*str == 0) {
return str;
}
// Trim trailing space
end = str + strlen(str) - 1;
while (end > str && (*end == ' ' || *end == '\t' || *end == '\n' || *str == '\r')) {
end--;
}
// Write new null terminator character
end[1] = '\0';
return str;
}
// Function to parse coordinates and instructions from the textbox
void ParseCoordinates() {
coordinateCount = 0;
currentCoordinateIndex = 0;
// Get the text from the textbox
int textLength = GetWindowTextLength(hwndTextBox);
char *buffer = (char *)malloc(textLength + 1);
if (buffer) {
GetWindowText(hwndTextBox, buffer, textLength + 1);
char *line = strtok(buffer, "\n");
while (line != NULL && coordinateCount < 100) {
char *trimmedLine = trim(line);
if (strlen(trimmedLine) > 0) {
int x, y;
if (sscanf(trimmedLine, "%d,%d", &x, &y) == 2) {
coordinates[coordinateCount].x = x;
coordinates[coordinateCount].y = y;
coordinateCount++;
}
}
line = strtok(NULL, "\n");
}
free(buffer);
}
}
// Function to perform mouse click
void PerformLeftClick() {
INPUT input[2];
memset(input, 0, sizeof(input));
// Left button down
input[0].type = INPUT_MOUSE;
input[0].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
// Left button up
input[1].type = INPUT_MOUSE;
input[1].mi.dwFlags = MOUSEEVENTF_LEFTUP;
SendInput(2, input, sizeof(INPUT));
}
// Function to perform key press
void PerformKeyPress(WORD vkCode, BOOL isUp) {
INPUT input;
memset(&input, 0, sizeof(input));
input.type = INPUT_KEYBOARD;
input.ki.wVk = vkCode;
if (isUp) {
input.ki.dwFlags = KEYEVENTF_KEYUP;
}
SendInput(1, &input, sizeof(INPUT));
}
// Function to process the current coordinate or instruction
void ProcessCoordinate() {
if (currentCoordinateIndex < coordinateCount) {
int x = coordinates[currentCoordinateIndex].x;
int y = coordinates[currentCoordinateIndex].y;
if (x == 0 && y == 0) {
PerformLeftClick();
} else if (x == 6 && y == 6) {
PerformKeyPress(VK_RIGHT, FALSE); // Right key down
PerformKeyPress(VK_RIGHT, TRUE); // Right key up
} else if (x == 4 && y == 4) {
PerformKeyPress(VK_LEFT, FALSE); // Left key down
PerformKeyPress(VK_LEFT, TRUE); // Left key up
} else if (x == 8 && y == 8) {
PerformKeyPress(VK_UP, FALSE); // Up key down
PerformKeyPress(VK_UP, TRUE); // Up key up
} else if (x == 2 && y == 2) {
PerformKeyPress(VK_DOWN, FALSE); // Down key down
PerformKeyPress(VK_DOWN, TRUE); // Down key up
} else {
// Move the mouse if no special instruction
SetCursorPos(x, y);
}
currentCoordinateIndex++;
} else {
// End of current repetition
currentRepetition++;
currentCoordinateIndex = 0; // Reset to the beginning of the instructions
if (currentRepetition >= repetitionCount) {
// Stop the timer when all repetitions are complete
KillTimer(hwndMain, MOUSE_MOVE_TIMER_ID);
isMoving = FALSE;
EnableWindow(hwndButtonStart, TRUE); // Re-enable the START button
EnableWindow(hwndButtonEnd, FALSE); // Disable the END button
currentRepetition = 0;
}
}
}
// Function to update the label with mouse coordinates
void UpdateMouseCoordinates(HWND hwnd) {
POINT cursorPoint;
char buffer[100];
// Get the current mouse cursor position (screen coordinates)
GetCursorPos(&cursorPoint);
// Format the coordinates into a string
sprintf(buffer, "X: %ld, Y: %ld", cursorPoint.x, cursorPoint.y);
// Set the text of the label
SetWindowText(hwndLabel, buffer);
}
// Function to handle button clicks
void HandleButtonClick(WPARAM wParam) {
WORD controlId = LOWORD(wParam);
switch (controlId) {
case 1001: // START button
if (!isMoving) {
ParseCoordinates();
if (coordinateCount > 0) {
// Get the selected repetition count from the listbox
LRESULT selectedIndex = SendMessage(hwndListBox, CB_GETCURSEL, 0, 0);
if (selectedIndex != CB_ERR) {
char buffer[10];
SendMessage(hwndListBox, CB_GETLBTEXT, selectedIndex, (LPARAM)buffer);
repetitionCount = atoi(buffer);
currentRepetition = 0;
isMoving = TRUE;
SetTimer(hwndMain, MOUSE_MOVE_TIMER_ID, 500, NULL); // Set timer for 500ms intervals
EnableWindow(hwndButtonStart, FALSE); // Disable the START button
EnableWindow(hwndButtonEnd, TRUE); // Enable the END button
}
}
}
break;
case 1002: // END button
if (isMoving) {
KillTimer(hwndMain, MOUSE_MOVE_TIMER_ID);
isMoving = FALSE;
currentRepetition = 0;
EnableWindow(hwndButtonStart, TRUE); // Re-enable the START button
EnableWindow(hwndButtonEnd, FALSE); // Disable the END button
}
break;
}
}
// Function to handle the main window's messages
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WM_CREATE: {
hwndMain = hwnd; // Store the main window handle
// Create the label control
hwndLabel = CreateWindowEx(
0,
"STATIC", // Static control class
"X: 0, Y: 0", // Initial text
WS_CHILD | WS_VISIBLE, // Styles: child window, visible
10, // Initial X position
10, // Initial Y position
150, // Initial width
20, // Initial height
hwnd, // Parent window (our main window)
NULL, // Control ID
GetModuleHandle(NULL),
NULL
);
if (hwndLabel == NULL) {
MessageBox(hwnd, "Could not create label.", "Error", MB_OK | MB_ICONERROR);
return -1;
}
// Create the START button
hwndButtonStart = CreateWindowEx(
0,
"BUTTON", // Button control class
"START", // Button text
WS_CHILD | WS_VISIBLE, // Styles: child window, visible
10, // Initial X position (below the label)
40, // Initial Y position
80, // Initial width
30, // Initial height
hwnd, // Parent window
(HMENU)1001, // Control ID (for later identification)
GetModuleHandle(NULL),
NULL
);
if (hwndButtonStart == NULL) {
MessageBox(hwnd, "Could not create START button.", "Error", MB_OK | MB_ICONERROR);
return -1;
}
// Create the END button (initially disabled)
hwndButtonEnd = CreateWindowEx(
0,
"BUTTON", // Button control class
"END", // Button text
WS_CHILD | WS_VISIBLE | WS_DISABLED, // Styles: child, visible, disabled
100, // Initial X position (beside the START button)
40, // Initial Y position
80, // Initial width
30, // Initial height
hwnd, // Parent window
(HMENU)1002, // Control ID
GetModuleHandle(NULL),
NULL
);
if (hwndButtonEnd == NULL) {
MessageBox(hwnd, "Could not create END button.", "Error", MB_OK | MB_ICONERROR);
return -1;
}
// Create the dropdown listbox beside the END button
hwndListBox = CreateWindowEx(
WS_EX_CLIENTEDGE, // Extended style for border
"COMBOBOX", // Combobox control class
"", // No initial text
CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL, // Styles: dropdown list, child, visible, vertical scroll
190, // Initial X position (beside the END button)
40, // Initial Y position
100, // Initial width
100, // Initial height (determines the dropdown height)
hwnd, // Parent window
(HMENU)1004, // Control ID
GetModuleHandle(NULL),
NULL
);
if (hwndListBox == NULL) {
MessageBox(hwnd, "Could not create combobox.", "Error", MB_OK | MB_ICONERROR);
return -1;
}
// Add items to the combobox (1 to 20)
for (int i = 1; i <= 20; i++) {
char buffer[10];
sprintf(buffer, "%d", i);
SendMessage(hwndListBox, CB_ADDSTRING, 0, (LPARAM)buffer);
}
// Set the initially visible item (optional, but good practice)
SendMessage(hwndListBox, CB_SETCURSEL, 0, 0); // Select the first item (index 0)
// Create the multiline textbox
hwndTextBox = CreateWindowEx(
WS_EX_CLIENTEDGE, // Extended style for border
"EDIT", // Edit control class
"", // No initial text
WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL, // Styles
10, // Initial X position (below the buttons and listbox)
150, // Initial Y position
280, // Initial width
140, // Initial height (adjusted to fit)
hwnd, // Parent window
(HMENU)1003, // Control ID
GetModuleHandle(NULL),
NULL
);
if (hwndTextBox == NULL) {
MessageBox(hwnd, "Could not create textbox.", "Error", MB_OK | MB_ICONERROR);
return -1;
}
// Set a timer to periodically update the mouse coordinates label
SetTimer(hwnd, 1, 100, NULL); // Timer ID 1
return 0;
}
case WM_TIMER:
if (wParam == 1) {
UpdateMouseCoordinates(hwnd);
} else if (wParam == MOUSE_MOVE_TIMER_ID && isMoving) {
ProcessCoordinate(); // Process coordinate or perform action
}
return 0;
case WM_COMMAND:
HandleButtonClick(wParam);
return 0;
case WM_DESTROY:
KillTimer(hwnd, 1);
KillTimer(hwnd, MOUSE_MOVE_TIMER_ID);
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
const char CLASS_NAME[] = "MyWindowClass";
WNDCLASS wc = { };
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
RegisterClass(&wc);
// Create the window with a larger size
HWND hwnd = CreateWindowEx(
0, // Optional window styles
CLASS_NAME, // Window class
"Mouse Mover", // Window text
WS_OVERLAPPEDWINDOW, // Window style
// Size and position (increased size to accommodate the listbox)
CW_USEDEFAULT, CW_USEDEFAULT, 400, 350,
NULL, // Parent window
NULL, // Menu
hInstance, // Instance handle
NULL // Additional application data
);
if (hwnd == NULL) {
return 0;
}
ShowWindow(hwnd, nCmdShow);
// Run the message loop
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}