Многократное отображение курсора рисования (только значок рисования текста) - PullRequest
0 голосов
/ 22 апреля 2019

Я выбираю дисплеи в нескольких средах отображения и создаю захваченные программы.

И пытаюсь нарисовать курсор, выбирая dc среди нескольких дисплеев.

Я рисую курсоры с растровыми изображениями bitblt, и это работаетхорошо.

HDC HDCC = CreateDC((L"Display"), NULL, NULL, NULL);

Но Когда я выбираю из множества отображаемых значений createDC,

DISPLAY_DEVICEW info = { 0 };
info.cb = sizeof(DISPLAY_DEVICEW);
EnumDisplayDevicesW(NULL, 0, &info, EDD_GET_DEVICE_INTERFACE_NAME); 
HDCC = CreateDC(info.DeviceName, NULL, NULL, NULL);

Я прилагаю все усилия, чтобы получить другие изображения дисплея.Но нет курсора рисования.(Другие формы курсора не отображаются, отображается только текстовый курсор)

Это мой код.

const int d_count = GetSystemMetrics(SM_CMONITORS);  //I have 3 display and count is 3.
HDC hCaptureDC;
HDC HDCC;
HBITMAP hBitmap;
HGDIOBJ hOld;
BYTE *src;


bool GetMouse() {
     CURSORINFO cursor = { sizeof(cursor) };
     ::GetCursorInfo(&cursor);

     ICONINFOEXW info = { sizeof(info) };
     ::GetIconInfoExW(cursor.hCursor, &info);

     BITMAP bmpCursor = { 0 };
     GetObject(info.hbmColor, sizeof(bmpCursor), &bmpCursor);

     POINT point;
     GetCursorPos(&point);

     bool res = DrawIconEx(hCaptureDC, point.x, point.y, cursor.hCursor, bmpCursor.bmWidth, bmpCursor.bmHeight, 0, NULL, DI_NORMAL);
     return res;
}

void screencap(){
    BITMAPINFO MyBMInfo;
    BITMAPINFOHEADER bmpInfoHeader;
    HWND m_hWndCopy= GetDesktopWindow();
    GetClientRect(m_hWndCopy, &ImageRect);  
    const int nWidth = ImageRect.right - ImageRect.left; 
    const int nHeight = ImageRect.bottom - ImageRect.top;

    MyBMInfo = { 0 };
    MyBMInfo.bmiHeader.biSize = sizeof(MyBMInfo.bmiHeader);

    bmpInfoHeader = { sizeof(BITMAPINFOHEADER) };
    bmpInfoHeader.biWidth = nWidth;
    bmpInfoHeader.biHeight = nHeight;
    bmpInfoHeader.biPlanes = 1;
    bmpInfoHeader.biBitCount = 32;

    b_size = ((nWidth * bmpInfoHeader.biBitCount + 31) / 32) * 4 * nHeight;

     //HDCC = CreateDC((L"Display"), NULL, NULL, NULL);   //It's good.
    DISPLAY_DEVICEW info = { 0 };
    info.cb = sizeof(DISPLAY_DEVICEW);
    EnumDisplayDevicesW(NULL, 0, &info, EDD_GET_DEVICE_INTERFACE_NAME); 
    HDCC = CreateDC(info.DeviceName, NULL, NULL, NULL);   // It draws only text cursor.

    hCaptureDC = CreateCompatibleDC(HDCC);
    hBitmap = CreateCompatibleBitmap(HDCC, nWidth, nHeight);
    hOld = SelectObject(hCaptureDC, hBitmap);

    BitBlt(hCaptureDC, 0, 0, nWidth, nHeight, HDCC, 0, 0, SRCCOPY);

    GetMouse();

    SelectObject(hCaptureDC, hOld);

    src = (BYTE*)malloc(b_size);
    if (GetDIBits(hCaptureDC, hBitmap, 0, nHeight, src, (BITMAPINFO*)&bmpInfoHeader, DIB_RGB_COLORS)) {
        if (RGBSaveBMP(src) == true) 
        free(src);
    }  
}

