Автор: eriser
« : 02 Ноября 2009, 22:01:20 »Блин. Разжевал и в рот положил. Теперь голово ломать нечем...
Спасибо!
Спасибо!
procedure TForm1.WMDeviceChange(var Msg: TWMDeviceChange);
begin
if (Msg.Event = DBT_CUSTOMEVENT) then
with PDevBroadcastHandle(Msg.dwData)^ do begin
if (dbch_devicetype = DBT_DEVTYP_HANDLE) then begin
if IsEqualGUID( dbch_eventguid, GUID_IO_MEDIA_ARRIVAL)
then begin
//*** карточку воткнули
Label1.Caption := \'Inserted\';
end
else if IsEqualGUID( dbch_eventguid, GUID_IO_MEDIA_REMOVAL)
then begin
//*** карточку выдернули
Label1.Caption := \'Removed\';
end;
end;
end;
end;
function RegNotif( Wnd: HWND; DriveChar: Char;
var Fltr: TDevBroadcastHandle): HDEVNOTIFY;
var
PhysDrvH: THandle;
PhysDrvName: String;
PhysDrvNum: Integer;
begin
Result := nil;
FillChar(Fltr, SizeOf(Fltr), 0);
//*** находим номер физического диска
PhysDrvNum := GetFirstPhysicalDriveNumber(DriveChar);
if PhysDrvNum = -1 then Exit;
//*** имя физического диска
PhysDrvName := \'\\\\.\\PhysicalDrive\'+IntToStr(PhysDrvNum);
//*** открываем диск (неважно, вставлена ли карточка)
PhysDrvH := CreateFile(PChar(PhysDrvName), 0, FILE_SHARE_WRITE,
nil, OPEN_EXISTING, 0, 0);
//*** заполняем структуру TDevBroadcastHandle
Fltr.dbch_size := SizeOf(Fltr);
Fltr.dbch_devicetype := DBT_DEVTYP_HANDLE; // тип
Fltr.dbch_handle := PhysDrvH; // хэндл диска
//*** регистрируем для окна Wnd
Result := RegisterDeviceNotification( Wnd, @Fltr,
DEVICE_NOTIFY_WINDOW_HANDLE );
//*** освобождаем хэндл диска
CloseHandle(PhysDrvH);
end;
//*** GetFirstPhysicalDriveNumber
//*** возвращает номер физического диска для указанной буквы диска
function GetFirstPhysicalDriveNumber(DrvChar: Char): Integer;
var
i: Cardinal;
Buf: packed array[0..256]of Char;
DriveName: String;
begin
Result := -1;
//*** получаем имя диска вида \\Device\\HardDiskX\\...
QueryDosDevice(PChar(\'\'+DrvChar+\':\'), Buf, 256);
//*** извлекаем номер X
DriveName := AnsiLowerCase(StrPas(Buf));
Form1.Memo1.Lines.Add( \'Drive \'+DrvChar+\': is a \'+Buf );
i := Pos(\'\\device\\harddisk\', DriveName);
if i = 1 then begin
Delete(DriveName,1,Length(\'\\device\\harddisk\'));
i := Pos(\'\\\',DriveName);
if i > 0 then
Delete(DriveName, i, MAXINT);
try
Result := StrToInt(DriveName);
except
end;
end;
end;
PPS: Andy, наверное эти посты в отдельную тему лучше перенести.
PS: Так, к слову, посмотрел как работает ImaTouch. Он делает это ежесекундным опросом дисков.Это подтверждает данную проблему.