procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
Rect: TRect; State: TOwnerDrawState);
begin
inherited;
TListBox(Control).Canvas.FillRect(Rect);
TListBox(Control).Canvas.TextOut(Rect.Left+5, Rect.Top+8, TListBox(Control).Items[Index]);
if odSelected in State then
begin
Button.Left:=Rect.Right-80;
Button.Top:=Rect.Top+4;
Button.Visible:=true;
Button.Invalidate;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
ListBox1.DoubleBuffered:=true;
ListBox1.ItemHeight:=30;
ListBox1.Style:=lbOwnerDrawFixed;
Button:=TButton.Create(ListBox1);
Button.Parent:=ListBox1;
Button.DoubleBuffered:=true;
Button.Visible:=false;
Button.Width:=50;
Button.Height:=20;
Button.Caption:='BTN';
end;
重绘问题仅在使用ScrollBar或向我的ListBox发送WM_VSCROLL消息时才存在。当我通过使用键盘箭头或鼠标点击更改选择时,通常都会绘制。当通过滚动显示所选项目而不留下可见区域时,问题也不存在。
我认为Button.Top属性在DrawItem调用之前仍然具有旧值,并且稍后会更改(例如,更改为-30px)。
答案 0 :(得分:5)
问题是您正在使用OnDrawItem
事件来更改UI(在这种情况下,定位按钮)。不要这样做,事件仅限于绘图。
我建议您:
继承ListBox以处理WM_VSCROLL
消息,并让消息处理程序根据需要重新定位按钮。
var
PrevListBoxWndProc: TWndMethod;
procedure TForm1.FormCreate(Sender: TObject);
begin
PrevListBoxWndProc := ListBox1.WindowProc;
ListBox1.WindowProc := ListBoxWndProc;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
ListBox1.WindowProc := PrevListBoxWndProc;
end;
procedure TForm1.PositionButton(Index: Integer);
var
R: TRect;
begin
if Index <= -1 then
Button.Visible := False
else
begin
R := ListBox1.ItemRect(Index);
Button.Left := R.Right - 80;
Button.Top := R.Top + 4;
Button.Visible := True;
end;
end;
var
LastIndex: Integer = -1;
procedure TForm1.ListBox1Click(Sender: TObject);
var
Index: Integer;
begin
Index := ListBox1.ItemIndex;
if Index <> LastIndex then
begin
LastIndex := Index;
PositionButton(Index);
end;
end;
procedure TForm1.ListBoxWndProc(var Message: TMessage);
begin
PrevListBoxWndProc(Message);
if Message.Msg = WM_VSCROLL then
PositionButton(ListBox1.ItemIndex);
end;
完全摆脱TButton
。使用OnDrawItem
直接在ListBox上绘制按钮的图像(您可以使用DrawFrameControl()
或DrawThemeBackground()
),然后使用{{1 }}或OnMouseDown/Up
事件检查鼠标是否在“按钮”上方,如果是,则根据需要进行相应操作。
OnClick