亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? uopc.pas

?? delphi 開發(fā)OPc工業(yè)通訊 delphi 開發(fā)OPc工業(yè)通訊
?? PAS
字號:
//******************************************************************************
// sOPC created by ACHAT SOLUTIONS GmbH, http://www.achat-solutions.de/
//******************************************************************************
unit uOPC;

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

interface

uses
  SysUtils, Classes, Windows, ActiveX,
  OPCDA,
  uOPCNode;

type
  sOnRead = procedure (OPCNode: sOPCNode; Path: string; DataType: TVarType);
  // tag read event
  // OPCNode  = tag class
  // Path     = access path
  // DataType = requested data type from client

  sOnWrite = procedure (OPCNode: sOPCNode; Value: variant; Path: string; DataType: TVarType);
  // tag write event
  // OPCNode  = tag class
  // Value    = value to write
  // Path     = access path
  // DataType = requested data type from client

  sOnSetDataType = function(OPCNode: sOPCNode; DataType: TVarType): boolean;
  // not used

  sOnInitAddressSpace = procedure;
  // init address space event

  { sOnRead and sOnWrite must set the fields CurrentValue, Quality and LastUpdate
    of the OPCNode object.
    If LastUpdate is set, the server automatically updates the client if callback
    is enabled.
    Path is the desired AccessPath and DataType is the requested data type.
    If DataType = VT_EMPTY then the native (canonical) data type must be used.
  }

  sNodeArray = array of sOPCNode;

  sOPC = class
  protected
    FDataAccessServers: TList;
    FServerName: string;
    FServerDescription: string;
    FAddressSpaceInit: boolean;
    FNodes: sNodeArray;
    FCanStart: boolean;

    FOnRead: sOnRead;
    FOnWrite: sOnWrite;
    FOnSetDataType: sOnSetDataType;
    FOnInitAddressSpace: sOnInitAddressSpace;

    procedure CreateQualifiedName;
    procedure CheckRegister;
    // check register or unregister

  public
    //**************************************************************************
    // this public functions and propertys are used internal
    //**************************************************************************
    function GetOPCNode(stItemID: string; Ident: integer = -1): sOPCNode;

    procedure ItemWrite(OPCNode: sOPCNode; Value: variant; Path: string; DataType: TVarType);

    procedure ItemRead(OPCNode: sOPCNode; Path: string; DataType: TVarType);

    procedure InitAddressSpace;

    function GetIndexOfNode(Ident: integer): integer;

    function GetIndexOfstItemID(stItemID: string): integer;

    procedure AddDataAccessServer(Server: TObject);
    // add new Data Access Server

    procedure RemoveDataAccessServer(Server: TObject);
    // removes Data Access Server

    property CanStart: boolean read FCanStart;
    // OPC can be started

    property Nodes: sNodeArray read FNodes;
    // all defined nodes

  public
    //**************************************************************************
    // this public functions and propertys are used external
    //**************************************************************************
    constructor Create;

    destructor Destroy; override;

    procedure Init(
      ServerName: string;
      ServerDescription: string;
      SetExePath: boolean = True;
      LogFlag: boolean = False);
    // init OPC
    // ServerName is the name of the OPC server e.g. MyVendor.Servername.1
    // ServerDescription is the OPC server description
    // if SetExePath = True then the actual path is set to the path where the
    // exe file is loaded.
    // if LogFlag = True then OPCLog is activated (for debug sessions only)

    procedure Start;
    // OPC can be started

    procedure ShutDown;
    // shuts down the OPC Server

    procedure AddBranch(Parent, Ident: integer; stItemID: string);
    // add a branch to name space

    procedure AddLeaf(Parent, Ident: integer; stItemID: string;
      vtDataType: TVarType; dwAccessRights: DWORD);
    // add a leaf (tag) to name space

    procedure AddProperty(Parent: integer; dwPropertyID: DWORD; stItemID,
      stDescription: string; vtDataType: TVarType; vPropertyData: variant);
    // add a property to name the space

    function GetServerCount: integer;
    // returns number of connected DataAccess servers

    function GetGroupCount: integer;
    // returns number of connected groups (private and public)

    property ServerName: string read FServerName;
    // OPC server name

    property ServerDescription: string read FServerDescription;
    // OPC server description

    property OnRead: sOnRead read FOnRead write FOnRead;
    // client reads data

    property OnWrite: sOnWrite read FOnWrite write FOnWrite;
    // client writes data

    property OnSetDataType: sOnSetDataType read FOnSetDataType write FOnSetDataType;
    // client wants to change data type, True -> Ok DataType is changed

    property OnInitAddressSpace: sOnInitAddressSpace read FOnInitAddressSpace write FOnInitAddressSpace;
    // create name space

  end;

var
  OPC: sOPC;

implementation

uses
  ComServ, Forms,
  uLogging,
  uGlobals, uRegister, uOPCDataAccess;

procedure sOPC.CreateQualifiedName;
var
  i, j, Parent: integer;
begin
  for i := 0 to High(FNodes) do begin
    FNodes[i].stItemID := FNodes[i].stItemDataID;
    Parent := FNodes[i].Parent;
    while True do begin
      j := GetIndexOfNode(Parent);
      if j = -1 then break;
      FNodes[i].stItemID := FNodes[j].stItemDataID + '.' + FNodes[i].stItemID;
      Parent := FNodes[j].Parent;
    end;
  end;
end;

constructor sOPC.Create;
begin
  FDataAccessServers := TList.Create;
  FAddressSpaceInit := False;
  FCanStart := False;
  FOnRead := nil;
  FOnWrite := nil;
  FOnSetDataType := nil;
  FOnInitAddressSpace := nil;
end;

destructor sOPC.Destroy;
var
  i: integer;
begin
  for i := 0 to High(FNodes) do FNodes[i].Free;
  if Assigned(Logging) then Logging.Free;
  FDataAccessServers.Free;
  inherited;
end;

procedure sOPC.CheckRegister;
begin
  case ComServer.StartMode of
    smRegServer: RegisterOPCServer;
    smUnregServer: UnRegisterOPCServer;
  end;
end;

procedure sOPC.Init(
  ServerName: string;
  ServerDescription: string;
  SetExePath: boolean = True;
  LogFlag: boolean = False);
begin
  FServerName := ServerName;
  FServerDescription := ServerDescription;
  if SetExePath then SetCurrentDir(ExtractFileDir(Application.ExeName));
  if LogFlag and (not Assigned(Logging)) then begin
    Logging := TLogging.Create('OPCLog.txt');
    Logging.WriteWithTimeStamp(True);
    OPCLog('Start Log');
  end;
end;

procedure sOPC.Start;
begin
  FCanStart := True;
end;

procedure sOPC.ShutDown;
var
  i: integer;
  l: Tlist;
begin
  // FDataAccessServers list is copied, because ShutDown Destroys the
  // DataAccessServer!
  l := TList.Create;
  for i := 0 to FDataAccessServers.Count - 1 do l.Add(FDataAccessServers.Items[i]);
  for i := 0 to l.Count - 1 do sOPCDataAccess(l.Items[i]).ShutDown;
  l.Free;
end;

procedure sOPC.AddBranch(Parent, Ident: integer; stItemID: string);
var
  OPCNode: sOPCNode;
begin
  OPCNode := sOPCNode.Create;
  OPCNode.NodeType := 0;
  OPCNode.Ident := Ident;
  OPCNode.Parent := Parent;
  OPCNode.stItemDataID := stItemID;
  SetLength(FNodes, High(FNodes) + 2);
  FNodes[High(FNodes)] := OPCNode;
end;

procedure sOPC.AddLeaf(Parent, Ident: integer; stItemID: string;
  vtDataType: TVarType; dwAccessRights: DWORD);
// slAddressPathList: TStringList; als Parameter kommt sp鋞er +++
var
  OPCNode: sOPCNode;
begin
  OPCNode := sOPCNode.Create;
  OPCNode.NodeType := 1;
  OPCNode.Ident := Ident;
  OPCNode.Parent := Parent;
  OPCNode.stItemDataID := stItemID;
  OPCNode.vtCanonicalDataType := vtDataType;
  OPCNode.dwAccessRights := dwAccessRights;
  SetLength(FNodes, High(FNodes) + 2);
  FNodes[High(FNodes)] := OPCNode;
end;

procedure sOPC.AddProperty(Parent: integer; dwPropertyID: DWORD; stItemID,
  stDescription: string; vtDataType: TVarType; vPropertyData: variant);
var
  OPCNode: sOPCNode;
begin
  OPCNode := sOPCNode.Create;
  OPCNode.NodeType := 2;
  OPCNode.Ident := -1;
  OPCNode.Parent := Parent;
  OPCNode.dwPropertyID := dwPropertyID;
  OPCNode.stItemDataID := stItemID;
  OPCNode.stDescription := stDescription;
  OPCNode.vtPropertyDataType := vtDataType;
  OPCNode.vPropertyData := vPropertyData;
  SetLength(FNodes, High(FNodes) + 2);
  FNodes[High(FNodes)] := OPCNode;
end;

function sOPC.GetOPCNode(stItemID: string; Ident: integer): sOPCNode;
var
  i: integer;
begin
  Result := nil;
  if Ident = -1 then begin
    for i := 0 to High(FNodes) do begin
      if FNodes[i].stItemID = stItemID then begin
        Result := FNodes[i];
        exit;
      end;
    end;
  end else begin
    for i := 0 to High(FNodes) do begin
      if FNodes[i].Ident = Ident then begin
        Result := FNodes[i];
        exit;
      end;
    end;
  end;
end;

function sOPC.GetServerCount: integer;
begin
  Result := FDataAccessServers.Count;
end;

function sOPC.GetGroupCount: integer;
var
  i: integer;
begin
  Result := 0;
  for i := 0 to FDataAccessServers.Count - 1 do begin
    // count private groups
    inc(Result, sOPCDataAccess(FDataAccessServers.Items[i]).GroupCount(False));
    // count public groups
    inc(Result, sOPCDataAccess(FDataAccessServers.Items[i]).GroupCount(True));
  end;
end;

procedure sOPC.ItemWrite(OPCNode: sOPCNode; Value: variant; Path: string; DataType: TVarType);
begin
  if Assigned(FOnWrite) then begin
    try
      FOnWrite(OPCNode, Value, Path, DataType);
    except
      on E: Exception do OPCLogException('sOPC.ItemWrite', E);
    end;
  end else begin
    OPCNode.CurrentValue := Value;
    OPCNode.LastUpdate := Now;
  end;
end;

procedure sOPC.ItemRead(OPCNode: sOPCNode; Path: string; DataType: TVarType);
begin
  try
    if Assigned(FOnRead) then FOnRead(OPCNode, Path, DataType);
  except
    on E: Exception do begin
      OPCLogException('sOPC.ItemRead', E);
      VarClear(OPCNode.CurrentValue);
      OPCNode.LastUpdate := Now;
      OPCNode.Quality := OPC_QUALITY_OUT_OF_SERVICE;
    end;
  end;
end;

// +++ OnSetDataType kommt sp鋞er!

procedure sOPC.InitAddressSpace;
begin
  if FAddressSpaceInit then exit;
  FAddressSpaceInit := True;
  try
    if Assigned(FOnInitAddressSpace) then begin
      FOnInitAddressSpace;
    end else begin
      AddLeaf(0, 1, 'No address space defined!', VT_I4, OPC_READABLE + OPC_WRITEABLE);
    end;
  except
    on E: Exception do begin
      OPCLogException('InitAddressSpace', E);
      AddLeaf(0, 1, 'No address space defined (Exception)!', VT_I4, OPC_READABLE + OPC_WRITEABLE);
    end;
  end;
  CreateQualifiedName;
