RemObjects Hydra插件无法直接处理WM_DEVICECHANGE Windows消息

时间:2012-10-09 14:55:55

标签: delphi plugins interface message hydra

我创建了Hydra主机应用程序和Hydra插件。我在插件中提出了处理Windows消息的过程;但在这种情况下,我们无法处理此Windows消息。为了解决这个问题,我们可以在Host App中处理它,然后我们必须通过传递接口来讨论插件。 在这种情况下,我想找到一个直接的方法来处理Hydra插件中的Windows消息。请帮我解决这个问题。

此问题的更新1: 这是一个简单的测试代码:

插件端:

unit VisualPlugin;

interface

uses
  { vcl: } Windows, Messages, SysUtils, Variants, Classes, Graphics,
  Controls, Forms, Dialogs, StdCtrls,
  { Hydra: } uHYVisualPlugin, uHYIntf;

type
  TVisualPlugin1 = class(THYVisualPlugin)
  private

    procedure WMDEVICECHANGE(var Msg: TMessage); message WM_DEVICECHANGE;

  end;

implementation

uses
  { Hydra: } uHYPluginFactories;
{$R *.dfm}

procedure Create_VisualPlugin1(out anInstance: IInterface);
begin
  anInstance := TVisualPlugin1.Create(NIL);
end;

resourcestring
  sDescription = '';

const
  sRequiredPrivilege = '';
  sUserData = '';

  { TVisualPlugin1 }

procedure TVisualPlugin1.WMDEVICECHANGE(var Msg: TMessage);
begin
  // ===================================
  // This Line Of Code Can't Be Run!!!!!!
  ShowMessage('USB Changed');

  // ===================================
end;

initialization

THYPluginFactory.Create(HInstance, 'VisualPlugin1', Create_VisualPlugin1,
  TVisualPlugin1, 1, 0, sRequiredPrivilege, sDescription, sUserData);

end.

Plugin Side中的PluginController:

unit hcPluginController;

interface

uses
  {vcl:} SysUtils, Classes, 
  {Hydra:} uHYModuleController, uHYIntf, uHYCrossPlatformInterfaces;

type
  TPluginController = class(THYModuleController)
  private
  public
  end;

var
  PluginController : TPluginController;

implementation

uses
  {Hydra:} uHYRes;

{$R *.dfm}

procedure HYGetCrossPlatformModule(out result: IHYCrossPlatformModule); stdcall;
begin
  result := PluginController as IHYCrossPlatformModule;
end;

function HYGetModuleController : THYModuleController;
begin
  result := PluginController;
end;

exports
  HYGetCrossPlatformModule,
  HYGetModuleController name name_HYGetModuleController;

resourcestring
  sDescription = '';

const
  sRequiredPrivilege = '';

initialization
  PluginController := TPluginController.Create('Plugin.Library', 1, 0, sRequiredPrivilege, sDescription);

finalization
  FreeAndNil(PluginController);

end.

主机应用程序端:

unit fMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, uHYModuleManager, uHYIntf, ExtCtrls, StdCtrls;

type
  TMainForm = class(TForm)
    HYModuleManager1: THYModuleManager;
    Panel1: TPanel;
    btnLoadPlugin: TButton;
    procedure btnLoadPluginClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  MainForm: TMainForm;

implementation

{$R *.dfm}

var
  AppDir: string;
  fPlugin: IHYVisualPlugin;

const
  PluginDll = 'Plugin.dll';
  PluginName = 'VisualPlugin1';

procedure TMainForm.btnLoadPluginClick(Sender: TObject);
begin
  if HYModuleManager1.FindModule(AppDir + PluginDll) = nil then
    HYModuleManager1.LoadModule(AppDir + PluginDll);

  HYModuleManager1.CreateVisualPlugin(PluginName, fPlugin, Panel1);
end;

procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  HYModuleManager1.ReleaseInstance(fPlugin);
  HYModuleManager1.UnloadModules;
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
  AppDir := ExtractFilePath(Application.ExeName);
end;

end.

1 个答案:

答案 0 :(得分:5)

不确定问题的真正原因,但您可以使用RegisterDeviceNotification函数来实现相同的结果:

type
  DEV_BROADCAST_DEVINTERFACE = record
    dbcc_size: DWORD;
    dbcc_devicetype: DWORD;
    dbcc_reserved: DWORD;
    dbcc_classguid: TGUID;
    dbcc_name: short;
  end;

const
  DEVICE_NOTIFY_ALL_INTERFACE_CLASSES = $4;
  DBT_DEVTYP_DEVICEINTERFACE = $5;

function RegisterNotification(Handle: THandle): HDEVNOTIFY;
var
  Filter: DEV_BROADCAST_DEVINTERFACE;
begin
  ZeroMemory(@Filter, SizeOf(DEV_BROADCAST_DEVINTERFACE));
  Filter.dbcc_size := SizeOf(DEV_BROADCAST_DEVINTERFACE);
  Filter.dbcc_devicetype :=  DBT_DEVTYP_DEVICEINTERFACE;
  Filter.dbcc_reserved := 0;
  Filter.dbcc_name := 0;

  Result := RegisterDeviceNotification(Handle, @Filter, DEVICE_NOTIFY_WINDOW_HANDLE or DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
end;

现在在插件内你需要这样的东西:

  TVisualPlugin = class(THYVisualPlugin)
  protected
    NofitifyHandle: HDEVNOTIFY;
    procedure WMDEVICECHANGE(var Msg: TMessage); message WM_DEVICECHANGE;
    procedure CreateWnd; override;
    procedure DestroyWindowHandle; override;
  end;

procedure TVisualPlugin.CreateWnd;
begin
  inherited;
  if HandleAllocated then
    NofitifyHandle := RegisterNotification(Self.Handle);
end;

procedure TVisualPlugin.DestroyWindowHandle;
begin
  if Assigned(NofitifyHandle) then begin
    UnregisterDeviceNotification(NofitifyHandle);
    NofitifyHandle := nil;
  end;
  inherited;
end;

procedure TVisualPlugin.WMDEVICECHANGE(var Msg: TMessage);
begin
  ShowMessage('USB Changed');
end;