我用了一个具有排序功能的LISTVIEW 控件,是继承自 LISTVIEW 的, 我想让这个自定义的控件也能具有XP风格,就是利用 DELPHI 自带的 XPMAN 时,有XP效果,但总是报错,请各位大侠帮忙看看吧,不胜感激!错误信息: raised exception class EStackOverFlow with message 'Stack OverFlow';出错的地方提示是:ComCtrls 的  Result := CallWindowProc(FDefHeaderProc, FHeaderHandle, Msg, WParam, LParam);我的代码:
-----------------------------------------------------------------------------------------
unit SortListView;
interface
uses
  Windows, SysUtils, Messages, Classes, Graphics, Controls, ComCtrls, CommCtrl;type
  TSortListView = class;  TSortListView = class(TListView)
  private
    FaToz    :Boolean;
    FoldCol  :Integer;
    FPicture :TPicture;
    procedure DrawHeaderItem(pDS:PDrawItemStruct);
    procedure SetHeaderStyle(phd:PHDNotify);
    procedure SetPicture(Value: TPicture);
    procedure PictureChanged(Sender: TObject);
    procedure LCustomDraw(Sender: TCustomListView; const ARect: TRect; var DefaultDraw: Boolean);//virtual;
    procedure DrawBack;
  protected
    procedure WndProc(var Message : TMessage); override;
  public
    constructor Create(AOwner: TComponent); override;
    procedure CreateWnd; override;
    destructor Destroy; override;
    procedure SortColumn(Column: TListColumn);
  published
    property BackPicture: TPicture read FPicture write SetPicture;
  end;procedure Register;implementationprocedure Register;
begin
  RegisterComponents('SortListView', [TSortListView]);
end;constructor TSortListView.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FPicture:=TPicture.Create;
  FPicture.OnChange:=PictureChanged;
  OnCustomDraw:=LCustomDraw;
end;
procedure TSortListView.CreateWnd;
begin
  inherited CreateWnd;
  if HandleAllocated then HandleNeeded;
end;destructor TSortListView.Destroy;
begin
  FPicture.Free;
  inherited Destroy;
end;procedure TSortListView.SetPicture(Value: TPicture);
begin
  FPicture.Assign(Value);
end;procedure TSortListView.PictureChanged(Sender: TObject);
begin
  Invalidate;
end;procedure TSortListView.LCustomDraw(Sender: TCustomListView; const ARect: TRect; var DefaultDraw: Boolean);begin
  if (FPicture.Graphic<>nil)then begin
     DrawBack;
     SetBkMode(Canvas.Handle,TRANSPARENT);
     ListView_SetTextBKColor(Handle,CLR_NONE);
  end;
end;procedure TSortListView.DrawBack;
var x,y,dx: Integer;
begin
  x:=0;
  y:=0;
  if Items.Count>0 then begin
      if ViewStyle = vsReport then x:=TopItem.DisplayRect(drBounds).Left
      else x:=Items[0].DisplayRect(drBounds).Left;
      y:=Items[0].DisplayRect(drBounds).Top - 2;
  end;
  if X>0 then x:=0;
  dx:=x;
  while y<=ClientHeight do begin
    while x<=ClientWidth do begin
          Canvas.Draw(x,y,FPicture.Graphic);
          inc(x,FPicture.Graphic.Width);
    end;
    inc(y,FPicture.Graphic.Height);
    x:=dx;
  end;
end;
//==================================================================
procedure TSortListView.WndProc(var Message : TMessage);
var pDS :PDrawItemStruct;
    phd :PHDNotify;
begin
  inherited WndProc(Message);
  with Message do
    case Msg of
    WM_DRAWITEM :
      begin
      pDS := PDrawItemStruct(Message.lParam);
      if pDS.CtlType<>ODT_MENU then begin
           DrawHeaderItem(pDS);
           Result := 1;
         end;
      end;
    WM_NOTIFY:
      begin
      phd := PHDNotify(Message.lParam);
      if (phd.Hdr.hwndFrom = GetDlgItem(Handle, 0)) then
        Case phd.Hdr.code of
          HDN_ITEMCLICK,HDN_ITEMCLICKW:
            begin
              SortColumn(Columns.Items[phd.item]);
              InvalidateRect(GetDlgItem(Handle, 0), nil, true);
            end;
          HDN_ENDTRACK,HDN_ENDTRACKW,HDN_ITEMCHANGED:
            Begin
              SetHeaderStyle(phd);
            end;
        end;
      end;
  end;
end;//=====================================================================
var   AtoZOrder: Boolean;
function CustomSortProc(Item1, Item2: TListItem; ParamSort: Integer): Integer; stdcall;
begin
  case ParamSort of
    0:
    if AtoZOrder then
      Result := lstrcmp(PChar(TListItem(Item1).Caption), PChar(TListItem(Item2).Caption))
    else
      Result := -lstrcmp(PChar(TListItem(Item1).Caption), PChar(TListItem(Item2).Caption));
  else
    if(AtoZOrder) then
      Result := lstrcmp(PChar(TListItem(Item1).SubItems[ParamSort-1]), PChar(TListItem(Item2).SubItems[ParamSort-1]))
    else
      Result := -lstrcmp(PChar(TListItem(Item1).SubItems[ParamSort-1]), PChar(TListItem(Item2).SubItems[ParamSort-1]));
  end;
