- 浏览: 119530 次
文章分类
最新评论
C#:从外部强制关闭用ShowDialog方法打开的模态窗口
在写C#程序时,一般我们不需要从外部强行关闭用ShowDialog方法打开的模态窗口。但在实际工作中,我遇到了一个非常坑爹的场景,需要在控制一个客户端程序锁屏前强制关闭由客户端程序打开的“打开”、“另存为”等窗口。因为这几个窗口是三方库打开的,我只能自己找方法手动关闭这几个窗口。
后来在网上找了一些资料,发现如下方法可以从外部关闭其他方法使用ShowDialog打开的模态窗口:
1、使用DllImport加载函数FindWindow和PostMessage
[DllImport("user32.dll")]
private static extern IntPtr FindWindow(string a, string b);
[DllImport("user32.dll")]
private static extern IntPtr PostMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
2、使用下面方法关闭标题为指定文字窗口(需要将“窗体标题”替换为要关闭的窗体的标题)
IntPtr ptr1 = FindWindow(null, "窗体标题");
if (ptr1 != IntPtr.Zero)
{
PostMessage(ptr1, 0x0010, IntPtr.Zero, IntPtr.Zero);
}
需要注意的是:
1、PostMessage函数执行后,指定要关闭的窗口并不会被立即关闭,而是有一个极短时间的延迟,所以若想在PostMessage函数调用后进行其他操作(如锁屏操作),建议先让程序Sleep约0.5秒的时间。
2、我做的用于输入密码的解锁窗体,在使用此方法关闭了指定模态窗口后虽然可以弹出,但并没有弹出到界面的最前面。此时需要在程序的其他部位点一下鼠标,解锁窗体才会蹦到前面来。于是我想了一个办法,使用SwitchToThisWindow方法将解锁窗体在Load函数执行完毕0.2秒后强制放到界面最前。
函数声明:
/// <summary>
/// 将窗体调整至界面最前
/// </summary>
/// <param name="hWnd"></param>
/// <param name="fAltTab"></param>
/// <returns></returns>
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool SwitchToThisWindow(IntPtr hWnd, bool fAltTab);
/// <summary>
/// 定时器,本窗口打开后,如未到界面最前,则在指定时间后强制调到界面最前 liwh - 20161215
/// </summary>
System.Windows.Forms.Timer timerSwitchToThisWindow = new System.Windows.Forms.Timer();
Load函数的末尾添加下面这句话:
//2秒后将窗体调整至界面最前 liwh - 20161215
timerSwitchToThisWindow.Tick += (obj, arg) =>
{
SwitchToThisWindow(this.Handle, true);
timerSwitchToThisWindow.Stop();
};
timerSwitchToThisWindow.Interval = 2000;
timerSwitchToThisWindow.Start();
下面放一个例子,我写了一个DEMO程序,测试此函数
界面上含有8个Button和1个TextBox用于输出文字
本DEMO程序针对ColorDialog、FolderBrowserDialog、FontDialog、OpenFileDialog、SaveFileDialog、MessageBox、使用Show方法打开的自定义窗体、使用ShowDialog方法打开的自定义窗体八种情况分别做了测试。点击8个按钮分别打开这八类窗体,有一个Timer每5秒检查一下这些窗口,如检测到这些窗口被打开了就关闭它们。
代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
namespace CloseDialogTest
{
public partial class FormMain : Form
{
[DllImport("user32.dll")]
private static extern IntPtr FindWindow(string a, string b);
[DllImport("user32.dll")]
private static extern IntPtr PostMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
public FormMain()
{
InitializeComponent();
}
/// <summary>
/// Load函数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FormMain_Load(object sender, EventArgs e)
{
Timer timer = new Timer();
timer.Tick += (obj, arg) =>
{
//1、尝试关闭ColorDialog
IntPtr ptr1 = FindWindow(null, "颜色");
if (ptr1 != IntPtr.Zero)
{
PostMessage(ptr1, 0x0010, IntPtr.Zero, IntPtr.Zero);
SetInfoBar("ColorDialog已关闭");
}
//2、尝试关闭FolderBrowserDialog
IntPtr ptr2 = FindWindow(null, "浏览文件夹");
if (ptr2 != IntPtr.Zero)
{
PostMessage(ptr2, 0x0010, IntPtr.Zero, IntPtr.Zero);
SetInfoBar("FolderBrowserDialog已关闭");
}
//3、尝试关闭FontDialog
IntPtr ptr3 = FindWindow(null, "字体");
if (ptr3 != IntPtr.Zero)
{
PostMessage(ptr3, 0x0010, IntPtr.Zero, IntPtr.Zero);
SetInfoBar("FontDialog已关闭");
}
//4、尝试关闭OpenFileDialog
IntPtr ptr4 = FindWindow(null, "打开");
if (ptr4 != IntPtr.Zero)
{
PostMessage(ptr4, 0x0010, IntPtr.Zero, IntPtr.Zero);
SetInfoBar("OpenFileDialog已关闭");
}
//5、尝试关闭SaveFileDialog
IntPtr ptr5 = FindWindow(null, "另存为");
if (ptr5 != IntPtr.Zero)
{
PostMessage(ptr5, 0x0010, IntPtr.Zero, IntPtr.Zero);
SetInfoBar("SaveFileDialog已关闭");
}
//6、尝试关闭MessageBox
IntPtr ptr6 = FindWindow(null, "测试消息");
if (ptr6 != IntPtr.Zero)
{
PostMessage(ptr6, 0x0010, IntPtr.Zero, IntPtr.Zero);
SetInfoBar("MessageBox已关闭");
}
//7、尝试关闭自定义窗口(Show)
IntPtr ptr7 = FindWindow(null, "自定义窗口(Show)");
if (ptr7 != IntPtr.Zero)
{
PostMessage(ptr7, 0x0010, IntPtr.Zero, IntPtr.Zero);
SetInfoBar("自定义窗口(Show)已关闭");
}
//8、尝试关闭自定义窗口(ShowDialog)
IntPtr ptr8 = FindWindow(null, "自定义窗口(ShowDialog)");
if (ptr8 != IntPtr.Zero)
{
PostMessage(ptr8, 0x0010, IntPtr.Zero, IntPtr.Zero);
SetInfoBar("自定义窗口(ShowDialog)已关闭");
}
};
timer.Interval = 5000;
timer.Enabled = true;
timer.Start();
}
/// <summary>
/// 1、打开ColorDialog
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnOpenColorDialg_Click(object sender, EventArgs e)
{
ColorDialog colorDialog = new ColorDialog();
if (colorDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
Color selectedColor = colorDialog.Color;
SetInfoBar("你选择了颜色:" + selectedColor.ToString());
}
}
/// <summary>
/// 2、打开FolderBrowserDialog
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnOpenFolderBrowserDialog_Click(object sender, EventArgs e)
{
FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
if (folderBrowserDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string selectedPath = folderBrowserDialog.SelectedPath;
SetInfoBar("你选择了目录:" + selectedPath);
}
}
/// <summary>
/// 3、打开FontDialog
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnOpenFontDialog_Click(object sender, EventArgs e)
{
FontDialog fontDialog = new FontDialog();
if (fontDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
Font selectedFont = fontDialog.Font;
SetInfoBar("你选择了字体:" + selectedFont);
}
}
/// <summary>
/// 4、打开OpenFileDialog
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnOpenOpenFileDialog_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string selectedFile = openFileDialog.FileName;
SetInfoBar("你选择了文件:" + selectedFile);
}
}
/// <summary>
/// 5、打开SaveFileDialog
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnOpenSaveFileDialog_Click(object sender, EventArgs e)
{
SaveFileDialog saveFileDialog = new SaveFileDialog();
if (saveFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string selectedPath = saveFileDialog.FileName;
SetInfoBar("你选择了路径:" + selectedPath);
}
}
/// <summary>
/// 6、打开MessageBox
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnOpenMessageBox_Click(object sender, EventArgs e)
{
MessageBox.Show("测试消息内容", "测试消息");
}
/// <summary>
/// 7、通过Show打开自定义窗口
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnOpenCustomWindowByShow_Click(object sender, EventArgs e)
{
//CustomForm构造函数接收的参数决定了该窗体的标题
CustomForm costumForm = new CustomForm("自定义窗口(Show)");
costumForm.Show();
}
/// <summary>
/// 8、通过ShowDialog打开自定义窗口
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnOpenCustomWindowByShowDialog_Click(object sender, EventArgs e)
{
//CustomForm构造函数接收的参数决定了该窗体的标题
CustomForm costumForm = new CustomForm("自定义窗口(ShowDialog)");
costumForm.ShowDialog();
}
/// <summary>
/// 在文本框内显示指定文字
/// </summary>
/// <param name="info"></param>
private void SetInfoBar(string info)
{
this.txtInfoBar.Text = info;
}
}
}
这个DEMO程序需要使用VS2012以上版本打开,可在此位置下载到:
https://pan.baidu.com/s/1gfhx0P1
END
转载于:https://my.oschina.net/Tsybius2014/blog/817910
相关推荐
而`ShowDialog()`方法打开一个模态窗体,直到该窗体关闭,用户无法与父窗体或其他子窗体交互。 要实现非模态窗体像模态窗体那样工作,我们可以采用以下策略: 1. **禁用父窗体**:在打开子窗体之前,先禁用父窗体...
在父窗口中,我们可以通过`ShowDialog()`方法打开子窗口。`ShowDialog()`会阻塞父窗口的执行,直到子窗口关闭。我们可以检查`DialogResult`属性来判断用户是确认还是取消了操作: ```csharp private void ...
### 使用C#打开新窗口并关闭旧窗口的方法 在C#开发中,特别是在Windows Forms应用程序中,有时我们需要在用户执行某些操作后打开一个新的窗口(Form),同时关闭当前窗口。这种需求常见于登录验证、切换视图等场景...
在C# WinForm应用开发中,经常会遇到需要管理和关闭多个打开窗口的情况。本文将深入探讨如何在C#环境下实现WinForm窗口的关闭操作,以及如何关闭所有已打开的窗口。 首先,我们需要理解C# WinForm窗口(Form)的...
这个方法用于以模态对话框的形式显示一个窗体,即用户必须先关闭该对话框才能与父窗体或其他窗口进行交互。在本教程中,我们将深入探讨如何使用`ShowDialog()`实现简单、无代码的关闭和退回操作。 `ShowDialog()`的...
模态窗体强制用户与该窗体进行交互,直到完成或关闭该窗体后才能继续操作主窗体,而非模态窗体则允许用户在打开新窗体的同时,仍可与主窗体或其他窗口进行交互。本教程将重点讲解如何使用非模态窗体`Show`方法来模拟...
在C#中,我们通常使用`ShowDialog()`方法来显示模态窗口。例如: ```csharp Form2 modalForm = new Form2(); // 创建模态窗口实例 modalForm.ShowDialog(); // 显示模态窗口 ``` 非模态窗口则不同,它允许用户同时...
通过`ShowDialog`方法,我们可以实现一个模态对话框,该对话框在关闭前会阻止程序的其他部分继续运行,确保用户在完成操作(如输入信息)后才继续执行后续代码。本文将深入探讨如何使用`ShowDialog`方法以及如何在子...
在WPF中,`Window.ShowDialog()`方法用于打开一个模态窗口,这意味着用户必须先关闭该窗口才能继续与父窗口进行交互。然而,由于MVVM模式中ViewModel不直接操作View,因此不能直接调用`ShowDialog()`。我们需要找到...
在C#编程中,控制模态子窗体中的进度条是一项常见的需求,特别是在进行耗时操作时,为了提供用户友好的界面,我们需要显示一个带有进度条的子窗口,让用户了解后台任务的执行进度。然而,由于模态窗体(Modal Form)...
当模态窗口打开时,用户必须先关闭该窗口才能继续操作主窗口。这在需要用户做出决定或输入信息的情况下非常常见,例如弹出的对话框。在VS2015中,可以使用C++ MFC(Microsoft Foundation Classes)或者C# WPF...
`Form.ShowDialog`方法会在当前线程中打开一个模态对话框,阻止用户与父窗口或其他窗体交互,直到该对话框关闭。为了在非主线程中显示窗体并使其置顶,你需要确保在正确的线程上执行`ShowDialog`,因为窗体必须在其...
模态窗口会阻止用户与父窗口或其他窗口进行交互,直到该窗口关闭。在这个窗口中,我们可以添加一个`ProgressBar`控件来展示任务的进度。 以下是一个简单的示例代码: ```csharp using System; using System....
在父窗口中,我们可以使用`ShowDialog`方法来打开子窗口。这个方法会阻塞父窗口,直到子窗口关闭。例如: ```csharp ChildWindow child = new ChildWindow(); child.ShowDialog(); ``` 3. 传递数据: - 值...
为了实现登录成功后的窗体切换,可以使用`Show()`或`ShowDialog()`方法打开Form2,并使用`Close()`方法关闭Form1。假设我们有文本框txtUsername和txtPassword,以及用于存储正确用户名和密码的全局变量: ```csharp...
4. **适当使用Show()和Hide()方法**:在打开新窗口时,使用`Show()`方法而不是`ShowDialog()`,因为`ShowDialog()`会阻塞父窗口,直到子窗口关闭。而`Show()`方法允许子窗口和主窗口同时存在,可以实现更灵活的切换...
`ShowDialog()`方法会阻塞父窗口直到用户关闭模态窗口,并返回一个`DialogResult`枚举值,你可以根据这个值判断用户是如何关闭窗口的。 ### 创建非模态窗口 非模态窗口则使用`Show()`方法来显示。例如: ```csharp...
在C# Winform应用程序开发中,常常需要在不同的窗体之间传递数据,以便实现各功能模块之间的交互。这里我们将详细探讨两种主要的传值方法:通过构造函数传值和通过属性传值。 首先,我们来看**通过构造函数传值**的...
在C#编程环境中,开发图形用户界面(GUI)应用程序时,常常需要处理图像显示功能。`PictureBox`控件是Windows Forms库中一个非常实用的组件,用于在窗口中展示图片。本篇将深入探讨如何利用C#和`PictureBox`控件来...
3. **ShowDialog方法**:在C#中,使用`ShowDialog`方法可以以模态方式打开子窗口,这意味着用户必须先关闭子窗口才能返回到父窗口。这是一种常见的父子窗口交互方式。 4. **控件的通信**:子窗口和父窗口之间可以...