Win32 API窗口应用程序在Windows 10

时间:2017-06-24 22:39:51

标签: winapi windows-10 win32gui

主题:基于简单C ++ Win32 API的单一窗口应用程序。请参阅下面的代码。 计算机是MacBook Retina,本机安装了Windows 10。

问题:标题栏中的最小化/最大化/关闭按钮(窗口的非客户区域)在鼠标悬停事件中表现不正确。每个按钮仅在鼠标光标移动时突出显示,而按钮应始终突出显示,直到鼠标指针离开按钮区域。

问题:有什么问题? Win10清单?

代码:

#include <Windows.h>
#include <tchar.h>

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT ps;
    HDC hdc;
    TCHAR msgGreeting[] = _T("Hello World from MyWindowsApp!");

    switch (message)
    {
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        TextOut(hdc, 10, 10, msgGreeting, (int)_tcsclen(msgGreeting));
        EndPaint(hWnd, &ps);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
        break;
    }

    return 0;
}

int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    // 1. Initialize the application
    // 2. Display the main window
    WNDCLASSEX wndClassWindowMain;
    wndClassWindowMain.cbSize = sizeof(WNDCLASSEX);
    wndClassWindowMain.style = CS_VREDRAW | CS_HREDRAW;
    wndClassWindowMain.lpfnWndProc = WndProc;
    wndClassWindowMain.cbClsExtra = 0;
    wndClassWindowMain.cbWndExtra = 0;
    wndClassWindowMain.hInstance = hInstance;
    wndClassWindowMain.hIcon = LoadIcon(wndClassWindowMain.hInstance, IDI_APPLICATION);
    wndClassWindowMain.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndClassWindowMain.hbrBackground = (HBRUSH)(COLOR_WINDOW);
    wndClassWindowMain.lpszMenuName = NULL;
    wndClassWindowMain.lpszClassName = TEXT("MyMainWindowClass");
    wndClassWindowMain.hIconSm = LoadIcon(wndClassWindowMain.hInstance, IDI_APPLICATION);

    if (0 == RegisterClassEx(&wndClassWindowMain))
    {
        MessageBox(NULL
            , _T("Call to RegisterClassEx failed!")
            , _T("MyWindowsApplication")
            , MB_ICONERROR | MB_OK);
        return FALSE;
    }

    HWND hwndWindowMain = CreateWindowEx(WS_EX_APPWINDOW
        , _T("MyMainWindowClass")
        , _T("My Window")
        , WS_OVERLAPPEDWINDOW
        , 100, 100
        , 640, 480
        , NULL
        , NULL
        , hInstance
        , NULL);
    if (NULL == hwndWindowMain)
    {
        MessageBox(NULL
            , _T("Call to CreateWindowEx failed!")
            , _T("MyWindowsApplication")
            , MB_ICONERROR | MB_OK);
        return FALSE;
    }
    ShowWindow(hwndWindowMain, SW_SHOWDEFAULT);
    UpdateWindow(hwndWindowMain);
    // 3. Go to the message retrieval-and-dispatch loop
    MSG msg;
    BOOL bRet;

    while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
    {
        if (bRet == -1)
        {
            // handle the error and possibly exit
            return FALSE;
        }
        else
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return (int)msg.wParam;
}

1 个答案:

答案 0 :(得分:4)

<强>解决方案:

问题在于上述示例中应用程序的DPI(每英寸点数)意识。为了使您的本机C ++ / Win32 API代码与不同的屏幕(包括4K和Retina)兼容,您需要做的是遵循以下步骤:

  1. 包含相应的标题#include <ShellScalingApi.h>
  2. 告诉链接器编译的功能代码在哪里#pragma comment(lib,"Shcore.lib")
  3. 最后在WinMain添加以下调用SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
  4. 瞧!

    现在在Retina上,我看到我的应用程序窗口已适当缩放。最小化/最大化/关闭按钮按预期工作。

    进一步阅读:https://msdn.microsoft.com/en-us/library/windows/desktop/dn302122(v=vs.85).aspx