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); //當(dāng)前窗口的構(gòu)造函數(shù)下調(diào)用
// setWindowFlags(Qt::ToolTip); //同時(shí)隱藏任務(wù)欄圖標(biāo)和標(biāo)題欄圖標(biāo)
//子窗口在父窗口之上,但仍可以對(duì)父窗口進(jìn)行操作
// this->setWindowFlags(Qt::WindowStaysOnTopHint); //當(dāng)前窗口置于頂部
//如果要求只能操作子窗口,不能操作父窗口可以增加以下代碼
// this->setWindowModality(Qt::ApplicationModal); //阻塞除當(dāng)前窗體之外的所有的窗體
// //單擊任務(wù)欄圖標(biāo),對(duì)窗口進(jìn)行顯示/隱藏
// this->setWindowFlags(Qt::WindowMinimizeButtonHint|Qt::WindowMaximizeButtonHint);
#if 1
//系統(tǒng)所有窗口的頂層包括桌面
// setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint|Qt::X11BypassWindowManagerHint);
setAttribute(Qt::WA_TranslucentBackground, true);
// showMaximized();
showFullScreen();
#else
//當(dāng)前應(yīng)用程序的頂層窗口,exec調(diào)用,模態(tài),無法關(guān)閉 show調(diào)用非模態(tài),主窗口可接受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:除任務(wù)欄外,全屏
qhook.h
#ifndef QHOOK_H
#define QHOOK_H
#include <QObject>
#include <Windows.h>
#include <QDebug>
#include <QSettings>
//在注冊(cè)表該目錄下增加新內(nèi)容
#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); //顯示任務(wù)欄
void enableTaskManager(bool flag); //任務(wù)管理器
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表示不作處理,消息繼續(xù)傳遞
}
// if(pkbhs->vkCode == VK_F12)
// {
// void unHook();
// qApp->quit();
// }
}
return CallNextHookEx(keyHook, nCode, wParam, lParam);
}
//鼠標(biāo)鉤子過程
LRESULT CALLBACK mouseProc(int nCode,WPARAM wParam,LPARAM lParam )
{
return 1;
}
QHook::~QHook()
{
}
//安裝鉤子,調(diào)用該函數(shù)即安裝鉤子
void QHook::hook(bool flag)
{
if (flag)
{
//這兩個(gè)底層鉤子,不要DLL就可以全局
//底層鍵盤鉤子
keyHook =SetWindowsHookEx( WH_KEYBOARD_LL,keyProc,GetModuleHandle(NULL),0);
//底層鼠標(biāo)鉤子
// mouseHook =SetWindowsHookEx( WH_MOUSE_LL,mouseProc,GetModuleHandle(NULL),0);
}
else
{
UnhookWindowsHookEx(keyHook);
// UnhookWindowsHookEx(mouseHook);
}
}
//添加注冊(cè)屏蔽Ctrl+Alt+del
void QHook::enableTaskManager(bool flag)
{
// 屏蔽ctrl + alt +del 需要修改注冊(cè)表的值, 取得管理員權(quán)限, 關(guān)閉360等殺毒軟件
int value = flag ? 0x00000001 : 0x00000000;
QSettings *settings = new QSettings(TASKMANAGERSystem, QSettings::NativeFormat);
settings->setValue("DisableTaskMgr", value); //任務(wù)管理器
settings->setValue("DisableChangePassword", value); //更改密碼
settings->setValue("DisableLockWorkstation", value); //鎖定計(jì)算機(jī)
settings->setValue("DisableSwitchUserOption", value); //切換用戶
QSettings *settings2 = new QSettings(TASKMANAGERExplorer, QSettings::NativeFormat);
settings2->setValue("NoLogOff", value); //注銷
delete settings;
delete settings2;
}
//屏蔽任務(wù)欄
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("鎖定中,請(qǐng)勿關(guān)機(jī)"));
// setFocusProxy(_maskdlg);
_maskdlg->setWindowFlag(Qt::Tool);
_maskdlg->raise();
// _maskdlg->setGeometry(frameGeometry());
_maskdlg->exec();
_maskdlg->deleteLater();
_maskdlg=nullptr;
若僅為應(yīng)用程序主界面,則設(shè)置父窗口,并調(diào)用以下函數(shù),蓋住主界面
m_maskdlg->setGeometry(frameGeometry());
若要遮罩窗口跟隨主界面自動(dòng)拉伸,需重寫主界面(MainWindow)的ResizeEvent,如果為全屏遮罩,則不需要,
void MainWindow::resizeEvent(QResizeEvent *event)
{
if(m_maskdlg) m_maskdlg->setGeometry(frameGeometry());
}
3.效果圖
4、說明
目前的效果是僅屏蔽了鼠標(biāo)按鍵,全屏范圍不接受鼠標(biāo)點(diǎn)擊,如需屏蔽鍵盤按鍵,需要安裝系統(tǒng)鉤子,屏蔽特定的組合鍵(ALT+TAB,ESC,CTRL+ALT+DEL等等),并且修改注冊(cè)表來實(shí)現(xiàn),具體可以查看下面這位老哥的博文。
另外有個(gè)小bug,這個(gè)透明的全屏遮罩窗口,必須點(diǎn)擊一下,才能響應(yīng)ctrl+U關(guān)閉,即便調(diào)用setFocus()也無濟(jì)于事,如有解決方法,歡迎評(píng)論留言文章來源:http://www.zghlxwxcb.cn/news/detail-817765.html
參考博文:https://blog.csdn.net/liulihuo_gyh/article/details/78129248文章來源地址http://www.zghlxwxcb.cn/news/detail-817765.html
到了這里,關(guān)于Qt實(shí)現(xiàn)遮罩窗口系統(tǒng)全屏鎖定或應(yīng)用程序界面鎖定的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!