• 1634阅读
  • 4回复

[讨论]重写QSplashScreen加载界面,加载界面外如何不影响其他软件的使用呢? [复制链接]

上一主题 下一主题
离线lwei24
 

只看楼主 倒序阅读 楼主  发表于: 2022-08-26
如题,在重写QSplashScreen后,并做了一个加载界面(加载界面是一个小于桌面的矩形),现在,安装钩子后,点击加载界面以外的区域,加载界面不会消失,鼠标也能在加载界面区域外的范围内移动,如今,想实现加载界面区域以外,用户可以不受影响的自由使用其他应用程序,比如拖拽、移动等,而加载界面也不受影响。具体代码如下:
  1. ////MyLoader.h
  2. class MyLoader : public QSplashScreen
  3. {
  4. public:
  5.     MyLoader(const QString fileName);
  6.     ~MyLoader();
  7. public:
  8.     void InitUI();
  9.     void SetRange(int min, int max);
  10. protected:
  11.     virtual void enterEvent(QEvent *);
  12.     virtual void leaveEvent(QEvent *);
  13.     virtual void drawContents(QPainter *painter);
  14.     bool eventFilter(QObject *watched, QEvent *event);
  15. private:
  16.     static void InstallMouseHook();
  17.     static void UnInstallMouseHook();
  18. private:
  19.     int                 m_framecount;
  20.     QString             m_fileName;
  21. };
  22. ////MyLoader.cpp
  23. static HHOOK mouseHook = nullptr;
  24. static bool  isEnterArea = false;
  25. MyLoader::MyLoader(const QString fileName)
  26.     : m_fileName(fileName)
  27. {
  28.     InstallMouseHook();
  29.     this->InitUI();
  30.     this->setMouseTracking(true);
  31. }
  32. MyLoader::~MyLoader()
  33. {
  34.     UnInstallMouseHook();
  35. }
  36. void MyLoader::InitUI()
  37. {
  38.     this->installEventFilter(this);
  39.     QPixmap pix(m_fileName);
  40.     this->setPixmap(pix);
  41. }
  42. void MyLoader::drawContents(QPainter *painter)
  43. {
  44.     QFont font;
  45.     FontHelper::Instance()->SetFont(font, 15, QFont::Normal);
  46.     painter->setFont(font);
  47.     painter->setPen(QColor(213, 218, 220));
  48.     painter->drawText(QPointF(5, 15), "Version: 1.0.0.0");
  49.     QSplashScreen::drawContents(painter);
  50. }
  51. LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
  52. {
  53.     if(!isEnterArea)
  54.     {
  55.         return CallNextHookEx(mouseHook, nCode, wParam, lParam);
  56.     }
  57.     LPMOUSEHOOKSTRUCT   pMouseHook = (MOUSEHOOKSTRUCT   FAR   *)   lParam;
  58.     //Current mouse coordinates
  59.     int   posX = pMouseHook->pt.x;
  60.     int   posY = pMouseHook->pt.y;
  61.     fprintf(stderr, "Mouse posX = %d, posY = %d\n", posX, posY);
  62.     if (nCode >= 0)
  63.     {
  64.             if(wParam == WM_MOUSEMOVE || wParam == WM_DROPFILES || wParam == WM_LBUTTONUP ||
  65.                wParam == WM_RBUTTONUP || wParam == WM_MBUTTONUP)
  66.             {
  67.                 return 0;
  68.             }
  69.             if(wParam == WM_LBUTTONDOWN || wParam == WM_LBUTTONDBLCLK ||  wParam == WM_RBUTTONDOWN ||
  70.                wParam == WM_RBUTTONDBLCLK || wParam == WM_MBUTTONDOWN || wParam == WM_MBUTTONDBLCLK ||
  71.                wParam == WM_MOUSEWHEEL)
  72.             {
  73.                 return 1;
  74.             }
  75.     }
  76.     return CallNextHookEx(mouseHook, nCode, wParam, lParam);
  77. }
  78. void NetacLoader::InstallMouseHook()
  79. {
  80.     mouseHook = SetWindowsHookEx(
  81.                 WH_MOUSE_LL,    // 监听类型【鼠标】
  82.                 MouseProc,      // 处理函数v
  83.                 nullptr,        // 当前实例句柄
  84.                 0               // 监听窗口句柄(NULL为全局监听)
  85.                 );
  86. }
  87. void MyLoader::UnInstallMouseHook()
  88. {
  89.     if(mouseHook != nullptr)
  90.     {
  91.         UnhookWindowsHookEx(mouseHook);
  92.         mouseHook = nullptr;
  93.     }
  94. }
  95. bool MyLoader::eventFilter(QObject *watched, QEvent *event)
  96. {
  97.     Q_UNUSED(watched);
  98.     if(event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick)
  99.     {
  100.         return true;
  101.     }
  102.     return false;
  103. }

各位大佬,劳烦帮忙看看,钩子如何能做到加载界面外不去屏蔽其他应用程序的操作呢?小弟在此感激不尽!
离线liudianwu

只看该作者 1楼 发表于: 2022-08-26
把钩子去掉试试
欢迎关注微信公众号:Qt实战/Qt入门和进阶(各种开源作品、经验整理、项目实战技巧,专注Qt/C++软件开发,视频监控、物联网、工业控制、嵌入式软件、国产化系统应用软件开发) QQ:517216493  WX:feiyangqingyun  QQ群:751439350
离线lwei24

只看该作者 2楼 发表于: 2022-08-26
回 liudianwu 的帖子
liudianwu:把钩子去掉试试 (2022-08-26 16:40) 

大佬,试过了,把钩子去掉的话,点击加载窗口外的区域,加载窗口就会突然消失。所以,我才装上了钩子。不过,安装钩子虽然屏蔽调了加载窗口外的区域,点击等操作导致加载窗口已不会消失。但是,加载窗口外的区域,假如还想对其他应用程序操作,比如想对文本操作,这时候,就不得不等待加载窗口加载外后,把钩子卸载了,才能操作。因此,想让加载窗口一直显示在桌面(直到它加载完后显示主窗口这段时间内),不受加载窗口外的区域所有的操作,比如鼠标、键盘的事件影响,不知道您这边有什么好办法能实现吗?
离线fsu0413

只看该作者 3楼 发表于: 2022-08-26
你想太多了, Qt::WindowStaysOnTopHint 一个flag解决,看文档
https://doc.qt.io/qt-5/qsplashscreen.html
6条评分好评度+1贡献值+2金钱+10威望+2
lwei24 贡献值 +1 - 2022-08-29
lwei24 威望 +1 - 2022-08-29
20091001753 好评度 +1 - 2022-08-28
20091001753 贡献值 +1 - 2022-08-28
20091001753 威望 +1 - 2022-08-28
20091001753 金钱 +10 - 2022-08-28
离线lwei24

只看该作者 4楼 发表于: 2022-08-29
回 fsu0413 的帖子
fsu0413:你想太多了, Qt::WindowStaysOnTopHint 一个flag解决,看文档
https://doc.qt.io/qt-5/qsplashscreen.html (2022-08-26 22:19) 

多谢指点,的确,设置Qt::WindowStaysOnTopHint后就可以解决问题了!
快速回复
限100 字节
 
上一个 下一个