Windows7においてのメッセージボックスの強制終了
- 題名: Windows7においてのメッセージボックスの強制終了
- 著者: ぱんだこぱんだ
- 日時: 2010/11/30 16:02:50
- ID: 27725
- この記事の返信元:
- この記事への返信:
- ツリーを表示
- 題名: Re[1]: Windows7においてのメッセージボックスの強制終了
- 著者: Azulean
- 日時: 2010/11/30 23:07:37
- ID: 27727
- この記事の返信元:
- この記事への返信:
- ツリーを表示
- 題名: Re[2]: Windows7においてのメッセージボックスの強制終了
- 著者: ぱんだこぱんだ
- 日時: 2010/12/01 12:18:43
- ID: 27732
- この記事の返信元:
- この記事への返信:
- ツリーを表示
- 題名: Re[3]: Windows7においてのメッセージボックスの強制終了
- 著者: 魔界の仮面弁士
- 日時: 2010/12/01 12:43:06
- ID: 27733
- この記事の返信元:
- この記事への返信:
- ツリーを表示
- 題名: Re[3]: Windows7においてのメッセージボックスの強制終了
- 著者: Azulean
- 日時: 2010/12/01 22:40:00
- ID: 27740
- この記事の返信元:
- この記事への返信:
- ツリーを表示
- 題名: Re[4]: Windows7においてのメッセージボックスの強制終了
- 著者: ぱんだこぱんだ
- 日時: 2010/12/02 13:47:27
- ID: 27747
- この記事の返信元:
- この記事への返信:
- ツリーを表示
分類:[.NET]
いつもお世話になっております。
http://www.divakk.co.jp/blog/aoyagi/archive/2004/09/22/591.aspx
上記サイトを参考に保存ダイアログを強制的に10秒後に閉じる、というのを作りました。
しかし、Windows7において、保存ダイアログで既存のファイルに上書きする場合に、確認メッセージが表示され、
その確認メッセージを表示したまま10秒が経過すると、確認メッセージが消えずに残ってしまう という現象が発生しました。
Windows XPでは確認メッセージも一緒に強制的に閉じるようです。
Windows7においても、上書き確認メッセージごと強制的に閉じるようにするには、どうしたらよいのでしょうか?
どうぞよろしくお願い致します。
*************************************************************************
// 使い方:TimeoutDialog.ShowDialog();
using System;
using System.Collections.Generic;
using System.Collections;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;
using System.Text;
using System.Diagnostics;
public class TimeoutDialog
{
[DllImport("kernel32.dll")]
private static extern uint GetCurrentThreadId();
private delegate int EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
[DllImport("user32.dll")]
private static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
[DllImport("user32.dll", SetLastError = true)]
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
[DllImport("user32.dll")]
private static extern int GetClassName(IntPtr hWnd, [Out] StringBuilder lpClassName, int nMaxCount);
[DllImport("user32.dll")]
private static extern bool IsWindowEnabled(IntPtr hWnd);
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool PostMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
/// <summary>
/// 別スレッドでタイムアウトを監視するためのクラスです。
/// </summary>
private class TimerThread
{
private DateTime timeoutTime;
private uint currentThreadId;
private bool terminateFlag;
private Thread thread;
/// <summary>
/// コンストラクタです。
/// メッセージボックスのタイムアウト監視を開始します。
/// </summary>
/// <param name="timeoutMillisec">タイムアウト値(ミリ秒)。</param>
public TimerThread(int timeoutMillisec)
{
this.timeoutTime = DateTime.Now.AddMilliseconds(timeoutMillisec);
this.currentThreadId = GetCurrentThreadId();
this.terminateFlag = false;
this.thread = new Thread(new ThreadStart(this.ThreadProc));
this.thread.Start();
}
/// <summary>
/// スレッド関数です。
/// </summary>
private void ThreadProc()
{
while (!this.terminateFlag)
{
Thread.Sleep(100);
if (DateTime.Now > this.timeoutTime)
{
// タイムアウトが発生
// EnumWindows API を使ってメッセージボックスウインドウを探す
EnumWindows(new EnumWindowsProc(this.EnumWindowsProc), new IntPtr(0));
return;
}
}
}
/// <summary>
/// メッセージボックスウインドウを探して、見つかった場合は閉じます。
/// </summary>
/// <param name="hWnd"></param>
/// <param name="lParam"></param>
/// <returns></returns>
private int EnumWindowsProc(IntPtr hWnd, IntPtr lParam)
{
uint processId;
uint threadId;
threadId = GetWindowThreadProcessId(hWnd, out processId);
if (processId == Process.GetCurrentProcess().Id)
{
StringBuilder className = new StringBuilder("", 256);
GetClassName(hWnd, className, 256);
// メッセージボックスを閉じる
if (className.ToString() == "#32770")
{
const int WM_COMMAND = 0x111;
PostMessage(hWnd, WM_COMMAND, new IntPtr(2), new IntPtr(0)); // キャンセルボタン
PostMessage(hWnd, WM_COMMAND, new IntPtr(7), new IntPtr(0)); // Noボタン
return 1;
}
}
return 1;
}
/// <summary>
/// タイムアウト監視用スレッドを終了させます。
/// </summary>
public void Terminate()
{
this.terminateFlag = true;
this.thread.Join();
}
}
/// <summary>
/// 保存ダイアログを表示します。
/// </summary>
/// <returns><see cref="DialogResult"/></returns>
public static DialogResult ShowDialog()
{
TimerThread tt = new TimerThread(10000); // 10秒後に、保存ダイアログを強制的に閉じる
try
{
SaveFileDialog saveFileDialog1 = new SaveFileDialog();
saveFileDialog1.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
return saveFileDialog1.ShowDialog();
}
finally
{
tt.Terminate();
}
}
}
************************************************************************