在可见之后将窗口设置为模态

时间:2010-10-14 14:47:28

标签: .net c++

是否可以在模态和非模态之后切换窗口?

这就是我需要的...调用一个传递窗口句柄的方法,并设置是否我想要它是模态的。

如果可能,任何样本都会有很大帮助!

.net,c ++等

谢谢!

编辑: 为什么? 在这种情况下,我使用TWAIN扫描图像,“一些”数据源不会将其对话框显示为模态,即使我将其设置为这样做,如果它不是模态,则用户可能会弄​​乱背景窗口...

4 个答案:

答案 0 :(得分:2)

窗口模态主要由窗口句柄所有权驱动。禁用父窗口并设置本地消息循环是次要工件。

将模态窗口句柄的所有者设置为应用程序主窗口会创建单击主窗口将焦点发送到模态子窗口的行为。如果没有正确设置所有者,主窗口可以在显示“模态”窗口时聚焦,这不是模态行为。

我似乎模糊地回忆起你还需要禁用所有者窗口,以防止鼠标点击按钮或在模态窗口处于活动状态时选择所有者窗口上的菜单。

模态窗口通常也与本地消息循环相关联,但这与窗口的模态UI行为以及与执行代码的模态状态有关的一切都没有关系。在Form.ShowDialog()中运行本地消息循环使函数调用与模态窗口生命周期同步 - 它阻止函数返回到调用者,直到模式窗口关闭。

在创建子窗口句柄时,设置窗口句柄的所有者只能是一个。子窗口句柄存在后,无法更改所有者。请参阅Owned Windows

上的MSDN

所以你不能简单地翻转开关并制作非模态窗口模态。

您最好的选择是销毁窗口手柄并使用所需的所有者重新创建窗口手柄。这可以在很少或没有屏幕闪烁的情况下完成,但更大的问题是保留窗口上的子控件的任何本地状态(编辑框中的文本,复选框状态等)。销毁窗口将丢失子窗口中的任何状态信息,因此您需要确保先提取所有状态,然后重新创建窗口句柄,然后恢复子窗口数据。

答案 1 :(得分:0)

你不能用标准的WinAPI做到这一点,我很确定你不能用.NET框架做到这一点。您可以通过创建自己的消息泵例程来伪造它,该例程在从非模态切换到模态时调用。 但是,听起来这是对错误问题的回答。你能澄清为什么需要它在模态和非模态之间切换吗?

答案 2 :(得分:0)

使用.NET Framework,我知道无法实现此类行为。在.NET中创建非模态或模态的表单的方法是分别通过Form.Show()Form.ShowDialog()方法显示它。

我没有得到这样的事实,你需要将它显示为非模态,然后使其成为模态。你想要完成什么?也许进一步的细节可以帮助我们找到另一种方法,这将推动你找到更好的解决方案,我希望。

答案 3 :(得分:0)

我想知道为什么OP问这个问题,但它让我思考。我有一些可能是寻找答案的开始。

我创建了两种形式:Form1和Form2。 Form1有一个按钮; Form2有一个文本框。

我为Form1尝试了以下代码:

    private void button_Click(object sender, EventArgs e)
    {
        form2.Show(this);            
        System.Threading.Thread thread = new System.Threading.Thread(showModal);
        thread.Start();
    }        

    private void showModal()
    {
        System.Threading.Thread.Sleep(2000);
        form2.Visible = false;
        form2.ShowDialog(this);
    }

单击Form1上的按钮时,它将Form2显示为非模态框;它等了两秒钟;然后它隐藏Form2然后将其显示为模式框。如果我在切换之前输入Form2的文本框,则会保留文本。但是,当我单击Form2右上角的x时,我无法关闭它。由于它是模态的,我必须通过任务管理器终止程序才能阻止它。