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

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

* empty log message *

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