?? opcserver.cpp
字號:
info->m_clsid,
NULL,
CLSCTX_ALL,
IID_IUnknown,
(LPVOID*)&punknown);
if(FAILED(hr) || punknown == NULL){ //創建失敗
CString msg;
msg.Format(_T("CoCreateInstance %s failed:"), info->m_ProgID.GetBuffer(0));
theDoc->ReportError(msg, hr);
return false;
}
}
else{ //遠程對象
COSERVERINFO si;
MULTI_QI qi;
si.dwReserved1 = 0;
si.pAuthInfo = NULL;
si.pwszName = T2OLE(info->m_NodeName.GetBuffer(0));
si.dwReserved2 = 0;
qi.pIID = &IID_IOPCServer;
qi.pItf = NULL;
qi.hr = 0;
hr = CoCreateInstanceEx(
info->m_clsid,
NULL,
CLSCTX_REMOTE_SERVER,
&si,
1,
&qi);
if(FAILED(hr)){
CString msg(_T("CoCreateInstanceEx failed: "));
theDoc->ReportError(msg, hr);
return false;
}
if(FAILED(qi.hr) || (qi.pItf == NULL)){
CString msg(_T("MULTI_QI failed: "));
theDoc->ReportError(msg, qi.hr);
return false;
}
punknown = qi.pItf;
}
hr = opc_server.Attach(punknown);
punknown->Release(); //釋放IUnknown接口
punknown = NULL;
if(FAILED(hr)){
CString msg(_T("OPC Server Attach failed:"));
if(theDoc)
theDoc->ReportError(msg, hr);
}
//是否實現了IShutdown接口
hr = AtlAdvise(
opc_server,
shut_down->GetUnknown(),
IID_IOPCShutdown,
&shut_down_connection
);
if(FAILED(hr)){
CString msg;
msg.Format(_T("%s: %s can't support IOPCShutdown interface."),
info->m_NodeName,
info->m_ProgID);
if(theDoc)
theDoc->ReportError(msg.GetBuffer(0));
}
//添加所有組
/*
POSITION group_pos = groups.GetHeadPosition();
while(group_pos){
COPCGroup* group = groups.GetNext(group_pos);
if(!group)
continue;
group = add_group(group);
if(group){ //添加所有點
POSITION item_pos = group->items.GetHeadPosition();
while(item_pos){
Item* item = group->items.GetNext(item_pos);
if(!item)
continue;
item = group->add_item(item);
}
}
}
*/
return true;
}
//斷開OPCServer
bool COPCServer::disconnect()
{
if(!is_connected())
return false;
HRESULT hr = S_OK;
if(shut_down_connection){
hr = AtlUnadvise(
opc_server,
IID_IOPCShutdown,
shut_down_connection);
shut_down_connection = 0;
if(FAILED(hr)){
CString msg(_T("AtlUnadvise IOPCShutdown failed."));
if(theDoc)
theDoc->ReportError(msg.GetBuffer(0), hr);
}
}
//斷開所有Group,并刪除
/*.....*/
current_group = NULL;
while(!groups.IsEmpty())
delete groups.RemoveHead();
opc_server.Detach();
return true;
}
//連接狀態
bool COPCServer::is_connected()
{
return opc_server.IsOk() ? true : false;
}
//獲取錯誤信息
HRESULT COPCServer::GetErrorString(
HRESULT dwError,
LCID dwLocale,
LPWSTR* ppString)
{
return opc_server.GetErrorString(dwError, dwLocale, ppString);
}
OPCServerInfo* const COPCServer::get_server_info()
{
return server_info;
}
//添加點
COPCGroup* COPCServer::add_group(COPCGroup *group)
{
USES_CONVERSION;
if(!group)
return 0;
OPCServerInfo* info = server_info;
//add group
LPCWSTR group_name = T2OLE(group->get_name().GetBuffer(0));
BOOL active = group->get_active();
ULONG update_rate = group->get_update_rate();
long time_bias = group->get_time_bias();
float dead_band = group->get_dead_band();
DWORD local_id = group->get_local_id();
DWORD rate;
HRESULT hr = opc_server.AddGroup(
L"WuLiangFeng",
active,
update_rate,
(OPCHANDLE)group,
&time_bias,
&dead_band,
local_id,
&group->group_handle,
&rate,
IID_IOPCGroupStateMgt,
group->opc_group);
// CString ss;
// ss.Format("group id=%d",group->group_handle);
// AfxMessageBox(ss);
if(FAILED(hr)){
CString msg;
msg.Format(_T("Add Group: %s failed."), group_name);
theDoc->ReportError(msg.GetBuffer(0), hr);
return 0;
}
#ifdef FULL_TEST
IOPCGroupStateMgt* pTest=NULL;
hr = opc_server.GetGroupByName(
L"WuLiangFeng",
IID_IOPCGroupStateMgt,
(LPUNKNOWN*)&pTest );
if( SUCCEEDED(hr) )
{
ASSERT( pTest == (IOPCGroupStateMgt*)group->opc_group ); // should get the same
hr = pTest->SetName( group_name ); // set new name
pTest->Release();
if( FAILED(hr) )
{
theDoc->ReportError( _T("IOPCGroupStateMgt::SetName: "), hr );
}
else
{
// should now go by this new name
hr = opc_server.GetGroupByName(
group_name,
IID_IOPCGroupStateMgt,
(LPUNKNOWN*)&pTest );
if( SUCCEEDED(hr) )
{
ASSERT( pTest == (IOPCGroupStateMgt*)group->opc_group );
pTest->Release();
}
}
}
#endif//FULL_TEST
//OPC 2.0 connection point
hr = AtlAdvise(
group->opc_group,
group->call_back->GetUnknown(),
IID_IOPCDataCallback,
&group->call_back_connection);
if(SUCCEEDED(hr))
group->use_cp = true;
if(!group->use_cp){ //不支持連接點
CString msg;
msg.Format(_T("%s: %s can't support IOPCDataCallback interface."),
info->m_NodeName,
info->m_ProgID);
theDoc->ReportError(msg.GetBuffer(0), hr);
//opc 1.0 data advise format
FORMATETC format_etc;
format_etc.tymed = TYMED_HGLOBAL;
format_etc.ptd = NULL;
format_etc.dwAspect = DVASPECT_CONTENT;
format_etc.lindex = -1;
// IAdviseSink is an interface on OUR object that is passed to
// the server for callbacks
IAdviseSink *pAdviseSink = NULL;
hr = group->advise_sink->QueryInterface(IID_IAdviseSink, (LPVOID *)&pAdviseSink);
if( FAILED(hr) )
{
msg = _T("IAdviseSink: ");
theDoc->ReportError(msg.GetBuffer(0), hr);
group->opc_group.Detach();
//opc_server.Detach();
return 0;
}
// Get an IDataObject interface on the group
DataObject dataObject;
hr = dataObject.Attach( group->opc_group );
if(FAILED(hr) || !dataObject.IsOk() )
{
//some servers don't do this, so don't quit altogether
msg = _T("IDataObject not supported by this server\nNo data notifications will take place");
theDoc->ReportError(msg.GetBuffer(0));
return 0;
}
// Register our IAdvise with the group
// Need to register both formats: data change, and write complete
format_etc.cfFormat = OPCSTMFORMATWRITECOMPLETE ;
hr = dataObject.DAdvise(&format_etc,
ADVF_PRIMEFIRST, // ADVF flag
pAdviseSink,
&group->connection2);
if( FAILED(hr) )
{
msg = _T("IDataObject::DAdvise: : ");
theDoc->ReportError(msg.GetBuffer(0), hr);
return 0;
}
#ifdef DATATIMEFORMAT
format_etc.cfFormat = OPCSTMFORMATDATATIME ;
#else
format_etc.cfFormat = OPCSTMFORMATDATA ;
#endif // DATATIMEFORMAT
hr = dataObject.DAdvise(&format_etc,
ADVF_PRIMEFIRST, // ADVF flag
pAdviseSink,
&group->connection1);
pAdviseSink->Release();
if( FAILED(hr) )
{
msg = _T("IDataObject::DAdvise: : ");
theDoc->ReportError(msg.GetBuffer(0), hr);
return 0;
}
}
groups.AddTail(group);
current_group = group;
theDoc->UpdateAllViews(NULL, ADD_GROUP, (CObject*)group);
return current_group;
}
//獲取當前組
COPCGroup* COPCServer::get_current_group()
{
return current_group;
}
//獲取父服務器
COPCServer* COPCGroup::get_parent() const
{
return parent;
}
OPCServer& COPCServer::get_opc_server()
{
return opc_server;
}
COPCGroup* COPCServer::set_current_group(COPCGroup *group)
{
if(group)
current_group = group;
return group;
}
//保存
void COPCServer::Serialize(CArchive &ar)
{
CWaitCursor wait_cursor;
//Lock wait(&item_cs);
if(ar.IsStoring()){
if(server_info){
ar << server_info->m_ProgID;
ar << server_info->m_NodeName;
ar << server_info->m_Description;
ar << server_info->m_clsid.Data1;
ar << server_info->m_clsid.Data2;
ar << server_info->m_clsid.Data3;
int times = sizeof(server_info->m_clsid.Data4) / sizeof(BYTE);
for(int i = 0; i < times; i++){
ar << server_info->m_clsid.Data4[i];
}
}
int group_count = groups.GetCount();
ar << group_count;
POSITION group_pos = groups.GetHeadPosition();
while(group_pos){
COPCGroup* group = groups.GetNext(group_pos);
if(group)
group->Serialize(ar);
}
}
else{
if(server_info)
delete server_info;
server_info = new OPCServerInfo;
if(server_info){
ar >> server_info->m_ProgID;
ar >> server_info->m_NodeName;
ar >> server_info->m_Description;
ar >> server_info->m_clsid.Data1;
ar >> server_info->m_clsid.Data2;
ar >> server_info->m_clsid.Data3;
int times = sizeof(server_info->m_clsid.Data4) / sizeof(BYTE);
for(int i = 0; i < times; i++){
ar >> server_info->m_clsid.Data4[i];
}
}
if(!is_connected()) //連接OPC Server
connect();
while(!groups.IsEmpty())
delete groups.RemoveHead();
int group_count = 0;
ar >> group_count;
while(group_count--){
COPCGroup* group = new COPCGroup;
if(group){
group->parent = this;
group->Serialize(ar);
//add_group(group);
//groups.AddTail(group);
}
}
}
}
//刪除點
void COPCGroup::remove_item()
{
if(current_item == NULL)
return;
OPCItemMgt item_mgt;
HRESULT hr = item_mgt.Attach(opc_group);
if(SUCCEEDED(hr)){
HRESULT* errors = NULL;
hr = item_mgt.RemoveItems(
1,
¤t_item->hServerHandle,
&errors);
if(SUCCEEDED(hr))
CoTaskMemFree(errors);
EnterCriticalSection(&item_cs);
POSITION pos = items.Find(current_item);
if(pos)
items.RemoveAt(pos);
delete current_item;
current_item = NULL;
LeaveCriticalSection(&item_cs);
theDoc->SetModifiedFlag(TRUE);
theDoc->UpdateAllViews(NULL, UPDATE_GROUP, (CObject*)this);
}
}
void COPCServer::remove_group(COPCGroup *group)
{
Lock wait(&item_cs);
if(group == NULL){
group = current_group;
current_group = 0;
}
POSITION group_pos = groups.Find(group);
if(group_pos){
groups.RemoveAt(group_pos);
delete group;
}
theDoc->UpdateAllViews(NULL, UPDATE_SERVER, (CObject*)this);
}
//讀取點
void COPCGroup::read_item(Item *item)
{
}
void COPCGroup::write_item(BOOL async, CString value, Item *item)
{
}
void COPCGroup::SetItemValue(OPCHANDLE hItem, VARIANT *pVar, FILETIME timestamp, WORD quality)
{
POSITION item_pos = items.GetHeadPosition();
for(int index = 0; item_pos; index++){
Item* item = items.GetNext(item_pos);
ASSERT(item);
if(hItem ==(OPCHANDLE) item)
{
item->quality = quality;
VariantCopy(&(item->value), pVar);
item->timestamp=timestamp;
break;
}
}
}
void COPCServer::SetItemValue(OPCHANDLE hGroup, OPCHANDLE hItem, VARIANT *pVar, FILETIME timestamp, WORD quality)
{
POSITION group_pos = groups.GetHeadPosition();
while(group_pos){
COPCGroup* group = groups.GetNext(group_pos);
CString ss;
ss.Format("%d=%d",group->group_handle,hGroup);
AfxMessageBox(ss);
if(!group)
continue;
if(group->group_handle == hGroup)
{
group->SetItemValue(hItem,pVar,timestamp,quality);
break;
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -