抓鼠标的猫(Win32实现,Codeblocks+GCC编译)
程序效果:
猫的眼睛一直跟着鼠标移动:
鼠标经过猫的右脚附近时,猫会抓住鼠标。(未使用Hook)
代码:
//main.cpp
1 #include <windows.h> 2 #include <math.h> 3 //#include <iostream> 4 //using namespace std; 5 LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; 6 double WIDTH=410,HEIGHT=430; 7 double px=0.0,py=0.0; 8 double ppx=0.0,ppy=0.0; 9 POINT sp; 10 int cat=0; 11 double width,height; 12 PAINTSTRUCT ps ; 13 RECT rect ; 14 POINT pts[3]; 15 double left_eye_px=0.0,right_eye_px=0.0; 16 double eye_py=0.0; 17 double eye_r=0.0; 18 double k=0.0; 19 double ball_hr=0.0;//半径 20 double deltax=0.0; 21 POINT p,pp; 22 int initGraph=1; 23 LPPOINT catp; 24 RECT eye_rect; 25 HBRUSH gray_brush =CreateSolidBrush (RGB(180,180,180)); 26 HBRUSH white_brush =CreateSolidBrush (RGB(255,255,255)); 27 HBRUSH black_brush =CreateSolidBrush (RGB(0,0,0)); 28 int drawRound(HDC hdc,int x,int y,int r) //r 直径 29 { 30 Ellipse(hdc,x-r/2,y-r/2,x+r/2,y+r/2); 31 return 0; 32 } 33 int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, 34 PSTR szCmdLine, int iCmdShow) 35 { 36 static TCHAR szAppName[] = TEXT ("HelloWin") ; 37 HWND hwnd ; 38 MSG msg ; 39 WNDCLASS wndclass ; 40 wndclass.style = CS_HREDRAW | CS_VREDRAW ; 41 wndclass.lpfnWndProc = WndProc ; 42 wndclass.cbClsExtra = 0 ; 43 wndclass.cbWndExtra = 0 ; 44 wndclass.hInstance = hInstance ; 45 wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; 46 wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; 47 wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; 48 wndclass.lpszMenuName = NULL ; 49 wndclass.lpszClassName = szAppName ; 50 if (!RegisterClass (&wndclass)) 51 { 52 MessageBox (NULL, TEXT ("This program requires Windows NT!"), 53 szAppName, MB_ICONERROR) ; 54 return 0 ; 55 } 56 hwnd = CreateWindow (szAppName, // window class name 57 TEXT ("Mouse Hook"), // window caption 58 WS_OVERLAPPEDWINDOW, // window style 59 CW_USEDEFAULT, // initial x position 60 CW_USEDEFAULT, // initial y position 61 WIDTH, // initial x size 62 HEIGHT, // initial y size 63 NULL, // parent window handle 64 NULL, // window menu handle 65 hInstance, // program instance handle 66 NULL) ; // creation parameters 67 ShowWindow (hwnd, iCmdShow) ; 68 UpdateWindow (hwnd) ; 69 while (GetMessage (&msg, NULL, 0, 0)) 70 { 71 TranslateMessage (&msg) ; 72 DispatchMessage (&msg) ; 73 } 74 return msg.wParam ; 75 } 76 77 int init(HWND hwnd) 78 { 79 GetClientRect (hwnd, &rect) ; 80 width=rect.right-rect.left ; 81 height=rect.bottom-rect.top ; 82 left_eye_px=width*3/8-height/16; 83 right_eye_px=width*5/8+height/16; 84 eye_py=height*5/10-height/16; 85 eye_r=height/8; 86 ball_hr=eye_r/8;//半径 87 px=left_eye_px; 88 py=eye_py; 89 ppx=right_eye_px; 90 ppy=eye_py; 91 eye_rect.left=left_eye_px-eye_r/2; 92 eye_rect.right=right_eye_px+eye_r/2; 93 eye_rect.top=eye_py-eye_r/2; 94 eye_rect.bottom=eye_py+eye_r/2; 95 return 0; 96 } 97 int drawHand(HDC hdc) 98 { 99 /**< 画嘴 */ 100 if(cat==0) 101 { 102 MoveToEx (hdc, width/4+width/10,height/48*33, NULL) ; 103 LineTo (hdc, width*3/4-width/10, height/48*33) ; 104 SelectObject (hdc,gray_brush ) ; 105 Ellipse(hdc,width/4-width/20,height/4*3,width/4+width/20,height*1.1);//左胳膊 106 Ellipse(hdc,width/4*3-width/20,height/4*3,width/4*3+width/20,height*1.1);//右胳膊 107 return 0; 108 } 109 SelectObject (hdc, gray_brush) ; 110 Ellipse(hdc,width/4*3-width/20,height/4*3,width/4*3+width/20,height*1.1);//右胳膊 111 Ellipse(hdc,width/4-width/20,height-height/4,width/4+width/20,height);//左胳膊 112 /**< 画脚掌 */ 113 Ellipse(hdc,width/4-width/12,height-height/7,width/4+width/12,height); 114 MoveToEx (hdc, width/4-width/15,height-height/9, NULL) ; 115 LineTo (hdc, width/4-width/16, height-height/15) ; 116 MoveToEx (hdc, width/4,height-height/7, NULL) ; 117 LineTo (hdc, width/4, height-height/16) ; 118 MoveToEx (hdc, width/4+width/15,height-height/9, NULL) ; 119 LineTo (hdc, width/4+width/16, height-height/15) ; 120 Arc( hdc, width/4-width/18, height-height/16,width/4+width/18, height,width/4+width/16, height,width/4-width/16, height); 121 /**< 画嘴 */ 122 Arc( hdc, width*1/4+width/10, height/48*27,width*3/4-width/10, height/48*33,width*1/4, height/48*30, width*3/4, height/48*30); 123 return 0; 124 } 125 LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 126 { 127 POINT pc; 128 HDC hdc; 129 switch (message) 130 { 131 case WM_CREATE: 132 init(hwnd); 133 initGraph =1; 134 InvalidateRect (hwnd,NULL, true) ; 135 return 0 ; 136 case WM_SIZE: 137 init(hwnd); 138 initGraph =1; 139 InvalidateRect (hwnd,NULL, true) ; 140 return 0; 141 case WM_MOVE: 142 return 0; 143 case WM_LBUTTONDOWN: 144 GetCursorPos(&pc); 145 if(pc.x==sp.x&&pc.y==sp.y) 146 { 147 cat=0; 148 SetCursorPos(sp.x,sp.y-height/2); 149 ReleaseCapture () ; 150 initGraph=1; 151 InvalidateRect (hwnd,NULL, true) ; 152 } 153 return 0 ; 154 case WM_MOUSEMOVE: 155 if(cat==1) 156 { 157 SetCursorPos(sp.x,sp.y); 158 return 0; 159 } 160 GetCursorPos(&p); 161 pp=p; 162 ScreenToClient(hwnd,&pp); 163 if((pp.x>width/4-width/12)&&(pp.x<width/4+width/12)&&(pp.y>height-height/7)&&(pp.y<height)) 164 { 165 SetCapture (hwnd) ; 166 sp.x=width/4; 167 sp.y=height-height/14; 168 ClientToScreen(hwnd,&sp); 169 cat=1; 170 initGraph=1; 171 InvalidateRect (hwnd,NULL, true) ; 172 return 0; 173 } 174 k=999.0; 175 if(pp.x-left_eye_px!=0) 176 { 177 k=(pp.y-eye_py)/(pp.x-left_eye_px); 178 } 179 deltax=(ball_hr/4)/(1+k*k); 180 deltax=sqrt(deltax); 181 if(!(pp.x>left_eye_px)) 182 { 183 deltax=(-1.0)*deltax; 184 } 185 px=left_eye_px+deltax*8; 186 deltax=(ball_hr/4)/(1+1/(k*k)); 187 deltax=sqrt(deltax); 188 if(!(pp.y>eye_py)) 189 { 190 deltax=(-1.0)*deltax; 191 } 192 py=eye_py+deltax*8; 193 k=999.0; 194 if(pp.x-right_eye_px!=0) 195 { 196 k=(pp.y-eye_py)/(pp.x-right_eye_px); 197 } 198 deltax=(ball_hr/4)/(1+k*k); 199 deltax=sqrt(deltax); 200 if(!(pp.x>right_eye_px)) 201 { 202 deltax=(-1.0)*deltax; 203 } 204 ppx=right_eye_px+deltax*8; 205 deltax=(ball_hr/4)/(1+1/(k*k)); 206 deltax=sqrt(deltax); 207 if(!(pp.y>eye_py)) 208 { 209 deltax=(-1.0)*deltax; 210 } 211 ppy=eye_py+deltax*8; 212 InvalidateRect (hwnd, &eye_rect, false) ; 213 return 0 ; 214 case WM_PAINT: 215 hdc=BeginPaint (hwnd,&ps) ; 216 if(initGraph==1) 217 { 218 SelectObject (hdc, gray_brush) ; 219 Ellipse(hdc,width/6,height/2,width-width/6,height*3/2);//身体 220 /**< 画脸 */ 221 Ellipse(hdc,0,height/4,width*20/20,height*3/4); 222 /**< 画耳朵 */ 223 pts[0].x =width/4; 224 pts[0].y =height/10; 225 pts[1].x =width/8; 226 pts[1].y =height/9*3; 227 pts[2].x =width/8*3; 228 pts[2].y =height/33*9; 229 Polygon (hdc, pts, 3) ; 230 pts[0].x =width/4*3; 231 pts[0].y =height/10; 232 pts[1].x =width/8*7; 233 pts[1].y =height/9*3; 234 pts[2].x =width/8*5; 235 pts[2].y =height/33*9; 236 Polygon (hdc, pts, 3) ; 237 /**< 画胡子 */ 238 MoveToEx (hdc, 0, height/48*27, NULL) ; 239 LineTo (hdc, width/8*2,height/48*27) ; 240 MoveToEx (hdc, 0, height/48*30, NULL) ; 241 LineTo (hdc, width/8*2,height/48*30) ; 242 MoveToEx (hdc, 0, height/48*33, NULL) ; 243 LineTo (hdc, width/8*2,height/48*33) ; 244 MoveToEx (hdc, width, height/48*27, NULL) ; 245 LineTo (hdc, width/8*6,height/48*27) ; 246 MoveToEx (hdc, width, height/48*30, NULL) ; 247 LineTo (hdc, width/8*6,height/48*30) ; 248 MoveToEx (hdc, width, height/48*33, NULL) ; 249 LineTo (hdc, width/8*6,height/48*33) ; 250 drawHand(hdc); 251 initGraph=0; 252 } 253 /**< 画眼睛 */ 254 SelectObject (hdc, white_brush) ; 255 drawRound(hdc,left_eye_px,eye_py,eye_r); 256 drawRound(hdc,right_eye_px,eye_py,eye_r); 257 SelectObject (hdc, black_brush) ; 258 drawRound(hdc,px,py,ball_hr*2); 259 drawRound(hdc,ppx,ppy,ball_hr*2); 260 EndPaint (hwnd, &ps) ; 261 return 0 ; 262 case WM_DESTROY: 263 PostQuitMessage (0) ; 264 return 0 ; 265 } 266 return DefWindowProc (hwnd, message, wParam, lParam) ; 267 }
程序写于大三上学期,Windows程序设计 课程考核作业。
2016.4.12更新博客。