void __fastcall TframTag::cmbTypeChange(TObject *Sender) { // ValidateView(); switch(cmbType->ItemIndex){ case 0: set_value_type(m_Tag.s.Flags, dt_bool); break; case 1: set_value_type(m_Tag.s.Flags, dt_real4); break; case 2: set_value_type(m_Tag.s.Flags, dt_real8); break; case 3: set_value_type(m_Tag.s.Flags, dt_int16); break; case 4: set_value_type(m_Tag.s.Flags, dt_int32); break; } UpdateView(); PageControl1->ActivePageIndex = 0; // PageControl1->Pages[0]->Visible = true; }
/* 功能:从设备驱动中更新并得到实时值 参数: tag 更新的标签结构体,包含更新实时值所需要的配置信息[in] new_value 实时值指针,用于存储更新所得到的实时值[in, out] now 更新时间[in] 返回: 1 成功 0 tag中动态属性的设备信息丢失 或 tag中动态属性设备信息的驱动信息丢失 或 tag中驱动信息中的更新tag的导出函数丢失 */ IO_API __bool PMC_API io_update_tag( PCRTK_TAG tag, Ppmc_value_t new_value, PCRTK_TIME now ) { PDRIVER_INFO drv; //1 设置新实时值的Flags new_value->Flags = 0; set_value_type(new_value->Flags, get_value_type(tag->s.Flags)); //2 将实时值的union清0,u64是union中的最大元素,即可表示union的大小 /* pre-set all unused bytes to zero, this will make it easier to write code depending on the tag types */ new_value->Value.u64 = 0; // assert(tag->d.DeviceObj == io_open_device(&tag->s.Device)); //3 从标签的动态属性中得到设备驱动信息的结构体 if(!tag->d.DeviceObj){ return __false; } drv = ((PDEVICE_INFO)tag->d.DeviceObj)->d; if(!drv){ return __false; } //4 调用设备驱动DLL的导出函数更新实时值 if(!drv->update_tag){ return __false; } if(drv->update_tag){ drv->update_tag(tag, new_value, now); } //5 某些设备驱动可能会重写实时值的类型标识,需要再用标签静态属性中的类型标识设置一下 // some ill-behavioured driver will overwrite the type field set_value_type(new_value->Flags, get_value_type(tag->s.Flags)); //6 若静态属性配置为开关量,则将true转化为1,false转化为0 if(get_value_type(tag->s.Flags) == dt_bool){ /* make digital variable cannonical */ new_value->Value.b = new_value->Value.b? 1 : 0; } return __true; }
RTDB_API RTK_CURSOR PMC_API create_tag( RTK_CURSOR group, PCTAG_KEY tag, PCSTATIC_TAG_DATA sd ) { RTK_CURSOR handle; RTK_GROUP * grp; RTK_TAG t; handle = open_tag_g(group, tag); if(handle){ return handle; } if(g_dwTags >= g_dwMaxTags){ rtk_set_last_error(RTDB_HARD_CONSTRAINTS); return 0; } grp = (RTK_GROUP*)cursor_get_item(group); if(!grp){ return 0; } ZeroMemory(&t, sizeof(t)); t.key = *tag; make_unified_key(t.key); t.s = *sd; t.node = grp->node; t.group = grp->key; handle = (RTK_CURSOR)_HTAG::create((TAG_TABLE*)grp->itemtable, t.key, t); RTK_TAG * pTag = (RTK_TAG*)cursor_get_item(handle); if(pTag){ ZeroMemory(&pTag->d, sizeof(pTag->d)); set_value_type(pTag->d.Value.Flags, get_value_type(pTag->s.Flags)); RtkInitializeListHead(&pTag->d.DeviceLink); RtkInitializeListHead(&pTag->d.RefreshLink); FIRE_EVENT(OnAddTag, (pTag)); g_dwTags++; } return handle; }
//--------------------------------------------------------------------------- void __fastcall TframTag::btnWriteDeviceClick(TObject *Sender) { AnsiString value; pmc_value_t strVal, val; value = InputBox( "输入要写的数值", (char*)CTagName(m_TagName.sname.tag), "" ); if(value.Length() == 0){ return; } set_value_type(strVal.Flags, dt_string); strVal.Value.str = value.c_str(); val.Flags = m_Tag.s.Flags; pmc_type_cast(&strVal, &val); if(proxy_write_tags(1, &m_TagName, &val.Value) ){ m_Hint = "写入成功"; }else{ m_Hint = "写入失败"; } }
/* 功能:将pmc_value_t实时值写入设备 参数: name 待写入实时值对应的 组名.标签名 value 待写入的实时值 返回:即设备驱动导出函数write_device()的返回值 */ IO_API __bool PMC_API io_write_device_ex( PCSHORT_TAG_NAME name, PCpmc_value_t value ) { pmc_value_t value2; __bool retval = __false; if(!lock_rtdb(__false, 100)){ return __false; } PRTK_TAG p = query_tag(HNODE_LOCAL_MACHINE, name); if(p && !(p->d.Value.Flags & TF_ReadOnly)){ ZeroMemory(&value2, sizeof(value2)); set_value_type(value2.Flags, get_value_type(p->s.Flags)); if(pmc_type_cast(value, &value2)){ retval = _writeDevice(p, &value2.Value); } } unlock_rtdb(); return retval; }
void __fastcall TframTag::tmrUpdaterTimer(TObject *Sender) { pmc_value_t value; AnsiString txtValue; char buf[64]; FILETIME ft; SYSTEMTIME st; proxy_read_tags(1, &m_TagName, &value, 0); if(value.Flags & TF_Valid){ pmc_value_t strVal; set_value_type(strVal.Flags, dt_string); pmc_type_cast(&value, &strVal); txtValue = strVal.Value.str; pmc_clear(&strVal); }else{ txtValue = "N.A."; } edtValue->Text = txtValue; RTK_TAG * p = query_tag_f(&m_TagName); if(p){ AnsiString s; FILETIME lft; SYSTEMTIME st; FileTimeToLocalFileTime((LPFILETIME)&p->d.CachedTime, &lft); FileTimeToSystemTime(&lft, &st); s = ""; s.cat_printf( "%d年%d月%d日 %02d:%02d:%02d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond ); lblStatus->Caption = s; }else{ lblStatus->Caption =""; } }
double CExpression::vexp ( arbore a ) { double v; SYSTEMTIME tm; GetSystemTime(&tm); if (a->operatie==NULL) {error_code=10;return 0;} switch(a->operatie){ case '+' : return( vexp(a->left)+vexp(a->right) ); case '-' : return( vexp(a->left)-vexp(a->right) ); case '*' : return( vexp(a->left)*vexp(a->right) ); case '%': { v = vexp(a->right); if(v == 0){ error_code = DIVISION_BY_0; return 0; } return (int)vexp(a->left) % (int)v; } case '/' : v=vexp(a->right) ; if (v==0){ error_code=DIVISION_BY_0; return -vexp(a->left)/0.001; }else{ return(vexp(a->left)/v); } case 150 : return(sin(vexp(a->left))); case 151 : return(cos(vexp(a->left))); case 152 : return(exp(vexp(a->left))); case 153 : v=vexp(a->left) ; if (v<0) {error_code=INVALID_DOMAIN;return 0;} else return(sqrt(v)); case 154 : v=vexp(a->left) ; if (v<=0) {error_code=INVALID_DOMAIN;return 0;} else return(log(v)); case 155 : return (tan (vexp(a->left))); case 156 : return (1 / tan (vexp(a->left))); case 157 : return (asin (vexp(a->left))); case 158 : return (acos (vexp(a->left))); case 159 : return (atan (vexp(a->left))); case 173 : return (fabs (vexp(a->left))); case 160 : return tm.wYear; case 161 : return tm.wMonth; case 162 : return tm.wDay; case 163 : return tm.wHour; case 164 : return tm.wMinute; case 165 : return tm.wSecond; case 166 : return max(vexp(a->left),vexp(a->right)); case 167 : return min(vexp(a->left),vexp(a->right)); case 168 : return rng_rand(0,RAND_MAX)*vexp(a->left)/RAND_MAX; //case '|' : return(fabs(vexp(a->left))); case '^' : return(pow(vexp(a->left),vexp(a->right))); case '@' : return (a->valoare); //logical operations evaluation case '<' : return( vexp(a->left) < vexp(a->right) ); case '>' : return( vexp(a->left) > vexp(a->right) ); case '!' : return(!vexp(a->right)) ; // added by chenj, @2008-5-22 case '=' : return( vexp(a->left) == vexp(a->right) ); case '&' : return (int)(vexp(a->left)) & (int)(vexp(a->right)); case '|' : return (int)(vexp(a->left)) | (int)(vexp(a->right)); case 169: { RTK_TIME t; rtk_time_mark(&t); return (double)(__int64)t.Data / 1e7; } case 170: { /* last update time */ PRTK_TAG tte; __r8 retval = 0; tte = (PRTK_TAG)a->left->pvObj; if(!tte){ error_code=UNDEFINED_VARIABLE; retval = 0; }else{ if(!(tte->d.Value.Flags & TF_Valid)){ error_code=UNDEFINED_VARIABLE; retval = 0; }else{ PRTK_TIME pTime = (PRTK_TIME)&tte->d.BinaryAddress[8]; retval = (double)(__int64)pTime->Data / 1e7; rtk_time_mark(pTime); } } return retval; } case 171 : { // a database tag PRTK_TAG tte; __r8 retval = 0; tte = (PRTK_TAG)a->pvObj; if(!tte){ error_code=UNDEFINED_VARIABLE; retval = 0; }else{ if(!(tte->d.Value.Flags & TF_Valid)){ error_code=UNDEFINED_VARIABLE; retval = 0; }else{ pmc_value_t dblVal; set_value_type(dblVal.Flags, dt_real8); pmc_type_cast(&tte->d.Value, &dblVal); retval = dblVal.Value.dbl; } } return retval; } case 172: { /* span time */ PRTK_TAG tte; RTK_TIME now; __r8 retval = 0; tte = (PRTK_TAG)a->left->pvObj; if(!tte){ error_code=UNDEFINED_VARIABLE; retval = 0; }else{ if(!(tte->d.Value.Flags & TF_Valid)){ error_code=UNDEFINED_VARIABLE; retval = 0; }else{ PRTK_TIME pTime = (PRTK_TIME)&(tte->d.BinaryAddress[8]); rtk_time_mark(&now); if(pTime->Data != 0){ /* yes, the field is previouly stored with a resonable value, thus valid for a sub-operation to get a duration time */ retval = rtk_time_diff(&now, pTime); }else{ /* this might be the first time that a time-span was requested for this tag */ retval = 0; } *pTime = now; } } return retval; } } return 0; }
void CText::Draw(CDC *pDC) { long x1,y1,x2,y2; if(m_DnyAttr.m_Linked && m_DnyAttr.m_na) { CPen *pop=(CPen*)(pDC->SelectStockObject(BLACK_PEN)); CBrush *pob=(CBrush*)(pDC->SelectStockObject(WHITE_BRUSH)); UPtoLP(m_lox1,m_loy1,&x1,&y1); UPtoLP(m_lox2,m_loy2,&x2,&y2); pDC->Rectangle(x1,y1,x2,y2); /* pDC->MoveTo(x1, y1); pDC->LineTo(x1 + 10, y1 + 10); pDC->MoveTo(x1 + 10, y1); pDC->LineTo(x1, y1 + 10); */ pDC->SelectObject(pop); pDC->SelectObject(pob); pDC->DrawIcon(x1,y1,ghNA); return; } if(m_DnyAttr.m_Linked && !m_DnyAttr.m_vi) return; LOGFONT tFont; tFont=m_font; UPtoLP(tFont.lfHeight,tFont.lfWidth,&tFont.lfHeight,&tFont.lfWidth); CFont font; font.CreateFontIndirect(&tFont); CFont *pOldFont=pDC->SelectObject(&font); int i,iWidth; long lTemp,lUWidth=0; UINT nTemp; i=0; while(i<m_text.GetLength()) { nTemp=(UCHAR)m_text[i]; if(IsDBCSLeadByte(nTemp)) { nTemp=nTemp*256+(UCHAR)m_text[i]; i++; } ::GetCharWidth(pDC->GetSafeHdc(),nTemp,nTemp,&iWidth); //CMeatFileDC没有属性DC,下面这句话就不灵了。 //pDC->GetCharWidth(nTemp,nTemp,&iWidth); CElement::LPtoUP(iWidth,iWidth,&lTemp,0); lUWidth+=lTemp; i++; } pDC->SetBkMode(TRANSPARENT); pDC->SetTextColor(m_FaceColor); UPtoLP(m_lx1,m_ly1,&x1,&y1); CString sTemp; sTemp=m_text; if(m_DnyAttr.m_ValueA.m_Used) { pmc_value_t d; set_value_type(d.Flags, dt_real4); pmc_type_cast(&m_DnyAttr.m_ValueA.m_TagValue, &d); sTemp.Format(m_DnyAttr.m_ValueA.m_Format, d.Value.flt); } else if(m_DnyAttr.m_ValueD.m_Used) { if(m_DnyAttr.m_ValueD.action_proc && m_DnyAttr.m_ValueD.action_proc != (void*)-1) { char * s; s = ((char * (WINAPI*)())m_DnyAttr.m_ValueD.action_proc)(); sTemp = s; free_buffer(s); } else { if(m_DnyAttr.m_ValueD.m_TagValue.Value.iValue) { sTemp=m_DnyAttr.m_ValueD.m_OnMsg; } else { sTemp=m_DnyAttr.m_ValueD.m_OffMsg; } } } pDC->TextOut(x1,y1,sTemp); pDC->SelectObject(pOldFont); }
uniform_node& set_value_type(void) { set_value_type(get_data_type_v<T>); return *this; }
/* gather data from UI to internal representation */ bool TframTag::ValidateView() { PTAG_NAME name; PRTK_TAG tag; name = &m_TagName; tag = &m_Tag; try{ #undef cc #define cc(name) tag->s.Flags |= (chk##name->Checked ? TF_##name : 0); if( edtTagName->Text.Length() >sizeof(TAG_KEY) || !edtTagName->Text.Length() ){ m_Hint = "变量名不正确"; throw(-1); } if( !is_valid_name(edtTagName->Text.c_str()) ){ m_Hint = "变量名只能包含字母、数字和下划线"; throw(-3); } if(edtTagName->Text.Length() > sizeof(TAG_KEY)){ m_Hint = AnsiString("错误: 标签名不能超过 ") + IntToStr(sizeof(TAG_KEY)) + " 个字节"; throw(-3); } name->sname.tag = CTagName(edtTagName->Text.c_str()); tag->s.Device = CDeviceName(cmbDevice->Text.c_str()); tag->key = name->sname.tag; if(edtCName->Text.Length() > sizeof(tag->s.Description)){ m_Hint = "中文名太长(最长 " + AnsiString(sizeof(tag->s.Description)/2) + " 字)"; throw(-4); } strncpy(tag->s.Description, edtCName->Text.c_str(), sizeof(tag->s.Description)); tag->s.Description[sizeof(tag->s.Description) - 1] = 0; if(edtAddr->Text.Length() > sizeof(tag->s.Address)){ m_Hint = "地址太长(最长 " + AnsiString(sizeof(tag->s.Address)/2) + " 字)"; throw(-5); } strncpy(tag->s.Address, edtAddr->Text.c_str(), sizeof(tag->s.Address)); tag->s.Address[sizeof(tag->s.Address) - 1] = 0; tag->s.Flags = 0; switch(cmbType->ItemIndex){ case 0: set_value_type(tag->s.Flags, dt_bool); break; case 1: set_value_type(tag->s.Flags, dt_real4); break; case 2: set_value_type(tag->s.Flags, dt_real8); break; case 3: set_value_type(tag->s.Flags, dt_int8); break; case 4: set_value_type(tag->s.Flags, dt_int16); break; case 5: set_value_type(tag->s.Flags, dt_int32); break; case 6: set_value_type(tag->s.Flags, dt_int64); break; case 7: set_value_type(tag->s.Flags, dt_uint8); break; case 8: set_value_type(tag->s.Flags, dt_uint16); break; case 9: set_value_type(tag->s.Flags, dt_uint32); break; case 10: set_value_type(tag->s.Flags, dt_uint64); break; case 11: set_value_type(tag->s.Flags, dt_date); break; case 12: m_Hint = "不支持这个数据类型."; throw(-41); break; } cc(SaveToHistory); cc(Step); // collecting common analog attributes switch(get_value_type(tag->s.Flags)){ case dt_int8: case dt_int16: case dt_int32: case dt_int64: case dt_uint8: case dt_uint16: case dt_uint32: case dt_uint64: case dt_real4: case dt_real8: case dt_date: cc(HiHi); cc(Lo); cc(Hi); cc(LoLo); cc(Rate); strncpy( tag->s.AnalogMsg.EU, edtEU->Text.c_str(), sizeof(tag->s.AnalogMsg.EU) ); tag->s.AnalogMsg.EU[sizeof(tag->s.AnalogMsg.EU) - 1] = 0; break; case dt_bool: cc(On2Off); cc(Off2On); strncpy( tag->s.SwitchMsg.OnMsg, edtOnMessage->Text.c_str(), sizeof(tag->s.SwitchMsg.OnMsg) ); tag->s.SwitchMsg.OnMsg[sizeof(tag->s.SwitchMsg.OnMsg) - 1] = 0; strncpy( tag->s.SwitchMsg.OffMsg, edtOffMessage->Text.c_str(), sizeof(tag->s.SwitchMsg.OffMsg) ); tag->s.SwitchMsg.OffMsg[sizeof(tag->s.SwitchMsg.OffMsg) - 1] = 0; break; } #define get(msg, name, ignore_on_condition, _default_value)\ m_Hint = msg;\ if( !edt##name->Text.Length() ){\ if(ignore_on_condition){\ tag->s.flt##name = _default_value;\ }else{\ throw(-1);\ }\ }else{\ tag->s.flt##name = edt##name->Text.ToDouble();\ } #pragma warn -ccc #pragma warn -rch switch(get_value_type(tag->s.Flags)){ case dt_real4: case dt_real8: get("高高值不正确", HiHi, !chkHiHi->Checked, 0); get("低低值不正确", LoLo, !chkLoLo->Checked, 0); get("低值不正确", Lo, !chkLo->Checked, 0); get("高值不正确", Hi, !chkHi->Checked, 0); get("报警死区值不正确", AlarmDeadband, !(tag->s.Flags & 0xffffff00), 0); get("最大值不正确", MaxValue, false, 0); get("最小值不正确", MinValue, false, 0); get("速率报警阈值不正确", Rate, !chkRate->Checked, 0.1); break; case dt_int8: case dt_int16: case dt_int32: case dt_int64: case dt_uint8: case dt_uint16: case dt_uint32: case dt_uint64: get("速率报警阈值不正确", Rate, !chkRate->Checked, 0.1); #undef get #define get(msg, attrName, uiName, ignore_on_condition, _default_value)\ m_Hint = msg;\ if( !edt##uiName->Text.Length() ){\ if(ignore_on_condition){\ tag->s.##attrName = _default_value;\ }else{\ throw(-1);\ }\ }else{\ tag->s.attrName = edt##uiName->Text.ToDouble();\ } get("高高值不正确", u_hihi.i, HiHi, !chkHiHi->Checked, 0); get("低低值不正确", u_lolo.i, LoLo, !chkLoLo->Checked, 0); get("低值不正确", u_lo.i, Lo, !chkLo->Checked, 0); get("高值不正确", u_hi.i, Hi, !chkHi->Checked, 0); get("报警死区值不正确", u_deadband.i, AlarmDeadband, !(tag->s.Flags & 0xffffff00), 0); get("最大值不正确", u_max.i, MaxValue, false, 0); get("最小值不正确", u_min.i, MinValue, false, 0); break; } #pragma warn .ccc #pragma warn .rch if(get_value_type(tag->s.Flags) == dt_bool){ tag->s.AlarmRank = edtAlarmRank2->Text.ToInt(); }else{ tag->s.AlarmRank = edtAlarmRank->Text.ToInt(); } tag->s.Compressing = Compress_Const; tag->s.CompDev = StrToFloat(edtCompDev->Text); tag->s.CompMax = StrToInt(edtCompMax->Text); }catch(...){ return false; } m_Hint = "更新成功"; return true; }