【发布时间】:2010-09-26 03:13:59
【问题描述】:
我正在尝试为我用 C# 编写的应用程序编写专门的屏幕键盘 (OSK)。为此,我创建了一个表单,上面有几个代表键的按钮,单击它们会调用SendKeys 并发送相应的键。
此表单归应用程序首次启动时显示的主窗口所有,使用Owner 属性。这样,每当用户聚焦应用程序时,OSK 就会弹出,如果主窗口被拖动到它上面,它就会停留在主窗口的顶部。
这一切都很好,但是因为我有模式对话框,我也想与 OSK 一起使用,我试图在一个单独的线程中创建它,完成它自己的消息循环(通过Application.Run)所以它仍然可以可用于主线程中的任何模式对话框。
问题在于,显然,由于跨线程调用,处于单独的线程中可能会导致InvalidOperationExceptions。这方面的一个具体示例是,当从新线程调用 Application.Run(osk) 时,会发生跨线程错误,因为它试图用所有者(主窗口)更新窗口句柄。
我的问题是,是否可以在与所有者分开的线程上以安全的方式拥有自有表单?而且,如果做不到这一点,是否可以模拟拥有的表单的特性(即仅在主窗口始终位于顶部,并在主窗口获得焦点时弹出)?
谢谢,如有混淆,请见谅。
【问题讨论】:
-
为什么要在单独的 UI 线程中使用模态对话框?似乎如果有多个 UI 线程,每个线程都应该有自己的 OSK。我不明白你为什么需要启动其他线程。
-
我创建的唯一单独线程是其中包含 OSK 的线程,因此它可以与需要文本输入的模式对话框一起使用。其他一切都在原始的主线程上。
-
您使用的是哪个操作系统(以防万一您使用的是 Mono)?这可能会产生影响。
标签: c# winforms multithreading