在发布模式下未添加C++/WinRT KeyDown事件处理程序



我正在尝试对开源的Microsoft终端应用程序进行一些更改。

我正在向现有的文本框中添加一个KeyDown事件侦听器。

当我使用Debug配置运行应用程序时,一切都按预期工作,但当我在Release下运行相同的代码时,KeyDown事件处理程序不会添加到控件中。

我正在运行:Release,x64,CascadiaPackage。


这是添加KeyUp处理程序的原始代码:

// Tab.cpp (original)
Controls::TextBox tabTextBox;

// ...
tabTextBox.KeyUp([weakThis](const IInspectable& sender, Input::KeyRoutedEventArgs const& e) {
auto tab{ weakThis.get() };
auto textBox{ sender.try_as<Controls::TextBox>() };
if (tab && textBox)
{
// handle keyup event
}
});

以下是我如何将KeyDown处理程序添加到同一控件:

// Tab.cpp (edited)
auto sawKeyDown = false;

/*
!!! This event handler works in Debug but doesn't exist when run in Release configuration !!!
*/
tabTextBox.KeyDown([&sawKeyDown](const IInspectable&, Input::KeyRoutedEventArgs const&) {
sawKeyDown = true;
});
// !!!

tabTextBox.KeyUp([weakThis, &sawKeyDown](const IInspectable& sender, Input::KeyRoutedEventArgs const& e) {
auto tab{ weakThis.get() };
auto textBox{ sender.try_as<Controls::TextBox>() };
if (tab && textBox && sawKeyDown)
{
// ... original code here...
}
sawKeyDown = false;
});

如果我试图在Release模式下在事件处理程序中添加断点,Visual Studio会在断点图标上显示以下消息:

当前不会命中断点。没有调试器目标代码类型的可执行代码与此行关联。可能的原因包括:条件编译、编译器优化,或者当前调试器代码类型不支持此行的目标体系结构。

位置:Tab.cpp,第716行("_ConstructTabRenameBox(const winrt::hstring&tabText("(


是否出于某种原因优化了代码KeyDown侦听器?或者我还需要做些什么来将事件侦听器添加到文本框中。

我尝试在KeyDown处理程序中引用weakThis,但更改代码似乎没有任何效果。

我相信Ryan Shepherd的评论说明了问题的原因。

sawKeyDown变量是在堆栈上本地定义的,这意味着在调用lambda时它不再存在(oops!(。

解决方案是将标志设为成员变量。

// file.h - define the member variable inside the struct/type
bool _receivedKeyDown{ false };
// file.cpp
tabTextBox.KeyDown([weakThis](const IInspectable&, Input::KeyRoutedEventArgs const&) {
auto tab{ weakThis.get() };
tab->sawKeyDown = true;
});

tabTextBox.KeyUp([weakThis](const IInspectable& sender, Input::KeyRoutedEventArgs const& e) {
auto tab{ weakThis.get() };
auto textBox{ sender.try_as<Controls::TextBox>() };
if (tab && textBox && tab->sawKeyDown)
{
// ... original code here...
}
tab->sawKeyDown = false;
});

最新更新