怎么把listview的checkbox的勾改为叉?(100分)

  • 主题发起人 主题发起人 wheel
  • 开始时间 开始时间
W

wheel

Unregistered / Unconfirmed
GUEST, unregistred user!
如题,我试了几个listview的事件都找不到怎么写.:(
点击checkbox时参数State的值不是定义中的任何一个?怎么写??

请详细一点,小弟很白痴的说.

BTW:请不要叫我改源码,因为还要用不要此功能的listview。也不想换控件.
 
>>BTW:请不要叫我改源码,因为还要用不要此功能的listview。也不想换控件.
那就放个Panel在上面,把他弄成平的,挡住ListView的复选框,Panel上面再放个Image,在Image的Click里写事件,动态
调用图片
 
我的娘哎

也没人叫你改源码
继承一个下来写几行代码不就得了.
 
我觉得要改这个勾本身比较困难,因为最终Delphi是通过发Windows消息设置Check状态的,
也就是说这个勾很可能是Windows系统确定的。

可以用一个变通的方法,但效果可能不是很理想。
就是你自己画两个小图标,一个空的方框,一个带叉的方框;
把它们加到一个TImageList里,把ListView的StateImages指向这个ImageList;

首先在适当的时机初始化各Item的StateIndex——

var
I: Integer;
begin
for I := 0 to ListView1.Items.Count - 1 do
ListView1.Items.StateIndex := 0;
end;

然后在ListView的OnMouseDown和OnKeyDown事件里模拟Check效果——

procedure TForm1.ListView1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
Item: TListItem;
begin
Item := ListView1.GetItemAt(X, Y);
if (Button <> mbLeft) or (Item = nil) then Exit;
if htOnStateIcon in ListView1.GetHitTestInfoAt(X, Y) then begin//鼠标是否点在CheckBox的位置
Item.Checked := not Item.Checked;
Item.StateIndex := Abs(Item.StateIndex - 1);//假定只有0和1两种情况
end;
end;

procedure TForm1.ListView1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if (Key = VK_SPACE) and (ListView1.Selected <> nil) then
with ListView1.Selected do begin
Checked := not Checked;
StateIndex := Abs(StateIndex - 1);
end;
end;
 
呵呵,发现在ListView的OnGetImageIndex事件里做初始化不错——
procedure TForm1.ListView1GetImageIndex(Sender: TObject; Item: TListItem);
begin
if Item.StateIndex = -1 then Item.StateIndex := 0;
end;
 
这个勾勾不是程序能够控制的,看看源码就知道。
procedure TListItem.SetChecked(Value: Boolean);
var
LV: TCustomListView;
begin
FChecked := Value;
LV := Owner.Owner;
if not LV.OwnerData and LV.HandleAllocated then
<font color = #ff0000><strong>ListView_SetCheckState(LV.Handle, Index, Value)</font></strong>;
end;

如果是 TCheckListBox ,还可以控制:
DrawItem 是 virtual 函数,
procedure DrawItem(Index: Integer; Rect: TRect;State: TOwnerDrawState); override;
begin
...
DrawCheck(...);
...
end;
procedure TCheckListBox.DrawCheck(R: TRect; AState: TCheckBoxState; AEnabled: Boolean);
begin
...
DrawFrameControl(Handle, DrawRect, DFC_BUTTON, DrawState);// 勾勾就是在这里画的
...
end;
 
用dq兄的办法搞定了.
//我怎么就没注意过StateImages呢?白痴,真是白痴:(

多谢两位高手:)
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
后退
顶部