2

在我的 Delphi 应用程序中,我想使用 Microsoft Windows 网络列表管理器 API (NLM) 了解网络更改:http: //msdn.microsoft.com/library/ee264321

我查看了链接的“如何注册 NLM 事件”示例并将其翻译为 Delphi。但是,我不知道如何继续。

var
    pNLM: INetworkListManager;
    pCpc: IConnectionPointContainer;
    pConnectionPoint: IConnectionPoint;
    pSink: IUnknown;
    dwCookie: LongInt;
const
    IID_IConnectionPointContainer: TGUID = '{B196B284-BAB4-101A-B69C-00AA00341D07}';
    IID_IUnknown: TGUID = '{00000000-0000-0000-C000-000000000046}';
begin
    if Succeeded(CoCreateInstance(CLASS_NetworkListManager, nil, CLSCTX_ALL, IID_INetworkListManager, pNLM)) then
    begin
        if Succeeded(pNLM.QueryInterface(IID_IConnectionPointContainer, pCpc)) then
        begin
            if Succeeded(pCpc.FindConnectionPoint(IID_INetworkEvents, pConnectionPoint)) then
            begin
                if Succeeded(pCpc.QueryInterface(IID_IUnknown, pSink)) then
                begin
                    pConnectionPoint.Advise(pSink, dwCookie);
                end;
            end;
        end;
    end;
end;

文章说:

“在您创建了上面的 INetworkListManager 对象后,您将从该点开始收到 INetworkEvents 通知。pSink 实现了 INetworkEvent 接口,包括那些事件处理方法,例如 NetworkAdded、NetworkDeleted、NetworkConnectivityChanged 和 NetworkPropertyChanged。”

不幸的是,我不知道该怎么做。没有进一步的说明,所以我希望这里有人可以指导我/提供一个示例来调用这些事件的自定义过程。谢谢。

4

1 回答 1

7

您将错误的对象传递给Advise(). 您正在传递IConnectionPointContainer对象。您需要编写自己的实现INetworkEvents接口的类,然后创建该类的实例并将该对象传递给Advise(). 这就是 NLM(或任何其他使用连接点的 COM 对象)能够将事件发送到您的代码的方式。

更新:您需要更改NLMEvents单位以在退出后保持 NLM 对象处于活动状态StartNLMEventListener(),然后事件将正常工作。按照您的编码方式,NLM 对象是本地的StartNLMEventListener(),因此在退出时会被释放StartNLMEventListener(),这会取消注册您的事件接收器。

试试这个:

unit NLMEvents;

interface

function StartNLMEventListener: HResult;
function StopNLMEventListener: HResult;

implementation

uses
  Windows, ActiveX, NETWORKLIST_TLB, SysUtils, Unit1;

type
  TMyNetworkEvents = class(TInterfacedObject, INetworkEvents, INetworkConnectionEvents, INetworkListManagerEvents)
  public
    function NetworkAdded(networkId: TGUID): HResult; stdcall;
    function NetworkConnectivityChanged(networkId: TGUID; NewConnectivity: NLM_CONNECTIVITY): HResult; stdcall;
    function NetworkDeleted(networkId: TGUID): HResult; stdcall;
    function NetworkPropertyChanged(networkId: TGUID; fFlags: NLM_NETWORK_PROPERTY_CHANGE): HResult; stdcall;
    function ConnectivityChanged(NewConnectivity: NLM_CONNECTIVITY): HResult; stdcall;
    function NetworkConnectionConnectivityChanged(networkId: TGUID; NewConnectivity: NLM_CONNECTIVITY): HResult; stdcall;
    function NetworkConnectionPropertyChanged(networkId: TGUID; fFlags: NLM_NETWORK_PROPERTY_CHANGE): HResult; stdcall;
  end;

var
  pNLM: INetworkListManager = nil;
  dwCookie1: LongInt = -1;
  dwCookie2: LongInt = -1;
  dwCookie3: LongInt = -1;

const
  IID_IConnectionPointContainer: TGUID = '{B196B284-BAB4-101A-B69C-00AA00341D07}';
  //IID_IUnknown: TGUID = '{00000000-0000-0000-C000-000000000046}';
  //CLSID_NetworkListManager: TGUID = '{DCB00C01-570F-4A9B-8D69-199FDBA5723B}';

function TMyNetworkEvents.ConnectivityChanged(NewConnectivity: NLM_CONNECTIVITY): HResult; stdcall;
begin
  Form2.Memo1.Lines.Add('ConnectivityChanged');
  Result := S_OK;
end;

function TMyNetworkEvents.NetworkConnectionConnectivityChanged(networkId: TGUID; NewConnectivity: NLM_CONNECTIVITY): HResult; stdcall;
begin
  Form2.Memo1.Lines.Add('NetworkConnectionConnectivityChanged');
  Result := S_OK;
end;

function TMyNetworkEvents.NetworkConnectionPropertyChanged(networkId: TGUID; fFlags: NLM_NETWORK_PROPERTY_CHANGE): HResult; stdcall;
begin
  Form2.Memo1.Lines.Add('NetworkConnectionPropertyChange');
  Result := S_OK;
end;

function TMyNetworkEvents.NetworkAdded(networkId: TGUID): HResult; stdcall;
begin
  Form2.Memo1.Lines.Add('NetworkAdded');
  Result := S_OK;
end;

function TMyNetworkEvents.NetworkConnectivityChanged(networkId: TGUID; NewConnectivity: NLM_CONNECTIVITY): HResult; stdcall;
begin
  Form2.Memo1.Lines.Add('NetworkConnectivityChanged');
  Result := S_OK;
end;

function TMyNetworkEvents.NetworkDeleted(networkId: TGUID): HResult; stdcall;
begin
  Form2.Memo1.Lines.Add('NetworkDeleted');
  Result := S_OK;
end;

function TMyNetworkEvents.NetworkPropertyChanged(networkId: TGUID; fFlags: NLM_NETWORK_PROPERTY_CHANGE): HResult; stdcall;
begin
  Form2.Memo1.Lines.Add('NetworkPropertyChanged');
  Result := S_OK;
end;

function StartNLMEventListener: HResult;
var
  pCpc: IConnectionPointContainer;
  pConnectionPoint: IConnectionPoint;
  pSink: INetworkEvents;
begin
  if pNLM = nil then
  begin
    Result := CoCreateInstance(CLASS_NetworkListManager, nil, CLSCTX_ALL, IID_INetworkListManager, pNLM);
    if Failed(Result) then
      Exit;
  end else
  begin
    Result := S_OK;
  end;

  if Succeeded(pNLM.QueryInterface(IID_IConnectionPointContainer, pCpc)) then
  begin
    pSink := TMyNetworkEvents.Create as INetworkEvents;

    if dwCookie1 = -1 then
    begin
      if Succeeded(pCpc.FindConnectionPoint(IID_INetworkEvents, pConnectionPoint)) then
      begin
        pConnectionPoint.Advise(pSink, dwCookie1);
        pConnectionPoint := nil;
      end;
    end;

    if dwCookie2 = -1 then
    begin
      if Succeeded(pCpc.FindConnectionPoint(IID_INetworkConnectionEvents, pConnectionPoint)) then
      begin
        pConnectionPoint.Advise(pSink, dwCookie2);
        pConnectionPoint := nil;
      end;
    end;

    if dwCookie3 = -1 then
    begin
      if Succeeded(pCpc.FindConnectionPoint(IID_INetworkListManagerEvents, pConnectionPoint)) then
      begin
        pConnectionPoint.Advise(pSink, dwCookie3);
        pConnectionPoint := nil;
      end;
    end;
  end;
end;

function StopNLMEventListener: HResult;
var
  pCpc: IConnectionPointContainer;
  pConnectionPoint: IConnectionPoint;
begin
  if pNLM <> nil then
  begin
    if Succeeded(pNLM.QueryInterface(IID_IConnectionPointContainer, pCpc)) then
    begin
      if dwCookie1 <> -1 then
      begin
        if Succeeded(pCpc.FindConnectionPoint(IID_INetworkEvents, pConnectionPoint)) then
        begin
          pConnectionPoint.Unadvise(dwCookie1);
          pConnectionPoint := nil;
        end;
      end;

      if dwCookie2 <> -1 then
      begin
        if Succeeded(pCpc.FindConnectionPoint(IID_INetworkConnectionEvents, pConnectionPoint)) then
        begin
          pConnectionPoint.Unadvise(dwCookie2);
          pConnectionPoint := nil;
        end;
      end;

      if dwCookie3 <> -1 then
      begin
        if Succeeded(pCpc.FindConnectionPoint(IID_INetworkListManagerEvents, pConnectionPoint)) then
        begin
          pConnectionPoint.Unadvise(dwCookie3);
          pConnectionPoint := nil;
        end;
      end;
    end;

    pNLM := nil;
  end;

  dwCookie1 := -1;
  dwCookie2 := -1;
  dwCookie3 := -1;

  Result := S_OK;
end;

end.
于 2014-07-03T15:41:04.217 回答