tlistview 排序 问题 请问一下,一些C写的程序排序(如windows资源管理器)的时候那个排序的那一列的标题会变出个排序的符号来,用于表示排序是降序还是升序。请问那个符合是字符还是需要画出来的?还是要对列表的句柄发送某个消息就会给系统就会自动画出来的? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 画出来的,要自己画,Listview有个Header的,你要找到那个Head画在上面,找的方法如下Header:= FindwindowEx(Listview.handle,0,'SysHeader32',nil);然后再画吧 unit SortListView;interfaceuses SysUtils, Classes, Controls, ComCtrls,CommCtrl, Graphics, Windows, Messages;type TSortListView = class(TListView) private { Private declarations } FaToz :Boolean; FoldCol :Integer; FPicture :TPicture; FHeaderFont:TFont; procedure SetHeaderFont(Value:TFont); procedure SetHeaderStyle(phd:PHDNotify); procedure DrawHeaderItem(pDS:PDrawItemStruct); procedure SetPicture(Value: TPicture); procedure PictureChanged(Sender: TObject); procedure LVCustomDraw(Sender:TCustomListView;const ARect:TRect;var DefaultDraw:Boolean); procedure DrawBack; protected { Protected declarations } procedure WndProc(var Message : TMessage); override; public { Public declarations } constructor Create(AOwner: TComponent); override; destructor Destroy; override; procedure SortColumn(Column: TListColumn); published { Published declarations } property BackPicture: TPicture read FPicture write SetPicture; property HeaderFont: TFont read FHeaderFont write SetHeaderFont; end;procedure Register;implementationprocedure Register;begin RegisterComponents('Samples', [TSortListView]);end;//============== 构造函数 ===================================constructor TSortListView.Create(AOwner: TComponent);begin inherited Create(AOwner);//继承 FHeaderFont:=TFont.Create; FPicture:=TPicture.Create; FPicture.OnChange:=PictureChanged; OnCustomDraw:=LVCustomDraw;end;//============== 析构函数 ===================================destructor TSortListView.Destroy;begin FPicture.Free; FHeaderFont.Free; inherited Destroy;//继承end;//============== 设置表头字体 ===============================procedure TSortListView.SetHeaderFont(Value:TFont);begin //转换表头字体设置,将值给FHeaderFomt私有数据域,并重绘表头区域 if FHeaderFont <> Value then begin FHeaderFont.Assign(Value); InvalidateRect(GetDlgItem(Handle, 0),nil,true);//调用Windows API(二个函数均是) end;end;//============== 设置背景图 =================================procedure TSortListView.SetPicture(Value: TPicture);begin //转换背景图设置,将值赋给FPicture私有数据域 if FPicture <> Value then FPicture.Assign(Value);end;//============== TPicture的OnChange事件响应过程 ==============procedure TSortListView.PictureChanged(Sender: TObject);begin //重绘列表视图 Invalidate;end;//============== TListView的OnCustomDraw事件响应过程==========procedure TSortListView.LVCustomDraw(Sender: TCustomListView; const ARect: TRect; var DefaultDraw: Boolean);begin if (FPicture.Graphic<>nil)then begin DrawBack;//绘制背景图 SetBkMode(Canvas.Handle,TRANSPARENT);//调用Windows API,将画布的背景设为透明模式 ListView_SetTextBKColor(Handle,CLR_NONE);//调用Windows API,将Item的文本背景设为透明 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; 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;//====== Windows 消息应答 ====================================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); //在PDrawItemStruct数据结构中有我们需要的数据 if pDS.CtlType<>ODT_MENU then begin DrawHeaderItem(pDS); Result := 1; end; end; WM_NOTIFY: begin phd := PHDNotify(Message.lParam); //在PHDNotify数据结构中有我们需要的数据 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);//调用Windows API end; //当拖动或改变表头时 HDN_ENDTRACK,HDN_ENDTRACKW,HDN_ITEMCHANGED: begin SetHeaderStyle(phd); InvalidateRect(GetDlgItem(Handle, 0), nil, true);//调用Windows API end; end; end; end;end;//=====================================================================var AtoZOrder: Boolean;function CustomSortProc(Item1, Item2: TListItem; ParamSort: Integer): Integer; stdcall;begin//自定义TListView的排序函数类型TLVComparecase 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 //调用TListView的CustomSort函数,按列排序 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.Font := FHeaderFont; tmpCanvas.Brush.Color := clBtnFace; //重绘文字 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+15; 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; 高手请进 ★★★在panel上动态增加了一些shape控件,如何移除,以便进行刷新?★★★ 我也想“考古”,请拥有的朋友进来看看 如何获得上级目录路径,如何获得program files的路径? 整数与字符串的转换 在delphi中如何产生-100~~~100的随机数 怎样实现在table中数据库的物理排序? It's a very bad thing! delphi5中可以,怎么6就不行了? 在线调查:这里有多少人是三角高手? 用IdHTTP.post 登录后如何保持连接? 关于自定义编号的问题
Header:= FindwindowEx(Listview.handle,0,'SysHeader32',nil);
然后再画吧
unit SortListView;interfaceuses
SysUtils, Classes, Controls, ComCtrls,CommCtrl, Graphics, Windows, Messages;type
TSortListView = class(TListView)
private
{ Private declarations }
FaToz :Boolean;
FoldCol :Integer;
FPicture :TPicture;
FHeaderFont:TFont;
procedure SetHeaderFont(Value:TFont);
procedure SetHeaderStyle(phd:PHDNotify);
procedure DrawHeaderItem(pDS:PDrawItemStruct);
procedure SetPicture(Value: TPicture);
procedure PictureChanged(Sender: TObject);
procedure LVCustomDraw(Sender:TCustomListView;const ARect:TRect;var DefaultDraw:Boolean);
procedure DrawBack;
protected
{ Protected declarations }
procedure WndProc(var Message : TMessage); override;
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure SortColumn(Column: TListColumn);
published
{ Published declarations }
property BackPicture: TPicture read FPicture write SetPicture;
property HeaderFont: TFont read FHeaderFont write SetHeaderFont;
end;procedure Register;implementationprocedure Register;
begin
RegisterComponents('Samples', [TSortListView]);
end;//============== 构造函数 ===================================
constructor TSortListView.Create(AOwner: TComponent);
begin
inherited Create(AOwner);//继承
FHeaderFont:=TFont.Create;
FPicture:=TPicture.Create;
FPicture.OnChange:=PictureChanged;
OnCustomDraw:=LVCustomDraw;
end;//============== 析构函数 ===================================
destructor TSortListView.Destroy;
begin
FPicture.Free;
FHeaderFont.Free;
inherited Destroy;//继承
end;//============== 设置表头字体 ===============================
procedure TSortListView.SetHeaderFont(Value:TFont);
begin
//转换表头字体设置,将值给FHeaderFomt私有数据域,并重绘表头区域
if FHeaderFont <> Value then
begin
FHeaderFont.Assign(Value);
InvalidateRect(GetDlgItem(Handle, 0),nil,true);//调用Windows API(二个函数均是)
end;
end;//============== 设置背景图 =================================procedure TSortListView.SetPicture(Value: TPicture);
begin
//转换背景图设置,将值赋给FPicture私有数据域
if FPicture <> Value then
FPicture.Assign(Value);
end;//============== TPicture的OnChange事件响应过程 ==============
procedure TSortListView.PictureChanged(Sender: TObject);
begin
//重绘列表视图
Invalidate;
end;//============== TListView的OnCustomDraw事件响应过程==========
procedure TSortListView.LVCustomDraw(Sender: TCustomListView; const ARect: TRect; var DefaultDraw: Boolean);
begin
if (FPicture.Graphic<>nil)then
begin
DrawBack;//绘制背景图
SetBkMode(Canvas.Handle,TRANSPARENT);//调用Windows API,将画布的背景设为透明模式
ListView_SetTextBKColor(Handle,CLR_NONE);//调用Windows API,将Item的文本背景设为透明
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;
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;//====== Windows 消息应答 ====================================
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);
//在PDrawItemStruct数据结构中有我们需要的数据
if pDS.CtlType<>ODT_MENU then begin
DrawHeaderItem(pDS);
Result := 1;
end;
end;
WM_NOTIFY:
begin
phd := PHDNotify(Message.lParam);
//在PHDNotify数据结构中有我们需要的数据
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);//调用Windows API
end;
//当拖动或改变表头时
HDN_ENDTRACK,HDN_ENDTRACKW,HDN_ITEMCHANGED:
begin
SetHeaderStyle(phd);
InvalidateRect(GetDlgItem(Handle, 0), nil, true);//调用Windows API
end;
end;
end;
end;
end;//=====================================================================var AtoZOrder: Boolean;function CustomSortProc(Item1, Item2: TListItem; ParamSort: Integer): Integer; stdcall;
begin
//自定义TListView的排序函数类型TLVCompare
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
//调用TListView的CustomSort函数,按列排序
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.Font := FHeaderFont;
tmpCanvas.Brush.Color := clBtnFace;
//重绘文字
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+15;
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;