Mar*_*unu 1 delphi delphi-2009 windows-messages
直到今天,我使用以下代码来捕获WM_DEVICECHANGE应用程序主窗体中的消息,并且它完美地工作.但是如果我尝试在我的自定义控件中使用它,我不会在设备插入或删除时收到通知.怎么了 ?
TDriveBar = class(TCustomPanel)
private
procedure WMDeviceChange(var Msg: TMessage); message WM_DEVICECHANGE;
end;
implementation
procedure TDriveBar.WMDeviceChange(var Msg: TMessage);
const DBT_DEVICEARRIVAL = $8000;
DBT_DEVICEREMOVECOMPLETE = $8004;
DBT_DEVTYP_VOLUME = 2;
type PDEV_BROADCAST_HDR = ^DEV_BROADCAST_HDR;
DEV_BROADCAST_HDR = record
dbch_size: dword;
dbch_devicetype: dword;
dbch_reserved: dword;
end;
begin
case Msg.WParam of
DBT_DEVICEREMOVECOMPLETE:
if PDEV_BROADCAST_HDR(Msg.LParam)^.dbch_devicetype = DBT_DEVTYP_VOLUME then UpdateDrives;
DBT_DEVICEARRIVAL:
if PDEV_BROADCAST_HDR(Msg.LParam)^.dbch_devicetype = DBT_DEVTYP_VOLUME then UpdateDrives;
end;
end;
Run Code Online (Sandbox Code Playgroud)
Rob*_*edy 10
操作系统向wm_DeviceChange所有顶级窗口发送消息.应用程序的主窗体是顶级窗口,但您的控件不是,这就是表单接收消息而控件不接收的原因.
对于任意设备类型,您有两种选择:
使用AllocateHWnd创建一个唯一的消息,顶级窗口,将通过调用你的控制相关的功能响应消息.这将为您提供与主表单接收的相同的基本信息.
为您的控件编写一个匹配签名的方法TWndMethod,这是AllocateHWnd需要的.它可能看起来像这样:
procedure TDriveBar.DeviceWindowProc(var Message: TMessage);
begin
case Message.Msg of
wm_DeviceChange: begin
case Message.WParam of
DBT_DEVICEREMOVECOMPLETE, DBT_DEVICEARRIVAL:
if PDEV_BROADCAST_HDR(Message.LParam).dbch_devicetype = DBT_DEVTYP_VOLUME then
UpdateDrives;
end;
end;
end;
Message.Result := DefWindowProc(FDeviceWnd, Message.Msg, Message.WParam, Message.LParam);
end;
Run Code Online (Sandbox Code Playgroud)
然后在创建消息窗口时使用该方法:
FDeviceWnd := AllocateHWnd(DeviceWindowProc);
Run Code Online (Sandbox Code Playgroud)打电话RegisterDeviceNotification告诉操作系统您的控件的窗口也想要接收通知.(确保处理控件CreateWnd和DestroyWnd方法,以便在重新创建控件时,使用控件的新窗口句柄续订通知注册.)这将为您提供比默认wm_DeviceChange消息提供的更详细的信息,但仅针对类型注册窗口句柄时指定的设备.
但是,您对卷的更改感兴趣.有关该问题的评论RegisterDeviceNotification(重点补充):
在
DBT_DEVICEARRIVAL和DBT_DEVICEREMOVECOMPLETE事件自动广播到端口设备的所有顶级窗口.因此,没有必要调用RegisterDeviceNotification端口,如果dbch_devicetype成员是,则函数失败DBT_DEVTYP_PORT.卷通知也会广播到顶级窗口,因此如果dbch_devicetype是,则函数会失败DBT_DEVTYP_VOLUME.
这消除了通知注册作为您的选项,因此您的唯一解决方案是使用AllocateHWnd.
| 归档时间: |
|
| 查看次数: |
1462 次 |
| 最近记录: |