end;procedure TSortListView.SortColumn(Column: TListColumn);
begin
  if FOldCol = Column.Index then
    FaToz := not FAtoZ
  else
    FOldCol := Column.Index;
  AtoZOrder := FaToz;
  CustomSort(@CustomSortProc, Column.Index);
end;
//=====================================================================procedure TSortListView.DrawHeaderItem(pDS :PDrawItemStruct);
var
    tmpCanvas :TCanvas;
    tmpLeft :Integer;
begin
  tmpCanvas := TCanvas.Create;
  tmpCanvas.Handle:=pDS.hDC;
  tmpCanvas.Brush.Style:=bsClear;
  tmpCanvas.TextOut(pDS^.rcItem.Left+6,pDS^.rcItem.Top+2,Columns[pDS^.itemID].Caption);
  if (abs(pDS^.itemID) <> FOldCol) then Exit;
  with tmpCanvas do
      with pDS^.rcItem do
        begin
          tmpLeft := TextWidth(Columns[pDS^.itemID].Caption) + Left + 16;
          if FAtoZ then
          begin
            Pen.Color := clBtnHighlight;
            MoveTo(tmpLeft, Bottom - 5);
            LineTo(tmpLeft + 8, Bottom - 5);
            Pen.Color := clBtnHighlight;
            LineTo(tmpLeft + 4, Top + 5);
            Pen.Color := clBtnShadow;
            LineTo(tmpLeft, Bottom - 5);
        end else
        begin
            Pen.Color := clBtnShadow;
            MoveTo(tmpLeft, Top + 5);
            LineTo(tmpLeft + 8, Top + 5);
            Pen.Color := clBtnHighlight;
            LineTo(tmpLeft + 4, Bottom - 5);
            Pen.Color := clBtnShadow;
            LineTo(tmpLeft, Top + 5);
       end;
      end;
  tmpCanvas.Free;
end;procedure TSortListView.SetHeaderStyle(phd:PHDNotify);
var
    i :integer;
  hdi :THDItem;
begin
  for i := 0 to Columns.Count - 1 do
    begin
      hdi.Mask:= HDF_STRING or HDI_FORMAT;
      hdi.fmt := HDF_STRING or HDF_OWNERDRAW;
      Header_SetItem(phd.Hdr.hwndFrom, i, hdi);
    end;
end;
//=====================================================================
end.

解决方案 »

  1.   

    代码这么多,看不过来
    摘自别处:
    type
        PSortInfo = ^TSortInfo;
        TSortInfo = record
            Col     : Integer;
            Style   : TSortStyle;
            Asc     : Boolean;
        end;function  ListViewCompare(I1, I2: TListItem; Data: Integer): Integer; stdcall;
    var
        V1, V2: string;    function    Sign(Val: Extended): Integer;
        begin
            if Val < 0 then
                Result := -1
            else if Val > 0 then
                Result := 1
            else
                Result := 0;
        end;    function    ExtractNum(const S: string): string;
        var
            i, j: Integer;
        begin
            j := 0;
            for i := 1 to Length(S) do
                if S[i] in ['0'..'9'] then
                    Inc(j)
                else
                    Break;
            if j = 0 then
                Result := '0'
            else
                Result := Copy(S,1,j);
        end;
    begin
        with PSortInfo(Data)^ do
        begin        if Col = 0 then
            begin
                V1 := I1.Caption;
                V2 := I2.Caption;
            end
            else
            begin
                V1 := I1.SubItems[Col-1];
                V2 := I2.SubItems[Col-1];
            end;        case Style of
                ssAlpha     : Result := AnsiCompareText(V1,V2);
                ssNumeric   : Result := Sign(StrToFloat(ExtractNum(V1))-StrToFloat(ExtractNum(V2)));
                ssDateTime  : Result := Sign(StrToDateTime(V1) - StrToDateTime(V2));
            else
                Result := 0;
            end;        if not Asc then
                Result := -Result;
        end;
    end;procedure SortListView(ListView:TListView; ColumnIndex:Integer;
                           Style: TSortStyle; Ascending: Boolean=True);
    {排序ListView,ColumnIndex:排序列索引号,
     Style 排序方式:按字符,按数值,按日期(日期格式为
     SysUtils.ShortDataTimeFmt,缺省为YY-MM-DD);
     Ascending:=True按升序,否则按降序}
    var
      FSortInfo:TSortInfo;
    begin
        FSortInfo.Col   := ColumnIndex;
        FSortInfo.Style := Style;
        FSortInfo.Asc   := Ascending;
        ListView.CustomSort(@ListViewCompare,LongInt(@FSortInfo));
    end;
      

  2.   

    我想知道你的listview在哪里找到的呢?我找半天都没找到