CD-ROM状态的检测(不用MediaPlayer控件)(100分)

  • 主题发起人 主题发起人 胡小翔
  • 开始时间 开始时间

胡小翔

Unregistered / Unconfirmed
GUEST, unregistred user!
我不想用任何Form,只是在DPR文件的begin
和AND中
写一些代码:先判断CD-ROM状态(是关还是开),
然后执行操作(是关就打开,是开就关上)。
现在的问题是如何不截获Drive Change Message就
能判断CD-ROM的状态。
请高手不吝赐教!
 
mciSendCommand或者mciSendString
 
到<a href="http://ftp.maoming.gd.cn/c/leonyxl/software/cdevents.zip">这里</a>看看,应该可以从源程序中学到点东西
 
瞧我如何判断光区状态(来自Delphi forever)
TForm1 = class(TForm)
label1:Tlabel;
.......
procedure WMDeviceChange(var Msg : TWMDeviceChange);
procedure HasCdRom;
procedure HasNotCdRom;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);

private
FWindowHandle: HWND;
procedure myWndProc(var Msg: TMessage);
{ Private declarations }
public
{ Public declarations }
end;


procedure TForm1.myWndProc(var Msg: TMessage);
begin

if (Msg.Msg = WM_DEVICECHANGE) then
//如果是设备改变消息的话
try
WMDeviceChange(TWMDeviceChange(Msg));

except
Application.HandleException(Self);
end
else

Msg.Result := DefWindowProc(FWindowHandle, Msg.Msg, Msg.wParam, Msg.lParam);
//如果不是设备改变消息,则交给FORM缺省的消息处理系统完成
end;

procedure TForm1.WMDeviceChange(var Msg : TWMDeviceChange);
var
lpdb : PDEV_BROADCAST_HDR;
//
lpdbv : PDEV_BROADCAST_VOLUME;
begin

(* 接受 a wm_devicechange message *)
lpdb := PDEV_BROADCAST_HDR(Msg.dwData);
(* 查看 wm_devicechange 消息中EVENT 是何事件 *)
case Msg.Event of
DBT_DEVICEARRIVAL : begin

if lpdb^.dbch_devicetype = DBT_DEVTYP_VOLUME then

begin

lpdbv := PDEV_BROADCAST_VOLUME(Msg.dwData);
if (lpdbv^.dbcv_flags and DBTF_MEDIA) = 1 then

begin

//CheckCdRomVolume;我的程序里要检查光盘卷标
//HasCdRom;
CDRom被加载
showmessage('有光盘加入进来');
end;

end;

end;

DBT_DEVICEREMOVECOMPLETE : begin

if lpdb^.dbch_devicetype = DBT_DEVTYP_VOLUME then
begin

lpdbv := PDEV_BROADCAST_VOLUME(Msg.dwData);
if (lpdbv^.dbcv_flags and DBTF_MEDIA) = 1 then

//HasNotCdRom;
CD Rom被取出
showmessage('CD被取出');
end;

end;

end;

end;



procedure TForm1.FormCreate(Sender: TObject);
begin

FWindowHandle:=AllocateHWnd(mywndproc);
//截取WINDOWS交给每个窗口的消息,交给MYWNDPROC处理,用来判断CD驱动器改变
//在WIN95里,每个设备的改变,系统都要发一个消息给所有当前窗口
//所以这里要用自定义的消息循环代替DELPHI 程序默认的窗口消息循环
end;


procedure TForm1.FormDestroy(Sender: TObject);
begin

DeallocateHWnd(FWindowHandle);
//释放句柄
end;

献佛!可分别忘!
 
使用mciSendString函数。(uses MMSystem)
MCIERROR mciSendString(
LPCTSTR lpszCommand,
LPTSTR lpszReturnString,
UINT cchReturn,
HANDLE hwndCallback
)
如mciSendString('Open the CD_Rom', ReturnString, 127, 0);

If successful, return zero.

我没有实验,不知道可行不可行?
 
利用mciSendCommand就可以判断出光驱是开还是关的.还有mcisendstring也可以用的啊!!写起来很简单的.
 
在windows9x下,对光驱的判断有一个bug
就是无论用mciSendMessage还是DOS下的汇编,查出的光驱状态只有2种
其一是光驱中有光碟,并光驱门是关着的;剩下的就是另一种状态
所以无法判断出光驱门是开着的,还是没光碟并且光驱门是关着的.
但Tale小组的CDEject程序能准确的判断出状态,
并且能做出相应的动作(关/开 -> 开/关)
不知是怎么做到的.


 
用windows 的shellAPI可以实现基本功能。
我这里边席了一个例子,你需要的话发新到我的
信箱里xiaoxiaoniao@263.net
 
我也想知道,关注一下
 
这么长时间没人回答,再刺激一下,回答出来我也给100分
 
下面的SAMPLE可能对你有所帮助。
procedure TForm1.Button1Click(Sender: TObject);
var
systeminfo: SYSTEM_INFO;
sector,byte,cluster,free: DWORD;
CDtype: UINT;
name: CHAR;
drvname: string;
volname,filesysname: PCHAR;
sno,maxl,fileflag: DWORD;
begin

Memo1.Lines.Clear();

//检测CD-ROM,是否有光盘
GetMem(volname, 255);
GetMem(filesysname, 100);
for name :='C' to 'Z' do
//循环检测A~Z
begin

drvname := name + ':';
CDtype := GetDriveType(PCHAR(@drvname[1]));
//获得磁盘类型
if (CDtype = DRIVE_CDROM) then

begin

Memo1.Lines.Add('您的光驱盘符为[' + drvname + ']');
volname^ := Chr(0);
filesysname^ := Chr(0);
if ( not (GetVolumeInformation(PCHAR(@drvname[1]), volname, 250, LPDWORD(@sno), LPDWORD(@maxl)^, LPDWORD(@fileflag)^, filesysname,100))) then

Memo1.Lines.Add(drvname + '驱中没有发现光盘') //如果返回值为假
else
//如果返回值为真
begin

Memo1.Lines.Add (drvname + '驱中光盘卷标为: [' + String(volname) + ']');
Memo1.Lines.Add (drvname + '驱中光盘序号为: [' + inttostr(sno) + ']');
end;

end;

end;

FreeMem(volname);
FreeMem(filesysname)
end;
 
to wangjerry
不行,题意要求光驱是弹出的,就关闭,是关闭的就弹出
 
多人接受答案了。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
1K
import
I
后退
顶部