[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盘插入!\n已记录本机信息!\n为避免不良记录,请立即拔出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的响应要比易语言快很多,基本是实时就弹出提示

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

posted @ 2018-03-13 20:39  leeli73  阅读(1286)  评论(0编辑  收藏  举报