Delphi Tokyo中用ExtCreatePen创建的自定义虚线无法正常绘制,求排查
问题分析与修正方案
你的代码里有两个关键问题导致自定义画笔样式不生效,画出来是实线:
1. 样式数组的类型错误
Windows API的ExtCreatePen函数要求lpStyle参数是指向DWORD类型数组的指针,但你定义的LUserstyle是Double数组。Double类型的内存布局和DWORD完全不同,API无法正确解析你设置的样式参数,自然就 fallback 成了实线。
你需要把数组类型改成DWORD(或者Delphi里的LongWord,两者等价)。
2. VCL Pen对象的句柄管理问题
直接给PaintBox1.Canvas.Pen.Handle赋值后,VCL的TPen对象可能会在内部操作中覆盖你设置的自定义画笔句柄。更稳妥的做法是:
- 先保存原来的Pen句柄
- 使用自定义画笔完成绘制
- 恢复原来的Pen句柄,避免影响后续绘制
修正后的代码
var LLogBrush: TLogBrush; LUserstyle: array[0..3] of DWORD; // 改成DWORD类型 LOldPenHandle: HPEN; begin // 设置自定义样式:8单位实线,4单位空白,循环 LUserstyle[0] := 8; LUserstyle[1] := 4; LUserstyle[2] := 8; LUserstyle[3] := 4; LLogBrush.lbStyle := BS_SOLID; LLogBrush.lbColor := Color; LLogBrush.lbHatch := 0; // 创建自定义画笔并保存原Pen句柄 LOldPenHandle := PaintBox1.Canvas.Pen.Handle; PaintBox1.Canvas.Pen.Handle := ExtCreatePen(PS_GEOMETRIC or PS_USERSTYLE, 2, LLogBrush, Length(LUserstyle), @LUserstyle); try // 执行绘制 PaintBox1.Canvas.MoveTo(10, 10); PaintBox1.Canvas.LineTo(100, 100); finally // 恢复原来的Pen句柄,避免VCL出错 PaintBox1.Canvas.Pen.Handle := LOldPenHandle; end; end;
额外提示
- 如果你用的是
PS_COSMETIC类型的画笔,样式数组的数值代表的是像素单位;而PS_GEOMETRIC是逻辑单位,会受画布的映射模式(Canvas.MapMode)影响,需要注意两者的区别。 - 确保
ExtCreatePen调用成功(返回的句柄不为0),如果失败可以调用GetLastError排查原因。
内容的提问来源于stack exchange,提问作者KimC
相关产品推荐
相关产品推荐

