【发布时间】:2020-09-03 06:33:07
【问题描述】:
我正在尝试对开源 Microsoft Terminal application 进行一些更改。
我正在向现有文本框添加 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;
});
如果我尝试在发布模式下的事件处理程序中添加断点,Visual Studio 会在断点图标上显示此消息:
当前不会命中断点。没有调试器目标代码类型的可执行代码与此行相关联。 可能的原因包括:条件编译、编译器优化或当前调试器代码类型不支持此行的目标架构。
位置:Tab.cpp,第 716 行('_ConstructTabRenameBox(const winrt::hstring& tabText)')
是否出于某种原因优化了代码 KeyDown 侦听器?或者我还需要做些什么来将事件侦听器添加到文本框。
我尝试在 KeyDown 处理程序中引用 weakThis,但更改代码似乎没有任何效果。
【问题讨论】:
-
请问您是如何判断KeyDown事件处理程序没有添加到控件中的?您在发布模式下的事件处理程序中添加了一个断点,断点没有被触发或其他?因为当我尝试在 KeyDown 事件中更改文本框的文本时,它在调试和发布模式下都可以正常工作。
-
与您的问题无关,在
TextBox中注册关键事件可能选择了错误的抽象级别。TextBox对字符进行操作,并且大量处理将键盘输入转换为字符。注册关键事件是对所有处理的回避,并最终导致重新实现它。你没有这样做。例如,如果用户按下 [Shift]+A,则您实现的逻辑不能代表这种情况(即同时按下多个键)。 -
Faywang-MSFT 两件事: 1.
sawKeyDown值未设置为 true,这在调试模式下确实发生; 2. 当我在 KeyDown 监听器中设置断点时,Visual Studio 显示消息The breakpoint will not currently be hit. No executable code of the debugger's target code type is associated with this line.(也在我的问题中列出)。在调试模式下,我可以在处理程序中设置一个断点,一切都按预期工作。 -
您是否使用调试符号编译发布配置?您是否设置了/Zo 编译器选项?
-
该 lambda 是否试图修改堆栈上的局部变量?连接处理程序的方法将在您的 lambda 被调用之前返回,从而导致严重的内存损坏。
标签: visual-c++ winrt-xaml c++-winrt windows-terminal