QT防止锁屏工具(QT模拟Windows按键按下)

        有些公司可能会对员工使用的电脑进行加域控制。如长时间无操作,熄灭屏幕并自动锁定、长时间无使用自动关机等控制。且不能进行个性化设置。有时与同事讨论问题,一段时间没有操作电脑就会导致进入锁定状态,必须重新输入密码登录。关键是密码还不能设太简单,得有大小写、符号、数字长度的要求,实在无语。迫不得已,于是想到了用程序模拟键盘按下操作,来"欺骗"电脑。达到防止锁屏的效果。

       随着计算机的发展,scolllock键的作用越来越小,除了在Excel中有点用处,其它地方根本没用不上。于是打算模拟按下scolllock按键来“欺骗”电脑,这样既能防止锁屏,又不会影响电脑的正常使用。

查找相关资料: QT中如下代码可模拟键盘按键。

QKeyEvent tabKey(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier);
QCoreApplication::sendEvent(this, &tabKey);

实测后发现并不能达到按键真实按下的效果,QT只是模拟发送了一个信号,能够供QT程序自己使用,window其他的软件并不能接收到。

继续查找资料发现,要模拟键盘按下必须使用windows的 API实现。

头文件:

      #include

函数原型:

void keybd_event(BYTE bVk,BYTE bScan,DWORD dwFlags,DWORD dwExtralnfo);

参数:

       bVk:定义一个虚拟键码。键码值必须在1~254之间。
  bScan:定义该键的硬件扫描码。
  dwFlags:定义函数操作的各个方面的一个标志位集。应用程序可使用如下一些预定义常数的组合设置标志位。
  KEYEVENTF_EXTENDEDKEY:若指定该值,则扫描码前一个值为OXEO(224)的前缀字节。 
  KEYEVENTF_KEYUP:若指定该值,该键将被释放;若未指定该值,该键将被按下。
  dwExtralnfo:定义与击键相关的附加的32位值。

模拟scolllock键按下的程序如下:

keybd_event(VK_SCROLL, 0, KEYEVENTF_EXTENDEDKEY, 0);//按键按下
keybd_event(VK_SCROLL, 0, KEYEVENTF_KEYUP, 0);//按键松开

防止锁屏程序除了实现定时模拟发送按键信号外,还做了防止程序双开、托盘后台运行等功能,方便使用。代码如下:

widget.h

#ifndef WIDGET_H
#define WIDGET_H
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
    void closeEvent(QCloseEvent *event);
public slots:
    void sleep_timeout();    //定时超时
    void exit_application();  //退出程序
    void show_application();  //显示窗口
    void TrayIcon_proc(QSystemTrayIcon::ActivationReason reason); //托盘图标操作事件响应

private slots:
    void on_pushButton_clicked();

    void on_spinBox_valueChanged(const QString &arg1);

private:
    Ui::Widget *ui;
    QTimer *timer;
    QSystemTrayIcon *mSysTrayIcon;  //托盘图标
    QAction *show_app; 
    QAction *exit_app; 
    QMenu *mMenu;  //托盘菜单栏
};

#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"

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

    QIcon icon("ico.png");//默认为当前目录,所谓当前目录,指编译后生成的以build开头的那个目录
    this->setWindowIcon(icon);//图标
    this->setWindowTitle("防锁屏工具");//设置窗体标题
    mSysTrayIcon = new QSystemTrayIcon(this);
    mSysTrayIcon->setIcon(icon);
    mSysTrayIcon->setToolTip("防锁屏工具");
    connect(mSysTrayIcon,SIGNAL(activated(QSystemTrayIcon::ActivationReason)),this,SLOT(TrayIcon_proc(QSystemTrayIcon::ActivationReason)));

    show_app = new QAction(QObject::trUtf8("显示主界面"),this);
    connect(show_app,SIGNAL(triggered()),this,SLOT(show_application()));
    exit_app = new QAction(QObject::trUtf8("退出程序"),this);
    connect(exit_app,SIGNAL(triggered()),this,SLOT(exit_application()));

    mMenu = new QMenu(this);
    mMenu->addAction(show_app);
    mMenu->addSeparator(); //增加分隔符
    mMenu->addAction(exit_app);

    mSysTrayIcon->setContextMenu(mMenu);
    mSysTrayIcon->show();


    timer = new QTimer(this);
    connect(timer,SIGNAL(timeout()), this, SLOT(sleep_timeout()));
    on_pushButton_clicked();
}

Widget::~Widget()
{
    delete ui;
}

void Widget::closeEvent(QCloseEvent *event)
{
    qDebug()<<"close !";
    this->hide();
    //mSysTrayIcon->showMessage("提示","程序已最小化至托盘,右键单击托盘图标可退出程序",QSystemTrayIcon::Information,1000);
    event->ignore();
}

void Widget::TrayIcon_proc(QSystemTrayIcon::ActivationReason reason)
{
    switch (reason) {
    case QSystemTrayIcon::Trigger:
        qDebug()<<"单击";
        this->show();
        break;
    case QSystemTrayIcon::DoubleClick:
        qDebug()<<"双击";
        this->show();
        break;
    case QSystemTrayIcon::MiddleClick:
        qDebug()<<"中间按键";
        this->show();
        break;
    default:
        break;
    }
}

void Widget::sleep_timeout()
{
    timer->stop();

    // QKeyEvent tabKey(QEvent::KeyPress, Qt::Key_ScrollLock, Qt::NoModifier);


    qDebug()<<"send key";
    //      QKeyEvent tabKey(QEvent::KeyPress , Qt::Key_A, Qt::NoModifier);
    //      QApplication::sendEvent(focusObject, &tabKey);

    //        int key = translateKeyCode(Qt::Key_ScrollLock);
    keybd_event(VK_SCROLL, 0, KEYEVENTF_EXTENDEDKEY, 0);//按键按下
    keybd_event(VK_SCROLL, 0, KEYEVENTF_KEYUP, 0);//按键松开

    int time = ui->spinBox->value();
    timer->start(time*1000);

}

void Widget::exit_application()
{
    qApp->quit();
}

void Widget::show_application()
{
    this->show();
}

void Widget::on_pushButton_clicked()
{
    if(timer->isActive())
        timer->stop();

    if(ui->pushButton->text() == "启用")
    {
        int time = ui->spinBox->value();
        timer->start(time*1000);
        ui->pushButton->setText("停用");
    }
    else if(ui->pushButton->text() == "停用")
    {
        ui->pushButton->setText("启用");
    }
}

void Widget::on_spinBox_valueChanged(const QString &arg1)
{
    if(timer->isActive())
    {
         timer->stop();
         int time = ui->spinBox->value();
         timer->start(time*1000);
    }
}

main.c

#include "widget.h"
#include 
#include 
#include 

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QTextCodec *codec = QTextCodec::codecForName("unlock");
    QTextCodec::setCodecForLocale(codec);
    QSharedMemory shared_memory;
    shared_memory.setKey(QString("123456"));
    if(shared_memory.attach())
    {
        return 0;
    }
    if(shared_memory.create(1))
    {
        Widget w;
        w.show();
        return a.exec();
    }
    return 0;
}

运行效果如图:

QT防止锁屏工具(QT模拟Windows按键按下)_第1张图片

你可能感兴趣的:(QT学习)