Ajuda - Busca - Membros - Calendário
Versão Completa: Abrir A Bandeja Do Dvd
Fórum Script Brasil > Programação & Desenvolvimento > Delphi, Kylix
luizf
Será que alguém pode me dizer como faço para abrir a bandeja do DVD.

Sei como abrir a do CD, mas não do DVD.

Já procurei dicas em vários sites, mas não encontrei.

Muito Obrigado.

T+ cool.gif
paulobergo
Olá...
Uso o código abaixo para abrir o leitor de gravador de CD no trabalho e também o gravador de CD/leitor de DVD em casa:

CODE

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  // Adicionar MMSystem;
  With MediaPlayer1 do Begin
    If (MediaPlayer1.Mode=mpOpen) then
      mciSendCommand(MediaPlayer1.DeviceID,MCI_SET,
                     MCI_SET_DOOR_CLOSED,0)
    Else
      mciSendCommand(MediaPlayer1.DeviceID,MCI_SET,
                     MCI_SET_DOOR_OPEN,0);
    {EndIf}
  End;{With MediaPlayer1}
End;


Funciona para ambos...
Experimenta....

Ok?
Micheus
QUOTE
Sei como abrir a do CD, mas não do DVD.
luizf, utilizo a função mciSendString que, comumente é utilizada para abrir CD's, funciona perfeitamente em meu gravador de DVD.
Dê uma olhada se está sendo retornado algum erro: utilize mciGetErrorString para verificar. Ex.:
CODE
procedure TForm1.Button1Click(Sender: TObject);
var
  Erro :LongInt;
  Texto :array[0..128] of char;
begin
  if Boolean(Button1.Tag) then
    Erro := mciSendString('set cdaudio door closed wait', nil, 0, handle)
  else
    Erro := mciSendString('set cdaudio door open wait', nil, 0, handle);

  if mciGetErrorString(Erro, Texto, SizeOf(Texto)) then
    ShowMessage(Texto);

  Button1.Tag := Ord(not Boolean(Button1.Tag));
end;


[]s
Paulo Nobre
E caso se possua os dois dispositivos?
Micheus
QUOTE(Paulo Nobre @ Nov 13 2006, 05:31 AM) *

E caso se possua os dois dispositivos?
Uma boa pergunta. Acho que teria que utilizar mciSendCommand e definir o dispositivo desejado. Alguém tem como testar?
Paulo Nobre
Fiz a pergunta pois em casa tenho um computador com os dois dispositivos e com o código tradicional(mencionado acima) ele só abre o gravador de CD. Nos computadores que apresentam apenas um dispositivo ele abre qualquer um que esteja la´. (DVD ou CD)
paulobergo
Oi pessoal...

Isso é para abrir qualquer unidade pela letra...
Só funciona com leitores de CD... não sei porque não funciona com os DVDs... quem quiser se arriscar a descobrir...
CODE

Unit Unit1;

Interface

Uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, MMSystem, StdCtrls, MPlayer;

Type
  TForm1 = class(TForm)
    MediaPlayer1: TMediaPlayer;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

Var
  Form1: TForm1;

Implementation

{$R *.dfm}

{********* Abre qualquer unidade (desde que seja CD), pela letra ********}
Function OpenCD(Drive: Char): Boolean;
Var
  Res: MciError;
  OpenParm: TMCI_Open_Parms;
  Flags: DWORD;
  S: string;
  DeviceID: Word;
Begin
  Result := False;
  S := Drive + ':';
  Flags  := MCI_OPEN_TYPE or MCI_OPEN_ELEMENT;
  With OpenParm do Begin
    dwCallback := 0;
    lpstrDeviceType := 'CDAudio';
    lpstrElementName := PChar(S);
  End;{with OpenParm}
  Res := mciSendCommand(0, MCI_OPEN, Flags, Longint(@OpenParm));
  if Res <> 0 then Exit;
  DeviceID := OpenParm.wDeviceID;
  Try
    Res := mciSendCommand(DeviceID, MCI_SET, MCI_SET_DOOR_OPEN, 0);
    if Res = 0 then Exit;
    Result := True;
  Finally
    mciSendCommand(DeviceID, MCI_CLOSE, Flags, Longint(@OpenParm));
  End;
End;

