代码之家  ›  专栏  ›  技术社区  ›  Peter

重写VCL类/组件保护方法-如何编码和使用?

  •  0
  • Peter  · 技术社区  · 8 年前

    我正在重写现有的旧代码,并对图标进行了全面检查。我以前有位图分配给 TMenuItem 但我正在改变这一点 ImageIndex TImageList 颜色深度为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 '.

    那么,我要创建 我的图片列表 模板施工期间和 Assign() 设计时ImageList的内容,还是有更有效的方法避免复制所有内容?

    实际上,更多地思考后一个问题, I could simply use the internal ImageList of the design time Imagelist instance .

    2 回复  |  直到 8 年前
        1
  •  1
  •   Remy Lebeau    8 年前

    下面是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);
        }
    }
    
        2
  •  0
  •   Peter    8 年前

    好吧,答案很简单,需要一些尝试和错误才能实现,因为 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
            }
        };
    

    本期已结束。