'================================================================================= 'Для события появления и изятия диска в CD-ROM Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long Public Const GWL_WNDPROC = (-4) Public Const WM_DEVICECHANGE = &H219 Public glngPrevWndProc As Long
Public Function MyWindowProc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long If Msg = WM_DEVICECHANGE Then Select Case wParam ' Событие возникает при появлении нового диска в CD-ROM'е. Case &H8000& Call Form1.DeviceArrival ' Событие возникает при изъятии диска из CD-ROM'а Case &H8004& Call Form1.DeviceRemoveComplete End Select MyWindowProc = 0 Exit Function End If ' остальные сообщения передаются для обработки стандартной процедуре окна MyWindowProc = CallWindowProc(glngPrevWndProc, hwnd, Msg, wParam, lParam) End Function
При сообщении в wParam будет передан параметр: DBT_DEVICEARRIVAL
А в lParam - указатель на структуру DEV_BROADCAST_HDR. Второй параметр которой dbch_devicetype указывает на тип стройства, его проверки-то в коде, что запостен был выше, и нет...
Должен помочь примерно такой код:
Есть проблема, не могу найти объявление константы IOCTL_DISK_CHECK_VERIFY (свистните, если кто найдет).
IOCTL_DISK_CHECK_VERIFY – проверка наличия носителя и его читаемости в устройстве со сменным носителем информации.
Option Explicit
Private Type OSVERSIONINFO
dwOSVersionInfoSize As Long
dwMajorVersion As Long
dwMinorVersion As Long
dwBuildNumber As Long
dwPlatformId As Long
szCSDVersion As String * 128
End Type
Private Type OVERLAPPED
ternal As Long
ternalHigh As Long
offset As Long
OffsetHigh As Long
hEvent As Long
End Type
Private Enum IDE_DRIVE_NUMBER
PRIMARY_MASTER
PRIMARY_SLAVE
SECONDARY_MASTER
SECONDARY_SLAVE
End Enum
Private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" (LpVersionInformation As OSVERSIONINFO) As Long
Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function DeviceIoControl Lib "kernel32" (ByVal hDevice As Long, ByVal dwIoControlCode As Long, lpInBuffer As Any, ByVal nInBufferSize As Long, lpOutBuffer As Any, ByVal nOutBufferSize As Long, lpBytesReturned As Long, ByVal lpOverlapped As Long) As Long
Private Sub Command1_Click()
Dim OL As OVERLAPPED
Dim retVal As Long
Dim lpcbBytesReturned As Long
retVal = DeviceIoControl(hDrive(1), IOCTL_DISK_CHECK_VERIFY, ByVal 0, 0, ByVal 0, lpcbBytesReturned, ByVal 0)
'или так - retVal = DeviceIoControl(hDrive(1), IOCTL_DISK_CHECK_VERIFY, ByVal 0, 0, ByVal 0, lpcbBytesReturned, OL)
If retVal <> 0 Then
MsgBox "CD - Drive is ready", vbInformation, "Ready"
Else
MsgBox "CD - Drive is not ready", vbInformation, "Not ready"
End If
End Sub
Private Function hDrive(drvNum As IDE_DRIVE_NUMBER) As Long
'параметр drvNum, найдешь перебором от 0 до 3 (0 скорее всего - нет)
If IsWindowsNT Then
hDrive = CreateFile("\\.\PhysicalDrive" & CStr(drvNum), GENERIC_READ Or GENERIC_WRITE, FILE_SHARE_READ Or FILE_SHARE_WRITE, ByVal 0&, OPEN_EXISTING, 0, 0)
Else
hDrive = CreateFile("\\.\SMARTVSD", 0, 0, ByVal 0&, CREATE_NEW, 0, 0)
End If
End Function
Private Function IsWindowsNT() As Boolean
Dim vInfo As OSVERSIONINFO
vInfo.dwOSVersionInfoSize = Len(vInfo)
If (GetVersionEx(vInfo)) = 0 Then Exit Function
If vInfo.dwPlatformId = 2 Then IsWindowsNT = True
End Function
Option Explicit
Private Const CREATE_NEW As Long = 1
Private Const FILE_SHARE_READ As Long = &H1
Private Const FILE_SHARE_WRITE As Long = &H2
Private Const OPEN_EXISTING As Long = 3
Private Const GENERIC_WRITE As Long = &H40000000
Private Const GENERIC_READ As Long = &H80000000
Private Const IOCTL_STORAGE_CHECK_VERIFY As Long = &H2D4800
Private Const IOCTL_DISK_CHECK_VERIFY As Long = &H74800
Private Type OSVERSIONINFO
dwOSVersionInfoSize As Long
dwMajorVersion As Long
dwMinorVersion As Long
dwBuildNumber As Long
dwPlatformId As Long
szCSDVersion As String * 128
End Type
Private Type OVERLAPPED
ternal As Long
ternalHigh As Long
offset As Long
OffsetHigh As Long
hEvent As Long
End Type
Private Enum IDE_DRIVE_NUMBER
PRIMARY_MASTER
PRIMARY_SLAVE
SECONDARY_MASTER
SECONDARY_SLAVE
End Enum
Private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" (LpVersionInformation As OSVERSIONINFO) As Long
Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function DeviceIoControl Lib "kernel32" (ByVal hDevice As Long, ByVal dwIoControlCode As Long, lpInBuffer As Any, ByVal nInBufferSize As Long, lpOutBuffer As Any, ByVal nOutBufferSize As Long, lpBytesReturned As Long, ByVal lpOverlapped As Long) As Long
Private Sub Command1_Click()
Dim OL As OVERLAPPED
Dim retVal As Long
Dim hDev As Long
Dim lpcbBytesReturned As Long
If IsWindowsNT Then
hDev = CreateFile("\\.\D:", GENERIC_READ Or GENERIC_WRITE, FILE_SHARE_READ Or FILE_SHARE_WRITE, ByVal 0&, OPEN_EXISTING, 0, 0)
Else
hDev = CreateFile("\\.\D:", 0, 0, ByVal 0&, CREATE_NEW, 0, 0)
End If
retVal = DeviceIoControl(hDev, IOCTL_DISK_CHECK_VERIFY, ByVal 0, 0, ByVal 0, 0, lpcbBytesReturned, ByVal 0)
If retVal <> 0 Then
MsgBox "CD - Drive is ready", vbInformation, "Ready"
Else
MsgBox "CD - Drive is not ready", vbInformation, "Not ready"
End If
CloseHandle hDev
End Sub
Private Function IsWindowsNT() As Boolean
Dim vInfo As OSVERSIONINFO
vInfo.dwOSVersionInfoSize = Len(vInfo)
If (GetVersionEx(vInfo)) = 0 Then Exit Function
If vInfo.dwPlatformId = 2 Then IsWindowsNT = True
End Function