2014-09-22 45 views
3

我有一个高数量的项目的列表框。它并不总是满的。我知道,当用户没有通过验证码选择一个项目:检测列表框中的“空白”点击

if (lstbox.ItemIndex = -1) then 
    ShowMessage('here'); 

但是,当我一个项目被选中,这并不工作,然后我点击列表框中的“空白”。我如何检测这种情况?

+0

我最近在XE5中注意到了这一点。我很好奇,如果这是TListboxes行为的一个相对最近的变化,因为我发誓它曾经是,如果你点击空白区域是否选择了一个项目,.ItemIndex的值将是-1。现在,如果某个项目已被选中,它将忽略该点击。 – 2014-09-23 01:01:12

回答

6

您可以通过多种方式来完成此操作。

procedure TMyForm.ListBox1MouseDown(Sender: TObject; 
            Button: TMouseButton; 
            Shift: TShiftState; 
            X, Y: Integer); 
begin 
    if TListbox(Sender).ItemAtPos(Point(X, Y), TRUE) <> -1 then 
    // item was clicked 
    else 
    // 'whitespace' was clicked 
end; 

但这韩元”:人们会使用Xÿ参数,这种情况下,这是客户坐标在该用户点击列表框是在onmousedown事件事件t会影响任何OnClick事件中的行为。如果您需要在的OnClick执行此测试,那么你需要获得鼠标位置和它做同样的测试之前转换为列表框客户坐标:

procedure TMyForm.ListBox1Click(Sender: TObject); 
var 
    msgMousePos: TSmallPoint; 
    mousePos: TPoint; 
begin 
    // Obtain screen co-ords of mouse at time of originating message 
    // 
    // Note that GetMessagePos returns a TSmallPoint which we need to convert to a TPoint 
    // in order to make further use of it 

    msgMousePos := TSmallPoint(GetMessagePos); 

    mousePos := SmallPointToPoint(msgMousePos); 
    mousePos := TListbox(Sender).ScreenToClient(mousePos); 

    if TListbox(Sender).ItemAtPos(mousePos, TRUE) <> -1 then 
    // item clicked 
    else 
    // 'whitespace' clicked 
end; 

注:GetMessagePos()取得在最近观察到的鼠标消息时的鼠标位置(在这种情况下应该是发起的消息点击事件)。但是,如果您的点击处理程序被直接调用,那么GetMessagePos()返回的鼠标位置很可能与处理程序中的处理很少或根本没有关系。如果任何这样的直接调用可能明智地利用当前的鼠标位置,则可以使用GetCursorPos()来获得。

GetCursorPos()也更直接使用,因为它直接获得在TPoint值鼠标位置,避免了需要从TSmallPoint转换:

GetCursorPos(mousePos); 

无论哪种方式,事实上,你的处理程序以任何方式依赖于鼠标位置,这使得直接调用这个事件处理程序有问题,所以如果这是一个考虑因素,那么你可能希望将事件处理程序中的任何位置无关响应分离成一个方法,该方法可以显式调用,如果/当需要时,inde垂直鼠标与控件的交互。

+0

还有全球鼠标的CursorPos。 – 2014-09-22 21:20:06

+0

它应该是GetMessagePos而不是GetCursorPos。与GetKeyState和GetAsyncKeyState相同。但请记住,除了鼠标事件之外,OnClick触发的可能性还有一些原因。 – 2014-09-22 21:38:08

+0

除非直接调用OnClick事件,否则消息循环观察到的鼠标位置可能会大量不正确,因为GetCursorPos()具有非常偏远的机会。实现对消息的直接响应时,GetMessagePos()是适当的,但在VCL事件处理程序中,您不具备这种确定性。 – Deltics 2014-09-22 22:30:33