[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的响应要比易语言快很多,基本是实时就弹出提示
但是易语言则是在一段事件之后才弹出提示,这一点,确实百思不得其解