【问题标题】:Open form in separate thread, and keep it on top of other windows in the application在单独的线程中打开表单,并将其保持在应用程序中其他窗口的顶部
【发布时间】:2018-02-02 13:39:35
【问题描述】:

关于这个问题的另一个问题。相信我已经彻底调查过,但仍然没有找到适合我的应用的解决方案。

简介: 我的应用程序由一个主表单和几个表单组成,它们在需要时显示为模态。 然后我有一个“屏幕转储”表单,它是一个带有按钮的小表单。按下此按钮时,屏幕会转储屏幕。

以上所有的表单都是通过在主表单上按相应的按钮来显示的。

我想要什么: 显示时,屏幕转储表单应始终位于我的应用程序的所有其他窗口(也显示为 ShowModal() 的窗口)的顶部。如果这自动意味着在所有其他程序之上也是可以接受的。

我尝试过的: 我很确定我必须在单独的线程中打开表单,以便即使在其他表单显示为模态时也能保持它的可操作性。 这个我试过如下:

private void btnScreenDump_MouseDown(object sender, MouseEventArgs e)
        {
            Thread thread = new Thread(ThreadProc);
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();
        }

private void ThreadProc()
        {
            using (FormScreenDump frmScreenDump1 = new FormScreenDump())
            {
                frmScreenDump1.TopMost = true;                  
                Application.Run(frmScreenDump1);
            }                
        }

有什么问题/疑问? 问题一: frmScreenDump1 形式根本不是最顶层的。每当在我的应用程序中单击任何其他表单时,表单 frmScreenDump1 都会位于应用程序后面。 为什么当 frmScreenDump1.TopMost = true; 时表单不在最顶层,我必须更改什么才能获得这种行为?

问题 2: 我希望窗体 frmScreenDump1 在主窗体关闭时自动关闭。当这个表单在单独的线程上运行时,我应该怎么做?

非常感谢任何帮助!

【问题讨论】:

    标签: c# multithreading winforms


    【解决方案1】:

    您不应在其他线程中打开表单。所有与 UI 相关的代码(和对象)必须在 UI 线程上,否则可能会发生意想不到的事情。这可能就是为什么您的表单不是最顶层的原因,即使您已将其设置为最顶层。

    如果您想在保持此表单处于活动状态的同时将其他表单显示为模态,则不要将其他表单显示为模态。而是让每个新表单在打开/关闭时更改父/所有者表单的 Enabled 属性。

    或者,将您的表单放在单独的应用程序中,并将其作为主应用程序的新进程启动。

    【讨论】:

    • 屏幕转储功能应该也可以进行屏幕转储,例如消息框,始终显示为模态。
    • @JohnSaps :那你最好把FormScreenDump放到另一个进程中(或者做一个自定义的消息框形式)。如果您愿意,您可以在辅助线程中显示 Windows 的消息框。
    • 当你建议将FormScreenDump放在另一个进程中时,你的意思是为这个小功能创建一个完全独立的应用程序,然后从我的主应用程序启动.exe?
    • @JohnSaps:是的。即使它很小,也能满足您的需要。
    • 好的,非常感谢。我应该如何接受这个作为答案??
    【解决方案2】:

    Form.TopMost,根据其他 TopMost 相关问题的用户的说法,它适用于应用程序内的所有表单,但您有两个应用程序 [这是错误的,我看错了]。

    因此,您正在构建一个屏幕截图功能,如果表单作为对话框打开,该功能应该可以工作。这就是新表单的线程和额外应用程序的原因。我曾经有过同样的要求,我通过让我的屏幕截图功能不对它自己的点击事件做出反应来解决它,而是我使用鼠标钩来跟踪用户何时点击按钮所在的位置。警告:在 VS 调试模式下启动应用时,鼠标钩子会导致严重滞后。

    【讨论】:

    • 我只有一个应用程序,但不止一个线程。屏幕转储功能只是一个单独的表单,我在单独的线程中开始。
    • mouse-hooks are leading to heavy lagging when starting the app in VS debug mode - 我以前从未遇到过这样的问题...您确定您使用的代码是正确的吗?
    • 虽然我正在从鼠标钩子中引发事件,但这可能足以减慢速度,以免发生延迟(因为它很可能发生,因为在移动鼠标时会非常频繁地调用回调) . -- 我的实现(在 VB.NET 中,但可以在“Releases”下找到已编译的 DLL):github.com/Visual-Vincent/InputHelper
    • 啊,好吧,我明白你的意思了。我不会称其为 heavy 滞后,但它绝对滞后。对我来说并没有那么多,因为它只在你遇到断点时才会发生(可能是因为 VS 正在处理中断代码),我觉得这不是很麻烦。
    • 钩子在那之后不再起作用,所以我认为它被 VS 或操作系统处理为无法正常工作。
    猜你喜欢
    • 1970-01-01
    • 2013-12-26
    • 2019-03-04
    • 1970-01-01
    • 1970-01-01
    • 2011-01-27
    • 2017-06-17
    • 2018-04-17
    • 2010-10-27
    相关资源
    最近更新 更多