QA@IT
«回答へ戻る

MessageBoxButtons.YesNo などのケースで閉じない件に追記しました。

110
 
 ご覧のとおり、Win32 API を使用しています。
 ご提示の NativeWindow に関しては、私はわかりません。
+
+## 2013/07/10 追記
+
+正直、MessageBox 風のダイアログウィンドウを自作してしまったほうがいいのではないかとも思いますが、
+まぁそれぞれ事情はあろうかと思いますので…
+
+`MessageBoxButtons.YesNo` などのケースでメッセージボックスが閉じないとのことですが、
+`WM_CLOSE` の代わりに
+
+```
+        const int WM_NCDESTROY = 0x0082;
+```
+
+を送りつけるとどうでしょうか。
+
+私自身ウィンドウメッセージ等に関して精通しているわけではないので(^_^;)
+副作用等が生じないことは保証できませんが…

環境も不明ですし「不定のタイミング」というのがイマイチどういうことかわかりませんが…

仮に MessageBox を表示して一定時間経過後に自動的に閉じたい、ということであれば
以下のような感じでいかがでしょう。
(Visual Studio 2012 Pro & .Net Framework 4.0 で確認。)

using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll")]
        static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp); 

        const int WM_CLOSE = 0x10;


        private string caption = "テスト";
        private int limit = 5000; // msec.

        public Form1()
        {
            InitializeComponent();
        }


        private void button1_Click(object sender, EventArgs e)
        {
            using (var timer = new System.Threading.Timer(s =>
            {
                var hWnd = FindWindow(null, this.caption);
                if (hWnd != IntPtr.Zero)
                {
                    SendMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
                }
            }, null, this.limit, Timeout.Infinite))

            MessageBox.Show(this, "メッセージ", this.caption);
        }
    }
}

キャプションを指定してメッセージボックスを表示するその直前にタイマーを作成して、
limit だけ(例では5秒)時間が経過した際に指定したキャプションのウィンドウがあればそれを閉じる。

ご覧のとおり、Win32 API を使用しています。
ご提示の NativeWindow に関しては、私はわかりません。

2013/07/10 追記

正直、MessageBox 風のダイアログウィンドウを自作してしまったほうがいいのではないかとも思いますが、
まぁそれぞれ事情はあろうかと思いますので…

MessageBoxButtons.YesNo などのケースでメッセージボックスが閉じないとのことですが、
WM_CLOSE の代わりに

        const int WM_NCDESTROY = 0x0082;

を送りつけるとどうでしょうか。

私自身ウィンドウメッセージ等に関して精通しているわけではないので(^_^;)
副作用等が生じないことは保証できませんが…

環境も不明ですし「不定のタイミング」というのがイマイチどういうことかわかりませんが…

仮に MessageBox を表示して一定時間経過後に自動的に閉じたい、ということであれば
以下のような感じでいかがでしょう。
(Visual Studio 2012 Pro & .Net Framework 4.0 で確認。)

```cs
using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll")]
        static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp); 

        const int WM_CLOSE = 0x10;


        private string caption = "テスト";
        private int limit = 5000; // msec.

        public Form1()
        {
            InitializeComponent();
        }


        private void button1_Click(object sender, EventArgs e)
        {
            using (var timer = new System.Threading.Timer(s =>
            {
                var hWnd = FindWindow(null, this.caption);
                if (hWnd != IntPtr.Zero)
                {
                    SendMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
                }
            }, null, this.limit, Timeout.Infinite))

            MessageBox.Show(this, "メッセージ", this.caption);
        }
    }
}
```

キャプションを指定してメッセージボックスを表示するその直前にタイマーを作成して、
`limit` だけ(例では5秒)時間が経過した際に指定したキャプションのウィンドウがあればそれを閉じる。

ご覧のとおり、Win32 API を使用しています。
ご提示の NativeWindow に関しては、私はわかりません。

## 2013/07/10 追記

正直、MessageBox 風のダイアログウィンドウを自作してしまったほうがいいのではないかとも思いますが、
まぁそれぞれ事情はあろうかと思いますので…

`MessageBoxButtons.YesNo` などのケースでメッセージボックスが閉じないとのことですが、
`WM_CLOSE` の代わりに

```
        const int WM_NCDESTROY = 0x0082;
```

を送りつけるとどうでしょうか。

私自身ウィンドウメッセージ等に関して精通しているわけではないので(^_^;)
副作用等が生じないことは保証できませんが…

using ディレクティブがないと分かりづらいのでコードを全て記載しました

110
 (Visual Studio 2012 Pro & .Net Framework 4.0 で確認。)
 
 ```cs
-public partial class Form1 : Form
+using System;
+using System.Runtime.InteropServices;
+using System.Threading;
+using System.Windows.Forms;
+
+namespace WindowsFormsApplication1
 {
-    [DllImport("user32.dll", CharSet = CharSet.Auto)]
-    private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
+    public partial class Form1 : Form
+    {
+        [DllImport("user32.dll", CharSet = CharSet.Auto)]
+        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
 
-    [DllImport("user32.dll")]
-    private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp); 
+        [DllImport("user32.dll")]
+        static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp); 
 
-    private const int WM_CLOSE = 0x10;
+        const int WM_CLOSE = 0x10;
 
-    private string caption = "テスト";
-    private int limit = 5000; // msec.
 
-    public Form1()
-    {
-        InitializeComponent();
-    }
+        private string caption = "テスト";
+        private int limit = 5000; // msec.
 
-    private void button1_Click(object sender, EventArgs e)
-    {
-        using (var timer = new System.Threading.Timer(s =>
+        public Form1()
         {
-            var hWnd = FindWindow(null, this.caption);
-            if (hWnd != IntPtr.Zero)
+            InitializeComponent();
+        }
+
+
+        private void button1_Click(object sender, EventArgs e)
+        {
+            using (var timer = new System.Threading.Timer(s =>
             {
-                SendMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
-            }
-        }, null, this.limit, Timeout.Infinite))
+                var hWnd = FindWindow(null, this.caption);
+                if (hWnd != IntPtr.Zero)
+                {
+                    SendMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
+                }
+            }, null, this.limit, Timeout.Infinite))
 
-        MessageBox.Show(this, "メッセージ", this.caption);
+            MessageBox.Show(this, "メッセージ", this.caption);
+        }
     }
 }
 ```

環境も不明ですし「不定のタイミング」というのがイマイチどういうことかわかりませんが…

仮に MessageBox を表示して一定時間経過後に自動的に閉じたい、ということであれば
以下のような感じでいかがでしょう。
(Visual Studio 2012 Pro & .Net Framework 4.0 で確認。)

using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll")]
        static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp); 

        const int WM_CLOSE = 0x10;


        private string caption = "テスト";
        private int limit = 5000; // msec.

        public Form1()
        {
            InitializeComponent();
        }


        private void button1_Click(object sender, EventArgs e)
        {
            using (var timer = new System.Threading.Timer(s =>
            {
                var hWnd = FindWindow(null, this.caption);
                if (hWnd != IntPtr.Zero)
                {
                    SendMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
                }
            }, null, this.limit, Timeout.Infinite))

            MessageBox.Show(this, "メッセージ", this.caption);
        }
    }
}

キャプションを指定してメッセージボックスを表示するその直前にタイマーを作成して、
limit だけ(例では5秒)時間が経過した際に指定したキャプションのウィンドウがあればそれを閉じる。

ご覧のとおり、Win32 API を使用しています。
ご提示の NativeWindow に関しては、私はわかりません。

環境も不明ですし「不定のタイミング」というのがイマイチどういうことかわかりませんが…

仮に MessageBox を表示して一定時間経過後に自動的に閉じたい、ということであれば
以下のような感じでいかがでしょう。
(Visual Studio 2012 Pro & .Net Framework 4.0 で確認。)

```cs
using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll")]
        static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp); 

        const int WM_CLOSE = 0x10;


        private string caption = "テスト";
        private int limit = 5000; // msec.

        public Form1()
        {
            InitializeComponent();
        }


        private void button1_Click(object sender, EventArgs e)
        {
            using (var timer = new System.Threading.Timer(s =>
            {
                var hWnd = FindWindow(null, this.caption);
                if (hWnd != IntPtr.Zero)
                {
                    SendMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
                }
            }, null, this.limit, Timeout.Infinite))

            MessageBox.Show(this, "メッセージ", this.caption);
        }
    }
}
```

キャプションを指定してメッセージボックスを表示するその直前にタイマーを作成して、
`limit` だけ(例では5秒)時間が経過した際に指定したキャプションのウィンドウがあればそれを閉じる。

ご覧のとおり、Win32 API を使用しています。
ご提示の NativeWindow に関しては、私はわかりません。

回答を投稿

環境も不明ですし「不定のタイミング」というのがイマイチどういうことかわかりませんが…

仮に MessageBox を表示して一定時間経過後に自動的に閉じたい、ということであれば
以下のような感じでいかがでしょう。
(Visual Studio 2012 Pro & .Net Framework 4.0 で確認。)

public partial class Form1 : Form
{
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    [DllImport("user32.dll")]
    private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp); 

    private const int WM_CLOSE = 0x10;

    private string caption = "テスト";
    private int limit = 5000; // msec.

    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        using (var timer = new System.Threading.Timer(s =>
        {
            var hWnd = FindWindow(null, this.caption);
            if (hWnd != IntPtr.Zero)
            {
                SendMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
            }
        }, null, this.limit, Timeout.Infinite))

        MessageBox.Show(this, "メッセージ", this.caption);
    }
}

キャプションを指定してメッセージボックスを表示するその直前にタイマーを作成して、
limit だけ(例では5秒)時間が経過した際に指定したキャプションのウィンドウがあればそれを閉じる。

ご覧のとおり、Win32 API を使用しています。
ご提示の NativeWindow に関しては、私はわかりません。

環境も不明ですし「不定のタイミング」というのがイマイチどういうことかわかりませんが…

仮に MessageBox を表示して一定時間経過後に自動的に閉じたい、ということであれば
以下のような感じでいかがでしょう。
(Visual Studio 2012 Pro & .Net Framework 4.0 で確認。)

```cs
public partial class Form1 : Form
{
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    [DllImport("user32.dll")]
    private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp); 

    private const int WM_CLOSE = 0x10;

    private string caption = "テスト";
    private int limit = 5000; // msec.

    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        using (var timer = new System.Threading.Timer(s =>
        {
            var hWnd = FindWindow(null, this.caption);
            if (hWnd != IntPtr.Zero)
            {
                SendMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
            }
        }, null, this.limit, Timeout.Infinite))

        MessageBox.Show(this, "メッセージ", this.caption);
    }
}
```

キャプションを指定してメッセージボックスを表示するその直前にタイマーを作成して、
`limit` だけ(例では5秒)時間が経過した際に指定したキャプションのウィンドウがあればそれを閉じる。

ご覧のとおり、Win32 API を使用しています。
ご提示の NativeWindow に関しては、私はわかりません。