我正在重写旧的现有代码,我正在对图标进行大修。我曾经将位图分配给TMenuItem
,但我改为支持ImageIndex
和TImageList
colordepth 32位,包含带alpha通道的图标。 ImageList在设计时创建并填充图标。 ImageIndex在程序启动期间分配,并在适当时更改。
我注意到当禁用MenuItem(enabled = false
)时,生成的图像看起来不太好(根本),我读到这是due to VCL。提到的链接还链接到可以将图标转换为其灰度值的Delphi代码。
我不熟练使用Delphi,也不会更改VCL组件,继承它们,继承它们等等。我通常只使用可用而无需更改它。所以我从一些基本问题开始:
这是一个非常简单的尝试从TImage继承并覆盖DoDraw(),使其永远不会禁用图标(将第二步中的Delphi代码删除灰度可以完成)
class MyTImageList : public TImageList
{
public:
__fastcall MyTImageList(Classes::TComponent* AOwner)
: TImageList(AOwner) {} ;
virtual __fastcall DoDraw(int Index, TCanvas *Canvas, int X, int Y, unsigned int Style, bool Enabled = true)
{
return TImageList::DoDraw(Index, Canvas, X, Y, Style) ;
}
};
仅供参考:我使用的是C ++ Builder 2009
它不编译,错误:[BCC32 Error] Main.h(1018): E2113 Virtual function '_fastcall TMainForm::MyTImageList::DoDraw(int,TCanvas *,int,int,unsigned int,bool)' conflicts with base class 'TCustomImageList'
由于我对继承VCL组件类非常不安全,我不确定我是在处理拼写错误还是非常有建设性的错误?请赐教。
假设这个编译我实际上也不确定如何继续进行。
因为ImageList是在设计时创建的,并且在整个代码中使用。要使此更改生效,我必须使用“MyTimageList
”。
那么,我在表单构造期间创建MyTimageList
并在{ - 1}}设计时 - ImageList的内容中创建,还是有更有效的方法来避免复制所有内容?
实际上,更多地考虑后一个问题I could simply use the internal ImageList of the design time Imagelist instance。
答案 0 :(得分:1)
以下是Delphi代码的C ++翻译:
class MyTImageList : public TImageList
{
protected:
virtual void __fastcall DoDraw(int Index, Graphics::TCanvas *Canvas, int X, int Y, unsigned Style, bool Enabled = true);
public:
__fastcall MyTImageList(Classes::TComponent* AOwner, TImageList *DesignImageList);
};
__fastcall MyTImageList::MyTImageList(Classes::TComponent* AOwner, TImageList *DesignImageList)
: TImageList(AOwner)
{
ColorDepth = DesignImageList->ColorDepth;
Handle = DesignImageList->Handle; // Use the internally kept List of the design time ImageList
ShareImages = true;
}
unsigned __fastcall GetRGBColor(TColor Value)
{
unsigned Result = ColorToRGB(Value);
switch (Result)
{
case clNone: Result = CLR_NONE; break;
case clDefault: Result = CLR_DEFAULT; break;
}
return Result;
}
void __fastcall MyTImageList::DoDraw(int Index, TCanvas *Canvas, int X, int Y, unsigned Style, bool Enabled)
{
if ((Enabled) || (ColorDepth != cd32Bit))
{
TImageList::DoDraw(Index, Canvas, X, Y, Style, Enabled);
}
else if (HandleAllocated())
{
IMAGELISTDRAWPARAMS Options = {0};
Options.cbSize = sizeof(Options);
Options.himl = (HIMAGELIST) Handle;
Options.i = Index;
Options.hdcDst = Canvas->Handle;
Options.x = X;
Options.y = Y;
Options.cx = 0;
Options.cy = 0;
Options.xBitmap = 0;
Options.yBitmap = 0;
Options.rgbBk = GetRGBColor(BkColor);
Options.rgbFg = GetRGBColor(BlendColor);
Options.fStyle = Style;
Options.fState = ILS_SATURATE; // Grayscale for 32bit images
ImageList_DrawIndirect(&Options);
}
}
答案 1 :(得分:0)
好的,答案很简单,需要一些试验和错误才能到达那里,因为我有权访问的documentation并不清楚。 (例如,TCanvas
指针也是错误的。
函数/方法返回void
。这是最初发布的代码中缺少的内容以及导致错误的原因。我得到了以下代码以便很好地工作。
class MyTImageList : public TImageList
{
public:
__fastcall MyTImageList(Classes::TComponent* AOwner, TImageList *DesignImageList)
: TImageList(AOwner)
{
Handle = DesignImageList->Handle ; // Use the internally kept List of the design time ImageList
ShareImages = true;
}
protected:
virtual __fastcall void DoDraw(int Index, TCanvas *Canvas, int X, int Y, unsigned int Style, bool Enabled = true)
{
return TImageList::DoDraw(Index, Canvas, X, Y, Style, true /*Enabled*/) ; // Always draw enabled
}
};
此问题已关闭。