0

Builderでサポートされているよりも多くのイベント(つまり、マウスの中央でのダブルクリックなど)を判別するために、コントロールのWindowProc関数をオーバーライドすることができました。

問題は、子コンポーネントWindowProcをオーバーライドすると、親がまだイベントを取得することです。

私の場合、ボタンが親になっているパネルがあります。ボタンはパネルの一部を覆い隠しますが、ボタンをクリックすると、親(パネル)もイベントを取得します(ボタンもイベントを取得することはテストされていませんが、誰かが最初にこれに対する解決策を持っているかどうかを確認したいと考えていました)。

親がイベントを受信するのをプログラムで停止する方法、またはイベントが親ではなく子のためであるかどうかを判断する方法はありますか。

私が抱える問題は、ユーザーがボタンを押すと、パネルイベントとボタンイベントがトリガーされることです。

アドバイスをいただければ幸いです。

ジョー

コード例:PanelとButtonは、m_kOldComponentWndMethodとComponentWndProcメソッドが存在するConfigComponentクラスから派生していることに注意してください。

パネルをオーバーライドする

//---------------------------------------------------------------------------
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;
}
//---------------------------------------------------------------------------

Component Wnd Procメソッド(ここでは、パネル用に1回、ボタン用に1回)

//---------------------------------------------------------------------------
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 );
    }
}
//---------------------------------------------------------------------------

ありがとう、ジョー

4

1 に答える 1

2

TAdvToolButtonTGraphicControl子孫です 。TGraphicalControl独自のウィンドウがないため、ユーザー入力を直接受け取ることはできません。ユーザー入力はParentウィンドウに送信されるため、WindowProcのはParent最初にメッセージを確認します。子のクライアント領域内で入力が発生した場合、はその子TGraphicControlParent入力を転送します。そのため、両方のコンポーネントでユーザー入力メッセージが表示されます。またはCConfigComponentButtonのようなウィンドウボタンを使用するようにクラスを変更すると、ユーザー入力は親ではなくボタンに直接送信されるため、重複するメッセージは表示されなくなります。TButtonTBitBtnTPanel

于 2012-01-13T19:04:05.770 に答える