AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi TListView - Problem mit HotTrack und Selektion bei Verwendung AdvancedCustomDrawItem
Thema durchsuchen
Ansicht
Themen-Optionen

TListView - Problem mit HotTrack und Selektion bei Verwendung AdvancedCustomDrawItem

Ein Thema von eholzer · begonnen am 27. Jan 2013 · letzter Beitrag vom 1. Feb 2013
Antwort Antwort
eholzer

Registriert seit: 22. Okt 2009
51 Beiträge
 
#1

TListView - Problem mit HotTrack und Selektion bei Verwendung AdvancedCustomDrawItem

  Alt 27. Jan 2013, 19:44
Hallo,

ich habe ein Problem (eigentlich sind zwei) mit der ListView, wenn ich AdvancedCustomDrawItem verwende.
Wichtig: die Theme ist abgeschaltet with SetWindowTheme(Handle, 'explorer', '').

Problem 1:
In der ListView sollte HotTrack aktiv sein - in meiner ListView der HotTrack erscheint kurz und dann verschwindet. Wenn man kein AdvancedCustomDrawItem verwendet, dann der HotTrack ist die ganze Zeit sichtbar (wenn der Mauszeiger über dem Text ist).

Problem2:
Ich möchte gerne, dass die Selektion mit der Maus erfolgt in dem ganzen Spaltenbereich. Die ListView reagiert aber auf Mausklicks genauso, wie ohne AdvancedCustomDrawItem. ListView erlaubt den Selektionsbereich abzufragen Item.DisplayRect( drSelectBounds ), gibt es vielleicht die Möglichkeit den Selektionsbereich festzusetzen? Wenn nicht, wie kann man trotzdem so was erreichen?

Danke
Eric

Delphi XE2 on Win7/Win8

Delphi-Quellcode:
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.ComCtrls, Vcl.Themes, UxTheme;

type TmyListView = class(TListView)

      private
         procedure DrawShortedCaption(Sender: TCustomListView;
                        Item: TListItem; State: TCustomDrawState; Stage: TCustomDrawStage;
                        var DefaultDraw: Boolean);
      protected
        Procedure CreateWnd; Override;
        procedure InternalAdvancedCustomDrawItem(Sender: TCustomListView;
                        Item: TListItem; State: TCustomDrawState; Stage: TCustomDrawStage;
                        var DefaultDraw: Boolean);
      public
        constructor Create(AOwner: TComponent);override;
        destructor Destroy; override;
end;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }

    FListView: TmyListView;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}


procedure TForm1.FormCreate(Sender: TObject);
var col: TListColumn;
    litem: TListItem;
    i,j: integer;
    s: string;
    c: word;
begin
   FListView := TmyListView.Create(Self);
   FListView.Parent := Panel1;

   col := FListView.Columns.Add;
   col.Caption := 'COL1';
   col.Width := 200;
   col := FListView.Columns.Add;
   col.Caption := 'COL2';
   col := FListView.Columns.Add;
   col.Caption := 'COL3';
   col.Width := 250;

   FListView.ViewStyle := vsReport;

   for i := 0 to 100 do
   begin
     litem := FListView.Items.Add;
     s := '';
     for j := 0 to Random(25) do
     begin
        c := Random(Succ(90 - 65)) + 65;
        s := s + Chr(c);
     end;
     litem.Caption := s;
     litem.SubItems.Add('A'+IntToStr(i+1)+ '_1');
     litem.SubItems.Add('A'+IntToStr(i+1)+ '_2');
   end;
end;



//=========================== TmyListView ========================
Constructor TmyListView.Create(AOwner:TComponent);

begin
  inherited Create(AOwner);

  OnAdvancedCustomDrawItem := InternalAdvancedCustomDrawItem;
  Align := alClient;
  MultiSelect := true;
  RowSelect := false;
  DoubleBuffered := true;
  HoverTime := 0;
  HotTrack := false;
  HotTrackStyles := [htHandPoint, htUnderlineHot];


end;

procedure TmyListView.CreateWnd;
begin

  inherited CreateWnd;
  SetWindowTheme(Handle, 'explorer', '');

end;

destructor TmyListView.Destroy;
begin


  inherited Destroy;
end;

procedure TmyListView.InternalAdvancedCustomDrawItem(Sender: TCustomListView;
                        Item: TListItem; State: TCustomDrawState; Stage: TCustomDrawStage;
                        var DefaultDraw: Boolean);
begin
  if not Assigned(Item) then exit;
  Case Stage of
      cdPrePaint:
        begin

        end;

      cdPostPaint:
        begin
          DrawShortedCaption(Sender, Item, State, Stage, DefaultDraw );
        end;
  End;
end;

procedure TmyListView.DrawShortedCaption(Sender: TCustomListView;
                        Item: TListItem; State: TCustomDrawState; Stage: TCustomDrawStage;
                        var DefaultDraw: Boolean);
