Grigoriy |
Отправлено: 16.03.2006, 17:46 |
|
Мастер участка
Группа: Участник
Сообщений: 381
|
Вот узнал, что есть библиотека winmm.dll
и в ней есть функция позволяющая открыть и закрыть привод CD-DVD.
mciSendStringA
Я реализовал пример использования этой функции так
CODE |
//---------------------------------------------------------------------------
TForm1 *Form1;
char* strb ="Set cdaudio door open\0";
char* str1 ="Set cdaudio door closed\0";
HINSTANCE a;
void* h;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
a=LoadLibrary("winmm.dll");
h=GetProcAddress(a,"mciSendStringA");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
asm
{
push 0;
push 0;
push 0;
push strb;
call h;
};
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
asm
{
push 0;
push 0;
push 0;
push str1;
call h;
};
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
FreeLibrary(a);
}
|
Но на моем компьютере два привода и открывается и закрывается только один из них.
А как то же самое проделать со вторым ?
|
|
Gal |
Отправлено: 16.03.2006, 18:39 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 124
|
Для начала определим вспомогательные переменные и функции, которые облегчат передачу команд:
CODE |
#include <mmsystem.h>
#include <stdio.h>
#pragma comment(lib,"winmm.lib")
/* Команды */
char * CdCmdSet = "set";
char * CdCmdStatus = "status";
char * CdCmdPlay = "play";
char * CdCmdPause = "pause";
char * CdCmdStop = "stop";
char * CdCmdResume = "resume";
/* Флаги команд */
char * CdCmdFlagOpen = "door open";
char * CdCmdFlagClose = "door closed";
char * CdCmdCurTrack = "current track";
char * CdCmdCurMode = "mode";
char * CdCmdFlagEmpty = "";
/* Флаги выполнения */
char * CdFlagWait = "wait";
char * CdFlagEmpty = "";
/* Буфер, в котором будем создавать команды */
char CdCommandBuffer[256];
/* Создание команды без указания имени CD-ROM'а */
char * CreateCdCommand(char * pBuffer, char * pCommand, char * pCmdFlags, char * pFlags) {
sprintf(pBuffer,"%s cdaudio %s %s",pCommand,pCmdFlags,pFlags);
return pBuffer;
}
/* Создание команды с указанием имени CD-ROM'а */
char * CreateCdCommandEx(char * pBuffer, char DriveLetter, char * pCommand, char * pCmdFlags, char * pFlags) {
sprintf(pBuffer,"%s cdaudio!%c: %s %s",pCommand,DriveLetter,pCmdFlags,pFlags);
return pBuffer;
}
|
Теперь, используя вспомогательные функции и переменные, отдавать команды управления CD-ROM'ом не просто, а очень просто.
1.Открыть CD-ROM, ожидая выполнения этой команды:
CODE |
mciSendStringA(CreateCdCommand(CdCommandBuffer,CdCmdSet,CdCmdFlagOpen,CdFlagWait),
NULL,
0,
INVALID_HANDLE_VALUE);
|
2.
CODE |
mciSendStringA(CreateCdCommand(CdCommandBuffer,CdCmdSet,CdCmdFlagClose,CdFlagWait),
NULL,
0,
INVALID_HANDLE_VALUE);
|
Если в системе присутствует несколько приводов CD, то для задания конкретного привода вместо функции CreateCdCommand следует использовать CreateCdCommandEx.
Отредактировано Gal — 16/03/2006, 18:45 |
|
Павел |
Отправлено: 16.03.2006, 23:03 |
|
Не зарегистрирован
|
У меня есть пара исходников, но они на Delphi, если надо могу скинуть |
|
Grigoriy |
Отправлено: 16.03.2006, 23:38 |
|
Мастер участка
Группа: Участник
Сообщений: 381
|
QUOTE (Павел @ 16/03/2006, 23:03) | У меня есть пара исходников, но они на Delphi, если надо могу скинуть |
Я хотел разобраться на каком принципе формируются строки от
CreateCdCommand
Кстати, а что означают остальные три опреранда функции
mciSendStringA
?
|
|
Grigoriy |
Отправлено: 17.03.2006, 03:05 |
|
Мастер участка
Группа: Участник
Сообщений: 381
|
Что возвращает функция
mciSendStringA
?
Как использовать команду
status
?
|
|
Gal |
Отправлено: 17.03.2006, 12:18 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 124
|
function mciSendStringA(lpstrCommand, lpstrReturnString: PChar; uReturnLength: UINT; hWndCallback: HWND): MCIERROR;
Посылает командную строку для MCI-устройства.
lpstrReturnString — Строка возврата информации об исполнении команды
uReturnLength — Размер буфера исполняемой строки
hWndCallback — Хендл (Handle) окна для возврата сообщения о событии, если это оговорено в посылаемой команде.
Возвpащаемое значение: В случае успеха 0, или ошибку в противном случае. Младшее слово возвращаемой величины содержит код ошибки. Если ошибка вызвана устройством, то старшее слово возвращаемой величины, является идентификатором драйвера, в противном случае равно 0. Получить строку с ошибкой, можно с помощью функции mciGetErrorString.
См. также mciSendCommand
Функция находится в файле winmm.dll
Отредактировано Gal — 17/03/2006, 12:19 |
|
X-Phantom |
Отправлено: 24.03.2007, 08:43 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 3
|
CODE |
void __fastcall TForm1::Button1Click(TObject *Sender)
{
char res[256];
mciSendString("status cdaudio mode",res,256,Handle);
Label1->Caption=res;
}
|
Почему в независимости от того, открыт или закрыт привод, функция всегда возвращает open? |
|
Gedeon |
Отправлено: 24.03.2007, 12:35 |
|
Ветеран
Группа: Модератор
Сообщений: 1742
|
Вот моя прожка для открытия/закрытия любых приводов, определяет приводы, на форме для каждого рисует пару кнопок: откр./закр. ну и собственно работает.
CODE |
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
#define BUFSIZE 512
TCHAR szTemp[BUFSIZE];
static int i = 15;
if (GetLogicalDriveStrings(BUFSIZE-1, szTemp))
{
TCHAR szDrive[3] = TEXT(" :");
BOOL bFound = FALSE;
TCHAR* p = szTemp;
do
{
// Copy the drive letter to the template string
*szDrive = *p;
if(GetDriveType(szDrive)==DRIVE_CDROM)
{
TButton *btn = new TButton(this);
btn->Top = i;
btn->Width = 40;
btn->Caption = szDrive;
btn->Parent = this;
btn->OnClick = btn1Click;
btn = new TButton(this);
btn->Left = 41;
btn->Top = i;
btn->Width = 40;
btn->Caption = szDrive;
btn->Parent = this;
btn->OnClick = btn2Click;
i=i+25;
}
// Go to the next NULL character.
while (*p++);
} while (!bFound && *p); // end of string
}
this->Height = i+27;
this->Width = 87;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::btn1Click(TObject *Sender)
{
TButton *btn = dynamic_cast<TButton*> (Sender);
DriveLetter = "\\\\.\\" + btn->Caption;
hCDDevice = CreateFile(DriveLetter.c_str(),
GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
if(hCDDevice!=INVALID_HANDLE_VALUE)
{
DeviceIoControl(hCDDevice,/*IOCTL_DISK_EJECT_MEDIA*/0x074808,NULL,0,NULL,0,&lpBytesReturned,NULL);
CloseHandle(hCDDevice);
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::btn2Click(TObject *Sender)
{
TButton *btn = dynamic_cast<TButton*> (Sender);
DriveLetter = "\\\\.\\" + btn->Caption;
hCDDevice = CreateFile(DriveLetter.c_str(),
GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
if(hCDDevice!=INVALID_HANDLE_VALUE)
{
DeviceIoControl(hCDDevice,/*IOCTL_DISK_LOAD_MEDIA*/0x07480C,NULL,0,NULL,0,&lpBytesReturned,NULL);
CloseHandle(hCDDevice);
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
for(int i=0; i<this->ComponentCount; i++)
{
TButton *btn = dynamic_cast<TButton*> (this->Components[i]);
if(btn)
{
delete btn;
i=0; // так как кол-во компонентов изменилось, то цикл проходим заново
}
}
}
//---------------------------------------------------------------------------
|
Полностью готовый и рабочий код.
ЗЫ. Была написана т.к. комп на балконе — бегать харит.
|
|
aquanet sk |
Отправлено: 24.03.2007, 13:12 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 87
|
Могу кинуть и свой исходник (смиксован с примера Билдера и примера из инета), если подойдет принцип работы (см. exe`шник)
|
|
X-Phantom |
Отправлено: 24.03.2007, 18:55 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 3
|
А как узнать текущее состояние привода, открыт он или закрыт?
Кстати написал прожку на основе кода Gal'а. Кому интересно, вот она Drive Manager v.1.1 (343 KB)
Поддерживает максимум два привода (не уверен, что у кого-либо больше, не считая виртуалок)
Отредактировано X-Phantom — 25.03.2007, 22:23 |
|
|