WinGDI下修改PolyDraw绘制的图形颜色时遇到的问题
问题原因与解决方案
核心原因分析
你遇到的绘制颜色始终为黑色的问题,通常由以下几个原因导致:
DC_PEN是GDI提供的库存画笔对象,部分场景下会存在绑定兼容问题或系统支持问题,导致SetDCPenColor调用未生效,画笔保持默认黑色。你可以检查SetDCPenColor的返回值,如果返回CLR_INVALID(值为0xFFFFFFFF)即可确认调用失败。- 若你绘制的是带填充的闭合图形,仅修改画笔颜色只会影响边框颜色,填充区域使用DC默认画刷,若未单独修改画刷颜色也会导致图形整体呈现默认黑色。
- 原代码最后的资源清理逻辑存在错误:
DC_PEN属于系统库存GDI对象,不需要用户调用DeleteObject删除,该操作虽然不会直接导致颜色异常,但会引发潜在的GDI资源管理问题。
解决方案
建议放弃使用DC_PEN,改为手动创建自定义画笔,该方式兼容性更强,不会出现颜色不生效的问题,修正后的代码如下:
pub fn draw_rect(dc: *mut HDC__, rect: RECT, (r, g, b): (u8, u8, u8)) { // 创建1像素宽的实线自定义画笔 let custom_pen = unsafe { CreatePen(PS_SOLID, 1, RGB(r, g, b)) }; if custom_pen.is_null() { // 画笔创建失败可在此添加错误处理逻辑 return; } // 选入自定义画笔,保存原有画笔对象 let original_pen = unsafe { SelectObject(dc, custom_pen as HGDIOBJ) }; // 若需要绘制填充图形,可同时创建自定义画刷 // let custom_brush = unsafe { CreateSolidBrush(RGB(r, g, b)) }; // let original_brush = unsafe { SelectObject(dc, custom_brush as HGDIOBJ) }; // 矢量处理与绘制逻辑 unsafe { PolyDraw(dc, pts.as_ptr(), pt_instructions.as_ptr(), num_pts); } // 恢复原有GDI对象并释放手动创建的资源 // unsafe { // SelectObject(dc, original_brush); // DeleteObject(custom_brush as HGDIOBJ); // } unsafe { SelectObject(dc, original_pen); DeleteObject(custom_pen as HGDIOBJ); } }
额外注意事项
- 提前确认你使用的
RGB宏实现正确,正确实现应为((r as u32) | ((g as u32) << 8) | ((b as u32) << 16)),避免颜色值传反。 - 传入的
(r,g,b)参数值需要确保不为全0,可加日志打印确认参数传递正常。
内容的提问来源于stack exchange,提问作者Nikolai Savulkin
相关产品推荐
相关产品推荐

