source: trunk/src/comctl32/hotkey.c@ 1010

Last change on this file since 1010 was 988, checked in by cbratschi, 26 years ago

* empty log message *

File size: 9.9 KB
Line 
1/* $Id: hotkey.c,v 1.7 1999-09-20 15:59:27 cbratschi Exp $ */
2/*
3 * Hotkey control
4 *
5 * Copyright 1998, 1999 Eric Kohl
6 * Copyright 1999 Achim Hasenmueller
7 * Copyright 1999 Christoph Bratschi
8 *
9 * NOTES
10 * Development in progress.
11 *
12 * TODO:
13 * - keyboard messages
14 */
15
16#include "winbase.h"
17#include "commctrl.h"
18#include "hotkey.h"
19#include <string.h>
20
21#define HOTKEY_GetInfoPtr(hwnd) ((HOTKEY_INFO*)GetWindowLongA(hwnd,0))
22
23static VOID
24HOTKEY_Refresh(HWND hwnd)
25{
26 InvalidateRect(hwnd,NULL,FALSE);
27}
28
29
30static BYTE
31HOTKEY_Check(HOTKEY_INFO *infoPtr,BYTE bfMods)
32{
33 if ((infoPtr->fwCombInv & HKCOMB_A && bfMods == HOTKEYF_ALT) ||
34 (infoPtr->fwCombInv & HKCOMB_C && bfMods == HOTKEYF_CONTROL) ||
35 (infoPtr->fwCombInv & HKCOMB_CA && bfMods == HOTKEYF_CONTROL | HOTKEYF_ALT) ||
36 (infoPtr->fwCombInv & HKCOMB_NONE && bfMods == 0) ||
37 (infoPtr->fwCombInv & HKCOMB_S && bfMods == HOTKEYF_SHIFT) ||
38 (infoPtr->fwCombInv & HKCOMB_SA && bfMods == HOTKEYF_SHIFT | HOTKEYF_ALT) ||
39 (infoPtr->fwCombInv & HKCOMB_SC && bfMods == HOTKEYF_SHIFT | HOTKEYF_CONTROL) ||
40 (infoPtr->fwCombInv & HKCOMB_SCA && bfMods == HOTKEYF_SHIFT | HOTKEYF_CONTROL | HOTKEYF_ALT))
41 return infoPtr->fwModInv;
42 else
43 return bfMods;
44}
45
46
47static LRESULT
48HOTKEY_SetHotKey(HWND hwnd,WPARAM wParam,LPARAM lParam)
49{
50 HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr(hwnd);
51
52 infoPtr->bVKHotKey = wParam & 0xFF;
53 infoPtr->bfMods = HOTKEY_Check(infoPtr,(wParam & 0xFF00)>>8);
54
55 HOTKEY_Refresh(hwnd);
56
57 return 0;
58}
59
60
61static LRESULT
62HOTKEY_GetHotKey(HWND hwnd,WPARAM wParam,LPARAM lParam)
63{
64 HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr(hwnd);
65
66 return MAKEWORD(infoPtr->bVKHotKey,infoPtr->bfMods);
67}
68
69
70static LRESULT
71HOTKEY_SetRules(HWND hwnd,WPARAM wParam,LPARAM lParam)
72{
73 HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr(hwnd);
74 BYTE oldMods = infoPtr->bfMods;
75
76 infoPtr->fwCombInv = wParam;
77 infoPtr->fwModInv = lParam;
78
79 infoPtr->bfMods = HOTKEY_Check(infoPtr,infoPtr->bfMods);
80 if (infoPtr->bfMods != oldMods) HOTKEY_Refresh(hwnd);
81
82 return 0;
83}
84
85
86static LRESULT
87HOTKEY_Char(HWND hwnd,WPARAM wParam,LPARAM lParam,BOOL sysKey)
88{
89 //CB:
90 return 0;
91}
92
93static LRESULT
94HOTKEY_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
95{
96 HOTKEY_INFO *infoPtr;
97 TEXTMETRICA tm;
98 HDC hdc;
99
100 /* allocate memory for info structure */
101 infoPtr = (HOTKEY_INFO *)COMCTL32_Alloc (sizeof(HOTKEY_INFO));
102 SetWindowLongA(hwnd,0,(DWORD)infoPtr);
103
104 /* initialize info structure */
105
106 infoPtr->hFont = 0;
107 infoPtr->bFocus = FALSE;
108 infoPtr->bVKHotKey = 0;
109 infoPtr->bfMods = 0;
110 infoPtr->fwCombInv = 0;
111 infoPtr->fwModInv = 0;
112 infoPtr->cursorPos.x = 3;
113 infoPtr->cursorPos.y = 3;
114
115 /* get default font height */
116 hdc = GetDC (hwnd);
117 GetTextMetricsA (hdc, &tm);
118 infoPtr->nHeight = tm.tmHeight;
119 ReleaseDC (hwnd, hdc);
120
121 return 0;
122}
123
124
125static LRESULT
126HOTKEY_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
127{
128 HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr (hwnd);
129
130 /* free hotkey info data */
131 COMCTL32_Free (infoPtr);
132
133 return 0;
134}
135
136
137static LRESULT
138HOTKEY_EraseBackground (HWND hwnd, WPARAM wParam, LPARAM lParam)
139{
140 HBRUSH hBrush;
141 RECT rc;
142
143 hBrush = (HBRUSH)SendMessageA(GetParent(hwnd),WM_CTLCOLOREDIT,wParam,(LPARAM)hwnd);
144 if (!hBrush) hBrush = (HBRUSH)GetStockObject(WHITE_BRUSH);
145 GetClientRect(hwnd,&rc);
146 FillRect((HDC)wParam,&rc,hBrush);
147
148 return -1;
149}
150
151
152static LRESULT
153HOTKEY_GetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
154{
155 HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr (hwnd);
156
157 return infoPtr->hFont;
158}
159
160
161static LRESULT
162HOTKEY_KeyDown (HWND hwnd, WPARAM wParam, LPARAM lParam,BOOL sysKey)
163{
164 HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr (hwnd);
165 INT newMods = sysKey ? HOTKEYF_ALT:0;
166
167 switch (wParam)
168 {
169 case VK_RETURN:
170 case VK_TAB:
171 case VK_SPACE:
172 case VK_DELETE:
173 case VK_ESCAPE:
174 case VK_BACK:
175 return DefWindowProcA (hwnd,sysKey ? WM_SYSKEYDOWN:WM_KEYDOWN, wParam, lParam);
176
177 case VK_SHIFT:
178 newMods |= HOTKEYF_SHIFT;
179 break;
180
181 case VK_CONTROL:
182 newMods |= HOTKEYF_CONTROL;
183 break;
184
185 default:
186 break;
187 }
188
189 infoPtr->bfMods = newMods;
190 HOTKEY_Refresh(hwnd);
191
192 return TRUE;
193}
194
195
196static LRESULT
197HOTKEY_KeyUp (HWND hwnd, WPARAM wParam, LPARAM lParam,BOOL sysKey)
198{
199 HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr (hwnd);
200
201// FIXME (hotkey, " %d\n", wParam);
202
203 return 0;
204}
205
206
207static LRESULT
208HOTKEY_KillFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
209{
210 HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr (hwnd);
211
212 infoPtr->bFocus = FALSE;
213 DestroyCaret ();
214
215 return 0;
216}
217
218
219static LRESULT
220HOTKEY_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
221{
222/* HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr (hwnd); */
223
224 SetFocus (hwnd);
225
226 return 0;
227}
228
229
230static LRESULT
231HOTKEY_NCCreate (HWND hwnd, WPARAM wParam, LPARAM lParam)
232{
233 DWORD dwExStyle = GetWindowLongA (hwnd, GWL_EXSTYLE);
234 SetWindowLongA (hwnd, GWL_EXSTYLE, dwExStyle | WS_EX_CLIENTEDGE);
235 return DefWindowProcA (hwnd, WM_NCCREATE, wParam, lParam);
236}
237
238
239static VOID
240HOTKEY_Draw(HWND hwnd,HDC hdc)
241{
242 HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr(hwnd);
243 RECT rect,newRect;
244 char text[50];
245 HFONT oldFont;
246
247 HideCaret(hwnd);
248 GetClientRect(hwnd,&rect);
249 DrawEdge(hdc,&rect,EDGE_SUNKEN,BF_RECT | BF_ADJUST);
250
251 //draw string
252 text[0] = 0;
253 if (infoPtr->bfMods & HOTKEYF_ALT) strcat(text,"ALT");
254 if (infoPtr->bfMods & HOTKEYF_CONTROL)
255 {
256 if (text[0]) strcat(text,"+");
257 strcat(text,"CONTROL");
258 }
259 if (infoPtr->bfMods & HOTKEYF_SHIFT)
260 {
261 if (text[0]) strcat(text,"+");
262 strcat(text,"SHIFT");
263 }
264
265 if (infoPtr->bVKHotKey)
266 {
267 char char2[2];
268
269 if (text[0]) strcat(text,"+");
270 char2[0] = (char)infoPtr->bVKHotKey;
271 char2[1] = 0;
272 strcat(text,char2);
273 }
274 if(infoPtr->hFont) oldFont = SelectObject(hdc,infoPtr->hFont);
275 SetBkMode(hdc,TRANSPARENT);
276 CopyRect(&newRect,&rect);
277 DrawTextA(hdc,text,strlen(text),&newRect,DT_LEFT | DT_BOTTOM | DT_SINGLELINE);
278 DrawTextA(hdc,text,strlen(text),&newRect,DT_LEFT | DT_BOTTOM | DT_SINGLELINE | DT_CALCRECT);
279 if (infoPtr->hFont) SelectObject(hdc,oldFont);
280 infoPtr->cursorPos.x = (newRect.right >= rect.right)? 3:newRect.right;
281 SetCaretPos(infoPtr->cursorPos.x,infoPtr->cursorPos.y);
282 ShowCaret(hwnd);
283}
284
285
286static LRESULT
287HOTKEY_Paint(HWND hwnd,WPARAM wParam,LPARAM lParam)
288{
289 PAINTSTRUCT ps;
290 HDC hdc;
291
292 if (wParam == 0) hdc = BeginPaint(hwnd,&ps);
293 else hdc = wParam;
294
295 HOTKEY_Draw(hwnd,hdc);
296
297 if (wParam == 0) EndPaint(hwnd,&ps);
298
299 return 0;
300}
301
302
303static LRESULT
304HOTKEY_SetFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
305{
306 HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr (hwnd);
307
308 infoPtr->bFocus = TRUE;
309
310 CreateCaret(hwnd,(HBITMAP)0,1,infoPtr->nHeight);
311 SetCaretPos(infoPtr->cursorPos.x,infoPtr->cursorPos.y);
312 ShowCaret(hwnd);
313
314 return 0;
315}
316
317
318static LRESULT
319HOTKEY_SetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
320{
321 HOTKEY_INFO *infoPtr = HOTKEY_GetInfoPtr (hwnd);
322 TEXTMETRICA tm;
323 HDC hdc;
324 HFONT hOldFont = 0;
325
326 infoPtr->hFont = (HFONT)wParam;
327
328 hdc = GetDC (hwnd);
329 if (infoPtr->hFont)
330 hOldFont = SelectObject (hdc, infoPtr->hFont);
331
332 GetTextMetricsA (hdc, &tm);
333 infoPtr->nHeight = tm.tmHeight;
334
335 if (infoPtr->hFont)
336 SelectObject (hdc, hOldFont);
337 ReleaseDC (hwnd, hdc);
338
339 if (LOWORD(lParam)) HOTKEY_Refresh(hwnd);
340
341 return 0;
342}
343
344
345static LRESULT WINAPI
346HOTKEY_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
347{
348 switch (uMsg)
349 {
350 case HKM_GETHOTKEY:
351 return HOTKEY_GetHotKey(hwnd,wParam,lParam);
352
353 case HKM_SETHOTKEY:
354 return HOTKEY_SetHotKey(hwnd,wParam,lParam);
355
356 case HKM_SETRULES:
357 return HOTKEY_SetRules(hwnd,wParam,lParam);
358
359 case WM_CHAR:
360 return HOTKEY_Char(hwnd,wParam,lParam,FALSE);
361
362 case WM_SYSCHAR:
363 return HOTKEY_Char(hwnd,wParam,lParam,TRUE);
364
365 case WM_CREATE:
366 return HOTKEY_Create (hwnd, wParam, lParam);
367
368 case WM_DESTROY:
369 return HOTKEY_Destroy (hwnd, wParam, lParam);
370
371 case WM_ERASEBKGND:
372 return HOTKEY_EraseBackground (hwnd, wParam, lParam);
373
374 case WM_GETDLGCODE:
375 return DLGC_WANTCHARS | DLGC_WANTARROWS;
376
377 case WM_GETFONT:
378 return HOTKEY_GetFont (hwnd, wParam, lParam);
379
380 case WM_KEYDOWN:
381 return HOTKEY_KeyDown(hwnd,wParam,lParam,FALSE);
382
383 case WM_SYSKEYDOWN:
384 return HOTKEY_KeyDown(hwnd,wParam,lParam,TRUE);
385
386 case WM_KEYUP:
387 return HOTKEY_KeyUp(hwnd,wParam,lParam,FALSE);
388
389 case WM_SYSKEYUP:
390 return HOTKEY_KeyUp(hwnd,wParam,lParam,TRUE);
391
392 case WM_KILLFOCUS:
393 return HOTKEY_KillFocus (hwnd, wParam, lParam);
394
395 case WM_LBUTTONDOWN:
396 return HOTKEY_LButtonDown (hwnd, wParam, lParam);
397
398 case WM_NCCREATE:
399 return HOTKEY_NCCreate (hwnd, wParam, lParam);
400
401 case WM_PAINT:
402 return HOTKEY_Paint(hwnd,wParam,lParam);
403
404 case WM_SETFOCUS:
405 return HOTKEY_SetFocus (hwnd, wParam, lParam);
406
407 case WM_SETFONT:
408 return HOTKEY_SetFont (hwnd, wParam, lParam);
409
410 default:
411// if (uMsg >= WM_USER)
412// ERR (hotkey, "unknown msg %04x wp=%08x lp=%08lx\n",
413// uMsg, wParam, lParam);
414 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
415 }
416 return 0;
417}
418
419
420VOID
421HOTKEY_Register (VOID)
422{
423 WNDCLASSA wndClass;
424
425 if (GlobalFindAtomA (HOTKEY_CLASSA)) return;
426
427 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
428 wndClass.style = CS_GLOBALCLASS;
429 wndClass.lpfnWndProc = (WNDPROC)HOTKEY_WindowProc;
430 wndClass.cbClsExtra = 0;
431 wndClass.cbWndExtra = sizeof(HOTKEY_INFO *);
432 wndClass.hCursor = 0;
433 wndClass.hbrBackground = 0;
434 wndClass.lpszClassName = HOTKEY_CLASSA;
435
436 RegisterClassA (&wndClass);
437}
438
439
440VOID
441HOTKEY_Unregister (VOID)
442{
443 if (GlobalFindAtomA (HOTKEY_CLASSA))
444 UnregisterClassA (HOTKEY_CLASSA, (HINSTANCE)NULL);
445}
446
Note: See TracBrowser for help on using the repository browser.