To begin with, I created a windows hook for the keyboard. This enables you to catch messages related to the keyboard and handle them before windows does.
bool ld = 0, // Left button down
rd = 0, // Right button down
ud = 0, // Up button down
dd = 0, // Down button down
lcd = 0; // Left Control key down
These are flags to show if any of the arrow keys or the left control key is being pressed, they are kept up to date in the keyboard hook.
I also set up a timer in the main windows message loop with an interval of 5ms. So every 5ms it checks if any of the arrow keys are down, if any of them are, then it will change the velocity the cursor is moving in the appropriate direction.
case WM_TIMER:
{
// Check if keys are down
if (ld) vx -= cursorSpeed; // Left key
if (rd) vx += cursorSpeed; // Right key
if (ud) vy -= cursorSpeed; // Up key
if (dd) vy += cursorSpeed; // Down key
GetCursorPos(&mousePos);
// Add velocity to current coordinates
x += vx;
y += vy;
// Slows the velocity of the cursor down
vx *= cursorFriction;
vy *= cursorFriction;
// Calculate the average speed
avSpeed = sqrt( vx * vx + vy * vy );
if (avSpeed > 0.2) {
// If cursor isn't almost stopped
SetCursorPos(x, y);
} else {
// Allow user to move cursor with the mouse instead
x = mousePos.x;
y = mousePos.y;
}
}
break;
As for allowing the user to left click using only the left ctrl key, I put this code in the keyboard hook process.
if (p->vkCode == VK_LCONTROL) {
if (LOWORD(wParam) == WM_KEYDOWN && !lcd) {
// Ctrl key pressed = left mouse button down
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
lcd = true; // Set flag
} else if (LOWORD(wParam) == WM_KEYUP && lcd) {
// Ctrl key released = left mouse button up
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
lcd = false; // Set flag
}
// We are handling the ctrl key, so don't let windows process it too
eat = true;
}
I commented the code to help, but overall, it uses the same basic idea to move the cursor as what Freaky_Chris said.
Hope this helps.