Dylan
Dylan

Reputation: 1183

How to use this CustomSort function to sort listview?

If customsort function is passed in with a variable, it seems it will access violation.


public 
...
col: integer;
...

Procedure listviewcol;
begin
  col:=5
...
end;

procedure TForm1.sortcol(listview: tlistview);
  function CustomSortProc(Item1,Item2: TListItem;
    OptionalParam: integer): integer;stdcall;
  begin
    Result := AnsiCompareText(Item2.subitems.Strings[col], Item1.subitems.Strings[col]);
  end;
begin
  ListView.CustomSort(@CustomSortProc,0);
end;

This will prompt errors. // access violation

But if we change col in AnsicompareText to 5, it works well.

procedure TForm1.sortcol(listview: tlistview);
  function CustomSortProc(Item1,Item2: TListItem;
    OptionalParam: integer): integer;stdcall;
  begin
    Result := AnsiCompareText(Item2.subitems.Strings[5], Item1.subitems.Strings[5]);// it works.
  end;
begin
  ListView.CustomSort(@CustomSortProc,0);
end;

How to fix it. Please help. Thanks a lot.

Upvotes: 2

Views: 2058

Answers (2)

Sertac Akyuz
Sertac Akyuz

Reputation: 54772

You cannot access col inside the callback function, it is not a method of your form. Your trick of nesting the callback in a method is futile. ;) If you need to access form fields then use the OptionalParam to be able to refer to your form in the callback.

begin
  ListView.CustomSort(@CustomSortProc, Integer(Self));
  [...]

function CustomSortProc(Item1,Item2: TListItem;
  OptionalParam: integer): integer; stdcall;
var
  Form: TForm1;
begin
  Form := TForm1(OptionalParam);
  Result := AnsiCompareText(Item2.subitems.Strings[Form.col],
      Item1.subitems.Strings[Form.col]);

Of course you can send the value of col in 'OptionalParam' if that's the only thing you need. Or, you can make 'col' a global variable instead of a field, or use the 'Form1' global variable itself which the IDE puts just before the implementation section if it's not commented out.

You can also make use of the OnCompare event.

Upvotes: 5

kludg
kludg

Reputation: 27493

Pass col as OptionalParam:

function CustomSortProc(Item1,Item2: TListItem; col: integer): integer;stdcall;
begin
  Result := AnsiCompareText(Item2.subitems.Strings[col], Item1.subitems.Strings[col]);
end;

begin
  ListView.CustomSort(@CustomSortProc, col);
end;

Or use Sertac answer - he was faster :)

Upvotes: 2

Related Questions