When unsubclassing tools, use toolPtr->hwnd instead of toolPtr->uId if
[wine] / dlls / comctl32 / hotkey.c
1 /*
2  * Hotkey control
3  *
4  * Copyright 1998, 1999 Eric Kohl
5  *
6  * NOTES
7  *   Development in progress. An author is needed! Any volunteers?
8  *   I will only improve this control once in a while.
9  *     Eric <ekohl@abo.rhein-zeitung.de>
10  *
11  * TODO:
12  *   - Some messages.
13  *   - Display code.
14  */
15
16 #include "winbase.h"
17 #include "commctrl.h"
18 #include "hotkey.h"
19 #include "debugtools.h"
20
21 DEFAULT_DEBUG_CHANNEL(hotkey)
22
23
24 #define HOTKEY_GetInfoPtr(hwnd) ((HOTKEY_INFO *)GetWindowLongA (hwnd, 0))
25
26
27 /* << HOTHEY_GetHotKey >> */
28 /* << HOTHEY_SetHotKey >> */
29 /* << HOTHEY_SetRules >> */
30
31
32
33 /* << HOTKEY_Char >> */
34
35
36 static LRESULT
37 HOTKEY_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
38 {
39     HOTKEY_INFO *infoPtr;
40     TEXTMETRICA tm;
41     HDC hdc;
42
43     /* allocate memory for info structure */
44     infoPtr = (HOTKEY_INFO *)COMCTL32_Alloc (sizeof(HOTKEY_INFO));
45     SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
46
47     /* initialize info structure */
48
49
50     /* get default font height */
51     hdc = GetDC (hwnd);
52     GetTextMetricsA (hdc, &tm);
53     infoPtr->nHeight = tm.tmHeight;
54     ReleaseDC (hwnd, hdc);
55
56     return 0;
57 }
58
59
60 static LRESULT
61 HOTKEY_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
62 {
63     HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr (hwnd);
64
65
66
67     /* free hotkey info data */
68     COMCTL32_Free (infoPtr);
69     SetWindowLongA (hwnd, 0, 0);
70     return 0;
71 }
72
73
74 static LRESULT
75 HOTKEY_EraseBackground (HWND hwnd, WPARAM wParam, LPARAM lParam)
76 {
77     /* HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr (hwnd); */
78     HBRUSH hBrush;
79     RECT   rc;
80
81     hBrush =
82         (HBRUSH)SendMessageA (GetParent (hwnd), WM_CTLCOLOREDIT,
83                                 wParam, (LPARAM)hwnd);
84     if (hBrush)
85         hBrush = (HBRUSH)GetStockObject (WHITE_BRUSH);
86     GetClientRect (hwnd, &rc);
87
88     FillRect ((HDC)wParam, &rc, hBrush);
89
90     return -1;
91 }
92
93
94 inline static LRESULT
95 HOTKEY_GetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
96 {
97     HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr (hwnd);
98
99     return infoPtr->hFont;
100 }
101
102
103 static LRESULT
104 HOTKEY_KeyDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
105 {
106     /* HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr (hwnd); */
107
108     switch (wParam) {
109         case VK_RETURN:
110         case VK_TAB:
111         case VK_SPACE:
112         case VK_DELETE:
113         case VK_ESCAPE:
114         case VK_BACK:
115             return DefWindowProcA (hwnd, WM_KEYDOWN, wParam, lParam);
116
117         case VK_SHIFT:
118         case VK_CONTROL:
119         case VK_MENU:
120             FIXME("modifier key pressed!\n");
121             break;
122
123         default:
124             FIXME(" %d\n", wParam);
125             break;
126     }
127
128     return TRUE;
129 }
130
131
132 static LRESULT
133 HOTKEY_KeyUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
134 {
135     /* HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr (hwnd); */
136
137     FIXME(" %d\n", wParam);
138
139     return 0;
140 }
141
142
143 static LRESULT
144 HOTKEY_KillFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
145 {
146     HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr (hwnd);
147
148     infoPtr->bFocus = FALSE;
149     DestroyCaret ();
150
151     return 0;
152 }
153
154
155 static LRESULT
156 HOTKEY_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
157 {
158 /*    HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr (hwnd); */
159
160     SetFocus (hwnd);
161
162     return 0;
163 }
164
165
166 inline static LRESULT
167 HOTKEY_NCCreate (HWND hwnd, WPARAM wParam, LPARAM lParam)
168 {
169     DWORD dwExStyle = GetWindowLongA (hwnd, GWL_EXSTYLE);
170     SetWindowLongA (hwnd, GWL_EXSTYLE, dwExStyle | WS_EX_CLIENTEDGE);
171     return DefWindowProcA (hwnd, WM_NCCREATE, wParam, lParam);
172 }
173
174
175
176
177
178 static LRESULT
179 HOTKEY_SetFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
180 {
181     HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr (hwnd);
182
183     infoPtr->bFocus = TRUE;
184
185
186     CreateCaret (hwnd, (HBITMAP)0, 1, infoPtr->nHeight);
187
188     SetCaretPos (1, 1);
189
190     ShowCaret (hwnd);
191
192
193     return 0;
194 }
195
196
197 inline static LRESULT
198 HOTKEY_SetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
199 {
200     HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr (hwnd);
201     TEXTMETRICA tm;
202     HDC hdc;
203     HFONT hOldFont = 0;
204
205     infoPtr->hFont = (HFONT)wParam;
206
207     hdc = GetDC (hwnd);
208     if (infoPtr->hFont)
209         hOldFont = SelectObject (hdc, infoPtr->hFont);
210
211     GetTextMetricsA (hdc, &tm);
212     infoPtr->nHeight = tm.tmHeight;
213
214     if (infoPtr->hFont)
215         SelectObject (hdc, hOldFont);
216     ReleaseDC (hwnd, hdc);
217
218     if (LOWORD(lParam)) {
219
220         FIXME("force redraw!\n");
221
222     }
223
224     return 0;
225 }
226
227
228 static LRESULT WINE_UNUSED
229 HOTKEY_SysKeyDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
230 {
231     /* HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr (hwnd); */
232
233     switch (wParam) {
234         case VK_RETURN:
235         case VK_TAB:
236         case VK_SPACE:
237         case VK_DELETE:
238         case VK_ESCAPE:
239         case VK_BACK:
240             return DefWindowProcA (hwnd, WM_SYSKEYDOWN, wParam, lParam);
241
242         case VK_SHIFT:
243         case VK_CONTROL:
244         case VK_MENU:
245             FIXME("modifier key pressed!\n");
246             break;
247
248         default:
249             FIXME(" %d\n", wParam);
250             break;
251     }
252
253     return TRUE;
254 }
255
256
257 static LRESULT WINE_UNUSED
258 HOTKEY_SysKeyUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
259 {
260     /* HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr (hwnd); */
261
262     FIXME(" %d\n", wParam);
263
264     return 0;
265 }
266
267
268
269 static LRESULT WINAPI
270 HOTKEY_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
271 {
272     TRACE("hwnd=%x msg=%x wparam=%x lparam=%lx\n", hwnd, uMsg, wParam, lParam);
273     if (!HOTKEY_GetInfoPtr (hwnd) && (uMsg != WM_CREATE))
274         return DefWindowProcA (hwnd, uMsg, wParam, lParam);
275     switch (uMsg)
276     {
277 /*      case HKM_GETHOTKEY: */
278 /*      case HKM_SETHOTKEY: */
279 /*      case HKM_SETRULES: */
280
281 /*      case WM_CHAR: */
282
283         case WM_CREATE:
284             return HOTKEY_Create (hwnd, wParam, lParam);
285
286         case WM_DESTROY:
287             return HOTKEY_Destroy (hwnd, wParam, lParam);
288
289         case WM_ERASEBKGND:
290             return HOTKEY_EraseBackground (hwnd, wParam, lParam);
291
292         case WM_GETDLGCODE:
293             return DLGC_WANTCHARS | DLGC_WANTARROWS;
294
295         case WM_GETFONT:
296             return HOTKEY_GetFont (hwnd, wParam, lParam);
297
298         case WM_KEYDOWN:
299         case WM_SYSKEYDOWN:
300             return HOTKEY_KeyDown (hwnd, wParam, lParam);
301
302         case WM_KEYUP:
303         case WM_SYSKEYUP:
304             return HOTKEY_KeyUp (hwnd, wParam, lParam);
305
306         case WM_KILLFOCUS:
307             return HOTKEY_KillFocus (hwnd, wParam, lParam);
308
309         case WM_LBUTTONDOWN:
310             return HOTKEY_LButtonDown (hwnd, wParam, lParam);
311
312         case WM_NCCREATE:
313             return HOTKEY_NCCreate (hwnd, wParam, lParam);
314
315 /*      case WM_PAINT: */
316
317         case WM_SETFOCUS:
318             return HOTKEY_SetFocus (hwnd, wParam, lParam);
319
320         case WM_SETFONT:
321             return HOTKEY_SetFont (hwnd, wParam, lParam);
322
323 /*      case WM_SYSCHAR: */
324
325         default:
326             if (uMsg >= WM_USER)
327                 ERR("unknown msg %04x wp=%08x lp=%08lx\n",
328                      uMsg, wParam, lParam);
329             return DefWindowProcA (hwnd, uMsg, wParam, lParam);
330     }
331     return 0;
332 }
333
334
335 VOID
336 HOTKEY_Register (void)
337 {
338     WNDCLASSA wndClass;
339
340     ZeroMemory (&wndClass, sizeof(WNDCLASSA));
341     wndClass.style         = CS_GLOBALCLASS;
342     wndClass.lpfnWndProc   = (WNDPROC)HOTKEY_WindowProc;
343     wndClass.cbClsExtra    = 0;
344     wndClass.cbWndExtra    = sizeof(HOTKEY_INFO *);
345     wndClass.hCursor       = 0;
346     wndClass.hbrBackground = 0;
347     wndClass.lpszClassName = HOTKEY_CLASSA;
348  
349     RegisterClassA (&wndClass);
350 }
351
352
353 VOID
354 HOTKEY_Unregister (void)
355 {
356     UnregisterClassA (HOTKEY_CLASSA, (HINSTANCE)NULL);
357 }
358