更改笔记本电脑刷新率的 Win32 程序 - 崩溃
Win32 Program to Change Laptop Refresh Rate - Crashing
我正在制作的 Win32 应用程序的快速 运行down。它基本上应该根据笔记本电脑是否插入来改变 60 和 144 Hz 之间的刷新率。当我启动应用程序时,GUI 启动但它崩溃了。我将 post 下面的代码和调试。
#ifndef UNICODE
#define UNICODE
#define UNICODE_WAS_UNDEFINED
#endif
#include <Windows.h>
#ifdef UNICODE_WAS_UNDEFINED
#undef UNICODE
#endif
#include <iostream>
using namespace std;
BOOL checked = FALSE;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
MSG msg;
WNDCLASS wc = { 0 };
wc.lpszClassName = L"autoRefresh";
wc.hInstance = hInstance;
wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wc.lpfnWndProc = WndProc;
wc.hCursor = LoadCursor(0, IDC_ARROW);
RegisterClass(&wc);
HWND hWnd = CreateWindowW(wc.lpszClassName, L"Refresh Changer", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 860, 540, 500, 150, 0, 0, hInstance, 0);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
RegisterPowerSettingNotification(hWnd, &GUID_ACDC_POWER_SOURCE, DEVICE_NOTIFY_WINDOW_HANDLE);
return (int)msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
DEVMODE dm;
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
switch (msg) {
case WM_CREATE: {
CreateWindow(TEXT("button"), TEXT("Enable automatic refresh rate changer (Will run at startup)"), WS_VISIBLE | WS_CHILD | BS_CHECKBOX, 20, 20, 500, 35, hwnd, (HMENU)1, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
CheckDlgButton(hwnd, 1, BST_UNCHECKED);
break;
}
case WM_COMMAND: {
OutputDebugStringW(L"WM_COMMAND case\n");
checked = IsDlgButtonChecked(hwnd, 1);
if (checked) {
OutputDebugStringW(L"Box unchecked\n");
CheckDlgButton(hwnd, 1, BST_UNCHECKED);
checked = FALSE;
}
else {
OutputDebugStringW(L"Box checked\n");
CheckDlgButton(hwnd, 1, BST_CHECKED);
checked = TRUE;
}
break;
}
case WM_POWERBROADCAST: {
OutputDebugStringW(L"WM_BROADCAST case\n");
if (checked) {
OutputDebugStringW(L"WM_BROADCAST checked is TRUE\n");
//std::wstring progPath = L"C:\Users\user\AppData\Roaming\Microsoft\Windows\RefreshChanger.exe";
//HKEY hkey = NULL;
//LONG createStatus = RegCreateKey(HKEY_CURRENT_USER, L"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", &hkey); //Creates a key
//LONG status = RegSetValueEx(hkey, L"RefreshChanger", 0, REG_SZ, (BYTE*)progPath.c_str(), (progPath.size() + 1) * sizeof(wchar_t));
SYSTEM_POWER_STATUS powerStatus;
GetSystemPowerStatus(&powerStatus);
if (powerStatus.ACLineStatus == 1) {
OutputDebugStringW(L"Refresh rate before changing: " + dm.dmDisplayFrequency);
dm.dmDisplayFrequency = 144;
LONG ret = ChangeDisplaySettingsEx(NULL, &dm, NULL, 0, NULL);
OutputDebugStringW(L"ChangeDisplaySettingsEx returned " + ret);
if (0 != EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm)) {
OutputDebugStringW(L"Refresh rate after changing: " + dm.dmDisplayFrequency);
}
switch (ret) {
case DISP_CHANGE_SUCCESSFUL:
OutputDebugStringW(L"Display successfully changed\n");
break;
case DISP_CHANGE_BADDUALVIEW:
OutputDebugStringW(L"The settings change was unsuccessful because the system is DualView capable\n");
break;
case DISP_CHANGE_BADFLAGS:
OutputDebugStringW(L"An invalid set of flags was passed in.\n");
break;
case DISP_CHANGE_BADMODE:
OutputDebugStringW(L"The graphics mode is not supported.\n");
break;
case DISP_CHANGE_BADPARAM:
OutputDebugStringW(L"An invalid parameter was passed in. This can include an invalid flag or combination of flags.\n");
break;
case DISP_CHANGE_FAILED:
OutputDebugStringW(L"The display driver failed the specified graphics mode.\n");
break;
case DISP_CHANGE_NOTUPDATED:
OutputDebugStringW(L"Unable to write settings to the registry.\n");
break;
case DISP_CHANGE_RESTART:
OutputDebugStringW(L"The computer must be restarted for the graphics mode to work.\n");
break;
}//switch
}
else {
OutputDebugStringW(L"WM_BROADCAST checked is FALSE\n");
OutputDebugStringW(L"Refresh rate before changing: " + dm.dmDisplayFrequency);
dm.dmDisplayFrequency = 60;
LONG ret = ChangeDisplaySettingsEx(NULL, &dm, NULL, 0, NULL);
OutputDebugStringW(L"ChangeDisplaySettingsEx returned " + ret);
if (0 != EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm)) {
OutputDebugStringW(L"Refresh rate after changing: " + dm.dmDisplayFrequency);
}
switch (ret) {
case DISP_CHANGE_SUCCESSFUL:
OutputDebugStringW(L"Display successfully changed\n");
break;
case DISP_CHANGE_BADDUALVIEW:
OutputDebugStringW(L"The settings change was unsuccessful because the system is DualView capable\n");
break;
case DISP_CHANGE_BADFLAGS:
OutputDebugStringW(L"An invalid set of flags was passed in.\n");
break;
case DISP_CHANGE_BADMODE:
OutputDebugStringW(L"The graphics mode is not supported.\n");
break;
case DISP_CHANGE_BADPARAM:
OutputDebugStringW(L"An invalid parameter was passed in. This can include an invalid flag or combination of flags.\n");
break;
case DISP_CHANGE_FAILED:
OutputDebugStringW(L"The display driver failed the specified graphics mode.\n");
break;
case DISP_CHANGE_NOTUPDATED:
OutputDebugStringW(L"Unable to write settings to the registry.\n");
break;
case DISP_CHANGE_RESTART:
OutputDebugStringW(L"The computer must be restarted for the graphics mode to work.\n");
}//switch
}//if/else
}//if checked
}//case
case WM_DESTROY: {
OutputDebugStringW(L"WM_DESTROY case\n");
PostQuitMessage(0);
break;
}
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
下面是调试控制台的屏幕截图:
当我拔掉充电器时,GUI 崩溃了。它会 运行 从被拔掉,但当我插入充电器时它也会崩溃。刷新率没有改变并且 WM_DESTROY 被调用,即使我没有点击顶部的 X的 window。我是 Win32 的超级新手,所以如果我遗漏了一些非常简单的东西,我很抱歉。我的背景主要是 Android 开发。感谢您的帮助!
你没有break
走出你的外层 switch/case 所以你陷入了 WM_DESTROY
的情况。
我正在制作的 Win32 应用程序的快速 运行down。它基本上应该根据笔记本电脑是否插入来改变 60 和 144 Hz 之间的刷新率。当我启动应用程序时,GUI 启动但它崩溃了。我将 post 下面的代码和调试。
#ifndef UNICODE
#define UNICODE
#define UNICODE_WAS_UNDEFINED
#endif
#include <Windows.h>
#ifdef UNICODE_WAS_UNDEFINED
#undef UNICODE
#endif
#include <iostream>
using namespace std;
BOOL checked = FALSE;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
MSG msg;
WNDCLASS wc = { 0 };
wc.lpszClassName = L"autoRefresh";
wc.hInstance = hInstance;
wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wc.lpfnWndProc = WndProc;
wc.hCursor = LoadCursor(0, IDC_ARROW);
RegisterClass(&wc);
HWND hWnd = CreateWindowW(wc.lpszClassName, L"Refresh Changer", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 860, 540, 500, 150, 0, 0, hInstance, 0);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
RegisterPowerSettingNotification(hWnd, &GUID_ACDC_POWER_SOURCE, DEVICE_NOTIFY_WINDOW_HANDLE);
return (int)msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
DEVMODE dm;
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
switch (msg) {
case WM_CREATE: {
CreateWindow(TEXT("button"), TEXT("Enable automatic refresh rate changer (Will run at startup)"), WS_VISIBLE | WS_CHILD | BS_CHECKBOX, 20, 20, 500, 35, hwnd, (HMENU)1, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
CheckDlgButton(hwnd, 1, BST_UNCHECKED);
break;
}
case WM_COMMAND: {
OutputDebugStringW(L"WM_COMMAND case\n");
checked = IsDlgButtonChecked(hwnd, 1);
if (checked) {
OutputDebugStringW(L"Box unchecked\n");
CheckDlgButton(hwnd, 1, BST_UNCHECKED);
checked = FALSE;
}
else {
OutputDebugStringW(L"Box checked\n");
CheckDlgButton(hwnd, 1, BST_CHECKED);
checked = TRUE;
}
break;
}
case WM_POWERBROADCAST: {
OutputDebugStringW(L"WM_BROADCAST case\n");
if (checked) {
OutputDebugStringW(L"WM_BROADCAST checked is TRUE\n");
//std::wstring progPath = L"C:\Users\user\AppData\Roaming\Microsoft\Windows\RefreshChanger.exe";
//HKEY hkey = NULL;
//LONG createStatus = RegCreateKey(HKEY_CURRENT_USER, L"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", &hkey); //Creates a key
//LONG status = RegSetValueEx(hkey, L"RefreshChanger", 0, REG_SZ, (BYTE*)progPath.c_str(), (progPath.size() + 1) * sizeof(wchar_t));
SYSTEM_POWER_STATUS powerStatus;
GetSystemPowerStatus(&powerStatus);
if (powerStatus.ACLineStatus == 1) {
OutputDebugStringW(L"Refresh rate before changing: " + dm.dmDisplayFrequency);
dm.dmDisplayFrequency = 144;
LONG ret = ChangeDisplaySettingsEx(NULL, &dm, NULL, 0, NULL);
OutputDebugStringW(L"ChangeDisplaySettingsEx returned " + ret);
if (0 != EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm)) {
OutputDebugStringW(L"Refresh rate after changing: " + dm.dmDisplayFrequency);
}
switch (ret) {
case DISP_CHANGE_SUCCESSFUL:
OutputDebugStringW(L"Display successfully changed\n");
break;
case DISP_CHANGE_BADDUALVIEW:
OutputDebugStringW(L"The settings change was unsuccessful because the system is DualView capable\n");
break;
case DISP_CHANGE_BADFLAGS:
OutputDebugStringW(L"An invalid set of flags was passed in.\n");
break;
case DISP_CHANGE_BADMODE:
OutputDebugStringW(L"The graphics mode is not supported.\n");
break;
case DISP_CHANGE_BADPARAM:
OutputDebugStringW(L"An invalid parameter was passed in. This can include an invalid flag or combination of flags.\n");
break;
case DISP_CHANGE_FAILED:
OutputDebugStringW(L"The display driver failed the specified graphics mode.\n");
break;
case DISP_CHANGE_NOTUPDATED:
OutputDebugStringW(L"Unable to write settings to the registry.\n");
break;
case DISP_CHANGE_RESTART:
OutputDebugStringW(L"The computer must be restarted for the graphics mode to work.\n");
break;
}//switch
}
else {
OutputDebugStringW(L"WM_BROADCAST checked is FALSE\n");
OutputDebugStringW(L"Refresh rate before changing: " + dm.dmDisplayFrequency);
dm.dmDisplayFrequency = 60;
LONG ret = ChangeDisplaySettingsEx(NULL, &dm, NULL, 0, NULL);
OutputDebugStringW(L"ChangeDisplaySettingsEx returned " + ret);
if (0 != EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm)) {
OutputDebugStringW(L"Refresh rate after changing: " + dm.dmDisplayFrequency);
}
switch (ret) {
case DISP_CHANGE_SUCCESSFUL:
OutputDebugStringW(L"Display successfully changed\n");
break;
case DISP_CHANGE_BADDUALVIEW:
OutputDebugStringW(L"The settings change was unsuccessful because the system is DualView capable\n");
break;
case DISP_CHANGE_BADFLAGS:
OutputDebugStringW(L"An invalid set of flags was passed in.\n");
break;
case DISP_CHANGE_BADMODE:
OutputDebugStringW(L"The graphics mode is not supported.\n");
break;
case DISP_CHANGE_BADPARAM:
OutputDebugStringW(L"An invalid parameter was passed in. This can include an invalid flag or combination of flags.\n");
break;
case DISP_CHANGE_FAILED:
OutputDebugStringW(L"The display driver failed the specified graphics mode.\n");
break;
case DISP_CHANGE_NOTUPDATED:
OutputDebugStringW(L"Unable to write settings to the registry.\n");
break;
case DISP_CHANGE_RESTART:
OutputDebugStringW(L"The computer must be restarted for the graphics mode to work.\n");
}//switch
}//if/else
}//if checked
}//case
case WM_DESTROY: {
OutputDebugStringW(L"WM_DESTROY case\n");
PostQuitMessage(0);
break;
}
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
下面是调试控制台的屏幕截图:
当我拔掉充电器时,GUI 崩溃了。它会 运行 从被拔掉,但当我插入充电器时它也会崩溃。刷新率没有改变并且 WM_DESTROY 被调用,即使我没有点击顶部的 X的 window。我是 Win32 的超级新手,所以如果我遗漏了一些非常简单的东西,我很抱歉。我的背景主要是 Android 开发。感谢您的帮助!
你没有break
走出你的外层 switch/case 所以你陷入了 WM_DESTROY
的情况。