And*_*ker 5 c# winapi hotkeys winforms
我试图在系统托盘中放置一个图标,然后给它一个全局键盘快捷键来执行一个功能.
我正在使用RegisterHotKey设置全局键盘快捷键,如果与该图标关联的主窗体可见,则它可以正常工作.但是如果表单不可见,那么永远不会调用WndProc方法.
有任何想法吗?
编辑:我的意思是"隐藏"是将以下内容添加到主窗体:
protected override void OnLoad(EventArgs e)
{
hotKey = new GlobalHotkey(GlobalHotkey.WIN, Keys.T, this);
bool registered = hotKey.Register();
Visible = false;
ShowInTaskbar = false;
base.OnLoad(e);
}
Run Code Online (Sandbox Code Playgroud)
"registered"显示为"true",如果我忽略"Visible = false",快捷键可以正常工作 和"ShowInTaskbar = false;".
问题是将ShowInTaskbar设置为false会更改窗口句柄,这意味着传递给RegisterHotkey的hwnd不再有效.
设置ShowInTaskBar 后注册热键可以正常工作.
Winforms 绕过了 winapi 中相当严格的限制。窗口的某些属性只能在创建窗口时指定,以后无法更改。或者换句话说,它们是在本机 CreateWindowEx() 调用中指定的。
它通过再次调用 CreateWindowEx() 来解决这个问题。或者换句话说,销毁现有窗口并重新创建它。这是一个绝妙的技巧,但它确实有一些副作用。例如,当新窗口自行绘制时,您可以看到一点点闪烁。一些更大的副作用在例如 TreeView 上是可见的。重新创建时所有节点都会崩溃。很难避免的是,与原始窗口相关的状态太多了。对于 Form,ShowInTaskbar 属性就是这样的属性之一。还有 RightToLeft、FormBorderStyle、ControlBox 等。
最相关的副作用就是您遇到的副作用。重新创建窗口总是不可避免地会更改 Handle 属性。当您使用 RegisterHotKey() 或使用它的库时,winapi 调用使用窗口句柄时,就会出现问题。因此,当 Winforms 销毁该窗口时,将永远不会再有回调。
这很容易修复,您只是使用了错误的事件处理程序。相反,在方法的重写中进行调用OnHandleCreated。重新创建窗口时它会重新运行。另一个简单的修复方法是仅在构造函数中设置 ShowInTaskbar 等属性,但不太可靠。
| 归档时间: |
|
| 查看次数: |
1557 次 |
| 最近记录: |