取消

Windows Form定义快捷键(热键)

在windows form编程中定义快捷键(热键),通过重写WndProc消息方法捕获快捷键按下事件


注册快捷键

在窗体加载方法中注册热键

1
2
WinAPIHelper.RegisterHotKey(this.Handle, 100, WinAPIHelper.KeyModifiers.Ctrl , Keys.F);
//WinAPIHelper.RegisterHotKey(this.Handle, 100, WinAPIHelper.KeyModifiers.Ctrl | WinAPIHelper.KeyModifiers.Alt, Keys.None); 只按下Ctrl+Alt触发键盘事件,比如你想实现按下ctrl+alt打开窗口

快捷键按下时触发事件

重写消息捕获方法拦截快捷键按下事件

1
2
3
4
5
6
7
8
9
10
11
12
13
protected override void WndProc(ref Message m)
{
    base.WndProc(ref m);
    Console.WriteLine(m.WParam);
    if (m.Msg == WinAPIHelper.WM_HOTKEY)
    {
        MessageBox.Show(m.WParam.ToString());
        if (m.WParam.ToInt32()==100)//m.WParam是WinAPIHelper.RegisterHotKey第二个参数的值
        {
            Console.WriteLine("你按下了Ctrl+Alt");
        }
    }
}

WindowsAPI辅助类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
public struct tagMSG
{
    public int hwnd;
    public uint message;
    public int wParam;
    public long lParam;
    public uint time;
    public POINT pt;
}

public struct POINT
{
    public int x;
    public int y;
}

public class WinAPIHelper
{
    #region 消息定义
    //标准
    public const int WM_CLOSE = 0x10;
    public const int WM_SETICON = 0x80;
    public const int WM_KEYDWON = 0x0100;
    public const int WM_HOTKEY = 0x312;
    public const int IMAGW_ICON = 1;
    public const int LR_LOADFROMFILE = 0x10;

    //自定义
    public const int WM_OPENDT = 0x8888;
    public const int WM_OPENHTWJ = 0x7777;
    public const int WM_OPENPROJ = 0x6666;
    public const int WM_CLOSEPROJ = 0x5555;
    public const int WM_REFRESHPROJ = 0x5511;
    public const int WM_DELENTITY = 0x4444;
    public const int WM_SHOWENTTIY = 0x4443;
    public const int WM_GETCGT = 0x3339;
    public const int WM_CGTEND = 0x3338;
    public const int WM_STRSTR = 0x3333;
    public const int WM_USER = 0x0400;
    public const int WM_UNDO = 0x2229;


    public const uint GW_CHILD = 5;
    public const int GWL_WNDPROC = -4;

    public struct SELFDEFINfO
    {
        public int nInt;
        public string strCon;
        public string objName;
        public object obj;
    }

    #endregion

    #region 消息循环
    [DllImport("user32", EntryPoint = "DispatchMessage")]
    public static extern int DispatchMessage(ref tagMSG lpMsg);



    [DllImport("user32", EntryPoint = "GetMessage")]
    public static extern int GetMessage(
            out tagMSG lpMsg,
            int hwnd,
            int wMsgFilterMin,
            int wMsgFilterMax
    );

    [DllImport("user32", EntryPoint = "TranslateMessage")]
    public static extern int TranslateMessage(ref tagMSG lpMsg);

    #endregion

