场景
- 在开发
WTL/Win32程序时,有些界面绘制的元素比较多,内容多的时候还需要使用进行滚动显示; 比如在显示聊天气泡是,需要先计算气泡的个数并算好它的位置; 在使用滚动条时可以在滑条停止位置显示对应的气泡内容; 如果气泡上万个之后,在主线程计算就会卡,怎么解决?
说明
-
简单来说计算坐标和区域只要工作线程计算好即可;
-
通常情况,使用
HDC或者Gdiplus::Graphics时,这些图形元素都需要在界面线程执行,因为他们通常需要传递一个HWND句柄; 而句柄涉及到窗口,窗口的相关操作只能在界面线程执行; -
可是用
HDC和Gdiplus::Graphics计算文本大小时,影响最大的也只是字体,跟界面没关系,因此需要有一种方法不使用HWND创建HDC和Gdiplus::Graphics。 -
创建内存
HDC,GDI的::CreateCompatibleDC(NULL)就可以创建,因此对应在WTL里可以用以下方法创建HDC:
cpp
CDC dc;
dc.CreateCompatibleDC();
Gdiplus::Graphics graphics(dc);
例子
cpp
DWORD WINAPI WorkerThread(LPVOID lpParam)
{
// 创建一个虚拟的内存DC
CDC dc;
dc.CreateCompatibleDC();
// 创建 Graphics 对象
Gdiplus::Graphics graphics(dc);
// 设置文本渲染模式(可选,影响测量结果)
graphics.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAlias);
// 创建字体
Gdiplus::Font font(L"Arial", 12.0f, Gdiplus::FontStyleRegular, Gdiplus::UnitPixel);
// 测量文本
Gdiplus::RectF layoutRect(0, 0, 10000, 10000);
Gdiplus::RectF boundingBox;
Gdiplus::Status status = graphics.MeasureString(
L"Hello World",
-1,
&font,
layoutRect,
nullptr,
&boundingBox
);
if (status == Gdiplus::Ok)
{
float width = boundingBox.Width;
float height = boundingBox.Height;
// 使用计算结果...
}
return 0;
}