拦截并阻止特定 window 的 ALT 按键
Intercept and prevent ALT keypress for specific window
我构建了一个 C# 应用程序,它采用另一个 window 处理程序及其过程,就像这个 post,我可以通过 PostMessage 从我的应用程序向 window 发送一些命令这个 window 即使在不活动时也会做出相应的反应。
当我按下 ALT 时出现问题,这个 window 像热键一样对 ALT + my_key_command 做出反应。
请解释如何阻止我的应用程序在特定 window 中处理 ALT 按键事件?这可能吗?
我只想关闭这个 window 的 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;
}
这段代码很适合这些用途,但应用程序处理 ALT+F5 和 F5 命令的方式不同,所以我根本不需要 ALT+F5。这就是为什么我首先想到阻止ALT键。
请使用SetWindowsHookEx and WH_KEYBOARD.
您需要在目标程序中注入一个包含键盘钩子的dll。通过安装键盘钩子,防止ALT键的return。
示例代码:(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#代码。
我构建了一个 C# 应用程序,它采用另一个 window 处理程序及其过程,就像这个 post,我可以通过 PostMessage 从我的应用程序向 window 发送一些命令这个 window 即使在不活动时也会做出相应的反应。
当我按下 ALT 时出现问题,这个 window 像热键一样对 ALT + my_key_command 做出反应。 请解释如何阻止我的应用程序在特定 window 中处理 ALT 按键事件?这可能吗?
我只想关闭这个 window 的 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;
}
这段代码很适合这些用途,但应用程序处理 ALT+F5 和 F5 命令的方式不同,所以我根本不需要 ALT+F5。这就是为什么我首先想到阻止ALT键。
请使用SetWindowsHookEx and WH_KEYBOARD.
您需要在目标程序中注入一个包含键盘钩子的dll。通过安装键盘钩子,防止ALT键的return。
示例代码:(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#代码。