C#自动弹出窗口并定时自动关闭
最近做個(gè)小項(xiàng)目,用到一個(gè)小功能:后臺(tái)線程定時(shí)查詢數(shù)據(jù)庫(kù),不符合條件的記錄彈出消息提醒(在窗口最前面),并且過(guò)幾秒鐘再自動(dòng)關(guān)閉彈出的窗口。
所以從網(wǎng)上找來(lái)資料,如下:
WinForm 下實(shí)現(xiàn)一個(gè)自動(dòng)關(guān)閉的MessageBox
Author: eaglet
????? WinForm 下我們可以調(diào)用MessageBox.Show 來(lái)顯示一個(gè)消息對(duì)話框,提示用戶確認(rèn)等操作。在有些應(yīng)用中我們需要通過(guò)程序來(lái)自動(dòng)關(guān)閉這個(gè)消息對(duì)話框而不是由用戶點(diǎn)擊確認(rèn)按鈕來(lái)關(guān)閉。然而.Net framework 沒(méi)有為我們提供自動(dòng)關(guān)閉MessageBox 的方法,要實(shí)現(xiàn)這個(gè)功能,我們需要使用Window API 來(lái)完成。
????? 首先我們需要找到這個(gè)消息對(duì)話框的窗口句柄,一個(gè)比較簡(jiǎn)單的方法就是用 FindWindow API 來(lái)查找對(duì)應(yīng)的窗體句柄。
????????static?extern?IntPtr?FindWindow(string?lpClassName,?string?lpWindowName);
????? 這個(gè)API調(diào)用可以通過(guò)窗口的類名或者窗口標(biāo)題的名字來(lái)查找窗口句柄。
????? 接下來(lái)我們還需要找到一個(gè) API 來(lái)關(guān)閉對(duì)話框,這里我使用 EndDialog
????????static?extern?bool?EndDialog(IntPtr?hDlg,?out?IntPtr?nResult);
????? 有了這兩個(gè)API函數(shù),我們就可以來(lái)關(guān)閉消息對(duì)話框了。思路是在調(diào)用MessageBox.Show 前啟動(dòng)一個(gè)后臺(tái)工作線程,這個(gè)工作線程等待一定時(shí)間后開始查找消息對(duì)話框的窗口句柄,找到后調(diào)用EndDialog API 函數(shù)關(guān)閉這個(gè)消息對(duì)話框。不過(guò)這個(gè)方法有個(gè)問(wèn)題,就是如果同時(shí)又多個(gè)同名的消息對(duì)話框(可能不一定是這個(gè)應(yīng)用的),這樣做可能會(huì)關(guān)錯(cuò)窗口,如何解決這個(gè)問(wèn)題,我還沒(méi)有想出比較好的方法,如果大家有更好的方法解決這個(gè)問(wèn)題,不妨一起討論討論。
?????
????? 我根據(jù)這個(gè)思路編寫了延時(shí)關(guān)閉消息對(duì)話框的函數(shù)
????????????MessageBoxButtons?buttons,?int?timeout)
????????{
????????????ThreadPool.QueueUserWorkItem(new?WaitCallback(CloseMessageBox),?
????????????????new?CloseState(caption,?timeout));
????????????MessageBox.Show(text,?caption,buttons);
????????}
?? 這個(gè)函數(shù)中timeout 參數(shù)單位是毫秒,其他參數(shù)和MessageBox.Show的參數(shù)含義是一樣的,這里不再詳細(xì)說(shuō)明。
?? 這個(gè)函數(shù)中首先利用線程池調(diào)用一個(gè)工作線程 CloseMessageBox ,并將對(duì)話框的標(biāo)題和延時(shí)時(shí)間通過(guò)CloseState這個(gè)類傳遞給CloseMessageBox函數(shù)。
?? CloseState 的定義如下:
???
????????{
????????????private?int?_Timeout;
????????????///?<summary>
????????????///?In?millisecond
????????????///?</summary>
????????????public?int?Timeout
????????????{
????????????????get
????????????????{
????????????????????return?_Timeout;
????????????????}
????????????}
????????????private?string?_Caption;
????????????///?<summary>
????????????///?Caption?of?dialog
????????????///?</summary>
????????????public?string?Caption
????????????{
????????????????get
????????????????{
????????????????????return?_Caption;
????????????????}
????????????}
????????????public?CloseState(string?caption,?int?timeout)
????????????{
????????????????_Timeout?=?timeout;
????????????????_Caption?=?caption;
????????????}
????????}
最后就是CloseMessageBox函數(shù)了,直接看代碼吧
????????{
????????????CloseState?closeState?=?state?as?CloseState;
????????????Thread.Sleep(closeState.Timeout);
????????????IntPtr?dlg?=?FindWindow(null,?closeState.Caption);
????????????if?(dlg?!=?IntPtr.Zero)
????????????{
????????????????IntPtr?result;
????????????????EndDialog(dlg,?out?result);
????????????}
????????} 出處:http://www.cnblogs.com/XGLSummer/archive/2012/09/06/2673334.html ============================================================================================= 發(fā)現(xiàn)上面的代碼是可以,但彈出的窗口沒(méi)有在最前面,所以還需要繼續(xù)找資料。
在屏幕的最前面彈一個(gè)消息框
有人要說(shuō)了,彈一個(gè)ShowDialog不就完了嗎?!或者M(jìn)essageBox.Show("saaaaa");就可以達(dá)到目的。
但你要看到下面的情況,你就不這樣說(shuō)了。
我在C#中創(chuàng)建了一個(gè)Excel,每當(dāng)我編輯一個(gè)值的時(shí)候,都會(huì)用C#代碼判斷這些值是否是有效的,當(dāng)無(wú)效進(jìn)就提醒他們。我用的就是MessageBox.Show("aaaaaaa");
但它不一定彈在最前面,因?yàn)樗荂#的代碼,故當(dāng)Excel在最前面時(shí),那個(gè)消息框是不能顯示在最頭面的。
用以下方法可以解決此問(wèn)題:
MessageBox.Show("要彈的信息。", "信息", MessageBoxButtons.OK, MessageBoxIcon.Information,MessageBoxDefaultButton.Button1, essageBoxOptions.DefaultDesktopOnly);
呵呵,雖然還是那個(gè)MessageBox.Show,但很多人都不知道呀。大家可以試試。
出處:http://www.cnblogs.com/pnljs/archive/2012/09/19/2694182.html ======================================================================================================== 使用上面的代碼,可以實(shí)現(xiàn)彈出窗口在最上面,但是結(jié)合第一段的代碼,無(wú)法正常關(guān)閉,直接報(bào)錯(cuò)了。說(shuō)明調(diào)用的static?extern?bool?EndDialog(IntPtr?hDlg,?out?IntPtr?nResult);方法不能正常關(guān)閉窗口,那么咱們?cè)僦匦抡覀€(gè)可以關(guān)閉窗口的API函數(shù)把。在網(wǎng)上找到如下代碼: public const int WM_CLOSE = 0x10;[System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "SendMessageA")]public static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);private void button1_Click(object sender, System.EventArgs e){IntPtr hwnd_win;hwnd_win = FindWindow(null, "要找的窗體名");SendMessage(hwnd_win, WM_CLOSE, 0, 0);}
查找窗口函數(shù):
//查找窗體[DllImport("User32.dll", EntryPoint = "FindWindow")]private static extern int FindWindow(string lpClassName, string lpWindowName);static void Main(){//@Form1根據(jù)窗體的Text文本值獲得窗體int WINDOW_HANDLER = FindWindow(null, @"Form1");}?
出處:http://bbs.csdn.net/topics/340065537/ ======================================================================================= 通過(guò)以上幾步,我們現(xiàn)在可以正常的實(shí)現(xiàn)了我們文章開頭提到的功能了。總結(jié)
以上是生活随笔為你收集整理的C#自动弹出窗口并定时自动关闭的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 一段简单的表格样式
- 下一篇: C# DataTable的Select(