Я использую Windows 10.

Как можноЯ решил?

Любые ссылки, идея, спасибо.

ДОБАВИТЬ

Он не рисует курсор .... (кроме текстового курсора.)

HDCC = CreateDC(TEXT("\\\\.\\Display1"), NULL, NULL, NULL);

HDCC = CreateDC(TEXT(

Рисует курсор ..

HDCC = CreateDC(TEXT("Display"), NULL, NULL, NULL);

HDCC = CreateDC(TEXT(

решено:

Теперь я изменил свой алгоритм.

CreateDC (L "Показать", NULL, NULL, NULL) создать DC для всех мониторов, так в чем ваша проблема?- user2120666 22 апреля в 15: 37

Этот комментарий очень полезен, но он не был добрым.(Или я был глуп.): (

HDC HDCC = CreateDC((L"Display"), NULL, NULL, NULL);

HDCC имеет "Все виртуальные экраны" DC.

Когда я выбрал нужный мне монитор, соответственно выбрал и использовал область для захватана виртуальном экране.

HDC hCaptureDC = CreateCompatibleDC(HDCC);  
HBITMAP hBitmap = CreateCompatibleBitmap(HDCC, nWidth, nHeight);
HDC HDCC = CreateDC((L"Display"), NULL, NULL, NULL);
DEVMODE dev;

std::string str = "\\\\.\\Display" + std::to_string(select);
std::wstring temp;
temp.assign(str.begin(), str.end());

EnumDisplaySettingsW(temp.c_str(), ENUM_CURRENT_SETTINGS, &dev);
printf("Display%d : (%d * %d) (%d, %d)\n", select, dev.dmPelsWidth, dev.dmPelsHeight, dev.dmPosition.x, dev.dmPosition.y);

nWidth = dev.dmPelsWidth;
nHeight = dev.dmPelsHeight;
nposx = dev.dmPosition.x;
nposy = dev.dmPosition.y;

hOld = SelectObject(hCaptureDC, hBitmap);
BitBlt(hCaptureDC, 0, 0, nWidth, nHeight, HDCC, nposx, nposy, SRCCOPY);
int colorcheck = GetSystemMetrics(SM_SAMEDISPLAYFORMAT);

CURSORINFO cursor = { sizeof(cursor) };
bool check = ::GetCursorInfo(&cursor);
bool check2 = ::GetCursorInfo(&cursor);
int count = ShowCursor(TRUE);

info = { sizeof(info) };
::GetIconInfoExW(cursor.hCursor, &info);

GetCursorPos(&point);

if (point.x > nWidth) {
    point.x = point.x - nWidth;
}
else if (point.x < 0) {
    point.x = nWidth + point.x;
}
if (point.y > nHeight) {
    point.y = point.y - nHeight;
}
else if (point.y < 0) {
    point.y = nHeight + point.y;
}
cursor.ptScreenPos.x = point.x;
cursor.ptScreenPos.y = point.y;

bool res = ::DrawIconEx(hCaptureDC, point.x, point.y, cursor.hCursor, 0, 0, 0, NULL, DI_NORMAL);


BYTE* src = (BYTE*)malloc(b_size);
GetDIBits(hCaptureDC, hBitmap, 0, nHeight, src, (BITMAPINFO*)&bmpInfoHeader, DIB_RGB_COLORS)

Спасибо за комментарий!

Ответы [ 2 ]

0 голосов
/ 23 апреля 2019

Ваш звонок GetClientRect(m_hWndCopy, &ImageRect); неверен.

Из документации :

Прямоугольник окна рабочего стола, возвращаемый GetWindowRect или GetClientRect, всегда равенпрямоугольник основного монитора для совместимости с существующими приложениями.

Таким образом, вы снимаете только основной дисплей.

0 голосов
/ 23 апреля 2019

После MSDN для получения EnumDisplayMonitor может решить вашу проблему.

Используйте EnumDisplayMonitors, чтобы получить имя устройства и передать его CreateDC.

...