• 7275阅读
  • 8回复

求助于热键设置 [复制链接]

上一主题 下一主题
离线mewjerry
 
只看楼主 倒序阅读 楼主  发表于: 2010-08-17
— 本帖被 XChinux 执行加亮操作(2010-09-01) —
想要为软件设置一个老板键,老板键可以在任何时候,无论是程序被激活与否都可以隐藏或显示软件。

在网上看了下,要用WINAPI来实现,但是这里有点疑问:

用RegisterHotKey注册的热键会在热键触发时发送消息给一个确定的窗口

按理说我只要在这个widget里面实现对消息的响应就可以了,

但软件可能有多个窗口均在运行当中,

这种情况下我该在每个窗口创建的时候都去注册一遍热键吗?

如何才能保证自己软件的所有窗口去共享这一个热键呢?
离线mewjerry
只看该作者 1楼 发表于: 2010-08-17
继续上顶求助
离线XChinux

只看该作者 2楼 发表于: 2010-08-17
你的程序必定有一个主窗口吧,
你可重新实现QApplication是一个消息过滤事件函数,在里面进行处理。然后决定该如何做。
你搜索一下网上,有相关的示例代码。
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线dbzhang800

只看该作者 3楼 发表于: 2010-08-17
1. 你可以给 QApplication 安装过滤器,这样在你的窗口收到热键之前 qApp 就截到了

2. 其实也不用装过滤器,你的窗口可以直接访问QApplication,通过它可以获得所有topwidget的指针
离线mewjerry
只看该作者 4楼 发表于: 2010-08-19
2L:
我的程序没有“主”窗口- -||
至少是没有一个确定的主窗口,不同时间显示的窗口不一样,想来想去只有让QApplication去接收Windows发来的消息,但是QApplication却又没有句柄,只有widget才有句柄,这太囧了- -我总不能为了接收这个消息就建立一个一直存在的widget吧。
3L:
那个过滤器顶多保证我的窗口在激活状态下能够收到消息,也就是说,一旦窗体因这个老板键全部隐藏了,恢复的那个消息就接收不到了,而且如果我的窗口没有在激活状态下,也收不到隐藏的那个消息。

于是,继续求解……
离线paranoid
只看该作者 5楼 发表于: 2010-08-19
必须得有一个窗口负责注册,接收,删除热键,就用这个窗口管理其他你要隐藏的窗口。当热键被此窗口捕获后,可以emit 一个自定义的信号,其他需要隐藏的窗口连接并处理这个信号。如果不想看到这个管理窗口,创建后不show就是了。
离线mewjerry
只看该作者 6楼 发表于: 2010-08-19
看来非得搞一个窗口了OTZ
离线mewjerry
只看该作者 7楼 发表于: 2010-08-19
  1. #if defined(WIN32) || defined(WIN64)
  2. #include <windows.h>
  3. class QGlobalHotKey : public QWidget
  4. {
  5. public:
  6.     QGlobalHotKey(quint32 p_nativeMods, quint32 p_nativeKey, QString p_keyid);
  7.     bool setHotKey();
  8.     bool clearHotKey();
  9.     QGlobalHotKey(){}
  10.     QGlobalHotKey(const QGlobalHotKey&){}
  11. private:
  12.     bool event(QEvent *event);
  13.     QString keyid;
  14.     WCHAR *hotkeyid;
  15.     ATOM keyatom;
  16.     quint32 nativeMods;
  17.     quint32 nativeKey;
  18.     quint32 times;//Key press time counter.
  19. };
  20. #endif

  1. #if defined(WIN32) || defined(WIN64)
  2. QGlobalHotKey::QGlobalHotKey(quint32 p_nativeMods, quint32 p_nativeKey, QString p_keyid)
  3. {
  4.     keyid=p_keyid;
  5.     nativeMods=p_nativeMods;
  6.     nativeKey=p_nativeKey;
  7.     times=0;
  8.     hide();
  9.     bool ok=setHotKey();
  10.     int a=1;
  11. }
  12. bool QGlobalHotKey::setHotKey()
  13. {
  14.     WCHAR *hotkeyid=new WCHAR[keyid.size()];
  15.     keyid.toWCharArray(hotkeyid);
  16.     keyatom=GlobalAddAtom(hotkeyid)-0xC000;
  17.     delete [] hotkeyid;
  18.     return RegisterHotKey(winId(),keyatom,nativeMods,nativeKey);
  19. }
  20. bool QGlobalHotKey::clearHotKey()
  21. {
  22.     return UnregisterHotKey(winId(), keyatom);
  23. }
  24. bool QGlobalHotKey::event(QEvent *event)
  25. {
  26.     if(event->type()==QEvent::Shortcut)
  27.     {
  28.         if(times%2==0){
  29.             foreach (QWidget *widget, qApp->allWidgets())
  30.                 ShowWindow(widget->winId(), SW_HIDE);
  31.         }else{
  32.             foreach (QWidget *widget, qApp->allWidgets())
  33.                 ShowWindow(widget->winId(), SW_SHOW);
  34.         }
  35.     }else{
  36.         QWidget::event(event);
  37.     }
  38.     return true;
  39. }
  40. #endif

  1. int main(int argc, char *argv[])
  2. {
  3.         QApplication a(argc, argv);
  4.         QGlobalHotKey MyHotKey=QGlobalHotKey(0,0x77,"POboss");
  5.         QWidget *window = new QWidget;
  6.         QLineEdit *edit = new QLineEdit();
  7.         QPushButton *button=new QPushButton("Edit");
  8.         QHBoxLayout *layout=new QHBoxLayout();
  9.         layout->addWidget(edit);
  10.         layout->addWidget(button);
  11.         window->setLayout(layout);
  12.         window->show();
  13.         return a.exec();
  14. }


用其他查看热键的程序可以看到热键在程序运行后注册成功,但是无论在什么时候按下该快捷键都没有反应,那个event()根本就接收不到消息,不知为何?
离线paranoid
只看该作者 8楼 发表于: 2010-08-19
使用winEvent
  1. bool QGlobalHotKey::winEvent( MSG* msg, long* result )
  2. {
  3.     if ( WM_HOTKEY == msg->message ) {
  4.         if ( isHidden() )
  5.             show();
  6.         else
  7.             hide();
  8.         return true;
  9.     }
  10.     return QWidget::winEvent( msg, result );
  11. }
快速回复
限100 字节
 
上一个 下一个