注:源码为学习《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;