• [QT+易语言]分别实现检测U盘的插入


    最近发现很多同学在机考时插U盘互相传递代码,所以写了这么个警告程序

    废话不多说直接贴代码

    qt版

    uDisk.h

    #ifndef UDISK_H
    #define UDISK_H
    #include <QWidget>
    #include <windows.h>
    #include <QAbstractNativeEventFilter>
    #include <dbt.h>
    class uDisk: public QWidget,public QAbstractNativeEventFilter
    {
        Q_OBJECT
    protected:
        bool nativeEventFilter(const QByteArray &eventType,void *message,long *result);
    signals:
        void sigUDiskCome(QString uDiskName);
        void sigUDiskRemove();
    private:
        char FirstDriveFromMask(ULONG unitmask);
    };
    #endif

    uDisk.cpp

    #include "uDisk.h"
    #include <QApplication>
    #include <QDebug>
    char uDisk::FirstDriveFromMask(ULONG unitmask)
    {
        char i;
        for(i=0;i<26;++i){
            if(unitmask & 0x1){
                break;
            }
            unitmask = unitmask >> 1;
        }
        return (i + 'A');
    }
    bool uDisk::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
    {
        MSG* msg = reinterpret_cast<MSG*>(message);
        int msgType = msg->message;
        if(msgType == WM_DEVICECHANGE) {
            PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)msg->lParam;
            switch (msg->wParam) {
            case DBT_DEVICEARRIVAL:
                if(lpdb->dbch_devicetype == DBT_DEVTYP_VOLUME) {
                    PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;
                    if(lpdbv->dbcv_flags ==0) {
                        QString USBDisk = QString(this->FirstDriveFromMask(lpdbv ->dbcv_unitmask));
                        emit sigUDiskCome(USBDisk);
                    }
                }
                break;
            case DBT_DEVICEREMOVECOMPLETE:
                if(lpdb->dbch_devicetype == DBT_DEVTYP_VOLUME) {
                    PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;
                    if(lpdbv->dbcv_flags == 0) {
                        emit sigUDiskRemove();
                    }
                }
                break;
            case DBT_DEVNODES_CHANGED:
                break;
            default:
                break;
            }
        }
        return QWidget::nativeEvent(eventType, message, result);
    }

    mainwindows.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include "uDisk.h"
    #include "QFile"
    #include "QMessageBox"
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        uDisk*m_uDisk = new uDisk;
        qApp->installNativeEventFilter(m_uDisk);
        connect(m_uDisk, &uDisk::sigUDiskCome, [=](QString uDiskName){
            QFile sign;
            if(!sign.exists(uDiskName+":\sign.txt"))
            {
                ui->label->setText(tr("U Disk Come!").append(tr("The Disk is ") + uDiskName));
                QMessageBox::warning(NULL, tr("警告"), "检测到U盘插入!
    已记录本机信息!
    为避免不良记录,请立即拔出U盘!",QMessageBox::Yes);
            }
            else//管理U盘进入
            {
                ui->label->setText(tr("admin Disk Come!").append(tr("The Disk is ") + uDiskName));
            }
        });
        connect(m_uDisk, &uDisk::sigUDiskRemove, [=](){
        ui->label->setText(tr("U Disk Remove!"));
        });
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }

    易语言版

    dll命令定义表

    .版本 2

    .DLL命令 SetWindowLong, 子程序指针, , "SetWindowLongA"
        .参数 hwnd, 整数型
        .参数 nIndex, 整数型
        .参数 value, 子程序指针

    .DLL命令 CallWindowProc, 整数型, , "CallWindowProcA"
        .参数 proc, 子程序指针
        .参数 hwnd, 整数型
        .参数 msg, 整数型
        .参数 wp, 整数型
        .参数 lp, 整数型

    .DLL命令 复制结构体, 整数型, , "RtlMoveMemory"
        .参数 dest, PDEV_BROADCAST_VOLUME, 传址
        .参数 source, 整数型
        .参数 len, 整数型, , 14

    自定义数据类型表

    .版本 2

    .数据类型 PDEV_BROADCAST_VOLUME
        .成员 dbcv_size, 整数型, , , 14
        .成员 dbcv_devicetype, 整数型
        .成员 dbcv_reserved, 整数型
        .成员 dbcv_unitmask, 整数型
        .成员 dbcv_flags, 短整数型

    .数据类型 _DEV_BROADCAST_HDR
        .成员 dbch_size, 整数型
        .成员 dbch_devicetype, 整数型
        .成员 dbch_reserved, 整数型

    常量数据表

    .版本 2

    .常量 WM_DEVICECHANGE, "537", , 驱动盘符被改变
    .常量 DBT_DEVICEREMOVECOMPLETE, "32772"
    .常量 DBT_DEVICERARRIVAL, "32768"
    .常量 DBT_DEVTYP_OEM, "0"
    .常量 DBT_DEVTYP_DEVNODE, "1"
    .常量 DBT_DEVTYP_VOLUME, "2"
    .常量 DBT_DEVTYP_PORT, "3"
    .常量 DBT_DEVTYP_N, "4"

    主程序

    .版本 2
    .支持库 eAPI

    .程序集 窗口程序集1
    .程序集变量 a, 子程序指针

    .子程序 __启动窗口_创建完毕

    a = SetWindowLong (_启动窗口.取窗口句柄 (), -4, &MsgProc)


    .子程序 MsgProc, 整数型
    .参数 hwnd, 整数型
    .参数 msg, 整数型
    .参数 wp, 整数型
    .参数 lp, 整数型
    .局部变量 val, PDEV_BROADCAST_VOLUME
    .局部变量 i, 整数型
    .局部变量 mask, 整数型
    .局部变量 盘符, 文本型

    .判断开始 (msg = 537)
        .判断开始 (wp = #DBT_DEVICERARRIVAL)
            复制结构体 (val, lp, 14)
            .如果真 (val.dbcv_devicetype = #DBT_DEVTYP_VOLUME)
                mask = val.dbcv_unitmask
                .变量循环首 (0, 25, 1, i)
                    .如果真 (位与 (mask, 1) = 1)
                        跳出循环 ()
                    .如果真结束
                    mask = 右移 (mask, 1)
                .变量循环尾 ()
                盘符 = 字符 (65 + i)
                检测 (盘符)
            .如果真结束

        .判断 (wp = #DBT_DEVICEREMOVECOMPLETE)
            复制结构体 (val, lp, 14)
            .如果真 (val.dbcv_devicetype = #DBT_DEVTYP_VOLUME)
                mask = val.dbcv_unitmask
                .变量循环首 (0, 25, 1, i)
                    .如果真 (位与 (mask, 1) = 1)
                        跳出循环 ()
                    .如果真结束
                    mask = 右移 (mask, 1)
                .变量循环尾 ()
            .如果真结束

        .默认

        .判断结束

    .默认

    .判断结束
    返回 (CallWindowProc (a, hwnd, msg, wp, lp))

    .子程序 __启动窗口_将被销毁

    a = SetWindowLong (_启动窗口.取窗口句柄 (), -4, a)

    .子程序 检测
    .参数 盘符, 文本型

    .如果 (文件是否存在 (盘符 + “:sign.txt”))
        管理进入子程序 (盘符)
    .否则
        进入子程序 ()
    .如果结束


    .子程序 管理进入子程序
    .参数 盘符, 文本型
    .局部变量 命令, 文本型

    命令 = 到文本 (读入文件 (盘符 + “:sign.txt”))
    .如果 (命令 = “关闭”)
        信息框 (“检测到关闭命令!程序即将自动关闭!”, 0, “检测到命令”, )
        结束 ()
    .否则

    .如果结束


    .子程序 进入子程序

    信息框 (“检测到U盘插入!” + #换行符 + “已收集不良记录!” + #换行符 + “请立即移除设备!”, 0, “警告”, )


    .子程序 _时钟1_周期事件
    .局部变量 进程数组, 进程信息, , "0"
    .局部变量 i, 整数型

    进程数组 = 取系统进程列表 ()

    .计次循环首 (取数组成员数 (进程数组), i)
        .如果真 (到小写 (进程数组 [i].进程名称) = 到小写 (“QQ.exe”))
            信息框 (“检测QQ启动!” + #换行符 + “已收集不良记录!” + #换行符 + “请立即关闭程序!”, 0, “警告”, )
        .如果真结束
        .如果真 (到小写 (进程数组 [i].进程名称) = 到小写 (“iexplore.exe”))
            信息框 (“检测IE浏览器启动!” + #换行符 + “已收集不良记录!” + #换行符 + “请立即关闭程序!”, 0, “警告”, )
        .如果真结束
        .如果真 (到小写 (进程数组 [i].进程名称) = 到小写 (“sogouexplorer.exe”))
            信息框 (“检测搜狗浏览器启动!” + #换行符 + “已收集不良记录!” + #换行符 + “请立即关闭程序!”, 0, “警告”, )
        .如果真结束
        .如果真 (到小写 (进程数组 [i].进程名称) = 到小写 (“The world .exe”))
            信息框 (“检测世界之窗浏览器启动!” + #换行符 + “已收集不良记录!” + #换行符 + “请立即关闭程序!”, 0, “警告”, )
        .如果真结束
        .如果真 (到小写 (进程数组 [i].进程名称) = 到小写 (“Firefox.exe”))
            信息框 (“检测火狐浏览器启动!” + #换行符 + “已收集不良记录!” + #换行符 + “请立即关闭程序!”, 0, “警告”, )
        .如果真结束
        .如果真 (到小写 (进程数组 [i].进程名称) = 到小写 (“opera.exe”))
            信息框 (“检测opera浏览器启动!” + #换行符 + “已收集不良记录!” + #换行符 + “请立即关闭程序!”, 0, “警告”, )
        .如果真结束
        .如果真 (到小写 (进程数组 [i].进程名称) = 到小写 (“360SE.exe”))
            信息框 (“检测360浏览器启动!” + #换行符 + “已收集不良记录!” + #换行符 + “请立即关闭程序!”, 0, “警告”, )
        .如果真结束
        .如果真 (到小写 (进程数组 [i].进程名称) = 到小写 (“Chrome.exe”))
            信息框 (“检测Chrome浏览器启动!” + #换行符 + “已收集不良记录!” + #换行符 + “请立即关闭程序!”, 0, “警告”, )
        .如果真结束
        .如果真 (到小写 (进程数组 [i].进程名称) = 到小写 (“360chrome.exe”))
            信息框 (“检测360极速浏览器启动!” + #换行符 + “已收集不良记录!” + #换行符 + “请立即关闭程序!”, 0, “警告”, )
        .如果真结束
        .如果真 (到小写 (进程数组 [i].进程名称) = 到小写 (“TIM.exe”))
            信息框 (“检测TIM启动!” + #换行符 + “已收集不良记录!” + #换行符 + “请立即关闭程序!”, 0, “警告”, )
        .如果真结束

    .计次循环尾 ()

     -----------------------------------------------------------------------------------------------------------------------------------------------------------------

    易语言程序相对来说还加入了检测常规的浏览器进程

    我大概测试了两个程序,设备插入后,qt的响应要比易语言快很多,基本是实时就弹出提示

    但是易语言则是在一段事件之后才弹出提示,这一点,确实百思不得其解

  • 相关阅读:
    harbor无法登陆解决
    k8s中使用harbor
    harbor扩容
    harbor设置开机自启
    设置开机自启
    关Java的内存模型(JMM)
    多线程相关概念
    多线程(JDK1.5的新特性互斥锁)
    synchronized关键字
    【异常】redis.clients.jedis.exceptions.JedisDataException: ERR unknown command 'PSETEX'
  • 原文地址:https://www.cnblogs.com/lee-li/p/8561758.html
Copyright © 2020-2023  润新知