编程使用系统热键{定时器SetTimer()和GetAsyncKeyState()}

简介: 编程使用系统热键{定时器SetTimer()和GetAsyncKeyState()}

GetAsyncKeyState()=========================

功能:确定用户当前是否按下了键盘上的一个键

原型:SHORT GetAsyncKeyState(int vKey);

参数:nVirtKey指出要检查键的虚键代码。结果的高位指出该键当前是否被按下(是为1,否为0)。

常用键的VK值:

VK_SHIFT Shift键

VK_LSHIFT 左Shift键

VK_RSHIFT 右Shift键

VK_CONTROL Ctrl键

VK_LCONTROL 左Ctrl键

VK_RCONTROL 右Ctril键

VK_MENU Alt键

VK_LMENU 左Alt键

VK_RMENU 右Alt键

VK_LBUTTON 鼠标左键

VK_RBUTTON 鼠标右键

另一个函数GetKeyState与GetAsyncKeyState函数不同。GetAsyncKeyState在按下某键的同时调用,判断正在按下某键。

GetKeyState则在按过某键之后再调用,它返回最近的键盘消息从线程的队列中移出时的键盘状态,判断刚按过了某键。

与RegisterHotKey()相比,GetAsyncKeyState()的优点在于可以监控鼠标按键,缺点是需要使用定时器,并且无法保证热键的惟一性。

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; 文件名: HotKey2.asm
; 作 者: Purple Endurer
; 功 能: 演示定时器SetTimer()和GetAsyncKeyState()
; 点击“监测Alt+鼠标右键! 成功后按
; Alt+鼠标右键可打开记事本!”按钮,
; 则尝试监测Alt+鼠标右键是否按下
; 如果尝试不成功,则提示出错信息!
; 如果尝试成功,则按Alt+鼠标右键时,
; 可将当前程序窗口恢复到前台
; 并启动计事本!
; 开发环境:Windows 2000 Pro + MASM32
; 注:源代码和可执行程序可以到http://purpleendurer.ys168.com下载
;
; Date log
;-------------------------------------------------
;2006-03-09 创建!
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
.386
.model flat, stdcall
option casemap: none
include /masm32/ include/windows.inc
include /masm32/ include/user32.inc
include /masm32/ include/kernel32.inc
include /masm32/ include/shell32.inc
includelib /masm32/ lib/user32.lib
includelib /masm32/ lib/kernel32.lib
includelib /masm32/ lib/shell32.lib
WinMain proto : DWORD, : DWORD, : DWORD, : DWORD
m_m2m MACRO d1, d2
push d2
pop d1
ENDM
.const
c_ButtonID equ 1
c_TimerID equ 1
.data
g_szWinClsName db "DemoWinClass", 0
g_szAppName db "系统演示程序2 by PurpleEndurer", 0
g_szBtnClsName db "button", 0
g_szFailSetTimer db "不能"
g_szRegisterKey db "监测Alt+鼠标右键! 成功后按Alt+鼠标右键可打开记事本!", 0
g_szFailKillTimer db "不能"
g_szUnregisterKey db "停止监测Alt+鼠标右键!", 0
g_bRegisted dword FALSE
g_szOpen db "Open", 0
g_szNotePad db "NotePad", 0
.data?
hInstance HINSTANCE ?
CommandLine LPSTR ?
g_hwndButton HANDLE ?
.code
start:
invoke GetModuleHandle, NULL
mov hInstance, eax
invoke GetCommandLine
mov CommandLine, eax
invoke WinMain, hInstance, NULL, CommandLine, SW_SHOWDEFAULT
invoke ExitProcess, eax
WinMain proc hInst:HINSTANCE, hPrevInst:HINSTANCE, CmdLine:LPSTR, CmdShow: DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL hwnd:HWND
mov wc.cbSize, SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra, NULL
mov wc.cbWndExtra, NULL
push hInstance
pop wc.hInstance
mov wc.hbrBackground, COLOR_WINDOW+1
mov wc.lpszMenuName, NULL
mov wc.lpszClassName, OFFSET g_szWinClsName
invoke LoadIcon, NULL, IDI_APPLICATION
mov wc.hIcon, eax
mov wc.hIconSm, eax
invoke LoadCursor, NULL, IDC_ARROW
mov wc.hCursor, eax
invoke RegisterClassEx, addr wc
INVOKE CreateWindowEx, NULL, ADDR g_szWinClsName, ADDR g_szAppName, /
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, /
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, /
hInst, NULL
mov hwnd, eax
invoke ShowWindow, hwnd, SW_SHOWNORMAL
invoke UpdateWindow, hwnd
.WHILE TRUE
invoke GetMessage, ADDR msg, NULL, 0, 0
.BREAK .IF (! eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.ENDW
mov eax, msg.wParam
ret
WinMain endp
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.IF uMsg==WM_DESTROY
.if g_bRegisted== TRUE
invoke KillTimer, hWnd, c_TimerID
.endif
invoke PostQuitMessage, NULL
.ELSEIF uMsg==WM_CREATE
;创建按钮
invoke CreateWindowEx, NULL, ADDR g_szBtnClsName, ADDR g_szRegisterKey, /
WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON,/
25, 25, 560, 50, hWnd, c_ButtonID, hInstance, NULL
mov g_hwndButton, eax
.ELSEIF uMsg==WM_COMMAND
mov eax, wParam
.IF lParam!=0
.IF ax==c_ButtonID
shr eax, 16
.IF ax==BN_CLICKED
.if g_bRegisted== TRUE
;禁用监测
invoke KillTimer, hWnd, c_TimerID
.IF eax==0
invoke MessageBox, hWnd, ADDR g_szFailKillTimer,/
ADDR g_szAppName, MB_IC ONERROR
ret
.ENDIF
m_m2m g_bRegisted, FALSE
;修改按钮的文本
invoke SetWindowText, g_hwndButton, ADDR g_szRegisterKey
.else
;启用监测
invoke SetTimer, hWnd, c_TimerID, 100, NULL
.IF eax==0
invoke MessageBox, hWnd, ADDR g_szFailSetTimer,/
ADDR g_szAppName, MB_IC ONERROR
ret
.ENDIF
m_m2m g_bRegisted, TRUE
;修改按钮的文本
invoke SetWindowText, g_hwndButton, ADDR g_szUnregisterKey
.endif
.ENDIF
.ENDIF
.ENDIF
.ELSEIF uMsg==WM_TIMER
invoke GetAsyncKeyState, VK_LMENU ;左Alt键
test eax, 08000h
jz @F
invoke GetAsyncKeyState, VK_RBUTTON ;鼠标右键
test eax, 08000h
jz @F
;把本程序窗口恢复到前台
invoke ShowWindow, hWnd, SW_RESTORE
invoke SetForegroundWindow, hWnd
;打开记事本
invoke ShellExecute, hWnd, ADDR g_szOpen, ADDR g_szNotePad, NULL, NULL, SW_RESTORE
@@:
.ELSE
invoke DefWindowProc, hWnd, uMsg, wParam, lParam
ret
.ENDIF
xor eax, eax
ret
WndProc endp
end


相关文章
|
缓存 小程序 JavaScript
从零开始搭建uni-app框架的小程序开发环境
从零开始搭建uni-app框架的小程序开发环境
1028 0
从零开始搭建uni-app框架的小程序开发环境
|
6月前
|
JavaScript 前端开发 中间件
除了 Pinia,还有哪些状态管理库可以实现类似的中间件功能?
除了 Pinia,还有哪些状态管理库可以实现类似的中间件功能?
310 73
|
机器学习/深度学习 缓存 PyTorch
异步数据加载技巧:实现 DataLoader 的最佳实践
【8月更文第29天】在深度学习中,数据加载是整个训练流程中的一个关键步骤。为了最大化硬件资源的利用率并提高训练效率,使用高效的数据加载策略变得尤为重要。本文将探讨如何通过异步加载和多线程/多进程技术来优化 DataLoader 的性能。
2171 1
【Azure API 管理】在 Azure API 管理中使用 OAuth 2.0 授权和 Azure AD 保护 Web API 后端,在请求中携带Token访问后报401的错误
【Azure API 管理】在 Azure API 管理中使用 OAuth 2.0 授权和 Azure AD 保护 Web API 后端,在请求中携带Token访问后报401的错误
257 0
|
网络协议 网络安全 网络虚拟化
HCIP-Datacom H12-821 题库 (3)
HCIP-Datacom H12-821 题库 (3)
157 0
HCIP-Datacom H12-821 题库 (3)
|
消息中间件 监控 Kafka
查询Kafka集群中消费组(group)信息和对应topic的消费情况
查询Kafka集群中消费组(group)信息和对应topic的消费情况
6258 0
|
Web App开发 移动开发 IDE
laya入门,这一篇应该够了
laya入门,这一篇应该够了
6665 1
|
前端开发 Linux Android开发
请问阿里云rpa可以模拟手机app操作么?
请问阿里云rpa可以模拟手机app操作么?
420 1
UE中创建可脚本化编辑器工具(Scriptable Tools)
UE中创建可脚本化编辑器工具(Scriptable Tools)
522 0
UE中创建可脚本化编辑器工具(Scriptable Tools)