为什么捕捉不到WM_DEVICECHANGE消息啊 ( 积分: 50 )

  • 主题发起人 主题发起人 rabbitlzx
  • 开始时间 开始时间
R

rabbitlzx

Unregistered / Unconfirmed
GUEST, unregistred user!
我想在程序中捕获光盘插入事件,代码如下:
private
procedure GetCDMsg(var msg: TMessage);
message WM_DEVICECHANGE;
implementation
procedure TForm1.GetCDMsg(var msg: TMessage);
begin
ShowMessage('');
end;

我在光驱中放了光盘,结果发现不管怎样打开、关闭光驱,就是不触发这个事件,为什么啊?郁闷啊
-----------------------------------------------------------------------
我也试了下面的方法,也不好用
主要是定义新的窗口过程,在这里面截获 WM_DEVICECHANGE 消息来判断(该消息跟设备有关),以下是大富翁里的例子:
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;

我的光驱取消自动运行了,会是因为这个么
 
我想在程序中捕获光盘插入事件,代码如下:
private
procedure GetCDMsg(var msg: TMessage);
message WM_DEVICECHANGE;
implementation
procedure TForm1.GetCDMsg(var msg: TMessage);
begin
ShowMessage('');
end;

我在光驱中放了光盘,结果发现不管怎样打开、关闭光驱,就是不触发这个事件,为什么啊?郁闷啊
-----------------------------------------------------------------------
我也试了下面的方法,也不好用
主要是定义新的窗口过程,在这里面截获 WM_DEVICECHANGE 消息来判断(该消息跟设备有关),以下是大富翁里的例子:
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;

我的光驱取消自动运行了,会是因为这个么
 
要RegisterMessage哈!这个消息必须你像系统登记要获得系统才发给你,系统不会傻不啦几的到处广播消息哈!
 
zqw0117 说的对,需要先Register,程序结束后再UnRegister,具体函数记不清了,查查资料!
 
我到别人电脑上试了一下,我写的方法是正确的,可是我电脑取消光驱自动运行功能了
所以才会接收不到,应该不是RegisterMessage的问题
 
后退
顶部