首页 > 解决方案 > Win32 程序更改笔记本电脑刷新率 - 崩溃

问题描述

所以我正在制作的 Win32 应用程序的简要介绍。它基本上应该根据笔记本电脑是否插入在 60 到 144 Hz 之间改变刷新率。当我启动应用程序时,GUI 启动但它崩溃了。我将在下面发布代码和调试。

#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。我是 Win32 的超级新手,所以如果我遗漏了一些超级简单的东西,我很抱歉。我的背景主要是 Android 开发。谢谢你的帮助!

标签: c++winapiwin32gui

解决方案


您没有break脱离外部开关/外壳,因此您会掉入WM_DESTROY外壳中。


推荐阅读