當前位置:網站首頁>關於創建模態窗口和非模態窗口的研究
關於創建模態窗口和非模態窗口的研究
2022-05-14 16:53:17【clever101】
作者:朱金燦
來源:clever101的專欄
模態窗口和非模態窗口的區別
模態窗口和非模態窗口的主要區別在於是獨占的活動窗口。模態窗口是獨占的活動窗口,非模態窗口不是獨占的活動窗口,是可以和其它窗口進行切換的。注意這裏說的模態窗口和非模態窗口並不限於模態對話框和非模態對話框。
創建模態窗口和非模態窗口的做法
模態窗口分為兩種,一種是模態對話框,使用DialogBox函數來彈出,這個網上資料很多,這裏就不介紹了;這裏要重點介紹的是創建不是對話框界面形式的模態窗口,具體做法是需要在CreateWindow後將它的父窗口設置為不可用,使用EnableWindow函數,在關閉模態窗口之前調用EnableWindow函數將父窗口設置為可用。有兩個創建模態窗口的函數:CreateChildWindow和DisplayModalWindow。建議使用DisplayModalWindow,因為使用DisplayModalWindow更為簡潔。創建非模態窗口則直接調用創建窗口函數即可。
//子窗口的消息響應函數
LRESULT CALLBACK WndProc1(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
switch (wMsg)
{
case WM_DESTROY:
{
PostQuitMessage(0);
}
break;
case WM_CLOSE:
{
//啟用主窗口
if(NULL!= g_hWnd)
EnableWindow(g_hWnd, TRUE);
return DefWindowProc(hWnd, wMsg, wParam, lParam);
}
default:
return DefWindowProc(hWnd, wMsg, wParam, lParam);
}
}
/* 目的:創建模態或非模態子窗口 pszWinTitle —— 窗口標題 pszClassName —— 窗口類名(這個可以自己指定一個常量字符串) bModal —— 是否為模態窗口,true為模態,false為非模態 */
void CreateChildWindow(LPCTSTR pszWinTitle,TCHAR* pszClassName,bool bModal)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc1;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = GetModuleHandle(nullptr);
wcex.hIcon = 0;
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = (LPCWSTR)pszClassName;
wcex.hIconSm = 0;
RegisterClassEx(&wcex);
HWND hChildWnd = CreateWindow(pszClassName, pszWinTitle,WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
0, CW_USEDEFAULT, 0, NULL, NULL, wcex.hInstance, 0);
//禁用主窗口
if(bModal)
EnableWindow(g_hWnd,FALSE);
ShowWindow(hChildWnd, SW_SHOW);
UpdateWindow(hChildWnd);
MSG msg;
while (GetMessage(&msg, nullptr, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
LRESULT CALLBACK ChildWinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
//創建模態窗口的第二種做法
void DisplayModalWindow(HWND hParent)
{
// 注册窗口類
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInst;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpfnWndProc = ChildWinProc;
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = TEXT("ModalWindow2");
RegisterClass(&wndclass);
EnableWindow(hParent, FALSE);
HWND hChildWin = CreateWindow(TEXT("ModalWindow2"),TEXT("模態窗口2"),WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
hParent,
NULL,
(HINSTANCE)GetWindowLong(hParent, GWLP_HINSTANCE),
NULL);
ShowWindow(hChildWin, SW_SHOW);
UpdateWindow(hChildWin);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
EnableWindow(hParent, TRUE);
// SetForegroundWindow(hParent);
SetActiveWindow(hParent);
}
//CreateChildWindow函數的調用處
void OnCommand(HWND hWnd, int id, HWND hwndCtl, UINT codeNotify)
{
switch (id)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
case ID_CREATE_MODAL:
{
//創建模態窗口的第一種做法
CreateChildWindow(_T("模態窗口"),_T("ModalChildWin"),true);
break;
}
case ID_CREATE_MODELESS:
{
//創建非模態窗口
CreateChildWindow(_T("非模態窗口"), _T("ModelessChildWin"),false);
break;
}
case ID_DISPLAY_MODAL:
{
DisplayModalWindow(hWnd);
break;
}
default:
return;
}
}
版權聲明
本文為[clever101]所創,轉載請帶上原文鏈接,感謝
https://cht.chowdera.com/2022/134/202205141633252273.html
邊欄推薦
猜你喜歡
隨機推薦
- 不均衡樣本集的重采樣
- uni-app技術分享| uni-app轉小程序-實時消息
- SQL中某個字段大於等於且不等於某值該如何寫
- 【Leetcode】442. 數組中重複的數據
- 2022年為什麼降薪也要跳槽?機會比漲薪很重要?
- 工作流結合動態錶單的工作流程
- 為什麼要使用.NET5?.NET5是未來!
- (pycharm)安裝nltk包
- 安裝Apache
- 利用循環輸入輸出數組(簡便易學)利用循環設置函數
- 雲原生時代的搜索服務算力管理
- 證券投資基金的監管
- ArrayList循環删除元素的常見問題及解决方法
- Stack Overflow 上最熱門的 10 個 Kotlin 問題
- 555 定時器的時間計算
- 二叉樹的最近公共祖先
- 模擬卷Leetcode【普通】931. 下降路徑最小和
- C語言 數組(一維數組 · 二維數組)
- NFC之華為AIPASS認證:測試用例簡介
- 622. 設計循環隊列
- VMware虛擬機 之 NAT模式詳解
- 【Devops】kubernetes網絡
- 新式茶飲“拿捏”年輕人,“八馬茶業”們的出路在哪?
- 機器學習之金融風控
- 1.67版本vscode括號著色(Bracket Pair Colorizer)取消
- MySQL日期查詢使用的方法函數
- HugeGraph客戶端APP開發(一)
- [.Net]使用Soa庫+Abp搭建微服務項目框架(五):服務發現和健康監測
- 添加虛擬內存,不添加硬盤的方式
- Redis源碼學習(25),雙端鏈錶學習,adlist.h
- 虛幻5新特性之EnhancedInput
- 緩存命中錶示什麼?
- sencha touch 在線實戰培訓 第一期 第四節
- “我們從 Google 離職了”
- yolov5訓練測試與源碼解讀
- 原生JS 實現輪播圖效果
- 邏輯回歸 解决報錯:ValueError: Solver lbfgs supports only ‘l2‘ or ‘none‘ penalties, got l1 penalty.
- Oracle OCI 計算、存儲、網絡工具旨在降低雲複雜性
- Go項目實戰之日志必備篇[開源十年項目第11次更新]
- Shell脚本變量和運算符