- 題名: ShowInTaskbar = False でのメインウィンドウハンドルの取得方法について
- 日時: 2009/02/04 14:22:49
- ID: 23906
- この記事の返信元:
- (なし)
- この記事への返信:
- [23907] サンプルソースの訂正2009/02/04 14:26:39
- [23908] Re[1]: ShowInTaskbar = False でのメインウィンドウハンドルの取得方法について2009/02/04 14:41:27
- ツリーを表示
サンプルソースに一部誤りが有りましたので訂正いたします。 static void Main() { Application.SetCompatibleTextRenderingDefault(false); StringBuilder className = new StringBuilder(256); using (Form1 dummy = new Form1()) { GetClassName(new HandleRef(null, dummy.Handle), className, className.Capacity); } IntPtr hWnd = FindWindow(className.ToString(), null); if (hWnd == IntPtr.Zero) { Application.Run(new Form1()); } else { SendMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero); } }
■No23908に返信(Hongliangさんの記事) > EventWaitHandle を使って名前付きイベントで多重起動を通知すればいいかと思います。 > 先に起動した方は EventWaitHandle をワーカスレッドでタイムアウト無しの WaitOne。待機が完了したら Invoke を使って終了処理。 > 後に起動した方は EventWaitHandle を Set。 > 多重起動判定も EventWaitHandle 作成時にできますね(コンストラクタの引数 createNew が false を返したら 2 つ目のインスタンスが起動)。 Hongliangさん、お返事ありがとうございます。 EventWaitHandle や 名前付きイベント と言う物を始めて知りまして、現在調べている 最中なのですが、厚かましいお願いを承知の上で、もし良ければお手隙の際で結構です ので具体的なサンプルコードを提示しては頂けないでしょうか? 宜しくお願い致します。
■No23908に返信(Hongliangさんの記事) > EventWaitHandle を使って名前付きイベントで多重起動を通知すればいいかと思います。 実業務が一段落しましたので EventWaitHandle について調べて見ました。 Hongliangさんに教えて頂いた内容を元にソースを記述してみたのですが、雰囲気的に 下記のような記述で合っているでしょうか? public partial class Form1 : Form { private EventWaitHandle ewh; public Form1() { InitializeComponent(); bool createdNew; ewh = new EventWaitHandle(false, EventResetMode.AutoReset, "hogehoge", out createdNew); if (!createdNew) { bool ret = ewh.Set(); } else { backgroundWorker1.RunWorkerAsync(); } } private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { ewh.WaitOne(); MessageBox.Show("他で起動されたから終了"); e.Result = 0; } private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { ewh.Close(); this.Close(); } } ただし1点分からない事がありましたので、引き続き教えて頂けると幸いです。 EventWaitHandleのコンストラクタの説明(ヘルプ)に「(非)シグナル状態」と「スレッド のブロック」について以下の様に記載が有ります。 > イベントの初期状態が非シグナル状態の場合、イベントを待機するスレッドはブロックされます。 > イベントの初期状態がシグナル状態で、ManualReset フラグが mode に指定されている場合、 > イベントを待機するスレッドはブロックされません。 > イベントの初期状態がシグナル状態で、mode が AutoReset である場合、イベントを待機している > 最初のスレッドはすぐに解放されますが、その後イベントがリセットされ、後続のスレッドはブロックされます。 この部分がどうにもイメージし難いのですが、どなたかもう少し噛み砕いた形で教えて 頂けないでしょうか? 以上 宜しくお願い致します。
■No23981に返信(Hongliangさんの記事) Hongliangさん、非常に分かりやすい説明を書いて下さって本当にありがとうございました。 仕様をきちんと把握できたお陰で、実務にも応用できそうです。 最後に実装したコードを"回答"として挙げ、本スレッドを"解決済み"とさせて頂きます。 static class Program { public static EventWaitHandle evnt = null; [STAThread] static void Main() { bool createdNew; evnt = new EventWaitHandle(false, EventResetMode.ManualReset, "hogehoge", out createdNew); if (createdNew) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } else { evnt.Set(); }; } } public partial class Form1 : Form { private Thread WaitThread = null; public Form1() { InitializeComponent(); WaitThread = new Thread(new ThreadStart(WaitOne)); WaitThread.IsBackground = true; WaitThread.Priority = ThreadPriority.Lowest; WaitThread.Start(); } public void WaitOne() { Program.evnt.WaitOne(); this.Invoke((MethodInvoker)delegate { this.Close(); }); } }
分類:[.NET]