[ucgui] 对话框5——鼠标位置和移动窗口
>_<" 这节主要是获取鼠标的位置和把窗口设置为可以移动。其中设置窗口可以移动用FRAMEWIN_SetMoveable(hFrameWin, 1)就行了。而获得鼠标位置则是利用WM_TOUCH消息的state结构体所传送过来的位置信息(见56、57两行)
1 #define FACTOR 5 2 #define EYE_X1 18 3 #define EYE_X2 54 4 #define EYE_Y 26 5 #define EYE_RX 16 6 #define EYE_RY 24 7 #define MIN_VISIBILITY 50 /* Make sure at least this many pixels stay visible when moved */ 8 9 static int _Min(int a, int b) { 10 return (a < b) ? a : b; 11 } 12 //画眼睛的函数 13 static void _DrawEye(int x0, int y0, int rx, int ry, int x1, int y1) { 14 int dx, dy, x, y; 15 float Hyp; 16 GUI_SetColor(GUI_WHITE); 17 GUI_FillEllipse(x0, y0, rx, ry); 18 GUI_SetColor(GUI_BLACK); 19 GUI_DrawEllipse(x0, y0, rx, ry); 20 /* Calculate the coordinates */ 21 dx = x1 - x0 + 1; 22 dy = y1 - y0 + 1; 23 Hyp = sqrt(dx * dx + dy * dy); 24 x = (dx * _Min(rx - 5, abs(dx)) * FACTOR / Hyp) + x0 * FACTOR; 25 y = (dy * _Min(ry - 5, abs(dy)) * FACTOR / Hyp) + y0 * FACTOR; 26 /* Draw the pupil */ 27 GUI_AA_SetFactor(FACTOR); 28 GUI_AA_EnableHiRes(); 29 GUI_SetColor(0xD00000); 30 GUI_AA_FillCircle(x, y, 5.75 * FACTOR); 31 GUI_SetColor(GUI_BLACK); 32 GUI_AA_FillCircle(x, y, 3.75 * FACTOR); 33 GUI_SetColor(GUI_GRAY); 34 GUI_AA_FillCircle(x - 1.25 * FACTOR, y - 1.25 * FACTOR, 1.25 * FACTOR); 35 GUI_AA_DisableHiRes(); 36 } 37 //窗口消息回调函数 38 static void _cbTransWindow(WM_MESSAGE* pMsg) { 39 WM_HWIN hWin = pMsg->hWin; 40 GUI_PID_STATE State; 41 GUI_PID_GetState(&State); 42 switch (pMsg->MsgId) { 43 case WM_PAINT: 44 State.x -= WM_GetWindowOrgX(hWin);//分别返回指定窗口的原点在桌面坐标中的X或Y位置 45 State.y -= WM_GetWindowOrgY(hWin); 46 _DrawEye(EYE_X1, EYE_Y, EYE_RX, EYE_RY, State.x, State.y); 47 _DrawEye(EYE_X2, EYE_Y, EYE_RX, EYE_RY, State.x, State.y); 48 break; 49 case WM_TOUCH: 50 if (pMsg->Data.p) { 51 GUI_PID_STATE* pState = (GUI_PID_STATE*)pMsg->Data.p; 52 if (pState->Pressed) { 53 int mx, my, x; 54 I32 Sum, SumY; 55 I32 OutConst = EYE_RX * EYE_RX * EYE_RY * EYE_RY + (EYE_RX * EYE_RX * EYE_RY >> 1); 56 mx = pState->x; 57 my = (pState->y < EYE_Y) ? (EYE_Y - pState->y) : (pState->y - EYE_Y); 58 if (my >= 0 && my <= EYE_RY) { 59 int y; 60 x = EYE_RX; 61 for (y = 0; y <= my; y++) { 62 SumY =((I32)(EYE_RX * EYE_RX)) * ((I32)(y * y)); 63 while (Sum = SumY + ((I32)(EYE_RY * EYE_RY)) * ((I32)(x * x)), (x > 0) && (Sum > OutConst)) { 64 x--; 65 } 66 } 67 } else { 68 x = -EYE_RX; 69 } 70 if (((mx >= EYE_X1 - x) && (mx <= EYE_X1 + x)) || 71 ((mx >= EYE_X2 - x) && (mx <= EYE_X2 + x)) || WM_HasCaptured(hWin)) 72 { 73 WM_SetCaptureMove(hWin, pState, MIN_VISIBILITY); 74 } else { 75 /* Transfer the message to the underlying window, since the transparent area has been clicked. */ 76 WM_HWIN hBelow = WM_Screen2hWinEx(hWin, State.x, State.y); 77 if (hBelow) { 78 pState->x = State.x - WM_GetWindowOrgX(hBelow); 79 pState->y = State.y - WM_GetWindowOrgY(hBelow); 80 WM_SendMessage(hBelow, pMsg); 81 } 82 } 83 } 84 } 85 break; 86 default: 87 WM_DefaultProc(pMsg); 88 } 89 } 90 //界面创建函数 91 static void _DemoTransWindow(void) { 92 WM_HWIN hTransWin, hFrameWin; 93 WM_SetCreateFlags(WM_CF_MEMDEV); 94 WM_EnableMemdev(WM_HBKWIN); 95 WM_SetDesktopColor(GUI_RED); 96 hTransWin = WM_CreateWindow(10, 10, 72, 52, WM_CF_SHOW | WM_CF_HASTRANS | WM_CF_STAYONTOP, 97 &_cbTransWindow, 0); 98 hFrameWin = FRAMEWIN_Create("Framewin", 0, WM_CF_SHOW, 100, 70, 120, 100); //创建一个FRAMEWIN小工具。(弃用) 99 FRAMEWIN_SetActive(hFrameWin, 1); //设置框架窗口的状态。(弃用) 100 FRAMEWIN_SetMoveable(hFrameWin, 1); //窗口可移动函数 101 GUI_CURSOR_Show(); 102 while (1) { 103 WM_InvalidateWindow(hTransWin); //使窗口无效。 104 GUI_Delay(20); 105 } 106 } 107 //主函数 108 void MainTask_eye(void) { 109 GUI_Init(); 110 _DemoTransWindow(); 111 }