Windows核心程式設計學習六:程序優先順序組和執行緒優先順序
阿新 • • 發佈:2019-02-10
注:原始碼為學習《Windows核心程式設計》的一些嘗試,非原創。若能有助於一二訪客,幸甚。
1.基本框架
使用CreateDialog和MAKEINTERESOURCE
/* * File: SchedLab.cpp * Time: 2013-04-20 * Describe:學習《Windows核心程式設計》 */ #include <windows.h> #include <windowsx.h> #include <tchar.h> #include <strsafe.h> #include "resource.h" #define chHANDLE_DLGMSG(hWnd, message, fn) \ case (message): return (SetDlgMsgResult(hWnd, uMsg, \ HANDLE_##message((hWnd), (wParam), (lParam), (fn)))) BOOL Dlg_OnInitDialog(HWND hWnd, HWND hWndFocus, LPARAM lParam) { return FALSE; } void Dlg_OnCommand(HWND hWnd, int id, HWND hWndCtl, UINT codeNotify) { switch (id) { case IDCANCEL: PostQuitMessage(0); break; } } INT_PTR WINAPI Dlg_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { chHANDLE_DLGMSG(hWnd, WM_INITDIALOG, Dlg_OnInitDialog); chHANDLE_DLGMSG(hWnd, WM_COMMAND, Dlg_OnCommand); } return FALSE; } int WINAPI _tWinMain(HINSTANCE hInstExe, HINSTANCE, PTSTR pszCmdLine, int) { HWND hWnd = CreateDialog(hInstExe, MAKEINTRESOURCE(IDD_SCHEDLAB), NULL, Dlg_Proc); BOOL fQuit = FALSE; while (!fQuit) { MSG msg; if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if (!IsDialogMessage(hWnd, &msg)) { if (msg.message == WM_QUIT) { fQuit = TRUE; } else { TranslateMessage(&msg); DispatchMessage(&msg); } } } else { static int s_n = -1; TCHAR sz[20]; StringCchPrintf(sz, _countof(sz), TEXT("%u"), ++s_n); HWND hWndWork = GetDlgItem(hWnd, IDC_WORK); ListBox_SetCurSel(hWndWork, ListBox_AddString(hWndWork, sz)); } } DestroyWindow(hWnd); return 0; }
2.當列表框中項過多時刪除一部分,並睡眠指定的毫秒數
發現列表框中的資料按字串順序排列了,把列表框屬性中的Sort去掉即可解決。
else { static int s_n = -1; TCHAR sz[20]; StringCchPrintf(sz, _countof(sz), TEXT("%u"), ++s_n); HWND hWndWork = GetDlgItem(hWnd, IDC_WORK); ListBox_SetCurSel(hWndWork, ListBox_AddString(hWndWork, sz)); // 當列表框中的專案多於100時,刪除最前面的項 while (ListBox_GetCount(hWndWork) > 100) ListBox_DeleteString(hWndWork, 0); // 獲取編輯框中指定的睡眠時間,並睡眠指定的毫秒數 int nSleep = GetDlgItemInt(hWnd, IDC_SLEEPTIME, NULL, FALSE); if (chINRANGE(1, nSleep, 9999)) Sleep(nSleep); }
3.初始化下拉列表中的專案
BOOL Dlg_OnInitDialog(HWND hWnd, HWND hWndFocus, LPARAM lParam) { chSETDLGICONS(hWnd, IDI_SCHEDLAB); // 初始化程序優先順序類下拉列表 HWND hWndCtl = GetDlgItem(hWnd, IDC_PROCESSPRIORITYCLASS); int n = ComboBox_AddString(hWndCtl, TEXT("High")); ComboBox_SetItemData(hWndCtl, n, HIGH_PRIORITY_CLASS); // 儲存當前的優先順序類 DWORD dwpc = GetPriorityClass(GetCurrentProcess()); // 判斷當前系統是否支援BELOW_NORMAL_PRIORITY_CLASS 優先順序 if (SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS)) { // 設定回原來的優先順序 SetPriorityClass(GetCurrentProcess(), dwpc); n = ComboBox_AddString(hWndCtl, TEXT("Above normal")); ComboBox_SetItemData(hWndCtl, n, ABOVE_NORMAL_PRIORITY_CLASS); dwpc = 0; } int nNormal = n = ComboBox_AddString(hWndCtl, TEXT("Normal")); ComboBox_SetItemData(hWndCtl, n, NORMAL_PRIORITY_CLASS); // 之所以在此處新增Below normal,個人認為只是下拉列表中的順序問題 if (dwpc == 0) { n = ComboBox_AddString(hWndCtl, TEXT("Below normal")); ComboBox_SetItemData(hWndCtl, n, BELOW_NORMAL_PRIORITY_CLASS); } n = ComboBox_AddString(hWndCtl, TEXT("Idle")); ComboBox_SetItemData(hWndCtl, n, IDLE_PRIORITY_CLASS); // 當前下拉列表選擇的項 ComboBox_SetCurSel(hWndCtl, nNormal); // 初始化相對執行緒優先順序下拉列表 hWndCtl = GetDlgItem(hWnd, IDC_THREADRELATIVEPRIORITY); n = ComboBox_AddString(hWndCtl, TEXT("Time critical")); ComboBox_SetItemData(hWndCtl, n, THREAD_PRIORITY_TIME_CRITICAL); n = ComboBox_AddString(hWndCtl, TEXT("Highest")); ComboBox_SetItemData(hWndCtl, n, THREAD_PRIORITY_HIGHEST); n = ComboBox_AddString(hWndCtl, TEXT("Above Normal")); ComboBox_SetItemData(hWndCtl, n, THREAD_PRIORITY_ABOVE_NORMAL); nNormal = n = ComboBox_AddString(hWndCtl, TEXT("Normal")); ComboBox_SetItemData(hWndCtl, n, THREAD_PRIORITY_NORMAL); n = ComboBox_AddString(hWndCtl, TEXT("Below normal")); ComboBox_SetItemData(hWndCtl, n, THREAD_PRIORITY_BELOW_NORMAL); n = ComboBox_AddString(hWndCtl, TEXT("Lowest")); ComboBox_SetItemData(hWndCtl, n, THREAD_PRIORITY_LOWEST); n = ComboBox_AddString(hWndCtl, TEXT("Idle")); ComboBox_SetItemData(hWndCtl, n, THREAD_PRIORITY_IDLE); ComboBox_SetCurSel(hWndCtl, nNormal); Edit_LimitText(GetDlgItem(hWnd, IDC_SLEEPTIME), 4); // 設定最大值為4位,即9999ms return TRUE; }
4.下拉列表選項改變事件處理
case IDC_PROCESSPRIORITYCLASS:
if (codeNotify == CBN_SELCHANGE) {
SetPriorityClass(GetCurrentProcess(), (DWORD)
ComboBox_GetItemData(hWndCtl, ComboBox_GetCurSel(hWndCtl)));
}
break;
case IDC_THREADRELATIVEPRIORITY:
if (codeNotify == CBN_SELCHANGE) {
SetThreadPriority(GetCurrentThread(), (DWORD)
ComboBox_GetItemData(hWndCtl, ComboBox_GetCurSel(hWndCtl)));
}
break;
5.掛起及恢復
#define chHANDLE_DLGMSG(hWnd, message, fn) \
case (message): return (SetDlgMsgResult(hWnd, uMsg, \
HANDLE_##message((hWnd), (wParam), (lParam), (fn))))
// Sets the dialog box icons
inline void chSETDLGICONS(HWND hWnd, int idi)
{
SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM)
LoadIcon((HINSTANCE) GetWindowLongPtr(hWnd, GWLP_HINSTANCE), MAKEINTRESOURCE(idi)));
SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM)
LoadIcon((HINSTANCE) GetWindowLongPtr(hWnd, GWLP_HINSTANCE), MAKEINTRESOURCE(idi)));
}
case IDC_SUSPEND:
EnableWindow(hWndCtl, FALSE);
HANDLE hThreadPrimary;
DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
GetCurrentProcess(), &hThreadPrimary,
THREAD_SUSPEND_RESUME, FALSE, DUPLICATE_SAME_ACCESS);
DWORD dwThreadID;
CloseHandle(chBEGINTHREADEX(NULL, 0, ThreadFunc,
hThreadPrimary, 0, &dwThreadID));
break;