来自不同线程的hwnd线程亲和力绘制

时间:2011-04-11 14:33:19

标签: multithreading winapi qt sockets gdi

我有一个DGRect::draw(HWND hwnd),它只是在HBITMAP窗口句柄上绘制空白hwnd。 我工作正常如果我从main()打电话给我。它甚至可以正常工作如果从DGRDPServer::DGRDPServer()构造函数调用QTcpServer派生。它也适用于DGRDPServer::listen(qint64 port)。 hwnd在DGRDPServer构造函数中传递。当我从DGRDPServer::incomingConnection(int socketDescriptor) qDebug() hwnd的{​​{1}}及其正确的值调用时,会出现问题。是什么导致抽签失败。 ?? 这是我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调用来自不同的线程。看起来像DGRDPServer::incomingConnection(int socketDescriptor)这样的函数是从不同的线程调用的。那么从不同的线程中绘制hwnd可以做些什么呢?

1 个答案:

答案 0 :(得分:0)

我的猜测是这里的问题是你使用BeginPaint:as per docs:应用程序不应该调用BeginPaint,除非响应WM_PAINT消息

除此之外,您可以使用普通的GetDC / ReleaseDC而不是BeginPaint / EndPaint对。

然而,执行此类操作的“Windows方式”是仅使用工作线程来适当地更新内部数据,然后使用InvalidateRect或类似命令告诉Windows窗口需要更新,Windows将在稍后发送WM_PAINT。 UpdateWindow本质上是一个更直接的版本:它将WM_PAINT发送到那里的窗口然后(这导致实际的绘制发生在该hwnd的线程上)。