Kilka ListView i blokada zmiany rozmiaru kolumn

0

Witam. Ten kod na http://www.swissdelphicenter.ch/torry/showcode.php?id=2133 oczywiście działa,
jednak tylko dla jednego ListView. Jeżeli mamy kilka ListView na przykład na zakładkach PageControla
i chcemy zablokować możliwosć zmian rozmiaru każdej z nich to w funkcji GetIndex nalezy zmienić - z
ListView1 na jakąś zmienną globalną, która np. przy zmianie zakładki PageCOntrol również się zmieni.
No i wszystko też działa, ale do czasu zamknięcia programu. Pokazuje mi się komunikat że nie można
znaleźć dojścia okna. Problem chyba tkwi w tym że trzeba na powrót ustawić to co widać w zdarzeniu
FormCloseQuery. Próbowałem w osobnym programie zrobić sobie, dla póby 2 ListViewy i 2 elementową
tablicę TWndMethod, komunikatu o błędzie przy wyjściu nie ma, ale PageControl nie pokazuje się mi na
drugiej zakładce w ogóle ListView. Myślee że to chyba przez linijki WndMethod(aMesg); A dodałem tam
wprawdzie beginy i endy oraz zmieniłem na WndMethod1; i WndMethod2; lecz tak
jak piszę - nie pokazują się inne ListViewy poza jednym. Jak ktoś wie jak poprawić ten kod aby działał
dla więcej niż jednego ListView to prosił bym o jakieś wskazówki. Z góry dziękuję za wszelką pomoc

0

Dostałem już odpowiedź na innym forum. Należy użyć pewnej klasy, w
taki sposób jak poniżej oraz TList. Poniżej kod jakby ktoś potrzebował.

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    ListView1: TListView;
    ListView2: TListView;
    procedure FormShow(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  private
    FList: TList;
  public
  end;

  TMsgProxy = class
    public
      constructor Create (LV : TListView);
      destructor Destroy; override;
    private
      FListView : TListView;
      fOldWndMethod : TWndMethod;
      function GetIndex(aNMHdr: pNMHdr) : Integer;
      procedure CheckMesg(var aMesg : TMessage);
  end;

var
  Form1: TForm1;

implementation

uses
  CommCtrl;

{$R *.dfm}

procedure TForm1.FormShow(Sender: TObject);
begin
  FList := TList.Create;
  FList.Add(TMsgProxy.Create(ListView1));
  FList.Add(TMsgProxy.Create(ListView2));
end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
var
  T : integer;
begin
  for T := 0 to FList.Count - 1 do
  begin
    TMsgProxy(FList[t]).Free;
  end;
  FreeAndNil(FList);
end;

{TMsgProxy}

procedure TMsgProxy.CheckMesg(var aMesg: TMessage);
var
  HDNotify: ^THDNotify;
  NMHdr: pNMHdr;
  iCode: Integer;
  iIndex: Integer;
begin
  case aMesg.Msg of
    WM_NOTIFY:
      begin
        HDNotify := Pointer(aMesg.lParam);

        iCode := HDNotify.Hdr.code;

        if (iCode = HDN_BEGINTRACKW) or
          (iCode = HDN_BEGINTRACKA) then
        begin
          NMHdr := TWMNotify(aMesg).NMHdr;
          // chekck column index
          iIndex := GetIndex(NMHdr);
          if iIndex < FListView.Columns.Count then
            aMesg.Result := 1;
        end
        else
          fOldWndMethod(aMesg);
      end;
    else
      fOldWndMethod(aMesg);
  end;
end;

constructor TMsgProxy.Create(LV: TListView);
begin
   FListView := LV;
   fOldWndMethod := LV.WindowProc;
   LV.WindowProc := CheckMesg;
end;

destructor TMsgProxy.Destroy;
begin
  FListView.WindowProc := fOldWndMethod;
  inherited;
end;

function TMsgProxy.GetIndex(aNMHdr: pNMHdr): Integer;
var
  hHWND: HWND;
  HdItem: THdItem;
  iIndex: Integer;
  iResult: Integer;
  iLoop: Integer;
  sCaption: string;
  sText: string;
  Buf: array [0..128] of Char;
begin
  Result := -1;

  hHWND := aNMHdr^.hwndFrom;

  iIndex := pHDNotify(aNMHdr)^.Item;

  FillChar(HdItem, SizeOf(HdItem), 0);
  with HdItem do
  begin
    pszText    := Buf;
    cchTextMax := SizeOf(Buf) - 1;
    Mask       := HDI_TEXT;
  end;

  Header_GetItem(hHWND, iIndex, HdItem);

  with FListView do
  begin
    sCaption := Columns[iIndex].Caption;
    sText    := HdItem.pszText;
    iResult  := CompareStr(sCaption, sText);
    if iResult = 0 then
      Result := iIndex
    else
    begin
      iLoop := Columns.Count - 1;
      for iIndex := 0 to iLoop do
      begin
        iResult := CompareStr(sCaption, sText);
        if iResult <> 0 then
          Continue;

        Result := iIndex;
        break;
      end;
    end;
  end;
end;

end.

1 użytkowników online, w tym zalogowanych: 0, gości: 1