{********* Fecha qualquer unidade (desde que seja CD), pela letra ********}
Function CloseCD(Drive: Char): Boolean;
Var
  Res: MciError;
  OpenParm: TMCI_Open_Parms;
  Flags: DWORD;
  S: string;
  DeviceID: Word;
Begin
  Result := False;
  S := Drive + ':';
  Flags  := MCI_OPEN_TYPE or MCI_OPEN_ELEMENT;
  With OpenParm do Begin
    dwCallback := 0;
    lpstrDeviceType := 'CDAudio';
    lpstrElementName := PChar(S);
  End;
  Res := mciSendCommand(0, MCI_OPEN, Flags, Longint(@OpenParm));
  if Res <> 0 then Exit;
  DeviceID := OpenParm.wDeviceID;
  Try
    Res := mciSendCommand(DeviceID, MCI_SET, MCI_SET_DOOR_CLOSED, 0);
    if Res = 0 then Exit;
    Result := True;
  Finally
    mciSendCommand(DeviceID, MCI_CLOSE, Flags, Longint(@OpenParm));
  End;
End;

{********** Jeito simples ***********}
Procedure TForm1.Button1Click(Sender: TObject);
Begin
  mciSendstring('SET CDAUDIO DOOR OPEN WAIT', nil, 0, Self.Handle);
End;

{********** Abrindo com as funções ***********}

Procedure TForm1.Button2Click(Sender: TObject);
Begin
  // Abre quando os dois são CDs.. quando um é dvd, não abre (o dvd)...
  OpenCD('E');
  OpenCD('F');
End;

Procedure TForm1.Button3Click(Sender: TObject);
Begin
  // Fecha quando os dois são CDs.. quando um é dvd, não fecha (o dvd)...
  CloseCD('E');
  CloseCD('F');
End;

end.


Ok?
luizf
É justamente por isso que quero saber como abrir a bandeja do DVD, pois possuo os dois.

Aguardo respostas.

Obrigado a todos.
luizf
Pô pessoal, ninguém sabe??

sad.gif

Ainda vou continuar aguardando.

T+
luizf
sad.gif Please........
s3c
Tente ejetar pelo Shell Application:
CODE
uses Variants, ComObj;
var SA:Variant;
begin
  SA := CreateOleObject('Shell.Application');
  SA.NameSpace(17).ParseName('E:\').InvokeVerb('E&ject');
  SA := Unassigned;
end;
Troque 'E:\' pela sua unidade de DVD.
Paulo Nobre
s3c,
testei, mas não funcionou.
Tenho os dois dispositivos e não funcionou.
Será que é porque tem os dois?

A propósito, como poderia descobrir qual o diretório que está instalado o DVD?(Via código é claro?)
Porque com esse abaixo
CODE
:
mciSendString('Set cdaudio door open wait', nil, 0, handle);

ele abre o dispositivo sempre do cd quando tem os dois e abre o do dvd quando so tem ele.

Para fechar é só trocar o opem pelo close.
Ou seja, ele não precisa saber qual é a letra onde está o CD.
Churc
QUOTE
uses Variants, ComObj;
var SA:Variant;
begin
SA := CreateOleObject('Shell.Application');
SA.NameSpace(17).ParseName('E:\').InvokeVerb('E&ject');
SA := Unassigned;
end;


opa
testei aqui não funcionou não...
aproveitei e já testei nos 2 drive, não abriu nenhum...
Churc
opa

achei um aqui que funcionou aqui, testa ai

http://www.thescripts.com/forum/thread124082.html

passando pra delphi seria

procedure AbreSafado(const Drive: Char; szAcao: String);
var
szBuff: String;
begin
szBuff := 'open ' + Drive + ':\ type cdaudio alias DRIVE';
mciSendString(PChar(szBuff), nil, 0, 0);
mciSendString(PChar('set DRIVE door ' + szAcao), nil, 0, 0);
mciSendString(PChar('close all'), nil, 0, 0);
end;

ai pra usar

AbreSafado('E', 'open');

troque o E pela letra do Drive só não consegui fazer fechar, mas
como o amigo quis somente saber como abre HUASHUA talvez
ajude


é marquei vi que acima já tem isso ai rsr fiz baseado no do s3c
mas se eu achar uma maneira melhor eu posto aqui
s3c
Pessoal, não sei se é o caso mas este código:
CODE
var SA:Variant;
begin
  SA := CreateOleObject('Shell.Application');
  SA.NameSpace(17).ParseName('E:\').InvokeVerb('E&ject');
  SA := Unassigned;
end;
Simula o clique do botão direito do mouse no Explorer em cima do drive E, depois procura por Eject(com o 'j' sublinhado e invoca o comando. Como o meu é o XP em inglês, "Eject" é o comando que aparece no menu popup do Explorer. Vejam se o de vocês é diferente como Ejetar, ou outra coisa qualquer e troquem pelo que aparece. Talvez seja isso.
Paulo Nobre
s3c,
usando
CODE

SA.NameSpace(17).ParseName('G:\').InvokeVerb('E&jetar');

funciona!!
Pena que não teria um análogo para fechar!!

Mas, como eu faço para descobrir. via código, qual a letra do DVD.
Tem algum código, tipo daqueles ,que descobrem onde está instalado o windows?
s3c
Olá Paulo,
1-O seu DVD, pelo Explorer você tem a opção no botão direito do mouse de ejetar ?
2-Aonde ele aparece ? abaixo do My Computer no mesmo nível do CDROM ?
3-Com que nome ele aparece ?

ps: se não tiver a opção de ejetá-lo pelo mouse, acho que Shell Application não servirá.
Churc
ahh sim verdade aqui funcionou também, achei que E&ject fosse comando
e não que tivesse haver com o Ejetar do menu do explorer rsr
até tirei o & achando que era erro de escrita...

pu.tz o Windows é foda meu, vai vendo os recursos que ele
da suporte, olha isso que absurdo uhahuashu rolleyes.gif

abs
Micheus
Bom, eu tenho apenas um Gravador de DVD, então acho que não estou entendendo direito o problema, pois a alguns posts acima (post do Paulo Bergo) o comando que está aparentemente configurado para executar no CD - cdaudio (ele comenta que funciona apenas com CD) está funcionando com meu gravador. E se eu trocar por digitalvideo ou videodisc não funciona. Alguém tentou com estes antes?

Os device types deveriam ser um destes: cdaudio, digitalvideo, videodisc
ou MCI_DEVTYPE_CD_AUDIO, MCI_DEVTYPE_DIGITAL_VIDEO, MCI_DEVTYPE_VIDEODISC; quando aplicável (msdn).


s3c, mas se pode haver problemas com o idima, será que é uma boa saída?
s3c
QUOTE(Micheus @ Nov 24 2006, 06:56 PM) *
s3c, mas se pode haver problemas com o idima, será que é uma boa saída?
Bom, você pode saber os ítens do menu popup que o Explorer apresenta:
CODE
var i:Integer; SA:Variant;
begin
  SA := CreateOleObject('Shell.Application');
  for i := 0 to SA.NameSpace(17).ParseName('D:\').Verbs.Count-1 do
    Memo1.Lines.Add(SA.NameSpace(17).ParseName('D:\').Verbs.Item(i).Name);
  SA := Unassigned;
end;
Utilizei um TMemo para visualizar, mas a cada iteração do for você pode checar o E&ject pertinente para aquele computador e depois executar o InvokeVerb.

Existe outra opção, sabendo-se a letra do drive, mandando diretamente o código de controle para o dispositivo(abrir ou fechar):
CODE
const IOCTL_Storage_Eject_Media = $002D4808; IOCTL_Storage_Load_Media = $002D480C;
var hDevice:THandle; dRet:DWord;
begin
  HDevice := CreateFile(PChar('\\.\E:'),
                        Generic_Read or Generic_Write,
                        0,
                        nil,
                        Open_Existing,
                        0,
                        0);
  DeviceIoControl(hDevice, IOCTL_Storage_Eject_Media, nil, 0, nil, 0, dRet, nil); // Ejeta
  DeviceIoControl(hDevice, IOCTL_Storage_Load_Media,  nil, 0, nil, 0, dRet, nil); // Fecha
  CloseHandle(hDevice);
end;
No caso foi utilizado E:
Paulo Nobre
Olá, s3c
QUOTE

Olá Paulo,
1-O seu DVD, pelo Explorer você tem a opção no botão direito do mouse de ejetar ?

Sim
QUOTE

2-Aonde ele aparece ? abaixo do My Computer no mesmo nível do CDROM ?

Abaixo do Meu Computador no mesmo nível do CDROM
QUOTE

3-Com que nome ele aparece ?

Unidade de DVD-RAM(G:)

QUOTE

ps: se não tiver a opção de ejetá-lo pelo mouse, acho que Shell Application não servirá.

Mas, eu já havia dito, s3c,no post acima do seu(#16), que funcionou para mim.
O que eu disse foi o seguinte:
QUOTE

funciona!!
Pena que não teria um análogo para fechar!!

Mas, como eu faço para descobrir. via código, qual a letra do DVD.
Tem algum código, tipo daqueles ,que descobrem onde está instalado o windows?


Tem como?

Não havendo, a única coisa que me vem a cabeça é fazer uso do velho e amigo registro.
Na primeira vez que usar o comando , abre uma tela para o usuário dizer qual a letra correspondente ao seu DVD, grava no registro e sempre que abrir o programa trás ela para o lugar ocupado pelo 'E" no código acima. Alguém tem outra idéia melhor?

Testei
CODE

DeviceIoControl(hDevice, IOCTL_Storage_Load_Media,  nil, 0, nil, 0, dRet, nil); // Fecha

Aqui não funciona.
O compilador esta mandando também as mensagens de que:
CODE

[Hint] Unit1.pas(91): Value assigned to 'hDevice' never used
[Hint] Unit1.pas(89): Variable 'dRet' is declared but never used in 'TForm1.Button4Click'
Denis Bittencourt Muniz
Legal esse tópico! Segui a dica do s3c ("Shell.Application") e funcionou! O mais legal é que eu não conhecia esse objeto COM/ActiveX chamado 'Shell.Application', interessante.

Falows!

P.S: Só que eu fiz o teste no VB6. Mas o que importa? É um objeto COM/ActiveX : )
s3c
QUOTE(Paulo Nobre @ Nov 24 2006, 10:05 PM) *
Unidade de DVD-RAM(G:)
Mesmo trocando a unidade por G:\ não funciona?
Se não funcionar, tente acessar o ítem pelo nome que aparece:
CODE
var i:Integer; SA:Variant;
begin
  SA := CreateOleObject('Shell.Application');
  for i := 0 to SA.NameSpace(17).Items.Count-1 do
  begin
    if Pos('DVD-RAM', SA.NameSpace(17).Items.Item(i).Name) > 0 then
      SA.NameSpace(17).Items.Item(i).InvokeVerb('E&jetar');
  end;
  SA := Unassigned;
end;

QUOTE(Paulo Nobre @ Nov 24 2006, 10:05 PM) *
CODE
DeviceIoControl(hDevice, IOCTL_Storage_Load_Media,  nil, 0, nil, 0, dRet, nil); // Fecha
Aqui não funciona.
O compilador esta mandando também as mensagens de que:
CODE

[Hint] Unit1.pas(91): Value assigned to 'hDevice' never used
[Hint] Unit1.pas(89): Variable 'dRet' is declared but never used in 'TForm1.Button4Click'
Esses dois Hints acho que estão dizendo que ele está executando CreateFile mas não está executando DeviceIoControl. Poste o código do Button4Click.
Micheus
s3c, essa idéia do uso do uso de DeviceIOControl (IOCTL) mais interessante, já que não depende de questões como idioma, o que torna mais genérico seu uso.
Ficamos de quaquer modo, para ambas as opções, com a questão de saber qual a letra do CD ou DVD, certo?!

Então, eu havia encontrado no site ma Micro$oft um exemplo de como obter informações, justamente utilizando recursos IOCTL, sobre como descobrir quantos, quais e detalhes dos drivers de CD's instalados. O detalhe é que achei o código meio comprido, em C++ e tô meio sem tempo para converter. Talvez algum colega, se habilite a dar uma enxugada no código de modo apenas a obter os drivers (respectivas letras) para serem utizados com com a opção que você postou utilizando IOCTL.

[]s
s3c
QUOTE(Micheus @ Nov 25 2006, 10:22 AM) *
s3c, essa idéia do uso do uso de DeviceIOControl (IOCTL) mais interessante, já que não depende de questões como idioma, o que torna mais genérico seu uso.
Ficamos de quaquer modo, para ambas as opções, com a questão de saber qual a letra do CD ou DVD, certo?!
Pelo DeviceIOControl acho que sim, por outro lado, pelo Shell.Application, você consegue pesquisar o nome do FolderItem e aplicar o InvokeVerb sem saber a letra:
CODE
var i:Integer; SA:Variant;
begin
  SA := CreateOleObject('Shell.Application');
  for i := 0 to SA.NameSpace(17).Items.Count-1 do
  begin
    if Pos('DVD-RAM', SA.NameSpace(17).Items.Item(i).Name) > 0 then
      SA.NameSpace(17).Items.Item(i).InvokeVerb('E&jetar');
  end;
  SA := Unassigned;
end;
É claro que para um código que funcione em qualquer máquina, devem ser checados os possíveis nomes que possam vir de CD e DVD; o que tornaria uma rotina bastante trabalhosa, além do que você só consegue ejetar a unidade.
Talvez pelo IOCTL e CreateFile retornando um Handle válido, o DeviceIOControl seria a forma mais direta e eficaz de abrir e fechar as bandejas.
Paulo Nobre
s3c

Para abrir está funcionando normalmente!!
Para fechar, não.
O código do button4click é:
CODE

procedure TForm1.Button4Click(Sender: TObject);
const IOCTL_Storage_Eject_Media = $002D4808; IOCTL_Storage_Load_Media = $002D480C;
var hDevice:THandle; dRet:DWord;
begin
  HDevice := CreateFile(PChar('\\.\g:'),
                        Generic_Read or Generic_Write,
                        0,
                        nil,
                        Open_Existing,
                        0,
                        0);
  //DeviceIoControl(hDevice, IOCTL_Storage_Eject_Media, nil, 0, nil, 0, dRet, nil); // Ejeta
  DeviceIoControl(hDevice, IOCTL_Storage_Load_Media,  nil, 0, nil, 0, dRet, nil); // Fecha
  CloseHandle(hDevice);
end;
s3c
Olá Paulo, após o CreateFile coloque:
CODE
  ShowMessage(IntToStr(hDevice));
E poste o número que aparece.
Paulo Nobre
QUOTE

Olá Paulo, após o CreateFile coloque:CODE ShowMessage(IntToStr(hDevice));E poste o número que aparece.


Olá,s3c,
O número que aparece é o 4294967295
luizf
E aí pessoal, beleza.

Obrigado pela atenção, aguardo respostas.

Parece que tá meio difícil de abrir e fechar a bandeja do DVD, mas ...


T+
Paulo Nobre
QUOTE

Parece que tá meio difícil de abrir e fechar a bandeja do DVD, mas ...


Realmente luizf não está fácil não, mas mesmo que não se consiga a resposta total, este
tópico foi muito enriquecedor na minha opinião, principalmente aquela parte postada pelo s3c, para obter
a lista das opções obtidas com o botão direiot do mouse(simulação).
Repare que já se tem como abrir a gaveta do DVD, tá faltando obter como se fecha.
Churc
QUOTE
Parece que tá meio difícil de abrir e fechar a bandeja do DVD, mas ...

mas luizf pra que você quer que seu programa faça com que a bandeja fecha sendo que se ela abre pro usuário por ou tirar o dvd, então impossível um programa saber se ele já colocou ou tirou, então acho que cabe ao usuário fechar e não ao sistema, onde entre ele clicar em um botao no seu sistema pra fechar a gaveta ou fecha-la manualmente é mais conveniente fechar manualmente pois ele vai tar colocando ou tirando um dvd mesmo, já vai estar com a mão na massa rsr
Micheus
QUOTE
Talvez pelo IOCTL e CreateFile retornando um Handle válido, o DeviceIOControl seria a forma mais direta e eficaz de abrir e fechar as bandejas.
s3c, aparentemente não há problemas com o abrir e fechar pelo menos com o W2K e XP, mas fico em dúvida se funcionaria com as versões anteriores (tentarei testar no Me amanhã) porque pela nota que lí no final deste artigo (msdn - Calling DeviceIoControl), há risco de não funcionar (tem que testar para comprovar).

QUOTE(Paulo Nobre @ Nov 24 2006, 03:17 PM) *
Mas, como eu faço para descobrir. via código, qual a letra do DVD.
Paulo, Considerando a questão de compatibilidade, há um meio simples de listar as unidades de disco ótico (CD/DVD), através da combinação das funções da API GetLogicalDriveStrings e GetDriveType. O exemplo abaixo adiciona a uma lista a letra dos dipositivos óticos encontrados:
CODE
procedure TForm1.Button1Click(Sender: TObject);
var
  pIdx :PChar;
  sDrives :array[0..255] of char;
  sDrive :string;
begin
  if GetLogicalDriveStrings(SizeOf(sDrives)-1, sDrives) > 0 then
  begin
    pIdx := sDrives;
    while pIdx^ <> '' do
    begin
      sDrive := Copy(pIdx, 1, 2);
      if GetDriveType(PChar(sDrive)) = DRIVE_CDROM then
        ListBox1.Items.Add('(CD/DVD) '+sDrive);
      Inc(pIdx, 4);
    end;
  end;
end;
Entretanto para saber se é um dispositivo de DVD ou CD, a coisa novamente complica um pouco. Utilizando das funções IOCTL só conseguimos a resposta correta a partir do W2K. Se interessar a alguém, tem uma versão em VB neste link

QUOTE(Churc @ Nov 25 2006, 09:15 PM) *
QUOTE
Parece que tá meio difícil de abrir e fechar a bandeja do DVD, mas ...

mas luizf pra que você quer que seu programa faça com que a bandeja fecha sendo que se ela abre pro usuário por ou tirar o dvd, então impossível um programa saber se ele já colocou ou tirou, então acho que cabe ao usuário fechar e não ao sistema, onde entre ele clicar em um botao no seu sistema pra fechar a gaveta ou fecha-la manualmente é mais conveniente fechar manualmente pois ele vai tar colocando ou tirando um dvd mesmo, já vai estar com a mão na massa rsr
Churc, dá para saber sim se há ou não um CD na bandeja dentro do gabinete. O lance é processar a mensagem WM_DEVICECHANGE. O parâmetro DBT_DEVICEARRIVAL só chega quando a gaveta é fechada e tem uma mídia dentro. Tem um exemplo completo na página do Torry's (link)

[]s
Churc
QUOTE
Churc, dá para saber sim se há ou não um CD na bandeja dentro do gabinete. O lance é processar a mensagem WM_DEVICECHANGE. O parâmetro DBT_DEVICEARRIVAL só chega quando a gaveta é fechada e tem uma mídia dentro. Tem um exemplo completo na página do Torry's (link)

Ah sim, mas não quis dizer nesse sentido, seria no sentido de quando o usuário colocar o dvd, sem fechar a gaveta...
Pois a questão que mencionei é pra que ele quer que o sistema fecha a gaveta se o usuário vai ter que colocar o dvd na gaveta... entendeu? rsr

QUOTE
Entretanto para saber se é um dispositivo de DVD ou CD, a coisa novamente complica um pouco. Utilizando das funções IOCTL só conseguimos a resposta correta a partir do W2K. Se interessar a alguém, tem uma versão em VB neste link

muito boa essa dica wink.gif
Micheus
QUOTE(Churc @ Nov 26 2006, 11:07 PM) *
Ah sim, mas não quis dizer nesse sentido, seria no sentido de quando o usuário colocar o dvd, sem fechar a gaveta...
Pois a questão que mencionei é pra que ele quer que o sistema fecha a gaveta se o usuário vai ter que colocar o dvd na gaveta... entendeu? rsr
#&%#@!!!
Foi mal, entendi errado.
Churc
QUOTE
#&%#@!!!
Foi mal, entendi errado.

da nada, nem tem muito haver o que eu falei, é que tem bastante informação neste tópico, e ao meu entender o criador do tópico fez um ar de não satisfeito e desprezo rsr, ai por isso questionei sobre o porque ele quer que fecha a bandeja, não tem muito sentido... rsr
Paulo Nobre
QUOTE

Entretanto para saber se é um dispositivo de DVD ou CD, a coisa novamente complica um pouco. Utilizando das funções IOCTL só conseguimos a resposta correta a partir do W2K.

Então se alguém souber o código, mesmo para XP apenas, poderia postar.
Mesmo que só para uso particular para quem tem XP, já serviria.


Em último caso, mesmo muito deselegantemente apelaria para a sugestão que dei num post anterior, embora não seja uma alternativa típica de um programador
QUOTE

Não havendo, a única coisa que me vem a cabeça é fazer uso do velho e amigo registro.
Na primeira vez que o usuário usar o comando , abre uma tela para o usuário dizer qual a letra correspondente ao seu DVD, grava no registro e sempre que abrir o programa trás ela para o lugar ocupado pelo 'E" no código acima, fornecido pelo s3c. O único problema é que não está funcionado para fechar a gaveta.
s3c
QUOTE(Paulo Nobre @ Nov 25 2006, 05:24 PM) *
QUOTE
Olá Paulo, após o CreateFile coloque:CODE ShowMessage(IntToStr(hDevice));E poste o número que aparece.

Olá,s3c,
O número que aparece é o 4294967295
Isto indica um Handle inválido e ao que parece CreateFile não está entendendo sua unidade g:, logo DeviceIoControl não funcionará nem para abrir, nem para fechar; assim como Shell.Application não entende ParseName('g:\').
Outra sugestão seria retornar a letra do Drive(se é que existe neste caso) utilizando WMI.
Paulo Nobre
s3c, algo muito estranho então deve estar acontecendo, pois estou conseguindo abrir o DVD.
Só fechar é que não.
Churc
QUOTE
Então se alguém souber o código, mesmo para XP apenas, poderia postar.
Mesmo que só para uso particular para quem tem XP, já serviria.

Opa
Mas então, esse código funciona pra XP porque é a partir do Windows 2000, então ai se inclui, 2000, NT, XP, 2003, Vista
s3c
QUOTE(Paulo Nobre @ Nov 27 2006, 09:33 AM) *
s3c, algo muito estranho então deve estar acontecendo, pois estou conseguindo abrir o DVD.
Só fechar é que não.
Você consegue abrir pelo Shell.Application ou pelo DeviceIoControl ?
Paulo Nobre
pelo DeviceIoControl ...
Consigo abrir usando o código abaixo, que você forneceu:

const IOCTL_Storage_Eject_Media = $002D4808; IOCTL_Storage_Load_Media = $002D480C;
var hDevice:THandle; dRet:DWord;
begin
HDevice := CreateFile(PChar('\\.\G:'),
Generic_Read or Generic_Write,
0,
nil,
Open_Existing,
0,
0);
DeviceIoControl(hDevice, IOCTL_Storage_Eject_Media, nil, 0, nil, 0, dRet, nil); // Ejeta
//DeviceIoControl(hDevice, IOCTL_Storage_Load_Media, nil, 0, nil, 0, dRet, nil); // Fecha
CloseHandle(hDevice);
end;

Quando uso para fechar

const IOCTL_Storage_Eject_Media = $002D4808; IOCTL_Storage_Load_Media = $002D480C;
var hDevice:THandle; dRet:DWord;
begin
HDevice := CreateFile(PChar('\\.\G:'),
Generic_Read or Generic_Write,
0,
nil,
Open_Existing,
0,
0);
//DeviceIoControl(hDevice, IOCTL_Storage_Eject_Media, nil, 0, nil, 0, dRet, nil); // Ejeta
DeviceIoControl(hDevice, IOCTL_Storage_Load_Media, nil, 0, nil, 0, dRet, nil); // Fecha
CloseHandle(hDevice);
end;

Nada acontece.

PS: Desculpem não estar colocando os cotes, mas neste computador que estou eles não estão funcionando!!
s3c
Paulo, retire Generic_Write, deixe somente Generic_Read; após CreateFile coloque:
CODE
  ShowMessage(SysErrorMessage(GetLastError));
Com a bandeja aberta, chame o programa e execute somente o botão para fechar, veja qual a mensagem e clique em Ok.
Paulo Nobre
s3c, a mensagem é a seguinte:
O arquivo já está sendo usado por outro processo.

s3c, só para resumir tudo.
Estou conseguindo abrir a gaveta do DVD por três códigos:

PRIMEIRO(Fornecido por você)
CODE

procedure TForm1.Button1Click(Sender: TObject);
//uses Variants, ComObj;
var
  SA:Variant;
begin
  SA := CreateOleObject('Shell.Application');
  //SA.NameSpace(17).ParseName('G:\').InvokeVerb('E&ject');
  SA.NameSpace(17).ParseName('G:\').InvokeVerb('E&jetar');
  SA := Unassigned;
end;


SEGUNDO(Fornecido por você)
CODE

procedure TForm1.Button3Click(Sender: TObject);
const IOCTL_Storage_Eject_Media = $002D4808; IOCTL_Storage_Load_Media = $002D480C;
var hDevice:THandle; dRet:DWord;
begin
  HDevice := CreateFile(PChar('\\.\g:'),
                        Generic_Read or Generic_Write,
                        0,
                        nil,
                        Open_Existing,
                        0,
                        0);
  DeviceIoControl(hDevice, IOCTL_Storage_Eject_Media, nil, 0, nil, 0, dRet, nil); // Ejeta
  //DeviceIoControl(hDevice, IOCTL_Storage_Load_Media,  nil, 0, nil, 0, dRet, nil); // Fecha
  CloseHandle(hDevice);
end;


TERCEIRO(Fornecido pelo Churc)
CODE

procedure TForm1.Button2Click(Sender: TObject);
begin
  AbreSafado('G', 'open');
end;

procedure AbreSafado(const Drive: Char; szAcao: String);
var
szBuff: String;
begin
szBuff := 'open ' + Drive + ':\ type cdaudio alias DRIVE';
mciSendString(PChar(szBuff), nil, 0, 0);
mciSendString(PChar('set DRIVE door ' + szAcao), nil, 0, 0);
mciSendString(PChar('close all'), nil, 0, 0);
end;


Problemas até agora para mim
1) Não consigo fechar com nenhum código.
2) Não consigo pegar a letra do DVD.

Fiz esse resumo para facilitar até pra mim mesmo quando ficar consultando os códigos e também
para facilitar aos que, como eu, tem menos experiência na procura.

Agora observe que coisa curiosa:
SE abrir pelo código 1 e mandar fechar depois pelo código que estamos analisando ele não fecha mais a mensagem agora é A operação foi concluida com êxito

Outra coisa se usar o código 1 para abrir, fechar manualmente é claro e depois tentar abrir pelo código 2
ele não abre. Tenho que fechar o programa abrir novamente e mandar abrir o dvd pelo código 2, aí sim ele abre.
s3c
Pode ser que ele não esteja liberando o Handle alocado; se não for isso, realmente não sei o que possa ser. Tente assim:
Abrir:
CODE
const IOCTL_Storage_Eject_Media = $002D4808;
var hDevice:THandle; dRet:DWord;
begin
  HDevice := CreateFile(PChar('\\.\G:'),
                        Generic_Read,
                        File_Share_Read,
                        nil,
                        Open_Existing,
                        0,
                        0);
  DeviceIoControl(hDevice, IOCTL_Storage_Eject_Media, nil, 0, nil, 0, dRet, nil);
  CloseHandle(hDevice);
end;

Fechar:
CODE
const IOCTL_Storage_Load_Media = $002D480C;
var hDevice:THandle; dRet:DWord;
begin
  HDevice := CreateFile(PChar('\\.\G:'),
                        Generic_Read,
                        File_Share_Read,
                        nil,
                        Open_Existing,
                        0,
                        0);
  DeviceIoControl(hDevice, IOCTL_Storage_Load_Media, nil, 0, nil, 0, dRet, nil);
  CloseHandle(hDevice);
end;
Paulo Nobre
Não funcionou.
Deixa prá lá!
Obrigado , s3c.
s3c
É, se ele abre mas não fecha, também pode ser algum outro código IOCTL para DVD.
Paulo Nobre
QUOTE

É, se ele abre mas não fecha, também pode ser algum outro código IOCTL para DVD.

É realmente, s3c, pode ser que seja outro código.
Quem deve ter preocupação com este tipo de código são desenvolvedores de programas de players.
Na realidade este tópico acabou virando uma fixação para muitos de nós, mas como o Churc, mencionou em um dos post, o principal seria saber abrir, pois como você vai tirar a mão do teclado ou mouse para colocar o DVD, então é só empurrar a gaveta. E mais um detalhe, em NOTEBOOK, este código nem teria sentido. O que achei muito interessante e que será aproveitado em códigos futuros é o uso do object Shell.Application.
Esta é uma versão simplificada de nosso conteúdo principal. Para ver a versão completa com maiores informações, formatação e imagens, por favor clique aqui.
Invision Power Board © 2001-2012 Invision Power Services, Inc.