C++ 管理Win32 app和QWinMigrate之间的键盘事件

C++ 管理Win32 app和QWinMigrate之间的键盘事件,c++,qt,winapi,qevent,qeventloop,C++,Qt,Winapi,Qevent,Qeventloop,我已经将Qt对话框集成到传统的Win32应用程序中,现在我有点困惑于如何管理从Qt->Win32传播的键盘事件。有没有办法测试Qt是否正在“处理”事件(例如,输入到editbox),并防止这些事件传播到主机应用程序 Win32应用程序有自己非常复杂的加速器系统,在使用本机EditBox时,通常会手动禁用加速器。我没有能力为Qt对话框做这件事,因为它是多个应用程序之间共享的小部件 目前我禁用了对话框上的主机加速器作为一个整体来获得焦点,但是有可能告诉Qt防止kbd事件从editboxs传播吗?理想

我已经将Qt对话框集成到传统的Win32应用程序中,现在我有点困惑于如何管理从Qt->Win32传播的键盘事件。有没有办法测试Qt是否正在“处理”事件(例如,输入到editbox),并防止这些事件传播到主机应用程序

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


目前我禁用了对话框上的主机加速器作为一个整体来获得焦点,但是有可能告诉Qt防止kbd事件从editboxs传播吗?理想情况下,无需修改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或其他什么),并且QApplication::sendEvent()不会传播自身

我希望这能奏效,祝你好运

(注:此代码未经测试或编译)

如果Qt正在“处理”事件(例如,输入进入编辑框),是否有任何方法进行测试

以防您还没有使用它,您肯定应该查看一下(包含在VisualStudio中),它使您能够跟踪每条消息

我不熟悉Qt,但如果您想捕获Win32中的所有消息,可以使用,例如:

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); 
    }
}

如果Qt对话框是一个模式对话框,它将禁用其所有者,并且禁用的窗口不会接收键盘或鼠标输入。如果QWinMigrate不提供自动支持,您必须通过调用手动实现模态。感谢您的建议,但它不是模态对话框,我无法创建它。它应该存在于主机应用程序中,并尽可能地“原生”。应用程序中有很多对话框用于编辑各种属性(想想Photoshop),这应该只是其中的一个对话框。谢谢-我将很快(几天后)试用,然后再与您联系,经过多次尝试,我得到了与此非常相似的结果——在qApplication上使用全局事件过滤器,然后有选择地将事件发送到Qt或主机应用程序。