找回密码
 加入
搜索
查看: 2587|回复: 7

[系统综合] 截获 WIN 键如何保留其组合键[已解决]

[复制链接]
发表于 2020-7-3 09:40:29 | 显示全部楼层 |阅读模式
本帖最后由 onestone01 于 2020-7-6 21:56 编辑

参考帮助文档和论坛的帖子,可以截获 win 键,阻止弹出开始菜单。
阻止了win 键传递结果导致 win组合键失效(如WIN+R;WIN+D...)
希望截获 win 键又保留组合键作用,应该怎么做?
#include <WinAPI.au3>
#include <WindowsConstants.au3>
Global $g_hHook, $g_hStub_KeyProc, $g_sBuffer = ""
Example()
Func Example()
        OnAutoItExitRegister("Cleanup")
        Local $hMod
        $g_hStub_KeyProc = DllCallbackRegister("_KeyProc", "long", "int;wparam;lparam")
        $hMod = _WinAPI_GetModuleHandle(0)
        $g_hHook = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($g_hStub_KeyProc), $hMod)
        While 1
                Sleep(10)
        WEnd
EndFunc   ;==>Example
; ===========================================================
; callback function
; ===========================================================
Func _KeyProc($nCode, $wParam, $lParam)
        Local $tKEYHOOKS
        $tKEYHOOKS = DllStructCreate($tagKBDLLHOOKSTRUCT, $lParam)
        If $nCode < 0 Then
                Return _WinAPI_CallNextHookEx($g_hHook, $nCode, $wParam, $lParam)
        EndIf
        $wVKey = DllStructGetData($tKEYHOOKS, "vkCode")
        If ($wVKey = 27) Then ; Esc 键
                Exit
        ElseIf ($wVKey = 91) Then ;lwin
                If $wParam = $WM_KEYDOWN Or $wParam = $WM_SYSKEYDOWN Then ;按下
                        ToolTip("{win}  DOWN.")
                        Return 1 ;如果按下不截获导致 WIN 键不弹起
                ElseIf $wParam = $WM_KEYUP Or $wParam = $WM_SYSKEYUP Then ;弹起
                        ToolTip("{win}  up." )
                        Return 1
                EndIf
        EndIf
        Return _WinAPI_CallNextHookEx($g_hHook, $nCode, $wParam, $lParam)
EndFunc   ;==>_KeyProc

Func Cleanup()
        _WinAPI_UnhookWindowsHookEx($g_hHook)
        DllCallbackFree($g_hStub_KeyProc)
EndFunc   ;==>Cleanup

发表于 2020-7-3 10:44:32 | 显示全部楼层
ToolTip("{win}  DOWN.")
Return 1 ;如果按下不截获导致 WIN 键不弹起

把这两行去掉就行了

评分

参与人数 1金钱 +10 收起 理由
onestone01 + 10 感谢!

查看全部评分

 楼主| 发表于 2020-7-3 10:54:14 | 显示全部楼层
guland 发表于 2020-7-3 10:44
ToolTip("{win}  DOWN.")
Return 1 ;如果按下不截获导致 WIN 键不弹起

感谢回复,Return 1 去掉 导致 WIN 键不能弹起,比如按下win键释放后,单按D会显示桌面(win+d)也就是说弹起时拦截导致 WIN 键没弹起
发表于 2020-7-4 15:06:17 | 显示全部楼层
按下win时不要 Return 1。如果返回1,不需要拦截的组合键就不容易处理响应了。
如果不返回,那就只需要处理win键弹起事件了。跟踪下在win按下到弹起期间有无其它键的消息,如果有则不处理,那样就可放过组合键;如果没有则send一些无意义的组合键即可。
仅给思路,无代码~

评分

参与人数 1金钱 +10 收起 理由
onestone01 + 10 感谢!

查看全部评分

 楼主| 发表于 2020-7-4 19:47:02 | 显示全部楼层
afan 发表于 2020-7-4 15:06
按下win时不要 Return 1。如果返回1,不需要拦截的组合键就不容易处理响应了。
如果不返回,那就只需要处 ...

非常感谢,高手思路就是开阔。我只考虑到按下或弹起有无其它键的消息,各种方法测试无果。
按照您的思路 按下win时不 Return 1,即使不使用组合键的情况下。也就是说按下到弹起期间无其它键的消息。
send一些无意义的组合键并不能阻止win弹起信息的传递。开始菜单仍然会弹出。
Return 1 拦截,系统又收不到弹起信息。
按照您的思路我再研究看看。
 楼主| 发表于 2020-7-6 09:00:25 | 显示全部楼层
