Skip to content

Instantly share code, notes, and snippets.

@Chrisso
Created November 10, 2011 15:34
Show Gist options
  • Save Chrisso/1355135 to your computer and use it in GitHub Desktop.
Save Chrisso/1355135 to your computer and use it in GitHub Desktop.
Animated eyes following mouse movement
#define WIN32_LEAN_AND_MEAN
#define _USE_MATH_DEFINES
#include <windows.h>
#include <stdio.h>
#include <math.h>
POINT CalcEyePosition(HWND hWnd, RECT *rcClient)
{
POINT ptWindow;
ptWindow.x = rcClient->right / 2;
ptWindow.y = rcClient->bottom / 2;
ClientToScreen(hWnd, &ptWindow);
POINT ptCursor;
GetCursorPos(&ptCursor);
double deg = (double)(ptCursor.x - ptWindow.x);
deg /= (double)(ptCursor.y - ptWindow.y);
deg = atan(deg);
int a = rcClient->right / 4;
int b = rcClient->bottom / 2;
POINT pt;
if (ptCursor.y > ptWindow.y)
{
pt.x = (LONG)(a/2 * sin(deg) + a);
pt.y = (LONG)(b/2 * cos(deg) + b);
}
else
{
pt.x = (LONG)(a - (a/2 * sin(deg)));
pt.y = (LONG)(b - (b/2 * cos(deg)));
}
return pt;
}
void UpdateFrame(HWND hWnd)
{
RECT rcClient;
GetClientRect(hWnd, &rcClient);
HDC hDC = GetDC(hWnd);
if (hDC)
{
Ellipse(hDC, 0, 0, (rcClient.right / 2) - 2, rcClient.bottom-1);
Ellipse(hDC, (rcClient.right / 2) + 1, 0, rcClient.right - 2, rcClient.bottom-1);
int wx = rcClient.right / 16, wy = rcClient.bottom / 8;
int mx = rcClient.right / 2, my = rcClient.bottom / 2;
SelectObject(hDC, GetStockObject(BLACK_BRUSH));
POINT pt = CalcEyePosition(hWnd, &rcClient);
Ellipse(hDC, pt.x -wx , pt.y - wy, pt.x + wx, pt.y + wy);
Ellipse(hDC, pt.x + mx - wx, pt.y - wy, pt.x + mx + wx, pt.y + wy);
ReleaseDC(hWnd, hDC);
}
}
void ResetRegion(HWND hWnd, WORD width, WORD height)
{
HRGN l_eye = CreateEllipticRgn(0, 0, (width / 2) - 1, height);
HRGN r_eye = CreateEllipticRgn((width / 2) + 1, 0, width - 1, height);
CombineRgn(l_eye, l_eye, r_eye, RGN_OR);
SetWindowRgn(hWnd, l_eye, TRUE);
}
void SaveSettings(HWND hWnd)
{
char name[MAX_PATH];
GetModuleFileName(NULL, name, sizeof(name));
size_t pos = strlen(name);
name[pos - 3] = 'i';
name[pos - 2] = 'n';
name[pos - 1] = 'i';
RECT rc; GetClientRect(hWnd, &rc);
POINT pt = {0, 0}; ClientToScreen(hWnd, &pt);
char tmp[32];
sprintf(tmp, "%d", pt.x); WritePrivateProfileString("Settings", "PosX", tmp, name);
sprintf(tmp, "%d", pt.y); WritePrivateProfileString("Settings", "PosY", tmp, name);
sprintf(tmp, "%d", rc.right); WritePrivateProfileString("Settings", "Width", tmp, name);
sprintf(tmp, "%d", rc.bottom); WritePrivateProfileString("Settings", "Height", tmp, name);
}
RECT ReadSettings()
{
RECT rc;
char name[MAX_PATH];
GetModuleFileName(NULL, name, sizeof(name));
size_t pos = strlen(name);
name[pos - 3] = 'i';
name[pos - 2] = 'n';
name[pos - 1] = 'i';
rc.left = GetPrivateProfileInt("Settings", "PosX", 100, name);
rc.top = GetPrivateProfileInt("Settings", "PosY", 100, name);
rc.right = GetPrivateProfileInt("Settings", "Width", 200, name);
rc.bottom = GetPrivateProfileInt("Settings", "Height", 125, name);
return rc;
}
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(hWnd, &ps);
UpdateFrame(hWnd);
EndPaint(hWnd, &ps);
}
break;
case WM_TIMER:
UpdateFrame(hWnd);
break;
case WM_SIZE:
ResetRegion(hWnd, LOWORD(lParam), HIWORD(lParam));
break;
case WM_LBUTTONDBLCLK:
{
if (MessageBox(hWnd, "Wirklich beenden?", "MouseEyes", MB_YESNO | MB_ICONQUESTION) == IDYES)
PostMessage(hWnd, WM_CLOSE, 0, 0);
}
break;
case WM_NCHITTEST:
{
POINT pt; RECT rc;
pt.x = LOWORD(lParam);
pt.y = HIWORD(lParam);
ScreenToClient(hWnd, &pt);
GetClientRect(hWnd, &rc);
if (pt.x > 0.75 * rc.right && pt.y > rc.bottom / 2)
return HTBOTTOMRIGHT;
else if (pt.x > rc.right / 2)
return HTCAPTION;
else return HTCLIENT;
}
case WM_CLOSE:
{
SaveSettings(hWnd);
PostQuitMessage(0);
return 0L;
}
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow)
{
if (FindWindow("MouseEye", NULL)) return 0;
WNDCLASS wc;
wc.hInstance = hInst;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = reinterpret_cast<HBRUSH>(GetStockObject(WHITE_BRUSH));
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.lpfnWndProc = WindowProc;
wc.lpszClassName = "MouseEye";
wc.lpszMenuName = NULL;
wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
RegisterClass(&wc);
//HWND hWnd = CreateWindow("MouseEye", "MouseEye", WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_THICKFRAME, 100, 100, 200, 125, NULL, NULL, hInst, NULL);
HWND hWnd = CreateWindow("MouseEye", "MouseEye", WS_POPUP, 100, 100, 200, 125, NULL, NULL, hInst, NULL);
if (!hWnd)
{
MessageBox(NULL, "Cannot Create Window!", "Error", MB_ICONERROR | MB_OK);
return 1;
}
RECT wndSettings = ReadSettings();
SetWindowPos(hWnd, HWND_TOPMOST, wndSettings.left, wndSettings.top, wndSettings.right, wndSettings.bottom, 0);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
RECT rcClient;
GetClientRect(hWnd, &rcClient);
ResetRegion(hWnd, (WORD)rcClient.right, (WORD) rcClient.bottom);
SetTimer(hWnd, 1, 100, NULL);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment