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

问题描述

我正在尝试对开源Microsoft Terminal application进行一些更改。

我正在向现有文本框中添加KeyDown事件监听器。

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

我正在运行: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,但是更改代码似乎没有任何效果

解决方法

我相信 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;
    });

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...