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

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

* empty log message *

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