Qt+Hook实现全局鼠标背景色

Qt+Hook实现全局鼠标背景色_第1张图片

具体效果如上图:

实现方法:

1.使用windows HOOK,获取全局鼠标位置,通过信号传递给qwidget调整窗口位置

2.设置鼠标事件穿透,屏蔽窗口的点击事件

3.绘制半透明背景色

4.使用windows hook将鼠标的点击事件,通过qt信号槽函数传递给窗口,实时更换点击时背景色

5.不显示状态栏图标,使用小图标退出程序

1. hookutil.h

// MIT License

// Copyright (c) 2022 hooy

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#ifndef HOOKUTIL_H
#define HOOKUTIL_H

#ifdef _WIN32
#include 
#endif

int startMouseHook();

bool stopMouseHook();

#endif // HOOKUTIL_H

 2. hoolutil.cpp

// MIT License

// Copyright (c) 2022 hooy

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#include "hookutil.h"
#include 
#include 

static HHOOK hMouseHook = NULL;

HMODULE ModuleFromAddress(PVOID pv)
{
    MEMORY_BASIC_INFORMATION mbi;
    if (VirtualQuery(pv, &mbi, sizeof(mbi)) != 0)
    {
        return (HMODULE)mbi.AllocationBase;
    }
    else
    {
        return NULL;
    }
}

bool stopMouseHook()
{
    if (hMouseHook == NULL)
    {
        return FALSE;
    }
    UnhookWindowsHookEx(hMouseHook);
    hMouseHook = NULL;
    return TRUE;
}
LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if(HC_ACTION == nCode){
        if (WM_LBUTTONDOWN == wParam || WM_RBUTTONDOWN == wParam
                        || WM_MBUTTONDOWN == wParam)
        {
            if (MouseHistory::instance())
            {
                MouseHistory::instance()->setPressEvent(1);
            }
        }

        if (WM_LBUTTONUP == wParam || WM_RBUTTONUP == wParam
                        || WM_MBUTTONUP == wParam)
        {
            if (MouseHistory::instance())
            {
                MouseHistory::instance()->setPressEvent(2);
            }
        }


        if (MouseHistory::instance())
        {
            PMSLLHOOKSTRUCT p = (PMSLLHOOKSTRUCT)lParam;
            MouseHistory::instance()->setPosValue(p->pt.x, p->pt.y);
        }
    }
    return CallNextHookEx(hMouseHook, nCode, wParam, lParam);
}

BOOL startMouseHook()
{
    if (hMouseHook != NULL)
    {
        return FALSE;
    }
    hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseProc, ModuleFromAddress((PVOID)MouseProc), NULL);
    if (NULL == hMouseHook)
    {
        qDebug() << "regiter hook for mouse failed";
        return FALSE;
    }
    return TRUE;
}

3. mainwindow.h

// MIT License

// Copyright (c) 2022 hooy

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 
#include 
#include 

class QSystemTrayIcon;
class QMenu;

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

protected:
    void paintEvent(QPaintEvent *event);

private:
    void InitTrayIcon();

private:
    Ui::MainWindow *ui;

    QSystemTrayIcon *_trayIcon{nullptr};
    QMenu           *_trayMenu{nullptr};

    //鼠标点击事件
    bool            pressed_{false};
};
#endif // MAINWINDOW_H

4. mainwindow.cpp

// MIT License

// Copyright (c) 2022 hooy

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include 
#include 
#include 
#include 
#include 
#include 

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    InitTrayIcon();

    setAttribute(Qt::WA_TransparentForMouseEvents, true);
    setFixedSize(QSize(50,50));
    setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::SplashScreen);
    setAttribute(Qt::WA_TranslucentBackground, true);

    connect(MouseHistory::instance(), &MouseHistory::getPos, [=](long x, long y){
        move(x-25, y-25);
    });

    connect(MouseHistory::instance(), &MouseHistory::getPress, [=](int key){
        if(key == 1)
            pressed_ = true;
        else{
            pressed_ = false;
        }
        update();
    });

    startMouseHook();
}

void MainWindow::InitTrayIcon()
{
    _trayIcon = new QSystemTrayIcon(this);
    _trayIcon->setIcon(QIcon(":/res/cat.ico"));
    _trayIcon->setToolTip("Shallow");
    _trayMenu = new QMenu(this);
//    _trayMenu->addAction(tr("显示Shallow窗口"),this,[=](){
//          this->show();
//          this->activateWindow();
//     });
    _trayMenu->addAction(tr("退出Shallow"),this,[=](){
          qApp->quit();
     });
    _trayIcon->setContextMenu(_trayMenu);
    _trayIcon->show();
}


void MainWindow::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    if(pressed_){
        painter.setBrush(QColor(255,200,200,100));
    }
    else{
        painter.setBrush(QColor(125,125,125,100));
    }
    painter.setPen(Qt::NoPen);
    painter.setRenderHint(QPainter::Antialiasing, true);
    painter.save();
    painter.drawEllipse(QPoint(this->rect().left()+25, this->rect().top()+25), 25, 25);
}

MainWindow::~MainWindow()
{
    delete ui;
    stopMouseHook();
}

5. mousehistory.h

// MIT License

// Copyright (c) 2022 hooy

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#ifndef MOUSEHISTORY_H
#define MOUSEHISTORY_H

#include 

class MouseHistory : public QObject
{
    Q_OBJECT
public:
    MouseHistory(QObject* parent = nullptr):QObject(parent){}
    virtual ~MouseHistory(){}
       static MouseHistory *&instance()
       {
           static MouseHistory *s = nullptr;
           if (s == nullptr)
           {
               s = new MouseHistory();
           }
           return s;
       }

     public:
       void setPosValue(long x, long y)
       {
           emit getPos(x,y);
       }

       void setPressEvent(int key){
           emit getPress(key);
       }

     signals:
       void getPos(long, long);
       void getPress(int);
};

#endif // MOUSEHISTORY_H

6. main.cpp

// MIT License

// Copyright (c) 2022 hooy

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#include "mainwindow.h"

#include 

#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    app.setWindowIcon(QIcon(":/res/cat.ico"));
    MainWindow w;
    w.show();
    return app.exec();
}

具体代码地址在github

你可能感兴趣的:(C++探究,OpenCV,图片合成,qt,windows,开发语言)