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

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

* empty log message *

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