2

I Hydra ホスト アプリケーションと Hydra プラグインを作成します。Windows メッセージを処理するための手順をプラグインに入れました。ただし、この場合、この Windows メッセージを処理できません。この問題を解決するには、ホスト アプリでそれを処理できます。次に、インターフェイスを渡すことでプラグインと対話する必要があります。この場合、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.

プラグイン側の 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.
4

1 に答える 1

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;
于 2012-10-10T10:39:15.703 に答える