1. 程式人生 > >Windows核心程式設計學習六:程序優先順序組和執行緒優先順序

Windows核心程式設計學習六:程序優先順序組和執行緒優先順序

注:原始碼為學習《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;