我想构建一个在后台运行的应用程序,并将捕获所有点击事件在最小化按钮上,实际运行的所有打开的表单/窗口。 (不仅在我当前的应用程序中)
它将是某种钩子,用于将最小化处理程序添加到所有其他窗口。
如何设置这种钩子?(请提供一些带有封送的 csharp 代码示例)
为了更好地理解这个想法:此过程已经存在于名为TrayIt的程序中,该程序处理Ctrl +单击最小化按钮,并将程序发送到系统托盘。
编辑:
我发现由于托管代码的限制,SetWindowsHookEx无法使用c#设置全局钩子(请参阅MSDN文档)
但可能WinEventProc与EVENT_OBJECT_STATECHANGE应该做这项工作
我已经找到了这个钩子的解决方案,这不是我能得到的最佳解决方案,但它可以完成工作
我在 SetWinEventHook 中混合了window_state_change
和组件来跟踪 Gma.UserActivityMonitor 中的控制键
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Windows;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Security.Permissions;
using Gma.UserActivityMonitor;
namespace example {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
public const uint WINEVENT_OUTOFCONTEXT = 0;
public const uint EVENT_OBJECT_STATECHANGE = 0x800A;
[DllImport("user32.dll")]
public static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr hmodWinEventProc, WinEventDelegate lpfnWinEventProc, uint idProcess, uint idThread, uint dwFlags);
[DllImport("user32.dll")]
public static extern bool UnhookWinEvent(IntPtr hWinEventHook);
public delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime);
public static bool ControlDown = false;
public static IntPtr hhook;
static WinEventDelegate procDelegate = new WinEventDelegate(WinEventProc);
private void load(object sender, System.EventArgs e) {
hhook = SetWinEventHook(EVENT_OBJECT_STATECHANGE, EVENT_OBJECT_STATECHANGE, IntPtr.Zero, procDelegate, 0, 0, winapi.WINEVENT_OUTOFCONTEXT);
HookManager.KeyDown += HookManager_KeyDown;
HookManager.KeyUp += HookManager_KeyUp;
}
private void closing(object sender, System.Windows.Forms.FormClosingEventArgs e) {
UnhookWinEvent(hhook);
HookManager.KeyDown -= HookManager_KeyDown;
HookManager.KeyUp -= HookManager_KeyUp;
}
private void HookManager_KeyUp(object sender, KeyEventArgs e) {
if (e.KeyCode == Keys.LControlKey) { ControlDown = false; }
}
private void HookManager_KeyDown(object sender, KeyEventArgs e) {
if (e.KeyCode == Keys.LControlKey) { ControlDown = true; }
}
static void WinEventProc(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime) {
if (idObject == -2 && idChild == 2) {
if (ControlDown) {
// HookWindow(hwnd);
.....
}
}
}
}
}
如果你愿意,你可以用注册热键设置一个简单的钩子
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);