`
mixer_a
  • 浏览: 364405 次
社区版块
存档分类
最新评论

编程使用系统热键{定时器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_ICONERROR
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_ICONERROR
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 start
分享到:
评论

相关推荐

    vc++2005定时器settimer()的使用

    在你提供的“Timer”压缩包文件中,可能包含了一个简单的示例程序,演示了如何在VC++2005中使用`SetTimer`创建和处理定时器。通过学习和理解这个例子,你应该能更好地掌握`SetTimer`的使用。在编写涉及定时器的代码...

    线程内使用SetTimer实现定时器

    在Windows编程中,定时器是实现程序自动化控制和时间间隔触发事件的重要工具。`SetTimer`函数是Windows API提供的一种简单、高效的定时器接口,它主要用于在消息循环中设置一个定时器,当达到预设的时间间隔后,系统...

    VC++定时器,比SetTimer更精确

    此外,频繁的高精度定时器可能对系统性能产生影响,因此在选择使用哪种定时器时,应根据实际需求权衡精度和性能。 在提供的`MultiTimerDemo`项目中,可能包含了一个实现多路定时器的示例,可以查看源代码了解如何...

    vc++实现非窗口类中使用定时器的方法

    - 使用`SetTimer()`函数创建定时器,并使用`KillTimer()`销毁定时器。这两个函数都需要传递一个窗口句柄。 ```cpp void CNonWindowClass::SetTimer(int nIDEvent, UINT uElapse) { ::SetTimer(m_hWnd, nIDEvent...

    MFC定时器的使用 MFC定时器的使用

    - 创建消息定时器通常在CWinApp或CWnd派生类的成员函数中进行,通过`SetTimer`函数设定定时器,参数包括定时器ID、间隔时间和两个可选参数(用于指定定时器的销毁方式)。 - `SetTimer`函数返回一个非零值,表示...

    VC 实现非窗口类中使用定时器的方法

    我们可以使用SetTimer API函数创建一个系统定时器,该函数需要四个参数:定时器ID、间隔时间(毫秒)、回调函数指针以及用户自定义数据。由于非窗口类没有消息循环,所以我们不能使用WM_TIMER消息,而是需要提供一个...

    VC 自定义定时器的使用

    有两种主要类型的定时器:`SetTimer`函数创建的系统定时器和`Ctimer`类创建的MFC定时器。 ### 2. `SetTimer`函数 `SetTimer`函数是Windows API提供的,用于设置一个定时器。它的基本用法如下: ```cpp UINT_PTR ...

    vb6做的毫秒级定时器(非控件)

    3. **设置定时器**:使用`SetTimer`函数来启动定时器,传入窗口句柄、定时器ID(一般可以设为0)、间隔时间(以毫秒计)和回调函数的地址。例如,`SetTimer 0, 0, 1, AddressOf TimerCallback`将创建一个每毫秒触发...

    delphi 几个定时器方法的比较

    1. **系统定时器**:Delphi中的TTimer组件是基于Windows API的SetTimer函数实现的,它提供了一个简单的接口来创建周期性事件。用户可以通过调整Interval属性来设置定时器触发的时间间隔。然而,系统定时器的精度受制...

    C/C++ 定时器程序(含源码和demo)

    2. **Windows定时器**:在Windows系统中,我们可以使用`SetTimer()` API创建窗口消息定时器,或者使用`CreateTimerQueueTimer()`创建异步定时器。这两种方法都会在指定时间后发送一个消息到指定的窗口或线程,从而...

    使用多媒体定时器做多线程编程的简单例子

    在IT领域,多线程编程和多媒体定时器是两个关键概念,它们经常被结合使用以实现高效的系统资源管理和任务调度。下面将详细讲解这两个概念及其在实际应用中的使用。 首先,我们来了解一下“多媒体定时器”。多媒体...

    游戏编程学习笔记01 -- 定时器操作 代码附件

    在游戏编程中,定时器(Timer)是一种至关重要的工具,它允许程序在特定的时间间隔执行特定的任务,这对于游戏循环、动画、用户输入...同时,这个过程也将锻炼你的系统编程能力,提升你对时间控制和程序同步的理解。

    基于VC_的实时数据采集系统中定时器的使用与比较

    ### 基于VC++的实时数据采集系统中定时器的使用与比较 #### 引言 实时数据采集系统在工业自动化、科学研究等多个领域扮演着重要角色。这类系统通常需要利用中断或定时器来实现数据的定时采集。特别是在对定时精度...

    VC++使用定时器的例子【源码】

    本示例提供了VC++使用定时器的一个基本源码实例,虽然只是一个功能模块,但可以帮助理解定时器的基本原理和使用方法。 首先,我们要了解定时器的工作原理。在Windows操作系统中,定时器是通过消息机制来实现的。当...

    vc 定时器 Timer 多媒体定时器 毫秒 ms

    Windows操作系统提供了两种主要类型的定时器:SetTimer和 Multimedia Timer。SetTimer是GUI应用程序中常用的一种简单定时器,适合处理相对较大的时间间隔,例如几百毫秒或几秒钟。而多媒体定时器则更适合需要毫秒级...

    多媒体定时器使用范例小例子

    在Windows编程中,普通定时器是基于消息队列的,其工作原理是:当设置一个定时器后,系统会在指定的时间间隔后向应用程序的消息队列发送一个`WM_TIMER`消息。而多媒体定时器则不依赖于消息队列,它使用硬件支持,...

    Windows高精度定时器(VC++实现)

    总结来说,"Windows高精度定时器(VC++实现)"是利用Windows消息机制和高级计时API实现的,主要目标是提供毫秒级精度的定时服务,便于开发者在需要精确控制时间的场景下进行编程。`MessageTimer`类可能是这一实现的...

    VC++ MFC 定时器函数 刷新窗口

    在VC++ MFC编程中,使用`SetTimer`和`KillTimer`函数可以方便地实现定时操作和窗口的定期刷新。通过合理的设置定时器标识符和重写`OnTimer`函数,可以轻松地管理多个定时器,并实现复杂的定时逻辑。此外,注意适时...

    VC++处理在文档类添加定时器和非窗口类添加定时器

    在VC++编程环境中,添加定时器是常见的需求,特别是在开发具有实时更新或自动执行特定任务的应用程序时。本文将深入探讨如何在文档类(CDocument)以及非窗口类中实现定时器功能,以便进行定时保存文件等操作。 ...

Global site tag (gtag.js) - Google Analytics