Как создать окно на дополнительном мониторе в приложении win10 - PullRequest
0 голосов
/ 13 марта 2019

Я очень плохо знаком с разработчиком win10 и пытаюсь создать приложение win10, которое создаст плавающее окно на всех мониторах, к которым подключена система.Пока я успешно использую GDI API для создания окна в моем основном мониторе, но он не работает на моем дополнительном мониторе, я не могу понять, почему он не работает, даже когда я использую API, как упомянуто на странице Microsoft.

Ниже мой код

// 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 ]

1 голос
/ 13 марта 2019

Вам нужно получить ограничивающий прямоугольник для нужного монитора на виртуальном экране , а затем вы можете расположить окно в этом прямоугольнике по своему усмотрению.Используйте EnumDisplayMonitors(), чтобы получить прямоугольник каждого moinitor.Или, если у вас есть ручка HMONITOR для конкретного монитора, вы можете использовать GetMonitorInfo().

1 голос
/ 13 марта 2019

EnumDisplayDevices неправильный API для этой работы.Вам нужно использовать EnumDisplayMonitors, который дает вам координаты монитора напрямую.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...