Override VCL class/component protected method - 如何编码和使用?

Override VCL class/component protected method - How to code and use?

我正在重写现有的旧代码,并对图标进行大修。我曾经将位图分配给 TMenuItems,但我正在改变它以支持 ImageIndex 和色深 32 位的 TImageList,包含带有 alpha 通道的图标。 ImageList 在设计时创建并填充有图标。 ImageIndex 在程序启动期间分配并适当更改 if/when。

我注意到当禁用 MenuItem (enabled = false) 时,生成的图像看起来不太好(根本),我读到这是 due to VCL。提到 link 也 link 到 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”。

那么,我是在构建表单期间创建 MyTimageListAssign() 设计时图像列表的内容,还是有更有效的方法来避免复制所有内容?

其实后一个问题想多了,.

好的,答案很简单,需要反复试验才能到达那里,因为我可以访问的 documentation 对此并不清楚。 (例如,TCanvas 指针也是错误的)。

function/method returns 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
        }
    };

此问题已关闭。

这是 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);
    }
}