自定义Button控件如何使用原生Images/ImageIndex属性及异常解决
初始需求
我自定义了Tdrawbutton控件,原本通过本地BMP文件绘制按钮外观,现希望使用Button原生的Images和ImageIndex属性来绘制按钮。
原有绘制本地BMP的代码
void __fastcall Tdrawbutton::DrawImag(AnsiString path) { ::Graphics::TBitmap *bmp= new ::Graphics::TBitmap; ::Graphics::TBitmap *newbmp= new ::Graphics::TBitmap; bmp->Transparent = true;//是否透明 newbmp->Transparent = true; bmp->LoadFromFile(path); int OriginalWidth = bmp->Width; int OriginalHeight = bmp->Height; int TargetWidth = OriginalWidth * hor; int TargetHeight = OriginalHeight * hor; newbmp->SetSize(TargetWidth, TargetHeight); newbmp->Canvas->CopyRect(TRect(0, 0, TargetWidth, TargetHeight), bmp->Canvas, TRect(0, 0, OriginalWidth, OriginalHeight)); Canvas_->Draw(0,0,newbmp); delete bmp; }
绘制消息处理代码
void __fastcall Tdrawbutton::CNDrawItem(TMessage &Msg){ // 获取 DRAWITEMSTRUCT const DRAWITEMSTRUCT* pDrawItem =reinterpret_cast<DRAWITEMSTRUCT*>(Msg.LParam); GetScreenDisplayScale(); // 保存当前状态 // 目标DC SaveDC(pDrawItem->hDC); // 绑定 Canvas_ 到目标 DC Canvas_->Handle = pDrawItem->hDC; try { // 提取状态标志... TOwnerDrawState state; // 按钮具有键盘焦点 if (pDrawItem->itemState & ODS_FOCUS) { state = state << odFocused; } // 按钮已按下 if (pDrawItem->itemState & ODS_SELECTED) { state = state << odSelected; } // 按钮禁用 if (pDrawItem->itemState & ODS_DISABLED) { state = state << odDisabled; } // 绘制按钮外观 DoDrawButtonFace(state); // 绘制按钮文本 DoDrawButtonText(state); } catch (...) { // 清理资源 Canvas_->Handle = NULL; RestoreDC(pDrawItem->hDC, -1); } // 清理资源 Canvas_->Handle = NULL; RestoreDC(pDrawItem->hDC, -1); // 返回处理成功 Msg.Result = TRUE; } //--------------------------------------------------------------------------- void __fastcall Tdrawbutton::DoDrawButtonFace(const TOwnerDrawState& state) { //Brush->Style = bsClear; Canvas_->Brush = Brush; TRect RClient = ClientRect; if(style == 0){ if (draw_as_default_ || state.Contains(odFocused)) { DrawImag("UI\\down.bmp"); } // 按钮按下状态... if (state.Contains(odSelected)) { DrawImag("UI\\down.bmp"); } // 按钮未按下状态... else { DrawImag("UI\\Normal.bmp"); } } if(style == 1){ if (selected) { DrawImag("UI\\down.bmp"); } else { DrawImag("UI\\Normal.bmp"); } } }
请问如何使用原生的Images和ImageIndex属性在自定义按钮上绘制图像?
更新1:使用GetBitmap方法出现显示异常
我尝试用GetBitmap(Index,bmp)方法读取图像,但生成的BMP显示异常,像是读取了ImageIndex对应的预览图像。
测试代码
void __fastcall Tdrawbutton::DrawIcon() { Canvas_->Brush = Brush; TRect RClient = ClientRect; ::Graphics::TBitmap *bmp= new ::Graphics::TBitmap; ::Graphics::TBitmap *newbmp = new::Graphics::TBitmap; this->Images->GetBitmap(ImageIndex,bmp); bmp->Transparent = true; newbmp->Transparent = true; int OriginalWidth = bmp->Width; int OriginalHeight = bmp->Height; int TargetWidth = OriginalWidth * hor; int TargetHeight = OriginalHeight * hor; newbmp->SetSize(TargetWidth, TargetHeight); newbmp->Canvas->CopyRect(TRect(0, 0, TargetWidth, TargetHeight),bmp->Canvas, TRect(0, 0, OriginalWidth, OriginalHeight)); Canvas_->Draw(48,3,newbmp); delete bmp; delete newbmp; }
[显示结果异常的截图]
这是什么原因?
更新2:调整ImageList的DrawingStyle解决部分问题
修改ImageList属性中的DrawingStyle后,设置为dsNormal或dsTransparent时显示正常,但设置为dsFocus和dsSelected时图像仍异常。根据VCL库帮助文档,dsFocus和dsSelected仅影响包含掩码的图像列表,但我的图像列表并未设置掩码,这一现象很奇怪,不过至少解决了部分问题。
内容的提问来源于stack exchange,提问作者thousandshadow
相关产品推荐
相关产品推荐

