2012-10-09 28 views
2

我創建了Hydra主機應用程序和Hydra插件。我在插件中放置了一個處理Windows消息的過程;但在這種情況下,我們無法處理這個Windows消息。爲了解決這個問題,我們可以在主機應用程序中處理它,然後我們必須通過傳遞接口來與插件進行交流。 在這種情況下,我想找到一個處理Hydra插件窗口消息的直接方式。請幫我解決這個問題。RemObjects Hydra插件無法直接處理WM_DEVICECHANGE 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. 
+0

請給一個簡單而具體的例子,最好用一些源代碼來展示你的問題。 –

+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; 
+1

好的,非常好的解決方案。感謝亞歷山大。 (^_^) –