Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi ListView - automatische Spaltenbreite-Anpassung abfangen (https://www.delphipraxis.net/172789-listview-automatische-spaltenbreite-anpassung-abfangen.html)

eholzer 23. Jan 2013 07:10


ListView - automatische Spaltenbreite-Anpassung abfangen
 
Hallo,

wenn man in der ListView (Detailansicht und ListView hat Focus) Shift+Strg++ drückt, dann wird die erste Spalte and die Breite der Texte angepasst. Das gleiche passiert, wenn man Doppelklick auf den Spaltentrenner im Spaltenkopf macht.
Meine Frage dazu: is es möglich diese Aktionen abzufangen?

Gruß
Eric

ThoPos 23. Jan 2013 07:53

AW: ListView - automatische Spaltenbreite-Anpassung abfangen
 
Hallo Eric,

ich habe mal in einem englischsprachigen Delphi-Forum (Quelle unbekannt) folgende Unit gefunden. Diese erweitert die Standard-Listview um die Events OnBeginColumnResize, OnColumnResize und OnEndColumnResize. Damit reagiere ich in meinen Programmen auf Änderungen der Spaltenbreiten.

Delphi-Quellcode:
unit ExListView;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls;

type
  TLVColumnResizeEvent = procedure(Sender: TCustomListview;
    columnindex: Integer;
    columnwidth: Integer) of object;

  TPBExListview = class(TListview)

  private
    FBeginColumnResizeEvent : TLVColumnResizeEvent;
    FEndColumnResizeEvent  : TLVColumnResizeEvent;
    FColumnResizeEvent     : TLVColumnResizeEvent;

  protected
    procedure DoBeginColumnResize(columnindex, columnwidth: Integer); virtual;
    procedure DoEndColumnResize(columnindex, columnwidth: Integer); virtual;
    procedure DoColumnResize(columnindex, columnwidth: Integer); virtual;
    procedure WMNotify(var Msg: TWMNotify); message WM_NOTIFY;
    function FindColumnIndex(pHeader: pNMHdr): Integer;
    function FindColumnWidth(pHeader: pNMHdr): Integer;
    procedure CreateWnd; override;
  published
    property OnBeginColumnResize: TLVColumnResizeEvent read FBeginColumnResizeEvent write FBeginColumnResizeEvent;
    property OnEndColumnResize: TLVColumnResizeEvent read FEndColumnResizeEvent write FEndColumnResizeEvent;
    property OnColumnResize: TLVColumnResizeEvent read FColumnResizeEvent write FColumnResizeEvent;
  end;

procedure Register;

implementation

uses CommCtrl;

procedure Register;
begin
  RegisterComponents('PBGoodies', [TPBExListview]);
end;

procedure TPBExListview.DoBeginColumnResize(columnindex, columnwidth: Integer);
begin
  if Assigned(FBeginColumnResizeEvent) then
    FBeginColumnResizeEvent(Self, columnindex, columnwidth);
end;

procedure TPBExListview.DoEndColumnResize(columnindex, columnwidth: Integer);
begin
  if Assigned(FEndColumnResizeEvent) then
    FEndColumnResizeEvent(Self, columnindex, columnwidth);
end;

procedure TPBExListview.DoColumnResize(columnindex, columnwidth: Integer);
begin
  if Assigned(FColumnResizeEvent) then
    FColumnResizeEvent(Self, columnindex, columnwidth);
end;

function TPBExListview.FindColumnIndex(pHeader: pNMHdr): Integer;
var
  hwndHeader: HWND;
  iteminfo: THdItem;
  ItemIndex: Integer;
  buf: array [0..128] of Char;
begin
  Result := -1;
  hwndHeader := pHeader^.hwndFrom;
  ItemIndex := pHDNotify(pHeader)^.Item;
  FillChar(iteminfo, SizeOf(iteminfo), 0);
  iteminfo.Mask := HDI_TEXT;
  iteminfo.pszText := buf;
  iteminfo.cchTextMax := SizeOf(buf) - 1;
  Header_GetItem(hwndHeader, ItemIndex, iteminfo);
  if CompareStr(Columns[ItemIndex].Caption, iteminfo.pszText) = 0 then
    Result := ItemIndex
  else
  begin
    for ItemIndex := 0 to Columns.Count - 1 do
      if CompareStr(Columns[ItemIndex].Caption, iteminfo.pszText) = 0 then
      begin
        Result := ItemIndex;
        Break;
      end;
  end;
end;

procedure TPBExListview.WMNotify(var Msg: TWMNotify);
begin
  inherited;
  case Msg.NMHdr^.code of
    HDN_ENDTRACK:
      DoEndColumnResize(FindColumnIndex(Msg.NMHdr),
        FindColumnWidth(Msg.NMHdr));
    HDN_BEGINTRACK:
      DoBeginColumnResize(FindColumnIndex(Msg.NMHdr),
        FindColumnWidth(Msg.NMHdr));
    HDN_TRACK:
      DoColumnResize(FindColumnIndex(Msg.NMHdr),
        FindColumnWidth(Msg.NMHdr));
  end;
end;

procedure TPBExListview.CreateWnd;
var
  wnd: HWND;
begin
  inherited;
  wnd := GetWindow(Handle, GW_CHILD);
  SetWindowLong(wnd, GWL_STYLE,
    GetWindowLong(wnd, GWL_STYLE) and not HDS_FULLDRAG);
end;

function TPBExListview.FindColumnWidth(pHeader: pNMHdr): Integer;
begin
  Result := -1;
  if Assigned(PHDNotify(pHeader)^.pItem) and
    ((PHDNotify(pHeader)^.pItem^.mask and HDI_WIDTH) <> 0) then
    Result := PHDNotify(pHeader)^.pItem^.cxy;
end;

end.
Gruß
Thomas

eholzer 23. Jan 2013 19:12

AW: ListView - automatische Spaltenbreite-Anpassung abfangen
 
Hallo Thomas,

danke für deine Antwort, leider die Ereignise aus deinem Beispiel (OnBeginColumnResize, OnEndColumnResize, OnColumnResize) werden nicht abgefeuert, wenn man die Spaltenbreite-Anpassung startet so wie ich beschrieben habe.

Gruß
Eric

Volker Z. 23. Jan 2013 22:07

AW: ListView - automatische Spaltenbreite-Anpassung abfangen
 
Hallo,

Du könntest mal folgendes Versuchen:

Delphi-Quellcode:
type
  TListView = class (Vcl.ComCtrls.TListView)
  private
    procedure WMNotify (var Msg : TWMNotify); message WM_NOTIFY;
  protected
    procedure KeyDown (var Key : Word; Shift : TShiftState); override;
  end;
im Interfaceteil Deiner Form deklarieren und

Delphi-Quellcode:
uses
  Winapi.CommCtrl;

procedure TListView.WMNotify (var Msg : TWMNotify);
begin
  if Msg.NMHdr.code = HDN_DIVIDERDBLCLICK then
    Exit;

  inherited
end;

procedure TListView.KeyDown (var Key : Word; Shift : TShiftState);
begin
  if (ssShift in Shift) and (ssCtrl in Shift) and (Key = VK_ADD) then
    Key := 0
end;
in Deinen Implementationsteil. Sollte es mit
Delphi-Quellcode:
HDN_DIVIDERDBLCLICK
nicht klappen, dann versuch es mit
Delphi-Quellcode:
HDN_DIVIDERDBLCLICKW
Gruß

eholzer 24. Jan 2013 19:59

AW: ListView - automatische Spaltenbreite-Anpassung abfangen
 
Hallo Volker,

danke, das ist genau was ich gesucht habe.

Eric


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:59 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz