管理 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);
}
}
我已经将 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);
}
}