首页 > 解决方案 > 为什么鼠标按下会阻止重新绘制组件?

问题描述

我正在尝试创建一个捕获鼠标事件的自定义组件,尤其是 MouseMove。

我派生自TWinControl,但我也尝试过TGraphicControl, TCustomControl,TTrackBar等。

我的问题是当我在组件上按住鼠标时,它没有被重新绘制。

在我释放鼠标按钮之前,不会调用该Paint()方法,即使我调用Invalidate().

TrackBar 是我想要制作的最接近的组件。您选择刻度,然后用鼠标移动它。但您不必释放鼠标即可看到刻度同时移动(再次绘制组件)。

如果我直接调用Paint(),它可以工作,但背景不会被删除。

我错过了什么?

编辑:我再次尝试并确认是否按住鼠标,Invalidate(); 仅当我释放鼠标时才考虑通话。用下面的代码试试你自己,paint 仅在发布时调用:

__fastcall TMyCustomComponent::TMyCustomComponent(TComponent* Owner)
    : TCustomTransparentControl(Owner)
{
    mValue = 0;
}

void __fastcall TMyCustomComponent::MouseDown(System::Uitypes::TMouseButton Button, System::Classes::TShiftState Shift, int X, int Y)
{
    if (Button == mbLeft)
        {
        mValueStart = 0;        
        }
}

void __fastcall TMyCustomComponent::MouseMove(System::Classes::TShiftState Shift, int X, int Y)
{       
    Invalidate();       
}

void __fastcall TMyCustomComponent::Paint(void)
{
    TGraphicControl::Paint();   
    Canvas->Font->Name = "Arial";
    Canvas->Font->Size = 8;
    Canvas->Font->Style = TFontStyles() << fsBold;
    Canvas->Font->Color = clInfoText;
    Canvas->Brush->Color = clInfoBk;
    Canvas->FillRect(TRect(0, 0, 104, 21));
    mValue++;
    Canvas->TextOut(0, 2, AnsiString(mValue));
    Canvas->Brush->Color = clBtnShadow; 
}

标签: c++c++buildervclc++builder-10.2-tokyo

解决方案


以下对我来说很好:

__fastcall TMyCustomComponent::TMyCustomComponent(TComponent* Owner)
    : TCustomTransparentControl(Owner)
{
    mValue = 0;
    InterceptMouse = true; // <-- needed for TCustomTransparentControl to trigger Mouse...() methods!
}

void __fastcall TMyCustomComponent::MouseDown(System::Uitypes::TMouseButton Button, System::Classes::TShiftState Shift, int X, int Y)
{
    if (Button == mbLeft)
    {
        mValue = 0;
        Invalidate();
    }
    TCustomTransparentControl::MouseDown(Button, Shift, X, Y);
}

void __fastcall TMyCustomComponent::MouseMove(System::Classes::TShiftState Shift, int X, int Y)
{
    ++mValue;
    Invalidate();
    TCustomTransparentControl::MouseMove(Shift, X, Y);
}

void __fastcall TMyCustomComponent::Paint()
{
    TCustomTransparentControl::Paint();
    Canvas->Font->Name = "Arial";
    Canvas->Font->Size = 8;
    Canvas->Font->Style = TFontStyles() << fsBold;
    Canvas->Font->Color = clInfoText;
    Canvas->Brush->Color = clInfoBk;
    Canvas->FillRect(TRect(0, 0, ClientWidth, ClientHeight));
    Canvas->TextOut(0, 2, String(mValue));
    Canvas->Brush->Color = clBtnShadow;
}

按下鼠标左键重置mValue为 0 并绘制它。并且在控件周围移动鼠标会增加mValue并绘制它,无论鼠标按钮是否被按住。


推荐阅读