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

时间:2019-03-13 15:01:11

标签: winapi

对于win10开发人员来说我是一个新手,我正在尝试创建一个win10应用程序,该应用程序将在系统连接的所有显示器中创建一个浮动窗口。到目前为止,我已成功使用GDI API在主监视器中创建窗口,但在辅助监视器上却无法正常工作,即使我使用Microsoft页面中提到的API,我也无法理解为什么它无法工作。 / p>

下面是我的代码

// 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);
}

2 个答案:

答案 0 :(得分:1)

EnumDisplayDevices是此作业的错误API。您需要使用EnumDisplayMonitors,它可以直接为您提供监视器坐标。

答案 1 :(得分:1)

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