HWND нить сродства рисования из другой нити - PullRequest
0 голосов
/ 11 апреля 2011

У меня есть DGRect::draw(HWND hwnd), который просто рисует пробел HBITMAP на hwnd дескрипторе окна. У меня нормально работает Если я позвоню с main(). Он даже работает правильно, если вызывается из DGRDPServer::DGRDPServer() конструктора, который QTcpServer Производный. Это также хорошо работает с DGRDPServer::listen(qint64 port). Hwnd передается в DGRDPServer конструкторе. Проблема появляется, когда я вызываю ее из DGRDPServer::incomingConnection(int socketDescriptor) У меня есть qDebug() ed значение hwnd и все в порядке. Что вызывает ничью за провал. ?? Вот мой код для DGRect::draw(HWND hwnd)

QByteArray ba;
HDC hdc = GetWindowDC(hwnd);
HBITMAP scrn = CreateCompatibleBitmap(hdc,/*width*/200,/*height*/200);
SetBitmapBits(scrn, /*size()*/200*200*4, ba.data());

BITMAP bm;
PAINTSTRUCT ps;
HDC whdc = BeginPaint(hwnd, &ps);
HDC hdcMem = CreateCompatibleDC(whdc);
HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, scrn);
GetObject(scrn, sizeof(bm), &bm);
BitBlt(whdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
SelectObject(hdcMem, hbmOld);
DeleteDC(hdcMem);
EndPaint(hwnd, &ps);
ShowWindow(hwnd, SW_SHOW);
UpdateWindow(hwnd);

Обновление

Похоже, hwnd может быть окрашен только из основной резьбы. Однако UpdateWindow Call работает из другого потока. и выглядит так, как будто функции DGRDPServer::incomingConnection(int socketDescriptor) вызываются из другого потока. Итак, что можно сделать, чтобы нарисовать hwnd из другого потока?

1 Ответ

0 голосов
/ 12 апреля 2011

Я предполагаю, что проблема заключается в том, что вы используете BeginPaint: согласно документам : приложение не должно вызывать BeginPaint, кроме как в ответ на сообщение WM_PAINT

Помимо этого, вы можете использовать обычную GetDC / ReleaseDC вместо пары BeginPaint / EndPaint.

Однако «способ Windows» для такого рода вещей заключается в том, чтобы просто использовать рабочий поток для надлежащего обновления внутренних данных, а затем использовать InvalidateRect или аналогичный, чтобы сообщить Windows, что для окна необходимо будет обновлен, и Windows отправит WM_PAINT позже. UpdateWindow, по сути, является более непосредственной версией этого: он тут же отправляет WM_PAINT в окно (что приводит к тому, что фактическое рисование происходит в потоке этого hwnd).

...