C ++ GetDC Все мониторы - PullRequest
       62

C ++ GetDC Все мониторы

0 голосов
/ 16 ноября 2018

По сути, я делаю что-то, что имитирует эффект плавления экрана, но я могу заставить его работать только на моем основном мониторе. Я посмотрел столько, сколько мог, и был только один форум по GetDC для всех мониторов, но это было бесполезно, все, что он сделал, это сделал прямоугольник от моего основного монитора до моего дополнительного монитора с эффектом, все еще работающим только на мой основной монитор. Это тема, которую я прочитал: GetDC (NULL) получает основной монитор или виртуальный экран?

LRESULT CALLBACK Melter(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam) {
    switch (Message) {
        case WM_CREATE: {
            HDC Desktop = GetDC(HWND_DESKTOP);
            HDC Window = GetDC(hWnd);

            BitBlt(Window, 0, 0, ScreenWidth, ScreenHeight, Desktop, 0, 0, SRCCOPY);
            ReleaseDC(hWnd, Window);
            ReleaseDC(HWND_DESKTOP, Desktop);

            SetTimer(hWnd, 0, Interval, 0);
            ShowWindow(hWnd, SW_SHOW);

            break;
        }
        case WM_PAINT: {
            ValidateRect(hWnd, 0);
            break;
        }
        case WM_TIMER: {
            HDC Window = GetDC(hWnd);
            int uX = (rand() % ScreenWidth) - (150 / 2), uY = (rand() % 15), Width = (rand() % 150);

            BitBlt(Window, uX, uY, Width, ScreenHeight, Window, uX, 0, SRCCOPY);
            ReleaseDC(hWnd, Window);

            break;
        }
        case WM_DESTROY: {
            KillTimer(hWnd, 0);
            PostQuitMessage(EXIT_SUCCESS);
            break;
        }
        return EXIT_SUCCESS;
    }

    return DefWindowProc(hWnd, Message, wParam, lParam);
}

Строка, которую я изменил, была HDC Window = GetDC(Window) to HDC Window = GetDC(NULL), а затем некоторые другие вещи, такие как RECT. Было бы здорово, если бы кто-то мог мне помочь, спасибо:)

PS, ScreenWidth = 3600, ScreenHeight = 1080, в то время как PMScreenWidth = 1920, PMScreenHeight = 1080. PM, как и в основном мониторе, поэтому все элементы этой функции настроены на ScreenWidth / ScreenHeight, так что это ширина / высота все мониторы. Все еще не работает, хотя.

Ответы [ 2 ]

0 голосов
/ 16 ноября 2018

Вы можете использовать HDC dc = CreateDC ((«DISPLAY»), NULL, NULL, NULL);

Проверьте по ссылкам ниже: -

  1. https://docs.microsoft.com/en-us/windows/desktop/gdi/using-multiple-monitors-as- независимые-дисплеи
  2. https://docs.microsoft.com/en-us/windows/desktop/api/Wingdi/nf-wingdi-createdca 3. https://docs.microsoft.com/en-us/windows/desktop/gdi/multiple-display-monitors-functions
0 голосов
/ 16 ноября 2018

GetDC(HWND_DESKTOP) (как и GetDC(0)) уже возвращает DC для всех мониторов. Проблема с приведенным выше кодом в основном связана с использованием BitBlt и выбором координат. См. MCVE ниже, в котором рассматривается вопрос.

Не рисуйте в ответ на WM_CREATE, оно просто будет стерто в WM_PAINT или при удалении фона.

Не звоните ValidateRect в ответ на WM_PAINT. Если вы хотите стереть окно, просто используйте FillRect или принудительно перекрасите из команды или другого маршрута.

Используйте GetSystemMetrics(SM_CXVIRTUALSCREEN) и GetSystemMetrics(SM_CYVIRTUALSCREEN), чтобы вернуть ширину и высоту для виртуального монитора.

Также убедитесь, что процесс поддерживает DPI. Для тестирования вы можете позвонить SetProcessDPIAware(); в начале программы. В идеале осведомленность о DPI должна быть установлена ​​в файле манифеста.

int uX = (rand() % ScreenWidth) - (150 / 2);
int uY = (rand() % 15);
int Width = (rand() % 150);
BitBlt(Window, uX, uY, Width, ScreenHeight, Window, uX, 0, SRCCOPY);

Выше код копирует биты с клиентского DC на тот же клиентский DC, он ничего не собирается делать. Предположительно, вы хотите скопировать данные с настольного DC на клиентский DC.

Более того, координаты в основном выбираются случайным образом. Предполагается, что основной монитор находится слева вверху. Если uX больше собственной ширины окна, оно не будет скопировано, если окно не растянет весь виртуальный монитор.

LRESULT CALLBACK Melter(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam) {

    switch(Message) 
    {
    case WM_PAINT: 
    {
        PAINTSTRUCT ps;
        auto hdc = BeginPaint(hWnd, &ps);
        RECT rc;
        GetClientRect(hWnd, &rc);

        HDC hdesktop = GetDC(0);

        int screenx = GetSystemMetrics(SM_XVIRTUALSCREEN);
        int screeny = GetSystemMetrics(SM_YVIRTUALSCREEN);
        int screenw = GetSystemMetrics(SM_CXVIRTUALSCREEN);
        int screenh = GetSystemMetrics(SM_CYVIRTUALSCREEN);

        StretchBlt(hdc, 0, 0, rc.right, rc.bottom,
            hdesktop, screenx, screeny, screenw, screenh, SRCCOPY);

        ReleaseDC(0, hdesktop);

        EndPaint(hWnd, &ps);
        break;
    }

    case WM_DESTROY: 
        PostQuitMessage(0);
        break;
    }

    return DefWindowProc(hWnd, Message, wParam, lParam);
}
...