var R: TRect;
    labelRect: TRect;
    focusBorderRect: TRect;
    displayName: string;
    lblWidth: integer;

    procedure DefineCanvasColors(ACanvas: TCanvas;Item: TListItem; State: TCustomDrawState);
    begin
       if Item.Selected then begin
            if Item.Focused then
                ACanvas.Brush.Color := clGray
            else
                ACanvas.Brush.Color := clLtGray;
            ACanvas.Font.Color := ColorToRGB(clWindowText);
            if cdsHot in State then
               ACanvas.Font.Color := ColorToRGB(clGreen);
      end
      else if Item.Focused then begin
            ACanvas.Brush.Color := ColorToRGB(clMaroon);
            ACanvas.Font.Color := ColorToRGB(clWhite);
      end
      else if cdsHot in State then begin
            ACanvas.Brush.Color := ColorToRGB(clHotLight);
            ACanvas.Font.Color := ColorToRGB(clHighlightText);
      end
    end;

    procedure DrawBox( Canvas: TCanvas; Bounds: TRect; Color: TColor );
    begin
      Canvas.Pen.Color := Color;

      Canvas.MoveTo( Bounds.Left, Bounds.Top );
      Canvas.LineTo( Bounds.Left, Bounds.Bottom );

      Canvas.MoveTo( Bounds.Left, Bounds.Top );
      Canvas.LineTo( Bounds.Right, Bounds.Top );

      Canvas.MoveTo( Bounds.Right - 1, Bounds.Top );
      Canvas.LineTo( Bounds.Right - 1, Bounds.Bottom );

      Canvas.MoveTo( Bounds.Left, Bounds.Bottom - 1 );
      Canvas.LineTo( Bounds.Right, Bounds.Bottom - 1 );
    end;

begin
   Sender.Canvas.Lock;
   try
     R := Item.DisplayRect( drLabel );

     DefineCanvasColors(Sender.Canvas, Item, State);

     displayName := Item.Caption;
     focusBorderRect := R;
     Sender.Canvas.FillRect(R);

     labelRect := R;
     labelRect.Left := labelRect.Left +2;

     DrawText(Sender.Canvas.Handle, displayName, Length(displayName),labelRect,
                DT_END_ELLIPSIS or DT_SINGLELINE or DT_NOPREFIX or DT_VCENTER);

     if Item.Focused then
         DrawBox(Sender.Canvas, focusBorderRect, ColorToRGB(clBlack))
     else if Item.Selected then
         DrawBox(Sender.Canvas, focusBorderRect, ColorToRGB(clPurple));

     //SetBkMode(Sender.Canvas.Handle, TRANSPARENT); // important if theme active
     DefaultDraw := false;

    finally
       Canvas.Unlock;
    end;

end;



end.
  Mit Zitat antworten Zitat
eholzer

Registriert seit: 22. Okt 2009
51 Beiträge
 
#2

AW: TListView - Problem mit HotTrack und Selektion bei Verwendung AdvancedCustomDrawI

  Alt 29. Jan 2013, 09:44
Hi,

keine Ideen, wie man richtig HotTrack selber zeichnet?
Mich würde auch eine Info freuen, wie man den HotTrack bei der aktiven Theme richtig steuern kann (aktivieren, deaktiviren).

Danke
Eric
  Mit Zitat antworten Zitat
Volker Z.

Registriert seit: 4. Dez 2012
Ort: Augsburg, Bayern, Süddeutschland
419 Beiträge
 
Delphi XE4 Ultimate
 
#3

AW: TListView - Problem mit HotTrack und Selektion bei Verwendung AdvancedCustomDrawI

  Alt 29. Jan 2013, 15:28
Hallo,

Zitat:
Problem 1:
In der ListView sollte HotTrack aktiv sein - in meiner ListView der HotTrack erscheint kurz und dann verschwindet. Wenn man kein AdvancedCustomDrawItem verwendet, dann der HotTrack ist die ganze Zeit sichtbar (wenn der Mauszeiger über dem Text ist).
Füge doch mal folgendes vor dem Canvas.Lock in Deine Methode DrawShortedCaption ein:
Delphi-Quellcode:
  if cdsHot in State then
    Exit;
  
  Sender.Canvas.Lock;
Zitat:
Problem2:
Ich möchte gerne, dass die Selektion mit der Maus erfolgt in dem ganzen Spaltenbereich. Die ListView reagiert aber auf Mausklicks genauso, wie ohne AdvancedCustomDrawItem. ListView erlaubt den Selektionsbereich abzufragen Item.DisplayRect( drSelectBounds ), gibt es vielleicht die Möglichkeit den Selektionsbereich festzusetzen? Wenn nicht, wie kann man trotzdem so was erreichen?
Mir ist im Moment keine Möglichkeit geläufig, die Spaltenbreite auf eine fixe Breite trimmt. Du kannst aber mal versuchen, ob folgender Code Dein Problem lösen würde.
Delphi-Quellcode:
  TmyListView = class(TListView)
    private
      procedure MouseMove (Shift: TShiftState; X, Y: Integer); override;

procedure TmyListView.MouseMove (Shift: TShiftState; X: Integer; Y: Integer);
var
  i : TListItem;
begin
  inherited MouseMove (Shift, X, Y);

  if X < Columns [0].Width then
    begin
      i := GetItemAt (4, Y); // das mit der 4 ist nicht schön, vielleicht Intervall-Halbierung
      if Assigned (i) then
        SendMessage (Handle, LVM_SETHOTITEM, i.Index, 0)
    end
end;
Gruß
Volker Zeller
  Mit Zitat antworten Zitat
eholzer

Registriert seit: 22. Okt 2009
51 Beiträge
 
#4

AW: TListView - Problem mit HotTrack und Selektion bei Verwendung AdvancedCustomDrawI

  Alt 1. Feb 2013, 14:31
Danke Volker für die Antwort.

Wenn jemand an der Lösung für HotTrack interessiert ist: https://forums.embarcadero.com/threa...82449&tstart=0.
  Mit Zitat antworten Zitat
Antwort Antwort

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:58 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz