Win32事件处理-检查充电器是否已插入



我正在尝试用C++做我的第一个Windows应用程序,我真的很难实现事件处理程序。我正在通读Win32文档,但它在示例上确实很稀疏。不幸的是,除了制作第一个窗口之外,我似乎在YouTube或其他书面来源上找不到太多。

我的应用程序的基本想法是让它根据笔记本电脑的充电器是否插入来改变显示器的刷新率。这主要是个人使用的,因为我的笔记本电脑支持144Hz和60Hz,我想在插入时利用更高的刷新率,但拔下插头后可以获得更好的电池寿命(而不用每次插入/拔下插头时都要查看显示器设置(。

我的背景主要是Android开发,但这一切似乎比这更令人生畏。我遇到了以下链接:

https://learn.microsoft.com/en-us/dotnet/api/microsoft.win32.systemevents.powermodechanged?redirectedfrom=MSDN&view=dotnet-plat-ext-3.1

https://learn.microsoft.com/en-us/dotnet/api/microsoft.win32.powermodechangedeventhandler?view=dotnet-plat-ext-3.1

如何检测笔记本电脑电源线何时断开?

这些似乎是我想要的,但我根本不知道如何在我的应用程序的上下文中真正将其组合在一起,尽管我似乎真的想使用PowerModeChangedEventHandler。以下是我到目前为止得到的(大量的复制/粘贴工作和修改(:

#include <Windows.h>
using namespace std;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
static char *title = TEXT("Refresh Changer");
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
DEVMODE dm;
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
MSG  msg;
WNDCLASS wc = {0};
wc.lpszClassName = TEXT("autoRefresh");
wc.hInstance = hInstance;
wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wc.lpfnWndProc = WndProc;
wc.hCursor = LoadCursor(0, IDC_ARROW);

RegisterClass(&wc);
CreateWindow(wc.lpszClassName, title, WS_OVERLAPPEDWINDOW|WS_VISIBLE, 860, 540, 350, 150, 0, 0, hInstance, 0);  
while(GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch(msg) {
case WM_CREATE: {
CreateWindow(TEXT("button"), TEXT("Enable automatic refresh rate changer"), WS_VISIBLE|WS_CHILD|BS_CHECKBOX, 20, 20, 300, 35, hwnd, (HMENU) 1, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
CheckDlgButton(hwnd, 1, BST_CHECKED);
break;
}
case WM_COMMAND: {
BOOL checked = IsDlgButtonChecked(hwnd, 1);
if (checked) {
//if/else blocks to check charger status and current refresh rate, then change accordingly
} else {
CheckDlgButton(hwnd, 1, BST_CHECKED);
SetWindowText(hwnd, title);
}
break;
}
case WM_DESTROY: {
PostQuitMessage(0);
break;
}
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}

这就是我在GUI方面所需要的全部内容,至少在第一个版本中是这样。但我真的对注册电源事件/检查并从那里出发感到失落。

有了窗口句柄hWnd后,调用RegisterPowerSettingNotification函数。
RegisterPowerSettingNotification(hWnd, &GUID_ACDC_POWER_SOURCE, DEVICE_NOTIFY_WINDOW_HANDLE);

在窗口过程中,查找WM_POWERBROADCAST消息,并检查电源管理事件的wParam

switch (message)
{
case WM_POWERBROADCAST:
if (wParam == PBT_APMPOWERSTATUSCHANGE)
{
SYSTEM_POWER_STATUS status;
if (GetSystemPowerStatus(&status))
{
// Look at the status structure for power information
}
}
else if (wParam == PBT_POWERSETTINGCHANGE)
{
POWERBROADCAST_SETTING *pSetting = (POWERBROADCAST_SETTING *)lParam;
// Look at the structure for power information
}
break;
}

注册电源事件:

应用程序接收到wParam为的WM_POWERBROADCAST消息PBT_POWERSETTINGCHANGE和指向POWERBROADCAstrongETTING结构。

电源设置GUID:

电源设置GUID在WinNT.h中定义。

GUID_ACDC_POWER_SOURCE

5D3E9A59-E9D5-4B00-A6BD-f34ff516548

系统电源已更改。数据成员是一个DWORDSYSTEM_POWER_CONDITION枚举中的值,该值指示电流电源。

PoAc(0(-计算机由AC电源(或类似电源,诸如由12V汽车适配器供电的笔记本电脑(。

PoDc(1(-计算机由板载电池电源供电。

PoHot(2(-计算机由短期电源供电,如作为UPS设备。

一些代码:

HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
HPOWERNOTIFY hPowerNotify;
hPowerNotify = RegisterPowerSettingNotification(hWnd, &GUID_ACDC_POWER_SOURCE, DEVICE_NOTIFY_WINDOW_HANDLE);
...
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_POWERBROADCAST:
{
if (wParam == PBT_POWERSETTINGCHANGE) {
POWERBROADCAST_SETTING* ppbs = (POWERBROADCAST_SETTING*)lParam;
if (memcmp(&ppbs->PowerSetting, &GUID_ACDC_POWER_SOURCE, sizeof(GUID)) == 0) {
unsigned int power_state = *(unsigned int*)ppbs->Data;
if (power_state == 0 ) {
//The computer is powered by an AC power source (or similar, such as a laptop powered by a 12V automotive adapter).                            
}
else if(power_state == 1) {
//The computer is powered by an onboard battery power source.
}
eles if(power_state == 2) {
//The computer is powered by a short-term power source such as a UPS device.
}
}
return 0;
}
}
break;
...

最新更新