来自其他线程的hwnd线程亲和力绘画 [英] hwnd thread affinity painting from a different thread

查看:88
本文介绍了来自其他线程的hwnd线程亲和力绘画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个DGRect::draw(HWND hwnd),它简单地在hwnd窗口句柄上绘制了空白HBITMAP. 如果我从main()调用它,我可以正常工作.如果从QTcpServer派生的DGRDPServer::DGRDPServer()构造函数调用,它甚至可以正常工作.从DGRDPServer::listen(qint64 port)也可以很好地工作. hwnd在DGRDPServer构造函数中传递.当我从DGRDPServer::incomingConnection(int socketDescriptor)调用它时,出现了问题,我已经qDebug()修改了hwnd的值,并且还可以.是什么导致平局失败. ?? 这是我的DGRect::draw(HWND hwnd)

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);

更新

看起来像hwnd只能从主线程绘制.但是,UpdateWindow调用是从其他线程进行的.看起来像DGRDPServer::incomingConnection(int socketDescriptor)这样的函数是从其他线程调用的.那么如何从不同的线程绘制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 ?

推荐答案

我的猜测是,这里的问题是您对BeginPaint的使用:

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

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

Outside of that, you may be able to use plain GetDC/ReleaseDC instead of BeginPaint/EndPaint pair.

但是,做这种事情的"Windows方式"是只使用工作线程来适当地更新内部数据,然后使用

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).

这篇关于来自其他线程的hwnd线程亲和力绘画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