OSDN Git Service

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