gpt4 book ai didi

C# - 等待 WinForms 消息循环

转载 作者:太空狗 更新时间:2023-10-29 23:02:21 26 4
gpt4 key购买 nike

我必须编写一个 C# API 来注册全局热键。为了接收 WM_HOTKEY 消息,我使用 System.Windows.Forms.NativeWindow 并使用 System.Windows.Forms.Application.Run(ApplicationContext) 运行自己的消息循环。当用户想要注册热键时,他必须运行一个名为 RegisterHotkey() 的方法,该方法使用 System.Windows.Forms.ApplicationContext.ExitThread() 停止消息循环, 使用 RegisterHotKey() (P/Invoke) 函数注册热键并再次启动消息循环。这是必需的,因为 RegisterHotKey() 必须在创建窗口的同一个线程中调用,它必须再次在运行消息循环的同一个线程中实例化。

问题是,如果用户在启动运行消息循环的线程后不久调用 RegisterHotkey() 方法,则会调用 ApplicationContext.ExitThread()Application.Run(ApplicationContext) 之前,因此应用程序会无限期地阻塞。有人知道等待消息循环开始的方法吗?

提前致谢!

最佳答案

因此 RegisterHotKey 需要从创建窗口和启动消息循环的同一个线程调用。为什么不将 RegisterHotKey 的执行注入(inject)到您的自定义消息循环线程中?这样您就不需要停止并重新启动消息循环。您可以重用您开始的第一个,同时避免奇怪的竞争条件。

您可以使用 ISynchronizeInvoke.Invoke 将委托(delegate)注入(inject)另一个线程,这会将委托(delegate)编码到托管 ISynchronizeInvoke 实例的线程。以下是它可能如何完成。

void Main()
{
var f = new Form();

// Start your custom message loop here.
new Thread(
() =>
{
var nw = NativeWindow.FromHandle(f.Handle);
Application.Run(new ApplicationContext(f));
}

// This can be called from any thread.
f.Invoke(
(Action)(() =>
{
RegisterHotKey(/*...*/);
}), null);
}

我不知道...也许您还想调用 UnregisterHotKey,具体取决于您所追求的行为。我不太熟悉这些 API,因此无法评论它们的使用方式。

如果您不想创建任意 Form 实例,那么您可以通过 SendMessage 等向线程提交自定义消息并在NativeWindow.WndProc 以获得与 ISynchronizeInvoke 方法自动提供的效果相同的效果。

关于C# - 等待 WinForms 消息循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7392598/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com