问题
I've a DGRect::draw(HWND hwnd)
which simply draws a Blank HBITMAP
on hwnd
window Handle.
I works fine If I call it from main()
. It even works correctly If called from DGRDPServer::DGRDPServer()
constructor which is QTcpServer
Derived. It also works well from DGRDPServer::listen(qint64 port)
. The hwnd is passed in DGRDPServer
constructor. The Problem appears when I call it from DGRDPServer::incomingConnection(int socketDescriptor)
I've qDebug()
ed value of hwnd
and its Okay. Whats Causing the draw for failing. ??
Here goes my code for 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);
Update
Seems like hwnd
can be painted from main thread only. However UpdateWindow
Call works from a different thread. and looks like functions like DGRDPServer::incomingConnection(int socketDescriptor)
are called from a different thread. So What can be done to paint hwnd
from a different thread ?
回答1:
My guess is that the problem here is your use of BeginPaint: as per docs: An application should not call BeginPaint except in response to a WM_PAINT message
Outside of that, you may be able to use plain GetDC/ReleaseDC instead of BeginPaint/EndPaint pair.
The 'windows way' of doing this sort of thing, however, is to just use the worker thread to update the internal data appropriately, and then use InvalidateRect or similar to tell Windows that the window needs to be updated, and Windows will send a WM_PAINT later. UpdateWindow is essentially a more immediate version of this: it sends WM_PAINT to the window right there and then (which causes the actual painting to take place on that hwnd's thread).
来源:https://stackoverflow.com/questions/5622850/hwnd-thread-affinity-painting-from-a-different-thread