![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Состояние лотка CD-ROM
Vladimyr © (2004-08-30 20:02:00)Уважаемые знатоки API, есть ли способ определить, задвинут или выдвинут лоток CD-ROM?!..
Выдвигать научился, определять наличие диска - тоже, а с этим никак не выходит, всё API перечитал уже :-((
grom (2004-09-01 08:59:00) [1]Конечно приведённые мной примеры это всё нето.
Но может хоть както помогут в решении вопроса.
Vladimyr (2004-09-01 02:57:00) [2]Спасибо всем за ответы, но мы сильно уклонились от сути вопроса :)
Вопрос не в том, как определить наличие диска,а как определить состояние лотка!
То есть, если мы закрываем рукой пустой лоток, как отловить этот момент?..
(to grom: DBT_DEVICEARRIVAL ловит только лоток с диском;
на RSDN похоже, что-то рабочее, но на С и требует установленного ASPI. Можно поковырять на досуге...)
GuAV (2004-08-31 22:27:00) [3]http://www.delphimaster.ru/cgi-bin/forum.pl?id=1091205205&n=5
тот же сабж, то же ответ :)
Anatoly Podgoretsky (2004-08-31 22:01:00) [4]А есть ли мальчик, в смысле лоток
grom (2004-08-31 21:32:00) [5]http://rsdn.ru/Forum/Message/279073.htm
grom (2004-08-31 21:30:00) [6]определить состояние лотка у CD
если на лотке есть диск = if GetVolumeInformation(...)then ...
grom (2004-08-31 21:27:00) [7]Обработать момент вставки и вытаскивания CD
type
TForm1 = class(TForm)
private
procedure WMDeviceChange(var Msg: TMessage); message WM_DEVICECHANGE;
public
end;
{...}
implementation
{$R *.DFM}
procedure TForm1.WMDeviceChange(var Msg: TMessage);
const
DBT_DEVICEARRIVAL = $8000; // system detected a new device
DBT_DEVICEREMOVECOMPLETE = $8004; // device is gone
var
myMsg: string;
begin
inherited;
case Msg.wParam of
DBT_DEVICEARRIVAL: myMsg := 'CD inserted!';
DBT_DEVICEREMOVECOMPLETE: myMsg := 'CD removed!';
end;
ShowMessage(myMsg);
end;
{*********************************************}
// Advanced Code:
// When the device is of type volume, then we can get some device specific
// information, namely specific information about a logical volume.
// by Juergen Kantz
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
label1: TLabel;
private
procedure WMDeviceChange(var Msg: TMessage); message WM_DeviceChange;
{ Private declarations }
public
{ Public declarations }
end;
const
DBT_DeviceArrival = $8000;
DBT_DeviceRemoveComplete = $8004;
DBTF_Media = $0001;
DBT_DevTyp_Volume = $0002;
type
PDevBroadcastHdr = ^TDevBroadcastHdr;
TDevBroadcastHdr = packed record
dbcd_size: DWORD;
dbcd_devicetype: DWORD;
dbcd_reserved: DWORD;
end;
type
PDevBroadcastVolume = ^TDevBroadcastVolume;
TDevBroadcastVolume = packed record
dbcv_size: DWORD;
dbcv_devicetype: DWORD;
dbcv_reserved: DWORD;
dbcv_unitmask: DWORD;
dbcv_flags: Word;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function GetDrive(pDBVol: PDevBroadcastVolume): string;
var
i: Byte;
Maske: DWORD;
begin
if (pDBVol^.dbcv_flags and DBTF_Media) = DBTF_Media then
begin
Maske := pDBVol^.dbcv_unitmask;
for i := 0 to 25 do
begin
if (Maske and 1) = 1 then
Result := Char(i + Ord('A')) + ':';
Maske := Maske shr 1;
end;
end;
end;
procedure TForm1.WMDeviceChange(var Msg: TMessage);
var
Drive: string;
begin
case Msg.wParam of
DBT_DeviceArrival:
if PDevBroadcastHdr(Msg.lParam)^.dbcd_devicetype = DBT_DevTyp_Volume then
begin
Drive := GetDrive(PDevBroadcastVolume(Msg.lParam));
label1.Caption := 'CD inserted in Drive ' + Drive;
end;
DBT_DeviceRemoveComplete:
if PDevBroadcastHdr(Msg.lParam)^.dbcd_devicetype = DBT_DevTyp_Volume then
begin
Drive := GetDrive(PDevBroadcastVolume(Msg.lParam));
label1.Caption := 'CD removed from Drive ' + Drive;
end;
end;
end;
end.
OSokin (2004-08-31 20:15:00) [8]Чтобы проверить, находится ли диск в приводе, нужно использовать функцию "GetDiskFreeSpace(pchar(disk+':\'),a,a,a,a);", где "disk" - это название диска, а "a" - переменная типа cardinal. Если функция возвращает false, то диска в приводе нет.
Woolen (2004-08-31 18:04:00) [9]Могу предложить такой вариант, но это только опевещает об открытии или закрытии диска.
const
DBT_DEVICEREMOVEPENDING = $8003;
procedure WMDeviceChange(var Msg: TMsg); message WM_DEVICECHANGE;
procedure TForm1.WMDeviceChange(var Msg: TMsg);
begin
if Msg.wParam = DBT_DEVICEREMOVEPENDING then
// Началось открытие устройства
// Укажем винде, что мы отработали сообщение
Msg.Result := True;
end;
При желании есть еще сообщение DBT_DEVICEREMOVECOMPLETE = $8004, свидетельствующее о завершении открытия устройства, которое тоже можно ловить.
Больше, думаю, ничем помочь не смогу.
Woolen (2004-08-31 16:41:00) [10]Я думаю, что не надо пытаться миновать виндузовые драйвера, а надо с ними работать. Дело в том, что CD-ROM, как я понимаю, хотя и не сильно в этом разбираюсь, это не только хранилище данных с буковкой, но и, прежде всего, устройство Windows. А, значит, с ним можно работать не только считывая с него файлы.
Vladimyr (2004-08-31 16:28:00) [11]Как это сделать из-под DOS, я уже знаю :)
Делается запрос к MSCDEX и действительно в младшем бите видим состояние лотка (нашёл исходник на С).
Проблема в том, что Винда (особенно NT) не поддерживает досовские прерывания, а как работать с устройствами на низком уровне, минуя виндузовые драйвера, тоже вопрос без ответа ;)
Ладно, буду копать в других местах...
Woolen (2004-08-31 15:53:00) [12]Тебе бы с этим податься в форум системных программистов-фокусников или почитать документацию по устройству ATAPI, IDE и CD-ROM.
Woolen (2004-08-31 15:51:00) [13]Насколько я знаю, возможность есть. Но не советую тебе с этим возиться. Задача не из легких. Винда понимает, когда лоток открыт, а когда закрыт. Более того, она понимает, когда он открывается, а когда закрывается, но приложениям таких возможностей Windows не предоставляет. Дело в том, что работая непосредственно с устройством на низком уровне (по свидетельствам тех, кто с этим работал) можно прочитать из него бит, отвечающий за состояние лотка. Более того, у части приводов CD-ROM выставленный бит означает открытый лоток, а у некоторых, наоборот, нулевой. Так что, сначала, определяют тип CD-ROM. Как именно (в деталях) сделать подобный фокус тебе тут вряд ли кто ответит. Такой вопрос здесь появляется постоянно. Ни одного ответа я не видел. Когда сам хотел сделать то же самое, я подумал и решил, что продукт будет хорошо работать и без этого.
Vladimyr (2004-08-31 12:38:00) [14]Спасибо, но я не понял ничего :(
Ответ - "нельзя" ... Ответ - "можно"
И где упомянутый пример?!..
Сам я думаю, что возможность такая есть.
Почему? Потому что после закрытия пустого лотка курсор в виндах на пару секунд изменяется на стрелку с изображением CD. Значит, система определила факт закрытия лотка и смотрит, есть ли диск.
К сожалению, перехватывать изменение курсора я тоже не умею :(
grom (2004-08-31 08:02:00) [15]http://www.delphimaster.ru/cgi-bin/forum.pl?id=1091205205&n=5
Vladimyr (2004-08-31 03:47:00) [16]Ни однапрога не умеет определять состояние лотка! :((
Все это делают косвенно (если его задвинуть рукой, и в нём нет диска, они все думают, что лоток выдвинут).
GuAV (2004-08-30 20:12:00) [17]"На каждый выпущенный CD-ROM по отдельной программе ;-)" © jack128