MainCommF.cpp 90 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948
  1. //---------------------------------------------------------------------------
  2. #pragma hdrstop
  3. #include "MainCommF.h"
  4. #include "CDSProcessF.h"
  5. #include "CDSCtlrF.h"
  6. #include "CDSFormF.h"
  7. #include "CDSIfscF.h"
  8. #include "CDSImageF.h"
  9. #include "CDSAtmpF.h"
  10. #include "CDSSafeF.h"
  11. #include "CDSParkF.h"
  12. #include "VmsUtilsF.h"
  13. #include "PacketHandllingF.h"
  14. //---------------------------------------------------------------------------
  15. #pragma package(smart_init)
  16. int g_ToggleFormSeq = 1;
  17. int __fastcall ChangePosition(TVmsFormObj *AVmsObj)
  18. {
  19. TLabel *pLabel = NULL;
  20. if (AVmsObj->TextData == "") return VERR_NONE;
  21. try
  22. {
  23. pLabel = new TLabel(NULL);
  24. if (pLabel == NULL) return VERR_OTHER;
  25. try
  26. {
  27. pLabel->AutoSize = true;
  28. pLabel->Font->Name = CodeToFontName(AVmsObj->TextFontName);
  29. pLabel->Font->Size = AVmsObj->TextFontSize;
  30. pLabel->Caption = AVmsObj->TextData;
  31. if (AVmsObj->TextFontBold)
  32. pLabel->Font->Style = TFontStyles() << fsBold;
  33. else
  34. pLabel->Font->Style = TFontStyles();
  35. #if 1
  36. switch(AVmsObj->TextAlign)
  37. {
  38. case text_align_left:
  39. //좌측정력인 경우 위치조정 필요 없음.
  40. break;
  41. case text_align_right:
  42. //좌측에서 글자길이를 뺀다음 만약 음수이면 0으로 설정
  43. AVmsObj->PosX = (AVmsObj->PosX+AVmsObj->Width) - pLabel->Width;
  44. break;
  45. case text_align_center:
  46. //원래 글자의 중앙값을 얻은 다음에 조정된 글자의 1/2 크기를 뺀다음 음수이면 0으로 설정
  47. AVmsObj->PosX = (AVmsObj->PosX+(AVmsObj->Width/2)) - (pLabel->Width/2);
  48. break;
  49. }
  50. if (AVmsObj->PosX < 0) AVmsObj->PosX = 0;
  51. AVmsObj->TextWidth = pLabel->Width;
  52. #else
  53. int nWidth = AVmsObj->Width - pLabel->Width;
  54. if (nWidth > 0)
  55. {
  56. switch(AVmsObj->TextAlign)
  57. {
  58. case text_align_right: AVmsObj->PosX += nWidth; break;
  59. case text_align_center: AVmsObj->PosX += (nWidth / 2); break;
  60. }
  61. }
  62. #endif
  63. }
  64. catch(Exception &e)
  65. {
  66. }
  67. }
  68. __finally
  69. {
  70. SAFE_DELETE(pLabel);
  71. }
  72. return VERR_NONE;
  73. }
  74. //---------------------------------------------------------------------------
  75. int __fastcall MakeVmsProvideForm()
  76. {
  77. int nFormCnt;
  78. int nSaveVmsCnt, nSaveFormCnt;
  79. TCDSForm *pCDSForm;
  80. TVmsForm *pVmsForm;
  81. TVmsFormObj *pVmsObj;
  82. VMS_SCHEDULE_INFO *pSch;
  83. VMS_SCHEDULE_DETL *pSchUnit;
  84. DWORD dwStart = GetTickCount();
  85. DWORD dwEnd = dwStart;
  86. MINFO("MAIN=============> MakeVmsProvideForm: Start");
  87. nSaveVmsCnt = 0;
  88. nSaveFormCnt= 0;
  89. //VMS스케줄에 대하여 다운로드 폼을 생성한다.
  90. CtlrItr it;
  91. for(it=CDSCtlrManager->FLists.FObjects.begin(); it != CDSCtlrManager->FLists.FObjects.end(); ++it)
  92. {
  93. TCDSCtlr *pObj = (TCDSCtlr*)it->second;
  94. if (!pObj->Used) continue;
  95. if (!pObj->FProvide) continue;
  96. nSaveVmsCnt++;
  97. //운영모드 변경
  98. pObj->RSTATE.OprMode = pObj->CTRLMODE->Control;
  99. pSch = pObj->SCHEDULE;
  100. pObj->CTRLMODE->MaxDisplayForm = pSch->Count;
  101. if (pObj->CTRLMODE->MaxDisplayForm > pObj->VMS_MAX_PHSE_NUM)
  102. {
  103. MWARN("MAIN=============> VMS Form Max count over1: %s, %d EA.", pObj->CTLR_NMBR.c_str(), pObj->CTRLMODE->MaxDisplayForm);
  104. pObj->CTRLMODE->MaxDisplayForm = pObj->VMS_MAX_PHSE_NUM;
  105. }
  106. if (pObj->CTRLMODE->MaxDisplayForm > INT_VMS_MAX_FORM)
  107. {
  108. MWARN("MAIN=============> VMS Form Max count over2: %s, %d EA.", pObj->CTLR_NMBR.c_str(), pObj->CTRLMODE->MaxDisplayForm);
  109. pObj->CTRLMODE->MaxDisplayForm = INT_VMS_MAX_FORM;
  110. }
  111. // 제어기별 다운로드 디렉토리가 존재하지 않으면 생성
  112. if (!DirectoryExists(pObj->FLocalFormDir))
  113. {
  114. ForceDirectories(pObj->FLocalFormDir.c_str());
  115. MWARN("MAIN=============> VMS Form Directory Re Create: %s, %s", pObj->FLocalFormDir.c_str(), pObj->FFtpFormDir.c_str());
  116. }
  117. pObj->pForms->Lock();
  118. try
  119. {
  120. TCDSAtmp *pAtmpObj = NULL;
  121. AnsiString ATMP_STTN_NMBR = "";
  122. //최대 제공 메시지 갯수만큼 생성
  123. for (int ii = 0; ii < pSch->Count && ii < pObj->CTRLMODE->MaxDisplayForm; ii++)
  124. {
  125. pSchUnit = &pSch->Unit[ii];
  126. if (pObj->FExistCngsForm && pSchUnit->DSPL_CNGS_YN == false)
  127. {
  128. //해당 제어기에 정체폼이 존재하는 경우
  129. //스케쥴 폼이 정체일때 표출하지 않는 경우
  130. //폼을 생성하지 않는다.
  131. continue;
  132. }
  133. nFormCnt = pObj->pForms->Count();
  134. AnsiString sFormId = pSchUnit->VMS_FORM_ID;
  135. pCDSForm = CDSFormManager->FLists.Find(sFormId);
  136. if (!pCDSForm)
  137. {
  138. MERROR("MAIN=============> VMS Schedule Form Not found: VmsNmbr(%s), FormId(%s) %d", pObj->CTLR_NMBR.c_str(), sFormId.c_str(), ii);
  139. continue;
  140. }
  141. //소통정보 표출폼 인 경우 표출할 구간의 소통정보가 존재하지 않는 경우
  142. //폼을 생성하지 않도록 한다.
  143. // TODO(20200525)
  144. int reqTraffic = 0;
  145. int setTraffic = 0;
  146. switch(pCDSForm->VMS_FORM_TYPE_CD)
  147. {
  148. case eFormTp_traf_1:// = 11, // 소통상황(1단)
  149. reqTraffic = 1;
  150. case eFormTp_traf_2:// = 12, // 소통상황(2단)
  151. reqTraffic = 2;
  152. case eFormTp_traf_3:// = 13, // 소통상황(3단)
  153. reqTraffic = 3;
  154. case eFormTp_traf_4:// = 14, // 소통상황(4단)
  155. reqTraffic = 4;
  156. {
  157. int ss;
  158. bool bNoData = true;
  159. AnsiString sVmsIfscId[4];
  160. AnsiString sImgIfscId[4];
  161. for (ss = 0; ss < 4; ss++)
  162. {
  163. sVmsIfscId[ss] = "";
  164. sImgIfscId[ss] = "";
  165. }
  166. sVmsIfscId[0] = pSchUnit->FRST_VMS_IFSC_ID;
  167. sVmsIfscId[1] = pSchUnit->SECD_VMS_IFSC_ID;
  168. sVmsIfscId[2] = pSchUnit->THIR_VMS_IFSC_ID;
  169. sVmsIfscId[3] = pSchUnit->FOUR_VMS_IFSC_ID;
  170. sImgIfscId[0] = pSchUnit->FRST_IMG_IFSC_ID;
  171. sImgIfscId[1] = pSchUnit->SECD_IMG_IFSC_ID;
  172. sImgIfscId[2] = pSchUnit->THIR_IMG_IFSC_ID;
  173. sImgIfscId[3] = pSchUnit->FOUR_IMG_IFSC_ID;
  174. for (ss = 0; ss < 4; ss++)
  175. {
  176. if (sVmsIfscId[ss] == "0") sVmsIfscId[ss] = "";
  177. if (sImgIfscId[ss] == "0") sImgIfscId[ss] = "";
  178. if (sVmsIfscId[ss] == "")
  179. {
  180. sVmsIfscId[ss] = sImgIfscId[ss];
  181. }
  182. if (sVmsIfscId[ss] == "") continue;
  183. setTraffic++;
  184. }
  185. if (reqTraffic > setTraffic)
  186. {
  187. //실제 소통정보 폼 갯수보다 할당된 구간이 적은 경우에 해당함
  188. reqTraffic = setTraffic;
  189. }
  190. setTraffic = 0;
  191. for (ss = 0; ss < 4; ss++)
  192. {
  193. if (sVmsIfscId[ss] == "") continue;
  194. TCDSIfsc *pTmpIfsc = CDSIfscManager->FLists.Find(sVmsIfscId[ss]);
  195. if (pTmpIfsc)
  196. {
  197. if (pTmpIfsc->CMTR_GRAD_CD != "0")
  198. {
  199. bNoData = false;
  200. setTraffic++;
  201. }
  202. }
  203. }
  204. //if (bNoData)
  205. if (reqTraffic != setTraffic)
  206. {
  207. MWARN("MAIN=============> VMS Schedule Form No Traffic: VmsNmbr(%s), FormId(%s), REQ(%d), SET(%d)", pObj->CTLR_NMBR.c_str(), sFormId.c_str(), reqTraffic, setTraffic);
  208. continue;
  209. }
  210. }
  211. break;
  212. #if 0
  213. //폼에 대기환경수집장소가 하나인경우에만 해당
  214. //폼 객체에 대기환경수집장소를 설정하도록 수정하였음.
  215. case eFormTp_atmp: //대기환경
  216. {
  217. //스케줄 정보를 디비에서 읽어서 스케쥴을 작성할때 확인하지만 다시한번 확인
  218. //아래 객체를 생성할때 사용할수 있게 미리 메모리를 찾아서 할당한다.
  219. ATMP_STTN_NMBR = pSchUnit->FRST_VMS_IFSC_ID;
  220. pAtmpObj = NULL;
  221. if (CDSAtmpManager) CDSAtmpManager->FLists.Find(ATMP_STTN_NMBR);
  222. if (!pAtmpObj) continue;
  223. if (pAtmpObj->SUCCESS == false)
  224. {
  225. pAtmpObj = NULL;
  226. continue;
  227. }
  228. }
  229. break;
  230. #endif
  231. }
  232. nSaveFormCnt++;
  233. //폼생성
  234. pVmsForm = pObj->pForms->AddForm(); // new 를 사용해서 생성하지 않고 기존에 생성한 폼을 이용한다.
  235. pVmsForm->Success = false;
  236. pVmsForm->FtpFileName = pCDSForm->FtpFileName; // 정적폼인경우 경로가 지정됨
  237. pVmsForm->LocalFileName = pCDSForm->LocalFileName; // 정적폼인경우 경로가 지정됨
  238. pVmsForm->VMS_SCH_TYPE = pSchUnit->VMS_SCH_TYPE;
  239. pVmsForm->VMS_SCH_FORM_TYPE = pSchUnit->VMS_SCH_FORM_TYPE;
  240. pVmsForm->SYMB_LIB_NMBR = pSchUnit->SYMB_LIB_NMBR;
  241. pVmsForm->STRM_ADDR = pSchUnit->STRM_ADDR;
  242. pVmsForm->ScenarioSeq = nFormCnt; /* 폼 표출순서 */
  243. pVmsForm->VMS_FORM_ID = pCDSForm->VMS_FORM_ID; /* 폼 ID */
  244. pVmsForm->DSPL_HH = pSchUnit->DSPL_HH; /* 표출시간(초) */
  245. pVmsForm->VMS_FORM_DSPL_DRCT_CD = AnsiString(pCDSForm->VMS_FORM_DSPL_DRCT_CD); /* 표출방향 */
  246. pVmsForm->VMS_FORM_DSPL_MTHD_CD = AnsiString(pCDSForm->VMS_FORM_DSPL_MTHD_CD); /* 표출기능 */
  247. pVmsForm->VMS_FORM_TYPE_CD = pCDSForm->VMS_FORM_TYPE_CD; /* 폼 종류 */
  248. pVmsForm->VMS_FORM_COLR_CD = pCDSForm->VMS_FORM_COLR_CD; /* 배경색상 */
  249. pVmsForm->Width = pObj->WIDTH; /* 폼넓이 */
  250. pVmsForm->Height = pObj->HEIGHT; /* 폼높이 */
  251. pVmsForm->SvcRes = false;
  252. pVmsForm->FtpRes = false;
  253. pVmsForm->Lock();
  254. //폼객체생성
  255. FOR_STL(TCDSFormObj*, pCDSObj, pCDSForm->FLists)
  256. {
  257. if (pVmsForm->Count() >= MAX_FORM_OBJ_LIST)
  258. {
  259. break;
  260. }
  261. //도형식 배경소통정보 폼인 경우 하단에 표출할 정보가 없는 경우
  262. //하단 소통정보 객체는 생성하지 않도록 하자.
  263. if (pVmsForm->VMS_FORM_TYPE_CD == eFormtp_figure) // = 15, // 소통상황(도형식배경소통정보))
  264. {
  265. switch(pCDSObj->VMS_FORM_OBJECT_TYPE_CD)
  266. {
  267. case 0: //문자열
  268. case 1: //심볼
  269. case 2: //이미지
  270. //N:일반(모두표출하는것)
  271. //T:소통정보(소통정보가 있는 경우에만 표출하는것)
  272. //F:하단고정(소통정보가 없는 경우에만 표출하는것)
  273. if (pSchUnit->VMS_IFSC_ID == "")
  274. {
  275. //표출할 소통정보가 없는 경우
  276. if (pCDSObj->TRFC_FILL_CD == "T") continue; //
  277. }
  278. else
  279. {
  280. //표출할 소통정보가 있는 경우
  281. if (pCDSObj->TRFC_FILL_CD == "F") continue; //
  282. }
  283. break;
  284. case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19:
  285. if (pSchUnit->VMS_IFSC_ID == "")
  286. {
  287. continue; //하단에 표출할 정보제공구간이 없는 경우임
  288. }
  289. //////////////////////// 20200515 추가함(S)
  290. if (pCDSObj->VMS_FORM_OBJECT_TYPE_CD == 17)
  291. {
  292. //하단 소통정보이미지
  293. pSchUnit->FRST_IMG_IFSC_ID = pSchUnit->VMS_IFSC_ID;
  294. }
  295. //////////////////////// 20200515 추가함(E)
  296. break;
  297. #if 0
  298. case 1://심볼(소통정보 시점 종점 사이 화살표)
  299. #if 1
  300. if (pCDSObj->VMS_DSPL_TXT.Trim() == "->")
  301. if (pSchUnit->VMS_IFSC_ID == "") continue; //하단에 표출할 정보제공구간이 없는 경우임
  302. #else
  303. if (pSchUnit->VMS_IFSC_ID == "") continue; //하단에 표출할 정보제공구간이 없는 경우임
  304. #endif
  305. break;
  306. #endif
  307. default: break;
  308. }
  309. } //pVmsForm->VMS_FORM_TYPE_CD == eFormtp_figure
  310. pVmsObj = pVmsForm->AddFormObject();
  311. pVmsObj->IFSC_ID = "";
  312. pVmsObj->TRFC_FILL_CD = pCDSObj->TRFC_FILL_CD;
  313. switch(pCDSObj->VMS_FORM_OBJECT_TYPE_CD)
  314. {
  315. case 1: //심볼
  316. pVmsObj->ObjectKind = graphicID_object_data; //요건 다운로드되어 있는 경우인데 다운로드상관없이 표출되도록하기위함
  317. //pVmsObj->ObjectKind = graphic_object_data;
  318. break;
  319. case 2: //이미지
  320. pVmsObj->ObjectKind = graphicID_object_data;
  321. break;
  322. case 3: //소통정보배경이미지
  323. pVmsObj->ObjectKind = graphic_object_data;
  324. break;
  325. case 17: //1단,소통정보이미지1
  326. case 27: //2단,소통정보이미지2
  327. case 37: //3단,소통정보이미지3
  328. case 47: //4단,소통정보이미지4
  329. case 167: //@우회소통정보이미지
  330. case 200: //동영상이미지
  331. case 300: //스트리밍영상이미지
  332. case 406: //@통합대기등급 이미지
  333. case 407: //@미세먼지등급 이미지
  334. case 408: //@초미세먼지등급 이미지
  335. case 413: //@오존등급이미지
  336. pVmsObj->ObjectKind = graphicID_object_data;
  337. break;
  338. default:
  339. pVmsObj->ObjectKind = text_object_data;
  340. break;
  341. } //switch(pCDSObj->VMS_FORM_OBJECT_TYPE_CD)
  342. pVmsObj->ObjectType = pCDSObj->VMS_FORM_OBJECT_TYPE_CD; //NUMBER(3) N VMS FORM OBJECT 유형 코드
  343. pVmsObj->TextFontName = pCDSObj->VMS_FONT_NAME_CD; //NUMBER(3) N VMS 글꼴 유형 코드
  344. //TODO
  345. pVmsObj->StrTextFontName = CodeToFontName(pVmsObj->TextFontName);
  346. pVmsObj->TextFontColor = pCDSObj->VMS_FONT_COLR_CD; //NUMBER(3) N VMS 글꼴 색상 코드
  347. pVmsObj->TextFontBold = pCDSObj->VMS_FONT_BOLD; //NUMBER(3) Y VMS 글꼴 방식 코드(0:Normal,1:Bold)
  348. pVmsObj->TextFontSize = pCDSObj->VMS_FONT_SIZE; //NUMBER(3) Y 0 VMS 글꼴 크기
  349. pVmsObj->TextAlign = pCDSObj->VMS_FONT_ALIGN; //NUMBER(1) Y 0 VMS 표출 문자열정열방식(0:LEFT,1:RIGHT,2:CENTER)
  350. pVmsObj->PosX = pCDSObj->VMS_DSPL_XCRDN; //NUMBER(5) Y VMS 표출 X좌표
  351. pVmsObj->PosY = pCDSObj->VMS_DSPL_YCRDN; //NUMBER(5) Y VMS 표출 Y좌표
  352. pVmsObj->Width = pCDSObj->VMS_DSPL_WIDTH; //NUMBER(5) Y 0 VMS 표출 넓이
  353. pVmsObj->TextWidth = pCDSObj->VMS_DSPL_WIDTH; //NUMBER(5) Y 0 VMS 표출 넓이
  354. pVmsObj->Height = pCDSObj->VMS_DSPL_HEIGHT; //NUMBER(5) Y 0 VMS 표출 높이
  355. pVmsObj->IsBlinking = pCDSObj->VMS_DSPL_BLINKING; //NUMBER(1) Y 0 VMS 표출 점멸 여부(0:지속, 1:점멸)
  356. pVmsObj->BkColor = pCDSObj->VMS_DSPL_BKCOLOR; //NUMBER(1) Y 0 VMS 표출 배경색상코드
  357. pVmsObj->ObjectSize = pCDSObj->VMS_DSPL_SIZE; //NUMBER(7) Y 0 VMS 표출 크기(문자:문자길이,이미지:이미지전체크기)
  358. if (pCDSObj->VMS_FORM_OBJECT_TYPE_CD == 201 || //동영상명칭
  359. pCDSObj->VMS_FORM_OBJECT_TYPE_CD == 301) //스트리밍영상주소
  360. {
  361. pVmsObj->TextData = pSchUnit->STRM_ADDR; //VARCHAR2(200) Y VMS 표출 텍스트
  362. }
  363. else
  364. {
  365. pVmsObj->TextData = pCDSObj->VMS_DSPL_TXT; //VARCHAR2(200) Y VMS 표출 텍스트
  366. }
  367. if (pCDSObj->VMS_FORM_OBJECT_TYPE_CD == 200 || //동영상이미지
  368. pCDSObj->VMS_FORM_OBJECT_TYPE_CD == 300) //스트리밍영상이미지
  369. {
  370. //TODO: 20241218
  371. // pVmsObj->ImageId = pSchUnit->SYMB_LIB_NMBR+"0"; //NUMBER(4) N 0 심벌라이브러리 번호
  372. pVmsObj->ImageId = pCDSObj->SYMB_LIB_NMBR+"0"; //NUMBER(4) N 0 심벌라이브러리 번호
  373. if (pCDSObj->VMS_FORM_OBJECT_TYPE_CD == 200)
  374. {
  375. #if 0
  376. pVmsObj->PosX = 0; //NUMBER(5) Y VMS 표출 X좌표
  377. pVmsObj->PosY = 0; //NUMBER(5) Y VMS 표출 Y좌표
  378. pVmsObj->Width = pVmsForm->Width; //NUMBER(5) Y 0 VMS 표출 넓이
  379. pVmsObj->Height = pVmsForm->Height; //NUMBER(5) Y 0 VMS 표출 높이
  380. #endif
  381. pVmsObj->TextData = pCDSObj->VMS_DSPL_TXT; // ftp 동영상 파일명
  382. pVmsForm->FtpFileName = pCDSObj->VMS_DSPL_TXT;
  383. pVmsForm->STRM_ADDR = pCDSObj->VMS_DSPL_TXT;
  384. if (pVmsForm->DSPL_HH <= 5) {
  385. // 5초 이하이면 0으로 설정해서 동영상 길이 만큼 동영상이 표출되도록 설정
  386. pVmsForm->DSPL_HH = 0;
  387. }
  388. TCDSImage* pTmpImg = CDSImageManager->FLists.Find(pVmsObj->ImageId);
  389. if (pTmpImg)
  390. {
  391. if (pVmsForm->DSPL_HH > 5) {
  392. // 표출시간이 설정되어 있고 동영상 길이보다 표출시간이 길면 동영상 길이로 표출시간을 설정
  393. if (pVmsForm->DSPL_HH > pTmpImg->PLAY_TM) {
  394. pVmsForm->DSPL_HH = pTmpImg->PLAY_TM;
  395. }
  396. }
  397. }
  398. if (pVmsForm->DSPL_HH > 254) {
  399. // 표출시간이 254보다 크면 254로 설정, 폼 표출 시간은 1바이트임...
  400. pVmsForm->DSPL_HH = 254;
  401. }
  402. }
  403. }
  404. else
  405. {
  406. pVmsObj->ImageId = pCDSObj->SYMB_LIB_NMBR+"0"; //NUMBER(4) N 0 심벌라이브러리 번호
  407. }
  408. pVmsObj->ImageType = "0"; //Bitmap
  409. if (pVmsObj->ObjectKind != text_object_data)
  410. {
  411. if (pVmsObj->NewImage() != NULL)
  412. {
  413. try
  414. {
  415. pVmsObj->pImageData->Picture->Bitmap->Canvas->Lock();
  416. try
  417. {
  418. if (pCDSObj->VMS_FORM_OBJECT_TYPE_CD == 200 || //동영상이미지
  419. pCDSObj->VMS_FORM_OBJECT_TYPE_CD == 300) //스트리밍영상이미지
  420. {
  421. TCDSImage* pTmpImg = CDSImageManager->FLists.Find(pVmsObj->ImageId);
  422. if (pTmpImg)
  423. {
  424. pVmsObj->pImageData->Picture->Assign(pTmpImg->IMAG_DATA->Picture);
  425. }
  426. else
  427. {
  428. pVmsObj->pImageData->Picture->Assign(pCDSObj->pImage->Picture);
  429. }
  430. }
  431. else
  432. if (CDSAtmpManager &&
  433. (pCDSObj->VMS_FORM_OBJECT_TYPE_CD == 406 || //@통합대기등급 이미지
  434. pCDSObj->VMS_FORM_OBJECT_TYPE_CD == 407 || //@미세먼지등급 이미지
  435. pCDSObj->VMS_FORM_OBJECT_TYPE_CD == 408 || //@초미세먼지등급 이미지
  436. pCDSObj->VMS_FORM_OBJECT_TYPE_CD == 413 ) //@오존등급이미지
  437. )
  438. {
  439. bool isObj = false;
  440. pAtmpObj = CDSAtmpManager->FLists.Find(pCDSObj->VMS_IFSC_ID);
  441. if (pAtmpObj && pAtmpObj->SUCCESS) isObj = true;
  442. if (isObj)
  443. {
  444. //관측장소 정보가 존재하는 경우에만 대기환경이미지를 폼에 적용한다.
  445. int nAtmpGrad = 0;
  446. switch(pCDSObj->VMS_FORM_OBJECT_TYPE_CD)
  447. {
  448. case 406: nAtmpGrad = pAtmpObj->INTG_ATMP_GRAD.ToIntDef(1); break;
  449. case 407: nAtmpGrad = pAtmpObj->PM10_1HH_GRAD.ToIntDef(1); break;
  450. case 408: nAtmpGrad = pAtmpObj->PM25_1HH_GRAD.ToIntDef(1); break;
  451. case 413: nAtmpGrad = pAtmpObj->O3_GRAD.ToIntDef(1); break;
  452. }
  453. if (nAtmpGrad > 0) nAtmpGrad--;
  454. TCDSImage *pTmp1 = CDSImageManager->FLists.Find(pVmsObj->ImageId);
  455. if (pTmp1)
  456. {
  457. AnsiString sGradSymbId = pTmp1->GRAD_SYMB_LIB_NMBR[nAtmpGrad];
  458. TCDSImage *pTmp2 = CDSImageManager->FLists.Find(sGradSymbId);
  459. if (pTmp2) pVmsObj->pImageData->Picture->Assign(pTmp2->IMAG_DATA->Picture);
  460. else pVmsObj->pImageData->Picture->Assign(pTmp1->IMAG_DATA->Picture);
  461. pVmsObj->ImageId = sGradSymbId;
  462. }
  463. else
  464. {
  465. pVmsObj->pImageData->Picture->Assign(pCDSObj->pImage->Picture);
  466. }
  467. }
  468. }
  469. else
  470. {
  471. #if 0
  472. //TODO: 심볼, 이미지 인경우 실재 이미지와 설정된 이미지 크기가 다르면
  473. //설정된 크기에 맞게 이미지를 복사한다.
  474. if (pCDSObj->VMS_FORM_OBJECT_TYPE_CD == 1 || pCDSObj->VMS_FORM_OBJECT_TYPE_CD == 2)
  475. {
  476. if (pCDSObj->VMS_DSPL_WIDTH != pCDSObj->pImage->Picture->Width ||
  477. pCDSObj->VMS_DSPL_HEIGHT != pCDSObj->pImage->Picture->Height)
  478. {
  479. pVmsObj->pImageData->Width = pCDSObj->VMS_DSPL_WIDTH;
  480. pVmsObj->pImageData->Height= pCDSObj->VMS_DSPL_HEIGHT;
  481. //pVmsObj->pImageData->Picture->Width = pCDSObj->VMS_DSPL_WIDTH;
  482. //pVmsObj->pImageData->Picture->Height= pCDSObj->VMS_DSPL_HEIGHT;
  483. pVmsObj->pImageData->Picture->Bitmap->Width = pCDSObj->VMS_DSPL_WIDTH;
  484. pVmsObj->pImageData->Picture->Bitmap->Height= pCDSObj->VMS_DSPL_HEIGHT;
  485. //TODO
  486. SetStretchBltMode(pVmsObj->pImageData->Canvas->Handle, MAXSTRETCHBLTMODE);//HALFTONE);//MAXSTRETCHBLTMODE)//STRETCH_HALFTONE;
  487. //TODO
  488. SetStretchBltMode(pVmsObj->pImageData->Picture->Bitmap->Canvas->Handle, MAXSTRETCHBLTMODE);//HALFTONE);//MAXSTRETCHBLTMODE)//STRETCH_HALFTONE;
  489. pVmsObj->pImageData->Picture->Bitmap->Canvas->CopyRect(Classes::Rect(0, 0, pCDSObj->VMS_DSPL_WIDTH, pCDSObj->VMS_DSPL_HEIGHT),
  490. pCDSObj->pImage->Picture->Bitmap->Canvas,
  491. Classes::Rect(0, 0, pCDSObj->pImage->Picture->Width, pCDSObj->pImage->Picture->Height));
  492. }
  493. else
  494. {
  495. pVmsObj->pImageData->Picture->Assign(pCDSObj->pImage->Picture);
  496. }
  497. }
  498. else
  499. {
  500. pVmsObj->pImageData->Picture->Assign(pCDSObj->pImage->Picture);
  501. }
  502. #else
  503. pVmsObj->pImageData->Picture->Assign(pCDSObj->pImage->Picture);
  504. #endif
  505. }
  506. }
  507. catch(Exception &e)
  508. {
  509. MERROR("MAIN=============> SaveMemoryStream1: %s[%s] - %s", pVmsForm->VMS_FORM_ID.c_str(), pVmsObj->ImageId.c_str(), AnsiString(e.Message).c_str());
  510. }
  511. }
  512. __finally
  513. {
  514. pVmsObj->pImageData->Picture->Bitmap->Canvas->Unlock();
  515. pVmsObj->pImageStream->Clear();
  516. pVmsObj->pImageStream->Position = 0;
  517. pVmsObj->pImageData->Picture->Graphic->SaveToStream((Classes::TStream*)pVmsObj->pImageStream);
  518. }
  519. }
  520. }
  521. //폼객체 유형별 Fill In
  522. if (pVmsObj->ObjectType == 0 || //고정문자열
  523. pVmsObj->ObjectType == 201 || //동영상파일명
  524. pVmsObj->ObjectType == 301) //스트리밍영상주소
  525. {
  526. #if 0
  527. if (pObj->FBmpDownload == false && pObj->FIsOldProtocol == false)
  528. {
  529. //신규VMS인 경우 첫자리가 0 인경우 해당 문자를 표출하지 못함
  530. if (pVmsObj->TextData != "")
  531. {
  532. if (pVmsObj->TextData.SubString(1,1) == "0")
  533. {
  534. pVmsObj->TextData = " " + pVmsObj->TextData;
  535. pVmsObj->PosX = pVmsObj->PosX - 5;
  536. }
  537. }
  538. }
  539. #endif
  540. ChangePosition(pVmsObj);
  541. }
  542. else
  543. if (pVmsObj->ObjectType == 501 || //재난안전문자 1열
  544. pVmsObj->ObjectType == 502 || //재난안전문자 2열
  545. pVmsObj->ObjectType == 503 //재난안전문자 3열 ==> 포항은 3단 문자열이 없음
  546. )
  547. {
  548. VMS_SAFE_DETL *pEvt = pSchUnit->SAFE;
  549. if (pEvt)
  550. {
  551. switch(pVmsObj->ObjectType)
  552. {
  553. case 501: //재난안전문자 1열
  554. pVmsObj->TextData = pEvt->MSG_LN_1;
  555. break;
  556. case 502: //재난안전문자 2열
  557. pVmsObj->TextData = pEvt->MSG_LN_2;
  558. break;
  559. case 503: //재난안전문자 3열
  560. pVmsObj->TextData = pEvt->MSG_LN_3;
  561. break;
  562. }
  563. }
  564. ChangePosition(pVmsObj);
  565. }
  566. else
  567. if (pVmsObj->ObjectType == 1 || //심볼
  568. pVmsObj->ObjectType == 2 ) //파일이미지
  569. {
  570. ; //처리없음
  571. }
  572. else
  573. if (pVmsObj->ObjectType == 17 || //1단,소통정보이미지1
  574. pVmsObj->ObjectType == 27 || //2단,소통정보이미지2
  575. pVmsObj->ObjectType == 37 || //3단,소통정보이미지3
  576. pVmsObj->ObjectType == 47 || //4단,소통정보이미지4
  577. pVmsObj->ObjectType == 167 ) //@우회소통정보이미지
  578. {
  579. if (!pVmsObj->pImageData) continue;
  580. TCDSImage *pSymbol = CDSImageManager->FLists.Find(pVmsObj->ImageId);
  581. if (!pSymbol) continue;
  582. try
  583. {
  584. int X, Y;
  585. switch(pVmsObj->ObjectType)
  586. {
  587. case 17: pVmsObj->IFSC_ID = pSchUnit->FRST_IMG_IFSC_ID; break;
  588. case 27: pVmsObj->IFSC_ID = pSchUnit->SECD_IMG_IFSC_ID; break;
  589. case 37: pVmsObj->IFSC_ID = pSchUnit->THIR_IMG_IFSC_ID; break;
  590. case 47: pVmsObj->IFSC_ID = pSchUnit->FOUR_IMG_IFSC_ID; break;
  591. case 167: pVmsObj->IFSC_ID = pSchUnit->SECD_IMG_IFSC_ID; break;
  592. }
  593. FOR_STL(TCDSImageCell*, pCell, pSymbol->FLists)
  594. {
  595. TCDSIfsc *pTmpIfsc = CDSIfscManager->FLists.Find(pVmsObj->IFSC_ID);
  596. if (pTmpIfsc)
  597. {
  598. X = pCell->POSX;
  599. Y = pCell->POSY;
  600. pVmsObj->ImageId = pCDSObj->SYMB_LIB_NMBR + pTmpIfsc->CMTR_GRAD_CD;
  601. pVmsObj->pImageData->Picture->Bitmap->Canvas->Lock();
  602. try
  603. {
  604. pVmsObj->pImageData->Picture->Bitmap->Canvas->Brush->Style = bsSolid;
  605. pVmsObj->pImageData->Picture->Bitmap->Canvas->Brush->Color = GradeToFillColor(pTmpIfsc->CMTR_GRAD_CD.ToIntDef(0));
  606. TColor clColor = pVmsObj->pImageData->Picture->Bitmap->Canvas->Pixels[X][Y];
  607. // TODO: 구미시 부영아파트 등 흰색으로 표출한다.
  608. if (clColor != clWhite)
  609. {
  610. pVmsObj->pImageData->Picture->Bitmap->Canvas->FloodFill(X, Y, clColor, fsSurface);
  611. }
  612. }
  613. __finally
  614. {
  615. pVmsObj->pImageData->Picture->Bitmap->Canvas->Unlock();
  616. }
  617. }
  618. }
  619. pVmsObj->pImageStream->Clear();
  620. pVmsObj->pImageStream->Position = 0;
  621. pVmsObj->pImageData->Picture->Graphic->SaveToStream((Classes::TStream*)pVmsObj->pImageStream);
  622. }
  623. catch(Exception &e)
  624. {
  625. MERROR("MAIN=============> SaveMemoryStreamX: %s[%s] - %s", pVmsForm->VMS_FORM_ID.c_str(), pVmsObj->ImageId.c_str(), AnsiString(e.Message).c_str());
  626. }
  627. }
  628. else
  629. if (pVmsObj->ObjectType == 3) //소통정보 배경이미지
  630. {
  631. if (!pVmsObj->pImageData) continue;
  632. TCDSImage *pSymbol = CDSImageManager->FLists.Find(pVmsObj->ImageId);
  633. if (!pSymbol) continue;
  634. try
  635. {
  636. int X, Y;
  637. FOR_STL(TCDSImageCell*, pCell, pSymbol->FLists)
  638. {
  639. TCDSIfsc *pTmpIfsc = CDSIfscManager->FLists.Find(pCell->VMS_IFSC_ID);
  640. if (pTmpIfsc)
  641. {
  642. X = pCell->POSX;
  643. Y = pCell->POSY;
  644. pVmsObj->pImageData->Picture->Bitmap->Canvas->Lock();
  645. try
  646. {
  647. pVmsObj->pImageData->Picture->Bitmap->Canvas->Brush->Color = GradeToFillColor(pTmpIfsc->CMTR_GRAD_CD.ToIntDef(0));
  648. TColor clColor = pVmsObj->pImageData->Picture->Bitmap->Canvas->Pixels[X][Y];
  649. pVmsObj->pImageData->Picture->Bitmap->Canvas->FloodFill(X, Y, clColor, fsSurface);
  650. }
  651. __finally
  652. {
  653. pVmsObj->pImageData->Picture->Bitmap->Canvas->Unlock();
  654. }
  655. }
  656. }
  657. pVmsObj->pImageStream->Clear();
  658. pVmsObj->pImageStream->Position = 0;
  659. pVmsObj->pImageData->Picture->Graphic->SaveToStream((Classes::TStream*)pVmsObj->pImageStream);
  660. }
  661. catch(Exception &e)
  662. {
  663. MERROR("MAIN=============> SaveMemoryStream2: %s[%s] - %s", pVmsForm->VMS_FORM_ID.c_str(), pVmsObj->ImageId.c_str(), AnsiString(e.Message).c_str());
  664. }
  665. }
  666. else
  667. if (pVmsObj->ObjectType == 61 || //구간명
  668. pVmsObj->ObjectType == 62 || //시점명
  669. pVmsObj->ObjectType == 63 || //종점명
  670. pVmsObj->ObjectType == 64 || //돌발유형
  671. pVmsObj->ObjectType == 65 || //대응문구
  672. pVmsObj->ObjectType == 66 //통제유형
  673. )
  674. {
  675. //돌발문안인 경우임
  676. pVmsObj->TextData = " ";
  677. VMS_EVENT_DETL *pEvt = pSchUnit->EVENT;
  678. if (pEvt)
  679. {
  680. switch(pVmsObj->ObjectType)
  681. {
  682. case 61: pVmsObj->TextData = pEvt->VMS_IFSC_NM; break; //@구간명(사용안함)
  683. case 62: pVmsObj->TextData = pEvt->STRT_LCTN_NM; break; //@시점명
  684. case 63: pVmsObj->TextData = pEvt->END_LCTN_NM; break; //@종점명
  685. case 64: pVmsObj->TextData = pEvt->VMS_INCD_DETL_NM; break; //@돌발유형
  686. case 65: pVmsObj->TextData = pEvt->OCRR_LCTN_NM; break; //@대응문구(사용안함-발생장소로 일단넣음)
  687. case 66: pVmsObj->TextData = pEvt->VMS_INCD_RSTR_TYPE_NM; break; //@통제유형
  688. }
  689. }
  690. if (pVmsObj->TextData == "") pVmsObj->TextData = " ";
  691. ChangePosition(pVmsObj);
  692. //TB_VMS_FORM_OBJECT_TYPE 테이블에 유형추가하고
  693. //돌발화면에서 필요한 항목 추가, TB_INCD_OCRR_VMS 테이블에 컬럼추가해야함
  694. }
  695. else
  696. if (pVmsObj->ObjectType == 71 || //발생장소
  697. pVmsObj->ObjectType == 72 || //INCD_TITL
  698. pVmsObj->ObjectType == 73 || //통제시점명
  699. pVmsObj->ObjectType == 74 || //통제종점명
  700. pVmsObj->ObjectType == 75 || //00차로 차단
  701. pVmsObj->ObjectType == 76 || //00월00일 ~ 00월00일
  702. pVmsObj->ObjectType == 77 || //대응문구
  703. pVmsObj->ObjectType == 78 //@통제유형
  704. )
  705. {
  706. //공사/행사문안 임
  707. pVmsObj->TextData = " ";
  708. VMS_EVENT_DETL *pEvt = pSchUnit->EVENT;
  709. if (pEvt)
  710. {
  711. switch(pVmsObj->ObjectType)
  712. {
  713. case 71: pVmsObj->TextData = pEvt->OCRR_LCTN_NM; break; //발생장소
  714. case 72: pVmsObj->TextData = pEvt->INCD_TITL; break; //@공사행사명
  715. case 73: pVmsObj->TextData = pEvt->STRT_LCTN_NM; break; //통제시점명
  716. case 74: pVmsObj->TextData = pEvt->END_LCTN_NM; break; //통제종점명
  717. case 75:
  718. {
  719. int nLane = pEvt->INCD_CLSR_LANE.ToIntDef(0);
  720. if (nLane == 111111)
  721. pVmsObj->TextData = "차로 차단";
  722. else
  723. if (nLane > 0)
  724. pVmsObj->TextData = "일부 차단";
  725. else
  726. pVmsObj->TextData = " ";
  727. }
  728. break; //00차로 차단
  729. case 76: //00월00일 ~ 00월00일
  730. {
  731. String sFrom = pEvt->INCD_STRT_DT.SubString(5,2) + "월" + pEvt->INCD_STRT_DT.SubString(7,2) + "일 " + pEvt->INCD_STRT_DT.SubString(9,2) + "시";
  732. String sTo = pEvt->INCD_END_PRAR_DT.SubString(5,2) + "월" + pEvt->INCD_END_PRAR_DT.SubString(7,2) + "일 " + pEvt->INCD_END_PRAR_DT.SubString(9,2) + "시";
  733. pVmsObj->TextData = sFrom + " ~ " + sTo;
  734. }
  735. break;
  736. case 77: pVmsObj->TextData = pEvt->OCRR_LCTN_NM; break; //대응문구(사용안함-발생장소로 일단넣음)
  737. case 78: pVmsObj->TextData = pEvt->VMS_INCD_RSTR_TYPE_NM; break; //@통제유형
  738. }
  739. }
  740. if (pVmsObj->TextData == "") pVmsObj->TextData = " ";
  741. ChangePosition(pVmsObj);
  742. }
  743. else
  744. if (CDSAtmpManager &&
  745. (pVmsObj->ObjectType == 401 || //@관측장소
  746. pVmsObj->ObjectType == 402 || //@PM10
  747. pVmsObj->ObjectType == 403 || //@PM2.5
  748. pVmsObj->ObjectType == 404 || //@PM10등급
  749. pVmsObj->ObjectType == 405 || //@PM2.5등급
  750. pVmsObj->ObjectType == 409 || //@통합대기등급
  751. pVmsObj->ObjectType == 410 || //@통합대기
  752. pVmsObj->ObjectType == 411 || //@오존
  753. pVmsObj->ObjectType == 412 ) //@오존등급
  754. )
  755. {
  756. bool isObj = false;
  757. pAtmpObj = CDSAtmpManager->FLists.Find(pCDSObj->VMS_IFSC_ID);
  758. if (pAtmpObj && pAtmpObj->SUCCESS) isObj = true;
  759. AnsiString sUnit = "";
  760. bool bUnit = false;
  761. if (pVmsObj->TextData.Pos(" -"))
  762. {
  763. bUnit = true;
  764. sUnit = " ";
  765. }
  766. else
  767. if (pVmsObj->TextData.Pos("-"))
  768. {
  769. bUnit = true;
  770. }
  771. pVmsObj->TextData = " ";
  772. if (pVmsObj->ObjectType == 401)
  773. {
  774. pVmsObj->TextData = pAtmpObj ? pAtmpObj->VMS_DISP_NM : AnsiString("---");
  775. }
  776. else
  777. if (pVmsObj->ObjectType == 402)
  778. {
  779. pVmsObj->TextData = isObj ? pAtmpObj->GetPM10_VAL(false) : AnsiString("-");
  780. //TODO 20200528: 구미기존 도형식 하단쪽에 엘이디 고장난게 있어서 흰색으로 표출해야 해서
  781. // 폰트색상이 흰색인 경우 그냥 흰색으로 표출하는 것으로.....
  782. if (pVmsObj->TextFontColor != 10)
  783. {
  784. pVmsObj->TextFontColor = isObj ? pAtmpObj->GetPM10_CLR() : clRed;
  785. }
  786. if (bUnit) pVmsObj->TextData = pVmsObj->TextData + sUnit + "㎍/㎥";
  787. }
  788. else
  789. if (pVmsObj->ObjectType == 403)
  790. {
  791. pVmsObj->TextData = isObj ? pAtmpObj->GetPM25_VAL(false) : AnsiString("-");
  792. //TODO 20200528: 구미기존 도형식 하단쪽에 엘이디 고장난게 있어서 흰색으로 표출해야 해서
  793. // 폰트색상이 흰색인 경우 그냥 흰색으로 표출하는 것으로.....
  794. if (pVmsObj->TextFontColor != 10)
  795. {
  796. pVmsObj->TextFontColor = isObj ? pAtmpObj->GetPM25_CLR() : clRed;
  797. }
  798. if (bUnit) pVmsObj->TextData = pVmsObj->TextData + sUnit + "㎍/㎥";
  799. }
  800. else
  801. if (pVmsObj->ObjectType == 404)
  802. {
  803. pVmsObj->TextData = isObj ? pAtmpObj->GetPM10_GRAD() : AnsiString("-");
  804. //TODO 20200528: 구미기존 도형식 하단쪽에 엘이디 고장난게 있어서 흰색으로 표출해야 해서
  805. // 폰트색상이 흰색인 경우 그냥 흰색으로 표출하는 것으로.....
  806. if (pVmsObj->TextFontColor != 10)
  807. {
  808. pVmsObj->TextFontColor = isObj ? pAtmpObj->GetPM10_CLR() : clRed;
  809. }
  810. }
  811. else
  812. if (pVmsObj->ObjectType == 405)
  813. {
  814. pVmsObj->TextData = isObj ? pAtmpObj->GetPM25_GRAD() : AnsiString("-");
  815. //TODO 20200528: 구미기존 도형식 하단쪽에 엘이디 고장난게 있어서 흰색으로 표출해야 해서
  816. // 폰트색상이 흰색인 경우 그냥 흰색으로 표출하는 것으로.....
  817. if (pVmsObj->TextFontColor != 10)
  818. {
  819. pVmsObj->TextFontColor = isObj ? pAtmpObj->GetPM25_CLR() : clRed;
  820. }
  821. }
  822. else
  823. if (pVmsObj->ObjectType == 409)
  824. {
  825. pVmsObj->TextData = isObj ? pAtmpObj->GetATMP_GRAD() : AnsiString("-");
  826. //TODO 20200528: 구미기존 도형식 하단쪽에 엘이디 고장난게 있어서 흰색으로 표출해야 해서
  827. // 폰트색상이 흰색인 경우 그냥 흰색으로 표출하는 것으로.....
  828. if (pVmsObj->TextFontColor != 10)
  829. {
  830. pVmsObj->TextFontColor = isObj ? pAtmpObj->GetATMP_CLR() : clRed;
  831. }
  832. }
  833. else
  834. if (pVmsObj->ObjectType == 410)
  835. {
  836. pVmsObj->TextData = isObj ? pAtmpObj->GetATMP_VAL(false) : AnsiString("-");
  837. //TODO 20200528: 구미기존 도형식 하단쪽에 엘이디 고장난게 있어서 흰색으로 표출해야 해서
  838. // 폰트색상이 흰색인 경우 그냥 흰색으로 표출하는 것으로.....
  839. if (pVmsObj->TextFontColor != 10)
  840. {
  841. pVmsObj->TextFontColor = isObj ? pAtmpObj->GetATMP_CLR() : clRed;
  842. }
  843. }
  844. else
  845. if (pVmsObj->ObjectType == 411)
  846. {
  847. pVmsObj->TextData = isObj ? pAtmpObj->GetO3_VAL(false) : AnsiString("-");
  848. //TODO 20200528: 구미기존 도형식 하단쪽에 엘이디 고장난게 있어서 흰색으로 표출해야 해서
  849. // 폰트색상이 흰색인 경우 그냥 흰색으로 표출하는 것으로.....
  850. if (pVmsObj->TextFontColor != 10)
  851. {
  852. pVmsObj->TextFontColor = isObj ? pAtmpObj->GetO3_CLR() : clRed;
  853. }
  854. if (bUnit) pVmsObj->TextData = pVmsObj->TextData + sUnit + "ppm";
  855. }
  856. else
  857. if (pVmsObj->ObjectType == 412)
  858. {
  859. pVmsObj->TextData = isObj ? pAtmpObj->GetO3_GRAD() : AnsiString("-");
  860. //TODO 20200528: 구미기존 도형식 하단쪽에 엘이디 고장난게 있어서 흰색으로 표출해야 해서
  861. // 폰트색상이 흰색인 경우 그냥 흰색으로 표출하는 것으로.....
  862. if (pVmsObj->TextFontColor != 10)
  863. {
  864. pVmsObj->TextFontColor = isObj ? pAtmpObj->GetO3_CLR() : clRed;
  865. }
  866. }
  867. if (pVmsObj->TextData == "") pVmsObj->TextData = " ";
  868. ChangePosition(pVmsObj);
  869. }
  870. else
  871. if (pVmsObj->ObjectType == 101 || //@주차장명
  872. pVmsObj->ObjectType == 102 || //@주차면수
  873. pVmsObj->ObjectType == 103 || //@주차가능면수
  874. pVmsObj->ObjectType == 104 //@주차혼잡도
  875. )
  876. {
  877. TCDSPark *pPark = NULL;
  878. if (CDSParkManager) {
  879. pPark = CDSParkManager->FLists.Find(pCDSObj->VMS_IFSC_ID);
  880. }
  881. if (pPark)
  882. {
  883. AnsiString sFmt = pCDSObj->VMS_DSPL_TXT;
  884. sFmt = StringReplace(sFmt, "@", "", TReplaceFlags() << rfReplaceAll);
  885. switch(pVmsObj->ObjectType) {
  886. case 101:// || //@주차장명
  887. pVmsObj->TextData = pPark->GetParkName();
  888. break;
  889. case 102:// || //@주차면수
  890. pVmsObj->TextData = pPark->GetTotalCo(sFmt);
  891. //pVmsObj->TextFontColor = pPark->GetGradeColor();
  892. break;
  893. case 103:// || //@주차가능면수
  894. pVmsObj->TextData = pPark->GetRemainCo(sFmt);
  895. pVmsObj->TextFontColor = pPark->GetGradeColor();
  896. if (pPark->FULL) {
  897. }
  898. break;
  899. case 104:// //@주차혼잡도
  900. pVmsObj->TextData = pPark->GetCgsSttus();
  901. pVmsObj->TextFontColor = pPark->GetGradeColor();
  902. break;
  903. }
  904. }
  905. else
  906. {
  907. pVmsObj->TextData = "-";
  908. pVmsObj->TextFontColor = clRed;
  909. }
  910. if (pVmsObj->TextData == "") pVmsObj->TextData = " ";
  911. ChangePosition(pVmsObj);
  912. }
  913. else
  914. if (pVmsObj->ObjectType == 81 || //돌발종류
  915. pVmsObj->ObjectType == 82 || //해당도로
  916. pVmsObj->ObjectType == 83 || //우회도로
  917. pVmsObj->ObjectType == 84 ) //발생장소
  918. {
  919. pVmsObj->TextData = " ";
  920. VMS_EVENT_DETL *pEvt = pSchUnit->EVENT;
  921. if (pEvt)
  922. {
  923. switch(pVmsObj->ObjectType)
  924. {
  925. case 81: pVmsObj->TextData = pEvt->VMS_INCD_DETL_NM; break; //돌발종류
  926. case 82: pVmsObj->TextData = pEvt->VMS_IFSC_NM; break; //해당도로
  927. case 83: pVmsObj->TextData = pEvt->VMS_IFSC_NM; break; //우회도로
  928. case 84: pVmsObj->TextData = pEvt->OCRR_LCTN_NM; break; //발생장소
  929. }
  930. }
  931. if (pVmsObj->TextData == "") pVmsObj->TextData = " ";
  932. ChangePosition(pVmsObj);
  933. }
  934. else
  935. {
  936. //객체가 가변(소통정보 표출) 인 경우 가변문자를 설정하자....
  937. AnsiString VMS_IFSC_ID = "";
  938. switch(pVmsObj->ObjectType)
  939. {
  940. case 11: case 12: case 13: case 14: case 15: case 16: case 18: case 19:
  941. VMS_IFSC_ID = pSchUnit->FRST_VMS_IFSC_ID;
  942. if (pVmsForm->VMS_FORM_TYPE_CD == eFormtp_figure)
  943. {
  944. VMS_IFSC_ID = pSchUnit->VMS_IFSC_ID;
  945. }
  946. else
  947. if (pVmsForm->VMS_FORM_TYPE_CD == enFormKindCongest)// && pVmsObj->ObjectType == 18)
  948. {
  949. VMS_IFSC_ID = pSchUnit->VMS_IFSC_ID;
  950. }
  951. break;
  952. case 161: case 162: case 163: case 164: case 165: case 166: case 168:
  953. VMS_IFSC_ID = pSchUnit->SECD_VMS_IFSC_ID;
  954. break;
  955. case 21: case 22: case 23: case 24: case 25: case 26: case 28:
  956. VMS_IFSC_ID = pSchUnit->SECD_VMS_IFSC_ID;
  957. break;
  958. case 31: case 32: case 33: case 34: case 35: case 36: case 38:
  959. VMS_IFSC_ID = pSchUnit->THIR_VMS_IFSC_ID;
  960. break;
  961. case 41: case 42: case 43: case 44: case 45: case 46: case 48:
  962. VMS_IFSC_ID = pSchUnit->FOUR_VMS_IFSC_ID;
  963. break;
  964. case 91: case 92:
  965. VMS_IFSC_ID = pCDSObj->VMS_IFSC_ID; //축통행시간/축소통상황(고정)
  966. break;
  967. case 93: case 94: case 95: case 96:
  968. VMS_IFSC_ID = pSchUnit->VMS_IFSC_ID;
  969. break;
  970. default: continue;
  971. }
  972. pVmsObj->TextData = " ";
  973. TCDSIfsc *pTmpIfsc = CDSIfscManager->FLists.Find(VMS_IFSC_ID);
  974. if (pTmpIfsc)
  975. {
  976. switch(pVmsObj->ObjectType)
  977. {
  978. case 11: case 21: case 31: case 41: case 161: //구간명
  979. pVmsObj->TextData = pTmpIfsc->ROAD_NM;
  980. break;
  981. case 12: case 22: case 32: case 42: case 93: case 162: //시점명
  982. pVmsObj->TextData = pTmpIfsc->DSPL_STRT_NODE_NM;
  983. break;
  984. case 13: case 23: case 33: case 43: case 94: case 163: //종점명
  985. pVmsObj->TextData = pTmpIfsc->DSPL_END_NODE_NM;
  986. break;
  987. case 14: case 24: case 34: case 44: case 92: case 95: case 164: //소통상황
  988. pVmsObj->TextData = GradeToString(pTmpIfsc->CMTR_GRAD_CD.ToIntDef(0), pVmsForm->VMS_FORM_TYPE_CD);
  989. //TODO 20200528: 구미기존 도형식 하단쪽에 엘이디 고장난게 있어서 흰색으로 표출해야 해서
  990. // 폰트색상이 흰색인 경우 그냥 흰색으로 표출하는 것으로.....
  991. if (pVmsObj->TextFontColor != 10)
  992. {
  993. pVmsObj->TextFontColor = GradeToColorCode(pTmpIfsc->CMTR_GRAD_CD.ToIntDef(0));
  994. }
  995. break;
  996. case 19: //소통상황(가변)
  997. {
  998. AnsiString sGradText = GradeToString(pTmpIfsc->CMTR_GRAD_CD.ToIntDef(0), pVmsForm->VMS_FORM_TYPE_CD);
  999. if (pTmpIfsc->CMTR_GRAD_CD.ToIntDef(0) == grade_smoothness)
  1000. {
  1001. sGradText.printf("소통원활 약 %d 분", pTmpIfsc->TRVL_HH);
  1002. }
  1003. pVmsObj->TextData = sGradText;
  1004. pVmsObj->TextFontColor = GradeToColorCode(pTmpIfsc->CMTR_GRAD_CD.ToIntDef(0));
  1005. }
  1006. break;
  1007. case 15: case 25: case 35: case 45: case 91: case 96: case 165: //통행시간
  1008. if (pTmpIfsc->TRVL_HH > 0)
  1009. {
  1010. AnsiString sFmt = pCDSObj->VMS_DSPL_TXT;
  1011. sFmt = StringReplace(sFmt, "@", "", TReplaceFlags() << rfReplaceAll);
  1012. if (sFmt.Pos("0"))
  1013. {
  1014. sFmt = StringReplace(sFmt, "0000", "%4d", TReplaceFlags() << rfReplaceAll);
  1015. sFmt = StringReplace(sFmt, "000", "%3d", TReplaceFlags() << rfReplaceAll);
  1016. sFmt = StringReplace(sFmt, "00", "%2d", TReplaceFlags() << rfReplaceAll);
  1017. sFmt = StringReplace(sFmt, "0", "%d", TReplaceFlags() << rfReplaceAll);
  1018. pVmsObj->TextData.printf(sFmt.c_str(), pTmpIfsc->TRVL_HH);
  1019. }
  1020. else
  1021. {
  1022. pVmsObj->TextData = AnsiString(pTmpIfsc->TRVL_HH);
  1023. }
  1024. pVmsObj->TextFontColor = GradeToColorCode(pTmpIfsc->CMTR_GRAD_CD.ToIntDef(0));
  1025. }
  1026. else
  1027. {
  1028. pVmsObj->TextData = " ";
  1029. pVmsObj->TextFontColor = clBlack;
  1030. }
  1031. break;
  1032. case 16: case 26: case 36: case 46: case 166: //통행속도
  1033. pVmsObj->TextData = AnsiString(pTmpIfsc->SPED);
  1034. pVmsObj->TextFontColor = GradeToColorCode(pTmpIfsc->CMTR_GRAD_CD.ToIntDef(0));
  1035. break;
  1036. case 17: case 27: case 37: case 47: //방향이미지...???
  1037. break;
  1038. case 18: case 28: case 38: case 48: case 168: //지점명
  1039. pVmsObj->TextData = pTmpIfsc->SPOT_NM;
  1040. break;
  1041. }
  1042. ChangePosition(pVmsObj);
  1043. }
  1044. }
  1045. } //FOR_STL(폼객체생성)
  1046. pVmsForm->UnLock();
  1047. } //for(최대 제공 메시지 갯수만큼 생성)
  1048. }
  1049. __finally
  1050. {
  1051. pObj->pForms->UnLock();
  1052. }
  1053. } //iterator(VMS전체루프)
  1054. MINFO("MAIN=============> MakeVmsProvideForm: End. (VMS: %d EA, Forms %d EA), %u ms.", nSaveVmsCnt, nSaveFormCnt, dwEnd-dwStart);
  1055. MINFO("MAIN=============> MakeVmsDatabaseForm: Start");
  1056. nSaveVmsCnt = 0;
  1057. nSaveFormCnt= 0;
  1058. //데이터베이스에 저장할 폼을 생성한다.
  1059. for(it=CDSCtlrManager->FLists.FObjects.begin(); it != CDSCtlrManager->FLists.FObjects.end(); ++it)
  1060. {
  1061. TCDSCtlr *pObj = (TCDSCtlr*)it->second;
  1062. if (!pObj->Used) continue;
  1063. if (!pObj->FProvide) continue;
  1064. if (g_AppCfg.BottomTrafficCenter)
  1065. {
  1066. //도형식폼의 하단소통정보위치를 가운데로 정렬하는 경우
  1067. MakeVmsFigureFormPos(pObj);
  1068. }
  1069. if (g_AppCfg.TextTrafficCenter && pObj->TYPE_CD == "VMP2") //2단 12열 일 경우 정렬
  1070. {
  1071. //1단교통정보의 이정을 가운데로 정렬하는 경우
  1072. MakeVmsTrafficFormPos2(pObj);
  1073. }
  1074. nSaveFormCnt += MakeVmsDatabaseForm(pObj);
  1075. nSaveVmsCnt++;
  1076. }
  1077. g_ToggleFormSeq++;
  1078. if (g_ToggleFormSeq >= 6) g_ToggleFormSeq = 1;
  1079. MINFO("MAIN=============> MakeVmsDatabaseForm: End. (VMS: %d EA, Forms %d EA), %u ms.", nSaveVmsCnt, nSaveFormCnt, GetTickCount()-dwEnd);
  1080. return VERR_NONE;
  1081. }
  1082. //---------------------------------------------------------------------------
  1083. int __fastcall MakeVmsFigureFormPos(TCDSCtlr *AObj)
  1084. {
  1085. int ARRAWGAP = 7;
  1086. int TRAFFGAP = 17;
  1087. int nSelCnt = 0;
  1088. if (!AObj) return VERR_MEMORY_ALLOC;
  1089. int nFormCnt = AObj->pForms->Count();
  1090. if (nFormCnt == 0) return nSelCnt;
  1091. if (nFormCnt > MAX_VMS_SCENARIO_FORM) {
  1092. MINFO("MAIN=============> ERROR: %25.25s: %s, Form Count Over: %d/%d EA.", __MYFUNC__, AObj->CTLR_NMBR.c_str(), nFormCnt, MAX_VMS_SCENARIO_FORM);
  1093. nFormCnt = MAX_VMS_SCENARIO_FORM;
  1094. }
  1095. int nObjCnt;
  1096. int nFormT;
  1097. TVmsFormObj *pArw;
  1098. TVmsFormObj *pStr;
  1099. TVmsFormObj *pEnd;
  1100. TVmsFormObj *pTrf;
  1101. int nTotW;
  1102. int nLeft;
  1103. AObj->pForms->Lock();
  1104. try
  1105. {
  1106. try
  1107. {
  1108. for (int ii = 0; ii < nFormCnt; ii++)
  1109. {
  1110. TVmsForm *pForm = AObj->pForms->GetItem(ii);
  1111. if (pForm->VMS_FORM_TYPE_CD != eFormtp_figure)
  1112. {
  1113. //도형식배경소통정보 폼이 아닌경우 계산하지 않음
  1114. continue;
  1115. }
  1116. nFormT = pForm->Height - 40; //하단소통정보 객체의 최대높이를 설정, 이것보다 작으면 위치조정 하지 않음
  1117. pArw = NULL;
  1118. pStr = NULL;
  1119. pEnd = NULL;
  1120. pTrf = NULL;
  1121. //소통상황 시점 -> 종점
  1122. //시점 -> 종점 소통상황
  1123. //위의 2가지 유형에 대하여 가운데 정렬
  1124. nObjCnt = pForm->Count();
  1125. for (int jj = 0; jj < nObjCnt; jj++)
  1126. {
  1127. TVmsFormObj *pFormObj = pForm->GetItem(jj);
  1128. if (pFormObj->PosY < nFormT)
  1129. {
  1130. continue;
  1131. }
  1132. switch(pFormObj->ObjectType)
  1133. {
  1134. //////////////////////// 20200515 수정함(S)
  1135. case 1: // 심볼 Y
  1136. case 2: // 이미지 Y
  1137. if (pFormObj->TRFC_FILL_CD == "T")
  1138. {
  1139. pArw = pFormObj;
  1140. }
  1141. break;
  1142. case 17: // @소통정보이미지 N
  1143. pArw = pFormObj;
  1144. break;
  1145. //////////////////////// 20200515 수정함(E)
  1146. case 12: // @시점명 Y
  1147. case 93: // @축시점명(순환) Y
  1148. case 13: // @종점명 Y
  1149. case 94: // @축종점명(순환) Y
  1150. if (pFormObj->ObjectType == 12 || pFormObj->ObjectType == 93)
  1151. {
  1152. pStr = pFormObj;
  1153. }
  1154. else
  1155. {
  1156. pEnd = pFormObj;
  1157. }
  1158. break;
  1159. case 14: // @소통상황 Y
  1160. case 15: // @통행시간 Y
  1161. case 16: // @통행속도 N
  1162. case 95: // @축소통상황(순환) Y
  1163. case 96: // @축통행시간(순환) Y
  1164. pTrf = pFormObj;
  1165. break;
  1166. }
  1167. }
  1168. if (pArw && pStr && pEnd && pTrf)
  1169. {
  1170. if ((pStr->TextWidth +
  1171. pArw->TextWidth +
  1172. pEnd->TextWidth +
  1173. pTrf->TextWidth) > (pForm->Width - ARRAWGAP - ARRAWGAP - TRAFFGAP - 10)
  1174. )
  1175. {
  1176. ARRAWGAP = 3;
  1177. TRAFFGAP = 10;
  1178. }
  1179. nTotW = pStr->TextWidth + ARRAWGAP +
  1180. pArw->TextWidth + ARRAWGAP +
  1181. pEnd->TextWidth + TRAFFGAP +
  1182. pTrf->TextWidth;
  1183. nLeft = (pForm->Width - nTotW) / 2;
  1184. if (pStr->PosX < pTrf->PosX)
  1185. {
  1186. //시점 -> 종점 소통상황
  1187. pStr->PosX = nLeft;
  1188. pArw->PosX = pStr->PosX + pStr->TextWidth + ARRAWGAP;
  1189. pEnd->PosX = pArw->PosX + pArw->TextWidth + ARRAWGAP;
  1190. pTrf->PosX = pEnd->PosX + pEnd->TextWidth + TRAFFGAP;
  1191. }
  1192. else
  1193. {
  1194. //소통상황 시점 -> 종점
  1195. pTrf->PosX = nLeft;
  1196. pStr->PosX = pTrf->PosX + pTrf->TextWidth + TRAFFGAP;
  1197. pArw->PosX = pStr->PosX + pStr->TextWidth + ARRAWGAP;
  1198. pEnd->PosX = pArw->PosX + pArw->TextWidth + ARRAWGAP;
  1199. }
  1200. }
  1201. }
  1202. }
  1203. catch(Exception &e)
  1204. {
  1205. MERROR("MAIN=============> MakeVmsFigureFormPos error: %s, %s", AnsiString(e.ClassName()).c_str(), AnsiString(e.Message).c_str());
  1206. }
  1207. }
  1208. __finally
  1209. {
  1210. AObj->pForms->UnLock();
  1211. }
  1212. return nSelCnt;
  1213. }
  1214. //---------------------------------------------------------------------------
  1215. int __fastcall MakeVmsFigureFormPos2(TCDSCtlr *AObj)
  1216. {
  1217. int nSelCnt = 0;
  1218. if (!AObj) return VERR_MEMORY_ALLOC;
  1219. int nFormCnt = AObj->pForms->Count();
  1220. if (nFormCnt == 0) return nSelCnt;
  1221. if (nFormCnt > MAX_VMS_SCENARIO_FORM) {
  1222. MINFO("MAIN=============> ERROR: %25.25s: %s, Form Count Over: %d/%d EA.", __MYFUNC__, AObj->CTLR_NMBR.c_str(), nFormCnt, MAX_VMS_SCENARIO_FORM);
  1223. nFormCnt = MAX_VMS_SCENARIO_FORM;
  1224. }
  1225. int nObjCnt;
  1226. int nFormT;
  1227. int nGapL, nGapR;
  1228. TVmsFormObj *pArw;
  1229. TVmsFormObj *pStr;
  1230. TVmsFormObj *pEnd;
  1231. TVmsFormObj *pTrf;
  1232. int nTotW;
  1233. int nLeft;
  1234. AObj->pForms->Lock();
  1235. try
  1236. {
  1237. try
  1238. {
  1239. for (int ii = 0; ii < nFormCnt; ii++)
  1240. {
  1241. TVmsForm *pForm = AObj->pForms->GetItem(ii);
  1242. if (pForm->VMS_FORM_TYPE_CD != eFormtp_figure)
  1243. {
  1244. //도형식배경소통정보 폼이 아닌경우 계산하지 않음
  1245. continue;
  1246. }
  1247. nFormT = pForm->Height - 40; //하단소통정보 객체의 최대높이를 설정, 이것보다 작으면 위치조정 하지 않음
  1248. pArw = NULL;
  1249. pStr = NULL;
  1250. pEnd = NULL;
  1251. pTrf = NULL;
  1252. //소통상황 시점 -> 종점
  1253. //시점 -> 종점 소통상황
  1254. //위의 2가지 유형에 대하여 가운데 정렬
  1255. nObjCnt = pForm->Count();
  1256. for (int jj = 0; jj < nObjCnt; jj++)
  1257. {
  1258. TVmsFormObj *pFormObj = pForm->GetItem(jj);
  1259. if (pFormObj->PosY < nFormT)
  1260. {
  1261. continue;
  1262. }
  1263. switch(pFormObj->ObjectType)
  1264. {
  1265. //////////////////////// 20200515 수정함(S)
  1266. case 1: // 심볼 Y
  1267. case 2: // 이미지 Y
  1268. if (pFormObj->TRFC_FILL_CD == "T")
  1269. {
  1270. pArw = pFormObj;
  1271. }
  1272. break;
  1273. case 17: // @소통정보이미지 N
  1274. pArw = pFormObj;
  1275. break;
  1276. //////////////////////// 20200515 수정함(E)
  1277. case 12: // @시점명 Y
  1278. case 93: // @축시점명(순환) Y
  1279. case 13: // @종점명 Y
  1280. case 94: // @축종점명(순환) Y
  1281. if (pFormObj->ObjectType == 12 || pFormObj->ObjectType == 93)
  1282. {
  1283. pStr = pFormObj;
  1284. }
  1285. else
  1286. {
  1287. pEnd = pFormObj;
  1288. }
  1289. break;
  1290. case 14: // @소통상황 Y
  1291. case 15: // @통행시간 Y
  1292. case 16: // @통행속도 N
  1293. case 95: // @축소통상황(순환) Y
  1294. case 96: // @축통행시간(순환) Y
  1295. pTrf = pFormObj;
  1296. break;
  1297. }
  1298. }
  1299. if (pArw && pStr && pEnd && pTrf)
  1300. {
  1301. nGapL = pArw->PosX - (pStr->PosX + pStr->TextWidth); // 시점 화살표 사이의 간격
  1302. nGapR = pEnd->PosX - (pArw->PosX + pArw->TextWidth); // 종점 화살표 사이의 간격
  1303. if (pStr->PosX < pTrf->PosX)
  1304. {
  1305. //시점 -> 종점 소통상황
  1306. nTotW = (pTrf->PosX + pTrf->TextWidth) - pStr->PosX; // 전체길이
  1307. nLeft = (pForm->Width - nTotW) / 2;
  1308. pStr->PosX = nLeft;
  1309. pArw->PosX = pStr->PosX + pStr->TextWidth + nGapL;
  1310. pEnd->PosX = pArw->PosX + pArw->TextWidth + nGapR;
  1311. pTrf->PosX = (nLeft + nTotW) - pTrf->TextWidth;
  1312. }
  1313. else
  1314. {
  1315. //소통상황 시점 -> 종점
  1316. nTotW = (pEnd->PosX + pEnd->TextWidth) - pTrf->PosX; // 전체길이
  1317. nLeft = (pForm->Width - nTotW) / 2;
  1318. pTrf->PosX = nLeft;
  1319. pEnd->PosX = (nLeft + nTotW) - pEnd->TextWidth;
  1320. pArw->PosX = pEnd->PosX + pArw->TextWidth - nGapR;
  1321. pStr->PosX = pArw->PosX - pStr->TextWidth - nGapL;
  1322. }
  1323. }
  1324. }
  1325. }
  1326. catch(Exception &e)
  1327. {
  1328. MERROR("MAIN=============> MakeVmsFigureFormPos2 error: %s, %s", AnsiString(e.ClassName()).c_str(), AnsiString(e.Message).c_str());
  1329. }
  1330. }
  1331. __finally
  1332. {
  1333. AObj->pForms->UnLock();
  1334. }
  1335. return nSelCnt;
  1336. }
  1337. //---------------------------------------------------------------------------
  1338. int __fastcall MakeVmsTrafficFormPos(TCDSCtlr *AObj)
  1339. {
  1340. int ARRAWGAP = 5;
  1341. int nSelCnt = 0;
  1342. if (!AObj) return VERR_MEMORY_ALLOC;
  1343. int nFormCnt = AObj->pForms->Count();
  1344. if (nFormCnt == 0) return nSelCnt;
  1345. if (nFormCnt > MAX_VMS_SCENARIO_FORM) {
  1346. MINFO("MAIN=============> ERROR: %25.25s: %s, Form Count Over: %d/%d EA.", __MYFUNC__, AObj->CTLR_NMBR.c_str(), nFormCnt, MAX_VMS_SCENARIO_FORM);
  1347. nFormCnt = MAX_VMS_SCENARIO_FORM;
  1348. }
  1349. int nObjCnt;
  1350. int nFormT;
  1351. TVmsFormObj *pArw;
  1352. TVmsFormObj *pStr;
  1353. TVmsFormObj *pEnd;
  1354. int nTotW;
  1355. int nLeft;
  1356. AObj->pForms->Lock();
  1357. try
  1358. {
  1359. try
  1360. {
  1361. for (int ii = 0; ii < nFormCnt; ii++)
  1362. {
  1363. TVmsForm *pForm = AObj->pForms->GetItem(ii);
  1364. if (pForm->VMS_FORM_TYPE_CD != eFormTp_traf_1)
  1365. {
  1366. //소통상황(1단) 폼이 아닌경우 계산하지 않음
  1367. continue;
  1368. }
  1369. pArw = NULL;
  1370. pStr = NULL;
  1371. pEnd = NULL;
  1372. // 시점(12) -> 종점(13)
  1373. nObjCnt = pForm->Count();
  1374. for (int jj = 0; jj < nObjCnt; jj++)
  1375. {
  1376. TVmsFormObj *pFormObj = pForm->GetItem(jj);
  1377. switch(pFormObj->ObjectType)
  1378. {
  1379. case 12: // @시점명 Y
  1380. pStr = pFormObj;
  1381. break;
  1382. case 13: // @종점명 Y
  1383. pEnd = pFormObj;
  1384. break;
  1385. }
  1386. }
  1387. for (int jj = 0; jj < nObjCnt; jj++)
  1388. {
  1389. TVmsFormObj *pFormObj = pForm->GetItem(jj);
  1390. switch(pFormObj->ObjectType)
  1391. {
  1392. case 1: // @심볼 Y
  1393. case 2: // @이미지 Y
  1394. case 17: // @소통정보이미지 Y
  1395. //if (pFormObj->TRFC_FILL_CD == "T")
  1396. if (pStr && pFormObj->PosY <= (pStr->PosY+pStr->Height) )
  1397. {
  1398. pArw = pFormObj;
  1399. }
  1400. break;
  1401. }
  1402. }
  1403. if (pArw && pStr && pEnd)
  1404. {
  1405. int nRange = pStr->PosY + pStr->Height;
  1406. if (pArw->PosY <= nRange && pEnd->PosY <= nRange)
  1407. {
  1408. nLeft = 0;
  1409. nTotW = pStr->TextWidth + ARRAWGAP +
  1410. pArw->TextWidth + ARRAWGAP +
  1411. pEnd->TextWidth;
  1412. if (nTotW < pForm->Width)
  1413. {
  1414. nLeft = (pForm->Width - nTotW) / 2;
  1415. }
  1416. nLeft = (pForm->Width - nTotW) / 2;
  1417. pStr->PosX = nLeft;
  1418. pArw->PosX = pStr->PosX + pStr->TextWidth + ARRAWGAP;
  1419. pEnd->PosX = pArw->PosX + pArw->TextWidth + ARRAWGAP;
  1420. }
  1421. }
  1422. }
  1423. }
  1424. catch(Exception &e)
  1425. {
  1426. MERROR("MAIN=============> MakeVmsTrafficFormPos error: %s, %s", AnsiString(e.ClassName()).c_str(), AnsiString(e.Message).c_str());
  1427. }
  1428. }
  1429. __finally
  1430. {
  1431. AObj->pForms->UnLock();
  1432. }
  1433. return nSelCnt;
  1434. }
  1435. //---------------------------------------------------------------------------
  1436. int __fastcall MakeVmsTrafficFormPos2(TCDSCtlr *AObj)
  1437. {
  1438. // 시점 화살표 종점 의 좌표는 폼생성할때 정의된데로 하고
  1439. // 시점 화살표 종점의 전체 길이를 폼의 넓이로 환산하여 가운데 정렬
  1440. // 시점(오른쪽정렬) 화살표(의미없고) 종점(왼쪽정렬) 로 폼설정에서 설정하도록 한다.
  1441. // 시점/화살표/종점의 Y축 좌표도 설정한 데로 표출한다.
  1442. // 시점/화살표/종점을 폼의 가운데에 정렬하는 것이다.
  1443. int nSelCnt = 0;
  1444. if (!AObj) return VERR_MEMORY_ALLOC;
  1445. int nFormCnt = AObj->pForms->Count();
  1446. if (nFormCnt == 0) return nSelCnt;
  1447. if (nFormCnt > MAX_VMS_SCENARIO_FORM) {
  1448. MINFO("MAIN=============> ERROR: %25.25s: %s, Form Count Over: %d/%d EA.", __MYFUNC__, AObj->CTLR_NMBR.c_str(), nFormCnt, MAX_VMS_SCENARIO_FORM);
  1449. nFormCnt = MAX_VMS_SCENARIO_FORM;
  1450. }
  1451. int nObjCnt;
  1452. int nGapL;
  1453. TVmsFormObj *pArw;
  1454. TVmsFormObj *pStr;
  1455. TVmsFormObj *pEnd;
  1456. int nTotW;
  1457. int nLeft;
  1458. AObj->pForms->Lock();
  1459. try
  1460. {
  1461. try
  1462. {
  1463. for (int ii = 0; ii < nFormCnt; ii++)
  1464. {
  1465. TVmsForm *pForm = AObj->pForms->GetItem(ii);
  1466. if (pForm->VMS_FORM_TYPE_CD != eFormTp_traf_1)
  1467. {
  1468. //소통상황(1단) 폼이 아닌경우 계산하지 않음
  1469. continue;
  1470. }
  1471. pArw = NULL;
  1472. pStr = NULL;
  1473. pEnd = NULL;
  1474. // 시점(12) -> 종점(13)
  1475. nObjCnt = pForm->Count();
  1476. for (int jj = 0; jj < nObjCnt; jj++)
  1477. {
  1478. TVmsFormObj *pFormObj = pForm->GetItem(jj);
  1479. switch(pFormObj->ObjectType)
  1480. {
  1481. case 12: // @시점명 Y
  1482. pStr = pFormObj;
  1483. break;
  1484. case 13: // @종점명 Y
  1485. pEnd = pFormObj;
  1486. break;
  1487. }
  1488. }
  1489. for (int jj = 0; jj < nObjCnt; jj++)
  1490. {
  1491. TVmsFormObj *pFormObj = pForm->GetItem(jj);
  1492. switch(pFormObj->ObjectType)
  1493. {
  1494. case 1: // @심볼 Y
  1495. case 2: // @이미지 Y
  1496. case 17: // @소통정보이미지 Y
  1497. //if (pFormObj->TRFC_FILL_CD == "T")
  1498. if (pStr && pFormObj->PosY <= (pStr->PosY+pStr->Height) )
  1499. {
  1500. pArw = pFormObj;
  1501. }
  1502. break;
  1503. }
  1504. }
  1505. if (pArw && pStr && pEnd)
  1506. {
  1507. //시점 화살표 종점 순으로 되어 있어야 한다.
  1508. int nRange = pStr->PosY + pStr->Height;
  1509. if (pArw->PosY <= nRange && pEnd->PosY <= nRange)
  1510. {
  1511. nGapL = pArw->PosX - (pStr->PosX + pStr->TextWidth); // 시점 화살표 사이의 간격
  1512. nTotW = (pEnd->PosX + pEnd->TextWidth) - pStr->PosX; // 전체길이
  1513. nLeft = (pForm->Width - nTotW) / 2;
  1514. pStr->PosX = nLeft;
  1515. pArw->PosX = pStr->PosX + pStr->TextWidth + nGapL;
  1516. pEnd->PosX = (nLeft + nTotW) - pEnd->TextWidth;
  1517. }
  1518. }
  1519. }
  1520. }
  1521. catch(Exception &e)
  1522. {
  1523. MERROR("MAIN=============> MakeVmsFigureFormPos2 error: %s, %s", AnsiString(e.ClassName()).c_str(), AnsiString(e.Message).c_str());
  1524. }
  1525. }
  1526. __finally
  1527. {
  1528. AObj->pForms->UnLock();
  1529. }
  1530. return nSelCnt;
  1531. }
  1532. //---------------------------------------------------------------------------
  1533. int __fastcall MakeVmsDatabaseForm(TCDSCtlr *AObj)
  1534. {
  1535. int nSelCnt = 0;
  1536. if (!AObj) return VERR_MEMORY_ALLOC;
  1537. int nFormCnt = AObj->pForms->Count();
  1538. if (nFormCnt == 0) return nSelCnt;
  1539. if (nFormCnt > MAX_VMS_SCENARIO_FORM) {
  1540. MINFO("MAIN=============> ERROR: %25.25s: %s, Form Count Over: %d/%d EA.", __MYFUNC__, AObj->CTLR_NMBR.c_str(), nFormCnt, MAX_VMS_SCENARIO_FORM);
  1541. nFormCnt = MAX_VMS_SCENARIO_FORM;
  1542. }
  1543. AObj->pForms->Lock();
  1544. try
  1545. {
  1546. try
  1547. {
  1548. for (int ii = 0; ii < nFormCnt; ii++)
  1549. {
  1550. TVmsForm *pForm = AObj->pForms->GetItem(ii);
  1551. int nObjCnt;
  1552. pForm->pBitmap->Canvas->Lock();
  1553. pForm->pBitmap->PixelFormat = g_AppCfg.PixelFormat;//pf24bit;//pf32bit;//pf24bit;//pf4bit; //TODO
  1554. //TODO
  1555. SetStretchBltMode(pForm->pBitmap->Canvas->Handle, HALFTONE);
  1556. try
  1557. {
  1558. pForm->FormClear(CodeToFormColor(pForm->VMS_FORM_COLR_CD));
  1559. nObjCnt = pForm->Count();
  1560. TRect rc;
  1561. TRect DstRect;
  1562. TRect SrcRect;
  1563. for (int jj = 0; jj < nObjCnt; jj++)
  1564. {
  1565. TVmsFormObj *pFormObj = pForm->GetItem(jj);
  1566. switch(pFormObj->ObjectType)
  1567. {
  1568. case 1: //심볼
  1569. case 2: //이미지
  1570. case 3: //소통정보배경이미지
  1571. case 17: //소통정보이미지1
  1572. case 27: //소통정보이미지2
  1573. case 37: //소통정보이미지3
  1574. case 47: //소통정보이미지4
  1575. case 167: //@우회소통정보이미지
  1576. case 200: //동영상이미지
  1577. case 300: //스트리밍영상이미지
  1578. case 406: //@통합대기등급 이미지
  1579. case 407: //@미세먼지등급 이미지
  1580. case 408: //@초미세먼지등급 이미지
  1581. case 413: //@오존등급이미지
  1582. #if 0
  1583. if (pFormObj->ObjectType == 17 ||
  1584. pFormObj->ObjectType == 27 ||
  1585. pFormObj->ObjectType == 37 ||
  1586. pFormObj->ObjectType == 47 ||
  1587. pFormObj->ObjectType == 167
  1588. )
  1589. {
  1590. rc.Top = pFormObj->PosY;
  1591. rc.Bottom = pFormObj->PosY + pFormObj->pImageData->Picture->Graphic->Height;
  1592. rc.Left = pFormObj->PosX;
  1593. rc.Right = pFormObj->PosX + pFormObj->pImageData->Picture->Graphic->Width;
  1594. pForm->pBitmap->Canvas->StretchDraw(rc, pFormObj->pImageData->Picture->Graphic);
  1595. }
  1596. else
  1597. {
  1598. pForm->pBitmap->Canvas->Draw(pFormObj->PosX, pFormObj->PosY, pFormObj->pImageData->Picture->Graphic);
  1599. }
  1600. #else
  1601. #if 0
  1602. pForm->pBitmap->Canvas->CopyMode = cmSrcCopy;
  1603. DstRect = Rect(pFormObj->PosX, //left, top, right, bottom
  1604. pFormObj->PosY,
  1605. pFormObj->PosX + pFormObj->Width,
  1606. pFormObj->PosY + pFormObj->Height);
  1607. SrcRect = Rect(0, 0, pFormObj->pImageData->Picture->Graphic->Width, pFormObj->pImageData->Picture->Graphic->Height);
  1608. pForm->pBitmap->Canvas->CopyRect(DstRect, pFormObj->pImageData->Picture->Bitmap->Canvas, SrcRect);
  1609. #else
  1610. rc = Rect(pFormObj->PosX, //left, top, right, bottom
  1611. pFormObj->PosY,
  1612. pFormObj->PosX + pFormObj->Width,
  1613. pFormObj->PosY + pFormObj->Height);
  1614. //rc.Top = pFormObj->PosY;
  1615. //rc.Bottom = pFormObj->PosY + pFormObj->Height;
  1616. //rc.Left = pFormObj->PosX;
  1617. //rc.Right = pFormObj->PosX + pFormObj->Width;
  1618. pForm->pBitmap->Canvas->StretchDraw(rc, pFormObj->pImageData->Picture->Bitmap);//Graphic);
  1619. #endif
  1620. #endif
  1621. break;
  1622. default://기타 문자열
  1623. pForm->pBitmap->Canvas->Brush->Color = CodeToBackColor(pFormObj->BkColor);
  1624. #if 0
  1625. //이력저장할때 폰트색상을 코드로 넣기 때문에 색상값을 직접사용할 수 없다.
  1626. switch(pFormObj->ObjectType)
  1627. {
  1628. //case 401: //@관측장소 ==> 관측장소 폰트 색상은 운영자가 입력한 색상을 그대로 사용한다.
  1629. case 402: //@PM10
  1630. case 403: //@PM2.5
  1631. case 404: //@PM10등급
  1632. case 405: //@PM2.5등급
  1633. case 409: //@통합대기등급
  1634. case 410: //@통합대기
  1635. case 411: //@오존
  1636. case 412: //@오존등급
  1637. pForm->pBitmap->Canvas->Font->Color = (TColor)(pFormObj->TextFontColor);
  1638. break;
  1639. default:
  1640. pForm->pBitmap->Canvas->Font->Color = CodeToFontColor(pFormObj->TextFontColor);
  1641. break;
  1642. }
  1643. #else
  1644. pForm->pBitmap->Canvas->Font->Color = CodeToFontColor(pFormObj->TextFontColor);
  1645. #endif
  1646. pForm->pBitmap->Canvas->Font->Name = CodeToFontName(pFormObj->TextFontName);
  1647. pForm->pBitmap->Canvas->Font->Size = pFormObj->TextFontSize;
  1648. if (pFormObj->TextFontBold)
  1649. pForm->pBitmap->Canvas->Font->Style = TFontStyles() << fsBold;
  1650. else
  1651. pForm->pBitmap->Canvas->Font->Style = TFontStyles();
  1652. pForm->pBitmap->Canvas->TextOutA(pFormObj->PosX, pFormObj->PosY, pFormObj->TextData);
  1653. break;
  1654. }
  1655. } // 폼의 객체수 만큼 객체를 폼에 그린다.
  1656. try
  1657. {
  1658. pForm->pStream->Clear();
  1659. pForm->pStream->Position = 0;
  1660. //if (AObj->PROTOCOL_VER == 1) //TEXT VMS
  1661. pForm->pBitmap->PixelFormat = g_AppCfg.PixelFormat;//pf24bit;//pf24bit;//pf4bit; //TODO
  1662. //else
  1663. // pForm->pBitmap->PixelFormat = g_AppCfg.PixelFormat;//pf16bit;//pf24bit;//pf4bit; //TODO
  1664. pForm->pBitmap->SaveToStream(pForm->pStream);
  1665. //SaveToStreamJpg(pForm->pBitmap, pForm->pStream);
  1666. //FTP다운로드 하는 경우 폼을 FTP디렉토리에 저장해야함
  1667. #if 0
  1668. if (pForm->VMS_SCH_FORM_TYPE != eSchTp_hongbo && //홍보(제어기별 폼생성시 CDSForm의 파일명으로 설정되어 있음
  1669. pForm->VMS_SCH_FORM_TYPE != eSchTp_video && //비디오
  1670. pForm->VMS_SCH_FORM_TYPE != eSchTp_stream ) //스트리밍영상 등은 로컬파일로 저장할 필요가 없음
  1671. #else
  1672. //TODO: 20241218
  1673. // if (pForm->VMS_SCH_FORM_TYPE != eSchTp_video && //비디오
  1674. // pForm->VMS_SCH_FORM_TYPE != eSchTp_stream ) //스트리밍영상 등은 로컬파일로 저장할 필요가 없음
  1675. #endif
  1676. { //파일이름을 여기서 변경하면 ftp 파일명이 변경된다.
  1677. if (AObj->FIsFtpDownload)
  1678. {
  1679. AnsiString sFormName;
  1680. if (g_AppCfg.IsImageSeqSave)
  1681. {
  1682. //시퀀스_운영모드-순서_폼유형-폼번호.bmp
  1683. sFormName.printf("%d_%c%02d_%X%s.bmp", g_ToggleFormSeq, AObj->CTRLMODE->Control, ii+1, (BYTE)pForm->VMS_SCH_FORM_TYPE, pForm->VMS_FORM_ID.c_str());
  1684. }
  1685. else
  1686. {
  1687. //운영모드-순서_폼유형-폼번호.bmp
  1688. sFormName.printf("%c%02d_%X%s.bmp", AObj->CTRLMODE->Control, ii+1, (BYTE)pForm->VMS_SCH_FORM_TYPE, pForm->VMS_FORM_ID.c_str());
  1689. }
  1690. //sFormName.printf("%s_%d%02d.bmp", AObj->CTLR_NMBR.c_str(), g_ToggleFormSeq, ii+1);
  1691. pForm->LocalFileName = AObj->FLocalFormDir + sFormName;
  1692. pForm->FtpFileName = AObj->FFtpFormDir + sFormName;
  1693. //pForm->pStream->SaveToFile(pForm->LocalFileName+".jpg");
  1694. if (FileExists(pForm->LocalFileName))
  1695. {
  1696. try {
  1697. DeleteFile(pForm->LocalFileName);
  1698. } catch(Exception &e)
  1699. {
  1700. MERROR("MAIN=============> MakeVmsDatabaseForm DeleteFile Failed: %s, %d, %s, %s", AObj->CTLR_NMBR.c_str(), ii, AnsiString(e.ClassName()).c_str(), AnsiString(e.Message).c_str());
  1701. }
  1702. }
  1703. try
  1704. {
  1705. pForm->pBitmap->SaveToFile(pForm->LocalFileName);
  1706. }
  1707. catch(Exception &e)
  1708. {
  1709. pForm->Success = false;
  1710. MERROR("MAIN=============> MakeVmsDatabaseForm SaveFile Failed: %s, %d, %s, %s", AObj->CTLR_NMBR.c_str(), ii, AnsiString(e.ClassName()).c_str(), AnsiString(e.Message).c_str());
  1711. }
  1712. }
  1713. }
  1714. pForm->Success = true;
  1715. switch (pForm->VMS_SCH_FORM_TYPE)
  1716. {
  1717. case eSchTp_traffic: // = 0, //0:교통,
  1718. case eSchTp_incident: // = 1, //1:돌발,
  1719. case eSchTp_gongsa: // = 2, //2:공사행사,
  1720. case eSchTp_deture: // = 4, //4:우회,
  1721. case eSchTp_congest: // = 5, //5:정체,
  1722. pForm->fileType = P_FILE_TYPE_TRAFFIC;
  1723. break;
  1724. case eSchTp_hongbo: // = 3, //3:홍보,
  1725. case eSchTp_safe: // = 6, //6:안전,
  1726. case eSchTp_atmp: // = 9, //9:대기환경
  1727. case eSchTp_park: // = 10, //10:주차정보
  1728. pForm->fileType = P_FILE_TYPE_TEXT;
  1729. break;
  1730. case eSchTp_video: // = 7, //7:동영상,
  1731. pForm->fileType = P_FILE_TYPE_VIDEO;
  1732. //TODO: 20241218
  1733. // pForm->FtpFileName = AnsiString(FTP_VIDEO) + "\\" + pForm->STRM_ADDR;
  1734. //폼디렉토리에 동영상파일을 복사해서 처리하도록 수정해야지..........
  1735. break;
  1736. case eSchTp_stream: // = 8, //8:스트리밍영상
  1737. pForm->fileType = P_FILE_TYPE_STREAM;
  1738. pForm->FtpFileName = pForm->STRM_ADDR;
  1739. break;
  1740. default:
  1741. pForm->Success = false;
  1742. break;
  1743. }
  1744. MINFO("MAIN=============> CTLR FORM: %s, %d, [%d] [0x%02X], %s", AObj->CTLR_NMBR.c_str(), ii, pForm->VMS_SCH_FORM_TYPE, pForm->fileType, pForm->FtpFileName.c_str());
  1745. nSelCnt++;
  1746. }
  1747. catch(Exception &e)
  1748. {
  1749. MERROR("MAIN=============> MakeVmsDatabaseForm error1: %s, %s", AnsiString(e.ClassName()).c_str(), AnsiString(e.Message).c_str());
  1750. pForm->LocalFileName = "";
  1751. pForm->FtpFileName = "";
  1752. }
  1753. }
  1754. __finally
  1755. {
  1756. pForm->pBitmap->Canvas->Unlock();
  1757. }
  1758. }
  1759. }
  1760. catch(Exception &e)
  1761. {
  1762. MERROR("MAIN=============> MakeVmsDatabaseForm error2: %s, %s", AnsiString(e.ClassName()).c_str(), AnsiString(e.Message).c_str());
  1763. }
  1764. }
  1765. __finally
  1766. {
  1767. AObj->pForms->UnLock();
  1768. }
  1769. return nSelCnt;
  1770. }
  1771. //---------------------------------------------------------------------------