Get a pic from TsVirtualImageList

Viewing 7 posts - 1 through 7 (of 7 total)
  • Author
    Posts
  • #38293
    SzakiLaci
    Participant

    Hi,

    How do I paint a cached picture to a canvas from TsVirtualImageList ?

    _______________________

    Edit: SOLUTION for TVirtualStringTree: Post#7

    #59635
    Support
    Keymaster

    Hi

    You can try these two methods:

    function GetBitmap32(Index: Integer; Image: TBitmap; GlyphHeight: integer = 0): Boolean; // Copy an image to existing bitmap

    function CreateBitmap32(Index: Integer): TBitmap;

    #59639
    SzakiLaci
    Participant
    'Support' wrote:

    function GetBitmap32(Index: Integer; Image: TBitmap; GlyphHeight: integer = 0): Boolean; // Copy an image to existing bitmap

    function CreateBitmap32(Index: Integer): TBitmap;

    Thanks for the quick answer! 🙂

    So basically there is no “direct” function for this (yet?),

    the only way is to create a temporary bitmap >> draw it to Canvas from there >> destroy the bitmap?

    This seems to me a waste of CPU resources, doing the same work twice. Isn't it?

    TargetCanvas.Handle is a HDC. Isn't it possible to do something like you do while painting to a sBitBtn?

    (Actually I was trying to decypher what is happening at sVclUtils.PaintControls … )

    My guess is that the magic happens at line: 2971

    Code:
    BitBlt(DC, Left + Offset.X, Top + Offset.Y, Width, Height, MemDC, Left, Top, SRCCOPY);

    but I'm not sure, and can not figure out: where you get the source HDC from?

    ________________________________

    I've spent 6 hours so far with:

    – reading all the FAQ

    – reading all Tricks from this topics

    – searching through troubleshooting topics

    – analyzing your code.

    I remember a few years ago somebody asked this once already but could not find that topic any more.

    #59641
    Support
    Keymaster

    Cached images are stored in the “private” section of the ImageList and can't be reached directly now.

    These images are not always ready. The cached image is created when some image is requested by the program.

    I can move it to the “protected” section where you can have access to this cache.

    Quote:
    but I'm not sure, and can not figure out: where you get the source HDC from?

    MemDC is a memory image which was created earlier:

    Code:
    MemDC := CreateCompatibleDC(0);
    OldBitmap := SelectObject(MemDC, MemBitmap);
    #59643
    SzakiLaci
    Participant

    I've found a “ready to use” method:

    Code:
    TsVirtualImageList.DoDraw(Index: Integer; Canvas: TCanvas; X, Y: Integer; …);

    Why isn't that good? It seems to me it can:

    – search for already cached bitmap

    – handle Style

    etc…

    Basically I just need a “Hacked” class of it, because it's protected … but otherwise is it OK to use?

    #59644
    Support
    Keymaster

    Yes, you can use it, but you can use the Draw method also, which is public in the base TCustomImageList class.

    This method calls the DoDraw procedure.

    #59648
    SzakiLaci
    Participant

    [SOLVED]

    This is working perfectly fine 🙂

    Code:
    type
    THackVirtList = class(TsVirtualImageList);

    procedure TFrm_myForm.VSTAfterItemPaint(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode; ItemRect: TRect);
    var
    D: PNodeData; // pointer data for VirtualStringTree node, where you store image-indexes (D.PicIndex) and other data…
    H: THackVirtList;
    begin
    if (csDestroying in Sender.ComponentState) then Exit;
    D := VST.GetNodeData(Node);
    if not Assigned(D) then Exit;

    if (D.WhatKind = fcsPictureNeeded) then begin
    H := THackVirtList(myVirt_Image_List);
    H.DoDraw(D.PicIndex, TargetCanvas, Cellrect.Left + 4, CellRect.Top + 4, 0);
    // you may do here other Canvas draw-effects too
    end
    end;

    … but the new problem is >> if not the VirtualTree is drawing and calculting the image placement >> it won't shift the text to the right place, but starting from the left.

    So it's painting text UNDER the image. 😡

    Edit3: Solution for text alignment problem:

    Code:
    procedure …BeforeCellPaint(…
    if Column = 0 then
    ContentRect.Left := 200;
Viewing 7 posts - 1 through 7 (of 7 total)
  • You must be logged in to reply to this topic.