本帖最后由 onestone01 于 2020-7-6 09:01 编辑

一个比较笨的方法,基本上够用。效果不理想。缺点长按组合键,会不停的执行。希望有更好的方法
#include <WinAPI.au3>
#include <WindowsConstants.au3>
Global $g_hHook, $g_hStub_KeyProc, $g_sBuffer = "", $WinDOWN = 0
Example()
Func Example()
        OnAutoItExitRegister("Cleanup") ;退出时移除钩子
        Local $hMod
        $g_hStub_KeyProc = DllCallbackRegister("_KeyProc", "long", "int;wparam;lparam")
        $hMod = _WinAPI_GetModuleHandle(0)
        $g_hHook = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($g_hStub_KeyProc), $hMod)
        While 1
                Sleep(10)
        WEnd
EndFunc   ;==>Example
; ===========================================================
; callback function
; ===========================================================
Func _KeyProc($nCode, $wParam, $lParam)
        Local $tKEYHOOKS = DllStructCreate($tagKBDLLHOOKSTRUCT, $lParam)
        If $nCode < 0 Then
                Return _WinAPI_CallNextHookEx($g_hHook, $nCode, $wParam, $lParam)
        EndIf
        $wVKey = DllStructGetData($tKEYHOOKS, "vkCode")
        Switch $wVKey
                Case 27 ; Esc 键
                        Exit
                Case 91, 92 ;左右 Win 键
                        If $wParam = $WM_KEYDOWN Then ;按下
                                $WinDOWN = 1
                                ToolTip('WIN  DOWN')
                        ElseIf $wParam = $WM_KEYUP Then ;弹起
                                $WinDOWN = 0
                                ToolTip('WIN  UP')
                        EndIf
                        Return 1
                Case 9, 19, 48 To 57, 65 To 90
                        If $WinDOWN = 1 AND $wParam = $WM_KEYDOWN Then
                                Send('#' & _KEYChr($wVKey))
                                $keyDOWN = 1
                                Return 1
                        EndIf
        EndSwitch
        Return _WinAPI_CallNextHookEx($g_hHook, $nCode, $wParam, $lParam)
EndFunc   ;==>_KeyProc

Func _KEYChr($Key)
        Switch $Key
                Case 9
                        Return ('{TAB}')
                Case 19
                        Return ('{PAUSE}')
                Case 48 To 90 ;48 To 57 => 0 - 9 键 |65 To 90 => a - z 键
                        Return StringLower(Chr($Key)) ;返回 ASCII 码 并转换为小写
        EndSwitch
        Return ''
EndFunc   ;==>_KEYChr
Func Cleanup()
        _WinAPI_UnhookWindowsHookEx($g_hHook)
        DllCallbackFree($g_hStub_KeyProc)
EndFunc   ;==>Cleanup


发表于 2020-7-6 20:46:24 | 显示全部楼层
这个就属于我上面说的“就不容易处理响应了”。
1,Ctrl、Shift、Alt 这些辅助键参与的组合键无效,因为它们几个被无视了。你可以 Case 160 to 165 ,处理需添加的 Send的辅助键
2,只处理了一些字母数字快捷键,然而还有很多都可以作为组合键的也被无视了,比如方向键、PageUp等。Case 48 To 90 ;48 To 57 => 0 - 9 键 |65 To 90 => a - z 键 可以改为 Case Else 处理
3,第38行Send,实际会被执行N次,你在下面添加一行ConsoleWrite调试看看便知。(但这里与你的“缺点长按组合键,会不停的执行”无关)

评分

参与人数 1金钱 +30 收起 理由
onestone01 + 30 感谢指点

查看全部评分

 楼主| 发表于 2020-7-6 21:55:24 | 显示全部楼层
afan 发表于 2020-7-6 20:46
这个就属于我上面说的“就不容易处理响应了”。
1,Ctrl、Shift、Alt 这些辅助键参与的组合键无效,因为它 ...

非常感谢指点,这种方法弊端很大,正如你所说确实不容易处理响应。我再试试你说的 SEND 一些无意义的组合键,先结贴吧。这种方法凑合也能用(要求不高自己用知道它的缺点)。
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-11-16 10:42 , Processed in 0.072531 second(s), 20 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表