[C++] 纯文本查看 复制代码
#include <windows.h>
#include <commctrl.h>
#include <string>
#include <sstream>
#pragma comment(lib, "comctl32.lib")
// 全局变量
HWND hwndMain = NULL;
HWND hwndHour = NULL, hwndMinute = NULL, hwndSecond = NULL;
HWND hwndStartBtn = NULL, hwndCancelBtn = NULL;
UINT timerId = 1;
int totalSeconds = 0;
bool isRunning = false;
// 函数声明
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
void StartCountdown();
void CancelCountdown();
void UpdateCountdown();
void ShutdownComputer();
// 应用程序入口
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
const wchar_t CLASS_NAME[] = L"ShutdownTimerClass";
// 初始化通用控件
INITCOMMONCONTROLSEX icex;
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
icex.dwICC = ICC_UPDOWN_CLASS;
InitCommonControlsEx(&icex);
WNDCLASSEX wc = {};
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.style = CS_HREDRAW | CS_VREDRAW;
RegisterClassEx(&wc);
int screenWidth = GetSystemMetrics(SM_CXSCREEN); // 获取屏幕宽度
int screenHeight = GetSystemMetrics(SM_CYSCREEN); // 获取屏幕高度
int windowWidth = 320;
int windowHeight = 150;
// 计算居中坐标
int x = (screenWidth - windowWidth) / 2;
int y = (screenHeight - windowHeight) / 2;
hwndMain = CreateWindowEx(
0,
CLASS_NAME,
L"关机助手",
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
x, y, // <--- 修改点:使用计算出的 x 和 y,替换 CW_USEDEFAULT
windowWidth, windowHeight,
NULL,
NULL,
hInstance,
NULL
);
if (hwndMain == NULL) {
return 0;
}
ShowWindow(hwndMain, nCmdShow);
MSG msg = {};
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
{
// 创建小时输入框
hwndHour = CreateWindow(
L"EDIT",
L"0",
WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL | ES_NUMBER,
20, 20, 40, 25,
hwnd,
(HMENU)101,
((LPCREATESTRUCT)lParam)->hInstance,
NULL
);
// 小时Spinbox(选择框)
HWND spinHour = CreateWindow(
UPDOWN_CLASS,
NULL,
WS_CHILD | WS_VISIBLE | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_SETBUDDYINT | UDS_WRAP,
0, 0, 0, 0, // 位置和大小会被自动调整
hwnd,
(HMENU)106,
((LPCREATESTRUCT)lParam)->hInstance,
hwndHour
);
SendMessage(spinHour, UDM_SETBUDDY, (WPARAM)hwndHour, 0);
SendMessage(spinHour, UDM_SETRANGE32, 0, 23);
SendMessage(spinHour, UDM_SETPOS32, 0, 0);
// 小时标签
CreateWindow(
L"STATIC",
L"时",
WS_CHILD | WS_VISIBLE | SS_CENTER,
70, 20, 20, 25,
hwnd,
NULL,
((LPCREATESTRUCT)lParam)->hInstance,
NULL
);
// 创建分钟输入框
hwndMinute = CreateWindow(
L"EDIT",
L"0",
WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL | ES_NUMBER,
100, 20, 40, 25,
hwnd,
(HMENU)102,
((LPCREATESTRUCT)lParam)->hInstance,
NULL
);
// 分钟Spinbox(选择框)
HWND spinMinute = CreateWindow(
UPDOWN_CLASS,
NULL,
WS_CHILD | WS_VISIBLE | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_SETBUDDYINT | UDS_WRAP,
0, 0, 0, 0,
hwnd,
(HMENU)107,
((LPCREATESTRUCT)lParam)->hInstance,
hwndMinute
);
SendMessage(spinMinute, UDM_SETBUDDY, (WPARAM)hwndMinute, 0);
SendMessage(spinMinute, UDM_SETRANGE32, 0, 59);
SendMessage(spinMinute, UDM_SETPOS32, 0, 0);
// 分钟标签
CreateWindow(
L"STATIC",
L"分",
WS_CHILD | WS_VISIBLE | SS_CENTER,
150, 20, 20, 25,
hwnd,
NULL,
((LPCREATESTRUCT)lParam)->hInstance,
NULL
);
// 创建秒钟输入框
hwndSecond = CreateWindow(
L"EDIT",
L"0",
WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL | ES_NUMBER,
180, 20, 40, 25,
hwnd,
(HMENU)103,
((LPCREATESTRUCT)lParam)->hInstance,
NULL
);
// 秒钟Spinbox(选择框)
HWND spinSecond = CreateWindow(
UPDOWN_CLASS,
NULL,
WS_CHILD | WS_VISIBLE | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_SETBUDDYINT | UDS_WRAP,
0, 0, 0, 0,
hwnd,
(HMENU)108,
((LPCREATESTRUCT)lParam)->hInstance,
hwndSecond
);
SendMessage(spinSecond, UDM_SETBUDDY, (WPARAM)hwndSecond, 0);
SendMessage(spinSecond, UDM_SETRANGE32, 0, 59);
SendMessage(spinSecond, UDM_SETPOS32, 0, 0);
// 秒钟标签
CreateWindow(
L"STATIC",
L"秒",
WS_CHILD | WS_VISIBLE | SS_CENTER,
230, 20, 20, 25,
hwnd,
NULL,
((LPCREATESTRUCT)lParam)->hInstance,
NULL
);
// 确定按钮
hwndStartBtn = CreateWindow(
L"BUTTON",
L"确定",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_TABSTOP,
50, 60, 60, 30,
hwnd,
(HMENU)104,
((LPCREATESTRUCT)lParam)->hInstance,
NULL
);
// 取消按钮
hwndCancelBtn = CreateWindow(
L"BUTTON",
L"取消",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_TABSTOP,
130, 60, 60, 30,
hwnd,
(HMENU)105,
((LPCREATESTRUCT)lParam)->hInstance,
NULL
);
EnableWindow(hwndCancelBtn, FALSE);
break;
}
case WM_COMMAND:
{
int controlId = LOWORD(wParam);
switch (controlId)
{
case 104: // 确定按钮
StartCountdown();
break;
case 105: // 取消按钮
CancelCountdown();
break;
}
break;
}
case WM_TIMER:
if (wParam == timerId) {
UpdateCountdown();
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
void StartCountdown()
{
// 获取输入的时间
wchar_t buffer[10];
GetWindowText(hwndHour, buffer, sizeof(buffer) / sizeof(wchar_t));
int hours = _wtoi(buffer);
GetWindowText(hwndMinute, buffer, sizeof(buffer) / sizeof(wchar_t));
int minutes = _wtoi(buffer);
GetWindowText(hwndSecond, buffer, sizeof(buffer) / sizeof(wchar_t));
int seconds = _wtoi(buffer);
// 验证输入
if (hours < 0 || minutes < 0 || seconds < 0 ||
hours > 23 || minutes > 59 || seconds > 59) {
MessageBox(hwndMain, L"请输入有效的时间!", L"错误", MB_OK | MB_ICONERROR);
return;
}
totalSeconds = hours * 3600 + minutes * 60 + seconds;
if (totalSeconds <= 0) {
MessageBox(hwndMain, L"请输入有效的时间!", L"错误", MB_OK | MB_ICONERROR);
return;
}
// 开始倒计时
isRunning = true;
EnableWindow(hwndStartBtn, FALSE);
EnableWindow(hwndCancelBtn, TRUE);
// 设置定时器,每秒触发一次
SetTimer(hwndMain, timerId, 1000, NULL);
// 更新标题
UpdateCountdown();
}
void CancelCountdown()
{
isRunning = false;
KillTimer(hwndMain, timerId);
EnableWindow(hwndStartBtn, TRUE);
EnableWindow(hwndCancelBtn, FALSE);
// 恢复原始标题
SetWindowText(hwndMain, L"关机助手");
}
void UpdateCountdown()
{
if (!isRunning) return;
if (totalSeconds > 0) {
// 计算时分秒
int hours = totalSeconds / 3600;
int mins = (totalSeconds % 3600) / 60;
int secs = totalSeconds % 60;
// 更新标题
wchar_t title[100];
swprintf_s(title, L"关机时间 - %02d:%02d:%02d", hours, mins, secs);
SetWindowText(hwndMain, title);
totalSeconds--;
}
else {
// 时间到了,执行关机
KillTimer(hwndMain, timerId);
ShutdownComputer();
}
}
void ShutdownComputer()
{
HANDLE hToken;
TOKEN_PRIVILEGES tkp;
// 获取进程令牌以获得关机特权
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
// 执行关机
ExitWindowsEx(EWX_SHUTDOWN | EWX_FORCE, 0);
CloseHandle(hToken);
}
}