OSDN Git Service

post WM_NULL to attached threads on yamy exit to unmap mayu{32,64}.dll
[yamy/yamy.git] / target.cpp
1 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
2 // target.cpp\r
3 \r
4 \r
5 #include "misc.h"\r
6 \r
7 #include "mayurc.h"\r
8 #include "target.h"\r
9 #include "windowstool.h"\r
10 \r
11 \r
12 ///\r
13 class Target\r
14 {\r
15         HWND m_hwnd;                                    ///\r
16         HWND m_preHwnd;                         ///\r
17         HICON m_hCursor;                                ///\r
18 \r
19         ///\r
20         static void invertFrame(HWND i_hwnd) {\r
21                 HDC hdc = GetWindowDC(i_hwnd);\r
22                 ASSERT(hdc);\r
23                 int rop2 = SetROP2(hdc, R2_XORPEN);\r
24                 if (rop2) {\r
25                         RECT rc;\r
26                         CHECK_TRUE( GetWindowRect(i_hwnd, &rc) );\r
27                         int width = rcWidth(&rc);\r
28                         int height = rcHeight(&rc);\r
29 \r
30                         HANDLE hpen = SelectObject(hdc, GetStockObject(WHITE_PEN));\r
31                         HANDLE hbr  = SelectObject(hdc, GetStockObject(NULL_BRUSH));\r
32                         CHECK_TRUE( Rectangle(hdc, 0, 0, width    , height    ) );\r
33                         CHECK_TRUE( Rectangle(hdc, 1, 1, width - 1, height - 1) );\r
34                         CHECK_TRUE( Rectangle(hdc, 2, 2, width - 2, height - 2) );\r
35                         SelectObject(hdc, hpen);\r
36                         SelectObject(hdc, hbr);\r
37                         // no need to DeleteObject StockObject\r
38                         SetROP2(hdc, rop2);\r
39                 }\r
40                 CHECK_TRUE( ReleaseDC(i_hwnd, hdc) );\r
41         }\r
42 \r
43         ///\r
44         Target(HWND i_hwnd)\r
45                         : m_hwnd(i_hwnd),\r
46                         m_preHwnd(NULL),\r
47                         m_hCursor(NULL) {\r
48         }\r
49 \r
50         /// WM_CREATE\r
51         int wmCreate(CREATESTRUCT * /* i_cs */) {\r
52                 CHECK_TRUE( m_hCursor =\r
53                                                 LoadCursor(g_hInst, MAKEINTRESOURCE(IDC_CURSOR_target)) );\r
54                 return 0;\r
55         }\r
56 \r
57         /// WM_PAINT\r
58         int wmPaint() {\r
59                 PAINTSTRUCT ps;\r
60                 HDC hdc = BeginPaint(m_hwnd, &ps);\r
61                 ASSERT(hdc);\r
62 \r
63                 if (GetCapture() != m_hwnd) {\r
64                         RECT rc;\r
65                         CHECK_TRUE( GetClientRect(m_hwnd, &rc) );\r
66                         CHECK_TRUE(\r
67                                 DrawIcon(hdc, (rcWidth(&rc) - GetSystemMetrics(SM_CXICON)) / 2,\r
68                                                  (rcHeight(&rc) - GetSystemMetrics(SM_CYICON)) / 2,\r
69                                                  m_hCursor) );\r
70                 }\r
71 \r
72                 EndPaint(m_hwnd, &ps);\r
73                 return 0;\r
74         }\r
75 \r
76         ///\r
77         struct PointWindow {\r
78                 POINT m_p;                                      ///\r
79                 HWND m_hwnd;                            ///\r
80                 RECT m_rc;                                      ///\r
81         };\r
82 \r
83         ///\r
84         static BOOL CALLBACK childWindowFromPoint(HWND i_hwnd, LPARAM i_lParam) {\r
85                 if (IsWindowVisible(i_hwnd)) {\r
86                         PointWindow &pw = *(PointWindow *)i_lParam;\r
87                         RECT rc;\r
88                         CHECK_TRUE( GetWindowRect(i_hwnd, &rc) );\r
89                         if (PtInRect(&rc, pw.m_p))\r
90                                 if (isRectInRect(&rc, &pw.m_rc)) {\r
91                                         pw.m_hwnd = i_hwnd;\r
92                                         pw.m_rc = rc;\r
93                                 }\r
94                 }\r
95                 return TRUE;\r
96         }\r
97 \r
98         ///\r
99         static BOOL CALLBACK windowFromPoint(HWND i_hwnd, LPARAM i_lParam) {\r
100                 if (IsWindowVisible(i_hwnd)) {\r
101                         PointWindow &pw = *(PointWindow *)i_lParam;\r
102                         RECT rc;\r
103                         CHECK_TRUE( GetWindowRect(i_hwnd, &rc) );\r
104                         if (PtInRect(&rc, pw.m_p)) {\r
105                                 pw.m_hwnd = i_hwnd;\r
106                                 pw.m_rc = rc;\r
107                                 return FALSE;\r
108                         }\r
109                 }\r
110                 return TRUE;\r
111         }\r
112 \r
113         /// WM_MOUSEMOVE\r
114         int wmMouseMove(WORD /* i_keys */, int /* i_x */, int /* i_y */) {\r
115                 if (GetCapture() == m_hwnd) {\r
116                         PointWindow pw;\r
117                         CHECK_TRUE( GetCursorPos(&pw.m_p) );\r
118                         pw.m_hwnd = 0;\r
119                         CHECK_TRUE( GetWindowRect(GetDesktopWindow(), &pw.m_rc) );\r
120                         EnumWindows(windowFromPoint, (LPARAM)&pw);\r
121                         while (1) {\r
122                                 HWND hwndParent = pw.m_hwnd;\r
123                                 if (!EnumChildWindows(pw.m_hwnd, childWindowFromPoint, (LPARAM)&pw))\r
124                                         break;\r
125                                 if (hwndParent == pw.m_hwnd)\r
126                                         break;\r
127                         }\r
128                         if (pw.m_hwnd != m_preHwnd) {\r
129                                 if (m_preHwnd)\r
130                                         invertFrame(m_preHwnd);\r
131                                 m_preHwnd = pw.m_hwnd;\r
132                                 invertFrame(m_preHwnd);\r
133                                 SendMessage(GetParent(m_hwnd), WM_APP_targetNotify, 0,\r
134                                                         (LPARAM)m_preHwnd);\r
135                         }\r
136                         SetCursor(m_hCursor);\r
137                 }\r
138                 return 0;\r
139         }\r
140 \r
141         /// WM_LBUTTONDOWN\r
142         int wmLButtonDown(WORD /* i_keys */, int /* i_x */, int /* i_y */) {\r
143                 SetCapture(m_hwnd);\r
144                 SetCursor(m_hCursor);\r
145                 CHECK_TRUE( InvalidateRect(m_hwnd, NULL, TRUE) );\r
146                 CHECK_TRUE( UpdateWindow(m_hwnd) );\r
147                 return 0;\r
148         }\r
149 \r
150         /// WM_LBUTTONUP\r
151         int wmLButtonUp(WORD /* i_keys */, int /* i_x */, int /* i_y */) {\r
152                 if (m_preHwnd)\r
153                         invertFrame(m_preHwnd);\r
154                 m_preHwnd = NULL;\r
155                 ReleaseCapture();\r
156                 CHECK_TRUE( InvalidateRect(m_hwnd, NULL, TRUE) );\r
157                 CHECK_TRUE( UpdateWindow(m_hwnd) );\r
158                 return 0;\r
159         }\r
160 \r
161 public:\r
162         ///\r
163         static LRESULT CALLBACK WndProc(HWND i_hwnd, UINT i_message,\r
164                                                                         WPARAM i_wParam, LPARAM i_lParam) {\r
165                 Target *wc;\r
166                 getUserData(i_hwnd, &wc);\r
167                 if (!wc)\r
168                         switch (i_message) {\r
169                         case WM_CREATE:\r
170                                 wc = setUserData(i_hwnd, new Target(i_hwnd));\r
171                                 return wc->wmCreate((CREATESTRUCT *)i_lParam);\r
172                         }\r
173                 else\r
174                         switch (i_message) {\r
175                         case WM_PAINT:\r
176                                 return wc->wmPaint();\r
177                         case WM_LBUTTONDOWN:\r
178                                 return wc->wmLButtonDown((WORD)i_wParam, (short)LOWORD(i_lParam),\r
179                                                                                  (short)HIWORD(i_lParam));\r
180                         case WM_LBUTTONUP:\r
181                                 return wc->wmLButtonUp((WORD)i_wParam, (short)LOWORD(i_lParam),\r
182                                                                            (short)HIWORD(i_lParam));\r
183                         case WM_MOUSEMOVE:\r
184                                 return wc->wmMouseMove((WORD)i_wParam, (short)LOWORD(i_lParam),\r
185                                                                            (short)HIWORD(i_lParam));\r
186                         case WM_NCDESTROY:\r
187                                 delete wc;\r
188                                 return 0;\r
189                         }\r
190                 return DefWindowProc(i_hwnd, i_message, i_wParam, i_lParam);\r
191         }\r
192 };\r
193 \r
194 \r
195 //\r
196 ATOM Register_target()\r
197 {\r
198         WNDCLASS wc;\r
199         wc.style         = CS_HREDRAW | CS_VREDRAW;\r
200         wc.lpfnWndProc   = Target::WndProc;\r
201         wc.cbClsExtra    = 0;\r
202         wc.cbWndExtra    = 0;\r
203         wc.hInstance     = g_hInst;\r
204         wc.hIcon         = NULL;\r
205         wc.hCursor       = LoadCursor(NULL, IDC_ARROW);\r
206         wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);\r
207         wc.lpszMenuName  = NULL;\r
208         wc.lpszClassName = _T("mayuTarget");\r
209         return RegisterClass(&wc);\r
210 }\r