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

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

* empty log message *

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