1.QMaskDialog
qmaskdialog.h
#ifndef QMASKDIALOG_H
#define QMASKDIALOG_H
#include <QDialog>
#include <QPainter>
#include <QDebug>
#include <QMovie>
#include <QKeyEvent>
#include <QStyleOption>
#include <QLineEdit>
#include "qhook.h"
namespace Ui {
class QMaskDialog;
}
class QMaskDialog : public QDialog
{
Q_OBJECT
public:
explicit QMaskDialog(const QString& tips, QWidget *parent = nullptr);
~QMaskDialog();
private:
Ui::QMaskDialog *ui;
QHook m_hook;
QString m_tips;
protected:
void paintEvent(QPaintEvent* event);
bool eventFilter(QObject *, QEvent *);
};
#endif // QMASKDIALOG_H
qmaskdialog.cpp
#include "qmaskdialog.h"
#include "ui_qmaskdialog.h"
QMaskDialog::QMaskDialog(const QString &tips, QWidget *parent) :
QDialog(parent),m_tips(tips),
ui(new Ui::QMaskDialog)
{
ui->setupUi(this);
// setWindowFlags(Qt::Tool); //当前窗口的构造函数下调用
// setWindowFlags(Qt::ToolTip); //同时隐藏任务栏图标和标题栏图标
//子窗口在父窗口之上,但仍可以对父窗口进行操作
// this->setWindowFlags(Qt::WindowStaysOnTopHint); //当前窗口置于顶部
//如果要求只能操作子窗口,不能操作父窗口可以增加以下代码
// this->setWindowModality(Qt::ApplicationModal); //阻塞除当前窗体之外的所有的窗体
// //单击任务栏图标,对窗口进行显示/隐藏
// this->setWindowFlags(Qt::WindowMinimizeButtonHint|Qt::WindowMaximizeButtonHint);
#if 1
//系统所有窗口的顶层包括桌面
// setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint|Qt::X11BypassWindowManagerHint);
setAttribute(Qt::WA_TranslucentBackground, true);
// showMaximized();
showFullScreen();
#else
//当前应用程序的顶层窗口,exec调用,模态,无法关闭 show调用非模态,主窗口可接受close事件
setWindowFlags(Qt::FramelessWindowHint);
setAttribute(Qt::WA_TranslucentBackground, true);
showMaximized();
#endif
// qDebug()<< QMovie::supportedFormats();
// QMovie *movie=new QMovie("E:\\qt64test\\untitled2\\gif\\progress\\22222.gif");
// movie->setScaledSize(QSize(50,50));
// movie->start();
// ui->label->setMovie(movie);
// ui->label->move(1000,500);
installEventFilter(this);
// setAttribute(Qt::WA_DeleteOnClose);
m_hook.hook(true);
m_hook.enableTaskManager(true);
}
QMaskDialog::~QMaskDialog()
{
delete ui;
m_hook.hook(false);
m_hook.enableTaskManager(false);
}
void QMaskDialog::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event)
QPainter painter(this);
painter.fillRect(rect(),QColor(0,0,255,20));
QFont font = this->font();
font.setBold(true);
font.setPixelSize(80);
painter.setFont(font);
painter.drawText(rect(), Qt::AlignCenter, m_tips);
}
bool QMaskDialog::eventFilter(QObject *obj, QEvent *e)
{
switch (e->type()) {
case QEvent::KeyPress:{
QKeyEvent* ev = static_cast<QKeyEvent*>(e);
if(ev->modifiers() == Qt::ControlModifier){
if(ev->key() == Qt::Key_U){
close();
return true;
}
}
}
break;
default:
break;
}
return QDialog::eventFilter(obj,e);
}
showFullScreen:全屏遮罩
showMaximized:除任务栏外,全屏
qhook.h
#ifndef QHOOK_H
#define QHOOK_H
#include <QObject>
#include <Windows.h>
#include <QDebug>
#include <QSettings>
//在注册表该目录下增加新内容
#define TASKMANAGERSystem "HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System"
#define TASKMANAGERExplorer "HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer"
class QHook : public QObject
{
Q_OBJECT
public:
explicit QHook(QObject *parent = nullptr);
~QHook();
void hook(bool flag); //功能键
void showTaskWindow(bool flag); //显示任务栏
void enableTaskManager(bool flag); //任务管理器
private:
HWND task;
signals:
};
#endif // QHOOK_H
qhook.cpp
#include "qhook.h"
#pragma comment(lib, "User32.lib")
HHOOK keyHook = NULL;
HHOOK mouseHook = NULL;
QHook::QHook(QObject *parent)
: QObject{parent}
{
}
//键盘钩子过程
LRESULT CALLBACK keyProc(int nCode,WPARAM wParam,LPARAM lParam )
{
//在WH_KEYBOARD_LL模式下lParam 是指向KBDLLHOOKSTRUCT类型地址
KBDLLHOOKSTRUCT *pkbhs = (KBDLLHOOKSTRUCT *) lParam;
//如果nCode等于HC_ACTION则处理该消息,如果小于0,则钩子子程就必须将该消息传递给 CallNextHookEx
if(nCode == HC_ACTION)
{
if((pkbhs->vkCode == VK_ESCAPE && GetAsyncKeyState(VK_CONTROL)& 0x8000 && GetAsyncKeyState(VK_SHIFT)&0x8000)|| //"Ctrl+Shift+Esc"
(pkbhs->vkCode == VK_ESCAPE && GetAsyncKeyState(VK_CONTROL) & 0x8000) || //"Ctrl+Esc"
(pkbhs->vkCode == VK_TAB && pkbhs->flags & LLKHF_ALTDOWN )|| //"Alt+Tab"
(pkbhs->vkCode == VK_ESCAPE && pkbhs->flags &LLKHF_ALTDOWN )|| //"Alt+Esc"
(pkbhs->vkCode == VK_LWIN || pkbhs->vkCode == VK_RWIN )|| // "LWIN/RWIN"
(pkbhs->vkCode == VK_F4 && pkbhs->flags & LLKHF_ALTDOWN )|| //"Alt+F4"
(pkbhs->vkCode == VK_ESCAPE))
{
qDebug()<<"屏蔽";
return 1;//返回1表示截取消息不再传递,返回0表示不作处理,消息继续传递
}
// if(pkbhs->vkCode == VK_F12)
// {
// void unHook();
// qApp->quit();
// }
}
return CallNextHookEx(keyHook, nCode, wParam, lParam);
}
//鼠标钩子过程
LRESULT CALLBACK mouseProc(int nCode,WPARAM wParam,LPARAM lParam )
{
return 1;
}
QHook::~QHook()
{
}
//安装钩子,调用该函数即安装钩子
void QHook::hook(bool flag)
{
if (flag)
{
//这两个底层钩子,不要DLL就可以全局
//底层键盘钩子
keyHook =SetWindowsHookEx( WH_KEYBOARD_LL,keyProc,GetModuleHandle(NULL),0);
//底层鼠标钩子
// mouseHook =SetWindowsHookEx( WH_MOUSE_LL,mouseProc,GetModuleHandle(NULL),0);
}
else
{
UnhookWindowsHookEx(keyHook);
// UnhookWindowsHookEx(mouseHook);
}
}
//添加注册屏蔽Ctrl+Alt+del
void QHook::enableTaskManager(bool flag)
{
// 屏蔽ctrl + alt +del 需要修改注册表的值, 取得管理员权限, 关闭360等杀毒软件
int value = flag ? 0x00000001 : 0x00000000;
QSettings *settings = new QSettings(TASKMANAGERSystem, QSettings::NativeFormat);
settings->setValue("DisableTaskMgr", value); //任务管理器
settings->setValue("DisableChangePassword", value); //更改密码
settings->setValue("DisableLockWorkstation", value); //锁定计算机
settings->setValue("DisableSwitchUserOption", value); //切换用户
QSettings *settings2 = new QSettings(TASKMANAGERExplorer, QSettings::NativeFormat);
settings2->setValue("NoLogOff", value); //注销
delete settings;
delete settings2;
}
//屏蔽任务栏
void QHook::showTaskWindow(bool flag)
{
if(flag)
ShowWindow(task,SW_SHOW);
else
{
task=FindWindow(L"Shell_TrayWnd",NULL);
ShowWindow(task,SW_HIDE);
}
}
2.使用
QMaskDialog *_maskdlg=new QMaskDialog(QString("锁定中,请勿关机"));
// setFocusProxy(_maskdlg);
_maskdlg->setWindowFlag(Qt::Tool);
_maskdlg->raise();
// _maskdlg->setGeometry(frameGeometry());
_maskdlg->exec();
_maskdlg->deleteLater();
_maskdlg=nullptr;
若仅为应用程序主界面,则设置父窗口,并调用以下函数,盖住主界面
m_maskdlg->setGeometry(frameGeometry());
若要遮罩窗口跟随主界面自动拉伸,需重写主界面(MainWindow)的ResizeEvent,如果为全屏遮罩,则不需要,
void MainWindow::resizeEvent(QResizeEvent *event)
{
if(m_maskdlg) m_maskdlg->setGeometry(frameGeometry());
}
3.效果图
4、说明
目前的效果是仅屏蔽了鼠标按键,全屏范围不接受鼠标点击,如需屏蔽键盘按键,需要安装系统钩子,屏蔽特定的组合键(ALT+TAB,ESC,CTRL+ALT+DEL等等),并且修改注册表来实现,具体可以查看下面这位老哥的博文。
另外有个小bug,这个透明的全屏遮罩窗口,必须点击一下,才能响应ctrl+U关闭,即便调用setFocus()也无济于事,如有解决方法,欢迎评论留言文章来源:https://www.toymoban.com/news/detail-817765.html
参考博文:https://blog.csdn.net/liulihuo_gyh/article/details/78129248文章来源地址https://www.toymoban.com/news/detail-817765.html
到了这里,关于Qt实现遮罩窗口系统全屏锁定或应用程序界面锁定的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!