Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2004.10.10;
Скачать: [xml.tar.bz2];

Вниз

Состояние лотка 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 вся ветка

Форум: "WinAPI";
Текущий архив: 2004.10.10;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.032 c
1-1096034724
ShproTT
2004-09-24 18:05
2004.10.10
Delphi+MS Word


1-1095939520
Kniaz
2004-09-23 15:38
2004.10.10
Блокирование файла


9-1086597391
Igoryok
2004-06-07 12:36
2004.10.10
Разве есть дельфих для directx9


1-1096094700
Leaner
2004-09-25 10:45
2004.10.10
Контрольная сумма файла.


1-1095753144
roma
2004-09-21 11:52
2004.10.10
kataloq





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский