TListView MouseUp事件过早触发,MouseMove Shift无法按预期工作

时间:2017-03-29 03:45:29

标签: c++ c delphi c++builder vcl

使用C ++ Builder 2009(但我也标记了Delphi,因为这是VCL)

我创建了一个继承自TListView的类,当没有要列出的对象时,我' DrawText' ListView Canvas中间的一些文字,但文字中有一个可以点击的热点。
基本上我使用两种颜色绘制文本,热点区域为蓝色。 我还跟踪自定义HotSpot类中该热点的坐标。

PS。我使用MultiSelect = true

当我将鼠标悬停在热点上方时,我想在文本下划线(使用下面的代码工作)

当我发布鼠标点击热点时,我希望它能够调用一个事件(如果MultiSelect = true可以使用下面的代码)

但是我还希望在再次发布(MouseUp)之前单击热点(MouseDown)时以粗体显示文本。 这不起作用,因为单击鼠标时不执行MouseDown代码,它仅在鼠标单击被释放时执行,并且仅在MouseUp代码之前执行。这是一个错误吗?

然而,当MultiSelect关闭(= false)时,逻辑会发生变化,MouseUp事件会在MouseDown之后直接触发,但鼠标按钮释放前

所以我想我忽略MouseDown并将逻辑放在MouseMove中并检查Shift以进行鼠标左键单击。然而,只有在MultiSelect = true MultiSelect = false时才会有效,因为MouseUp的触发速度太快,因此无法满足我的需求。

我有什么明显的遗失吗?

//---------------------------------------------------------------------------
void __fastcall ObjectListView::MouseMove(Classes::TShiftState Shift, int X, int Y)
{
TListView::MouseMove(Shift, X, Y);

if (Items->Count == 0 && HotSpot.Rect.Top > 0)
    {
    if (InRange(X, HotSpot.Rect.Left, HotSpot.Rect.Right) && InRange(Y, HotSpot.Rect.Top, HotSpot.Rect.Bottom))
        {
        if (!HotSpot.Hover)
            {
            HotSpot.Hover = true ;
            Invalidate() ; // Paint the text again, but this time Hot
            }

        if (Shift.Contains(ssLeft)) // Left Mouse button is being held down
            {
            if (!HotSpot.Select)
                {
                HotSpot.Select = true ;
                Invalidate() ; // Paint the text again, but this time Selected
                }
            }
        else if (HotSpot.Select)
            {
            HotSpot.Select = false ;
            Invalidate() ;
            }
        }
    else if (HotSpot.Hover)
        {
        HotSpot.Hover = false ;
        HotSpot.Select = false;
        Invalidate() ;
        }
    }
}
//---------------------------------------------------------------------------
void __fastcall ObjectListView::MouseUp(TMouseButton Button, Classes::TShiftState Shift, int X, int Y)
{
TListView::MouseUp(Button, Shift, X, Y);

if (OnHotSpotClick && Items->Count == 0 && HotSpot.Rect.Top > 0)
    {
    if (Button == mbLeft)
        {
        if (InRange(X, HotSpot.Rect.Left, HotSpot.Rect.Right) && InRange(Y, HotSpot.Rect.Top, HotSpot.Rect.Bottom))
            {
            HotSpot.Select = false ;
            Invalidate() ;
            OnHotSpotClick(this, ParentObject, (TLVStatus)HotSpot.Data) ;
            }
        }
    }
}
//---------------------------------------------------------------------------
void __fastcall ObjectListView::MouseDown(TMouseButton Button, Classes::TShiftState Shift, int X, int Y)
{
TListView::MouseDown(Button, Shift, X, Y);

// This event triggers when the mouse button is released (Bug ?) and if (MultiSelect == true)
// So there is no point trying to do something with the HotSpot state
// Instead, use the MouseMove event and check the Shift state
}
//---------------------------------------------------------------------------

0 个答案:

没有答案