Mar*_*unu 4 delphi message delphi-2009
创建控件后,我必须使用它DeviceWnd:=AllocateHWnd(DeviceWindowProc);来接收WM_DEVICECHANGE消息。进而...
procedure TFileList.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
OnDeviceChange;
end;
end;
end;
Message.Result:=DefWindowProc(DeviceWnd, Message.Msg, Message.WParam, Message.LParam);
end;
Run Code Online (Sandbox Code Playgroud)
这很好用,但是为什么当我这样做时我没有收到该消息?:
TFileList = class(TCustomControl)
private
procedure DeviceChage(var AMessage:TMessage); message WM_DEVICECHANGE;
end;
procedure TFileList.DeviceWindowProc(var Message: TMessage);
begin
Message.Result:=DefWindowProc(DeviceWnd, Message.Msg, Message.WParam, Message.LParam);
end;
procedure TFileList.DeviceChage(var AMessage:TMessage);
begin
case AMessage.WParam of
DBT_DEVICEREMOVECOMPLETE, DBT_DEVICEARRIVAL:
if PDEV_BROADCAST_HDR(AMessage.LParam).dbch_devicetype = DBT_DEVTYP_VOLUME then
OnDeviceChange;
end;
end;
Run Code Online (Sandbox Code Playgroud)
来自以下文档RegisterDeviceNotification:
应用程序使用 BroadcastSystemMessage 函数发送事件通知。任何具有顶级窗口的应用程序都可以通过处理 WM_DEVICECHANGE 消息来接收基本通知。应用程序可以使用 RegisterDeviceNotification 函数来注册接收设备通知。
您创建的窗口AllocateHWnd是顶级窗口。因此它接收广播消息。
您的自定义控件不是顶级窗口。如果您希望它接收消息,您必须调用RegisterDeviceNotification传递其窗口句柄。如果您这样做,请务必通过在 中注册CreateWnd和取消注册来处理 VCL 窗口重新创建DestroyWnd。
作为一般经验法则,AllocateHwnd这是侦听通知的首选方式。这是因为它不受 VCL 窗口重新创建的影响,因此不会错过通知。当重新创建 VCL 窗口时,有一个发送通知的机会窗口,但您的应用程序没有准备好接收的窗口。
这肯定会成为您的情况的一个问题,因此您应该使用AllocateHwnd. 您可以安排您创建的窗口归AllocateHwnd您的自定义控件所有,然后您可以将通知路由到该控件的代码。