Created
November 10, 2011 15:34
-
-
Save Chrisso/1355135 to your computer and use it in GitHub Desktop.
Animated eyes following mouse movement
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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