⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uopcitemenumerator.pas

📁 delphi 开发OPc工业通讯 delphi 开发OPc工业通讯
💻 PAS
字号:
//******************************************************************************
// sOPC created by ACHAT SOLUTIONS GmbH, http://www.achat-solutions.de/
//******************************************************************************
unit uOPCItemEnumerator;

{$IFDEF VER150}
{$WARN UNSAFE_CAST OFF}
{$ENDIF}

interface

uses
  Windows, Classes, WinProcs, ComObj, ActiveX,
  OPCDA, OpcError;

type
  sOPCItemEnumerator = class(TComObject, IEnumOPCItemAttributes)
  private
    nextIndex: cardinal;
    FOPCItemList: TList;

  public
    constructor Create(OPCItemList: TList);
    function Next(
      celt: cardinal;
      out ppItemArray: POPCITEMATTRIBUTESARRAY;
      out pceltFetched: cardinal): HResult; stdcall;
    function Skip(celt: cardinal): HResult; stdcall;
    function Reset: HResult; stdcall;
    function Clone(out ppEnumItemAttributes: IEnumOPCItemAttributes): HResult; stdcall;
  end;

implementation

uses
  ComServ, uGlobals, uOPCItem;

constructor sOPCItemEnumerator.Create(OPCItemList: TList);
begin
  inherited Create;
  FOPCItemList := OPCItemList;
  nextIndex := 0;
end;

function sOPCItemEnumerator.Next(
  celt: cardinal;
  out ppItemArray: POPCITEMATTRIBUTESARRAY;
  out pceltFetched: cardinal): HResult; stdcall;
var
 i: cardinal;
begin
  i := 0;
  pceltFetched := i;

  if celt < 1 then begin
    Result := RPC_X_ENUM_VALUE_OUT_OF_RANGE;
    exit;
  end;

  Result := E_FAIL;
  ppItemArray := POPCITEMATTRIBUTESARRAY(CoTaskMemAlloc(celt * sizeof(OPCITEMATTRIBUTES)));
  if ppItemArray = nil then begin
    Result := E_OUTOFMEMORY;
    exit;
  end;

  // sind noch Eintr鋑e in der Liste?
  if (nextIndex >= cardinal(FOPCItemList.Count)) then begin
    Result := RPC_X_ENUM_VALUE_OUT_OF_RANGE;
    exit;
  end;

  // Eintr鋑e verarbeiten
  while (i < celt) and (nextIndex < cardinal(FOPCItemList.Count)) do begin
    sOPCItem(FOPCItemList[nextIndex]).GetOPCItemAttributes(ppItemArray[i]);
    inc(i);
    inc(nextIndex);
  end;
  pceltFetched := i;
  if i = celt then Result := S_OK;
end;

function sOPCItemEnumerator.Skip(celt: cardinal):HResult;
begin
  if (nextIndex + celt) <= cardinal(FOPCItemList.Count) then begin
    nextIndex := nextIndex + celt;
    Result := S_OK;
  end else begin
    nextIndex := FOPCItemList.Count;
    Result := S_FALSE;
  end;
end;

function sOPCItemEnumerator.Reset: HResult;
begin
  nextIndex := 0;
  Result := S_OK;
end;

function sOPCItemEnumerator.Clone(out ppEnumItemAttributes: IEnumOPCItemAttributes): HResult;
begin
  try
    ppEnumItemAttributes := sOPCItemEnumerator.Create(FOPCItemList);
    Result := S_OK;
  except
    Result := E_UNEXPECTED;
  end;
end;

initialization

TComObjectFactory.Create(
  ComServer,
  sOPCItemEnumerator,
  IID_IEnumOPCItemAttributes,
  'sOPCItemEnumerator',
  'sOPCItemEnumerator Description',
  ciInternal,
  ThreadingModel);

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -