You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2528 lines
91 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "StdAfx.h"
#include "RecipeMgr.h"
#include "LogMgr.h"
#include "FileMgr.h"
#include "CStringFuc.h"
#include "WaferRecipeDataMgr.h"
#include "MsgBox.h"
#include "DlgChildRecipe.h"
#include "CommonParaMgr.h"
#include "GlobalFunction.h"
#include "Laser.h"
#include "ProgramLaserTuiHuo.h"
#include "RecipeMgr.h"
#include "DlgRecipeCtrl.h"
#include "MyXmlMgr.h"
#include "ExceptionMsg.h"
#include "AuthorityMgr.h"
#include "CommonParaMgr.h"
#include "Propertie.h"
#include "PropertieMgr.h"
#define RECIPE_FILE_PATH _T("\\RecipePar\\")
#define RECIPE_GROUP_NAME_FILE _T("\\font\\GroupNameList")//组名列表文件
#define SECS_RECIPE_FILE_PATH _T("\\SecsRecipe")
#define RECIPE_GROUP_CNT 10 //recipe 分组的数量
#define ONE_GROUP_PAR_CNT 50 //一个recipe 分组参数的数量
#define NEW_RECIPE_FILE_PATH _T("\\Recipe\\")
#define RECIPE_FILE_SUFFIX "rcp" //recipe 文件使用的后缀
#define XML_ITEM_PAR_TYPE "ParType"
#define XML_ITEM_PAR_VAL "ParVal"
#define RCP_PAR_TYPE_DOUBLE "Double"
#define RCP_PAR_TYPE_STRING "String"
#define RCP_PAR_TYPE_BOOL "Bool"
#define RCP_PAR_TYPE_INT "Int"
#define NULL_RECIPE_NAME "" //无效的recipe 名称
#define PARA_MODIFY_DATA_PATH _T("\\ParaModifyRecord\\")
#define OFFSET_TAB_FILE_PATH "\\OffsetTable\\TableFile\\"
#define MFC_CTRLSCAL _T("\\CommPar\\MFC_CtrlScal.bin") // MFC流量控制系数表
#if 1
CSubRecipe::CSubRecipe(void)
{
m_bUseSubRecipe = true;//生产中是否使用
ReadMFCCtrlScalFile();
//初始化recipe 参数容器
IntiRecipeParVec();
}
//从指定文件中读取Mfc系数
void CSubRecipe::ReadMFCCtrlScalFile()
{
CFileMgr FileMgr;
CString FilePath;
vector<vector<CString>> StrVec;
FileMgr.GetFullFilePath(FilePath, MFC_CTRLSCAL);
FileMgr.ReadFileToStrVec(FilePath, StrVec);
int StrSize = StrVec.size();
for (int i = 0; i < StrSize; i++)
{
if (2 == StrVec[i].size())
{
MFCScalStrVec.push_back(StrVec[i]);
}
}
return;
}
//初始化recipe 参数容器(中间可以添加新的参数)
void CSubRecipe::IntiRecipeParVec()
{
//可以被编辑的参数要在前面定义
{
CRecipeParameter RecipePar;
RecipePar.m_ParName = RECIPE_PAR_NAME_LASER_FRE;
RecipePar.m_ParShowName = "Laser1 Frequency";
RecipePar.m_ParUnit = "Hz";//参数的单位,用于显示
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
RecipePar.m_ParDoubleVal = 1000;//默认值
RecipePar.m_DoubleMinVal = 0;
RecipePar.m_DoubleMaxVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MAX_LASER_FRE);
RecipePar.m_DetailInfo = "激光1频率一秒内激光脉冲个数";
m_RecipeParVec.push_back(RecipePar);
}
{
CRecipeParameter RecipePar;
RecipePar.m_ParName = RECIPE_PAR_NAME_LASER2_FRE;
RecipePar.m_ParShowName = "Laser2 Frequency";
RecipePar.m_ParUnit = "Hz";//参数的单位,用于显示
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
RecipePar.m_ParDoubleVal = 1000;//默认值
RecipePar.m_DoubleMinVal = 0;
RecipePar.m_DoubleMaxVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MAX_LASER_FRE);
RecipePar.m_DetailInfo = "激光2频率一秒内激光脉冲个数";
m_RecipeParVec.push_back(RecipePar);
}
{
CRecipeParameter RecipePar;
RecipePar.m_ParName = RECIPE_PAR_NAME_PRF2_DELAY;
RecipePar.m_ParShowName = "Two Pulse Delay";
RecipePar.m_ParUnit = "ns";//参数的单位,用于显示
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
RecipePar.m_ParDoubleVal = 0;
RecipePar.m_DoubleMinVal = 0;
RecipePar.m_DoubleMaxVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MAX_LASER_PULSE_DELAY);
RecipePar.m_DetailInfo = "双脉冲延时:激光器脉冲延时时间";
m_RecipeParVec.push_back(RecipePar);
}
{
CRecipeParameter RecipePar;
RecipePar.m_ParName = RECIPE_PAR_NAME_LASER_CURR_1;
RecipePar.m_ParShowName = "Laser1 Current";
RecipePar.m_ParUnit = "A";//参数的单位,用于显示
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
RecipePar.m_ParDoubleVal = 0;
RecipePar.m_DoubleMinVal = 0;
RecipePar.m_DoubleMaxVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MAX_LASER_CURR_1);
RecipePar.m_DetailInfo = "Laser1电流值:工艺设置电流值";
m_RecipeParVec.push_back(RecipePar);
}
{
CRecipeParameter RecipePar;
RecipePar.m_ParName = RECIPE_PAR_NAME_LASER_CURR_2;
RecipePar.m_ParShowName = "Laser2 Current";
RecipePar.m_ParUnit = "A";//参数的单位,用于显示
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
RecipePar.m_ParDoubleVal = 0;
RecipePar.m_DoubleMinVal = 0;
RecipePar.m_DoubleMaxVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MAX_LASER_CURR_2);
RecipePar.m_DetailInfo = "Laser2电流值:工艺设置电流值";
m_RecipeParVec.push_back(RecipePar);
}
{
CRecipeParameter RecipePar;
RecipePar.m_ParName = RECIPE_PAR_NAME_LASER_EDI_1;
RecipePar.m_ParShowName = "Laser1 Edi";
RecipePar.m_ParUnit = "J/cm2";//参数的单位,用于显示
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
RecipePar.m_ParDoubleVal = 0;
RecipePar.m_DoubleMinVal = 0;
RecipePar.m_DoubleMaxVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MAX_LASER_EDI_1);
RecipePar.m_DetailInfo = "Laser1目标功率密度 最终的edi还要加上Laser Edi Offset和补偿表中的Laser Edi Offset值";
m_RecipeParVec.push_back(RecipePar);
}
{
CRecipeParameter RecipePar;
RecipePar.m_ParName = RECIPE_PAR_NAME_LASER_EDI_2;
RecipePar.m_ParShowName = "Laser2 Edi";
RecipePar.m_ParUnit = "J/cm2";//参数的单位,用于显示
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
RecipePar.m_ParDoubleVal = 0;
RecipePar.m_DoubleMinVal = 0;
RecipePar.m_DoubleMaxVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MAX_LASER_EDI_2);
RecipePar.m_DetailInfo = "Laser2目标功率密度 最终的edi还要加上Laser Edi Offset和补偿表中的Laser Edi Offset值";
m_RecipeParVec.push_back(RecipePar);
}
{
CRecipeParameter RecipePar;
RecipePar.m_ParName = RECIPE_PAR_NAME_LASER_EDI_OFFSET_1;
RecipePar.m_ParShowName = "Laser1 Edi Offset";
RecipePar.m_ParUnit = "J/cm2";//参数的单位,用于显示
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
RecipePar.m_ParDoubleVal = 0;
RecipePar.m_DoubleMinVal = -2;
RecipePar.m_DoubleMaxVal = 2;
RecipePar.m_DetailInfo = "Laser1目标功率密度补偿";
m_RecipeParVec.push_back(RecipePar);
}
{
CRecipeParameter RecipePar;
RecipePar.m_ParName = RECIPE_PAR_NAME_LASER_EDI_OFFSET_2;
RecipePar.m_ParShowName = "Laser2 Edi Offset";
RecipePar.m_ParUnit = "J/cm2";//参数的单位,用于显示
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
RecipePar.m_ParDoubleVal = 0;
RecipePar.m_DoubleMinVal = -2;
RecipePar.m_DoubleMaxVal = 2;
RecipePar.m_DetailInfo = "Laser2目标功率密度补偿";
m_RecipeParVec.push_back(RecipePar);
}
{
CRecipeParameter RecipePar;
RecipePar.m_ParName = RECIPE_PAR_NAME_EDI_CHECK_SCOPE;
RecipePar.m_ParShowName = "Edi Check Scope";
RecipePar.m_ParUnit = "J/cm2";//参数的单位,用于显示
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
RecipePar.m_ParDoubleVal = 0;
RecipePar.m_DoubleMinVal = 0;
RecipePar.m_DoubleMaxVal = 5;
RecipePar.m_DetailInfo = "功率密度复检卡控范围等于0表示不进行复检大于表示要进行复检且复检调整后的功率密度在这个误差范围之内";
m_RecipeParVec.push_back(RecipePar);
}
{
CRecipeParameter RecipePar;
RecipePar.m_ParName = RECIPE_PAR_NAME_OVERLAP_RATIO_X;
RecipePar.m_ParShowName = "Overlap Rate X";
RecipePar.m_ParUnit = "%";//参数的单位,用于显示
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
RecipePar.m_ParDoubleVal = 0;
RecipePar.m_DoubleMinVal = 0;
RecipePar.m_DoubleMaxVal = 99;
RecipePar.m_DetailInfo = "X方向光斑重叠率会影响X方向扫描速度的计算值";
m_RecipeParVec.push_back(RecipePar);
}
{
CRecipeParameter RecipePar;
RecipePar.m_ParName = RECIPE_PAR_NAME_OVERLAP_RATIO_Y;
RecipePar.m_ParShowName = "Overlap Rate Y";
RecipePar.m_ParUnit = "%";//参数的单位,用于显示
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
RecipePar.m_ParDoubleVal = 0;
RecipePar.m_DoubleMinVal = 0;
RecipePar.m_DoubleMaxVal = 99;
RecipePar.m_DetailInfo = "Y方向光斑重叠率会影响Y方向移动间隔";
m_RecipeParVec.push_back(RecipePar);
}
{
CRecipeParameter RecipePar;
RecipePar.m_ParName = RECIPE_PAR_NAME_FOCUS_ADJUST_VAL;
RecipePar.m_ParShowName = "Foucs Adjust Val";
RecipePar.m_ParUnit = "mm";//参数的单位,用于显示
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
RecipePar.m_ParDoubleVal = 0;
RecipePar.m_DoubleMinVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MIN_FOCUS_ADJUST);
RecipePar.m_DoubleMaxVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MAX_FOCUS_ADJUST);
RecipePar.m_DetailInfo = "Z轴焦距微调值用于工艺前Z轴在目前设置的激光焦距点上下进行微调";
m_RecipeParVec.push_back(RecipePar);
}
{
CRecipeParameter RecipePar;
RecipePar.m_ParName = RECIPE_PAR_NAME_FIX_SCAN_SPEED;
RecipePar.m_ParShowName = "Fix Scan Speed";
RecipePar.m_ParUnit = "mm/s";//参数的单位,用于显示
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
RecipePar.m_ParDoubleVal = 0;
RecipePar.m_DoubleMinVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MIN_SCAN_SPEED);
RecipePar.m_DoubleMaxVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MAX_SCAN_SPEED);
RecipePar.m_DetailInfo = "固定扫描速度等于0时无效大于0时X方向光斑重叠率无效工艺过程中将使用这个速度值作为X方向的扫描速度";
m_RecipeParVec.push_back(RecipePar);
}
{
CRecipeParameter RecipePar;
RecipePar.m_ParName = RECIPE_PAR_NAME_FIX_SCAN_LINE_GAP;
RecipePar.m_ParShowName = "Fix Scan Line Gap";
RecipePar.m_ParUnit = "mm";//参数的单位,用于显示
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
RecipePar.m_ParDoubleVal = 0;
RecipePar.m_DoubleMinVal = 0;
RecipePar.m_DoubleMaxVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MAX_FIX_SCAN_LINE_GAP);
RecipePar.m_DetailInfo = "固定扫描间隔等于0时无效大于0时Y方向光斑重叠率无效工艺过程中将使用这个值作为Y方向的扫描移动间隔";
m_RecipeParVec.push_back(RecipePar);
}
{
CRecipeParameter RecipePar;
RecipePar.m_ParName = RECIPE_PAR_NAME_SCAN_LINE_START_IDX;
RecipePar.m_ParShowName = "Start Scan Line Idx";
//RecipePar.m_ParUnit = "mm";//参数的单位,用于显示
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
RecipePar.m_ParDoubleVal = 0;
RecipePar.m_DoubleMinVal = 0;
RecipePar.m_DoubleMaxVal = 100000;
RecipePar.m_DetailInfo = "扫描线的起始索引值表示从第几根线开始扫描用于补打wafer";
m_RecipeParVec.push_back(RecipePar);
}
{
CRecipeParameter RecipePar;
RecipePar.m_ParName = RECIPE_PAR_NAME_ALIGNER_ANG;
RecipePar.m_ParShowName = "Wafer Aligner Angle";
RecipePar.m_ParUnit = "degree";//参数的单位,用于显示
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
RecipePar.m_ParDoubleVal = 270;
RecipePar.m_DoubleMinVal = 0;
RecipePar.m_DoubleMaxVal = 360;
RecipePar.m_DetailInfo = "wafer准直角度用于控制wafer放到stage上的notch方向多subrcp的情况第一个sub的值为有效值";
m_RecipeParVec.push_back(RecipePar);
}
{
int StrSize = MFCScalStrVec.size();
double m_MinVal = 0.0;
double m_MaxVal = 0.0;
if (StrSize > 0)
{
m_MinVal = CStringToDouble(MFCScalStrVec[0][1]);
m_MaxVal = CStringToDouble(MFCScalStrVec[StrSize - 1][1]);
}
CRecipeParameter RecipePar;
RecipePar.m_ParName = RECIPE_PAR_NAME_N2_VAL;
RecipePar.m_ParShowName = "N2 Val";
RecipePar.m_ParUnit = "L";//参数的单位,用于显示
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
RecipePar.m_ParDoubleVal = m_MinVal;
RecipePar.m_DoubleMinVal = m_MinVal;
RecipePar.m_DoubleMaxVal = m_MaxVal;
RecipePar.m_DetailInfo = "MFC流量控制值MFC控制N2流量值";
m_RecipeParVec.push_back(RecipePar);
}
//下拉框参数------------------------------------------------
{
CRecipeParameter RecipePar;
RecipePar.m_ParName = RECIPE_PAR_NAME_SCAN_AREA;
RecipePar.m_ParShowName = "Scan Area";
RecipePar.m_ParType = _RecipeParType_CString;//参数的类型
RecipePar.m_DetailInfo = "扫描区域文件名称:用于指定扫描区域的图形文件,确定扫描的范围";
m_RecipeParVec.push_back(RecipePar);
}
{
CRecipeParameter RecipePar;
RecipePar.m_ParName = RECIPE_PAR_NAME_AREA_IDX;
RecipePar.m_ParShowName = "Area Idx";
RecipePar.m_ParType = _RecipeParType_Int;//参数的类型
RecipePar.m_ParIntVal = 1;
RecipePar.m_DetailInfo = "扫描区域编号扫描区域文件中包含多个扫描区域时每个sub rcp只能选择一个区域编号进行工艺";
m_RecipeParVec.push_back(RecipePar);
}
{
CRecipeParameter RecipePar;
RecipePar.m_ParName = RECIPE_PAR_NAME_N2_STATE;
RecipePar.m_ParShowName = "N2";
RecipePar.m_ParType = _RecipeParType_Bool;//参数的类型
RecipePar.m_ParBoolVal = true;
RecipePar.m_DetailInfo = "N2开关控制退火过程中是否自动打开N2";
m_RecipeParVec.push_back(RecipePar);
}
{
CRecipeParameter RecipePar;
RecipePar.m_ParName = RECIPE_PAR_NAME_USE_CUR_N2VAL;
RecipePar.m_ParShowName = "Use CurN2Val";
RecipePar.m_ParType = _RecipeParType_Bool;//参数的类型
RecipePar.m_ParBoolVal = false;
RecipePar.m_DetailInfo = "MFC控制开关是否使用recipe的MFC流量控制值";
m_RecipeParVec.push_back(RecipePar);
}
#ifdef __OFFSET_TABLE__
{
CRecipeParameter RecipePar;
RecipePar.m_ParName = RECIPE_PAR_NAME_OFFSET_TAB;
RecipePar.m_ParShowName = "Offset Table";
RecipePar.m_ParType = _RecipeParType_CString;//参数的类型
RecipePar.m_ParStrVal = RECIPE_OFFSET_TBL_NULL;
RecipePar.m_DetailInfo = "补偿表的名称用于link指定的补偿表可以补偿edi和激光电流值";
m_RecipeParVec.push_back(RecipePar);
}
#endif
{
CRecipeParameter RecipePar;
RecipePar.m_ParName = RECIPE_PAR_NAME_RUNTIMES;
RecipePar.m_ParShowName = "Run Times";
RecipePar.m_ParType = _RecipeParType_Int;//参数的类型
RecipePar.m_ParIntVal = 1;//默认值
RecipePar.m_DetailInfo = "工艺运行次数正常设置为1大于1时表示跑cycle多subrcp的情况第一个sub的值为有效值";
m_RecipeParVec.push_back(RecipePar);
}
{
CRecipeParameter RecipePar;
RecipePar.m_ParName = RECIPE_PAR_NAME_CASSETTE_TIER_COUNT;
RecipePar.m_ParShowName = "Cassette Tier Cout";
RecipePar.m_ParUnit = "";
RecipePar.m_ParType = _RecipeParType_Int;//参数的类型
RecipePar.m_ParDoubleVal = 13;//默认值
RecipePar.m_DoubleMinVal = 13;
RecipePar.m_DoubleMaxVal = 25;
RecipePar.m_DetailInfo = "料盒层数设置设置料盒层数机械手根据料盒层数mapping";
m_RecipeParVec.push_back(RecipePar);
}
//不能被编辑的参数---------------------------------------------------------------
#if 1
{
CRecipeParameter RecipePar;
RecipePar.m_ParName = RECIPE_PAR_NAME_LASER1_POW;
RecipePar.m_ParShowName = "Laser1 Power";
RecipePar.m_ParUnit = "w";//参数的单位,用于显示
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
RecipePar.m_ParDoubleVal = 0;
RecipePar.m_DoubleMinVal = 0;
RecipePar.m_DoubleMaxVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MAX_LASER_POW_1);
RecipePar.m_bRcpInfoPar = true;//是否为计算参数(不能被编辑)
//RecipePar.m_DetailInfo = "Laser1功率值1.Laser固定电流为0时根据edi自动计算 2.Laser固定电流大于0时在功率点检表中查找对应的功率值用于计算衰减角度";
RecipePar.m_DetailInfo = "Laser1功率值在功率点检表中查找对应的功率值用于计算衰减角度";
m_RecipeParVec.push_back(RecipePar);
}
{
CRecipeParameter RecipePar;
RecipePar.m_ParName = RECIPE_PAR_NAME_LASER2_POW;
RecipePar.m_ParShowName = "Laser2 Power";
RecipePar.m_ParUnit = "w";//参数的单位,用于显示
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
RecipePar.m_ParDoubleVal = 0;
RecipePar.m_DoubleMinVal = 0;
RecipePar.m_DoubleMaxVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MAX_LASER_POW_2);
RecipePar.m_bRcpInfoPar = true;//是否为计算参数(不能被编辑)
//RecipePar.m_DetailInfo = "Laser2功率值1.Laser固定电流为0时根据edi自动计算 2.Laser固定电流大于0时在功率点检表中查找对应的功率值用于计算衰减角度";
RecipePar.m_DetailInfo = "Laser2功率值在功率点检表中查找对应的功率值用于计算衰减角度";
m_RecipeParVec.push_back(RecipePar);
}
{
CRecipeParameter RecipePar;
RecipePar.m_ParName = RECIPE_PAR_NAME_SCAN_SPEED;
RecipePar.m_ParShowName = "Scan Speed";
RecipePar.m_ParUnit = "mm/s";//参数的单位,用于显示
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
RecipePar.m_ParDoubleVal = 0;
RecipePar.m_DoubleMinVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MIN_SCAN_SPEED);
RecipePar.m_DoubleMaxVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MAX_SCAN_SPEED);
RecipePar.m_bRcpInfoPar = true;//是否为计算参数(不能被编辑)
RecipePar.m_DetailInfo = "X方向扫描速度固定扫描速度等于0时由X方向重叠率计算得出固定扫描速度大于0时等于固定扫描速度";
m_RecipeParVec.push_back(RecipePar);
}
{
CRecipeParameter RecipePar;
RecipePar.m_ParName = RECIPE_PAR_NAME_ROTATO_DIMMER_ANG;
RecipePar.m_ParShowName = "Dimmer1 Angle";
RecipePar.m_ParUnit = "degree";//参数的单位,用于显示
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
RecipePar.m_ParDoubleVal = 0;
RecipePar.m_DoubleMinVal = 0;
RecipePar.m_DoubleMaxVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MAX_DIMMER_ANG_1);
RecipePar.m_bRcpInfoPar = true;//是否为计算参数(不能被编辑)
RecipePar.m_DetailInfo = "Laser1衰减角度由edi频率功率计算得出的衰减器角度固定电流值大于0才会生效";
m_RecipeParVec.push_back(RecipePar);
}
{
CRecipeParameter RecipePar;
RecipePar.m_ParName = RECIPE_PAR_NAME_ROTATO_DIMMER_ANG2;
RecipePar.m_ParShowName = "Dimmer2 Angle";
RecipePar.m_ParUnit = "degree";//参数的单位,用于显示
RecipePar.m_ParType = _RecipeParType_Double;//参数的类型
RecipePar.m_ParDoubleVal = 0;
RecipePar.m_DoubleMinVal = 0;
RecipePar.m_DoubleMaxVal = gCommonParaMgr->GetCommonParaVal(RECIPE_PAR_MAX_DIMMER_ANG_2);
RecipePar.m_bRcpInfoPar = true;//是否为计算参数(不能被编辑)
RecipePar.m_DetailInfo = "Laser2衰减角度由edi频率功率计算得出的衰减器角度固定电流值大于0才会生效";
m_RecipeParVec.push_back(RecipePar);
}
#endif
}
#endif
#if 1
//根据参数的类型返回CString 类型值
CString CRecipeParameter::GetParStr()
{
CString ParStr;
switch(m_ParType)
{
case _RecipeParType_Double:
ParStr = Db2CString(m_ParDoubleVal);
break;
case _RecipeParType_Bool:
ParStr = (m_ParBoolVal)?(BOOL_STR_ON):(BOOL_STR_OFF);
break;
case _RecipeParType_CString:
ParStr = m_ParStrVal;
break;
case _RecipeParType_Int:
ParStr = Int2CString(m_ParIntVal);
break;
default:
break;
}
return ParStr;
}
CString CRecipeParameter::GetParTypeStr()
{
CString Str;
switch(m_ParType)
{
case _RecipeParType_Double:
Str = RCP_PAR_TYPE_DOUBLE;
break;
case _RecipeParType_Bool:
Str = RCP_PAR_TYPE_BOOL;
break;
case _RecipeParType_CString:
Str = RCP_PAR_TYPE_STRING;
break;
case _RecipeParType_Int:
Str = RCP_PAR_TYPE_INT;
break;
default:
break;
}
return Str;
}
void CRecipeParameter::SetValByStr(CString s)
{
switch(m_ParType)
{
case _RecipeParType_Double:
m_ParDoubleVal = CStringToDouble(s);
break;
case _RecipeParType_Bool:
m_ParBoolVal = ((s==BOOL_STR_ON))?(true):(false);
break;
case _RecipeParType_CString:
m_ParStrVal = s;
break;
case _RecipeParType_Int:
m_ParIntVal = CStringToInt(s);
break;
default:
break;
}
}
void CRecipeParameter::SetTypeByStr(CString TypeStr)
{
if(TypeStr==RCP_PAR_TYPE_DOUBLE)
{
m_ParType = _RecipeParType_Double;
}
if(TypeStr==RCP_PAR_TYPE_STRING)
{
m_ParType = _RecipeParType_CString;
}
if(TypeStr==RCP_PAR_TYPE_BOOL)
{
m_ParType = _RecipeParType_Bool;
}
if(TypeStr==RCP_PAR_TYPE_INT)
{
m_ParType = _RecipeParType_Int;
}
}
void CRecipeParameter::GetRangeStr(CString &Min,CString &Max)
{
if(m_ParType==_RecipeParType_Double)
{
Min = Db2CString(m_DoubleMinVal);
Max = Db2CString(m_DoubleMaxVal);
}
else
{
Min = Max = "---";
}
}
#endif
#if 1
CRecipe::CRecipe(void)
{
m_DoubleValCnt = 0;//double 类型参数的数量
m_GroupIdx = -1;//组的编号
m_RecipeIdx = -1;//在组中的编号
m_CurSubRecipeIdx = 0;//当前使用的SubRecipe 索引号
m_bEnableEdit = true;//当前时候可以编辑
RecipeReset();
CSubRecipe SubRecipe;
SubRecipe.m_SubRecipeName = "SubRecipe1";
m_SubRecipeVec.push_back(SubRecipe);//默认有一个SubRecipe
}
void CRecipe::RecipeReset()
{
m_RecipeName = NULL_RECIPE_NAME;//Recipe 名
}
bool CRecipe::IsValid()
{
return (m_RecipeName != NULL_RECIPE_NAME);
}
vector<CRecipeParameter> &CRecipe::GetRecipeParVec()
{
return m_SubRecipeVec[m_CurSubRecipeIdx].m_RecipeParVec;
};
//保存RecipePar 到文件
void CRecipe::SaveRecipeParToFile(CString FilePath)
{
}
//从文件读取recipe 参数
void CRecipe::ReadRecipeParFromFile(CString FilePath)
{
}
//通过参数名获取参数
CRecipeParameter CRecipe::GetRecipePar(CString ParName)
{
CRecipeParameter Par;
vector<CRecipeParameter> &RecipeParVec = GetRecipeParVec();
int size = RecipeParVec.size();
for(int i=0;i<size;i++)
{
CRecipeParameter &RecipePar = RecipeParVec[i];
if(RecipePar.m_ParName == ParName)
{
Par = RecipePar;
}
}
return Par;
}
//设置指定的参数
void CRecipe::SetRecipePar(CString ParName,CRecipeParameter Par)
{
vector<CRecipeParameter> &RecipeParVec = GetRecipeParVec();
int size = RecipeParVec.size();
for(int i=0;i<size;i++)
{
CRecipeParameter &RecipePar = RecipeParVec[i];
if(RecipePar.m_ParName == ParName)
{
RecipePar = Par;
break;
}
}
}
//检查参数范围
bool CRecipe::CheckParRange(bool bShowMsg)
{
gLogMgr->WriteDebugLog("Func---->Check Recipe Par Range");
vector<CRecipeParameter> &RecipeParVec = GetRecipeParVec();
int size = RecipeParVec.size();
for(int i=0;i<m_DoubleValCnt;i++)
{
CRecipeParameter &RecipePar = RecipeParVec[i];
if(!CheckParRangeExt(RecipePar,RecipePar.m_ParDoubleVal,bShowMsg))
return false;
}
return true;
}
bool CRecipe::CheckParRangeExt(CRecipeParameter &RecipePar,double ParVal,bool bShowMsg)
{
//优先使用文件中的参数
double DoubleMaxVal = gCommonParaMgr->GetCommonParaVal(RecipePar.m_ParName);
if(IsDbEqualZero(DoubleMaxVal))
DoubleMaxVal = RecipePar.m_DoubleMaxVal;
if(ParVal<RecipePar.m_DoubleMinVal || ParVal>DoubleMaxVal)
{
CString s,s1;
s += "[";
s += RecipePar.m_ParShowName;
s += "]";
s1.Format(" : %.2f",ParVal);
s += s1;
s1.Format("\n超出范围[%.2f~%.2f]",RecipePar.m_DoubleMinVal,DoubleMaxVal);
s += s1;
if(bShowMsg)
{
CMsgBox MsgBox;
MsgBox.Show(s);
}
return false;
}
return true;
}
//检查ParName 参数的范围
bool CRecipe::CheckParRangeByName(CString ParName,double val)
{
CRecipeParameter RecipePar = GetRecipePar(ParName);
return CheckParRangeExt(RecipePar,val,true);
}
//获取显示用的名字
CString CRecipe::GetShowName()
{
CString s("");
if(m_GroupIdx>=0 && m_RecipeIdx>=0)
{
s.Format("[%d][%d]",m_GroupIdx+1,m_RecipeIdx+1);
s += m_RecipeName;
}
else//恢复用recipe
{
s = "Recover : "+m_RecipeName;
}
return s;
}
void CRecipe::AddSubRecipe(CString SubRecipeName)
{
int size = m_SubRecipeVec.size();
if(size>0)
{
CSubRecipe SubRecipe = m_SubRecipeVec[m_CurSubRecipeIdx];//用当前选择的sub recipe 进行复制
SubRecipe.m_SubRecipeName = SubRecipeName;
m_SubRecipeVec.push_back(SubRecipe);
}
}
void CRecipe::DelSubRecipe(CString SubRecipeName)
{
int size = m_SubRecipeVec.size();
if(m_SubRecipeVec.size()>1)//两个以上才能删除
{
vector<CSubRecipe>::iterator iter = m_SubRecipeVec.begin();
vector<CSubRecipe>::iterator iter_end = m_SubRecipeVec.end();
for(;iter!=iter_end;iter++)
{
if((*iter).m_SubRecipeName == SubRecipeName)
{
m_SubRecipeVec.erase(iter);
m_CurSubRecipeIdx = 0;
break;
}
}
}
}
CString CRecipe::GetCurSubRecipeName()
{
CString RecipeName;
if(m_CurSubRecipeIdx>=0 && m_CurSubRecipeIdx<m_SubRecipeVec.size())
{
RecipeName = m_SubRecipeVec[m_CurSubRecipeIdx].m_SubRecipeName;
}
return RecipeName;
}
void CRecipe::SetCurSubRecipeName(CString Name)
{
if(m_CurSubRecipeIdx>=0 && m_CurSubRecipeIdx<m_SubRecipeVec.size())
{
m_SubRecipeVec[m_CurSubRecipeIdx].m_SubRecipeName = Name;
}
}
//读取OffsetTable 到对应的SubRecipe
bool CRecipe::ReadOffsetTableFile(CString TableName)
{
CString TableFilePath = gRecipeMgr->GetOffsetTablePath(TableName);
CSubRecipe &SubRecipe = m_SubRecipeVec[m_CurSubRecipeIdx];
bool Ret = SubRecipe.m_OffsetTable.ReadOffsetTableFile(TableFilePath);
if(TableName==RECIPE_OFFSET_TBL_NULL)
Ret = true;
return Ret;
}
//获取OffsetTable指定参数的值
double CRecipe::GetOffsetParVal(CString ParName)
{
CSubRecipe &SubRecipe = m_SubRecipeVec[m_CurSubRecipeIdx];
return SubRecipe.m_OffsetTable.GetOffsetParVal(ParName);
}
#endif
CRecipeMgr *gRecipeMgr = new CRecipeMgr;
CRecipeMgr::CRecipeMgr(void)
{
m_CurSelGroupIdx = 0;//当前选择的gourp 索引值
m_CurSelRecipeIdx = 0;//当前选择的recipe 索引值
m_CurSelRecipeParIdx = -1;//当前选择的par 索引值
m_pRecipeGroupComb = NULL;
m_FocusAdjustMin = 0;//焦距调整范围最小值
m_FocusAdjustMax = 0;//焦距调整范围最大值
}
CRecipeMgr::~CRecipeMgr(void)
{
}
void CRecipeMgr::OnAppInitialize()
{
//创建recipe 目录
CreatRecipeFilePath();
//初始化recipe dlg
CDlgChildRecipe *pDlg = dynamic_cast<CDlgChildRecipe*>(gChildRecipe);
pDlg->InitDialogItem();
}
//获取参数名list 文件路径
CString CRecipeMgr::GetRecipeNameListPath()
{
CFileMgr FileMgr;
CString FilePath;
FileMgr.GetFullFilePath(FilePath,RECIPE_GROUP_NAME_FILE);//获取完整路径
return FilePath;
}
//获取参数组的路径GroupIdx(0~RECIPE_GROUP_CNT)
CString CRecipeMgr::GetGroupDirPath(int GroupIdx)
{
CFileMgr FileMgr;
CString FilePath;
CString GroupDirName;
GroupDirName.Format("ParGroup%d\\",GroupIdx);
GroupDirName = RECIPE_FILE_PATH + GroupDirName;
FileMgr.GetFullFilePath(FilePath,GroupDirName);//获取完整路径
return FilePath;
}
//设置当前选中的Recipe 索引值
void CRecipeMgr::SetCurSelRecipeIdx(int Idx)
{
int size = m_CurGroupRecipeVec.size();
if(Idx>=0 && Idx<size)
{
m_CurSelRecipeIdx = Idx;
CString s;
s.Format("SetCurSelRecipeIdx : %d",Idx+1);
gLogMgr->WriteDebugLog(s);
}
}
#if 1
//保存当前选择的Recipe
void CRecipeMgr::SaveCurSelRecipe(CRecipe Recipe)
{
int size = m_CurGroupRecipeVec.size();
if(m_CurSelRecipeIdx>=0 && m_CurSelRecipeIdx<size)
{
m_CurGroupRecipeVec[m_CurSelRecipeIdx] = Recipe;
//获取Recipe 参数文件的路径
CString ParPath = GetRecipeFilePath(m_CurSelGroupIdx,m_CurSelRecipeIdx);
Recipe.SaveRecipeParToFile(ParPath);
}
}
//获取Recipe 参数文件的路径
CString CRecipeMgr::GetRecipeFilePath(int GroupIdx,int RecipeIdx)
{
//写入到文件
CFileMgr FileMgr;
CString DirPath = GetGroupDirPath(GroupIdx);
CString FilePath;
FilePath.Format("RecipePar%d.rcp",RecipeIdx);
FilePath = DirPath+FilePath;
return FilePath;
}
//获取当前选择的group 名字
CString CRecipeMgr::GetCurSelGroupName()
{
return m_RecipeGroupNameVec[m_CurSelGroupIdx];
}
//获取当前选择的group recipe 字符串
CString CRecipeMgr::GetSelGroupRecipeStr()
{
CString Num1,Num2;
Num1.Format("<%d>",m_CurSelGroupIdx+1);
Num2.Format("<%d>",m_CurSelRecipeIdx+1);
CString GroupRecipeStr;
GroupRecipeStr += Num1;
GroupRecipeStr += m_RecipeGroupNameVec[m_CurSelGroupIdx];
GroupRecipeStr += Num2;
GroupRecipeStr += m_CurGroupRecipeVec[m_CurSelRecipeIdx].m_RecipeName;
return GroupRecipeStr;
}
//创建当前recipe 的扫描路径
void CRecipeMgr::CreatRecipeScanPath(CRecipe *pRecipe,int SubRecipeIdx)
{
pRecipe->SetCurSubRecipeIdx(SubRecipeIdx);//设置为当前的SubRecipeIdx
CRecipeParameter RecipePar;
//打开扫描区域
CString AreaName;
RecipePar = pRecipe->GetRecipePar(RECIPE_PAR_NAME_SCAN_AREA);
AreaName = RecipePar.m_ParStrVal;
if(!gWaferRecipeDataMgr->SelScanAreaByName(AreaName))
{
CString Msg("扫描区域不存在: ");
Msg += AreaName;
CExceptionMsg ExceptionMsg;
ExceptionMsg.SetMsg(Msg);
throw ExceptionMsg;
}
//创建扫描路径
int AreaIdx;
RecipePar = pRecipe->GetRecipePar(RECIPE_PAR_NAME_AREA_IDX);
AreaIdx = RecipePar.m_ParIntVal-1;
gWaferRecipeDataMgr->CreatScanPath(AreaIdx);
m_pView->RefreshView();
}
void CRecipeMgr::CreatScanPath(CString AreaName,int AreaIdx)
{
//打开路径
if(!gWaferRecipeDataMgr->SelScanAreaByName(AreaName))
{
return;
}
//创建扫描路径
gWaferRecipeDataMgr->CreatScanPath(AreaIdx);
//默认选择area
//CObjContainer &ObjContainer = gLayer.GetObjContainer();
//ObjContainer.SelObjByIdx(AreaIdx);
m_pView->RefreshView();
}
#endif
#if 1
#if 1
CString CRecipeMgr::GetRecipePath()
{
CString DirPath = gProgramLaserTuiHuo->GetLaipuLaserDataDir(NEW_RECIPE_FILE_PATH);
return DirPath;
}
void CRecipeMgr::CreatRecipeFilePath()
{
CString DirPath = GetRecipePath();
CFileMgr FileMgr;
if(!FileMgr.IsDirectoryExists(DirPath))
FileMgr.CreatDir(DirPath);
DirPath += "\\";
}
//获取组Recipe文件的完整路径(参数RecipeName 无后缀)
CString CRecipeMgr::GetCtrlRecipeFilePath(CString GroupName,CString RecipeName)
{
CString Path = GetRecipePath();
Path += GroupName;
Path += "\\";
Path += RecipeName;
Path += ".";
Path += RECIPE_FILE_SUFFIX;
return Path;
}
#endif
#if 1
//设置当前选中的group 索引值
void CRecipeMgr::SetCurSelGourpIdx(int Idx)
{
int size = m_NewRecipeGroupNameVec.size();
if(Idx>=0 && Idx<size)
{
m_CurSelGroupName = m_NewRecipeGroupNameVec[Idx];
}
else
{
m_CurSelGroupName = "";
}
}
//是否选择了编辑的recipe
bool CRecipeMgr::IsbSelEditRecipe()
{
return (m_CurSelRecipeName!="");
}
void CRecipeMgr::RecipeCtrlInit(CRecipeCtrlItem &CtrlItem)
{
CString &EditName1 = *(CtrlItem.m_EditName1);
CString &EditName2 = *(CtrlItem.m_EditName2);
ERecipeCtrlType RecipeCtrlType = GetCurRecipeCtrlType();
int size = 0;
switch(RecipeCtrlType)
{
case _RecipeCtrl_AddGroup:
CtrlItem.m_DlgTitle = "Add Recipe Group";
break;
case _RecipeCtrl_DelGroup:
CtrlItem.m_DlgTitle = "Delete Recipe Group";
EditName2 = m_CurSelGroupName;
break;
case _RecipeCtrl_GroupName:
EditName1 = m_CurSelGroupName;
EditName2 = m_CurSelGroupName;
CtrlItem.m_DlgTitle = "Recipe Group ReName";
break;
case _RecipeCtrl_RecipeName:
CtrlItem.m_DlgTitle = "Recipe ReName";
EditName1 = m_CurSelRecipeName;
EditName2 = m_CurSelRecipeName;
break;
case _RecipeCtrl_AddRecipe:
CtrlItem.m_DlgTitle = "Add Recipe";
UpdateRecipeGroupComb(CtrlItem.m_RecipeCtrlGroupComb);
break;
case _RecipeCtrl_MoveRecipe:
CtrlItem.m_DlgTitle = "Move Recipe";
UpdateRecipeGroupComb(CtrlItem.m_RecipeCtrlGroupComb);
EditName2 = m_CurSelRecipeName;
break;
case _RecipeCtrl_CopyRecipe:
CtrlItem.m_DlgTitle = "Copy Recipe";
EditName1 = m_CurSelRecipeName;
EditName2 = m_CurSelRecipeName+"-Copy";
break;
case _RecipeCtrl_DelRecipe:
CtrlItem.m_DlgTitle = "Delete Recipe";
EditName1 = m_CurSelGroupName;
EditName2 = m_CurSelRecipeName;
break;
case _RecipeCtrl_AddSubRecipe:
{
CtrlItem.m_DlgTitle = "Add Sub Recipe";
vector<CSubRecipe> &SubRecipeVec = m_CurEditRecipe.GetSubRecipeVec();
CString Name;
Name.Format("SubRecipe%ld",SubRecipeVec.size()+1);
EditName1 = m_CurSelRecipeName;
EditName2 = Name;
}
break;
case _RecipeCtrl_DelSubRecipe:
{
CtrlItem.m_DlgTitle = "Delete Sub Recipe";
vector<CSubRecipe> &SubRecipeVec = m_CurEditRecipe.GetSubRecipeVec();
EditName1 = m_CurSelRecipeName;
EditName2 = SubRecipeVec[m_CurEditRecipe.m_CurSubRecipeIdx].m_SubRecipeName;
}
break;
case _RecipeCtrl_SubRecipeName:
{
CtrlItem.m_DlgTitle = "Sub Recipe ReName";
vector<CSubRecipe> &SubRecipeVec = m_CurEditRecipe.GetSubRecipeVec();
EditName1 = SubRecipeVec[m_CurEditRecipe.m_CurSubRecipeIdx].m_SubRecipeName;
EditName2 = EditName1;
}
break;
default:
break;
}
}
//绑定组下拉列表
void CRecipeMgr::BindingRecipeGroupComb(CComboBox *p)
{
m_pRecipeGroupComb = p;
UpdateRecipeGroupVec();
UpdateRecipeGroupComb(m_pRecipeGroupComb);
};
//刷新RecipeGroup 信息
void CRecipeMgr::UpdateRecipeGroupInfo()
{
UpdateRecipeGroupVec();
UpdateRecipeGroupComb(m_pRecipeGroupComb);
}
//更新组列表容器
void CRecipeMgr::UpdateRecipeGroupVec()
{
m_NewRecipeGroupNameVec.clear();
CString DirPath = GetRecipePath();
CFileMgr FileMgr;
vector<CString> FilePathVec;
FileMgr.GetChildFileOrDirName(true,GetRecipePath(),FilePathVec,"");
int size = FilePathVec.size();
for(int k=0;k<size;k++)
{
CString GroupName = FileMgr.GetFileNameFromPath(FilePathVec[k],true);
m_NewRecipeGroupNameVec.push_back(GroupName);
}
}
void CRecipeMgr::UpdatParBoolComb(CComboBox &Comb)
{
Comb.ResetContent();//清空
Comb.InsertString(0,BOOL_STR_ON);
Comb.InsertString(1,BOOL_STR_OFF);
}
//更新组下拉列表
void CRecipeMgr::UpdateRecipeGroupComb(CComboBox *pComb)
{
if(!pComb)
return;
CComboBox &ComboBox = *pComb;
ComboBox.ResetContent();//清空
int idx = -1;
int size = m_NewRecipeGroupNameVec.size();
for(int k=0;k<size;k++)
{
ComboBox.InsertString(k,m_NewRecipeGroupNameVec[k]);
if(m_CurSelGroupName == m_NewRecipeGroupNameVec[k])
idx = k;
}
if(idx>=0)
ComboBox.SetCurSel(idx);
}
void CRecipeMgr::UpdateSelRecipeComb(CComboBox &ComboBox,vector<CString> &SelGroupRecipeNameVec)
{
ComboBox.ResetContent();//清空
//从当前选中的recipe 目录读取recipe 文件列表
ReadCurGroupRecipeName(SelGroupRecipeNameVec);
int size = SelGroupRecipeNameVec.size();
for(int k=0;k<size;k++)
{
ComboBox.InsertString(k,SelGroupRecipeNameVec[k]);
}
}
void CRecipeMgr::UpdateSelSubRecipeComb(CComboBox &ComboBox,CRecipe Recipe)
{
ComboBox.ResetContent();//清空
vector<CSubRecipe> &SubRecipeVec = Recipe.GetSubRecipeVec();
int size = SubRecipeVec.size();
for(int k=0;k<size;k++)
{
ComboBox.InsertString(k,SubRecipeVec[k].m_SubRecipeName);
}
ComboBox.SetCurSel(0);
}
void CRecipeMgr::InitGroupRecipeList(CListCtrl &List)
{
//设置风格
List.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);
//设置列
int idx = 0;
List.InsertColumn(idx,"Idx",LVCFMT_LEFT,50,-1);
idx++;
List.InsertColumn(idx,"Recipe Name",LVCFMT_LEFT,300,-1);
idx++;
}
void CRecipeMgr::InitEditSubRecipeList(CListCtrl &List)
{
//设置风格
List.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);
//设置列
int idx = 0;
List.InsertColumn(idx,"Idx",LVCFMT_LEFT,50,-1);
idx++;
List.InsertColumn(idx,"Sub Recipe Name",LVCFMT_LEFT,430,-1);
idx++;
}
void CRecipeMgr::InitEditRecipeList(CListCtrl &List,bool bShowParRange)
{
//设置风格
List.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);
//设置列
int idx = 0;
List.InsertColumn(idx,"Idx",LVCFMT_CENTER,35,-1);
idx++;
List.InsertColumn(idx,"ParName",LVCFMT_LEFT,135,-1);
idx++;
List.InsertColumn(idx,"Type",LVCFMT_CENTER,80,-1);
idx++;
if(bShowParRange)
{
List.InsertColumn(idx,"Min",LVCFMT_CENTER,80,-1);
idx++;
List.InsertColumn(idx,"Max",LVCFMT_CENTER,80,-1);
idx++;
}
List.InsertColumn(idx,"Unit",LVCFMT_CENTER,80,-1);
idx++;
List.InsertColumn(idx,"Value",LVCFMT_LEFT,250,-1);
idx++;
}
void CRecipeMgr::UpdateGroupRecipeList(CListCtrl &List)
{
//从当前选中的recipe 目录读取recipe 文件列表
ReadCurGroupRecipeName(m_CurSelGroupRecipeNameVec);
List.DeleteAllItems();
int size = m_CurSelGroupRecipeNameVec.size();
for(int k=0;k<size;k++)
{
int idx = 0;
List.InsertItem(k," ");//插入一行
List.SetItemText(k,idx++,Int2CString(k+1));//序号
CString RecipeName = m_CurSelGroupRecipeNameVec[k];
RecipeName += ".";
RecipeName += RECIPE_FILE_SUFFIX;
List.SetItemText(k,idx++,m_CurSelGroupRecipeNameVec[k]);
}
}
void CRecipeMgr::UpdateEditSubRecipeList(CListCtrl &List)
{
List.DeleteAllItems();
if(!IsbSelEditRecipe())
return;
vector<CSubRecipe> &SubRecipeVec = m_CurEditRecipe.GetSubRecipeVec();
int size = SubRecipeVec.size();
for(int k=0;k<size;k++)
{
int idx = 0;
List.InsertItem(k," ");//插入一行
List.SetItemText(k,idx++,Int2CString(k+1));//序号
List.SetItemText(k,idx++,SubRecipeVec[k].m_SubRecipeName);
}
//高亮选择的行
List.SetItemState(m_CurEditRecipe.m_CurSubRecipeIdx,LVIS_FOCUSED | LVIS_SELECTED,LVIS_FOCUSED | LVIS_SELECTED);
}
void CRecipeMgr::UpdateEditRecipeList(CListCtrl &RecipeList,CListCtrl &RecipeInfoList,bool bResetErrRangeParIdxSet)
{
RecipeInfoList.DeleteAllItems();
if(bResetErrRangeParIdxSet)
{
RecipeList.DeleteAllItems();
ResetParIdxSet();
}
if(!IsbSelEditRecipe())//没有选择要编辑的Recipe
return;
//更新激光焦距相关config,计算焦距调整范围
UpdateLaserFocusProp();
//更新当前的无效参数索引值
UpdateInvalidParIdxSet(m_CurEditRecipe);
//更新recipe 的非设置参数
UpdateRecipeInfoPar(m_CurEditRecipe);
vector<CRecipeParameter> &RecipeParVec = m_CurEditRecipe.GetRecipeParVec();
int size = RecipeParVec.size();
if(size<=0)
return;
int RecipeListIdx = 0;
int RecipeInfoListIdx = 0;
for(int k=0;k<size;k++)
{
int idx = 0;
CRecipeParameter &RecipePar = RecipeParVec[k];
//改变焦距微调值的范围
if(RecipePar.m_ParName ==RECIPE_PAR_NAME_FOCUS_ADJUST_VAL)
{
RecipePar.m_DoubleMinVal = m_FocusAdjustMin;
RecipePar.m_DoubleMaxVal= m_FocusAdjustMax;
}
CString Min,Max;
RecipePar.GetRangeStr(Min,Max);
if(RecipePar.m_bRcpInfoPar)//计算参数
{
RecipeInfoList.InsertItem(RecipeInfoListIdx," ");//插入一行
RecipeInfoList.SetItemText(RecipeInfoListIdx,idx++,Int2CString(RecipeInfoListIdx+1));//序号
RecipeInfoList.SetItemText(RecipeInfoListIdx,idx++,RecipePar.m_ParShowName);//参数名
RecipeInfoList.SetItemText(RecipeInfoListIdx,idx++,RecipePar.GetParTypeStr());//参数类型
RecipeInfoList.SetItemText(RecipeInfoListIdx,idx++,Min);//最小值
RecipeInfoList.SetItemText(RecipeInfoListIdx,idx++,Max);//最大值
RecipeInfoList.SetItemText(RecipeInfoListIdx,idx++,RecipePar.m_ParUnit);//参数单位
RecipeInfoList.SetItemText(RecipeInfoListIdx,idx++,RecipePar.GetParStr());//参数值
RecipeInfoListIdx++;
}
else
{
if(bResetErrRangeParIdxSet)
{
RecipeList.InsertItem(RecipeListIdx," ");//插入一行
RecipeList.SetItemText(RecipeListIdx,idx++,Int2CString(RecipeListIdx+1));//序号
RecipeList.SetItemText(RecipeListIdx,idx++,RecipePar.m_ParShowName);//参数名
RecipeList.SetItemText(RecipeListIdx,idx++,RecipePar.GetParTypeStr());//参数类型
RecipeList.SetItemText(RecipeListIdx,idx++,Min);//最小值
RecipeList.SetItemText(RecipeListIdx,idx++,Max);//最大值
RecipeList.SetItemText(RecipeListIdx,idx++,RecipePar.m_ParUnit);//参数单位
RecipeList.SetItemText(RecipeListIdx,idx++,RecipePar.GetParStr());//参数值
RecipeListIdx++;
}
}
}
}
void CRecipeMgr::UpdateEditRecipeListExt(CListCtrl &RecipeList,CRecipe &Recipe)
{
RecipeList.DeleteAllItems();
vector<CRecipeParameter> &RecipeParVec = Recipe.GetRecipeParVec();
int size = RecipeParVec.size();
if(size<=0)
return;
int RecipeListIdx = 0;
int RecipeInfoListIdx = 0;
for(int k=0;k<size;k++)
{
int idx = 0;
CRecipeParameter &RecipePar = RecipeParVec[k];
CString Min,Max;
RecipePar.GetRangeStr(Min,Max);
if(!RecipePar.m_bRcpInfoPar)
{
{
RecipeList.InsertItem(RecipeListIdx," ");//插入一行
RecipeList.SetItemText(RecipeListIdx,idx++,Int2CString(RecipeListIdx+1));//序号
RecipeList.SetItemText(RecipeListIdx,idx++,RecipePar.m_ParShowName);//参数名
RecipeList.SetItemText(RecipeListIdx,idx++,RecipePar.GetParTypeStr());//参数类型
RecipeList.SetItemText(RecipeListIdx,idx++,Min);//最小值
RecipeList.SetItemText(RecipeListIdx,idx++,Max);//最大值
RecipeList.SetItemText(RecipeListIdx,idx++,RecipePar.m_ParUnit);//参数单位
RecipeList.SetItemText(RecipeListIdx,idx++,RecipePar.GetParStr());//参数值
RecipeListIdx++;
}
}
}
}
//不区分编辑和非编辑参数
void CRecipeMgr::UpdateAllRecipeParToList(CRecipe Recipe,CListCtrl &RecipeList)
{
RecipeList.DeleteAllItems();
//更新recipe 的非设置参数
UpdateRecipeInfoPar(Recipe);
vector<CRecipeParameter> &RecipeParVec = Recipe.GetRecipeParVec();
int size = RecipeParVec.size();
int RecipeListIdx = 0;
int RecipeInfoListIdx = 0;
for(int k=0;k<size;k++)
{
int idx = 0;
CRecipeParameter &RecipePar = RecipeParVec[k];
RecipeList.InsertItem(k," ");//插入一行
RecipeList.SetItemText(k,idx++,Int2CString(k+1));//序号
RecipeList.SetItemText(k,idx++,RecipePar.m_ParShowName);//参数名
RecipeList.SetItemText(k,idx++,RecipePar.m_ParUnit);//参数单位
RecipeList.SetItemText(k,idx++,RecipePar.GetParTypeStr());//参数类型
RecipeList.SetItemText(k,idx++,RecipePar.GetParStr());//参数值
}
}
//更新区域索引值下拉列表
void CRecipeMgr::UpdateAreaIdxCombo(CComboBox &AreaIdxComb)
{
CObjContainer &ObjContainer = gLayer.GetObjContainer();
int AreaCnt = ObjContainer.GetScanAreaCnt();
AreaIdxComb.ResetContent();//清空
int idx = 0;
for(int k=0;k<AreaCnt;k++)
{
CString Str = GetAreaIdxStr(k);
AreaIdxComb.InsertString(idx++,Str);
}
}
CString CRecipeMgr::GetAreaIdxStr(int k)
{
CString Str;
if(k<9)
Str.Format("[0%d]",k+1);
else
Str.Format("[%d]",k+1);
Str += "区域";
return Str;
}
#endif
#if 1
void CRecipeMgr::AddRecipeGroup(CString GroupName)
{
CString GroupPath = GetRecipePath();
GroupPath += "\\";
GroupPath += GroupName;
CFileMgr FileMgr;
FileMgr.CreatDir(GroupPath);
}
//删除Recipe组
void CRecipeMgr::DeleteRecipeGroup(CString GroupName)
{
CFileMgr FileMgr;
CString Path = GetRecipePath();
Path += GroupName;
Path += "\\";
CWorkTime WorkTime;
CCsvData CsvData;
CsvData.AddData("用户",false);
CsvData.AddData(gAuthorityMgr->GetCurUserName(),true);
CsvData.AddData("操作时间",false);
CsvData.AddData(WorkTime.GetDateTime("/",":"),true);
CsvData.AddData("Group 路径",false);
CsvData.AddData(Path,true);
CsvData.AddData("操作类型",false);
CsvData.AddData("删除recipe group",true);
vector<CString> RcpPathVec;
FileMgr.GetChildFileOrDirName(false,Path,RcpPathVec,RECIPE_FILE_SUFFIX);
int size1 = RcpPathVec.size();
for(int i=0;i<size1;i++)
{
CString Name = FileMgr.GetFileNameFromPath(RcpPathVec[i],true);
CsvData.AddData("删除recipe ",false);
CsvData.AddData(Name,true);
}
CString FileName = WorkTime.GetCurTime("_");
FileName += "_";
FileName += GroupName;
CString DataPath = CreatCurParDataPath();
FileMgr.WriteDataToExcel(DataPath,FileName,CsvData,false);
//执行删除
FileMgr.DeleteFolder(Path);
}
//添加recipe
void CRecipeMgr::AddRecipe(CString GroupName,CString RecipeName)
{
if(!CheckRecipeNameExist(RecipeName))
return;
CString RecipeFilePath = GetCtrlRecipeFilePath(GroupName,RecipeName);
gLogMgr->WriteDebugLog(RecipeFilePath);
CRecipe Recipe;
SaveRecipeToXml(RecipeFilePath,Recipe);
CRecipeCtrlPar RecipeCtrlPar;
RecipeCtrlPar.m_CtrlType = _RecipeCtrl_AddRecipe;
RecipeCtrlPar.m_FilePath = RecipeFilePath;
RecipeCtrlPar.m_RcpName = RecipeName;
SaveRecipeHistoy(RecipeCtrlPar);
}
//删除Recipe
void CRecipeMgr::DeletRecipe(CString RecipeName)
{
CString Path = GetCtrlRecipeFilePath(m_CurSelGroupName,RecipeName);
CFileMgr FileMgr;
FileMgr.DeleteFolder(Path);
CRecipeCtrlPar RecipeCtrlPar;
RecipeCtrlPar.m_CtrlType = _RecipeCtrl_DelRecipe;
RecipeCtrlPar.m_FilePath = Path;
RecipeCtrlPar.m_RcpName = RecipeName;
SaveRecipeHistoy(RecipeCtrlPar);
}
//移动recipe 到GroupName
void CRecipeMgr::MoveRecipe(CString GroupName,CString RecipeName)
{
CString OldPath = GetCtrlRecipeFilePath(m_CurSelGroupName,RecipeName);
CString NewPath = GetCtrlRecipeFilePath(GroupName,RecipeName);
CFileMgr FileMgr;
FileMgr.MoveFolder(OldPath,NewPath);
CRecipeCtrlPar RecipeCtrlPar;
RecipeCtrlPar.m_CtrlType = _RecipeCtrl_MoveRecipe;
RecipeCtrlPar.m_FilePath = OldPath;
RecipeCtrlPar.m_NewFilePath = NewPath;
RecipeCtrlPar.m_RcpName = RecipeName;
SaveRecipeHistoy(RecipeCtrlPar);
}
//复制选择的recipe 到当前的group
void CRecipeMgr::CopyRecipe(CString NewRecipeName)
{
if(!CheckRecipeNameExist(NewRecipeName))
return;
CString OldPath = GetCtrlRecipeFilePath(m_CurSelGroupName,m_CurSelRecipeName);
CString NewPath = GetCtrlRecipeFilePath(m_CurSelGroupName,NewRecipeName);
CFileMgr FileMgr;
FileMgr.CopyFolder(OldPath,NewPath);
CRecipeCtrlPar RecipeCtrlPar;
RecipeCtrlPar.m_CtrlType = _RecipeCtrl_CopyRecipe;
RecipeCtrlPar.m_FilePath = OldPath;
RecipeCtrlPar.m_RcpName = m_CurSelRecipeName;
RecipeCtrlPar.m_RcpNameNew = NewRecipeName;
SaveRecipeHistoy(RecipeCtrlPar);
}
bool CRecipeMgr::ReadEditRecipeFromFile()
{
CString RecipeFilePath = GetCtrlRecipeFilePath(m_CurSelGroupName,m_CurSelRecipeName);
if(ReadRecipeFromXml(RecipeFilePath,m_CurEditRecipe))
{
m_CurEditRecipe.m_RecipeName = m_CurSelRecipeName;
return true;
}
return false;
}
bool CRecipeMgr::ReadEditRecipeFromFile(CRecipe &Recipe,int SelGroupIdx,CString SelRecipeName)
{
int size = m_NewRecipeGroupNameVec.size();
if(SelGroupIdx<0||SelGroupIdx>=size)
return false;
CString SelGroupName = m_NewRecipeGroupNameVec[SelGroupIdx];
CString RecipeFilePath = GetCtrlRecipeFilePath(SelGroupName,SelRecipeName);
Recipe.m_RecipeName = SelRecipeName;
return ReadRecipeFromXml(RecipeFilePath,Recipe);
}
//改变组名称
void CRecipeMgr::ChangeGroupName(CString NewGroupName)
{
CString OldGroupPath = GetRecipePath();
CString NewGroupPath = OldGroupPath + NewGroupName;
OldGroupPath += m_CurSelGroupName;
CFileMgr FileMgr;
FileMgr.ReNameFolder(OldGroupPath,NewGroupPath);
m_CurSelGroupName = NewGroupName;
m_CurEditRecipe.m_FilePath = GetCtrlRecipeFilePath(m_CurSelGroupName,m_CurSelRecipeName);
}
//改变recipe 名称
void CRecipeMgr::ChangeRecipeName(CString NewRcpName)
{
if(!CheckRecipeNameExist(NewRcpName))
return;
CString OldPath = GetCtrlRecipeFilePath(m_CurSelGroupName,m_CurSelRecipeName);
CString NewPath = GetCtrlRecipeFilePath(m_CurSelGroupName,NewRcpName);
CFileMgr FileMgr;
FileMgr.ReNameFolder(OldPath,NewPath);
SetCurSelRecipeName(NewRcpName);
m_CurEditRecipe.m_FilePath = NewPath;
}
//改变SubRecipe 名称
void CRecipeMgr::ChangeSubRecipeName(CString NewRcpName)
{
m_CurEditRecipe.SetCurSubRecipeName(NewRcpName);
//保存
CString RecipeFilePath = GetCtrlRecipeFilePath(m_CurSelGroupName,m_CurEditRecipe.m_RecipeName);
SaveRecipeToXml(m_CurEditRecipe.m_FilePath,m_CurEditRecipe);
}
CString CRecipeMgr::GetRecipeCtrlName(ERecipeCtrlType RecipeCtrlType)
{
CString CtrlName;
switch(RecipeCtrlType)
{
case _RecipeCtrl_AddGroup:
CtrlName = "Add Group";
break;
case _RecipeCtrl_DelGroup:
CtrlName = "Delete Group";
break;
case _RecipeCtrl_GroupName:
CtrlName = "Group ReName";
break;
case _RecipeCtrl_AddRecipe:
CtrlName = "Add Recipe";
break;
case _RecipeCtrl_DelRecipe:
CtrlName = "Delete Recipe";
break;
case _RecipeCtrl_CopyRecipe:
CtrlName = "Copy Recipe";
break;
case _RecipeCtrl_MoveRecipe:
CtrlName = "Move Recipe";
break;
case _RecipeCtrl_RecipeName:
CtrlName = "Recipe ReName";
break;
case _RecipeCtrl_AddSubRecipe:
CtrlName = "Add SubRecipe";
break;
case _RecipeCtrl_DelSubRecipe:
CtrlName = "Delete SubRecipe";
break;
case _RecipeCtrl_SubRecipeName:
CtrlName = "SubRecipe ReName";
break;
default:
break;
}
return CtrlName;
}
//从当前选中的recipe 目录读取recipe 文件列表
void CRecipeMgr::ReadCurGroupRecipeName(vector<CString> &SelGroupRecipeNameVec)
{
SelGroupRecipeNameVec.clear();
CString RecipePath = GetRecipePath();
RecipePath += m_CurSelGroupName;
CFileMgr FileMgr;
vector<CString> FilePathVec;
FileMgr.GetChildFileOrDirName(false,RecipePath,FilePathVec,RECIPE_FILE_SUFFIX);
int size = FilePathVec.size();
for(int k=0;k<size;k++)
{
SelGroupRecipeNameVec.push_back(FileMgr.GetFileNameFromPath(FilePathVec[k],true));
}
}
CString CRecipeMgr::RecipeCtrlExcute(CRecipeCtrlItem &CtrlItem)
{
CString CtrlStr;
CString ErrMsg;
CString &EditName1 = *(CtrlItem.m_EditName1);
CString &EditName2 = *(CtrlItem.m_EditName2);
CString &SelGroupName = CtrlItem.m_SelGroupName;
bool bUpdateRecipeGroup = false;
ERecipeCtrlType RecipeCtrlType = GetCurRecipeCtrlType();
if(RecipeCtrlType==_RecipeCtrl_AddGroup
||RecipeCtrlType==_RecipeCtrl_GroupName
||RecipeCtrlType==_RecipeCtrl_RecipeName
||RecipeCtrlType==_RecipeCtrl_AddRecipe)
{
if(EditName2.Find('.',0)!= -1)
{
ErrMsg = "不能有小数点!";
return ErrMsg;
}
if(EditName2=="")
{
ErrMsg = "输入不能为空!";
return ErrMsg;
}
}
switch(RecipeCtrlType)
{
case _RecipeCtrl_AddGroup:
AddRecipeGroup(EditName2);
CtrlStr = EditName2;
bUpdateRecipeGroup = true;
break;
case _RecipeCtrl_DelGroup:
DeleteRecipeGroup(EditName2);
CtrlStr = EditName2;
bUpdateRecipeGroup = true;
break;
case _RecipeCtrl_GroupName:
ChangeGroupName(EditName2);
CtrlStr = EditName1 + "->" + EditName2;
bUpdateRecipeGroup = true;
break;
case _RecipeCtrl_RecipeName:
ChangeRecipeName(EditName2);
CtrlStr = EditName1 + "->" + EditName2;
bUpdateRecipeGroup = false;
break;
case _RecipeCtrl_AddRecipe:
AddRecipe(SelGroupName,EditName2);
CtrlStr = EditName2 + " To Group : " + SelGroupName;
break;
case _RecipeCtrl_DelRecipe:
DeletRecipe(EditName2);
CtrlStr = EditName2 + "Delete From Group: " + EditName1;
break;
case _RecipeCtrl_MoveRecipe:
MoveRecipe(SelGroupName,EditName2);
CtrlStr = EditName2 + " To Group : " + SelGroupName;
break;
case _RecipeCtrl_CopyRecipe:
CopyRecipe(EditName2);
CtrlStr = EditName1 + "Copy To: " + EditName2;
break;
case _RecipeCtrl_AddSubRecipe:
AddSubRecipe(EditName2);
CtrlStr = EditName2 + " To Recipe : " + EditName1;
break;
case _RecipeCtrl_DelSubRecipe:
DelSubRecipe(EditName2);
CtrlStr = EditName2 + " From Recipe : " + EditName1;
break;
case _RecipeCtrl_SubRecipeName:
ChangeSubRecipeName(EditName2);
CtrlStr = EditName1 + "->" + EditName2;
break;
default:
break;
}
if(bUpdateRecipeGroup)
{
UpdateRecipeGroupVec();
UpdateRecipeGroupComb(m_pRecipeGroupComb);
}
CString CtrlName = "RecipeCtrl-->";
CtrlName += GetRecipeCtrlName(RecipeCtrlType);
CtrlName += " : ";
CString Log = CtrlName + CtrlStr;
gLogMgr->WriteDebugLog(Log);
return ErrMsg;
}
bool CRecipeMgr::EditRecipeByCtrlType(ERecipeCtrlType CtrlType)
{
CString ErrMsg;
//检查执行条件
switch(CtrlType)
{
case _RecipeCtrl_AddGroup:
break;
case _RecipeCtrl_AddRecipe:
break;
case _RecipeCtrl_GroupName:
if(m_CurSelGroupName=="")
{
ErrMsg = "没有选择要操作的group";
}
break;
case _RecipeCtrl_RecipeName:
case _RecipeCtrl_MoveRecipe:
case _RecipeCtrl_CopyRecipe:
case _RecipeCtrl_DelRecipe:
case _RecipeCtrl_AddSubRecipe:
case _RecipeCtrl_DelSubRecipe:
if(!IsbSelEditRecipe())
ErrMsg = "没有选择要操作的Recipe";
break;
default:
break;
}
if(ErrMsg=="" && CtrlType==_RecipeCtrl_DelSubRecipe)
{
if(m_CurEditRecipe.GetSubRecipeVec().size()<=1)
ErrMsg = "只有一个sub Recipe 不能删除";
}
if(ErrMsg!="")
{
CMsgBox MsgBox;
MsgBox.Show(ErrMsg);
return false;
}
m_CurRecipeCtrlType = CtrlType;
CDlgRecipeCtrl dlg;
return (dlg.DoModal()==IDOK);
}
//添加一个sub recipe 到当前编辑的recipe 中
void CRecipeMgr::AddSubRecipe(CString SubRecipeName)
{
m_CurEditRecipe.AddSubRecipe(SubRecipeName);
//保存
CString RecipeFilePath = GetCtrlRecipeFilePath(m_CurSelGroupName,m_CurEditRecipe.m_RecipeName);
SaveRecipeToXml(m_CurEditRecipe.m_FilePath,m_CurEditRecipe);
CRecipeCtrlPar RecipeCtrlPar;
RecipeCtrlPar.m_CtrlType = _RecipeCtrl_AddSubRecipe;
RecipeCtrlPar.m_FilePath = RecipeFilePath;
RecipeCtrlPar.m_RcpName = m_CurEditRecipe.m_RecipeName;
RecipeCtrlPar.m_SubRcpName = SubRecipeName;
SaveRecipeHistoy(RecipeCtrlPar);
}
void CRecipeMgr::DelSubRecipe(CString SubRecipeName)
{
m_CurEditRecipe.DelSubRecipe(SubRecipeName);
//保存
CString RecipeFilePath = GetCtrlRecipeFilePath(m_CurSelGroupName,m_CurEditRecipe.m_RecipeName);
SaveRecipeToXml(m_CurEditRecipe.m_FilePath,m_CurEditRecipe);
CRecipeCtrlPar RecipeCtrlPar;
RecipeCtrlPar.m_CtrlType = _RecipeCtrl_DelSubRecipe;
RecipeCtrlPar.m_FilePath = RecipeFilePath;
RecipeCtrlPar.m_RcpName = m_CurEditRecipe.m_RecipeName;
RecipeCtrlPar.m_SubRcpName = SubRecipeName;
SaveRecipeHistoy(RecipeCtrlPar);
}
//移动SubRecipe 的顺序
bool CRecipeMgr::MoveSubRecipe(bool bMoveUp)
{
if(!IsbSelEditRecipe())
{
CMsgBox MsgBox;
MsgBox.Show("没有选择要操作的Recipe");
return false;
}
int CurSubRecipeIdx = m_CurEditRecipe.m_CurSubRecipeIdx;
int SwapSubRecipeIdx = (bMoveUp)?(CurSubRecipeIdx-1):(CurSubRecipeIdx+1);//交换的索引值
vector<CSubRecipe> &SubRecipeVec = m_CurEditRecipe.GetSubRecipeVec();
int size = SubRecipeVec.size();
if(SwapSubRecipeIdx >=0 && SwapSubRecipeIdx<size && SwapSubRecipeIdx != CurSubRecipeIdx)
{
swap(SubRecipeVec[CurSubRecipeIdx],SubRecipeVec[SwapSubRecipeIdx]);
m_CurEditRecipe.m_CurSubRecipeIdx = SwapSubRecipeIdx;//更新当前选择项目
return true;
}
return false;
}
void CRecipeMgr::SetSubRecipeIdx(int idx)
{
vector<CSubRecipe> &SubRecipeVec = m_CurEditRecipe.GetSubRecipeVec();
int size = SubRecipeVec.size();
if(idx>=0&&idx<size)
{
m_CurEditRecipe.SetCurSubRecipeIdx(idx);
}
}
void CRecipeMgr::OnSelRecipeIdxChange(int idx)
{
SetCurSelRecipeName("");
int size = m_CurSelGroupRecipeNameVec.size();
if(idx>=0&&idx<size)
{
SetCurSelRecipeName(m_CurSelGroupRecipeNameVec[idx]);
}
}
CString CRecipeMgr::GetCurEditRecipeInfo()
{
CString RecipeInfo;
if(IsbSelEditRecipe())
{
RecipeInfo = m_CurEditRecipe.m_FilePath;
}
return RecipeInfo;
}
CString CRecipeMgr::GetCurEditSubRecipeInfo()
{
CString SubRecipeInfo;
if(IsbSelEditRecipe())
{
SubRecipeInfo = m_CurEditRecipe.GetCurSubRecipeName();
}
return SubRecipeInfo;
}
//选择当前recipe 的扫描区域
void CRecipeMgr::SelRecipeScanArea(CComboBox &ComboBox)
{
}
#endif
#if 1
//保存recipe 到XML 文件(如果Xml 已存在,会覆盖)
void CRecipeMgr::SaveRecipeToXml(CString FilePath,CRecipe &Recipe)
{
CMyXmlItem XmlItemRoot;//根节点
XmlItemRoot.m_XmlItemName = "Root";
int SubRecipeCnt = Recipe.m_SubRecipeVec.size();
for(int k=0;k<SubRecipeCnt;k++)
{
CSubRecipe &SubRecipe = Recipe.m_SubRecipeVec[k];
CMyXmlItem XmlItemSubRecipe;
XmlItemSubRecipe.m_XmlItemName = "SubRecipe";
XmlItemSubRecipe.m_XmlItemAttributeName = "Name";
XmlItemSubRecipe.m_XmlItemAttributeVal = SubRecipe.m_SubRecipeName;
int size = SubRecipe.m_RecipeParVec.size();
for(int i=0;i<size;i++)
{
CRecipeParameter &RecipePar = SubRecipe.m_RecipeParVec[i];
if(RecipePar.m_bRcpInfoPar)//跳过非编辑参数
continue;
CMyXmlItem XmlItemPar;
XmlItemPar.m_XmlItemName = "RecipePar";
XmlItemPar.m_XmlItemAttributeName = "Name";
XmlItemPar.m_XmlItemAttributeVal = RecipePar.m_ParName;//参数名
{//参数类型
CMyXmlItem XmlItemParName;
XmlItemParName.m_XmlItemName = XML_ITEM_PAR_TYPE;
CMyXmlItem XmlItemParVal;
XmlItemParVal.m_XmlItemName = RecipePar.GetParTypeStr();
XmlItemParName.AddXmlItem(XmlItemParVal);
XmlItemPar.AddXmlItem(XmlItemParName);
}
{//参数值
CMyXmlItem XmlItemParName;
XmlItemParName.m_XmlItemName = XML_ITEM_PAR_VAL;
CMyXmlItem XmlItemParVal;
XmlItemParVal.m_XmlItemName = RecipePar.GetParStr();
XmlItemParName.AddXmlItem(XmlItemParVal);
XmlItemPar.AddXmlItem(XmlItemParName);
}
XmlItemSubRecipe.AddXmlItem(XmlItemPar);
}
XmlItemRoot.AddXmlItem(XmlItemSubRecipe);
}
CString Log("Save Rcp : ");
Log += FilePath;
gLogMgr->WriteDebugLog(Log);
CMyXmlMgr XmlMgr;
XmlMgr.SaveXmlItemToFile(FilePath,XmlItemRoot);
Log += " Complete" ;
gLogMgr->WriteDebugLog(Log);
}
//从xml 文件中读取Recipe 参数
bool CRecipeMgr::ReadRecipeFromXml(CString FilePath,CRecipe &Recipe)
{
CMyXmlMgr XmlMgr;
CMyXmlItem XmlItemRoot;
XmlMgr.ReadXmlItemFromFile(FilePath,XmlItemRoot);
vector<CMyXmlItem> &SubRecipeVec = XmlItemRoot.m_XmlItemVec;
int SubRecipeCnt = SubRecipeVec.size();
if(SubRecipeCnt<=0)
{
return false;
}
Recipe.m_FilePath = FilePath;
Recipe.m_SubRecipeVec.clear();
Recipe.m_CurSubRecipeIdx = 0;
for(int i=0;i<SubRecipeCnt;i++)
{
CMyXmlItem &XmlItemSubRecipe = SubRecipeVec[i];
//恢复Sub Recipe 的参数
CSubRecipe SubRecipe;
SubRecipe.m_SubRecipeName = XmlItemSubRecipe.m_XmlItemAttributeVal;
vector<CMyXmlItem> &RecipeParVec = XmlItemSubRecipe.m_XmlItemVec;
int ParCnt = RecipeParVec.size();
for(int j=0;j<ParCnt;j++)
{
CMyXmlItem &XmlItemRecipePar = RecipeParVec[j];
CRecipeParameter XmlRecipePar;
XmlRecipePar.m_ParName = XmlItemRecipePar.m_XmlItemAttributeVal;
vector<CMyXmlItem> &RecipeParInfoVec = XmlItemRecipePar.m_XmlItemVec;
int ParInfoCnt = RecipeParInfoVec.size();
for(int k=0;k<ParInfoCnt;k++)
{
CMyXmlItem &XmlItemParInfo = RecipeParInfoVec[k];
CString ParInfoName = XmlItemParInfo.m_XmlItemName;
CString ParInfoVal;
vector<CMyXmlItem> &RecipeParInfoValVec = XmlItemParInfo.m_XmlItemVec;
if(!RecipeParInfoValVec.empty())
{
ParInfoVal = RecipeParInfoValVec[0].m_XmlItemName;
}
if(ParInfoName==XML_ITEM_PAR_TYPE)
{
XmlRecipePar.SetTypeByStr(ParInfoVal);
}
if(ParInfoName==XML_ITEM_PAR_VAL)
{
XmlRecipePar.SetValByStr(ParInfoVal);
}
}
vector<CRecipeParameter> &SubRecipeParVec = SubRecipe.m_RecipeParVec;
int SubRecipeParCnt = SubRecipeParVec.size();
for(int m=0;m<SubRecipeParCnt;m++)
{
CRecipeParameter &RecipePar = SubRecipeParVec[m];
if(RecipePar.m_ParName == XmlRecipePar.m_ParName)
{
RecipePar.m_ParBoolVal= XmlRecipePar.m_ParBoolVal;
RecipePar.m_ParDoubleVal= XmlRecipePar.m_ParDoubleVal;
RecipePar.m_ParStrVal= XmlRecipePar.m_ParStrVal;
RecipePar.m_ParIntVal= XmlRecipePar.m_ParIntVal;
break;
}
}
}
Recipe.m_SubRecipeVec.push_back(SubRecipe);
}
CString Log("Read Rcp : ");
Log += FilePath;
gLogMgr->WriteDebugLog(Log);
return true;
}
//创建当前检测数据目录
CString CRecipeMgr::CreatCurParDataPath()
{
CString MonitoringDataPath = gProgramLaserTuiHuo->GetLaipuLaserDataDir(PARA_MODIFY_DATA_PATH);
CString Path = MonitoringDataPath;
CFileMgr FileMgr;
CWorkTime WorkTime;
Path += WorkTime.GetCurYear();
Path += "\\"+WorkTime.GetCurMonth();
Path += "\\"+WorkTime.GetCurDay();
Path += "\\";
if(!FileMgr.IsDirectoryExists(Path))
{
FileMgr.CreatDir(Path);
}
return Path;
}
void CRecipeMgr::ResetParIdxSet()
{
m_ErrRangeParIdxSet.clear();
m_ChangeParIdxSet.clear();
}
//保存当前编辑的recipe
bool CRecipeMgr::SaveEditRecipePar(CListCtrl &ListCtrl,CListCtrl &RecipeInfoList)
{
CMsgBox MsgBox;
ResetParIdxSet();
if(!IsbSelEditRecipe())
{
MsgBox.Show("没有选择要操作的Recipe");
return false;
}
CWorkTime WorkTime;
bool bHasParChange = false;//是否有参数变化
CCsvData CsvData;
CsvData.AddData("用户",false);
CsvData.AddData(gAuthorityMgr->GetCurUserName(),true);
CsvData.AddData("操作时间",false);
CsvData.AddData(WorkTime.GetDateTime("/",":"),true);
CsvData.AddData("Recipe Name",false);
CsvData.AddData(m_CurEditRecipe.m_RecipeName,true);
CsvData.AddData("SubRecipe Name",false);
CsvData.AddData(m_CurEditRecipe.GetCurSubRecipeName(),true);
CsvData.AddData("SubRecipe Idx",false);
CsvData.AddData(Int2CString(m_CurEditRecipe.GetCurSubRecipeIdx()),true);
CsvData.AddData("rcp路径",false);
CsvData.AddData(m_CurEditRecipe.m_FilePath,true);
CsvData.AddData(" ",false);
CsvData.AddData(" ",true);
CsvData.AddData("参数名",false);
CsvData.AddData("参数值",false);
CsvData.AddData("修改值",true);
CRecipe RecipeTmp = m_CurEditRecipe;//临时recipe 用来记录range 出错的时候的临时值
bool bLaser1EdiZero = false;//Edi 是否为0
bool bLaser2EdiZero = false;
bool bRangeCheckOk = true;//参数范围检查
vector<CRecipeParameter> &RecipeParVec = m_CurEditRecipe.GetRecipeParVec();
vector<CRecipeParameter> &RecipeParVecTmp = RecipeTmp.GetRecipeParVec();
int size = RecipeParVec.size();
for(int k=0;k<size;k++)
{
CString ParValOld,ParValNew;
CString Log("RecipePar : ");
CRecipeParameter &RecipePar = RecipeParVec[k];
CRecipeParameter &RecipeParTmp = RecipeParVecTmp[k];
ParValOld = RecipePar.GetParStr();
Log += RecipePar.m_ParShowName;
Log += "[";
Log += ParValOld;
Log += "]->[";
CString ParValStr = ListCtrl.GetItemText(k,Rcp_List_Val_Col);
if(RecipePar.m_ParType==_RecipeParType_Double)
{
double Val = CStringToDouble(ParValStr);
if(!(Val>=RecipePar.m_DoubleMinVal && Val<=RecipePar.m_DoubleMaxVal))
{
bRangeCheckOk = false;
RecipeParTmp.m_ParDoubleVal = CStringToDouble(ParValStr);
m_ErrRangeParIdxSet.insert(k);
}
else
{
RecipePar.m_ParDoubleVal = CStringToDouble(ParValStr);
RecipeParTmp.m_ParDoubleVal = RecipePar.m_ParDoubleVal;
if(RecipePar.m_ParName==RECIPE_PAR_NAME_LASER_EDI_1 && IsDbEqualZero(RecipePar.m_ParDoubleVal))
{
bLaser1EdiZero = true;
}
if(RecipePar.m_ParName==RECIPE_PAR_NAME_LASER_EDI_2 && IsDbEqualZero(RecipePar.m_ParDoubleVal))
{
bLaser2EdiZero = true;
}
}
}
else if(RecipePar.m_ParType==_RecipeParType_Bool)
{
RecipePar.m_ParBoolVal = (ParValStr==BOOL_STR_ON)?true:false;
RecipeParTmp.m_ParBoolVal = RecipePar.m_ParBoolVal;
}
else if(RecipePar.m_ParType==_RecipeParType_Int)
{
RecipePar.m_ParIntVal = CStringToDouble(ParValStr);
RecipeParTmp.m_ParIntVal = RecipePar.m_ParIntVal;
}
else if(RecipePar.m_ParType==_RecipeParType_CString)
{
RecipePar.m_ParStrVal = ParValStr;
RecipeParTmp.m_ParStrVal = RecipePar.m_ParStrVal;
}
ParValNew = RecipePar.GetParStr();
Log += ParValNew;
Log += "]";
gLogMgr->WriteDebugLog(Log);
//只记录非计算参数
if(!RecipePar.m_bRcpInfoPar)
{
if(ParValOld!=ParValNew)
{
bHasParChange = true;
m_ChangeParIdxSet.insert(k);
}
else//无变化
{
ParValNew = "";
}
CsvData.AddData(RecipePar.m_ParShowName,false);
CsvData.AddData(ParValOld,false);
CsvData.AddData(ParValNew,true);
}
}
//更新recipe 的非设置参数
UpdateEditRecipeList(ListCtrl,RecipeInfoList,false);
//检查计算参数的范围
{
vector<CRecipeParameter> &RecipeParVec = m_CurEditRecipe.GetRecipeParVec();
int size = RecipeParVec.size();
for(int k=0;k<size;k++)
{
CRecipeParameter &RecipePar = RecipeParVec[k];
if(!RecipePar.m_bRcpInfoPar)
continue;
if(RecipePar.m_ParType==_RecipeParType_Double)
{
if(!(RecipePar.m_ParDoubleVal>=RecipePar.m_DoubleMinVal && RecipePar.m_ParDoubleVal<=RecipePar.m_DoubleMaxVal))
{
//edi为0的时候dimmer ang == nan不要提示错误
if(RecipePar.m_ParName==RECIPE_PAR_NAME_ROTATO_DIMMER_ANG && bLaser1EdiZero)
continue;
if(RecipePar.m_ParName==RECIPE_PAR_NAME_ROTATO_DIMMER_ANG2 && bLaser2EdiZero)
continue;
bRangeCheckOk = false;
m_ErrRangeParIdxSet.insert(k);
}
}
}
}
//刷新list 显示
UpdateEditRecipeListExt(ListCtrl,RecipeTmp);
if(!bRangeCheckOk)
{
MsgBox.Show("参数范围检查失败");
return false;
}
//保存修改记录
if(bHasParChange)//有变化时才保存
{
CString FileName = WorkTime.GetCurTime("_");
FileName += "_";
FileName += m_CurEditRecipe.m_RecipeName;
CString DataPath = CreatCurParDataPath();
CFileMgr FileMgr;
FileMgr.WriteDataToExcel(DataPath,FileName,CsvData,false);
}
CString RecipeFilePath = GetCtrlRecipeFilePath(m_CurSelGroupName,m_CurEditRecipe.m_RecipeName);
SaveRecipeToXml(m_CurEditRecipe.m_FilePath,m_CurEditRecipe);
CString s = m_CurEditRecipe.m_RecipeName;
if(bHasParChange)
s += " 修改成功";
else
s += " 参数无变化";
MsgBox.Show(s);
return true;
}
//保存recipe的操作记录
void CRecipeMgr::SaveRecipeHistoy(CRecipeCtrlPar RecipeCtrlPar)
{
CWorkTime WorkTime;
CCsvData CsvData;
CsvData.AddData("用户",false);
CsvData.AddData(gAuthorityMgr->GetCurUserName(),true);
CsvData.AddData("操作时间",false);
CsvData.AddData(WorkTime.GetDateTime("/",":"),true);
CsvData.AddData("rcp路径",false);
CsvData.AddData(RecipeCtrlPar.m_FilePath,true);
CsvData.AddData("操作类型",false);
CsvData.AddData(GetRecipeCtrlName(RecipeCtrlPar.m_CtrlType),true);
CsvData.AddData("Recipe Name",false);
CsvData.AddData(RecipeCtrlPar.m_RcpName,true);
switch(RecipeCtrlPar.m_CtrlType)
{
case _RecipeCtrl_CopyRecipe:
{
CsvData.AddData("Copy Recipe Name",false);
CsvData.AddData(RecipeCtrlPar.m_RcpNameNew,true);
}
break;
case _RecipeCtrl_RecipeName:
{
CsvData.AddData("New Recipe Name",false);
CsvData.AddData(RecipeCtrlPar.m_RcpNameNew,true);
}
break;
case _RecipeCtrl_MoveRecipe:
{
CsvData.AddData("rcp移动路径",false);
CsvData.AddData(RecipeCtrlPar.m_NewFilePath,true);
}
break;
case _RecipeCtrl_AddSubRecipe:
case _RecipeCtrl_DelSubRecipe:
{
CsvData.AddData("Sub Recipe Name",false);
CsvData.AddData(RecipeCtrlPar.m_SubRcpName,true);
}
break;
default:
break;
}
CString FileName = WorkTime.GetCurTime("_");
FileName += "_";
FileName += RecipeCtrlPar.m_RcpName;
CString DataPath = CreatCurParDataPath();
CFileMgr FileMgr;
FileMgr.WriteDataToExcel(DataPath,FileName,CsvData,false);
}
//更新当前的无效参数索引值
void CRecipeMgr::UpdateInvalidParIdxSet(CRecipe &Recipe)
{
m_InvalidParIdxSet.clear();
CRecipeParameter RecipePar;
//edi check scope 为0 时参数无效,使用config 参数
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_EDI_CHECK_SCOPE);
if(IsDbEqualZero(RecipePar.m_ParDoubleVal))
m_InvalidParIdxSet.insert(Rcp_EdiScope_Idx);
//如果设置了固定扫描速度,重叠率X 无效
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_FIX_SCAN_SPEED);
if(!IsDbEqualZero(RecipePar.m_ParDoubleVal))
m_InvalidParIdxSet.insert(Rcp_OverlapX_Idx);
else
m_InvalidParIdxSet.insert(Rcp_FixSpeed_Idx);
//如果设置了固定扫描间隔,重叠率Y 无效
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_FIX_SCAN_LINE_GAP);
if(!IsDbEqualZero(RecipePar.m_ParDoubleVal))
m_InvalidParIdxSet.insert(Rcp_OverlapY_Idx);
else
m_InvalidParIdxSet.insert(Rcp_FixGap_Idx);
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_OFFSET_TAB);
if(RecipePar.m_ParStrVal ==RECIPE_OFFSET_TBL_NULL)
m_InvalidParIdxSet.insert(Rcp_OffsetTab_Idx);
}
#endif
#if 1
//更新recipe 的非设置参数
bool CRecipeMgr::UpdateRecipeInfoPar(CRecipe &Recipe)
{
CString log;
log = "Flow---->UpdateRecipeInfoPar : ";
log += Recipe.m_RecipeName;
gLogMgr->WriteDebugLog(log);
//更新系统参数
gLaser->UpdateLaserProp();
int BakSubRecipeIdx = Recipe.GetCurSubRecipeIdx();//用于恢复
vector<CSubRecipe> &SubRecipeVec = Recipe.GetSubRecipeVec();
int size = SubRecipeVec.size();
for(int k=0;k<size;k++)
{
Recipe.SetCurSubRecipeIdx(k);//标记当前处理的SubRecipe
CRecipeParameter RecipePar;
double OverlapRatio;//扫描重叠率
double Laser1Fre,Laser2Fre;//脉冲频率
double Laser1Edi;//Laser1功率密度
double Laser2Edi;//Laser2功率密度
double Laser1EdiOffset;//Laser1功率密度Offset
double Laser2EdiOffset;//Laser2功率密度Offset
DbSize SpotSize = gLaser->GetSpotSize(_LaserDeviceType_MainLaser1);//光斑尺寸
if(gLaser->IsbScanByDirX())
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_OVERLAP_RATIO_X);
else
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_OVERLAP_RATIO_Y);
OverlapRatio = RecipePar.m_ParDoubleVal;
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_LASER_FRE);
Laser1Fre = RecipePar.m_ParDoubleVal;
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_LASER2_FRE);
Laser2Fre = RecipePar.m_ParDoubleVal;
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_LASER_EDI_1);
Laser1Edi = RecipePar.m_ParDoubleVal;
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_LASER_EDI_2);
Laser2Edi = RecipePar.m_ParDoubleVal;
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_LASER_EDI_OFFSET_1);
Laser1EdiOffset = RecipePar.m_ParDoubleVal;
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_LASER_EDI_OFFSET_2);
Laser2EdiOffset = RecipePar.m_ParDoubleVal;
//重叠率/频率/光斑尺寸---->扫描速度
double ScanSpeed = gWaferRecipeDataMgr->CalScanSpeedByOverlapRatio(OverlapRatio,Laser1Fre);
if(ScanSpeed>0)
{
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_SCAN_SPEED);
RecipePar.m_ParDoubleVal = ScanSpeed;
Recipe.SetRecipePar(RECIPE_PAR_NAME_SCAN_SPEED,RecipePar);
}
//电流是Recipe 中的设定值
//功率是固定电流点检对应的功率值(还和频率有关)
double Laser1FixCurr = 0;
double Laser2FixCurr = 0;
{
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_LASER_CURR_1);
Laser1FixCurr = RecipePar.m_ParDoubleVal;
Recipe.SetRecipePar(RECIPE_PAR_NAME_LASER_CURR_1,RecipePar);
}
{
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_LASER_CURR_2);
Laser2FixCurr = RecipePar.m_ParDoubleVal;
Recipe.SetRecipePar(RECIPE_PAR_NAME_LASER_CURR_2,RecipePar);
}
double Laser1FixPow = 0;
double Laser2FixPow = 0;
gLaser->GetLaserFixedCurrentPow(_LaserDeviceType_MainLaser1,Laser1Fre,Laser1FixCurr,Laser1FixPow);
gLaser->GetLaserFixedCurrentPow(_LaserDeviceType_MainLaser2,Laser2Fre,Laser2FixCurr,Laser2FixPow);
{
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_LASER1_POW);
RecipePar.m_ParDoubleVal = Laser1FixPow;
Recipe.SetRecipePar(RECIPE_PAR_NAME_LASER1_POW,RecipePar);
}
{
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_LASER2_POW);
RecipePar.m_ParDoubleVal = Laser2FixPow;
Recipe.SetRecipePar(RECIPE_PAR_NAME_LASER2_POW,RecipePar);
}
//读取功率补偿表
{
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_OFFSET_TAB);
CString OffsetTableName = RecipePar.m_ParStrVal;
if(!Recipe.ReadOffsetTableFile(OffsetTableName))
{
//标记为异常
m_ErrRangeParIdxSet.insert(Rcp_OffsetTab_Idx);
}
}
//[功率密度/频率/光斑尺寸]--->[衰减器的旋转角度]
{
double OffsetTabEdi = Recipe.GetOffsetParVal(RECIPE_OFFSET_PAR_LASER1_EDI);
double Edi = Laser1Edi + Laser1EdiOffset + OffsetTabEdi;
double RotatoDimmerAng = gWaferRecipeDataMgr->CalRotatoDimmerAng(SpotSize.w,SpotSize.h,Edi,Laser1Fre,Laser1FixPow);
if(!(RotatoDimmerAng>-180 && RotatoDimmerAng<180))//无效计算范围
{
log.Format("Err Ang = %lf",RotatoDimmerAng);
gLogMgr->WriteDebugLog(log);
}
{
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_ROTATO_DIMMER_ANG);
RecipePar.m_ParDoubleVal = RotatoDimmerAng;
Recipe.SetRecipePar(RECIPE_PAR_NAME_ROTATO_DIMMER_ANG,RecipePar);
}
}
{
double OffsetTabEdi = Recipe.GetOffsetParVal(RECIPE_OFFSET_PAR_LASER2_EDI);
double Edi = Laser2Edi + Laser2EdiOffset + OffsetTabEdi;
double RotatoDimmerAng = gWaferRecipeDataMgr->CalRotatoDimmerAng(SpotSize.w,SpotSize.h,Edi,Laser2Fre,Laser2FixPow);
if(!(RotatoDimmerAng>-180 && RotatoDimmerAng<180))//无效计算范围
{
log.Format("Err Ang = %lf",RotatoDimmerAng);
gLogMgr->WriteDebugLog(log);
}
{
RecipePar = Recipe.GetRecipePar(RECIPE_PAR_NAME_ROTATO_DIMMER_ANG2);
RecipePar.m_ParDoubleVal = RotatoDimmerAng;
Recipe.SetRecipePar(RECIPE_PAR_NAME_ROTATO_DIMMER_ANG2,RecipePar);
}
}
}
Recipe.SetCurSubRecipeIdx(BakSubRecipeIdx);//恢复
return true;
}
//通过参数名获取当前的recipe 参数
CRecipeParameter CRecipeMgr::GetCurRecipePar(CString ParName)
{
return m_CurWorkRecipe.GetRecipePar(ParName);
}
void CRecipeMgr::CreatCurEditRecipeScanPath()
{
//打开扫描区域
CRecipe &CurEditRecipe = m_CurEditRecipe;
CRecipeParameter RecipePar = CurEditRecipe.GetRecipePar(RECIPE_PAR_NAME_SCAN_AREA);
CString AreaName = RecipePar.m_ParStrVal;
RecipePar = CurEditRecipe.GetRecipePar(RECIPE_PAR_NAME_AREA_IDX);
int AreaIdx = RecipePar.m_ParIntVal-1;
CreatScanPath(AreaName,AreaIdx);
}
#endif
#if 1
void CRecipeMgr::UpdateEditRecipeListExt(CRecipe &Recipe,CListCtrl &RecipeList,CListCtrl &RecipeInfoList)
{
if(!Recipe.IsValid())
return;
RecipeList.DeleteAllItems();
RecipeInfoList.DeleteAllItems();
//更新recipe 的非设置参数
UpdateRecipeInfoPar(Recipe);
vector<CRecipeParameter> &RecipeParVec = Recipe.GetRecipeParVec();
int size = RecipeParVec.size();
if(size<=0)
return;
int RecipeListIdx = 0;
int RecipeInfoListIdx = 0;
for(int k=0;k<size;k++)
{
int idx = 0;
CRecipeParameter &RecipePar = RecipeParVec[k];
if(RecipePar.m_bRcpInfoPar)//计算参数
{
RecipeInfoList.InsertItem(RecipeInfoListIdx," ");//插入一行
RecipeInfoList.SetItemText(RecipeInfoListIdx,idx++,Int2CString(RecipeInfoListIdx+1));//序号
RecipeInfoList.SetItemText(RecipeInfoListIdx,idx++,RecipePar.m_ParShowName);//参数名
RecipeInfoList.SetItemText(RecipeInfoListIdx,idx++,RecipePar.m_ParUnit);//参数单位
RecipeInfoList.SetItemText(RecipeInfoListIdx,idx++,RecipePar.GetParTypeStr());//参数类型
RecipeInfoList.SetItemText(RecipeInfoListIdx,idx++,RecipePar.GetParStr());//参数值
RecipeInfoListIdx++;
}
else
{
RecipeList.InsertItem(RecipeListIdx," ");//插入一行
RecipeList.SetItemText(RecipeListIdx,idx++,Int2CString(RecipeListIdx+1));//序号
RecipeList.SetItemText(RecipeListIdx,idx++,RecipePar.m_ParShowName);//参数名
RecipeList.SetItemText(RecipeListIdx,idx++,RecipePar.m_ParUnit);//参数单位
RecipeList.SetItemText(RecipeListIdx,idx++,RecipePar.GetParTypeStr());//参数类型
RecipeList.SetItemText(RecipeListIdx,idx++,RecipePar.GetParStr());//参数值
RecipeListIdx++;
}
}
}
void CRecipeMgr::UpdateEditSubRecipeListExt(CRecipe &Recipe,CListCtrl &List)
{
List.DeleteAllItems();
vector<CSubRecipe> &SubRecipeVec = Recipe.GetSubRecipeVec();
int size = SubRecipeVec.size();
if(size<=0)
return;
for(int k=0;k<size;k++)
{
int idx = 0;
List.InsertItem(k," ");//插入一行
List.SetItemText(k,idx++,Int2CString(k+1));//序号
List.SetItemText(k,idx++,SubRecipeVec[k].m_SubRecipeName);
}
//高亮选择的行
List.SetItemState(Recipe.m_CurSubRecipeIdx,LVIS_FOCUSED | LVIS_SELECTED,LVIS_FOCUSED | LVIS_SELECTED);
}
//获取RecipeName 对应的文件路径
CString CRecipeMgr::GetRecipePathByName(CString RecipeName)
{
vector<CString> RcpGroupPathVec;
CString DirPath = GetRecipePath();
CFileMgr FileMgr;
//先找到所有组文件夹的路径
FileMgr.GetChildFileOrDirName(true,DirPath,RcpGroupPathVec,"");
//获取所有组文件
int size = RcpGroupPathVec.size();
for(int k=0;k<size;k++)
{
vector<CString> RcpPathVec;
FileMgr.GetChildFileOrDirName(false,RcpGroupPathVec[k],RcpPathVec,RECIPE_FILE_SUFFIX);
int size1 = RcpPathVec.size();
for(int i=0;i<size1;i++)
{
CString Name = FileMgr.GetFileNameFromPath(RcpPathVec[i],true);
if(Name == RecipeName)
return RcpPathVec[i];
}
}
return "";
}
//检查recipe是否存在
bool CRecipeMgr::CheckRecipeNameExist(CString RecipeName)
{
CString RecipePath = GetRecipePathByName(RecipeName);
if(RecipePath != "")
{
CString s;
s = RecipePath + "已存在";
CMsgBox MsgBox;
MsgBox.Show(s);
return false;
}
return true;
}
//更新激光焦距相关config
void CRecipeMgr::UpdateLaserFocusProp()
{
gLogMgr->WriteDebugLog("Func---->UpdateLaserFocusProp");
//激光焦距值
double FocusZMoveUpVal = 0;
{
//添加属性变量映射
CString Path = "Laser";
CString Name = _T("m_FocusZMoveUpVal");//变量名字
CPropertie Propertie;
Propertie.SetpVal((void*)&FocusZMoveUpVal);
Propertie.SetType(_PROP_TYPE_DOUBLE);
Propertie.SetPath(Path);
Propertie.SetName(Name);
Propertie.WriteRead(true);//读取属性
}
//测距仪Z轴坐标
double DistanceMeterPosZ = 0;
{
//添加属性变量映射
CString Path = "PlatSpecialPosMgr";
CString Name = _T("m_SpecialPosTypeDistance_MeterPos_z");//变量名字
CPropertie Propertie;
Propertie.SetpVal((void*)&DistanceMeterPosZ);
Propertie.SetType(_PROP_TYPE_DOUBLE);
Propertie.SetPath(Path);
Propertie.SetName(Name);
Propertie.WriteRead(true);//读取属性
}
//Z轴安全坐标
double MotorZSafeCoord = 0;
{
//添加属性变量映射
CString Path = "PlatSpecialPosMgr";
CString Name = _T("m_MotorZSafeCoord");//变量名字
CPropertie Propertie;
Propertie.SetpVal((void*)&MotorZSafeCoord);
Propertie.SetType(_PROP_TYPE_DOUBLE);
Propertie.SetPath(Path);
Propertie.SetName(Name);
Propertie.WriteRead(true);//读取属性
}
CString log;
log.Format("FocusZMoveUpVal=%f,DistanceMeterPosZ=%f,MotorZSafeCoord=%f",FocusZMoveUpVal,DistanceMeterPosZ,MotorZSafeCoord);
gLogMgr->WriteDebugLog(log);
//计算焦距微调范围
double LaserFocusZ = DistanceMeterPosZ + FocusZMoveUpVal;
m_FocusAdjustMin = (MotorZSafeCoord - LaserFocusZ)+0.5;//向上调0.5mm
m_FocusAdjustMax = (LaserFocusZ*-1)-1;////向下调1 mm
log.Format("LaserFocusZ=%f,FocusAdjustMin=%f,FocusAdjustMax=%f",LaserFocusZ,m_FocusAdjustMin,m_FocusAdjustMax);
gLogMgr->WriteDebugLog(log);
}
//获取TabName 的完整路径
CString CRecipeMgr::GetOffsetTablePath(CString TabName)
{
CString TabPath = gProgramLaserTuiHuo->GetLaipuLaserDataDir(OFFSET_TAB_FILE_PATH);
TabPath += TabName;
TabPath += ".tbl";
return TabPath;
}
#endif
CString CRecipeMgr::GetShowParText(int Row)
{
CString str = "";
vector<CSubRecipe> &SubRecipeVec = m_CurEditRecipe.GetSubRecipeVec();
int size = SubRecipeVec.size();
if (size <= 0)
{
str = "无有效Recipe";
}
str = SubRecipeVec[0].m_RecipeParVec[Row].m_DetailInfo;
return str;
}
#endif