    #region  WinAPI定义
    [DllImport("user32.dll", EntryPoint = "SendMessageA")]
    public static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
    [DllImport("User32.dll", EntryPoint = "FindWindow")]
    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    [DllImport("User32.dll ")]
    public static extern bool ShowWindow(IntPtr hWnd, int cmdShow);
    [DllImport("User32.dll ", EntryPoint = "SetParent")]
    public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);


    [DllImport("user32", EntryPoint = "DispatchMessage")]
    public static extern int DispatchMessage(ref Message lpMsg);



    [DllImport("user32", EntryPoint = "GetMessage")]
    public static extern int GetMessage(
            out Message lpMsg,
            int hwnd,
            int wMsgFilterMin,
            int wMsgFilterMax
    );

    [DllImport("user32", EntryPoint = "TranslateMessage")]
    public static extern int TranslateMessage(ref Message lpMsg);

    /// <summary>
    /// 设置窗口显示图标
    /// </summary>
    /// <param name="hInst"></param>
    /// <param name="lpsz"></param>
    /// <param name="un1"></param>
    /// <param name="n1"></param>
    /// <param name="n2"></param>
    /// <param name="un2"></param>
    /// <returns></returns>
    [DllImport("user32", EntryPoint = "LoadImage")]
    public static extern int LoadImageA(int hInst, string lpsz, int un1, int n1, int n2, int un2);
    [DllImport("User32.dll", EntryPoint = "SendMessage")]
    public static extern int SendMessage(
        int hWnd, // handle to destination window 
        int Msg, // message 
        int wParam, // first message parameter 
        int lParam // second message parameter 
    );

    [DllImport("User32.dll", EntryPoint = "PostMessage")]
    public static extern int PostMessage(
        int hWnd, // handle to destination window 
        int Msg, // message 
        int wParam, // first message parameter 
        int lParam // second message parameter 
    );

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern int PostMessage(int hwnd, int msg, int wparam, IntPtr lParam);


    [DllImport("user32.dll", SetLastError = true)]
    public static extern bool PostThreadMessage(int threadId, uint msg, IntPtr wParam, IntPtr lParam);
    /// <summary>
    /// 向句柄发送消息(消息内容位对象)
    /// </summary>
    /// <param name="hwnd">句柄</param>
    /// <param name="msg">消息类型</param>
    /// <param name="wparam">参数</param>
    /// <param name="lParam">传递对象</param>
    /// 使用实例:WinAPIHelper.SELFDEFINfO INFO = new WinAPIHelper.SELFDEFINfO();
    ///           INFO.nInt = 5;
    ///           INFO.strCon = "1234";
    ///           INFO.obj = BussParaHelper._Chdata;
    ///           WinAPIHelper.PostMessage(BussParaHelper._ProjDetailView.GetHandle(), WinAPIHelper.WM_USER, 0, INFO);
    /// <returns></returns>
    public static int PostMessage(int hwnd, int msg, int wparam, object lParam)
    {
        System.Runtime.InteropServices.GCHandle h = System.Runtime.InteropServices.GCHandle.Alloc(lParam, System.Runtime.InteropServices.GCHandleType.WeakTrackResurrection);
        System.IntPtr addr = System.Runtime.InteropServices.GCHandle.ToIntPtr(h);

        return PostMessage(hwnd, msg, wparam, addr);
    }

    /// <summary>
    /// 根据消息获取实体
    /// </summary>
    /// <param name="msg">收到的消息</param>
    /// 使用实例: var obj23 = (WinAPIHelper.SELFDEFINfO)WinAPIHelper.GetObjectByMsg(m);
    ///            CHData jjj1 = obj23.obj as CHData; 
    /// <returns></returns>
    public static object GetObjectByMsg(Message msg)
    {
        System.Runtime.InteropServices.GCHandle handle2 = System.Runtime.InteropServices.GCHandle.FromIntPtr(msg.LParam);
        if (handle2 == null)
            return null;
        return handle2.Target;
    }

    [DllImport("user32.dll", EntryPoint = "SendMessageA")]
    public static extern int SendMessageA(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

    /// <summary>
    /// 设置窗口显示文本
    /// </summary>
    /// <param name="hwnd"></param>
    /// <param name="lpString"></param>
    /// <returns></returns>
    [DllImport("user32", EntryPoint = "SetWindowText")]
    public static extern int SetWindowTextA(int hwnd, string lpString);
    #endregion

    /// <summary>
    /// 如果函数执行成功,返回值不为0。
    /// 如果函数执行失败,返回值为0。要得到扩展错误信息,调用GetLastError。
    /// </summary>
    /// <param name="hWnd">要定义热键的窗口的句柄</param>
    /// <param name="id">定义热键ID(不能与其它ID重复)</param>
    /// <param name="fsModifiers">标识热键是否在按Alt、Ctrl、Shift、Windows等键时才会生效</param>
    /// <param name="vk">定义热键的内容</param>
    /// <returns></returns>
    [DllImport("user32.dll", SetLastError = true)]
    public static extern bool RegisterHotKey(
        IntPtr hWnd,                //要定义热键的窗口的句柄
        int id,                     //定义热键ID(不能与其它ID重复)           
        KeyModifiers fsModifiers,   //标识热键是否在按Alt、Ctrl、Shift、Windows等键时才会生效
        Keys vk                     //定义热键的内容
        );
    /// <summary>
    /// 取消注册
    /// </summary>
    /// <param name="hWnd">要取消热键的窗口的句柄</param>
    /// <param name="id">要取消热键的ID</param>
    /// <returns></returns>
    [DllImport("user32.dll", SetLastError = true)]
    public static extern bool UnregisterHotKey(
        IntPtr hWnd,                //要取消热键的窗口的句柄
        int id                      //要取消热键的ID
    );

    //强制释放进程
    [DllImport("kernel32.dll", EntryPoint = "SetProcessWorkingSetSize")]
    public static extern int SetProcessWorkingSetSize(IntPtr process, int minSize, int maxSize);

    [DllImport("user32", EntryPoint = "HideCaret")]
    public static extern bool HideCaret(IntPtr hWnd);

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
    [System.Runtime.InteropServices.DllImport("User32.dll")]
    public static extern IntPtr CallWindowProc(IntPtr lpPrevWndFunc,
    IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);

    [DllImport("psapi.dll")]
    public static extern int EmptyWorkingSet(IntPtr hwProc);
    /// <summary>
    /// 定义了辅助键的名称(将数字转变为字符以便于记忆,也可去除此枚举而直接使用数值)
    /// </summary>
    [Flags]
    public enum KeyModifiers
    {
        None = 0,
        Alt = 1,
        Ctrl = 2,
        Shift = 4,
        WindowsKey = 8
    }

}

本文会经常更新,请阅读原文: https://dashenxian.github.io/post/Windows-Form%E5%AE%9A%E4%B9%89%E5%BF%AB%E6%8D%B7%E9%94%AE ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

知识共享许可协议

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 小神仙 (包含链接: https://dashenxian.github.io ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 (125880321@qq.com)

登录 GitHub 账号进行评论