Witam

Mam pytania co do artykułu:
http://4programmers.net/Delphi/Artykuły/Wywołanie_funkcji_zwrotnych_z_klasy

Jak zrobić klasę w której:

  1. Tworzę kontrolkę np. ListView.
  2. Subclassuję ją.
  3. Zapamiętuję "starą" procedurę obsługi komunikatów.
  4. W nowej procedurze robię to co muszę i odpalam CallWindowProc kiedy zajdzie potrzeba.
  5. Nowa procedura musi mieć dostęp do zmiennych i metod z klasy.

Zrobiłem sobie klasę dla głównego okna i wszystko ładnie śmiga.
Problem jest natomiast z klasą dla ListView.
Niby po subclassingu nowa procedura działa, ale jak próbuję się odwołać do jakiejś zmiennej z klasy to się włącza klepsydra, aplikacja coś chwilę pomieli i się wyłącza bez żadnego okna błędu.

Zamieszczam kodzik:

unit CListView;

interface

uses Windows, Messages, CommCtrl;

type
  TListView = class
  private
    FHandle, FParentHandle: HWND;
    FListViewOldProc: TFNWndProc;
    function ListViewProc(uMsg: UINT; wPar: WPARAM; lPar: LPARAM): LRESULT; stdcall;
  public
    constructor Create; overload;
    function CreateWnd(const hParentWnd: HWND; const iX, iY, iW, iH: Integer): Boolean;
    property Handle: HWND read FHandle;
    property ParentHandle: HWND read FParentHandle;
end;

implementation

constructor TListView.Create;
begin
  FHandle := 0;
  FParentHandle := 0;
  FLabelEditOldProc := nil;
end;

function TListView.ListViewProc(uMsg: UINT; wPar: WPARAM; lPar: LPARAM): LRESULT; stdcall;
var
 hWindow: HWND;
 Ret: Integer;
begin
  Result := 0;
  hWindow := Integer(Self);
  Ret := GetWindowLong(hWindow, GWL_USERDATA);
  if (Ret <> 0) then Self := TListView(Ret)
  else Self := TListView(PCREATESTRUCT(lPar)^.lpCreateParams);
  case uMsg of
    WM_CREATE:
    begin
      SetWindowLong(hWindow, GWL_USERDATA, Integer(PCREATESTRUCT(lPar)^.lpCreateParams));
    end;
    WM_LBUTTONDBLCLK:
    begin
      MessageBeep(5000); //To śmiga
    end;
    else Result := CallWindowProc(Self.FListViewOldProc, FHandle, uMsg, wPar, lPar);
  end;
end;

function TListView.CreateWnd(const hParentWnd: HWND; const iX, iY, iW, iH: Integer): Boolean;
var
  CS: TCreateStruct;
begin
  FParentHandle := hParentWnd;
  CS.lpCreateParams := Self;
  FHandle := CreateWindowEx(WS_EX_CLIENTEDGE, WC_LISTVIEW, nil, WS_CHILD or WS_VISIBLE or LVS_REPORT or LVS_NOCOLUMNHEADER or LVS_SINGLESEL, iX, iY, iW, iH, FParentHandle, 0, hInstance, Self);
  if (FHandle <> 0) then
  begin
    ListView_SetExtendedListViewStyle(FHandle, LVS_EX_CHECKBOXES or LVS_EX_GRIDLINES);
    FListViewOldProc := Pointer(SetWindowLong(FHandle, GWL_WNDPROC, Integer(@TListView.ListViewProc)));
    SendMessage(FHandle, WM_CREATE, 0, Integer(@CS));
  end;
  Result := (FHandle <> 0);
end;

EDIT: Poprawiłem kod, działa, ale czy to dobre rozwiązanie?