📄 labviewimport.c
字号:
return true;
return false;
}
/////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
// set strName, strType, and nID starting search in strSource begining from nStart. Set nStart at the end to prepare for next search.
///DVT later handle <CONTENT>...</CONTENT> inside control which is inaccesible by lv.GetControlValue()
/*
<CONTROL ID=83 type="Cluster" name="Parameters">
...
<CONTENT>
<CONTROL ID=80 type="Numeric" name="Offset (volts)">
...
</CONTROL>
<CONTROL ID=80 type="Numeric" name="Number of Bursts">
...
</CONTROL>
...
</CONTENT>
<CONTROL ID=91 type="Path" name="file path (dialog if empty)">
...
<PARTS>
<PART ID=8019 order=0 type="Browse Button">
<CONTROL ID=79 type="Boolean" >
...
</CONTROL>
</PART>
</PARTS>
</CONTROL>
*/
//parser for LabViuew's ExportVIStrings generated tagged files that look like some sort of SGML
bool AddOneControl(const string &strRead, int &nStart, vector<int> &vIDs, vector<string> &vTypes, vector<string> &vNames )
{
///DVT later handle <CONTENT>...</CONTENT> inside control which is inaccesible by lv.GetControlValue()
//handle only top level <CONTROL... patern
/////////////////////////////////////////////////////////////
//<CONTROL ID=..."> sequence <CONTROL ID=94 type="Waveform Chart" name="trend1">
nStart = strRead.Find( LV_CONTROL_START, nStart );
RETURN_IF_NOT_FOUND(nStart, false);
nStart += LV_CONTROL_START_LENGTH;
int nEnd = strRead.Find( LV_CONTROL_START_END, nStart );
RETURN_IF_NOT_FOUND(nEnd, false);
//save position for return
int nStartReturn = nEnd + LV_CONTROL_START_END_LENGTH;
string strName = strRead.Mid( nStart, nEnd - nStart );
LV_DEBUG_STR("whole CONTROL:\t" + strName);
//ID
int nID;
sscanf( strName, "%d", &nID );
//nID = atol(strName); //mess
LV_DEBUG_INT("ID=",nID);
//type
nStart = strName.Find( LV_CONTROL_TYPE );
RETURN_IF_NOT_FOUND(nStart, false);
nStart += LV_CONTROL_TYPE_LENGTH;
nEnd = strName.Find( LV_CONTROL_NAME, nStart );
RETURN_IF_NOT_FOUND(nEnd, false);
string strType = strName.Mid( nStart, nEnd - 1 - nStart ); //-1 is to remove closing " before | name=|
LV_DEBUG_STR("type=" + strType);
//name
nStart = nEnd + LV_CONTROL_NAME_LENGTH;
strName = strName.Mid( nStart );
LV_DEBUG_STR("name=" + strName);
if ( -1 == strName.Find( LV_STR_EOL ) )
{
vIDs.Add(nID);
vTypes.Add(strType);
vNames.Add(strName);
}
nStart = nStartReturn;
LV_DEBUG_INT("END nStart\t\t",nStart);
//find next starting position (next <CONTROL on the same top level)
//DVT HANDLE_CONTENT
int nCount(0);
int nNextControl(-1);
do
{
if ( nCount++ > 50 ) //if file is corrupted
break;
nNextControl = strRead.Find( LV_CONTROL_START, nStart );
if ( -1 == nNextControl ) break;
nEnd = strRead.Find( LV_CONTROL_END, nStart );
if ( -1 == nEnd ) break;
nStart = nEnd;
} while (nNextControl <= nEnd ); //there is another <CONTROL... before
return true;
/*
//just ignore for now
int nNextControl = strRead.Find( LV_CONTROL_START, nStart );
RETURN_IF_NOT_FOUND(nNextControl, true); //no controls to the end of the file
nEnd = strRead.Find( LV_CONTENT, nStart );
RETURN_IF_NOT_FOUND(nEnd, true); //no sub <CONTENT>
if ( nNextControl > nEnd )
{
//there are sub controls, inside claster, array, or whatnot
//go past the </CONTENT>, skip inside for now
nEnd = strRead.Find( LV_CONTENT_END, nEnd );
RETURN_IF_NOT_FOUND(nEnd, true);
nStart = nEnd + LV_CONTENT_END_LENGTH;
LV_DEBUG_INT("END nStart\t\t",nStart);
}
*/
//end HANDLE_CONTENT
}
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
//Helper for ExtractLabView controls
bool ReadFileInString( LPCSTR lpcszPathName, string &strRead )
{
file fil;
if( fil.Open(lpcszPathName, file::modeRead) )
{
// Get file size
fil.SeekToEnd();
LONG l = fil.GetPosition();
fil.SeekToBegin();
// Get buffer
LPSTR lpstr = strRead.GetBuffer(l + 1);
LPVOID lpVoid = lpstr;
if( lpstr )
{
// Read whole file into buffer
fil.Read(lpVoid, l);
strRead.ReleaseBuffer();
}
fil.Close();
return true;
}
return false;
}
// end Helper for ExtractLabView controls
bool ExtractLabViewControls(LPCSTR lpcszPathName, vector<int> &vIDs, vector<string> &vTypes, vector<string> &vNames, string &strVIName)
{
vIDs.SetSize(0);
vTypes.SetSize(0); //fixed
vNames.SetSize(0);
string strRead;
if ( !ReadFileInString( lpcszPathName, strRead ) )
return false;
int nStart = 0;
//header, VI name sequence <VI syntaxVersion=6 LVversion=6108004 revision=20 name="Frequency Response.vi">
nStart = strRead.Find( LV_HEADER_START );
RETURN_IF_NOT_FOUND(nStart, false);
nStart += LV_HEADER_START_LENGTH;
int nEnd = strRead.Find( LV_CONTROL_START_END, nStart );
RETURN_IF_NOT_FOUND(nEnd, false);
nStart = strRead.Find( LV_CONTROL_NAME, nStart );
nStart += LV_CONTROL_NAME_LENGTH;
strVIName = strRead.Mid( nStart, nEnd - nStart );
LV_DEBUG_STR("VI name:----" + strVIName + "----");
nStart = nEnd + LV_CONTROL_START_END_LENGTH;
LV_DEBUG_INT("START nStart\t",nStart);
while ( AddOneControl(strRead, nStart, vIDs, vTypes, vNames ) );
LV_DEBUG_INT("vectorSize:", vIDs.GetSize());
return true;
}
bool GetOneControlValueAndType( const Object &viOne, const string &strControlName, string &strDisplay, USHORT &nVarType )
{
//_VARIANT val = viOne.GetControlValue( strControlName );
_VARIANT val;
try
{
val = viOne.GetControlValue( strControlName );
}
catch(int nErr)
{
return false;
}
USHORT nvt = val.vt;
nVarType = nvt;
int nLobyte = nvt & 0x00FF;
//#
LV_DEBUG_printf( "val.vt: %04x, lobyte %04x\n", nvt, nLobyte );
strDisplay = LV_STR_NOT_HANDLED;
if ( VT_ARRAY & nvt )
{
strDisplay = LV_STR_VECTOR;
WORD wSimpleType = nvt & VT_TYPEMASK;
LV_DEBUG_printf( "%s: wSimpleType: %04x\n", strDisplay, wSimpleType );
if ( VT_VARIANT == wSimpleType )
{
int nNumSubVariants = val.GetSize();
int nNumDimensions = val.GetNumDimensions();
if ( (1 <= nNumDimensions) && (1 <= nNumSubVariants) )
{
_VARIANT vVars;
//vector<_VARIANT> vVars;
//vVars.SetSize( nNumSubVariants );
vector<int> vnSizes;
vnSizes.SetSize( nNumSubVariants );
for( int i = 0; i < nNumSubVariants; i++ )
{
//if ( !val.GetSubVariant(0, vVars[i]) )
if ( !val.GetSubVariant(i, vVars) )
{
/// DVT 4/11/03 REMOVE_TREE_UTILS_FROM_LVDLG
//out_str("Error geting sub-variant in array");
LV_DEBUG_STR("Error geting sub-variant in array");
/// end REMOVE_TREE_UTILS_FROM_LVDLG
return false;
}
//if ( VT_ARRAY & vVars[i].vt )
// vnSizes[i] = vVars[i].GetSize();
if ( VT_ARRAY & vVars.vt )
vnSizes[i] = vVars.GetSize();
}
/// DVT 4/11/03 REMOVE_TREE_UTILS_FROM_LVDLG
//strDisplay.Format( "Array of %d vectors, %d long", nNumSubVariants, vnSizes[0] );
strDisplay.Format( LV_FMT_STR_ARRAY_VEC_LONG, nNumSubVariants, vnSizes[0] );
//out_str(strDisplay);
LV_DEBUG_STR(strDisplay);
/// end REMOVE_TREE_UTILS_FROM_LVDLG
}
}
}
else
{
switch (nvt)
{
case VT_BOOL:
short nVar = val;
strDisplay = ( VARIANT_TRUE == nVar )? DISPLAY_VARIANT_TRUE: DISPLAY_VARIANT_FALSE;
break;
case VT_I2:
case VT_I4:
case VT_R4:
case VT_R8:
case VT_BSTR:
case VT_I1:
case VT_UI1:
case VT_UI4:
case VT_I8:
case VT_UI8:
case VT_INT:
case VT_UINT:
strDisplay = val;
break;
default:
break;
}
}
return true;
}
//fill values and variant types for controls
bool ReadVIControlsValues( const string &strVI, const vector<int> &vIDs, const vector<string> &vTypes, const vector<string> &vNames, vector<string> &vValues, vector<USHORT> &vVarTypes )
{
vValues.SetSize(0);
vVarTypes.SetSize(0);
UINT nTotalNumber = vNames.GetSize();
Object viOne;
//if ( !GetVIObjectByName( lvapp, strVI, viOne ) )
if ( !GetVIObjectByName( strVI, viOne ) )
return false;
//Front panel VI is already open when no Callers are identified
//maybe here also for sub-vi to be able to read controls??
// - not needed, crashes where due to inaccessible controls <CONTENT>...</CONTENT> or controls with odd names "...<CR>\n\r..." multilineers
//that is handled (by ignoring such cases for now) in parser ( AddOneControl() )
/*
bool bAlreadyOpen = false;
if ( !viOne.FPWinOpen )
viOne.FPWinOpen = true;
else
bAlreadyOpen = true;
*/
//_VARIANT val;
for (int i = 0; i < nTotalNumber; i++)
{
USHORT nVarType = VT_EMPTY;
string strControlName = vNames[i];
strControlName.TrimLeft();
strControlName.TrimRight();
if ( strControlName.IsEmpty() )
{
vValues.Add( LV_STR_CONTROL_VAL_UNKNOWN );
vVarTypes.Add( nVarType );
continue;
}
string strDisplay;
GetOneControlValueAndType( viOne, strControlName, strDisplay, nVarType );
vValues.Add( strDisplay );
vVarTypes.Add( nVarType );
}
/*
//not needed
if ( !bAlreadyOpen ) //do not change the state VI entered this function
viOne.FPWinOpen = false;
*/
return true;
}
//exported function: given VI name strVI, fill vectors with vIDs, vTypes, and vNames of controls
bool GetVIControls( string &strVI, vector<int> &vIDs, vector<string> &vTypes, vector<string> &vNames, vector<string> &vValues, vector<USHORT> &vVarTypes )
{
if( !CheckLabView() )
return false;
string strExportPathName;
if ( !ExportVIControls( strVI, strExportPathName ) )
return false;
string strVIName;
if ( !ExtractLabViewControls(strExportPathName, vIDs, vTypes, vNames, strVIName) )
return false;
if ( !ReadVIControlsValues( strVI, vIDs, vTypes, vNames, vValues, vVarTypes ) )
return false;
DeleteFile( strExportPathName );
/*
//have to strip possible path from strVI first!!!
//e.g. G:\Program Files\National Instruments\LabVIEW 6.1\examples\comm\hiq\CookieFactoryReport.vi
if ( strVI != strVIName ) //compare VI name with name from inside:<VI syntaxVersion=... name="Frequency Response.vi">
{
ASSERT(FALSE); //not expected - file corrupted?
return false;
}
*/
return true;
}
const TreeNode GetTree() { return m_trVI; }
///VI hierarchy
//generate the hierarchy tree for all VI's in list
//this one used by Dlg class LabViewImport:
bool BuildCallerTree( vector<string> &vsALLVIs )
{
//trLV = NULL;
m_trVI.Reset();
TreeNode trBranch0 = m_trVI.AddNode(LV_TREE_ROOT_NODE);
trBranch0.SetAttribute(LV_TREE_NODE_ATTRIBUTE_LABEL, LV_TREE_ROOT_NODE_LABEL);
UINT nTotalNumber = vsALLVIs.GetSize();
for (int jj = 0; jj < nTotalNumber; jj++)
{
vector<string> vsCallersVIs;
FindVIsCollers( vsALLVIs[jj], vsCallersVIs );
if( 0 >= vsCallersVIs.GetSize() )
{
LV_DEBUG_STR( vsALLVIs[jj] + "-No Callers\n");
//add as root node
TreeNode trBranch = trBranch0.AddNode( LV_STR_NODE_NAME );
trBranch.SetAttribute(LV_TREE_NODE_ATTRIBUTE_LABEL, vsALLVIs[jj]);
//Bad design bellow!
Object viOne;
if ( !GetVIObjectByName( vsALLVIs[jj], viOne ) )
return false;
//Open front panel (if read from file have to, to be able to query sub vi's and its controls)
//opening sub-vi's doesn't seem to be necessary to read its controls
try
{
if ( !viOne.FPWinOpen )
viOne.FPWinOpen = true;
}
catch(int nErr)
{
return false;
}
//end Bad design bellow!
FindAllVIsCollees( trBranch, vsALLVIs[jj] );
}
}
//m_trVI;
return true;
}
bool FindVIsCollers( string &strVI, vector<string> &vsCallersVIs )
{
Object viOne;
if ( !GetVIObjectByName( strVI, viOne ) )
return false;
///////////////////////////////////////////////////
////Callers
_VARIANT varCallersVIs;
try
{
varCallersVIs = viOne.Callers;
}
catch(int nErr)
{
return false;
}
if( 0 >= varCallersVIs.GetSize() )
{
LV_DEBUG_STR( strVI + "-No Callers\n"); //add as root node
}
vsCallersVIs = varCallersVIs;
return true;
}
//recursive function to make tree out of callees
bool FindAllVIsCollees( TreeNode &trBranch, string &strVI )
{
vector<string> vsCalleesVIs;
if ( !FindVIsCollees( strVI, vsCalleesVIs ) )
return false;
UINT nTotalNumber = vsCalleesVIs.GetSize();
for (int jj = 0; jj < nTotalNumber; jj++)
{
//add as node
/*
string strTMP;
strTMP = vsCalleesVIs[jj];
strTMP.Replace(" ",'_');
strTMP.Replace("()",'-'); //this is too much, should do something about names
TreeNode trBranchR = trBranch.AddNode( strTMP );
*/
//TreeNode trBranchR = trBranch.AddNode( s_strNodeName );
TreeNode trBranchR = trBranch.AddNode( LV_STR_NODE_NAME );
trBranchR.SetAttribute(LV_TREE_NODE_ATTRIBUTE_LABEL, vsCalleesVIs[jj]);
//recursive call
FindAllVIsCollees( trBranchR, vsCalleesVIs[jj] );
}
return true;
}
//helper for FindAllVIsCollees, find the first level of callees for given VI
bool FindVIsCollees( string &strVI, vector<string> &vsCalleesVIs )
{
Object viOne;
if ( !GetVIObjectByName( strVI, viOne ) )
return false;
///////////////////////////////////////////////////
////Callees
_VARIANT varCalleesVIs;
try
{
varCalleesVIs = viOne.Callees;
}
catch(int nErr)
{
return false;
}
if( 0 >= varCalleesVIs.GetSize() )
{
LV_DEBUG_STR( strVI + "-No Callees\n");
//final node
}
vsCalleesVIs = varCalleesVIs;
///////////////////////////////////////////////////
return true;
}
///end VI hierarchy
// file open dialog
bool LabViewLLBFileImport( vector<string> &vsALLVIs )
{
//string strFilename = GetOpenBox( "[LabView (*.llb)] *.llb" ); //don't know how to see inside the library
string strFilename = GetOpenBox( LV_FILE_OPEN_STR_VI );
if( strFilename.GetLength() > 0 && strFilename.IsFile() )
{
vsALLVIs.SetSize( 0 );
vsALLVIs.Add( strFilename );
return true;
}
return false;
}
bool Build( bool bFileOpenIfNoVIs = true )
{
vector<string> vsALLVIs;
if ( !GetLVExportedVIs( vsALLVIs ) )
{
if(!CheckLabView( false )) //Is LV connected? do not try again
return false;
LV_DEBUG_STR("No VI's in memory!");
if ( !bFileOpenIfNoVIs )
return false;
// dir: F:\Program Files\National Instruments\LabVIEW 6.1\examples\comm\hiq
if ( !LabViewLLBFileImport( vsALLVIs ) ) //reed from file
return false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -