Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.10.10;
Скачать: CL | DM;

Вниз

Состояние лотка CD-ROM   Найти похожие ветки 

 
Vladimyr ©   (2004-08-30 20:02) [0]

Уважаемые знатоки API, есть ли способ определить, задвинут или выдвинут лоток CD-ROM?!..
Выдвигать научился, определять наличие диска - тоже, а с этим никак не выходит, всё API перечитал уже :-((


 
GuAV ©   (2004-08-30 20:12) [1]

"На каждый выпущенный CD-ROM по отдельной программе ;-)" © jack128


 
Vladimyr ©   (2004-08-31 03:47) [2]

Ни одна прога не умеет определять состояние лотка! :((
Все это делают косвенно (если его задвинуть рукой, и в нём нет диска, они все думают, что лоток выдвинут).


 
grom   (2004-08-31 08:02) [3]

http://delphimaster.net/view/4-1091205205/


 
Vladimyr ©   (2004-08-31 12:38) [4]

Спасибо, но я не понял ничего :(
Ответ - "нельзя" ... Ответ - "можно"
И где упомянутый пример?!..

Сам я думаю, что возможность такая есть.
Почему? Потому что после закрытия пустого лотка курсор в виндах на пару секунд изменяется на стрелку с изображением CD. Значит, система определила факт закрытия лотка и смотрит, есть ли диск.
К сожалению, перехватывать изменение курсора я тоже не умею :(


 
Woolen ©   (2004-08-31 15:51) [5]

Насколько я знаю, возможность есть. Но не советую тебе с этим возиться. Задача не из легких. Винда понимает, когда лоток открыт, а когда закрыт. Более того, она понимает, когда он открывается, а когда закрывается, но приложениям таких возможностей Windows не предоставляет. Дело в том, что работая непосредственно с устройством на низком уровне (по свидетельствам тех, кто с этим работал) можно прочитать из него бит, отвечающий за состояние лотка. Более того, у части приводов CD-ROM выставленный бит означает открытый лоток, а у некоторых, наоборот, нулевой. Так что, сначала, определяют тип CD-ROM. Как именно (в деталях) сделать подобный фокус тебе тут вряд ли кто ответит. Такой вопрос здесь появляется постоянно. Ни одного ответа я не видел. Когда сам хотел сделать то же самое, я подумал и решил, что продукт будет хорошо работать и без этого.


 
Woolen ©   (2004-08-31 15:53) [6]

Тебе бы с этим податься в форум системных программистов-фокусников или почитать документацию по устройству ATAPI, IDE и CD-ROM.


 
Vladimyr ©   (2004-08-31 16:28) [7]

Как это сделать из-под DOS, я уже знаю :)
Делается запрос к MSCDEX и действительно в младшем бите видим состояние лотка (нашёл исходник на С).
Проблема в том, что Винда (особенно NT) не поддерживает досовские прерывания, а как работать с устройствами на низком уровне, минуя виндузовые драйвера, тоже вопрос без ответа ;)
Ладно, буду копать в других местах...


 
Woolen ©   (2004-08-31 16:41) [8]

Я думаю, что не надо пытаться миновать виндузовые драйвера, а надо с ними работать. Дело в том, что CD-ROM, как я понимаю, хотя и не сильно в этом разбираюсь, это не только хранилище данных с буковкой, но и, прежде всего, устройство Windows. А, значит, с ним можно работать не только считывая с него файлы.


 
Woolen ©   (2004-08-31 18:04) [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, свидетельствующее о завершении открытия устройства, которое тоже можно ловить.
Больше, думаю, ничем помочь не смогу.


 
OSokin ©   (2004-08-31 20:15) [10]

Чтобы проверить, находится ли диск в приводе, нужно использовать функцию "GetDiskFreeSpace(pchar(disk+":\"),a,a,a,a);", где "disk" - это название диска, а "a" - переменная типа cardinal. Если функция возвращает false, то диска в приводе нет.


 
grom   (2004-08-31 21:27) [11]

Обработать момент вставки и вытаскивания 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.


 
grom   (2004-08-31 21:30) [12]

определить состояние лотка у CD
если на лотке есть диск = if GetVolumeInformation(...)then ...


 
grom   (2004-08-31 21:32) [13]

http://rsdn.ru/Forum/Message/279073.htm


 
Anatoly Podgoretsky ©   (2004-08-31 22:01) [14]

А есть ли мальчик, в смысле лоток


 
GuAV ©   (2004-08-31 22:27) [15]

http://delphimaster.net/view/4-1091205205/
тот же сабж, то же ответ :)


 
Vladimyr ©   (2004-09-01 02:57) [16]

Спасибо всем за ответы, но мы сильно уклонились от сути вопроса :)
Вопрос не в том, как определить наличие диска, а как определить состояние лотка!
То есть, если мы закрываем рукой пустой лоток, как отловить этот момент?..

(to grom: DBT_DEVICEARRIVAL ловит только лоток с диском;
на RSDN похоже, что-то рабочее, но на С и требует установленного ASPI. Можно поковырять на досуге...)


 
grom   (2004-09-01 08:59) [17]

Конечно приведённые мной примеры это всё нето.
Но может хоть както помогут в решении вопроса.



Страницы: 1 вся ветка

Текущий архив: 2004.10.10;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.04 c
14-1095679288
Dimedrol
2004-09-20 15:21
2004.10.10
Помогите! кажется меня похачили :-( (Linux-Apache)


6-1087399043
Davron
2004-06-16 19:17
2004.10.10
IntraWeb


1-1096113765
Billi
2004-09-25 16:02
2004.10.10
Проблема кодировок


1-1096031373
AdmeraL
2004-09-24 17:09
2004.10.10
TRegIniFile


14-1096002016
080D:07BBh
2004-09-24 09:00
2004.10.10
Caliber RM