如何在win10应用程序中在辅助监视器中创建窗口

问题描述 投票:-2回答:2

我是win10 dev的新手,我正在尝试创建一个win10应用程序,它将在系统连接的所有监视器中创建一个浮动窗口。到目前为止,我成功地使用GDI API在我的主监视器中创建窗口,但它不能在我的辅助监视器上工作,我无法理解为什么它甚至在我使用微软页面中提到的API时都不起作用。

以下是我的代码

// Register the window class.
WNDCLASSEX wcex = { sizeof(WNDCLASSEX) };
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = DXGIDraw::WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = sizeof(LONG_PTR);
wcex.hInstance = HINST_THISCOMPONENT;
wcex.hbrBackground = NULL;
wcex.lpszMenuName = NULL;
wcex.hCursor = LoadCursor(NULL, IDI_APPLICATION);
wcex.lpszClassName = L"DemoApp";

RegisterClassEx(&wcex);

m_hwnd = CreateWindowEx(WS_EX_LAYERED,
    L"DemoApp",
    L"Demo App",
    0,
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    HWND_DESKTOP,
    NULL,
    HINST_THISCOMPONENT,
    NULL
);

const int nWidth = GetSystemMetrics(SM_CXSCREEN);
const int nHeight = GetSystemMetrics(SM_CYSCREEN);

CImage img;

DISPLAY_DEVICE ddd;
ZeroMemory(&ddd, sizeof(ddd));
ddd.cb = sizeof(ddd);
for (int i = 0; EnumDisplayDevices(NULL, i, &ddd, 0); i++)
{
    if (ddd.StateFlags & DISPLAY_DEVICE_ACTIVE) {
        //Active monitor
    }
    if (ddd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) {
        //Primary monitor
    }
    else {
        //other types
    }
}

//The following API supposed to work for all the monitors, but this API is not working. This is where I need attention.
HDC hdcScreen = CreateDC(ddd.DeviceName, NULL, NULL, NULL);
//But if I use below API I can get it working for the primary monitor only, still trying to understand why
//HDC hdcScreen = CreateDC(L"DISPLAY", NULL, NULL, NULL);
HDC hDC = CreateCompatibleDC(hdcScreen);
HBITMAP hBmp = CreateCompatibleBitmap(hdcScreen, nWidth, nHeight);
HBITMAP hBmpOld = (HBITMAP)SelectObject(hDC, hBmp);
img.Draw(hDC, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight);

//Add layered window
BLENDFUNCTION blend = { 0 };
blend.BlendOp = AC_SRC_OVER;
blend.SourceConstantAlpha = 255;
blend.AlphaFormat = AC_SRC_ALPHA;
POINT ptLocation = { 0, 0 };
SIZE szWnd = { nWidth, nHeight };
POINT ptSrc = { 0, 0 };
BOOL status1 = UpdateLayeredWindow(m_hwnd, hdcScreen, &ptLocation, &szWnd, hDC, &ptSrc, 0, &blend, ULW_ALPHA);

//Set window's position
BOOL status = SetWindowPos(m_hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);

hr = m_hwnd ? S_OK : E_FAIL;
if (SUCCEEDED(hr))
{
    BOOL status;
    status = ShowWindow(m_hwnd, SW_MAXIMIZE);
    status = UpdateWindow(m_hwnd);
}

SelectObject(hDC, hBmpOld);
DeleteObject(hBmp);
DeleteDC(hDC);
ReleaseDC(NULL, hdcScreen);
}
winapi
2个回答
1
投票

EnumDisplayDevices是这项工作的错误API。您需要使用EnumDisplayMonitors直接为您提供监视器坐标。


1
投票

您需要在virtual screen中检索所需监视器的边界矩形,然后根据需要在该矩形内定位窗口。使用EnumDisplayMonitors()获取每个moinitor的矩形。或者,如果你有一个特定显示器的HMONITOR句柄,你可以使用GetMonitorInfo()

© www.soinside.com 2019 - 2024. All rights reserved.