將非模態對話框顯示為模態對話框_.Net教程
推薦:如何實現無刷新的DropdownList聯動效果ASP.NET給我們帶了了事件模型的編程機制,這使得我們將所有的任務都放在 服務器 上執行哪怕是一個小小變動,其實這到不是什么問題,可是有一點我們無法忍受,如果我們改變某一個輸入框中的內容
1、意圖
有時候我們希望將非模態窗口顯示為模態窗口。比如在IE的“文件”菜單下選擇“打印”,彈出的“打印”對話框就是非模態的(也許我們不太清楚Microsoft的設計意圖,一般來說這里的“打印”對話框應該是模態的)。這種情況下如何將“打印”對話框顯示為模態的呢(這個對話框對我們來說是Black Box)?
2、簡單實現
簡單地說,模態窗口顯示時,其父窗口是被Disable的,所以模態窗口才呈現“模態”,所以只要在顯示我們非模態窗口前將父窗口Disable即可實現,如下:
以下為引用的內容: …… AfxGetMainWnd()->EnableWindow(FALSE);//將主窗口Disable,顯示出的非模態窗口就變成模態的了 ShowModelessWindow(); …… |
問題在于非模態窗口顯示之后是立即返回的,那我們將父窗口Enable的代碼放在哪里呢?笨辦法是用時鐘,不斷地檢測顯示出來的非模態窗口是否已經關閉,若關閉則將父窗口Enable。
當然,還要更好的辦法。
3、WH_CBT Hook
WH_CBT鉤子的詳細說明請參閱MSDN,我們僅僅需要知道的是在窗口創建、銷毀之前系統都會調用掛上了WH_CBT的鉤子函數,這正是我們需要的。具體就是在顯示非模態窗口之前掛上我們的WH_CBT鉤子處理函數,之后非模態窗口創建的句柄就可以在鉤子函數的nCode為HCBT_CREATEWND(創建窗口)時從wParam參數獲得,將其保存下來,并在鉤子函數的nCode為HCBT_DESTROYWND(銷毀窗口)時與wParam參數進行比較,如果匹配則恢復主窗口的Enable狀態。
2、實現
1)首先定義兩個變量,此處為全局靜態變量。
以下為引用的內容: static HHOOK g_hHook = NULL; static HWND g_hWndDialog = NULL;//用以保存窗口句柄 |
2)再添加一個函數CbtProc,由于是回調函數,注意要聲明為static。
static LRESULT CALLBACK CbtProc(int nCode, WPARAM wParam, LPARAM lParam);
3)掛鉤
假設下面是我們的某個瀏覽器中調用“打印”對話框的函數
以下為引用的內容: void CMyHtmlView::OnFilePrint() { AfxGetMainWnd()->EnableWindow(FALSE); g_hWndDialog = 0; //可能多次調用,需要重置保存窗口句柄的變量 g_hHook = SetWindowsHookEx(WH_CBT, CbtProc, NULL, GetCurrentThreadId()); if (!g_hHook) { AfxGetMainWnd()->EnableWindow(TRUE); return; } |
調用“打印”對話框
以下為引用的內容: } LRESULT CALLBACK CMyHtmlView::CbtProc(int nCode, WPARAM wParam, LPARAM lParam) { switch (nCode) { case HCBT_CREATEWND: { HWND hWnd = (HWND)wParam; LPCBT_CREATEWND pcbt = (LPCBT_CREATEWND)lParam; LPCREATESTRUCT pcs = pcbt->lpcs;
if ((DWORD)pcs->lpszClass == 0x00008002)//#32770,“打印”對話框類名 { if ( g_hWndDialog == 0 ) g_hWndDialog = hWnd; // 只保存一次保存“打印”窗口的句柄 } break; } case HCBT_DESTROYWND: { HWND hwnd = (HWND)wParam; if (hwnd == g_hWndDialog) { AfxGetMainWnd()->EnableWindow(TRUE);//恢復窗口狀態 UnhookWindowsHookEx(g_hHook);//去除掛鉤 } break; } } return CallNextHookEx(g_hHook, nCode, wParam, lParam); } |
很簡單吧,更重要的是這種方法確實有效。
分享:url傳遞中文的解決方案1、設置web.config文件。 以下為引用的內容: <system.web> ...... <globalization requestEncoding="gb2312" responseEncoding=&
- asp.net如何得到GRIDVIEW中某行某列值的方法
- .net SMTP發送Email實例(可帶附件)
- js實現廣告漂浮效果的小例子
- asp.net Repeater 數據綁定的具體實現
- Asp.Net 無刷新文件上傳并顯示進度條的實現方法及思路
- Asp.net獲取客戶端IP常見代碼存在的偽造IP問題探討
- VS2010 水晶報表的使用方法
- ASP.NET中操作SQL數據庫(連接字符串的配置及獲取)
- asp.net頁面傳值測試實例代碼
- DataGridView - DataGridViewCheckBoxCell的使用介紹
- asp.net中javascript的引用(直接引入和間接引入)
- 三層+存儲過程實現分頁示例代碼
- 相關鏈接:
- 教程說明:
.Net教程-將非模態對話框顯示為模態對話框。