管理 Win32 应用程序和 QWinMigrate 之间的键盘事件

Managing keyboard events between Win32 app and QWinMigrate

我已经将 Qt 对话框集成到传统的 Win32 应用程序中,现在对如何管理从 Qt->Win32 传播的键盘事件感到有点困惑。有什么方法可以测试 Qt 是否有 'handling' 事件(例如,输入到编辑框),并防止这些事件传播到主机应用程序?

Win32 应用程序有自己非常复杂的加速器系统,在使用本机编辑框时,我们通常会手动禁用加速器。我没有能力为 Qt 对话框执行此操作,因为它是多个应用程序之间的共享小部件。

目前我禁用了整个对话框上的主机加速器以获得焦点,但是是否可以告诉 Qt 阻止来自编辑框的 kbd 事件传播?理想情况下不修改 QtDialogs 代码(尽管如果需要我可以这样做?)

我不知道这是否真的有效,但你可以试一试:

class KeyEventPropagetionPreventer: public QObject
{
public:
    KeyEventPropagetionPreventer( QWidget * widget ) 
    : QObject( widget ), widget( widget ), instercept_events( true )
    {
        widget->installEventFilter( this )
    }

    bool eventFilter(QObject *obj, QEvent *event)
    {
        if ( intercept_events && event->type() == QEvent::KeyPress) // or other types if needed
        {
            intercept_events = false; // prevents eating your own events
            QKeyEvent new_event( *event ); // Might be that you need to implement your own copying function if the copyconstructor is disabled
            QApplication::sendEvent(this->widget, &new_event);
            instercept_events = true;
            return true;
        } 
        else 
        {
            return QObject::eventFilter(obj, event);
        }
    }

private:
    QWidget * widget;
    bool instercept_events;
}

然后在创建对话框的地方添加这一行:

new KeyEventPropagetionPreventer( your_qt_dialog ); // will be deleted by the Qt parent/child system when the dialog is deleted.

想法是拦截所有键盘事件,然后创建它的副本并将其发送到小部件。希望拦截实际上阻止了事件的传播(并且不是 qt-eventsystem-only 之类的)并且 QApplication::sendEvent() 不会自行传播。

希望能成功,祝你好运!

(ps。此代码未经测试或编译)

Is there any way test if Qt is 'handling' events (eg, input going to an editbox)

以防万一您还没有使用过它,您一定要看看 Spy++(包含在 Visual Studio 中),它可以让您跟踪每条消息。

我对Qt不熟悉,但是如果你想在Win32中捕获所有消息,你可以使用GetMessage(),例如:

BOOL bRet;

while( (bRet = GetMessage( &msg, hWnd, 0, 0 )) != 0)
{ 
    if (bRet == -1)
    {
        // handle the error and possibly exit
    }
    else  // you could do whatever you want with the message before it is dispatched
    {
        TranslateMessage(&msg); 
        DispatchMessage(&msg); 
    }
}