有时,我们要在ListBox的弹出式菜单中通过ItemIndex显示项目的有关信息。但是,在项目上右击鼠标时,ItemIndex不会象左击那样被改变。这篇文章将通过例子来告诉你如何实现此功能。
假设你有一个ListBox,填充有称作Widgets的类:
type TWidget = class Tobject)
WidgetName : string;
WidgetStatus : boolean;
End;
Widgets : array [0..10] of TWidget
每一项WidgetName在ListBox中显示出来。
你想要通过一个弹出式菜单来改变每一个Widget的状态,其中弹出式菜单与ListBox的OnPopUp事件关联。如果状态是活动的,设置“Active”;如果不是活动的,不设置“Active”。单击“Active”来改变状态。
问题是:鼠标左键单击ListBox会选择一Widget,但用右键单击(并显示弹出菜单)时不会选择。如果鼠标不在已选项上,弹出菜单显示的将不是鼠标所在Widget的状态,而是已选Widget的状态。
幸运的是,ListBox的OnMouseDown比弹出式菜单的OnPopUp先被触发。这样,我们就能在弹出式菜单显示之前用OnMouseDown事件设置ItemIndex。
TlistBox有一个方法:ItemAtPos Pos: TPoint; Existing: Boolean): Integer;
如果能在Pos座标处找到ListBox的一项,这一方法将返回这一项的Index。如果没有找到任何项,且Existing值设为True,ItemAtPos将返回值-1,如果Existing值设为False,ItemAtPos将返回ListBox最后一项的Index值加1。
用这个方法结合OnMouseDown事件就解决了我们的问题:
OnMouseDown代码:
procedure TForm1.WidgetListMouseDown Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
MousePos : TPoint;
OverItemIndex : integer;
begin
MousePos.x := X;
MousePos.y := Y;
if Button = mbRight then
begin
OverItemIndex := WidgetList.ItemAtPos MousePos,False);
WidgetList.ItemIndex:=OverItemIndex;
end;
end;
OnPopUp代码:
procedure TForm1.PopupMenu1Popup Sender: TObject);
var
Index : integer;
begin
Index := WidgetList.ItemIndex;
PopUpMenuItemActive.Checked := Widgets[Index].WidgetStatus;
end;
弹出式菜单项"Active"的OnClick代码:
procedure TForm1.PopUpMenuItemActiveClick Sender: TObject);
var
Index : integer;
begin
Index := WidgetList.ItemIndex;
Widgets[Index].WidgetStatus := not Widgets[Index].WidgetStatus;
PopUpMenuItemActive.Checked:=not PopUpMenuItemActive.Checked;
end;
|