【问题标题】:How do I call the base class implementation TextBox::OnKeyDown() in my override?如何在我的覆盖中调用基类实现 TextBox::OnKeyDown()?
【发布时间】:2012-03-17 20:38:07
【问题描述】:

我创建了一个 TextBox 类的子类,这样我就可以在 OnKeyDown() 方法中捕获所有键盘事件(KeyDown 事件不会触发对于所有键盘事件,包括但不限于退格键和箭头键,但 OnKeyDown 将)

这样做的问题是它有效地禁用了 TextBox,因为它完全绕过了控件的内部键盘处理。显而易见的解决方案是在超类中调用 OnKeyDown。

如何在 Windows 运行时执行此操作? 仅仅调用 TextBox::OnKeyDown(...) 是行不通的,因为它会有效地将我带到我的覆盖范围

OnKeyDown() 方法是 IControlOverrides 接口的一部分,我似乎无法为 TextBox 对象实例获取指向该接口的接口指针,而只能获取我的派生对象实例。

【问题讨论】:

  • c++/cx中没有__super关键字吗?
  • __super 被 typedef'ed 到基类,这意味着它与在此示例中执行 TextBox::OnKeyDown(...) 相同。

标签: microsoft-metro windows-runtime c++-cx


【解决方案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 中实现的,可以阅读 here 的深入概述。

Visual Studio 11 开发者预览解决方案

简短的版本是 OnKeyDown() 方法是 IControlOverrides 接口的一部分,由 MyTextBox 和 TextBox 实现,这要归功于一些聪明的编译器技巧。为了获得 TextBox 实现的接口指针,我们首先需要向 TextBox 询问它——如果我们询问 MyTextBox,我们将在我们开始的地方结束。因为这是 COM 中的继承,而不是 C++,所以我们通过指向 baseclass 对象的指针而不是 this

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

Visual Studio 11 测试版解决方案

与其他许多事情一样,这在 VS 11 Beta 中得到了改进。虽然 "__super::" 仍然无法工作,但它现在可以正常工作,只是为了显式调用定义它的接口:

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

VS 中的对象浏览器会显示 OnKeyDown() 方法在 (IControlOverrides) 中定义的接口。

问题解决了!

【讨论】:

  • 几年后的更新:我尝试将TextBox::OnKeyDown(e) 与 VS 12 编译器一起使用,它只是做了正确的事情。这些体操应该不再是必要的了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-03
  • 2016-09-01
  • 2015-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多