RemObjects Hydra Plugin Can't Handle WM_DEVICECHANGE Windows Messages Directly

688 views Asked by At

I Creating a Hydra Host Application and a Hydra Plugin. I put a Procedure for Handling a Windows Message in Plugin; but in this case we can't handle this windows message. for solving this problem we can handle It in Host App and then we must talk with pluging via passing an Interface. In this case I want to find a direct way for handle windows messages in Hydra Plugin. Please help me for solving this problem.

Update 1 for this Question: this is a simple code for testing:

Plugin Side:

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 in Plugin Side:

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.

Host Application Side:

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

There are 1 answers

0
Alexander Krakovskii On BEST ANSWER

Not sure about the real cause of the problem, but you can use RegisterDeviceNotification function to achieve same result:

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;

Now inside plugin you need something like this:

  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;