YES, with David's advice, I realize the MouseMove function, it runs:
procedure TCnCustBuildForm.lstTaskMouseMove(Sender: TObject; Shift: TShiftState;
X, Y: Integer);
var
Rect:TRect;
I, J: Integer;
S: string;
ItemWidth: Integer;
begin
if taskRowNum > 0 then
for J := 0 to lstTask.Items.Count - 1 do
begin
Rect := lstTask.Items[J].DisplayRect(drBounds);
Rect.Left := Rect.Left + lstTask.Columns.Items[0].Width;
for I := 1 to lstTask.Columns.Count - 2 do
begin
S := taskContent[J, I];
ItemWidth := ListView_GetStringWidth(lstTask.Handle, PChar(S));
//if ItemWidth > lstTask.Column[I].Width then
// ItemWidth := lstTask.Column[I].Width;
if (taskContent[J, I] = 'error') and (x > Rect.Left) and (y > Rect.Top) and (x < Rect.Left + ItemWidth ) and (y < Rect.Bottom) then
begin
TListView(Sender).Cursor := crHandPoint;
//InvalidateRect(lstTask.Handle, Rect, True);
if lstTaskMouseMoveTrackingRect <> Rect then
begin
InvalidateRect(lstTask.Handle, lstTaskMouseMoveTrackingRect, True);
InvalidateRect(lstTask.Handle, Rect, True);
end;
lstTaskMouseMoveTrackingRect := Rect;
Exit;
end;
Rect.Left := Rect.Left + lstTask.Columns.Items[I].Width;
end;
end;
TListView(Sender).Cursor := crDefault;
InvalidateRect(lstTask.Handle, lstTaskMouseMoveTrackingRect, True);
end;