1) When I run this program and press the tilde/backquote key, a messagebox pops up as expected. However, if I press the hotkey again without closing the messagebox, a second messagebox appears (and a third and so forth). How can this be, given that it is a single-threaded application, and MessageBox blocks execution?
2) If I move the RegisterHotKey calls to the WM_CREATE handler of the window procedure, the hotkeys don't work, why?
3) Is this code 100% correct as far as the message loop, window procedure, etc? (other than not yet processing WM_PAINT messages)
Note: The use of hotkeys rather than simply processing WM_KEYDOWN messages is intentional.
include /masm32/include/masm32rt.inc
WinMain PROTO
hkIDBackQuote equ 0
hkIDAltF11 equ 1
.data
szClassName db "hkhkwin", 0
.data?
hWnd HWND ?
hInstance HINSTANCE ?
.code
start:
invoke WinMain
exit
WinMain PROC
LOCAL msg:MSG
LOCAL wc:WNDCLASSEX
mov hInstance, FUNC(GetModuleHandle, NULL)
mov wc.cbSize, sizeof WNDCLASSEX
mov wc.style, 0
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra, 0
mov wc.cbWndExtra, 0
m2m wc.hInstance, hInstance
mov wc.hIcon, NULL
mov wc.hCursor, FUNC(LoadCursor, NULL, IDC_ARROW)
mov wc.hbrBackground, FUNC(CreateSolidBrush, 00FFFFFFh)
mov wc.lpszMenuName, NULL
m2m wc.lpszClassName, OFFSET szClassName
mov wc.hIconSm, NULL
invoke RegisterClassEx, ADDR wc
invoke CreateWindowEx, 0, OFFSET szClassName, chr$("^^"), WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, NULL, NULL, hInstance, NULL
mov hWnd, eax
.IF !hWnd
return FALSE
.ENDIF
invoke ShowWindow, hWnd, SW_SHOWDEFAULT
invoke UpdateWindow, hWnd
invoke RegisterHotKey, hWnd, hkIDBackQuote, NULL, VK_OEM_3
invoke RegisterHotKey, hWnd, hkIDAltF11, MOD_ALT, VK_F11
.WHILE TRUE
invoke GetMessage, ADDR msg, NULL, 0, 0
.IF eax == 0
return msg.wParam
.ENDIF
invoke DispatchMessage, ADDR msg
.ENDW
WinMain ENDP
WndProc PROC hwnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
.IF uMsg == WM_CREATE
;; .ELSEIF uMsg == WM_PAINT
.ELSEIF uMsg == WM_HOTKEY
.IF wParam == hkIDAltF11
invoke DestroyWindow, hWnd
.ELSEIF wParam == hkIDBackQuote
MsgBox NULL, "backquote", "`", MB_OK
;; invoke Sleep, 10000
.ENDIF
.ELSEIF uMsg == WM_DESTROY
invoke UnregisterHotKey, hWnd, hkIDBackQuote
invoke UnregisterHotKey, hWnd, hkIDAltF11
invoke PostQuitMessage, 0
.ELSE
invoke DefWindowProc, hwnd, uMsg, wParam, lParam
ret
.ENDIF
return 0
WndProc ENDP
end start