1

OnKeyDown()メソッドですべてのキーボードイベントをキャプチャできるように、 TextBoxクラスのサブクラスを作成しました( KeyDownイベントは、バックスペースキーや矢印キーを含むがこれらに限定されないすべてのキーボードイベントに対してトリガーされるわけではありませんが、OnKeyDownはトリガーします

これに伴う問題は、コントロールの内部キーボード処理を完全にバイパスするため、TextBoxを効果的に無効にすることです。明らかな解決策は、スーパークラスでOnKeyDownを呼び出すことです。

Windowsランタイムでそれを行うにはどうすればよいですか?TextBox :: OnKeyDown(...)を呼び出すだけでは、オーバーライドに効果的に移動するため、機能しません

OnKeyDown()メソッドはIControlOverridesインターフェイスの一部であり、TextBoxオブジェクトインスタンスのそのインターフェイスへのインターフェイスポインタを取得できないようですが、派生オブジェクトインスタンスに対してのみ取得できます。

4

1 に答える 1

1

C ++ / CXでの継承は、C++での継承と同じではありません。これは、C ++ / CX refクラスが実際にはCOMオブジェクトであり、さまざまな集約を通じて継承を実装しているためです。

私が使っていた例は

public ref class MyTextBox : public TextBox {
  MyTextBox() {};
  ~MyTextBox() {};
  virtual void OnKeyDown(KeyEventArgs^ e) override {
    TextBox::OnKeyDown(e);
  };
};

TextBox :: OnKeyDown()はMyTextBox :: OnKeyDown()を効果的に呼び出すため、これは機能しません。これは、仮想メソッドがC ++ / CXおよびCOMでどのように実装されているかによるものであり、詳細な概要はここで読むことができます。

VisualStudio11開発者プレビューソリューション

短いバージョンでは、OnKeyDown()メソッドはIControlOverridesインターフェイスの一部であり、いくつかの巧妙なコンパイラトリックのおかげで、MyTextBoxとTextBoxの両方によって実装されています。TextBox実装のインターフェイスポインタを取得するには、最初にTextBoxにそれを要求する必要があります。MyTextBoxに要求すると、開始した場所に到達します。そして、これはC ++ではなくCOMの継承であるため、これを行うのではなく、ベースクラスオブジェクトへのポインターを介し行います。

  virtual void OnKeyDown(KeyEventArgs^ e) override {
    struct IControlOverrides^ ico;
    HRESULT hr = __cli_baseclass->__cli_QueryInterface(const_cast<class Platform::Guid%>(reinterpret_cast<const class Platform::Guid%>(__uuidof(struct IControlOverrides^))),reinterpret_cast<void**>(&ico));
    if (!hr) {
        hr = ico->__cli_OnKeyDown(e);
    };
  };

VisualStudio11ベータソリューション

他の多くのものと同様に、これはVS11ベータ版で改善されました。「__super::」はまだ機能しませんが、定義されているインターフェイスを明示的に呼び出すだけで正常に機能するようになりました。

  virtual void OnKeyDown(KeyEventArgs^ e) override {
    IControlOverrides::OnKeyDown(e);
  };

VSのオブジェクトブラウザは、OnKeyDown()メソッドが(IControlOverrides)で定義されているインターフェイスを表示します。

問題が解決しました!

于 2012-02-28T12:40:43.610 に答える