Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/dlls/comctl32/hotkey.c
4394 views
1
/*
2
* Hotkey control
3
*
4
* Copyright 1998, 1999 Eric Kohl
5
* Copyright 2002 Gyorgy 'Nog' Jeney
6
* Copyright 2004 Robert Shearman
7
*
8
* This library is free software; you can redistribute it and/or
9
* modify it under the terms of the GNU Lesser General Public
10
* License as published by the Free Software Foundation; either
11
* version 2.1 of the License, or (at your option) any later version.
12
*
13
* This library is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
* Lesser General Public License for more details.
17
*
18
* You should have received a copy of the GNU Lesser General Public
19
* License along with this library; if not, write to the Free Software
20
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21
*
22
* This code was audited for completeness against the documented features
23
* of Comctl32.dll version 6.0 on Sep. 21, 2004, by Robert Shearman.
24
*
25
* Unless otherwise noted, we believe this code to be complete, as per
26
* the specification mentioned above.
27
* If you discover missing features or bugs please note them below.
28
*
29
*/
30
31
#include <stdarg.h>
32
#include <stdlib.h>
33
#include <string.h>
34
#include "windef.h"
35
#include "winbase.h"
36
#include "wingdi.h"
37
#include "winuser.h"
38
#include "winnls.h"
39
#include "commctrl.h"
40
#include "comctl32.h"
41
#include "uxtheme.h"
42
#include "wine/debug.h"
43
44
WINE_DEFAULT_DEBUG_CHANNEL(hotkey);
45
46
typedef struct tagHOTKEY_INFO
47
{
48
HWND hwndSelf;
49
HWND hwndNotify;
50
HFONT hFont;
51
BOOL bFocus;
52
INT nHeight;
53
WORD HotKey;
54
WORD InvComb;
55
WORD InvMod;
56
BYTE CurrMod;
57
INT CaretPos;
58
DWORD ScanCode;
59
WCHAR strNone[15]; /* hope it's long enough ... */
60
} HOTKEY_INFO;
61
62
static const WCHAR HOTKEY_plussep[] = { ' ', '+', ' ' };
63
static LRESULT HOTKEY_SetFont (HOTKEY_INFO *infoPtr, HFONT hFont, BOOL redraw);
64
65
#define IsOnlySet(flags) (infoPtr->CurrMod == (flags))
66
67
static BOOL
68
HOTKEY_IsCombInv(const HOTKEY_INFO *infoPtr)
69
{
70
TRACE("(infoPtr=%p)\n", infoPtr);
71
if((infoPtr->InvComb & HKCOMB_NONE) && !infoPtr->CurrMod)
72
return TRUE;
73
if((infoPtr->InvComb & HKCOMB_S) && IsOnlySet(HOTKEYF_SHIFT))
74
return TRUE;
75
if((infoPtr->InvComb & HKCOMB_C) && IsOnlySet(HOTKEYF_CONTROL))
76
return TRUE;
77
if((infoPtr->InvComb & HKCOMB_A) && IsOnlySet(HOTKEYF_ALT))
78
return TRUE;
79
if((infoPtr->InvComb & HKCOMB_SC) &&
80
IsOnlySet(HOTKEYF_SHIFT | HOTKEYF_CONTROL))
81
return TRUE;
82
if((infoPtr->InvComb & HKCOMB_SA) && IsOnlySet(HOTKEYF_SHIFT | HOTKEYF_ALT))
83
return TRUE;
84
if((infoPtr->InvComb & HKCOMB_CA) &&
85
IsOnlySet(HOTKEYF_CONTROL | HOTKEYF_ALT))
86
return TRUE;
87
if((infoPtr->InvComb & HKCOMB_SCA) &&
88
IsOnlySet(HOTKEYF_SHIFT | HOTKEYF_CONTROL | HOTKEYF_ALT))
89
return TRUE;
90
91
TRACE("() Modifiers are valid\n");
92
return FALSE;
93
}
94
#undef IsOnlySet
95
96
static void
97
HOTKEY_DrawHotKey(HOTKEY_INFO *infoPtr, HDC hdc, LPCWSTR KeyName, WORD NameLen)
98
{
99
SIZE TextSize;
100
INT nXStart, nYStart;
101
COLORREF clrOldText, clrOldBk;
102
HFONT hFontOld;
103
104
/* Make a gap from the frame */
105
nXStart = GetSystemMetrics(SM_CXBORDER);
106
nYStart = GetSystemMetrics(SM_CYBORDER);
107
108
hFontOld = SelectObject(hdc, infoPtr->hFont);
109
if (GetWindowLongW(infoPtr->hwndSelf, GWL_STYLE) & WS_DISABLED)
110
{
111
clrOldText = SetTextColor(hdc, comctl32_color.clrGrayText);
112
clrOldBk = SetBkColor(hdc, comctl32_color.clrBtnFace);
113
}
114
else
115
{
116
clrOldText = SetTextColor(hdc, comctl32_color.clrWindowText);
117
clrOldBk = SetBkColor(hdc, comctl32_color.clrWindow);
118
}
119
120
TextOutW(hdc, nXStart, nYStart, KeyName, NameLen);
121
122
/* Get the text width for the caret */
123
GetTextExtentPoint32W(hdc, KeyName, NameLen, &TextSize);
124
infoPtr->CaretPos = nXStart + TextSize.cx;
125
126
SetBkColor(hdc, clrOldBk);
127
SetTextColor(hdc, clrOldText);
128
SelectObject(hdc, hFontOld);
129
130
/* position the caret */
131
SetCaretPos(infoPtr->CaretPos, nYStart);
132
}
133
134
/* Draw the names of the keys in the control */
135
static void
136
HOTKEY_Refresh(HOTKEY_INFO *infoPtr, HDC hdc)
137
{
138
WCHAR KeyName[64];
139
WORD NameLen = 0;
140
BYTE Modifier;
141
142
TRACE("(infoPtr=%p hdc=%p)\n", infoPtr, hdc);
143
144
if(!infoPtr->CurrMod && !infoPtr->HotKey) {
145
HOTKEY_DrawHotKey (infoPtr, hdc, infoPtr->strNone, lstrlenW(infoPtr->strNone));
146
return;
147
}
148
149
if(infoPtr->HotKey)
150
Modifier = HIBYTE(infoPtr->HotKey);
151
else if(HOTKEY_IsCombInv(infoPtr))
152
Modifier = infoPtr->InvMod;
153
else
154
Modifier = infoPtr->CurrMod;
155
156
if(Modifier & HOTKEYF_CONTROL) {
157
GetKeyNameTextW(MAKELPARAM(0, MapVirtualKeyW(VK_CONTROL, 0)),
158
KeyName, 64);
159
NameLen = lstrlenW(KeyName);
160
memcpy(&KeyName[NameLen], HOTKEY_plussep, sizeof(HOTKEY_plussep));
161
NameLen += 3;
162
}
163
if(Modifier & HOTKEYF_SHIFT) {
164
GetKeyNameTextW(MAKELPARAM(0, MapVirtualKeyW(VK_SHIFT, 0)),
165
&KeyName[NameLen], 64 - NameLen);
166
NameLen = lstrlenW(KeyName);
167
memcpy(&KeyName[NameLen], HOTKEY_plussep, sizeof(HOTKEY_plussep));
168
NameLen += 3;
169
}
170
if(Modifier & HOTKEYF_ALT) {
171
GetKeyNameTextW(MAKELPARAM(0, MapVirtualKeyW(VK_MENU, 0)),
172
&KeyName[NameLen], 64 - NameLen);
173
NameLen = lstrlenW(KeyName);
174
memcpy(&KeyName[NameLen], HOTKEY_plussep, sizeof(HOTKEY_plussep));
175
NameLen += 3;
176
}
177
178
if(infoPtr->HotKey) {
179
GetKeyNameTextW(infoPtr->ScanCode, &KeyName[NameLen], 64 - NameLen);
180
NameLen = lstrlenW(KeyName);
181
}
182
else
183
KeyName[NameLen] = 0;
184
185
HOTKEY_DrawHotKey (infoPtr, hdc, KeyName, NameLen);
186
}
187
188
static void
189
HOTKEY_Paint(HOTKEY_INFO *infoPtr, HDC hdc)
190
{
191
if (hdc)
192
HOTKEY_Refresh(infoPtr, hdc);
193
else {
194
PAINTSTRUCT ps;
195
hdc = BeginPaint (infoPtr->hwndSelf, &ps);
196
HOTKEY_Refresh (infoPtr, hdc);
197
EndPaint (infoPtr->hwndSelf, &ps);
198
}
199
}
200
201
static LRESULT
202
HOTKEY_GetHotKey(const HOTKEY_INFO *infoPtr)
203
{
204
TRACE("(infoPtr=%p) Modifiers: 0x%x, Virtual Key: %d\n", infoPtr,
205
HIBYTE(infoPtr->HotKey), LOBYTE(infoPtr->HotKey));
206
return (LRESULT)infoPtr->HotKey;
207
}
208
209
static void
210
HOTKEY_SetHotKey(HOTKEY_INFO *infoPtr, WORD hotKey)
211
{
212
infoPtr->HotKey = hotKey;
213
infoPtr->ScanCode =
214
MAKELPARAM(0, MapVirtualKeyW(LOBYTE(infoPtr->HotKey), 0));
215
TRACE("(infoPtr=%p hotKey=%x) Modifiers: 0x%x, Virtual Key: %d\n", infoPtr,
216
hotKey, HIBYTE(infoPtr->HotKey), LOBYTE(infoPtr->HotKey));
217
InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
218
}
219
220
static void
221
HOTKEY_SetRules(HOTKEY_INFO *infoPtr, WORD invComb, WORD invMod)
222
{
223
infoPtr->InvComb = invComb;
224
infoPtr->InvMod = invMod;
225
TRACE("(infoPtr=%p) Invalid Modifiers: 0x%x, If Invalid: 0x%x\n", infoPtr,
226
infoPtr->InvComb, infoPtr->InvMod);
227
}
228
229
230
static LRESULT
231
HOTKEY_Create (HOTKEY_INFO *infoPtr, const CREATESTRUCTW *lpcs)
232
{
233
infoPtr->hwndNotify = lpcs->hwndParent;
234
235
HOTKEY_SetFont(infoPtr, GetStockObject(SYSTEM_FONT), 0);
236
237
return 0;
238
}
239
240
241
static LRESULT
242
HOTKEY_Destroy (HOTKEY_INFO *infoPtr)
243
{
244
/* Free hotkey info data */
245
SetWindowLongPtrW (infoPtr->hwndSelf, 0, 0);
246
Free (infoPtr);
247
return 0;
248
}
249
250
251
static LRESULT
252
HOTKEY_EraseBackground (const HOTKEY_INFO *infoPtr, HDC hdc)
253
{
254
HBRUSH hBrush, hSolidBrush = NULL;
255
RECT rc;
256
257
if (GetWindowLongW(infoPtr->hwndSelf, GWL_STYLE) & WS_DISABLED)
258
hBrush = hSolidBrush = CreateSolidBrush(comctl32_color.clrBtnFace);
259
else
260
{
261
hBrush = (HBRUSH)SendMessageW(infoPtr->hwndNotify, WM_CTLCOLOREDIT,
262
(WPARAM)hdc, (LPARAM)infoPtr->hwndSelf);
263
if (!hBrush)
264
hBrush = hSolidBrush = CreateSolidBrush(comctl32_color.clrWindow);
265
}
266
267
GetClientRect (infoPtr->hwndSelf, &rc);
268
269
FillRect (hdc, &rc, hBrush);
270
271
if (hSolidBrush)
272
DeleteObject(hSolidBrush);
273
274
return -1;
275
}
276
277
278
static inline LRESULT
279
HOTKEY_GetFont (const HOTKEY_INFO *infoPtr)
280
{
281
return (LRESULT)infoPtr->hFont;
282
}
283
284
static LRESULT
285
HOTKEY_KeyDown (HOTKEY_INFO *infoPtr, DWORD key, DWORD flags)
286
{
287
WORD wOldHotKey;
288
BYTE bOldMod;
289
290
if (GetWindowLongW(infoPtr->hwndSelf, GWL_STYLE) & WS_DISABLED)
291
return 0;
292
293
TRACE("() Key: %ld\n", key);
294
295
wOldHotKey = infoPtr->HotKey;
296
bOldMod = infoPtr->CurrMod;
297
298
/* If any key is Pressed, we have to reset the hotkey in the control */
299
infoPtr->HotKey = 0;
300
301
switch (key)
302
{
303
case VK_RETURN:
304
case VK_TAB:
305
case VK_SPACE:
306
case VK_DELETE:
307
case VK_ESCAPE:
308
case VK_BACK:
309
InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
310
return DefWindowProcW (infoPtr->hwndSelf, WM_KEYDOWN, key, flags);
311
312
case VK_SHIFT:
313
infoPtr->CurrMod |= HOTKEYF_SHIFT;
314
break;
315
case VK_CONTROL:
316
infoPtr->CurrMod |= HOTKEYF_CONTROL;
317
break;
318
case VK_MENU:
319
infoPtr->CurrMod |= HOTKEYF_ALT;
320
break;
321
322
default:
323
if(HOTKEY_IsCombInv(infoPtr))
324
infoPtr->HotKey = MAKEWORD(key, infoPtr->InvMod);
325
else
326
infoPtr->HotKey = MAKEWORD(key, infoPtr->CurrMod);
327
infoPtr->ScanCode = flags;
328
break;
329
}
330
331
if ((wOldHotKey != infoPtr->HotKey) || (bOldMod != infoPtr->CurrMod))
332
{
333
InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
334
335
/* send EN_CHANGE notification */
336
SendMessageW(infoPtr->hwndNotify, WM_COMMAND,
337
MAKEWPARAM(GetDlgCtrlID(infoPtr->hwndSelf), EN_CHANGE),
338
(LPARAM)infoPtr->hwndSelf);
339
}
340
341
return 0;
342
}
343
344
345
static LRESULT
346
HOTKEY_KeyUp (HOTKEY_INFO *infoPtr, DWORD key)
347
{
348
BYTE bOldMod;
349
350
if (GetWindowLongW(infoPtr->hwndSelf, GWL_STYLE) & WS_DISABLED)
351
return 0;
352
353
TRACE("() Key: %ld\n", key);
354
355
bOldMod = infoPtr->CurrMod;
356
357
switch (key)
358
{
359
case VK_SHIFT:
360
infoPtr->CurrMod &= ~HOTKEYF_SHIFT;
361
break;
362
case VK_CONTROL:
363
infoPtr->CurrMod &= ~HOTKEYF_CONTROL;
364
break;
365
case VK_MENU:
366
infoPtr->CurrMod &= ~HOTKEYF_ALT;
367
break;
368
default:
369
return 1;
370
}
371
372
if (bOldMod != infoPtr->CurrMod)
373
{
374
InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
375
376
/* send EN_CHANGE notification */
377
SendMessageW(infoPtr->hwndNotify, WM_COMMAND,
378
MAKEWPARAM(GetDlgCtrlID(infoPtr->hwndSelf), EN_CHANGE),
379
(LPARAM)infoPtr->hwndSelf);
380
}
381
382
return 0;
383
}
384
385
386
static LRESULT
387
HOTKEY_KillFocus (HOTKEY_INFO *infoPtr)
388
{
389
infoPtr->bFocus = FALSE;
390
DestroyCaret ();
391
392
return 0;
393
}
394
395
396
static LRESULT
397
HOTKEY_LButtonDown (const HOTKEY_INFO *infoPtr)
398
{
399
if (!(GetWindowLongW(infoPtr->hwndSelf, GWL_STYLE) & WS_DISABLED))
400
SetFocus (infoPtr->hwndSelf);
401
402
return 0;
403
}
404
405
406
static inline LRESULT
407
HOTKEY_NCCreate (HWND hwnd, const CREATESTRUCTW *lpcs)
408
{
409
HOTKEY_INFO *infoPtr;
410
DWORD dwExStyle = GetWindowLongW (hwnd, GWL_EXSTYLE);
411
SetWindowLongW (hwnd, GWL_EXSTYLE,
412
dwExStyle | WS_EX_CLIENTEDGE);
413
414
/* allocate memory for info structure */
415
infoPtr = Alloc(sizeof(*infoPtr));
416
SetWindowLongPtrW(hwnd, 0, (DWORD_PTR)infoPtr);
417
418
/* initialize info structure */
419
infoPtr->HotKey = infoPtr->InvComb = infoPtr->InvMod = infoPtr->CurrMod = 0;
420
infoPtr->CaretPos = GetSystemMetrics(SM_CXBORDER);
421
infoPtr->hwndSelf = hwnd;
422
LoadStringW(COMCTL32_hModule, HKY_NONE, infoPtr->strNone, 15);
423
424
return DefWindowProcW (infoPtr->hwndSelf, WM_NCCREATE, 0, (LPARAM)lpcs);
425
}
426
427
static LRESULT
428
HOTKEY_NCPaint (HWND hwnd, HRGN region)
429
{
430
INT cxEdge, cyEdge;
431
HRGN clipRgn;
432
HTHEME theme;
433
LONG exStyle;
434
RECT r;
435
HDC dc;
436
437
theme = OpenThemeDataForDpi(NULL, WC_EDITW, GetDpiForWindow(hwnd));
438
if (!theme)
439
return DefWindowProcW(hwnd, WM_NCPAINT, (WPARAM)region, 0);
440
441
exStyle = GetWindowLongW(hwnd, GWL_EXSTYLE);
442
if (!(exStyle & WS_EX_CLIENTEDGE))
443
{
444
CloseThemeData(theme);
445
return DefWindowProcW(hwnd, WM_NCPAINT, (WPARAM)region, 0);
446
}
447
448
cxEdge = GetSystemMetrics(SM_CXEDGE);
449
cyEdge = GetSystemMetrics(SM_CYEDGE);
450
GetWindowRect(hwnd, &r);
451
452
/* New clipping region passed to default proc to exclude border */
453
clipRgn = CreateRectRgn(r.left + cxEdge, r.top + cyEdge, r.right - cxEdge, r.bottom - cyEdge);
454
if (region != (HRGN)1)
455
CombineRgn(clipRgn, clipRgn, region, RGN_AND);
456
OffsetRect(&r, -r.left, -r.top);
457
458
dc = GetDCEx(hwnd, region, DCX_WINDOW | DCX_INTERSECTRGN);
459
if (IsThemeBackgroundPartiallyTransparent(theme, 0, 0))
460
DrawThemeParentBackground(hwnd, dc, &r);
461
DrawThemeBackground(theme, dc, 0, 0, &r, 0);
462
ReleaseDC(hwnd, dc);
463
CloseThemeData(theme);
464
465
/* Call default proc to get the scrollbars etc. also painted */
466
DefWindowProcW(hwnd, WM_NCPAINT, (WPARAM)clipRgn, 0);
467
DeleteObject(clipRgn);
468
return 0;
469
}
470
471
static LRESULT
472
HOTKEY_SetFocus (HOTKEY_INFO *infoPtr)
473
{
474
infoPtr->bFocus = TRUE;
475
476
CreateCaret (infoPtr->hwndSelf, NULL, 1, infoPtr->nHeight);
477
SetCaretPos (infoPtr->CaretPos, GetSystemMetrics(SM_CYBORDER));
478
ShowCaret (infoPtr->hwndSelf);
479
480
return 0;
481
}
482
483
484
static LRESULT
485
HOTKEY_SetFont (HOTKEY_INFO *infoPtr, HFONT hFont, BOOL redraw)
486
{
487
TEXTMETRICW tm;
488
HDC hdc;
489
HFONT hOldFont = 0;
490
491
infoPtr->hFont = hFont;
492
493
hdc = GetDC (infoPtr->hwndSelf);
494
if (infoPtr->hFont)
495
hOldFont = SelectObject (hdc, infoPtr->hFont);
496
497
GetTextMetricsW (hdc, &tm);
498
infoPtr->nHeight = tm.tmHeight;
499
500
if (infoPtr->hFont)
501
SelectObject (hdc, hOldFont);
502
ReleaseDC (infoPtr->hwndSelf, hdc);
503
504
if (redraw)
505
InvalidateRect (infoPtr->hwndSelf, NULL, TRUE);
506
507
return 0;
508
}
509
510
static LRESULT WINAPI
511
HOTKEY_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
512
{
513
HOTKEY_INFO *infoPtr = (HOTKEY_INFO *)GetWindowLongPtrW (hwnd, 0);
514
515
TRACE("hwnd %p, msg %x, wparam %Ix, lparam %Ix\n", hwnd, uMsg, wParam, lParam);
516
517
if (!infoPtr && (uMsg != WM_NCCREATE))
518
return DefWindowProcW (hwnd, uMsg, wParam, lParam);
519
switch (uMsg)
520
{
521
case HKM_GETHOTKEY:
522
return HOTKEY_GetHotKey (infoPtr);
523
case HKM_SETHOTKEY:
524
HOTKEY_SetHotKey (infoPtr, (WORD)wParam);
525
break;
526
case HKM_SETRULES:
527
HOTKEY_SetRules (infoPtr, (WORD)wParam, (WORD)lParam);
528
break;
529
530
case WM_CHAR:
531
case WM_SYSCHAR:
532
return HOTKEY_KeyDown (infoPtr, MapVirtualKeyW(LOBYTE(HIWORD(lParam)), 1), lParam);
533
534
case WM_CREATE:
535
return HOTKEY_Create (infoPtr, (LPCREATESTRUCTW)lParam);
536
537
case WM_DESTROY:
538
return HOTKEY_Destroy (infoPtr);
539
540
case WM_ERASEBKGND:
541
return HOTKEY_EraseBackground (infoPtr, (HDC)wParam);
542
543
case WM_GETDLGCODE:
544
return DLGC_WANTCHARS | DLGC_WANTARROWS;
545
546
case WM_GETOBJECT:
547
if ((LONG)lParam == OBJID_QUERYCLASSNAMEIDX)
548
return 0x10010;
549
return DefWindowProcW (hwnd, uMsg, wParam, lParam);
550
551
case WM_GETFONT:
552
return HOTKEY_GetFont (infoPtr);
553
554
case WM_KEYDOWN:
555
case WM_SYSKEYDOWN:
556
return HOTKEY_KeyDown (infoPtr, wParam, lParam);
557
558
case WM_KEYUP:
559
case WM_SYSKEYUP:
560
return HOTKEY_KeyUp (infoPtr, wParam);
561
562
case WM_KILLFOCUS:
563
return HOTKEY_KillFocus (infoPtr);
564
565
case WM_LBUTTONDOWN:
566
return HOTKEY_LButtonDown (infoPtr);
567
568
case WM_NCCREATE:
569
return HOTKEY_NCCreate (hwnd, (LPCREATESTRUCTW)lParam);
570
571
case WM_NCPAINT:
572
return HOTKEY_NCPaint (hwnd, (HRGN)wParam);
573
574
case WM_PRINTCLIENT:
575
case WM_PAINT:
576
HOTKEY_Paint(infoPtr, (HDC)wParam);
577
return 0;
578
579
case WM_SETFOCUS:
580
return HOTKEY_SetFocus (infoPtr);
581
582
case WM_SETFONT:
583
return HOTKEY_SetFont (infoPtr, (HFONT)wParam, LOWORD(lParam));
584
585
default:
586
if ((uMsg >= WM_USER) && (uMsg < WM_APP) && !COMCTL32_IsReflectedMessage(uMsg))
587
ERR("unknown msg %04x, wp %Ix, lp %Ix\n", uMsg, wParam, lParam);
588
return DefWindowProcW (hwnd, uMsg, wParam, lParam);
589
}
590
return 0;
591
}
592
593
594
void
595
HOTKEY_Register (void)
596
{
597
WNDCLASSW wndClass;
598
599
ZeroMemory (&wndClass, sizeof(WNDCLASSW));
600
wndClass.style = CS_GLOBALCLASS;
601
wndClass.lpfnWndProc = HOTKEY_WindowProc;
602
wndClass.cbClsExtra = 0;
603
wndClass.cbWndExtra = sizeof(HOTKEY_INFO *);
604
wndClass.hCursor = 0;
605
wndClass.hbrBackground = 0;
606
wndClass.lpszClassName = HOTKEY_CLASSW;
607
608
RegisterClassW (&wndClass);
609
}
610
611
612
void
613
HOTKEY_Unregister (void)
614
{
615
UnregisterClassW (HOTKEY_CLASSW, NULL);
616
}
617
618