1、QApplication::addLibraryPath()添加库文件路径。
2、Qt中实现单启动 QSharedMemory (The QSharedMemory class provides access to a shared memory segment.),调用create()函数,通过其返回值来判断程序是否申请过该内存,若申请过则可判断程序已经启动,从而退出程序。
3、Q_INIT_RESOURCE(name),用于初始化资源,有时找不到资源文件时可以尝试使用此方法。
4、QSplashScreen的使用,用于显示启动时的动画窗口。
5、当在windows中使用Qt进行编程时,要处理windwos的中Qt没有处理的事件,例如usb设备的接入事件。
此时可以重新实现bool QWidget::winEvent(MSG*msg,long*result),也可以重新实现bool
QCoreApplication::winEventFilter ( MSG * msg, long * result ),但建议重新实现bool QWidget::winEvent(MSG *msg, long *result)。
如果不对某个窗体句柄注册申请设备通知,则每次不管设备接入还是拔出,msg->wParam值均为7(DBT_DEVNODES_CHANGED),达不到我们所要的结果,向系统申请设备通知的代码如下(可以在主窗口的构造函数中使用):
DEV_BROADCAST_VOLUME pDevBroadCastData; pDevBroadCastData.dbcv_size = sizeof(DEV_BROADCAST_VOLUME); pDevBroadCastData.dbcv_devicetype = DBT_DEVTYP_VOLUME; HDEVNOTIFY deviceNotifier = RegisterDeviceNotification(winId(), &pDevBroadCastData, DEVICE_NOTIFY_WINDOW_HANDLE);
注意头文件中必须按如下顺序包含
#define _WIN32_WINNT 0x0500
//#define _WIN32_WINDOWS 0x0500
#define WINVER 0x0500
#include <windows.h>
#include <dbt.h>
如果不按照以上顺序写,则可能出现如下错误:
error: 'DEVICE_NOTIFY_WINDOW_HANDLE' was not declared in this scope
error: 'RegisterDeviceNotificationW' was not declared in this scope
主要是以上蓝色区域文字条件编译的结果。
/*------------------------------------------------------------------ FirstDriveFromMask (unitmask) Description Finds the first valid drive letter from a mask of drive letters. The mask must be in the format bit 0 = A, bit 1 = B, bit 3 = C, etc. A valid drive letter is defined when the corresponding bit is set to 1. Returns the first drive letter that was found. --------------------------------------------------------------------*/ char FirstDriveFromMask(quint32 unitmask) { char i; for (i = 0; i < 26; ++i) { if (unitmask & 0x1) break; unitmask = unitmask >> 1; } return (i + 'A'); }
(a)
bool MainWindow::winEvent(MSG* msg, long * result) { bool bResult = false; 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 lpdbInterface = (PDEV_BROADCAST_VOLUME)lpdb; char diskID = FirstDriveFromMask( lpdbInterface->dbcv_unitmask); QString mountedName = QString::fromAscii(&diskID, 1); mountedName = mountedName + ":\\"; appearedDeivce(mountedName); } bResult = true; break; case DBT_DEVICEREMOVECOMPLETE: if(lpdb -> dbch_devicetype == DBT_DEVTYP_VOLUME) { PDEV_BROADCAST_VOLUME lpdbInterface = (PDEV_BROADCAST_VOLUME)lpdb; char diskID = FirstDriveFromMask( lpdbInterface->dbcv_unitmask); QString mountedName = QString::fromAscii(&diskID, 1); mountedName = mountedName + ":\\"; disAppearedDevice(mountedName); } bResult = true; break; default: bResult = true; break; } }
(b)
最后,如果重新实现bool QCoreApplication::winEventFilter ( MSG * msg, long * result )可能导致一个问题,就是每次设备的插入和弹出事件将接受两次,所以,建议重新实现bool QWidget::winEvent(MSG*msg,long*result)。
后来重新测试,其实直接重新实现bool QCoreApplication::winEventFilter ( MSG * msg, long * result )也能实现,且无需向系统申请设备通知,直接拷贝代码(a)、(b)并修改为相应的函数名,但有一点需要注意,在Qt中调试,断点不能打在switch语句处,否则每次均只能接收到7(DBT_DEVNODES_CHANGED),直接打开case内即可进入。
6、关于usb设备,由于如果打开软件之前,设备已经接入,则无法收到usb设备的接入事件,导致软件中无法正确显示。
GetLogicalDriveStrings()函数来查询当前所有逻辑驱动器的根驱动器路径;
GetDriveType()判断一个磁盘驱动器的类型;
CreateFile()打开一个设备句柄;
DeviceIoControl()对打开的设备句柄进行操作;
CloseHandle()关闭设备句柄;
GetDiskFreeSpace()获取与一个磁盘的组织有关的信息,以及了解剩余空间的容量;