Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

TListView - OnAdvancedCustomDrawItem Shadowed Text

Posted on 2010-09-22
5
Medium Priority
?
1,401 Views
Last Modified: 2013-12-03
I have a TListView working like the Windows desktop. Basically icons with text underneath. The end user is also able to set their own background.

Now, like the Windows desktop I want to add a shadow to the icons caption. This is because if part of the background is white or a light color, the text will be very hard to see.

So, I wanted to use the AdvancedCustomDrawItem with the Stage being cdPostPaint. This way the item is already painted and I could do just the shadowing.

Now, I need the area which the caption is drawn. So I thought to use:

IconCaptionArea := Item.DisplayRect(drLabel);

Open in new window


But, this doesn't return anything but null values. I stepped through the code and ListView_GetItemRect() returns True but the rect is full of zero's.

Any ideas? I'd also accept workarounds as well.
0
Comment
Question by:ThievingSix
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
5 Comments
 
LVL 32

Accepted Solution

by:
Ephraim Wangoya earned 2000 total points
ID: 33750443
I tried the DisplayRect and it returned the correct TRect, both in Delphi7 and Delphi2010

procedure TForm1.ListView1AdvancedCustomDrawItem(Sender: TCustomListView;
  Item: TListItem; State: TCustomDrawState; Stage: TCustomDrawStage;
  var DefaultDraw: Boolean);
var
  R: TRect;
  PrevCanvas: Graphics.TCanvas;

  procedure DrawSample3D(const ACanvas : TCanvas; const ACaption: string;
    const X, Y: Integer; const AColor : TColor);
  begin
    ACanvas.Brush.Style := bsClear;
    ACanvas.Pen.Mode := pmCopy;
    ACanvas.Pen.Style := psSolid;
    //Dark Shadow
    ACanvas.Font.Color := clGray;
    ACanvas.TextOut(X + 1, Y + 1, ACaption);
    //Light Shadow
    ACanvas.Font.Color := clWhite;
    ACanvas.TextOut(X - 1, Y - 1, ACaption);
    //Text
    ACanvas.Font.Color := AColor;
    ACanvas.TextOut(X, Y, ACaption);
  end;

begin
  R := Item.DisplayRect(drLabel);
  DrawSample3D(Sender.Canvas, Item.Caption, R.Left + 2, R.Top, clBlack);
end;
0
 
LVL 13

Author Comment

by:ThievingSix
ID: 33750933
How weird, it seems that when stepping through the first few iterations it returns a blank rect. But it eventually fills on a later call to CustomDraw().

Below is what I'm using now. Too bad it doesn't work with long single words. Turns out like:
procedure TfrmDesktop.lvDesktopManagerCustomDrawItem(Sender: TCustomListView;
  Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
var
  IconCaptionArea : TRect;
  IconCaption : String;
  OStyle : TBrushStyle;
  OColor : TColor;
  DrawFlags : DWORD;
begin
  IconCaptionArea := Item.DisplayRect(drLabel);
  With IconCaptionArea Do
    begin
    Left := Left + 3;
    Top := Top + 1;
  end;
  With Sender.Canvas Do
    begin
    OStyle := Brush.Style;
    OColor := Font.Color;
    Try
      Brush.Style := bsClear;
      Font.Color := InverseColor(OColor);
      FillRect(IconCaptionArea);
      IconCaption := Item.Caption;
      UniqueString(IconCaption);
      FillRect(IconCaptionArea);
      DrawFlags := DT_TOP Or DT_NOPREFIX Or DT_EDITCONTROL Or DT_CENTER Or
                   DT_WORDBREAK Or DT_WORD_ELLIPSIS Or DT_END_ELLIPSIS Or
                   DT_INTERNAL;
      DrawText(Handle, IconCaption, -1, IconCaptionArea, DrawFlags);
    Finally
      Brush.Style := OStyle;
      Font.Color := OColor;
    end;
  end;
end;

Open in new window

Untitled.png
0
 
LVL 13

Author Closing Comment

by:ThievingSix
ID: 33750939
Can't believe I believed it didn't work.
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

What do responsible coders do? They don't take detrimental shortcuts. They do take reasonable security precautions, create important automation, implement sufficient logging, fix things they break, and care about users.
If you are a mobile app developer and especially develop hybrid mobile apps then these 4 mistakes you must avoid for hybrid app development to be the more genuine app developer.
Six Sigma Control Plans
Introduction to Processes
Suggested Courses

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question