问题描述
我正在尝试对开源Microsoft Terminal application进行一些更改。
我正在向现有文本框中添加KeyDown
事件监听器。
当我使用Debug配置运行应用程序时,一切都按预期工作,但是当我在Release
下运行相同的代码时,KeyDown
事件处理程序未添加到控件中。
我正在运行:x64版,CascadiaPackage。
// 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
}
});
// 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;
});
如果在发布模式下尝试在事件处理程序中添加断点,Visual Studio会在断点图标上显示此消息:
该断点当前不会被命中。该行没有与调试器的目标代码类型关联的可执行代码。 可能的原因包括:当前的调试器代码类型不支持条件编译,编译器优化或该行的目标体系结构。
位置:Tab.cpp,第716行('_ConstructTabRenameBox(const winrt :: hstring&tabText)')
出于某些原因,是否优化了代码KeyDown侦听器?还是我需要做一些其他事情来将事件侦听器添加到文本框中。
我尝试在KeyDown处理程序中引用weakThis
,但是更改代码似乎没有任何效果。
解决方法
我相信 Ryan Shepherd's comment 显示了导致问题的原因。
sawKeyDown
变量是在堆栈本地定义的,这意味着在调用 lambda 时它不再存在(糟糕!)。
解决方案是将标志设为成员变量。
// 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;
});