end;

function sOPC.GetIndexOfNode(Ident: integer): integer;
var
  i: integer;
begin
  Result := -1;
  for i := 0 to High(Nodes) do begin
    if (FNodes[i].NodeType <> 2) and (FNodes[i].Ident = Ident) then begin
      Result := i;
      exit;
    end;
  end;
end;

function sOPC.GetIndexOfstItemID(stItemID: string): integer;
var
  i: integer;
begin
  Result := -1;
  for i := 0 to High(FNodes) do begin
    if (FNodes[i].NodeType <> 2) and (FNodes[i].stItemID = stItemID) then begin
      Result := i;
      exit;
    end;
  end;
end;

procedure sOPC.AddDataAccessServer(Server: TObject);
begin
  FDataAccessServers.Add(Server);
end;

procedure sOPC.RemoveDataAccessServer(Server: TObject);
begin
  FDataAccessServers.Remove(Server);
end;

initialization
  OPC := sOPC.Create;

finalization
  OPC.CheckRegister;
  OPC.Free;

end.

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美日韩国产电影| 欧美成人综合网站| 99久久久免费精品国产一区二区| 日本免费新一区视频| 日韩电影在线观看电影| 麻豆成人91精品二区三区| 精彩视频一区二区| 精品亚洲国产成人av制服丝袜| 精品一区二区在线看| 国精品**一区二区三区在线蜜桃| 久久国产欧美日韩精品| 波波电影院一区二区三区| 91丨九色丨尤物| 欧美视频中文一区二区三区在线观看 | av在线不卡观看免费观看| 91丨porny丨首页| 欧美性大战久久久久久久蜜臀| 欧美另类高清zo欧美| 精品日韩99亚洲| 亚洲欧美在线aaa| 日一区二区三区| 国产v日产∨综合v精品视频| 欧美色图免费看| 日韩免费观看2025年上映的电影| 国产婷婷色一区二区三区| 久久精品欧美一区二区三区麻豆| 精品免费99久久| 中文字幕亚洲电影| 国产精品自在在线| 欧美日韩国产经典色站一区二区三区| 欧美成人乱码一区二区三区| 自拍偷拍国产亚洲| 麻豆91精品91久久久的内涵| 91老师国产黑色丝袜在线| 精品久久99ma| 日韩精品电影一区亚洲| 97精品久久久久中文字幕 | 精品国产一区二区三区四区四| 综合中文字幕亚洲| 丰满亚洲少妇av| 日韩亚洲欧美在线观看| 午夜一区二区三区在线观看| 99re66热这里只有精品3直播| 日韩欧美高清在线| 日本欧美大码aⅴ在线播放| 欧美日韩高清影院| 亚洲一二三区视频在线观看| 91搞黄在线观看| 最新国产の精品合集bt伙计| 99视频热这里只有精品免费| 亚洲国产精品成人综合色在线婷婷 | 国产91精品免费| 久久这里只有精品6| 国内精品写真在线观看| 国产女同性恋一区二区| 国产精品一区一区| 国产精品久久久久一区二区三区共| 久草热8精品视频在线观看| 日韩欧美一级二级三级久久久| 蜜桃久久久久久| 国产三级久久久| 91浏览器打开| 亚洲国产精品嫩草影院| 国产98色在线|日韩| 亚洲欧美日本在线| 67194成人在线观看| 综合久久一区二区三区| 92国产精品观看| 婷婷开心激情综合| 国产午夜精品一区二区三区视频 | 日韩激情中文字幕| www国产成人免费观看视频 深夜成人网 | 日韩高清在线观看| 欧美高清在线视频| 欧美视频三区在线播放| 国产一区二区在线观看视频| 国产精品视频一区二区三区不卡| 一本色道久久综合狠狠躁的推荐 | 国产精品久久久久精k8 | 亚洲乱码中文字幕综合| 91精品中文字幕一区二区三区| 国产乱色国产精品免费视频| 亚洲精品亚洲人成人网在线播放| 日韩一区二区视频在线观看| 不卡的av电影| 久久精品二区亚洲w码| 又紧又大又爽精品一区二区| 精品av久久707| 欧美精选一区二区| 91在线播放网址| 国产精品中文有码| 日韩国产欧美在线视频| ㊣最新国产の精品bt伙计久久| 国产亚洲一二三区| 在线播放亚洲一区| 欧美日韩精品综合在线| 91一区二区在线| 91污片在线观看| 91精品国产综合久久久蜜臀图片| 91视频一区二区三区| 成人黄色在线视频| 国产精品性做久久久久久| 精品亚洲欧美一区| 国产精品亚洲成人| 亚洲精品福利视频网站| 久久久久久久网| 欧美va亚洲va| 久久久久久电影| 国产精品三级电影| 国产精品美女久久久久久2018 | 亚洲人精品午夜| 亚洲色图都市小说| 亚洲综合丝袜美腿| 日韩一区欧美二区| 精品一二三四在线| 国产v综合v亚洲欧| 99久久国产免费看| 欧美性受xxxx| 欧美一级欧美一级在线播放| 亚洲精品一区二区三区蜜桃下载| 日韩欧美你懂的| 中文在线一区二区| 天堂一区二区在线免费观看| 韩国女主播一区| 91亚洲精品久久久蜜桃网站| 欧美三级日韩三级国产三级| 日韩欧美一二三| 亚洲欧美一区二区在线观看| 午夜成人免费视频| 丁香另类激情小说| 在线成人小视频| 国产精品日韩精品欧美在线| 午夜精品一区在线观看| 国产99久久久精品| 欧美乱熟臀69xxxxxx| 久久精品欧美一区二区三区不卡 | 免费高清成人在线| 91小宝寻花一区二区三区| 精品少妇一区二区三区日产乱码 | 亚洲自拍与偷拍| 国产精品一区二区在线观看网站| 欧美三级午夜理伦三级中视频| 久久久午夜电影| 日韩成人免费看| 欧洲av一区二区嗯嗯嗯啊| 国产色产综合产在线视频| 日本欧美在线观看| 欧美综合一区二区| 亚洲欧洲日产国码二区| 国产一区二区视频在线| 成人午夜在线播放| 欧美一级久久久久久久大片| 亚洲激情五月婷婷| 成人动漫精品一区二区| 337p日本欧洲亚洲大胆精品| 麻豆成人久久精品二区三区红| 91成人在线观看喷潮| 亚洲精品免费一二三区| 成人h版在线观看| 亚洲图片激情小说| 91视频一区二区| 中文字幕人成不卡一区| 91一区二区在线| 亚洲视频免费在线| 欧美在线观看禁18| 亚洲第一久久影院| 欧美精品久久天天躁| 欧美aⅴ一区二区三区视频| 欧美岛国在线观看| 另类综合日韩欧美亚洲| 国产日产欧美一区| 成年人国产精品| 亚洲女同一区二区| 欧美日韩成人综合天天影院| 久久精品国产一区二区| 国产精品色在线| 欧美日高清视频| 国产河南妇女毛片精品久久久 | 日本在线不卡一区| 久久久久久久免费视频了| fc2成人免费人成在线观看播放 | 久久99精品久久久久久动态图| 久久午夜电影网| 欧美日韩国产高清一区二区| 国产夫妻精品视频| 日韩精品一区第一页| 国产精品视频第一区| 日韩欧美在线网站| 色欧美乱欧美15图片| 国产乱码精品一区二区三| 亚洲成a人片在线不卡一二三区 | 国产伦精品一区二区三区在线观看| 国产精品久久久久毛片软件| 色综合久久久网| 精品一区二区久久久| 亚洲一区二区在线观看视频| 欧美一区二区三区在线| 99这里都是精品| 日韩国产欧美三级| 亚洲国产视频一区|