拦截并阻止特定窗口的 ALT 按键
Posted
技术标签:
【中文标题】拦截并阻止特定窗口的 ALT 按键【英文标题】:Intercept and prevent ALT keypress for specific window 【发布时间】:2020-08-24 16:41:19 【问题描述】:我已经构建了一个 C# 应用程序,它采用另一个窗口处理程序及其进程,就像在这个 post 中一样,我可以通过 PostMessage 从我的应用程序向窗口发送一些命令,这个窗口即使在不活动时也会做出相应的反应。
当我按下 ALT 并且这个窗口像热键一样对 ALT + my_key_command 做出反应时,就会出现问题。 请解释如何防止我的应用程序在特定窗口中处理 ALT 按键事件?这可能吗?
我只想为 ALT 键关闭此窗口。示例如下:
[DllImport("user32.dll")]
static extern bool PostMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam);
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll", SetLastError = true)]
private static extern int GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId);
[STAThread]
static async Task Main()
await Task.Delay(TimeSpan.FromSeconds(5));
IntPtr window = GetForegroundWindow();
while (true)
int processId;
GetWindowThreadProcessId(window, out processId);
Process[] processes = Process.GetProcessesByName("iexplorer");
var process = findProcessById(processes, processId);
if (process != null)
PostMessage(process.MainWindowHandle, WM_KEYDOWN, 0x74, 0);
Thread.Sleep(5000);
static private Process findProcessById(Process[] processes, int id)
Process result = null;
foreach (Process proc in processes)
if (proc.Id == id)
result = proc;
return result;
【问题讨论】:
注入一个使用SetWindowsHookEx
的dll和一个键盘钩子来钩键..
使用 WindowsHooks 时要非常小心 - 了解可以搞砸事情的各种方式。
您要解决什么问题?这个问题询问您提出的解决方案。这种现象通常被描述为XY Problem。
我没有看到代码中建立了任何窗口层次结构。不过,我确实看到了带有 WM_KEYDOWN
消息的 PostMessage
。众所周知,you can't simulate keyboard input with PostMessage。那么,您要解决的真正问题是什么?
我需要我的应用程序将 F1、F2、... F12 等命令发送到另一个应用程序(窗口),例如 Internet Explorer。此代码适用于这些目的,但应用程序处理 ALT+F5 和 F5 命令的方式不同,所以我根本不需要 ALT+F5。这就是为什么我首先想到要阻止 ALT 键。如果有其他方法可以解决这个问题,我会尝试所有方法
【参考方案1】:
这段代码可以很好地用于这些目的,但是应用程序处理 ALT+F5 和 F5 命令的方式不同,所以我根本不需要 ALT+F5。这就是为什么我首先想到要屏蔽 ALT 键。
请使用SetWindowsHookEx 和WH_KEYBOARD。
您需要将包含键盘挂钩的 dll 注入目标程序。通过安装一个键盘挂钩,并防止 ALT 键返回。
示例代码:(C++)
.dll:
// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include <windows.h>
#include <iostream>
#include <stdio.h>
HINSTANCE hinst;
#pragma data_seg(".shared")
HHOOK hhk;
#pragma data_seg()
LRESULT CALLBACK wireKeyboardProc(int code, WPARAM wParam, LPARAM lParam)
if (code >= 0)
switch (wParam)
case VK_MENU:
return 1;
return CallNextHookEx(hhk, code, wParam, lParam);
extern "C" __declspec(dllexport) void install(unsigned long threadID)
hhk = SetWindowsHookEx(WH_KEYBOARD, wireKeyboardProc, hinst, threadID);
extern "C" __declspec(dllexport) void uninstall()
UnhookWindowsHookEx(hhk);
BOOL WINAPI DllMain(__in HINSTANCE hinstDLL, __in DWORD fdwReason, __in LPVOID lpvReserved)
hinst = hinstDLL;
return TRUE;
.cpp
#include <Windows.h>
#include <stdio.h>
#include <tchar.h>
unsigned long GetTargetThreadIdFromWindow(const char* className, const char* windowName)
HWND targetWnd;
HANDLE hProcess;
unsigned long processID = 0;
targetWnd = FindWindow(className, windowName);
return GetWindowThreadProcessId(targetWnd, &processID);
int main()
unsigned long threadID = GetTargetThreadIdFromWindow("Notepad", "1.txt - Notepad"); // Use Notepad for test
printf("TID: %i", threadID);
HINSTANCE hinst = LoadLibrary(_T("Mydll.dll"));
if (hinst)
typedef void (*Install)(unsigned long);
typedef void (*Uninstall)();
Install install = (Install)GetProcAddress(hinst, "install");
Uninstall uninstall = (Uninstall)GetProcAddress(hinst, "uninstall");
install(threadID);
MSG msg = ;
while (GetMessage(&msg, NULL, 0, 0))
TranslateMessage(&msg);
DispatchMessage(&msg);
uninstall();
return 0;
我使用记事本作为测试对象,它工作正常。这是c++代码,你可以根据需要转换成C#代码。
【讨论】:
谢谢!我会尽快尝试的!以上是关于拦截并阻止特定窗口的 ALT 按键的主要内容,如果未能解决你的问题,请参考以下文章