Borland Builder 2007 Child VCL控件和WindowProc方法

时间:2012-01-12 14:57:40

标签: c++builder vcl c++builder-2007

我已设法覆盖控件WindowProc函数,以确定比Builder支持的更多事件(即双击鼠标中键等等)。

问题是,当我覆盖说子组件WindowProc时,父级仍然获取事件。

在我的情况下,我有一个面板,其上有一个按钮。该按钮遮挡了面板的一部分,但是当单击按钮时,父(面板)也获得了事件(还没有测试按钮是否也获得了事件,但是想要看看是否有人首先找到了解决方案)。 / p>

是否有任何方法可以编程方式停止接收事件的父母或确定事件是针对孩子而不是父母的方式。

我将遇到的问题是,如果用户按下按钮,将触发面板事件和按钮事件。

请感谢任何建议。

代码示例: 请注意,Panel和Button派生自ConfigComponent类,该类是m_kOldComponentWndMethod和ComponentWndProc方法所在的位置。

覆盖面板

//---------------------------------------------------------------------------
CConfigComponentPanel::CConfigComponentPanel( TObject* pkParent,
                                              const CConfigComponentDimensions& rkConfigComponentDimensions,
                                              const CConfigComponentPos& rkConfigComponentPos,
                                              const CConfigSelect::SelectCollection& rkSelectCollection,
                                              TColor kBackgroundColour,
                                              TColor kForegroundColour,
                                              const std::string& rstrDisplayText,
                                              const CConfigFontRef& rkConfigFontRef,
                                              const CConfigComponent::ConfigComponentCollection& rkConfigComponentCollection )
:   CConfigComponent( rkConfigComponentDimensions, rkConfigComponentPos, kBackgroundColour, kForegroundColour ),
    m_pkPanel( new TPanel( ( TComponent* )NULL ) ),
    m_kConfigComponentCollection(),
    m_kSelectCollection(),
    m_kConfigFontRef( rkConfigFontRef ),
    m_strDisplayText( rstrDisplayText )
{
    // Set the parent.
    m_pkPanel->Parent = dynamic_cast<TWinControl*>( pkParent );

    if ( rkSelectCollection.size() > 0 )
    {
        // Store the old window proc method before overriding.
        m_kOldComponentWndMethod = m_pkPanel->WindowProc;
        m_pkPanel->WindowProc = ComponentWndProc;
    }

    // Add selects to collection
    AddSelectsToCollection( rkSelectCollection );
    // Add components to collection
    AddConfigComponentsToCollection( rkConfigComponentCollection );
}
//---------------------------------------------------------------------------

覆盖按钮

//---------------------------------------------------------------------------
CConfigComponentButton::CConfigComponentButton( TObject* pkParent,
                                                const CConfigSelect::SelectCollection& rkSelectCollection,
                                                const CConfigComponentDimensions& rkConfigComponentDimensions,
                                                const CConfigComponentPos& rkConfigComponentPos,
                                                TColor kBackgroundColour,
                                                TColor kForegroundColour,
                                                const CConfigButtonBGProperties& rkConfigButtonBGProperties ):
    CConfigComponent( rkConfigComponentDimensions, rkConfigComponentPos, kBackgroundColour, kForegroundColour ),
    m_kConfigButtonBGProperties( rkConfigButtonBGProperties ),
    m_pkButton( new TAdvToolButton( NULL ) ),
    m_kSelectCollection( rkSelectCollection )
{
    m_pkButton->Parent = dynamic_cast<TWinControl*>( pkParent );

    // Store the old window proc method before overriding.
    m_kOldComponentWndMethod = m_pkButton->WindowProc;
    m_pkButton->WindowProc = ComponentWndProc;
}
//---------------------------------------------------------------------------

组件Wnd Proc方法(此处两次为面板,一次为按钮)

//---------------------------------------------------------------------------
void __fastcall CConfigComponent::ComponentWndProc( TMessage& rkMessage )const
{
    if ( rkMessage.Msg == WM_MBUTTONDBLCLK )
    {
        (void)Application->MessageBox( "CConfigComponent::ComponentWndProc", "" );
    }
    if ( rkMessage.Msg == WM_LBUTTONDBLCLK )
    {
        (void)Application->MessageBox( "ComponentWndProc::Left Button", "" );
    }

    if ( m_kOldComponentWndMethod )
    {
        m_kOldComponentWndMethod( rkMessage );
    }
}
//---------------------------------------------------------------------------

谢谢, 乔

1 个答案:

答案 0 :(得分:2)

TAdvToolButtonTGraphicControl后代。 TGraphicalControl没有自己的窗口,因此无法直接接收用户输入。用户输入定向到Parent窗口,因此WindowProc的{​​{1}}会先看到消息。如果输入发生在子Parent的客户区域内,则TGraphicControl会将输入转发给该子项。这就是您在两个组件中都看到用户输入消息的原因。如果您更改Parent课程以使用窗口式按钮,例如CConfigComponentButtonTButton,则您将不再看到重复的消息,因为用户输入将直接指向按钮而不是父TBitBtn