From 2d96a36538df7d59e831aef19622ad01e8b5c02b Mon Sep 17 00:00:00 2001 From: LYW <leeyeanwoo@diteam.co.kr> Date: 금, 21 5월 2021 17:16:36 +0900 Subject: [PATCH] Ongoing90 #3361 CF AOI Review 전설비 Align Cam 비정상 연결 시 팝업 기능 추가 1) Align Cam, Review Cam 비정상 연결 시 팝업 기능 추가 2) 팝업 후 프로그램 종료 기능 추가 3) #3360_CF AOI QD Review WSI XY MotorMoving Error 알람 발생 원인 분석 및 조치 #3359_CF AOI Review REVIEW_LOADING_COMPLETE_TIMEOVER 알람 발생 원인 분석 트러블 조치 포함 --- DitGlassRawMessenger/DitGlassRawMessenger/GlassRawBase.cpp | 4 DitGlassRawMessenger/DitGlassRawMessenger/MacroResultFile.h | 12 + ReviewSystem/ReviewSystem/MainFrm.cpp | 6 ReviewSystem/ReviewSystem/SequenceProcessor_CPJT.cpp | 28 ++ DitGlassRawMessenger/DitGlassRawMessenger/MacroResultFile.cpp | 66 ++++--- DitGlassRawMessenger/Extern/DitGlassRawStruct.h | 17 + ReviewSystem/ReviewSystemSetting/ReviewSystemSettingDlg.cpp | 4 ReviewSystem/ReviewSystemSetting/stdafx.h | 2 ReviewSystem/ReviewSystem/DitGlassRawStruct.h | 135 ++++++++-------- ReviewSystem/ReviewRecipeEditor/ReviewRecipeEditorDlg.cpp | 22 +- ReviewSystem/ReviewRecipeEditor/stdafx.h | 2 ReviewSystem/ReviewSystem/CameraController.cpp | 26 +++ DitGlassRawMessenger/DitGlassRawMessenger/GlassRawCPJT.cpp | 103 +++++++++++- 13 files changed, 292 insertions(+), 135 deletions(-) diff --git a/DitGlassRawMessenger/DitGlassRawMessenger/GlassRawBase.cpp b/DitGlassRawMessenger/DitGlassRawMessenger/GlassRawBase.cpp index 3694c92..2b2092c 100644 --- a/DitGlassRawMessenger/DitGlassRawMessenger/GlassRawBase.cpp +++ b/DitGlassRawMessenger/DitGlassRawMessenger/GlassRawBase.cpp @@ -13,6 +13,7 @@ BOOL CGlassRawBase::WriteBinFile( CgrmGlassRawData* pData ) { + AKLOG("WriteBinFile Start"); CString strFileName; strFileName.Format("%s\\%s", pData->GetGlassData()->m_strPath, pData->GetGlassData()->m_strFileName); FILE* pf = fopen(strFileName.GetBuffer(0), "wb"); @@ -36,9 +37,10 @@ } else { + AKLOG("WriteBinFile Fail"); return FALSE; } - + AKLOG("WriteBinFile Finish"); return TRUE; } diff --git a/DitGlassRawMessenger/DitGlassRawMessenger/GlassRawCPJT.cpp b/DitGlassRawMessenger/DitGlassRawMessenger/GlassRawCPJT.cpp index 675e17c..4430a8c 100644 --- a/DitGlassRawMessenger/DitGlassRawMessenger/GlassRawCPJT.cpp +++ b/DitGlassRawMessenger/DitGlassRawMessenger/GlassRawCPJT.cpp @@ -106,11 +106,14 @@ } strcpy(pData->GetGlassData()->m_strPath, LOCAL_AOIRAWBIN_PATH); + if(!WriteBinFile(pData)) return FALSE; + if (1) ReadMuraFile(pData); + if (WriteAOIFile(pData) == FALSE) return FALSE; @@ -338,6 +341,7 @@ BOOL CGlassRawCPJT::MakeAOIFile( CgrmGlassRawData* pData ) { + AKLOG("MakeAOIFile Start"); m_nWriteRawDefectIdx = 1; _grmGlassData* pGlass = pData->GetGlassData(); @@ -430,7 +434,7 @@ strValue = "ITEM PANEL MODULETYPE MODULEID PROCESSID PRODUCTID STEPID PROD_TYPE BATCHID H_PANELID E_PANELID P_PANELID OPERID COMP_COUNT PPID GRADE CODE R_GRADE MAP_IMAGE L_TIME U_TIME S_TIME E_TIME T_DEFECT TR PR TB TW RB RW T_STACK MAX_AVG_GRAY MAX_PORTION OK_CELL RJ_CELL RW_CELL NR_CELL CSTID SLOT_NO JOB_END TD_DEFECT SD_DEFECT PD_DEFECT SP_DEFECT PAD_GATE PAD_DATA M_DEFECT C_DEFECT BR_DEFECT IMG_COUNT RECIPE SHRINK RAW_CUT"; //53ea strLine += strValue; strLine += "\n"; - strValue = "ITEM SUBPANEL SUBPANELID COORD_X COORD_Y SIZE_X SIZE_Y GATELINE DATALINE GRADE CODE R_GRADE T_DEFECT TD_DEFECT SD_DEFECT PD_DEFECT SP_DEFECT PAD_GATE PAD_DATA M_DEFECT C_DEFECT PRO_IMAGE AVG_GRAY PORTION"; //24ea result 0404nwh �궘�젣 : S_DEFECT CRACK P_SHIFT + strValue = "ITEM SUBPANEL SUBPANELID COORD_X COORD_Y SIZE_X SIZE_Y GATELINE DATALINE GRADE CODE R_GRADE T_DEFECT TD_DEFECT SD_DEFECT PD_DEFECT SP_DEFECT PAD_GATE PAD_DATA M_DEFECT C_DEFECT PRO_IMAGE AVG_GRAY_0 PORTION_0 AVG_GRAY_1 PORTION_1 AVG_GRAY_2 PORTION_2 AVG_GRAY_3 PORTION_3"; //30ea 21-05-12 Mura Data 異붽� strLine += strValue; strLine += "\n"; //210405 //ITEM DEFECT ID DEF_NO COORD_X COORD_Y GATELINE DATALINE SIZE_S SIZE_W SIZE_L SIZE_H GRADE CODE STACK_FLAG STACK_COUNT STACK_STEP IMAGE_FILE DSC_CODE VC_CODE DCR_CODE DEFECT_SIZE REPEAT_DEFECT WSI_HEIGHT CS_HEIGHT C_GRADE GRAY_MIN GRAY_MAX GRAY_AVG GRAY_DEF WSI_IMAGE USE_CCDIMAGE SCAN_NUM CAM_POSITION CCD_NO R_GRAY_MIN R_GRAY_MAX R_GRAY_AVG SCAN_AI REVIEW_AI INS_MODE INS_CHANNEL COMPACTNESS THICKNESS MAJOR MINOR WSI_TYPE DEFECT_TYPE SHRINK @@ -698,9 +702,23 @@ // 31 6 T_STACK // Panel �젙蹂� 08 SD+SP �닔 �엯�젰 SPRINTRAW(12, "%d", pGlassData->m_nDefectNumStackSD + pGlassData->m_nDefectNumStackSP); //32 6 BMDF // Panel �젙蹂� 09 -> 蹂�寃� MAX_AVG_GRAY 04/12 nwh - SPRINTRAW(12, "%5.4f", pGlassData->m_fMaxAvgGray); + if (strlen(pGlassData->m_strMaxAvgGray) == 0) + { + SPRINTRAW(12, "*"); + } + else + { + SPRINTRAW(12, "%s", pGlassData->m_strMaxAvgGray); + } // 33 6 CJ // Panel �젙蹂� 10 -> 蹂�寃� MAX_PORTION 04/12 nwh - SPRINTRAW(12, "%5.6f", pGlassData->m_fMaxPortion); + if (strlen(pGlassData->m_strMaxPortion) == 0) + { + SPRINTRAW(12, "*"); + } + else + { + SPRINTRAW(12, "%s", pGlassData->m_strMaxPortion); + } // 34 6 OK_CELL // OK Cell Count SPRINTRAW(12, "*"); // 35 6 RJ_CELL // RJ Cell Count @@ -884,11 +902,80 @@ SPRINTRAW(12,"*"); } - // 23 6 CRACK -> 23 6 AVG_GRAY 蹂�寃� - SPRINTRAW(12, "%5.4f", pCellData->m_fAvgGray); - - // 24 6 P_SHIFT ->24 6 PORTION - SPRINTRAW(12, "%5.6f", pCellData->m_fPortion); + // 23 12 AVG_GRAY_0 + if (strlen(pCellData->m_strAvgGray_0)) + { + SPRINTRAW(12, "%s", pCellData->m_strAvgGray_0); + } + else + { + SPRINTRAW(12, "*"); + } + + // 24 12 PORTION_0 + if (strlen(pCellData->m_strPortion_0)) + { + SPRINTRAW(12, "%s", pCellData->m_strPortion_0); + } + else + { + SPRINTRAW(12, "*"); + } + + // 25 12 AVG_GRAY_1 + if (strlen(pCellData->m_strAvgGray_1)) + { + SPRINTRAW(12, "%s", pCellData->m_strAvgGray_1); + } + else + { + SPRINTRAW(12, "*"); + } + // 26 12 PORTION_1 + if (strlen(pCellData->m_strPortion_1)) + { + SPRINTRAW(12, "%s", pCellData->m_strPortion_1); + } + else + { + SPRINTRAW(12, "*"); + } + // 27 12 AVG_GRAY_2 + if (strlen(pCellData->m_strAvgGray_2)) + { + SPRINTRAW(12, "%s", pCellData->m_strAvgGray_2); + } + else + { + SPRINTRAW(12, "*"); + } + // 28 12 PORTION_2 + if (strlen(pCellData->m_strPortion_2)) + { + SPRINTRAW(12, "%s", pCellData->m_strPortion_2); + } + else + { + SPRINTRAW(12, "*"); + } + // 29 12 AVG_GRAY_3 + if (strlen(pCellData->m_strAvgGray_3)) + { + SPRINTRAW(12, "%s", pCellData->m_strAvgGray_3); + } + else + { + SPRINTRAW(12, "*"); + } + // 30 12 PORTION_3 + if (strlen(pCellData->m_strPortion_3)) + { + SPRINTRAW(12, "%s", pCellData->m_strPortion_3); + } + else + { + SPRINTRAW(12, "*"); + } SPRINTRAWEND; //以묒슂!!! �젮 留덉�留됱뿉 瑗� �엳�뼱�빞�븿!!!(�궘�젣湲덉�) [源��깭�쁽2020/9/23] } diff --git a/DitGlassRawMessenger/DitGlassRawMessenger/MacroResultFile.cpp b/DitGlassRawMessenger/DitGlassRawMessenger/MacroResultFile.cpp index 565f53b..3423e3d 100644 --- a/DitGlassRawMessenger/DitGlassRawMessenger/MacroResultFile.cpp +++ b/DitGlassRawMessenger/DitGlassRawMessenger/MacroResultFile.cpp @@ -227,26 +227,43 @@ char* pReadPoint = NULL; char *pStr; + CString stranelData = "DATA PANEL"; + CString strSubPanelData = "DATA SUBPANEL"; + CString strMaxAvgGray, strMaxPortion; + while (!feof(pf)) { - pStr = fgets(buffer, 1024, pf); - if (!strncmp(buffer, "DATA,", 5)) continue; + pStr = fgets(buffer, 1024, pf); if (strlen(buffer) <= 0 || pStr == NULL) break; - - //else if (!strncmp(buffer, "DATA\tSUBPANEL\t", 14))// 탭 파싱 - else if (!strncmp(buffer, "DATA SUBPANEL ", 14))// 띄어쓰기 파싱 + + if (!strncmp(buffer, stranelData, strlen(stranelData)))// 띄어쓰기 파싱 { CakParser paser; if (strlen(buffer) <= 0) continue; - paser.process(buffer); + paser.process(buffer, " "); int nTokNum = paser.getTokNum(); - if (nTokNum < 1) continue; + if (nTokNum < 42) continue; + strMaxAvgGray = paser.getTokStr(41); + strMaxPortion = paser.getTokStr(42); + } - if (nTokNum > 0) MacroSubPanel.PRO_IMAGE = paser.getTokStr(20); - if (nTokNum > 1) MacroSubPanel.AVG_GRAY = atof(paser.getTokStr(21)); - if (nTokNum > 2) MacroSubPanel.PORTION = atof(paser.getTokStr(22)); - + if (!strncmp(buffer, strSubPanelData, strlen(strSubPanelData)))// 띄어쓰기 파싱 + { + CakParser paser; + if (strlen(buffer) <= 0) continue; + paser.process(buffer, " "); + int nTokNum = paser.getTokNum(); + if (nTokNum < 31) continue; + MacroSubPanel.PRO_IMAGE = paser.getTokStr(20); + MacroSubPanel.AVG_GRAY_0 = paser.getTokStr(21); + MacroSubPanel.PORTION_0 = paser.getTokStr(22); + MacroSubPanel.AVG_GRAY_1 = paser.getTokStr(24); + MacroSubPanel.PORTION_1 = paser.getTokStr(25); + MacroSubPanel.AVG_GRAY_2 = paser.getTokStr(27); + MacroSubPanel.PORTION_2 = paser.getTokStr(28); + MacroSubPanel.AVG_GRAY_3 = paser.getTokStr(30); + MacroSubPanel.PORTION_3 = paser.getTokStr(31); vecMacroSubPanel.push_back(MacroSubPanel); } @@ -260,23 +277,18 @@ { pGrmMura= pShared->GetCellData(i); - //pGrmMura->clear(); - - strcpy(pGrmMura->m_strProImage, m_vecMacroSubPanel[i].PRO_IMAGE); - pGrmMura->m_fAvgGray = m_vecMacroSubPanel[i].AVG_GRAY; - pGrmMura->m_fPortion = m_vecMacroSubPanel[i].PORTION; - + strcpy(pGrmMura->m_strProImage, m_vecMacroSubPanel[i].PRO_IMAGE.GetBuffer(0)); + strcpy(pGrmMura->m_strAvgGray_0, m_vecMacroSubPanel[i].AVG_GRAY_0.GetBuffer(0)); + strcpy(pGrmMura->m_strPortion_0, m_vecMacroSubPanel[i].PORTION_0.GetBuffer(0)); + strcpy(pGrmMura->m_strAvgGray_1, m_vecMacroSubPanel[i].AVG_GRAY_1.GetBuffer(0)); + strcpy(pGrmMura->m_strPortion_1, m_vecMacroSubPanel[i].PORTION_1.GetBuffer(0)); + strcpy(pGrmMura->m_strAvgGray_2, m_vecMacroSubPanel[i].AVG_GRAY_2.GetBuffer(0)); + strcpy(pGrmMura->m_strPortion_2, m_vecMacroSubPanel[i].PORTION_2.GetBuffer(0)); + strcpy(pGrmMura->m_strAvgGray_3, m_vecMacroSubPanel[i].AVG_GRAY_3.GetBuffer(0)); + strcpy(pGrmMura->m_strPortion_3, m_vecMacroSubPanel[i].PORTION_3.GetBuffer(0)); } - float Max_AVG_GRAY = m_vecMacroSubPanel[0].AVG_GRAY; - float Max_PORTION = m_vecMacroSubPanel[0].PORTION; - - for (int i = 1; i < m_vecMacroSubPanel.size(); ++i) - { - Max_AVG_GRAY = max(Max_AVG_GRAY, m_vecMacroSubPanel[i].AVG_GRAY); //큰 값을 다시 largest에 대입 - Max_PORTION = max(Max_PORTION, m_vecMacroSubPanel[i].PORTION); - } - pShared->GetGlassData()->m_fMaxAvgGray = Max_AVG_GRAY; - pShared->GetGlassData()->m_fMaxPortion = Max_PORTION; + strcpy(pShared->GetGlassData()->m_strMaxAvgGray, strMaxAvgGray.GetBuffer(0)); + strcpy(pShared->GetGlassData()->m_strMaxPortion, strMaxPortion.GetBuffer(0)); m_bReadSuccess = TRUE; return TRUE; diff --git a/DitGlassRawMessenger/DitGlassRawMessenger/MacroResultFile.h b/DitGlassRawMessenger/DitGlassRawMessenger/MacroResultFile.h index c107512..fdd2ee2 100644 --- a/DitGlassRawMessenger/DitGlassRawMessenger/MacroResultFile.h +++ b/DitGlassRawMessenger/DitGlassRawMessenger/MacroResultFile.h @@ -124,9 +124,15 @@ ///0404nwh struct _MacroSubPanel { - CString PRO_IMAGE; - float AVG_GRAY; - float PORTION; + CString PRO_IMAGE; + CString AVG_GRAY_0; // 0 Scan 0 Model + CString PORTION_0; + CString AVG_GRAY_1; // 0 Scan 1 Model + CString PORTION_1; + CString AVG_GRAY_2; // 1 Scan 0 Model + CString PORTION_2; + CString AVG_GRAY_3; // 1 Scan 1 Model + CString PORTION_3; }; class CMacroResultFile diff --git a/DitGlassRawMessenger/Extern/DitGlassRawStruct.h b/DitGlassRawMessenger/Extern/DitGlassRawStruct.h index c1e9afe..600196e 100644 --- a/DitGlassRawMessenger/Extern/DitGlassRawStruct.h +++ b/DitGlassRawMessenger/Extern/DitGlassRawStruct.h @@ -173,8 +173,8 @@ char m_strCount2[2]; //Mura Data 0412 nwh - float m_fMaxAvgGray; - float m_fMaxPortion; + char m_strMaxAvgGray[12]; + char m_strMaxPortion[12]; //1226NWH @@ -254,11 +254,14 @@ //Mura Data nwh 0404 char m_strProImage[32]; - float m_fAvgGray; - float m_fPortion; - - - + char m_strAvgGray_0[12]; + char m_strPortion_0[12]; + char m_strAvgGray_1[12]; + char m_strPortion_1[12]; + char m_strAvgGray_2[12]; + char m_strPortion_2[12]; + char m_strAvgGray_3[12]; + char m_strPortion_3[12]; int m_nDefectNumJudgeOKWhite; int m_nDefectNumJudgeOKBlack; diff --git a/ReviewSystem/ReviewRecipeEditor/ReviewRecipeEditorDlg.cpp b/ReviewSystem/ReviewRecipeEditor/ReviewRecipeEditorDlg.cpp index 12bdeed..b8f0898 100644 --- a/ReviewSystem/ReviewRecipeEditor/ReviewRecipeEditorDlg.cpp +++ b/ReviewSystem/ReviewRecipeEditor/ReviewRecipeEditorDlg.cpp @@ -373,11 +373,11 @@ CString strRecipeName, strPath, strMessage, strTemp; CCellID cellID = m_ctrlGridRecipeList.GetFocusCell(); - if(cellID.row > 0 && cellID.col > 0) + if (cellID.row > 0 && cellID.col > 0) { strRecipeName = m_ctrlGridRecipeList.GetItemText(cellID.row, 1); - if(m_bReviewSystemPC) + if (m_bReviewSystemPC) { strPath.Format(_T("%s\\%s.rcp"), _REVIEW_RECIPE_PATH_, strRecipeName); } @@ -386,7 +386,7 @@ strTemp.Format(_T("%s\\%s.rcp"), _REVIEW_RECIPE_PATH_, strRecipeName); nIdx = strTemp.Find(_T("\\")); - if(nIdx != -1) + if (nIdx != -1) { strTemp = strTemp.Mid(nIdx + 1); strPath.Format(_T("\\\\%s\\C\\%s"), NETIP_A2E_REVIEW_SYSTEM, strTemp); @@ -503,7 +503,7 @@ { CString strMessage; - if(RecipeName.IsEmpty()) + if (RecipeName.IsEmpty()) { AfxMessageBox(_T("Seleted recipe is not exist.")); } @@ -515,7 +515,7 @@ bRet = SaveRecipeFile(RecipeName); - if(bRet) + if (bRet) { // [2017:4:17]-[WEZASW] : CIM(Recipe) 보고 항목 추가. COPYDATA_RECIPE2REV copyData; @@ -537,7 +537,7 @@ // strBackupFile = strBackupPath + m_strCurrentRecipeName + strBackupFile; CString strSource, strDest; strSource.Format(_T("%s\\%s.rcp"), _REVIEW_RECIPE_PATH_, RecipeName); - strDest.Format(_T("%s\\%s_%s.rcp"),strBackupPath, RecipeName, strBackupFile ); + strDest.Format(_T("%s\\%s_%s.rcp"), strBackupPath, RecipeName, strBackupFile); CopyFile(strSource, strDest, TRUE); //LYW_#3344_CF AOI Review Config File 백업 기능 개선 ADD START @@ -570,7 +570,7 @@ // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다. CString strMessage; - if(m_strCurrentRecipeName.IsEmpty()) + if (m_strCurrentRecipeName.IsEmpty()) { AfxMessageBox(_T("Seleted recipe is not exist.")); } @@ -582,7 +582,7 @@ bRet = SaveRecipeFile(m_strCurrentRecipeName); - if(bRet) + if (bRet) { // [2017:4:17]-[WEZASW] : CIM(Recipe) 보고 항목 추가. COPYDATA_RECIPE2REV copyData; @@ -604,7 +604,7 @@ // strBackupFile = strBackupPath + m_strCurrentRecipeName + strBackupFile; CString strSource, strDest; strSource.Format(_T("%s\\%s.rcp"), _REVIEW_RECIPE_PATH_, m_strCurrentRecipeName); - strDest.Format(_T("%s\\%s_%s.rcp"),strBackupPath, m_strCurrentRecipeName, strBackupFile ); + strDest.Format(_T("%s\\%s_%s.rcp"), strBackupPath, m_strCurrentRecipeName, strBackupFile); CopyFile(strSource, strDest, TRUE); //LYW_#3344_CF AOI Review Config File 백업 기능 개선 ADD START @@ -628,7 +628,7 @@ RefreshRecipeList(); } - + CRMMInfoWriter rmmInfoWriter; int nMachineType = m_pDlgReviewFilter->GetMachineType(); if (rmmInfoWriter.WriteRmm(nMachineType) == FALSE) @@ -636,7 +636,7 @@ strMessage.Format(_T("Fail to save RMM INFO!")); AfxMessageBox(strMessage); } - + } void CReviewRecipeEditorDlg::OnBnClickedButtonReviewrcpEditorExit() diff --git a/ReviewSystem/ReviewRecipeEditor/stdafx.h b/ReviewSystem/ReviewRecipeEditor/stdafx.h index 43dbac0..b6f3a31 100644 --- a/ReviewSystem/ReviewRecipeEditor/stdafx.h +++ b/ReviewSystem/ReviewRecipeEditor/stdafx.h @@ -43,8 +43,6 @@ #define _REVIEW_SERVER_SYSTEM_SETTING_FILE_PATH_ _T("C:\\DIT_Review\\ReviewServerConfig\\SystemSetting.cfg") #define _REVIEW_RECIPE_BACKUP_PATH_CPJT _T("\\\\126.100.100.10\\d\\DIT Back up\\DIT Review\\Recipe") #define _REVIEW_SERVER_SYSTEM_SETTING_BACKUP_PATH_CPJT _T("\\\\126.100.100.10\\d\\DIT Back up\\DIT Review\\ReviewServerConfig") -//#define _REVIEW_RECIPE_BACKUP_PATH_CPJT _T("E:\\DIT Back up\\DIT Review\\Recipe") -//#define _REVIEW_SERVER_SYSTEM_SETTING_BACKUP_PATH_CPJT _T("E:\\DIT Back up\\DIT Review\\ReviewServerConfig") #define NETIP_A2E_AOI_SERVER _T("126.100.100.1") #define NETIP_A2E_REVIEW_SYSTEM _T("126.100.100.210") diff --git a/ReviewSystem/ReviewSystem/CameraController.cpp b/ReviewSystem/ReviewSystem/CameraController.cpp index 2231cb6..8848021 100644 --- a/ReviewSystem/ReviewSystem/CameraController.cpp +++ b/ReviewSystem/ReviewSystem/CameraController.cpp @@ -107,6 +107,32 @@ if (!pCameraControl->Connect(*it)) { + //#3361_ LYW CF AOI Review �쟾�꽕鍮� Align Cam 鍮꾩젙�긽 �뿰寃� �떆 �뙘�뾽 湲곕뒫 異붽� START + if (it->GetLibraryType() == CAMERA_LIBRARY_PYLON) + { + CString strMessage; + strMessage.Format(_T("Align移대찓�씪 �뿰寃� �떎�뙣 idx = %d"), nCamIndex); + if (IDOK == AfxMessageBox(strMessage, MB_OK | MB_ICONQUESTION)) + { + g_pLog->DisplayMessage(_T("Align Camera Connet Fail! Exit Review System")); + //exit(1); + return FALSE; + } + + } + else if(it->GetLibraryType() == CameraLibrary_Sapera) + { + CString strMessage; + strMessage.Format(_T("Review移대찓�씪 �뿰寃� �떎�뙣 idx = %d"), nCamIndex); + if (IDOK == AfxMessageBox(strMessage, MB_OK | MB_ICONQUESTION)) + { + g_pLog->DisplayMessage(_T("Review Camera Connet Fail! Exit Review System")); + //exit(1); + return FALSE; + } + } + + ////#3361_ LYW CF AOI Review �쟾�꽕鍮� Align Cam 鍮꾩젙�긽 �뿰寃� �떆 �뙘�뾽 湲곕뒫 異붽� END delete pCameraControl; continue; } diff --git a/ReviewSystem/ReviewSystem/DitGlassRawStruct.h b/ReviewSystem/ReviewSystem/DitGlassRawStruct.h index 9bb53b8..600196e 100644 --- a/ReviewSystem/ReviewSystem/DitGlassRawStruct.h +++ b/ReviewSystem/ReviewSystem/DitGlassRawStruct.h @@ -30,7 +30,7 @@ APS_None = 0, //AOI - APS_GlassLoading, + APS_GlassLoading, APS_InspectEnd, //Review APS_CustomReviewRead, @@ -63,10 +63,10 @@ //설비정보 char m_strLine[32]; - char m_strEquipType[32]; - char m_strEquipID[32]; - char m_strStepID[32]; - char m_strOperID[32]; + char m_strEquipType[32]; + char m_strEquipID[32]; + char m_strStepID[32]; + char m_strOperID[32]; CTime m_tmGlassLoading; //3. START_TIME CTime m_tmInspectionStart; //3. START_TIME @@ -76,8 +76,8 @@ //기본 물류정보 char m_strGlassID[32]; //Glass ID - char m_strPPID[32]; - char m_strEPPID[32]; + char m_strPPID[32]; + char m_strEPPID[32]; char m_strLotID[32]; //LOT_ID char m_strSLotID[32]; //SLOT_ID char m_strRecipeName[32]; //RECIPE_NAME @@ -129,7 +129,7 @@ //카메라/스캔 정보 [김태현 2018/12/5] short m_nCameraNum; short m_nScanNum; - unsigned char m_nGrayLevelAvg[RAWMESSENGER_MAXCAMNUM*RAWMESSENGER_MAXSCANNUM]; + unsigned char m_nGrayLevelAvg[RAWMESSENGER_MAXCAMNUM*RAWMESSENGER_MAXSCANNUM]; unsigned char m_nGrayLevelMin[RAWMESSENGER_MAXCAMNUM*RAWMESSENGER_MAXSCANNUM]; unsigned char m_nGrayLevelMax[RAWMESSENGER_MAXCAMNUM*RAWMESSENGER_MAXSCANNUM]; @@ -173,8 +173,8 @@ char m_strCount2[2]; //Mura Data 0412 nwh - float m_fMaxAvgGray; - float m_fMaxPortion; + char m_strMaxAvgGray[12]; + char m_strMaxPortion[12]; //1226NWH @@ -217,7 +217,7 @@ { memset(this, 0, sizeof(_grmCellData)); } - int getTotalDefectNum() { return m_nDefectNumTypeTB + m_nDefectNumTypeTW + m_nDefectNumTypeRB + m_nDefectNumTypeRW; }; + int getTotalDefectNum(){return m_nDefectNumTypeTB+m_nDefectNumTypeTW+m_nDefectNumTypeRB+m_nDefectNumTypeRW; }; int m_nCellID; //1. PANEL_ID short m_nModelIdx; // 몇 번째 모델인가? @@ -254,11 +254,14 @@ //Mura Data nwh 0404 char m_strProImage[32]; - float m_fAvgGray; - float m_fPortion; - - - + char m_strAvgGray_0[12]; + char m_strPortion_0[12]; + char m_strAvgGray_1[12]; + char m_strPortion_1[12]; + char m_strAvgGray_2[12]; + char m_strPortion_2[12]; + char m_strAvgGray_3[12]; + char m_strPortion_3[12]; int m_nDefectNumJudgeOKWhite; int m_nDefectNumJudgeOKBlack; @@ -295,7 +298,7 @@ ////////////////////////////////////////////////////////////////////////// //여기서 부터 리뷰 영역 [김태현 2019/1/19] - ditRaw::ReviewPlanType m_nPlanType; + ditRaw::ReviewPlanType m_nPlanType ; int m_nResultCode; //0:None, 1:Success int m_nShotIndex; //리뷰 찍은 순번 [김태현 2018/12/5] int m_nModuleIndex; @@ -316,7 +319,7 @@ int m_nWsi_Type; // 함몰 / 돌기 float m_fWsi_ResultData[8]; // 0:Type, 1:Height(um), 2:Width char m_strWsi_2DImageFilename[256]; - char m_strWsi_3DImageFilename[256]; + char m_strWsi_3DImageFilename[256]; int m_nWsiReflowPositionIndex; // WsiReflowPositionIndex int m_nWsi_pReflowResultData[8]; double m_dWsi_DamDistance; @@ -329,7 +332,7 @@ // Reflow 영역 int m_nReflow_Index; int m_nReflow_ResultCode; //0:None, // 검출한 Line의 개수. 3 미만 : DAM2 Reflow 판정, 4~5 : DAM1 Reflow 판정, 6 : no Reflow 판정 / -1 : image not loaded, -2 : roi setting error, -3 : roi length error, -5 : select wrong side - float m_fReflow_LinePosData[8]; + float m_fReflow_LinePosData[8]; int m_nReflow_Side; int m_nReflow_InspectionMode; }; @@ -382,7 +385,7 @@ short m_sZoneValueAvg[16]; // Zone별 결함 Avg short m_sZonePixelPercent[16]; // --------------------------------------Z0~ZF - //210127 CJH - Zone별 Source Gray 입력 + //210127 CJH - Zone별 Source Gray 입력 short m_sZoneValueSrcMin[16]; // Zone별 Source Min short m_sZoneValueSrcMax[16]; // Zone별 Source Max short m_sZoneValueSrcAvg[16]; // Zone별 Source Avg @@ -457,7 +460,7 @@ int m_nMinor; // 단축 길이(Short) int m_nCompact; // Blob 장축을 지름으로 하는 원의 넓이와 Blob 넓이의 비율 int m_nThickness; // Blob 넓이와 장축의 비율 (Area / Major) - + short m_nHliLevelIdx; // 몇 번째 레벨(채널)인가? int m_nHliLayers; // 해당결함에 포함된 레이어 bit처리 @@ -498,11 +501,11 @@ { int nCommand; char strParam[256]; - short nResult; + short nResult; }; short m_nCommandIdxWrite; short m_nCommandIdxRead; - _grmCommand m_nCommandBuffer[COMMAND_MAXCOUNT]; + _grmCommand m_nCommandBuffer[COMMAND_MAXCOUNT]; }; struct _grmDitMemInfo @@ -551,64 +554,64 @@ void clear() { - if (m_bRefAlloc) { m_pGlassRawData = NULL; return; } + if(m_bRefAlloc) { m_pGlassRawData = NULL; return;} - if (m_pGlassRawData) + if(m_pGlassRawData) { - delete[] m_pGlassRawData; + delete [] m_pGlassRawData; m_pGlassRawData = NULL; } }; BOOL ImportGlassRaw(_grmDitMemInfo* pInfo, char* pData, bool bRefAlloc = false) { - if (pInfo == NULL) return FALSE; + if(pInfo == NULL) return FALSE; - if (m_pGlassRawData && pInfo->m_nGlassRawDataSize != m_MemInfo.m_nGlassRawDataSize) clear(); + if(m_pGlassRawData && pInfo->m_nGlassRawDataSize != m_MemInfo.m_nGlassRawDataSize) clear(); - if (m_pGlassRawData == NULL) m_pGlassRawData = new char[pInfo->m_nGlassRawDataSize]; + if(m_pGlassRawData == NULL) m_pGlassRawData = new char[ pInfo->m_nGlassRawDataSize ]; m_MemInfo = *pInfo; m_nGlassRawDataSize = pInfo->m_nGlassRawDataSize; - m_nGlassMaxDataNum = pInfo->m_nGlassMaxDataNum; - m_nBlockMaxDataNum = pInfo->m_nBlockMaxDataNum; - m_nCellMaxDataNum = pInfo->m_nCellMaxDataNum; + m_nGlassMaxDataNum = pInfo->m_nGlassMaxDataNum ; + m_nBlockMaxDataNum = pInfo->m_nBlockMaxDataNum ; + m_nCellMaxDataNum = pInfo->m_nCellMaxDataNum ; m_nDefectMaxDataNum = pInfo->m_nDefectMaxDataNum; m_nStackMaxDataNum = pInfo->m_nStackMaxDataNum ; - m_nGlassDataPoint = pInfo->m_nGlassDataPoint; - m_nBlockDataPoint = pInfo->m_nBlockDataPoint; - m_nCellDataPoint = pInfo->m_nCellDataPoint; - m_nDefectDataPoint = pInfo->m_nDefectDataPoint; + m_nGlassDataPoint = pInfo->m_nGlassDataPoint ; + m_nBlockDataPoint = pInfo->m_nBlockDataPoint ; + m_nCellDataPoint = pInfo->m_nCellDataPoint ; + m_nDefectDataPoint = pInfo->m_nDefectDataPoint ; m_nStackDataPoint = pInfo->m_nStackDataPoint ; - m_nSizeOfGlassData = pInfo->m_nSizeOfGlassData; - m_nSizeOfBlockData = pInfo->m_nBlockDataPoint; - m_nSizeOfCellData = pInfo->m_nSizeOfCellData; + m_nSizeOfGlassData = pInfo->m_nSizeOfGlassData ; + m_nSizeOfBlockData = pInfo->m_nBlockDataPoint ; + m_nSizeOfCellData = pInfo->m_nSizeOfCellData ; m_nSizeOfDefectData = pInfo->m_nSizeOfDefectData; m_nSizeOfStackData = pInfo->m_nSizeOfStackData ; - if (bRefAlloc) + if(bRefAlloc) { m_pGlassRawData = pData; } else { - if (pData) + if(pData) { memcpy(m_pGlassRawData, pData, sizeof(char)*pInfo->m_nGlassRawDataSize); } else { - memset(m_pGlassRawData, 0, sizeof(char)*pInfo->m_nGlassRawDataSize); + memset(m_pGlassRawData, 0, sizeof(char)*pInfo->m_nGlassRawDataSize ); } } - m_pGlassData = (_grmGlassData*)&m_pGlassRawData[pInfo->m_nGlassDataPoint]; - m_pBlockData = (_grmBlockData*)&m_pGlassRawData[pInfo->m_nBlockDataPoint]; - m_pCellData = (_grmCellData*)&m_pGlassRawData[pInfo->m_nCellDataPoint]; + m_pGlassData = (_grmGlassData*)&m_pGlassRawData[pInfo->m_nGlassDataPoint]; + m_pBlockData = (_grmBlockData*)&m_pGlassRawData[pInfo->m_nBlockDataPoint]; + m_pCellData = (_grmCellData*)&m_pGlassRawData[pInfo->m_nCellDataPoint]; m_pDefectData = (_grmDefectData*)&m_pGlassRawData[pInfo->m_nDefectDataPoint]; m_pStackData = (_grmDefectData*)&m_pGlassRawData[pInfo->m_nStackDataPoint]; @@ -617,36 +620,36 @@ }; BOOL ExportGlassRaw(_grmDitMemInfo* pInfo, char* pData) { - if (pInfo == NULL || pData == NULL) return FALSE; + if(pInfo == NULL || pData == NULL) return FALSE; - if (1) //new type //메모리 총 공간 크기에 상관없이 + if(1) //new type //메모리 총 공간 크기에 상관없이 { //if(pInfo->m_nGlassRawDataSize != m_MemInfo.m_nGlassRawDataSize) return FALSE; - if (pInfo->m_nSizeOfGlassData != m_MemInfo.m_nSizeOfGlassData) return FALSE; - if (pInfo->m_nSizeOfBlockData != m_MemInfo.m_nSizeOfBlockData) return FALSE; - if (pInfo->m_nSizeOfCellData != m_MemInfo.m_nSizeOfCellData) return FALSE; - if (pInfo->m_nSizeOfDefectData != m_MemInfo.m_nSizeOfDefectData) return FALSE; + if(pInfo->m_nSizeOfGlassData != m_MemInfo.m_nSizeOfGlassData) return FALSE; + if(pInfo->m_nSizeOfBlockData != m_MemInfo.m_nSizeOfBlockData) return FALSE; + if(pInfo->m_nSizeOfCellData != m_MemInfo.m_nSizeOfCellData) return FALSE; + if(pInfo->m_nSizeOfDefectData != m_MemInfo.m_nSizeOfDefectData) return FALSE; if(pInfo->m_nSizeOfStackData != m_MemInfo.m_nSizeOfStackData) return FALSE; - if (pInfo->m_nCellMaxDataNum < m_pGlassData->m_nCellNum) return FALSE; - if (pInfo->m_nDefectMaxDataNum < m_pGlassData->m_nDefectNum) return FALSE; + if(pInfo->m_nCellMaxDataNum < m_pGlassData->m_nCellNum) return FALSE; + if(pInfo->m_nDefectMaxDataNum < m_pGlassData->m_nDefectNum) return FALSE; if(pInfo->m_nStackMaxDataNum < m_pGlassData->m_nDefectNum) return FALSE; - memcpy(&pData[pInfo->m_nGlassDataPoint], m_pGlassData, pInfo->m_nSizeOfGlassData * 1); - memcpy(&pData[pInfo->m_nBlockDataPoint], m_pBlockData, pInfo->m_nSizeOfBlockData * 1); - memcpy(&pData[pInfo->m_nCellDataPoint], m_pCellData, pInfo->m_nSizeOfCellData*m_pGlassData->m_nCellNum); + memcpy(&pData[pInfo->m_nGlassDataPoint], m_pGlassData, pInfo->m_nSizeOfGlassData* 1); + memcpy(&pData[pInfo->m_nBlockDataPoint], m_pBlockData, pInfo->m_nSizeOfBlockData* 1); + memcpy(&pData[pInfo->m_nCellDataPoint], m_pCellData, pInfo->m_nSizeOfCellData*m_pGlassData->m_nCellNum); memcpy(&pData[pInfo->m_nDefectDataPoint], m_pDefectData, pInfo->m_nSizeOfDefectData*m_pGlassData->m_nDefectNum); memcpy(&pData[pInfo->m_nStackDataPoint], m_pStackData, pInfo->m_nSizeOfStackData*m_pGlassData->m_nDefectNum); } else //if() //type old { - if (pInfo->m_nGlassRawDataSize != m_MemInfo.m_nGlassRawDataSize) return FALSE; + if(pInfo->m_nGlassRawDataSize != m_MemInfo.m_nGlassRawDataSize) return FALSE; - if (pInfo->m_nSizeOfGlassData != m_MemInfo.m_nSizeOfGlassData) return FALSE; - if (pInfo->m_nSizeOfBlockData != m_MemInfo.m_nSizeOfBlockData) return FALSE; - if (pInfo->m_nSizeOfCellData != m_MemInfo.m_nSizeOfCellData) return FALSE; - if (pInfo->m_nSizeOfDefectData != m_MemInfo.m_nSizeOfDefectData) return FALSE; + if(pInfo->m_nSizeOfGlassData != m_MemInfo.m_nSizeOfGlassData) return FALSE; + if(pInfo->m_nSizeOfBlockData != m_MemInfo.m_nSizeOfBlockData) return FALSE; + if(pInfo->m_nSizeOfCellData != m_MemInfo.m_nSizeOfCellData) return FALSE; + if(pInfo->m_nSizeOfDefectData != m_MemInfo.m_nSizeOfDefectData) return FALSE; memcpy(pData, m_pGlassRawData, sizeof(char)*pInfo->m_nGlassRawDataSize); } @@ -655,11 +658,11 @@ return TRUE; }; - _grmGlassData* GetGlassData() { return m_pGlassData; }; - _grmBlockData* GetBlockData(int nIndex) { return &m_pBlockData[nIndex]; }; - _grmCellData* GetCellData(int nIndex) { return &m_pCellData[nIndex]; }; - _grmDefectData* GetDefectData(int nIndex) { return &m_pDefectData[nIndex]; }; - _grmDitMemInfo* GetMemInfo() { return &m_MemInfo; }; + _grmGlassData* GetGlassData(){return m_pGlassData;}; + _grmBlockData* GetBlockData(int nIndex){return &m_pBlockData[nIndex];}; + _grmCellData* GetCellData(int nIndex){return &m_pCellData[nIndex];}; + _grmDefectData* GetDefectData(int nIndex){return &m_pDefectData[nIndex];}; + _grmDitMemInfo* GetMemInfo(){return &m_MemInfo;}; _grmDefectData* GetStackData(int nIndex) { return &m_pStackData[nIndex]; }; protected: _grmDitMemInfo m_MemInfo; diff --git a/ReviewSystem/ReviewSystem/MainFrm.cpp b/ReviewSystem/ReviewSystem/MainFrm.cpp index 2f49cd1..0e4cd9f 100644 --- a/ReviewSystem/ReviewSystem/MainFrm.cpp +++ b/ReviewSystem/ReviewSystem/MainFrm.cpp @@ -84,6 +84,12 @@ SetTimer(ID_TIMER_SEND_SIGNAL_ALIVE, 100, NULL); + system("net use Y: \\\\126.100.100.1\\d\\DIT_ResultData pw:dit/user:Server/persistent:yes"); + + //LYW Align Reconnect + //system("netsh interface set interface name = \"Align #1\" admin = disable&& netsh interface set interface name = \"Align #1\" admin = enable&& netsh interface set interface name = \"Align #2\" admin = disable&& netsh interface set interface name = \"Align #2\" admin = enable"); + //Sleep(2000); + // SetTimer(ID_TIMER_WSI_LONGRUN_TEST_TIME, 10000, NULL); return 0; diff --git a/ReviewSystem/ReviewSystem/SequenceProcessor_CPJT.cpp b/ReviewSystem/ReviewSystem/SequenceProcessor_CPJT.cpp index aea1b64..14ac4c3 100644 --- a/ReviewSystem/ReviewSystem/SequenceProcessor_CPJT.cpp +++ b/ReviewSystem/ReviewSystem/SequenceProcessor_CPJT.cpp @@ -48,6 +48,7 @@ #define AOIRAWBIN_PATH "\\\\126.100.100.1\\d\\DIT_ResultData\\RawBin" #define AOIRAWBIN_TEST_PATH "d:\\DIT_ResultData\\RawBin" +#define AOIRAWBIN_NETWORK_DRIVE_PATH "Y:\\RawBin" enum CPJT_MeasureMode { CPJT_ModeAuto = 0, CPJT_ModeManual }; // [2017:4:18]-[WEZASW] : WSI Module 장착 설비의 경우 PlanType 번호 변경. @@ -2635,11 +2636,22 @@ { CTime tmReviewLoading = CTime::GetCurrentTime(); CString strWild; - strWild.Format("%s\\%s_*.bin", strFilePath, strFileName); + //strWild.Format("%s\\%s_*.bin", strFilePath, strFileName); CakFileUtil akFileFinder; while (nReTryTime--) { - akFileFinder.FindFile(strWild.GetBuffer(0), FALSE); + //#3359_LYW CF AOI Review REVIEW_LOADING_COMPLETE_TIMEOVER 알람 발생 원인 분석 START + if (nReTryTime%2 == 0) + { + strFilePath = AOIRAWBIN_PATH; + } + else strFilePath = AOIRAWBIN_NETWORK_DRIVE_PATH; + + strWild.Format("%s\\%s_*.bin", strFilePath, strFileName); + akFileFinder.FindFile(strWild.GetBuffer(0), FALSE); + //LYW LOG추가 + g_pLog->DisplayMessage(_T("[GlassLoading][FindRawBinFile] Find Path = %s, RetryCount = %d, ResultCode = [%d]"), strFilePath, 30-nReTryTime, GetLastError()); + //#3359_LYW CF AOI Review REVIEW_LOADING_COMPLETE_TIMEOVER 알람 발생 원인 분석 END VECFINDDATA* pFindData = akFileFinder.getFindData(); int nFileNamePos = strlen(akFileFinder.getProcessPath()); std::map<LONGLONG, CString> mapSpanFileName; @@ -2684,6 +2696,7 @@ break; } } + akFileFinder.clear(); Sleep(100); } @@ -3108,7 +3121,7 @@ strReadData = pTransferData->strRerferData; break; } - m_pSP2P->ISP2P_DisplayMessage(_T("[ReadTransferData] Name: %s, Addr: %s, Size: %d, Data: %s"), pInfo->strName, strReadAddress, nReadSize, strReadData); + //m_pSP2P->ISP2P_DisplayMessage(_T("[ReadTransferData] Name: %s, Addr: %s, Size: %d, Data: %s"), pInfo->strName, strReadAddress, nReadSize, strReadData); //0517 } } @@ -4517,7 +4530,8 @@ strPath = strPath + _T("\\WSI"); if(CreateDirectory(strPath,NULL)==FALSE) { - g_pLog->DisplayMessage(_T("[MakeWSIUpLoadDirectory]Directory Create Fail %s "),strPath); + //LYW LOG추가 + g_pLog->DisplayMessage(_T("[MakeWSIUpLoadDirectory]Directory Create Fail %s, ERROR CODE = %d "),strPath, GetLastError()); } } @@ -4673,9 +4687,11 @@ //보낼 포인트가 있는지 없는지 체크 if (vectorPosX.empty() == TRUE) { - g_pLog->DisplayMessage(_T("[GantryAutoGo] No Exist Send Point "), vectorPosX.size()); + //3360 LYW_ CF AOI QD Review WSI XY MotorMoving Error 알람 발생 원인 분석 및 조치 START + g_pLog->DisplayMessage(_T("[GantryAutoGo] No Exist Send Point,TwoGantrySyncMode OFF!"), vectorPosX.size()); g_pLog->DisplayMessage(_T("[GantryAutoGo] (%d)Gantry Path Send Fail"), pModuleStatus->GetGantryIndex()); //taek 210128 - + pMotorControl->GantrySetTwoGantrySyncModeSend(1); + //3360 LYW_ CF AOI QD Review WSI XY MotorMoving Error 알람 발생 원인 분석 및 조치 END } else { diff --git a/ReviewSystem/ReviewSystemSetting/ReviewSystemSettingDlg.cpp b/ReviewSystem/ReviewSystemSetting/ReviewSystemSettingDlg.cpp index 15ea98b..767d0f5 100644 --- a/ReviewSystem/ReviewSystemSetting/ReviewSystemSettingDlg.cpp +++ b/ReviewSystem/ReviewSystemSetting/ReviewSystemSettingDlg.cpp @@ -503,7 +503,7 @@ { BOOL bRet = WriteReviewSystemConfigFile(); - if(bRet == TRUE) + if (bRet == TRUE) { // message g_pLog->DisplayMessage(_T("Setting file is Saved!")); @@ -511,7 +511,7 @@ COPYDATA_SYSTEM2REV copyData; copyData.Message = MsgSystem2Rev_ChangeSysConfig; SendData2ReviewSystem(©Data); - + // make backup path CString strBackupPath = _REVIEW_SERVER_CONFIG_PATH_; strBackupPath = strBackupPath + _T("\\Backup\\"); diff --git a/ReviewSystem/ReviewSystemSetting/stdafx.h b/ReviewSystem/ReviewSystemSetting/stdafx.h index 96a0767..f09914e 100644 --- a/ReviewSystem/ReviewSystemSetting/stdafx.h +++ b/ReviewSystem/ReviewSystemSetting/stdafx.h @@ -41,8 +41,6 @@ #define _REVIEW_SERVER_CONFIG_PATH_ _T("C:\\DIT_Review\\ReviewServerConfig") #define _REVIEW_SERVER_SYSTEM_SETTING_FILE_PATH_ _T("C:\\DIT_Review\\ReviewServerConfig\\SystemSetting.cfg") #define _REVIEW_SERVER_SYSTEM_PASSWORD_FILE_PATH_ _T("C:\\DIT_Review\\ReviewServerConfig\\SystemSetting.dat") -//#define _REVIEW_RECIPE_BACKUP_PATH_CPJT _T("E:\\DIT Back up\\DIT Review\\Recipe") -//#define _REVIEW_SERVER_SYSTEM_SETTING_BACKUP_PATH_CPJT _T("E:\\DIT Back up\\DIT Review\\ReviewServerConfig") #define _REVIEW_RECIPE_BACKUP_PATH_CPJT _T("\\\\126.100.100.10\\d\\DIT Back up\\DIT Review\\Recipe") #define _REVIEW_SERVER_SYSTEM_SETTING_BACKUP_PATH_CPJT _T("\\\\126.100.100.10\\d\\DIT Back up\\DIT Review\\ReviewServerConfig") #define _REVIEW_SYSTEM_TITLE_ _T("ReviewSystem") -- Gitblit v1.9.3