?? opcserver.cpp
字號:
#include "stdafx.h"
#include "opcserver.h"
#include "opcclientdoc.h"
//#define FULL_TEST
extern OPCClientDoc* theDoc;
// The OPC data formats
UINT OPCSTMFORMATDATA = RegisterClipboardFormat(_T("OPCSTMFORMATDATA"));
UINT OPCSTMFORMATDATATIME = RegisterClipboardFormat(_T("OPCSTMFORMATDATATIME"));
UINT OPCSTMFORMATWRITECOMPLETE = RegisterClipboardFormat(_T("OPCSTMFORMATWRITECOMPLETE"));
IMPLEMENT_SERIAL(Item, CObject,0)
IMPLEMENT_SERIAL(COPCGroup, CObject, 0)
IMPLEMENT_SERIAL(COPCServer, CObject, 0)
//************************************************************
//************************************************************
//************************************************************
//class Item
void Item::Serialize(CArchive& ar)
{
if(ar.IsStoring())
{
ar<<name; //名稱
ar<<access_path; //訪問路徑
ar<<description;
}
else
{
ar>>name;
ar>>access_path;
ar>>description;
}
}
//************************************************************
//默認(rèn)構(gòu)造函數(shù)
COPCGroup::COPCGroup(COPCServer* server)
:group_name(_T("Group1")),
update_rate(1000),
dead_band(0.0),
time_bias(0),
active(false),
local_id(0),
group_handle(0),
parent(server)
{
connection1 = 0;
connection2 = 0;
call_back_connection = 0;
use_cp = false;
tree_item = 0;
advise_sink = new CAdviseSink;
ASSERT(advise_sink);
advise_sink->AddRef();
call_back = new OPCCallbackObject;
call_back->AddRef();
current_item = NULL;
while(!items.IsEmpty())
delete items.RemoveHead();
}
//拷貝構(gòu)造函數(shù)
COPCGroup::COPCGroup(COPCServer* server, COPCGroup& group)
{
group_name = group.get_name();
update_rate = group.get_update_rate();
dead_band = group.get_dead_band();
time_bias = group.get_time_bias();
active = group.get_active();
local_id = group.get_local_id();
group_handle = 0;
parent = group.parent;
tree_item = 0;
connection1 = 0;
connection2 = 0;
call_back_connection = 0;
use_cp = false;
advise_sink = new CAdviseSink;
ASSERT(advise_sink);
advise_sink->AddRef();
call_back = new OPCCallbackObject;
call_back->AddRef();
current_item = NULL;
while(!items.IsEmpty())
delete items.RemoveHead();
ItemList& item_list = group.get_items();
POSITION item_pos = item_list.GetHeadPosition();
while(item_pos){
Item* item = item_list.GetNext(item_pos);
Item* new_item = new Item;
if(!new_item || !item)
continue;
CoFileTimeNow(&new_item->timestamp);
new_item->name = item->name;
new_item->access_path = item->access_path;
new_item->description = item->description;
new_item->hServerHandle = item->hServerHandle;
new_item->quality = item->quality;
new_item->access_rights = item->access_rights;
new_item->active = item->active;
new_item->native_type = item->native_type;
new_item->value = item->value;
new_item->server = parent;
new_item->group = this;
items.AddTail(new_item);
}
}
COPCGroup::~COPCGroup(){
//刪除每個點
HRESULT hr = S_OK;
if(opc_group.IsOk()){
if(use_cp)
hr = AtlUnadvise(opc_group, IID_IOPCDataCallback, call_back_connection);
else{
DataObject data_object;
hr = data_object.Attach(opc_group);
if(SUCCEEDED(hr)){
if(connection1)
hr = data_object.DUnadvise(connection1);
if(connection2)
hr = data_object.DUnadvise(connection2);
data_object.Detach();
}
}
int count = items.GetCount();
if(count > 0){
OPCItemMgt item_mgt;
hr = item_mgt.Attach(opc_group);
if(SUCCEEDED(hr)){
HRESULT* errors = NULL;
OPCHANDLE* handles = new OPCHANDLE[count];
ASSERT(handles);
POSITION item_pos = items.GetHeadPosition();
for(int index = 0; item_pos; index++){
Item* item = items.GetNext(item_pos);
ASSERT(item);
handles[index] = item->hServerHandle;
}
hr = item_mgt.RemoveItems(count, handles, &errors);
if(SUCCEEDED(hr))
CoTaskMemFree(errors);
delete[] handles;
item_mgt.Detach();
}
}
}
if(parent && parent->is_connected()){
hr = parent->opc_server.RemoveGroup(group_handle, FALSE);
if(FAILED(hr))
theDoc->ReportError(_T("Remove Group Failed: "), hr);
}
current_item = NULL;
while(!items.IsEmpty())
delete items.RemoveHead();
call_back->Release();
advise_sink->Release();
opc_group.Detach();
}
void COPCGroup::Serialize(CArchive& ar){
if(ar.IsStoring()){
ar << group_name;
ar << update_rate;
ar << dead_band;
ar << time_bias;
ar << local_id;
ar << active;
int item_count = items.GetCount();
ar << item_count;
POSITION item_pos = items.GetHeadPosition();
while(item_pos){
Item* item = items.GetNext(item_pos);
if(item)
item->Serialize(ar);
}
}
else{
ar >> group_name;
ar >> update_rate;
ar >> dead_band;
ar >> time_bias;
ar >> local_id;
ar >> active;
active = TRUE;
if(parent && parent->is_connected())
parent->add_group(this);
else{
delete this;
return;
}
while(!items.IsEmpty())
delete items.RemoveHead();
int item_count = 0;
ar >> item_count;
while(item_count --){
Item* item = new Item;
if(item){
item->Serialize(ar);
item->active = TRUE;
//items.AddTail(item);
add_item(item);
}
}
}
}
Item* COPCGroup::add_item(Item *item)
{
USES_CONVERSION;
CWaitCursor wait;
if(!(item && parent)){
delete item;
return 0;
}
OPCItemMgt item_mgt;
HRESULT hr = item_mgt.Attach(opc_group);
if(FAILED(hr)){
delete item;
return 0;
}
current_item = item; //當(dāng)前點
OPCITEMDEF item_def;
item_def.szItemID = T2OLE(item->name.GetBuffer(0));
item_def.szAccessPath = T2OLE(item->access_path.GetBuffer(0));
item_def.pBlob = NULL;
item_def.dwBlobSize = 0;
item_def.bActive = item->active;
item_def.hClient = (OPCHANDLE)item;
item_def.vtRequestedDataType = item->native_type;
//添加點
OPCITEMRESULT* results;
HRESULT* errors;
hr = item_mgt.AddItems(1, &item_def, &results, &errors);
if(FAILED(hr)){
theDoc->ReportError(_T("Add Items: "), hr);
delete item;
return 0;
}
item->hServerHandle = results->hServer;
item->native_type = results->vtCanonicalDataType;
HRESULT item_result = errors[0];
if(results->pBlob != NULL)
CoTaskMemFree(results->pBlob);
CoTaskMemFree(results);
CoTaskMemFree(errors);
if(FAILED(item_result)){
theDoc->ReportError(_T("Add Items: "), hr);
delete item;
return 0;
}
items.AddTail(item); //保存點
//讀取初始值
OPCSyncIO sync_io;
hr = sync_io.Attach(opc_group);
if(SUCCEEDED(hr)){
OPCITEMSTATE* item_state = NULL;
hr = sync_io.Read(
OPC_DS_CACHE,
1,
&item->hServerHandle,
&item_state,
&errors);
if(SUCCEEDED(hr)){
ASSERT(item_state->hClient == (OPCHANDLE)item);
item->quality = item_state->wQuality;
item->value = item_state->vDataValue;
VariantClear(&item_state->vDataValue);
CoTaskMemFree(item_state);
CoTaskMemFree(errors);
}
else{
theDoc->ReportError(_T("SysncIO Read: "), hr);
return 0;
}
sync_io.Detach();
}
return item;
}
DWORD COPCGroup::add_items(DWORD item_count, Item *item_arr)
{
USES_CONVERSION;
CWaitCursor wait;
DWORD dwCount = 0;
for(DWORD i = 0; i < item_count; i++){
Item* item = item_arr + i;
if(!(item && parent)){
delete item;
item = 0;
continue;
}
OPCItemMgt item_mgt;
HRESULT hr = item_mgt.Attach(opc_group);
if(FAILED(hr)){
delete item;
item = 0;
continue;
}
current_item = item; //當(dāng)前點
OPCITEMDEF item_def;
item_def.szItemID = T2OLE(item->name.GetBuffer(0));
item_def.szAccessPath = T2OLE(item->access_path.GetBuffer(0));
item_def.pBlob = NULL;
item_def.dwBlobSize = 0;
item_def.bActive = item->active;
item_def.hClient = (OPCHANDLE)item;
item_def.vtRequestedDataType = item->native_type;
//添加點
OPCITEMRESULT* results;
HRESULT* errors;
hr = item_mgt.AddItems(1, &item_def, &results, &errors);
if(FAILED(hr)){
theDoc->ReportError(_T("Add Items: "), hr);
delete item;
item = 0;
continue;
}
item->hServerHandle = results->hServer;
item->native_type = results->vtCanonicalDataType;
HRESULT item_result = errors[0];
if(results->pBlob != NULL)
CoTaskMemFree(results->pBlob);
CoTaskMemFree(results);
CoTaskMemFree(errors);
if(FAILED(item_result)){
theDoc->ReportError(_T("Add Items: "), hr);
delete item;
item = 0;
continue;
}
items.AddTail(item); //保存點
//讀取初始值
OPCSyncIO sync_io;
hr = sync_io.Attach(opc_group);
if(SUCCEEDED(hr)){
OPCITEMSTATE* item_state = NULL;
hr = sync_io.Read(
OPC_DS_CACHE,
1,
&item->hServerHandle,
&item_state,
&errors);
if(SUCCEEDED(hr)){
ASSERT(item_state->hClient == (OPCHANDLE)item);
item->quality = item_state->wQuality;
item->value = item_state->vDataValue;
VariantClear(&item_state->vDataValue);
CoTaskMemFree(item_state);
CoTaskMemFree(errors);
}
else{
theDoc->ReportError(_T("SysncIO Read: "), hr);
continue;
}
sync_io.Detach();
}
dwCount++;
}
return dwCount;
}
//****************************************************
COPCServer::COPCServer(){
current_group = 0;
server_info = 0;
/*
shut_down = new OPCShutdownObject;
shut_down->AddRef();
*/
shut_down_connection = 0;
tree_item = 0;
}
COPCServer::~COPCServer(){
if(is_connected())
disconnect();
shut_down->Release();
current_group = NULL;
while(!groups.IsEmpty())
delete groups.RemoveHead();
if(server_info){
delete server_info;
server_info = 0;
}
}
OPCServerInfo* COPCServer::SetServerInfo(OPCServerInfo *info)
{
if(is_connected()){
delete info;
info = 0;
return 0;
}
if(info){
if(server_info)
delete server_info;
server_info = info;
}
return info;
}
//通用
/*
LPWSTR ConvertMultiByteToWideChar(LPCSTR ttt)
{
try{
size_t aLen = strlen( ttt ) + 1;
int wLen = MultiByteToWideChar(
CP_ACP,
0,
ttt,
aLen,
NULL,
0);
LPOLESTR tempID= new WCHAR [wLen];
int nreturn=MultiByteToWideChar(CP_ACP,0,ttt,aLen,tempID,wLen);
return (LPWSTR)tempID;
}catch(...){
return L"";
}
}
*/
extern IOPCServer *m_pIOPCServer;
extern IOPCItemMgt *m_pIOPCItemMgt;
extern IOPCGroupStateMgt *m_pIOPCGroupStateMgt;
extern IOPCAsyncIO2 *m_pIOPCAsyncIO2;
extern OPCITEMRESULT *m_pItemResult;
extern HRESULT *m_pErrors;
extern OPCHANDLE m_GrpSrvHandle;
#include "opctest/callback.h"
//連接OPCServer
bool COPCServer::connect(OPCServerInfo *info)
{
USES_CONVERSION;
if(is_connected())
return true;
CWaitCursor wait_cursor;
if(info)
server_info = info;
else
info = server_info;
bool use_node = true;
if(info->m_NodeName.IsEmpty()
|| _tcsicmp(_T(""), info->m_NodeName) == 0
|| _tcsicmp(_T("localhost"), info->m_NodeName) == 0
|| _tcsicmp(_T("127.0.0.1"), info->m_NodeName) ==0 ){
use_node = false;
}
if(use_node){ //是否同為本機(jī)
TCHAR sz_local_host[MAX_COMPUTERNAME_LENGTH + 1];
DWORD dw_host_size = sizeof(sz_local_host);
if(GetComputerName(sz_local_host, &dw_host_size)){
if(_tcsicmp(sz_local_host, info->m_NodeName) == 0)
use_node = false;
}
}
//建立OPC對象
HRESULT hr = S_OK;
LPUNKNOWN punknown = NULL;
if(!use_node){ //本地OPCServer
hr = CoCreateInstance(
info->m_clsid,
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -