//---------------------------------------------------------------------------

#include <vcl.h>
#include "ITSSkinF.h"
#include "ITSUtilF.h"
#include "AppGlobalF.h"
#pragma hdrstop

#include "FrmInitializeF.h"  // 프로그램 초기화화면
#include "FrmVmsFormEditF.h"
#include "VMSM510MF.h"
#include "VMSM520MF.h"
#include "VMSM530MF.h"
#include "VMSM540MF.h"
#include "VMSM550MF.h"

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "cxButtons"
#pragma link "cxCalendar"
#pragma link "cxContainer"
#pragma link "cxControls"
#pragma link "cxDropDownEdit"
#pragma link "cxEdit"
#pragma link "cxGraphics"
#pragma link "cxGroupBox"
#pragma link "cxLabel"
#pragma link "cxLookAndFeelPainters"
#pragma link "cxLookAndFeels"
#pragma link "cxMaskEdit"
#pragma link "cxPC"
#pragma link "cxPCdxBarPopupMenu"
#pragma link "cxSpinEdit"
#pragma link "cxSplitter"
#pragma link "cxTextEdit"
#pragma link "cxTimeEdit"
#pragma link "dxSkinBlack"
#pragma link "dxSkinBlue"
#pragma link "dxSkinCaramel"
#pragma link "dxSkinCoffee"
#pragma link "dxSkinDarkRoom"
#pragma link "dxSkinDarkSide"
#pragma link "dxSkinFoggy"
#pragma link "dxSkinGlassOceans"
#pragma link "dxSkiniMaginary"
#pragma link "dxSkinLilian"
#pragma link "dxSkinLiquidSky"
#pragma link "dxSkinLondonLiquidSky"
#pragma link "dxSkinMcSkin"
#pragma link "dxSkinMoneyTwins"
#pragma link "dxSkinOffice2007Black"
#pragma link "dxSkinOffice2007Blue"
#pragma link "dxSkinOffice2007Green"
#pragma link "dxSkinOffice2007Pink"
#pragma link "dxSkinOffice2007Silver"
#pragma link "dxSkinOffice2010Black"
#pragma link "dxSkinOffice2010Blue"
#pragma link "dxSkinOffice2010Silver"
#pragma link "dxSkinsCore"
#pragma link "dxSkinscxPCPainter"
#pragma link "dxSkinSeven"
#pragma link "dxSkinSharp"
#pragma link "dxSkinSilver"
#pragma link "dxSkinStardust"
#pragma link "cxRadioGroup"
#pragma link "cxClasses"
#pragma link "cxCustomData"
#pragma link "cxData"
#pragma link "cxDataStorage"
#pragma link "cxDBData"
#pragma link "cxFilter"
#pragma link "cxGrid"
#pragma link "cxGridCustomTableView"
#pragma link "cxGridCustomView"
#pragma link "cxGridDBTableView"
#pragma link "cxGridLevel"
#pragma link "cxGridTableView"
#pragma link "cxStyles"
#pragma link "cxCheckBox"
#pragma link "cxImage"
#pragma link "cxButtonEdit"
#pragma link "cxBlobEdit"
#pragma link "VmsDesignerF"
#pragma link "cxColorComboBox"
#pragma link "cxCalc"
#pragma link "VmsDispF"
#pragma link "dxSkinsForm"
#pragma link "IdBaseComponent"
#pragma link "IdCoder"
#pragma link "IdCoder00E"
#pragma link "IdCoder3to4"
#pragma link "IdCoderMIME"
#pragma link "IdCoderUUE"
#pragma resource "*.dfm"

//---------------------------------------------------------------------------
#ifndef ULONG_PTR
#define ULONG_PTR unsigned long *
#endif

#include <stdio.h>
#include <string.h>
#include <list>
#include <map>

#define STRICT
#include <windows.h>
#include <algorithm>
using std::min;
using std::max;
#include "gdiplus.h"
#include "GdiplusBase.h" //항상 넣어 둔다.

class CGdiPlusStarter
{
private:
	ULONG_PTR m_gpToken;

public:
	bool m_bSuccess;
	CGdiPlusStarter()
    {
        ::CoInitialize(NULL);
		Gdiplus::GdiplusStartupInput gpsi;
		m_bSuccess = (Gdiplus::GdiplusStartup(&m_gpToken, &gpsi, NULL) == Gdiplus::Ok);
	}
	~CGdiPlusStarter()
    {
		Gdiplus::GdiplusShutdown(m_gpToken);
        ::CoUninitialize();
	}
};
CGdiPlusStarter g_gps;
//---------------------------------------------------------------------------
bool APP_CheckBmpFile(String AInFileName, String &AOutFileName);
#include <jpeg.hpp>
bool APP_CheckBmpFile(String AInFileName, String &AOutFileName)
{
    String sFilePath = ExtractFilePath(AInFileName);
    String sFileName = ExtractFileName(AInFileName);
    String sFileExt  = ExtractFileExt(AInFileName);

    AOutFileName = AInFileName;
    if (sFileExt.UpperCase() == ".BMP")
    {
        return true;
    }

    AOutFileName = AInFileName + ".bmp";

    TImage *Image1 = new TImage(NULL);
    TMemoryStream *pImgStream = new TMemoryStream();
    try
    {
        try
        {
            pImgStream->LoadFromFile(AInFileName);
            sFileExt = sFileExt.UpperCase();
            if (sFileExt == ".PNG")
            {
                TdxPNGImage *img = new TdxPNGImage;
                img->LoadFromStream(pImgStream);
                Image1->Picture->Bitmap->Assign(img);
                Image1->Picture->Bitmap->PixelFormat = pf24bit;
                Image1->Picture->Bitmap->SaveToFile(AOutFileName);
                SAFE_DELETE(img);
                return true;
            }
            else
            if (sFileExt == ".JPG" || sFileExt == ".JPEG")
            {
                TJPEGImage *img = new TJPEGImage();
                img->LoadFromStream(pImgStream);
                Image1->Picture->Bitmap->Assign(img);
                Image1->Picture->Bitmap->PixelFormat = pf24bit;
                Image1->Picture->Bitmap->SaveToFile(AOutFileName);
                SAFE_DELETE(img);
                return true;
            }
        }
        catch(Exception &e)
        {
        }
    }
    __finally
    {
        SAFE_DELETE(pImgStream);
        SAFE_DELETE(Image1);
    }

    return false;
}
//---------------------------------------------------------------------------

TFrmVmsFormEdit *FrmVmsFormEdit = NULL;
//---------------------------------------------------------------------------

__fastcall TFrmVmsFormEdit::TFrmVmsFormEdit(TComponent* Owner)
    : TForm(Owner)
{
    ::CoInitialize(NULL);

    Caption = g_AppCfg.sTitle + " - Active";

    ITSSkin_Initialize(Application);

    CMM_SetFormPosition(g_AppCfg.bSaveForm);
    //CMM_LoadForm(g_sFormsDir, this);

    FUpdate= false;

    String sCaption = "0";
    ReadConfigInfo(g_AppCfg.sConfigFile, "APPLICATION", "CAPTION", sCaption);
    ITSSkin_Caption(sCaption == "1" ? true : false);

    ITSSkin_Load(this);
    FTitle = Caption;//"VMS 폼관리";

	FListSymb = new TList;

    EditMode = false;

    PgEdit->ActivePage = TsEdit;
    PgFormTab->ActivePage = TsForm;

    //BtnSaveImgFile->Caption = "Save form image";
    //BtnSaveImgFile->Hint = "Save the form as an image file.";

    FSelObjType = eSelObjNone;
    //MyUseManager = new TVmsObjUseManager();

    //TvList->FilterRow->ApplyChanges = fracDelayed;//fracImmediately;
    TvList->OptionsBehavior->ShowLockedStateImageOptions->Filtering = lsimNever;
    BtnLime->LookAndFeel->NativeStyle = false;
    BtnLime->LookAndFeel->SkinName    = "";
    BtnYellow->LookAndFeel->NativeStyle = false;
    BtnYellow->LookAndFeel->SkinName    = "";
    BtnRed->LookAndFeel->NativeStyle = false;
    BtnRed->LookAndFeel->SkinName    = "";

    SetColorScheme(g_AppCfg.sSkinName);

    APP_InitDisplayColor();
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::SetColorScheme(String ASkinName)
{
    dxSkinController1->SkinName = ASkinName;
    dxSkinController1->Refresh();
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::CommClose()
{
    try
    {
        //if (MyUseManager)
        //{
        //    delete MyUseManager;
        //    MyUseManager = NULL;
        //}

        if (m_pEdtDesigner)
        {
            delete m_pEdtDesigner;
            m_pEdtDesigner = NULL;
        }

        //SAFE_DELETE(MyVmsObjTypeManager);

        ClearSymbloList();
        SAFE_DELETE(FListSymb);

        //CMM_SaveForm(g_sFormsDir, this);
    }
    catch(...)
    {
    }
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::FormCreate(TObject *Sender)
{
    Application->ShowMainForm = false;

    try {
        Application->Icon->LoadFromResourceName(((unsigned int)HInstance), "MAINICON");
    } catch(...) { ShowMessage("LoadFromResourceName failed"); }

    Application->ShowMainForm = true;

    m_pEdtDesigner = new TVmsFormDesigner(PnlEditForm);
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::FormShow(TObject *Sender)
{
    ::SendMessage(ReForm->Handle, EM_SETLANGOPTIONS, 0, (LPARAM)(::SendMessage(ReForm->Handle, EM_GETLANGOPTIONS, 0, 0) & ~IMF_AUTOFONT));
    ::SendMessage(ReFormTemp->Handle, EM_SETLANGOPTIONS, 0, (LPARAM)(::SendMessage(ReFormTemp->Handle, EM_GETLANGOPTIONS, 0, 0) & ~IMF_AUTOFONT));

    Refresh();
    ChangeEditMode(1);
    TmrShow->Enabled = true;
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::FormInit()
{
    TvList->OptionsView->NoDataToDisplayInfoText = "<등록되어 있는 폼 정보가 없습니다>";

    // TODO
    //CheckVideoStreamImage();

    //MyVmsObjTypeManager->LoadFromDb();

    m_pEdtDesigner->ApplicationHandle = (long)Handle;

    FOR_STL(TVmsFontColr*, pObj, VmsFontColrManager->FLists)
    {
        m_pEdtDesigner->InitFontColor(pObj->CODE, (TColor)pObj->COLR_VAL);
    }

    //VMS사이즈
    FillVmsSizeType(CbSizeType);

    //폼색상
	CbFormColor->Items->Clear();
	CbFormColor->Items->AddObject("", (TObject*)clBlack);
	CbFormColor->Items->AddObject("", (TObject*)clRed);
	CbFormColor->Items->AddObject("", (TObject*)clLime);
	CbFormColor->Items->AddObject("", (TObject*)clYellow);
    CbFormColor->ItemIndex = 0;

	CbFormColor1->Items->Clear();
	CbFormColor1->Items = CbFormColor->Items;
    CbFormColor1->ItemIndex = 0;

    //폼유형
    FillVmsFormType(CbFormKind);
    //표출방법
    FillVmsFormDispMthd(CbFormDsplMthd);
    //표출방향
    FillVmsFormDispDrct(CbFormDsplDrct);

    FormObjectInit();

    ReForm->Paragraph->Numbering = nsNone;
    ReForm->Paragraph->Alignment = (TAlignment)2;

    FNewDb = false;
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::FormObjectInit()
{
    TvObjList->OptionsView->NoDataToDisplayInfoText = "<등록되어 있는 객체 정보가 없습니다>";

    m_bEdit = false;

    PnlEdtBack->Left = 6;
    PnlEdtBack->Top  = 4;

    PnlRePreview->Left = 4;
    PnlRePreview->Top  = 4;

    //ReForm->Left = 6;
    //ReForm->Top  = 4;

    //객체배경색상
	CbBkColor->Items->Clear();
	CbBkColor->Items->AddObject("", (TObject*)clBlack);
	CbBkColor->Items->AddObject("", (TObject*)clRed);
	CbBkColor->Items->AddObject("", (TObject*)clLime);
	CbBkColor->Items->AddObject("", (TObject*)clYellow);
    CbBkColor->ItemIndex = 0;
    //문자열색상
	CbFontColor->Items->Clear();
#if 0
	CbFontColor->Items->AddObject("", (TObject*)clBlack);
	CbFontColor->Items->AddObject("", (TObject*)clRed);
	CbFontColor->Items->AddObject("", (TObject*)clLime);
	CbFontColor->Items->AddObject("", (TObject*)clYellow);
#endif

    FOR_STL(TVmsFontColr*, pObj, VmsFontColrManager->FLists)
    {
    	CbFontColor->Items->AddObject("", (TObject*)pObj->COLR_VAL);
    }
    CbFontColor->ItemIndex = 0;

    //직접입력 문자열색상
	CbFontColorRe->Items->Clear();
#if 0
	CbFontColorRe->Items->AddObject("", (TObject*)clBlack);
	CbFontColorRe->Items->AddObject("", (TObject*)clRed);
	CbFontColorRe->Items->AddObject("", (TObject*)clLime);
	CbFontColorRe->Items->AddObject("", (TObject*)clYellow);
#endif
	CbFontColorRe->Items = CbFontColor->Items;
    CbFontColorRe->ItemIndex = 0;

    //VMS Font
    FillVmsFont(CbFontName);
    CbFontName->ItemIndex = 0;
    FillVmsFont(CbFontNameRe);
    CbFontNameRe->ItemIndex = 0;
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::TmrShowTimer(TObject *Sender)
{
    TmrShow->Enabled = false;

    TFrmInitialize *FrmInitialize = new TFrmInitialize(this);
    FrmInitialize->FThreadId = g_AppCfg.thr.dwThreadId;
    FrmInitialize->ShowModal();

    FormInit();
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::BtnCloseClick(TObject *Sender)
{
    Close();
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::FormClose(TObject *Sender, TCloseAction &Action)
{
    CommClose();
    FrmVmsFormEdit = NULL;
    Action = caFree;
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::FormCloseQuery(TObject *Sender, bool &CanClose)
{
    if (FUpdate)
    {
        //CComm_VmsFormUpdate();
        //POST_MSG(Application->MainForm->Handle, WM_DATABASE_REFRESH, WP_MSG_14, 0);
    }
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::BtnEditClick(TObject *Sender)
{
    bool singleForm = false;
    int nFormTypeCd = m_sFormTypeCd.ToIntDef(11);
    if (nFormTypeCd == 70 || nFormTypeCd == 80)
    {
        singleForm = true;  //동영상, 스트리밍 영상 폼
    }
    if (BtnEdit->Caption == "편집")
    {
        ChangeEditMode(0);
        FNewDb = false;
        if (singleForm)
        {
            if (PnlCmd2->Enabled == true)
            {
                //PnlCmd2->Enabled = false;
            }
        }
        else
        {
            if (PnlCmd2->Enabled == false)
            {
                PnlCmd2->Enabled = true;
            }
        }
        if (PgFormTab->ActivePage != TsFormObject)
        {
            PgFormTab->ActivePage = TsFormObject;
        }
    }
    else
    {
        String sId = EdFormId->Text;
        ChangeEditMode(1);

        if (CMM_FindGridData(TvList->DataController, sId, Col01->Index) >= 0)
        {
            CMM_SetGridRow(CxList, TvList, sId, Col01->Index);
            DisplayInfo();
        }
    }
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::ChangeEditMode(int AEdit)
{
    bool bEnabled = false;
    CbFormKind->Enabled = false;
    switch(AEdit)
    {
    case 0: //편집버튼클릭
        {
            BtnEdit->Enabled = true;
            BtnInsert->Enabled = false;
            BtnDelete->Enabled = false;
            BtnCopyAdd->Enabled = false;
            BtnSave->Enabled = true;

            BtnEdit->Caption = "취소";
            BtnEdit->Hint    = "데이터 편집 취소";
            EditMode = true;
        }
        break;
    case 1: //편집[취소]버튼클릭
        {
            FormClear(); //화면을 모두 지운다.
            BtnEdit->Enabled = false;
            BtnInsert->Enabled = true;
            BtnDelete->Enabled = false;
            BtnCopyAdd->Enabled = false;
            BtnSave->Enabled = false;

            BtnEdit->Caption = "편집";
            BtnEdit->Hint    = "데이터 편집";
            //bEnabled = true;
            EditMode = false;
        }
        break;
    case 2: //추가
        {
            BtnEdit->Enabled = true;
            BtnInsert->Enabled = false;
            BtnDelete->Enabled = false;
            BtnCopyAdd->Enabled = false;
            BtnSave->Enabled = true;

            BtnEdit->Caption = "취소";
            BtnEdit->Hint    = "데이터 편집 취소";
            EditMode = true;
            //CbFormKind->Enabled = true;
        }
        break;
    case 3: //수정모드
        {
            BtnEdit->Enabled = true;
            BtnInsert->Enabled = true;
            BtnDelete->Enabled = true;
            BtnCopyAdd->Enabled = true;
            BtnSave->Enabled = false;

            BtnEdit->Caption = "편집";
            BtnEdit->Hint    = "데이터 편집";
            bEnabled = true;
            EditMode = false;
        }
        break;
    }

    BtnSaveImgFile->Enabled = false;
    if (ImgForm->Picture->Bitmap != NULL)
    {
        if (ImgForm->Picture->Bitmap->Height != 0)
        {
            BtnSaveImgFile->Enabled = true;
        }
    }

    if (AEdit == 0 || AEdit == 2)
    {
        PnlCmd1->Enabled = true;
        PnlCmd2->Enabled = true;
        GrpList->Enabled = false;
    }
    else
    {
        PnlCmd1->Enabled = false;
        PnlCmd2->Enabled = false;
        GrpList->Enabled = true;
    }

    ChangeEditModeObject(AEdit);
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::ChangeEditModeObject(int AEdit)
{
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::BtnInsertClick(TObject *Sender)
{
    int nFormId;

    if (!GetNextVmsFormId(nFormId))
    {
        Application->MessageBox(L"새로운 VMS 폼정보를 생성하지 못하였습니다.\r\n프로그램 종료후에 다시 시도해 보세요.",
                                FTitle.c_str(), MB_OK|MB_ICONERROR|MB_APPLMODAL);
        return;
    }

    TVMSM520M *pSelForm = new TVMSM520M(this);
    pSelForm->ShowModal();
    String sFormType = pSelForm->EdNmbr->Text.Trim();
    bool   bSelected = pSelForm->m_bSelected;
    delete pSelForm;
    pSelForm = NULL;

    if (!bSelected)
    {
        return;
    }

    if (sFormType == "")
    {
        return;
    }

    FormClear();

    EdFormId->Text = String(nFormId);

    ChangeEditMode(2);
    FNewDb = true;

    //폼유형을 설정
    APP_SetCode(CbFormKind, sFormType);
    CbFormDsplMthd->ItemIndex = 0;
    CbFormDsplDrct->ItemIndex = 0;

    bool singleForm = false;
    //폼유형에 맞게 기본 폼을 생성하자
    switch(sFormType.ToIntDef(11))
    {
    case 11:// '	소통상황(1단)
        MakeDefTrafficForm(1);
        break;
    case 12:// '	소통상황(2단)
        MakeDefTrafficForm(2);
        break;
    case 13:// '	소통상황(3단)
        MakeDefTrafficForm(3);
        break;
    case 14:// '	소통상황(4단)
        MakeDefTrafficForm(4);
        break;
    case 15:// '	소통상황(도형식)
        break;
    case 16:// '	정체소통상황
        //MakeDefTrafficForm(6);
        break;
    case 20:// '	돌발문안
        break;
    case 30:// '	공사/행사문안
        break;
    case 40:// '	홍보문안
        break;
    case 50:// '	우회도로
        break;
    case 60:// '	우회도로
        break;
    case 70:// '	동영상
        MakeDefVideoStreamForm(70);
        singleForm = true;
        break;
    case 80:// '	스트리밍영상
        MakeDefVideoStreamForm(80);
        singleForm = true;
        break;
    case 90:// '	대기환경(좋음)
        //MakeDefVideoStreamForm(90);
        break;
    case 91:// '	주차정보
        break;
    default:
        //APP_SetCode(CbFormKind, "11");
        MakeDefTrafficForm(1);
        break;
    }
    if (singleForm)
    {
        if (PnlCmd2->Enabled == true)
        {
            //PnlCmd2->Enabled = false;
        }
    }
    else
    {
        if (PnlCmd2->Enabled == false)
        {
            PnlCmd2->Enabled = true;
        }
    }

    if (PgFormTab->ActivePage != TsFormObject)
    {
        PgFormTab->ActivePage = TsFormObject;
    }
    EdFormName->SetFocus();
}
//---------------------------------------------------------------------------

bool __fastcall TFrmVmsFormEdit::AddDefFormObject(String AFontName, int AFontSize, String AFontColor,
                                            int AObjType, String AText, int ASize, int APosX, int APosY, int AAlign/*=0*/)
{
    TVmsFormObject *pObj;

    //1단 소통정보
    pObj = m_pEdtDesigner->AddObject(odtText);
    if (!pObj) return false;

    pObj->EditMode      = true;
    pObj->ObjKind       = OBJKIND_TEXT;
    pObj->ObjSeq        = m_pEdtDesigner->GetNewObjectSeq();
    pObj->ObjType       = String(AObjType);
    pObj->Text          = AText;
    pObj->ObjSize       = pObj->Text.Length();//ASize;  //Pixel
    pObj->BkColorCode   = "0";  //Balck, m_pEdtDesigner->BkColorCode;
    pObj->Blink         = false;

    pObj->FontName      = AFontName;
    pObj->FontNameCode  = APP_GetCodeIdByName(CbFontName, AFontName);
    pObj->FontColorCode = AFontColor;  //0:Black,1:Red,2:Green,3:Yellow
    pObj->FontSize      = AFontSize;
    pObj->FontBold      = true;
    pObj->TextAlign     = AAlign;    //(0:left, 1:right, 2:center

    pObj->SetPos(APosX, APosY);
    pObj->Show();
    AddObjectToList(pObj, true);
    return true;
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::MakeDefTrafficForm(int ARows)
{
    //0:Black,1:Red,   2:Green,  3:Yellow
    //0:left, 1:right, 2:center

    //1단 소통정보
    if (g_AppCfg.sLang == "kr")
    {
        switch(ARows)
        {
        case 1:
            AddDefFormObject("굴림체", 18, "3", 12, "@시점명",   160,  16,  7, 1);    //시점명
            AddDefFormObject("굴림체", 18, "3", 13, "@종점명",   160, 213,  7, 0);    //종점명
            AddDefFormObject("굴림체", 18, "3", 14, "@소통상황", 112,  64, 35, 2);    //소통상황
            AddDefFormObject("굴림체", 18, "2", 15, "@00분",      80, 213, 35, 0);    //통행시간
            break;
        case 2:
            AddDefFormObject("굴림체", 16, "3",  0, "현위치",    100,  31,  7);    //현위치

            AddDefFormObject("굴림체", 16, "3", 13, "@종점명1",  100, 133,  7);    //종점명1
            AddDefFormObject("굴림체", 16, "3", 23, "@종점명2",  100, 265,  7);    //종점명2
            AddDefFormObject("굴림체", 16, "2", 15, "@01분",      80, 133, 35);    //통행시간1
            AddDefFormObject("굴림체", 16, "2", 25, "@02분",      80, 265, 35);    //통행시간2
            break;
        case 3:
            AddDefFormObject("굴림체", 16, "3",  0, "현재위치부터", 126,   7,  7);    //현재위치부터

            AddDefFormObject("굴림체", 16, "3", 13, "@종점명1",      85,  38,  50);    //종점명1
            AddDefFormObject("굴림체", 16, "2", 15, "@1분",          80, 161,  50);    //통행시간1
            AddDefFormObject("굴림체", 16, "3", 14, "@상황1",        53, 217,  50);    //소통상황1

            AddDefFormObject("굴림체", 16, "3", 23, "@종점명2",      85,  38,  82);    //종점명2
            AddDefFormObject("굴림체", 16, "2", 25, "@2분",          80, 161,  82);    //통행시간2
            AddDefFormObject("굴림체", 16, "3", 24, "@상황2",        53, 217,  82);    //소통상황2

            AddDefFormObject("굴림체", 16, "3", 33, "@종점명3",      85,  38, 117);    //종점명3
            AddDefFormObject("굴림체", 16, "2", 35, "@3분",          80, 161, 117);    //통행시간3
            AddDefFormObject("굴림체", 16, "3", 34, "@상황3",        53, 217, 117);    //소통상황3
            break;
        case 6:
            AddDefFormObject("굴림체", 18, "3", 18, "@지점명",   300,  18,  20);    //지점명
            AddDefFormObject("굴림체", 18, "3",  0, "주변",      126,  153, 20);    //주변
            AddDefFormObject("굴림체", 18, "1",  0, "정체 극심", 126,  222, 20);    //정체극심
            break;
        }
    }
    else
    {
        String sFontName = lblFontName->Caption;
        switch(ARows)
        {
        case 1:
            AddDefFormObject(sFontName, 18, "3", 12, "@StartName",   160,  16,  7);     //@시점명       @StartName
            AddDefFormObject(sFontName, 18, "3", 13, "@EndName",   160, 213,  7);       //@종점명       @EndName
            AddDefFormObject(sFontName, 18, "3", 14, "@Congest", 112,  64, 35);         //@소통상황     @Congest
            AddDefFormObject(sFontName, 18, "2", 15, "@00Min",      80, 213, 35);       //@통행시간     @00Min
            break;
        case 2:
            AddDefFormObject(sFontName, 16, "3",  0, "Location",    100,  31,  7);      //현위치        Location

            AddDefFormObject(sFontName, 16, "3", 13, "@EndName1",  100, 133,  7);       //종점명1    EndName1
            AddDefFormObject(sFontName, 16, "3", 23, "@EndName2",  100, 265,  7);       //종점명2    EndName2
            AddDefFormObject(sFontName, 16, "2", 15, "@01Min",      80, 133, 35);       //통행시간1  01Min
            AddDefFormObject(sFontName, 16, "2", 25, "@02Min",      80, 265, 35);       //통행시간2  02Min
            break;
        case 3:
            AddDefFormObject(sFontName, 16, "3",  0, "From Location", 126,   7,  7);    //현재위치부터  From Location

            AddDefFormObject(sFontName, 16, "3", 13, "@EndName1",      85,  38,  50);   //종점명1     EndName1
            AddDefFormObject(sFontName, 16, "2", 15, "@1Min",          80, 161,  50);   //통행시간1   1Min
            AddDefFormObject(sFontName, 16, "3", 14, "@Congest1",        53, 217,  50); //소통상황1   Congest1

            AddDefFormObject(sFontName, 16, "3", 23, "@EndName2",      85,  38,  82);   //종점명2     EndName2
            AddDefFormObject(sFontName, 16, "2", 25, "@2Min",          80, 161,  82);   //통행시간2   2Min
            AddDefFormObject(sFontName, 16, "3", 24, "@Congest2",        53, 217,  82); //소통상황2   Congest2

            AddDefFormObject(sFontName, 16, "3", 33, "@EndName3",      85,  38, 117);   //종점명3     EndName3
            AddDefFormObject(sFontName, 16, "2", 35, "@3Min",          80, 161, 117);   //통행시간3  3Min
            AddDefFormObject(sFontName, 16, "3", 34, "@Congest3",        53, 217, 117); //소통상황3  Congest3
            break;
        case 6:
            AddDefFormObject(sFontName, 18, "3", 18, "@SpotName",   300,  18,  20);     //@지점명       @SpotName
            AddDefFormObject(sFontName, 18, "3",  0, "Around",      126,  153, 20);     //주변          Around
            AddDefFormObject(sFontName, 18, "1",  0, "Congest Zam", 126,  222, 20);     //정체극심      Congest Zam
            break;
        }
    }

#if 0
(String AFontName, int AFontSize, String AFontColor,
int AObjType, String AText, int ASize, int APosX, int APosY)
#endif
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::BtnDeleteClick(TObject *Sender)
{
    int nIdx = TvList->DataController->FocusedRecordIndex;
    if (nIdx < 0) return;

    String sFormId = EdFormId->Text;

    if (sFormId.IsEmpty())
    {
        Application->MessageBox(lblText2->Caption.c_str(),//L"VMS 폼 삭제\r\n삭제할 VMS 폼을 목록에서 선택하세요.",
                                FTitle.c_str(), MB_OK|MB_ICONERROR|MB_APPLMODAL);
        return;
    }

    if (!CheckVmsFormUse(sFormId)) return;

    String sMsg;
    sMsg = lblText3->Caption + ": " + sFormId;//"VMS 폼 ID: " + sFormId;
    sMsg+= "\r\n" + lblText4->Caption;//"선택하신 VMS 폼 정보를 삭제하시겠습니까?";

    if (Application->MessageBox(sMsg.c_str(), FTitle.c_str(), MB_YESNO|MB_ICONQUESTION|MB_APPLMODAL) != IDYES) return;

    if (DelVmsForm(sFormId))
    {
        FUpdate = true;

        Application->MessageBox(lblText5->Caption.c_str(),//L"VMS 폼 삭제\r\nVMS 폼정보를 삭제 하였습니다.",
                                FTitle.c_str(), MB_OK|MB_ICONINFORMATION|MB_APPLMODAL);

        FormClear();
        ChangeEditMode(1);

        LoadVmsForm();

        POST_MSG(Application->MainForm->Handle, WM_DATABASE_REFRESH, WP_MSG_14, 0);
	}
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::BtnSaveImgFileClick(TObject *Sender)
{
    if (EdFormId->Text == "") return;

    SaveDialog->Title      = FTitle;
    SaveDialog->InitialDir = ExtractFilePath(Application->ExeName);
    SaveDialog->Filter     = "Bitmap image Files (*.bmp)|*.bmp";
    SaveDialog->FileName   = EdFormId->Text + ".bmp";

    if (SaveDialog->Execute())
    {
        try {
            String sFileName = SaveDialog->FileName;

            int iRet = sFileName.Pos(".bmp");
            if (iRet == 0)
            {
                sFileName = SaveDialog->FileName + ".bmp";
            }

            ImgForm->Picture->SaveToFile(sFileName);
        }
        catch (Exception &exception)
        {
            Application->ShowException(&exception);
        }
    }
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::ClearSymbloList()
{
	for(int ii = 0; ii < FListSymb->Count; ii++)
	{
		Graphics::TBitmap *bitmap = (Graphics::TBitmap *)FListSymb->Items[ii];
		delete bitmap;
	}
	FListSymb->Clear();
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::TvListCellDblClick(TcxCustomGridTableView *Sender, TcxGridTableDataCellViewInfo *ACellViewInfo,
          TMouseButton AButton, TShiftState AShift,
          bool &AHandled)
{
	if (!ACellViewInfo) return;

    DisplayInfo();
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::TvListFocusedRecordChanged(TcxCustomGridTableView *Sender,
          TcxCustomGridRecord *APrevFocusedRecord, TcxCustomGridRecord *AFocusedRecord,
          bool ANewItemRecordFocusingChanged)
{
    if (!AFocusedRecord) return;
    DisplayInfo();
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::CbSizeTypePropertiesChange(TObject *Sender)
{
    EdSizeType->Text = CbSizeType->Text;
    BtnSearchClick(NULL);
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::BtnSearchClick(TObject *Sender)
{
    RefreshData();

    EdFocus->SetFocus();
    ChangeEditMode(1);
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::RefreshData()
{
    // 검색조건에 의한 링크 데이터 조회
    TvList->DataController->Filter->Clear();
    FormClear();
    LoadVmsForm();
}
//---------------------------------------------------------------------------
void __fastcall TFrmVmsFormEdit::FormClear()
{
    FSelObjType = eSelObjNone;

    FSelIdx = -1;

    ImgForm->Picture->Bitmap->FreeImage();
    ImgForm->Picture->Bitmap = NULL;

    EdFormId->Clear();

    EdFormName->Clear();
    EdFormDesc->Clear();

    CbFormKind->ItemIndex     = 0;
    CbFormDsplMthd->ItemIndex = 1;
    CbFormDsplDrct->ItemIndex = 3;
	CbFormColor->ItemIndex    = 0;

    FormObjectClear();

    FNewDb = false;
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::FormObjectClear()
{
    m_pEdtDesigner->Clear();
    CMM_ClearGridTableView(TvObjList);
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::DisplayInfo()
{
    TcxTabSheet* pActive = PgFormTab->ActivePage;

    try
    {
        LockWindowUpdate(Handle);

        FormClear();

        PgEdit->ActivePage = TsEdit;

        FSelIdx = TvList->DataController->FocusedRecordIndex;
        if( FSelIdx <= -1 )
            return;

        DisplayFormInfo(FSelIdx);

        ChangeEditMode(3);
    }
    __finally
    {
        if (PgFormTab->ActivePage != pActive)
            PgFormTab->ActivePage = pActive;

        LockWindowUpdate(0);
    }
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::DisplayFormInfo(int AIdx)
{
	TcxGridDataController *pDc = TvList->DataController;

    if (AIdx < FListSymb->Count)
    {
        //Graphics::TBitmap *bitmap = (Graphics::TBitmap*)FListSymb->Items[AIdx];
        //ImgForm->Picture->Bitmap->Assign(bitmap);
    }

    EdSizeType->Text       = CbSizeType->Text;

    EdFormId->Text         = VarToStr(pDc->Values[AIdx][Col01->Index]);
    EdFormName->Text       = VarToStr(pDc->Values[AIdx][Col02->Index]);
    EdFormDesc->Text       = VarToStr(pDc->Values[AIdx][Col03->Index]);
    EdFormName1->Text      = EdFormName->Text;
    EdFormDesc1->Text      = EdFormDesc->Text;
    CbFormColor->ItemIndex = VarToStr(pDc->Values[AIdx][Col08->Index]).ToIntDef(0);
    CbFormColor1->ItemIndex = CbFormColor->ItemIndex;

    m_sFormTypeCd = VarToStr(pDc->Values[AIdx][Col09->Index]);
    APP_SetCode(CbFormKind,     m_sFormTypeCd);
    APP_SetCode(CbFormDsplMthd, VarToStr(pDc->Values[AIdx][Col06->Index]));
    APP_SetCode(CbFormDsplDrct, VarToStr(pDc->Values[AIdx][Col07->Index]));

    m_pEdtDesigner->BkColorCode = String(CbFormColor->ItemIndex);

    LoadFormObjectInfo(EdFormId->Text, m_pEdtDesigner, m_sFormTypeCd);

    SelObjectListData();

    //MyUseManager->LoadFromDb(EdFormId->Text);
}
//---------------------------------------------------------------------------

String __fastcall TFrmVmsFormEdit::FindObjectTypeName(String AFormType, String ATypeCd)
{
    String sReturn = "--???--";

    TVmsFormObjType *pObj = VmsFormObjTypeManager->Find(AFormType.ToIntDef(-1));
    if (!pObj) return sReturn;

    TVmsCode *pType = pObj->FLists.Find(ATypeCd.ToIntDef(-1));
    if (pType) sReturn = pType->NAME;

    return sReturn;
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::FnFormObjectSelected(TMessage &Msg)
{
#if 0
static long sLParam = -1;
long cLParam = (long)Msg.LParam;
    if (sLParam == cLParam)
    {
        return;
    }
    sLParam = cLParam;
#endif

    m_bEdit = true;

    try {
        ImgDesc99->Visible = false;
        Lbl99->Visible = false;
        Cb99->Visible = false;
        //Cb99->ItemIndex = 0;

        PnlIfsc->Visible = false;
        EdIfscId->Text   = "";

        TVmsFormObject *pObj = (TVmsFormObject *)Msg.LParam;
        if (!pObj) return;
        if (!pObj->Selected) return;

        EdObjSeq->Text = String(pObj->ObjSeq);

        if (pObj->ObjType.ToIntDef(0) == 91 ||  //@축통행시간(고정)
            pObj->ObjType.ToIntDef(0) == 92)    //@축소통상황(고정)
        {
            LblTag->Caption = "제공구간";
            BtnIfscErase->Caption = "제공구간초기화";
            PnlIfsc->Visible = true;
            EdIfscId->Text   = pObj->Tag;
            FSelObjType = eSelObjIfsc;
        }
        else
        if (pObj->ObjType.ToIntDef(0) == 501 ||  //@주차가능대수
            pObj->ObjType.ToIntDef(0) == 502)    //@주차혼잡도
        {
            LblTag->Caption = "주차장";
            BtnIfscErase->Caption = "주차장초기화";
            PnlIfsc->Visible = true;
            EdIfscId->Text   = pObj->Tag;
            FSelObjType = eSelObjPark;
        }
        else
        if (pObj->ObjType.ToIntDef(0) >= 401 && pObj->ObjType.ToIntDef(0) <= 413)
        {
            LblTag->Caption = "관측소";
            BtnIfscErase->Caption = "관측소초기화";
            PnlIfsc->Visible = true;
            EdIfscId->Text   = pObj->Tag;
            FSelObjType = eSelObjAtmp;
        }

        String sFormType = APP_GetCode(CbFormKind);
        if (sFormType == "15")
        {
            //도형식배경소통정보
            if (pObj->ObjType.ToIntDef(0) == 0 ||  //문자열
                pObj->ObjType.ToIntDef(0) == 1 ||  //심볼
                pObj->ObjType.ToIntDef(0) == 2)    //이미지
            {
                ImgDesc99->Visible = true;
                Lbl99->Visible = true;
                Cb99->Visible = true;
                TNotifyEvent evt = Cb99->Properties->OnChange;
                Cb99->Properties->OnChange = NULL;
                APP_SetCode(Cb99, pObj->Tag);
                Cb99->Properties->OnChange = evt;
            }
        }

        EdObjId->Text        = pObj->ObjId;

        ChkBlinking->Checked = pObj->Blink;
        CbBkColor->ItemIndex = pObj->BkColorCode.ToInt();
        SeLeft->Value        = pObj->GetLeft();
        SeTop->Value         = pObj->GetTop();

        if (pObj->DrawType == odtText)
        {
            APP_SetCode(CbObjType, pObj->ObjType);
            APP_SetCode(CbFontName, pObj->FontNameCode);
#if 0
            CbFontColor->ItemIndex = pObj->FontColorCode.ToInt();
#else
            CbFontColor->ItemIndex = VmsFontColrManager->GetColorCodeIndex(pObj->FontColorCode.ToInt());
#endif
            SeFontSize->Value      = pObj->FontSize;
            ChkFontBold->Checked   = pObj->FontBold;
            CbTextAlign->ItemIndex = pObj->TextAlign;

            if (EdTextData->Text != pObj->Text)  EdTextData->Text = pObj->Text;

            if (pObj->ObjType.ToIntDef(0) == 19) //소통정보(가변)
            {
                EdTextData->Properties->ReadOnly = true;
            }
            else
            {
                EdTextData->Properties->ReadOnly = false;
            }
            //CbTextType->Visible = true;
            //CbImageType->Visible= false;
        }
        else
        {
            APP_SetCode(CbObjType, pObj->ObjType);
            if (EdTextData->Text != pObj->Text)  EdTextData->Text = pObj->Text;

            //CbTextType->Visible = false;
            //CbImageType->Visible= true;
        }

        TcxGridFocusedRecordChangedEvent evt = TvObjList->OnFocusedRecordChanged;
        TvObjList->OnFocusedRecordChanged = NULL;
        String sObjSeq = String(pObj->ObjSeq);
        CMM_SetGridRow(CxObjList, TvObjList, sObjSeq, ColSeq->Index);
        TvObjList->OnFocusedRecordChanged = evt;

        CheckImageSelected();

    } catch(...) {}

    m_bEdit = false;
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::TvObjListFocusedRecordChanged(TcxCustomGridTableView *Sender,
          TcxCustomGridRecord *APrevFocusedRecord, TcxCustomGridRecord *AFocusedRecord,
          bool ANewItemRecordFocusingChanged)
{
#if 0
    if (AFocusedRecord == NULL)
    {
        return;
    }
#endif

    ImgDesc99->Visible = false;
    Lbl99->Visible = false;
    Cb99->Visible = false;
    //Cb99->ItemIndex = 0;

    PnlIfsc->Visible = false;
    EdIfscId->Text   = "";

    if (TvObjList->ViewData->RecordCount <= 0) return;
    if (TvObjList->DataController->FocusedRowIndex < 0) return;

    TcxDataController *pGDC = TvObjList->DataController;
    int nIndex = pGDC->FocusedRecordIndex;
    String sObjSeq = pGDC->Values[nIndex][ColSeq->Index];
    String sObjId  = pGDC->Values[nIndex][ColId->Index];

    EdObjSeq->Text = sObjSeq;

    //m_pEdtDesigner->SelectObject(sObjSeq.ToInt());
    TVmsFormObject *pObj = m_pEdtDesigner->FindObject(sObjSeq.ToInt());
    if (pObj)
    {
        if (pObj->ObjType.ToIntDef(0) == 91 ||  //@축통행시간(고정)
            pObj->ObjType.ToIntDef(0) == 92)    //@축소통상황(고정)
        {
            LblTag->Caption = "제공구간";
            BtnIfscErase->Caption = "제공구간초기화";
            PnlIfsc->Visible = true;
            EdIfscId->Text   = pObj->Tag;
            FSelObjType = eSelObjIfsc;
        }
        else
        if (pObj->ObjType.ToIntDef(0) == 501 ||  //@주차가능대수
            pObj->ObjType.ToIntDef(0) == 502)    //@주차혼잡도
        {
            LblTag->Caption = "주차장";
            BtnIfscErase->Caption = "주차장초기화";
            PnlIfsc->Visible = true;
            EdIfscId->Text   = pObj->Tag;
            FSelObjType = eSelObjPark;
        }
        else
        if (pObj->ObjType.ToIntDef(0) >= 401 && pObj->ObjType.ToIntDef(0) <= 413)
        {
            LblTag->Caption = "관측소";
            BtnIfscErase->Caption = "관측소초기화";
            PnlIfsc->Visible = true;
            EdIfscId->Text   = pObj->Tag;
            FSelObjType = eSelObjAtmp;
        }

        if (pObj->ObjType.ToIntDef(0) == 19) //소통정보(가변)
        {
            EdTextData->Properties->ReadOnly = true;
        }
        else
        {
            EdTextData->Properties->ReadOnly = false;
        }

        String sFormType = APP_GetCode(CbFormKind);
        if (sFormType == "15")
        {
            //도형식배경소통정보
            if (pObj->ObjType.ToIntDef(0) == 0 ||  //문자열
                pObj->ObjType.ToIntDef(0) == 1 ||  //심볼
                pObj->ObjType.ToIntDef(0) == 2)    //이미지
            {
                ImgDesc99->Visible = true;
                Lbl99->Visible = true;
                Cb99->Visible = true;
                TNotifyEvent evt = Cb99->Properties->OnChange;
                Cb99->Properties->OnChange = NULL;
                APP_SetCode(Cb99, pObj->Tag);
                Cb99->Properties->OnChange = evt;
            }
        }
    }

    CheckImageSelected();
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::SelObjectListData()
{
    CMM_ClearGridTableView(TvObjList);

    int nObjCnt = m_pEdtDesigner->GetObjectCount();
    TVmsFormObject *pObj;
    for(int ii = 0; ii < nObjCnt; ii++)
    {
        pObj = m_pEdtDesigner->GetObject(ii);
        if (pObj)
        {
            AddObjectToList(pObj);
        }
    }
    if (TvObjList->DataController->RecordCount > 0) TvObjList->DataController->FocusedRecordIndex = 0;
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::AddObjectToList(TVmsFormObject *pObj, bool bSelect/*=false*/)
{
    int nAddRow = -1;

    String sFormType = APP_GetCode(CbFormKind);
    TcxGridDataController *pGDC = TvObjList->DataController;
    try
    {
        TvObjList->BeginUpdate();
        pGDC->BeginUpdate();

        nAddRow = pGDC->AppendRecord();

        pGDC->Values[nAddRow][ColSeq->Index]  = String(pObj->ObjSeq);
        pGDC->Values[nAddRow][ColId->Index]   = String(pObj->ObjId);
        pGDC->Values[nAddRow][ColType->Index] = FindObjectTypeName(sFormType, pObj->ObjType);
        pGDC->Values[nAddRow][ColData->Index] = pObj->Text;
#if 0
        if (pObj->ObjKind == OBJKIND_TEXT)
        {
            pGDC->Values[nAddRow][ColKind->Index] = "문자열";
            pGDC->Values[nAddRow][ColType->Index] = "";//GetComboBoxCodeName(CbTextType, pObj->ObjType);
            pGDC->Values[nAddRow][ColData->Index] = pObj->Text;
        }
        else
        if (pObj->ObjKind == OBJKIND_IMAGE)
        {
            pGDC->Values[nAddRow][ColKind->Index] = "이미지";
            pGDC->Values[nAddRow][ColType->Index] = "";//GetComboBoxCodeName(CbImageType, pObj->ObjType);
            pGDC->Values[nAddRow][ColData->Index] = pObj->Text;
        }
        else
        if (pObj->ObjKind == OBJKIND_IMAGEID)
        {
            pGDC->Values[nAddRow][ColKind->Index] = "이미지ID";
            pGDC->Values[nAddRow][ColType->Index] = "";//GetComboBoxCodeName(CbImageType, pObj->ObjType);
            pGDC->Values[nAddRow][ColData->Index] = pObj->Text + " [" + pObj->ImageId + "]";
        }
#endif

        //pGDC->Values[nAddRow][ColX->Index] = String(pObj->GetLeft());
        //pGDC->Values[nAddRow][ColY->Index] = String(pObj->GetTop());
        pGDC->Values[nAddRow][ColIfscId->Index] = pObj->Tag;
        pGDC->Values[nAddRow][ColMem->Index] = (int)pObj;
    }
    __finally
    {
        pGDC->EndUpdate();
        TvObjList->EndUpdate();
        if (bSelect && pGDC->RecordCount > 0) if (nAddRow >= 0) pGDC->FocusedRecordIndex = nAddRow;
    }
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::BtnSortReClick(TObject *Sender)
{
    TcxButton *pBtn = (TcxButton *)Sender;
    ReForm->Paragraph->Numbering = nsNone;
    ReForm->Paragraph->Alignment = (TAlignment)pBtn->Tag;
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::BtnBoldReClick(TObject *Sender)
{
    if (ReForm->SelAttributes->Style.Contains(fsBold))
        ReForm->SelAttributes->Style = TFontStyles() >> fsBold;
    else
        ReForm->SelAttributes->Style = TFontStyles() << fsBold;
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::SeFontSizeRePropertiesChange(TObject *Sender)
{
    if (((TcxSpinEdit*)Sender)->Value < ((TcxSpinEdit*)Sender)->Properties->MinValue)
        ((TcxSpinEdit*)Sender)->Value = ((TcxSpinEdit*)Sender)->Properties->MinValue;
    else if(((TcxSpinEdit*)Sender)->Value > ((TcxSpinEdit*)Sender)->Properties->MaxValue &&
        ((TcxSpinEdit*)Sender)->Properties->MaxValue)
        ((TcxSpinEdit*)Sender)->Value = ((TcxSpinEdit*)Sender)->Properties->MaxValue;

    ReForm->SelAttributes->Size = ((TcxSpinEdit*)Sender)->Value;
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::CbFontColorReClick(TObject *Sender)
{
#if 0
    switch(CbFontColorRe->ItemIndex)
    {
        case 0 : ReForm->SelAttributes->Color = clBlack;  break;
        case 1 : ReForm->SelAttributes->Color = clRed;    break;
        case 2 : ReForm->SelAttributes->Color = clLime;   break;
        case 3 :
        default: ReForm->SelAttributes->Color = clYellow; break;
    }
#else
    ReForm->SelAttributes->Color = CbFontColorRe->Selected;//CbFontColorRe->Colors[CbFontColorRe->ItemIndex];
#endif
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::CbFontNameReClick(TObject *Sender)
{
    String sFontCode = APP_GetCode(CbFontNameRe);
    String sFontName = APP_GetCodeName(CbFontNameRe, sFontCode);
    ReForm->SelAttributes->Name = sFontName;
}
//---------------------------------------------------------------------------

#include <imm.h>
bool IsInComposition(HWND AHwnd)
{
    int  H;
    char Buff[2];
    int  Len;
    bool res = false;

    H = Imm32GetContext(AHwnd);
    if (H)
    {
        Len = Imm32GetCompositionString(H, GCS_COMPSTR, Buff, 2);
        Imm32ReleaseContext(AHwnd, H);
        res = Len > 0 ? true : false;
    }
    return res;
}

void __fastcall TFrmVmsFormEdit::ReFormChange(TObject *Sender)
{
#if 0
    if (!IsInComposition(ReForm->Handle))
    {
        //m_pEdtDesigner->PreviewDrawForm(ReForm, ReFormTemp, ImgEdtPreview);
    }
#else
    if (ChkAutoPreview->Checked) BtnPreviewClick(NULL);
#endif
#if 0
    unsigned long Conversion, Sentence;
    HIMC Mode = ImmGetContext(Application->Handle);
    ImmGetConversionStatus(Mode, &Conversion, &Sentence);
    if (Conversion == IME_CMODE_HANGEUL)
    {
        if (!IsInComposition(ReForm->Handle))
        {
            m_pEdtDesigner->PreviewDrawForm(ReForm, ReFormTemp, ImgEdtPreview);
        }
    }
    else
    {
        m_pEdtDesigner->PreviewDrawForm(ReForm, ReFormTemp, ImgEdtPreview);
    }
      //AnsiString::IsReadByte()
//    m_pEdtDesigner->PreviewDrawForm(ReForm, ReFormTemp, ImgEdtPreview);
#endif
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::ChkAutoPreviewClick(TObject *Sender)
{
    if (ChkAutoPreview->Checked) BtnPreviewClick(NULL);
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::BtnPreviewClick(TObject *Sender)
{
    if (ChkDrawModule->Checked)
        m_pEdtDesigner->PreviewDrawModuleForm(ReForm, ReFormTemp, ImgEdtPreview, FVmsRows, FVmsCols);
    else
        m_pEdtDesigner->PreviewDrawForm(ReForm, ReFormTemp, ImgEdtPreview);
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::BtnReApplyClick(TObject *Sender)
{
    BtnPreviewClick(NULL);

    m_pEdtDesigner->AddDrawFormToVmsForm(ReForm, ImgEdtPreview);

    /*
    *  신규로 등록한 객체의 객체타입과 폰트코드를 업데이트 한다.
    */
    CbVmsObjType->ItemIndex = 0;   // For 고정문자열
    String sObjType = APP_GetCode(CbVmsObjType);

    TVmsFormObject *pObj;
    int nObjCnt = m_pEdtDesigner->GetObjectCount();
    for (int ii = 0; ii < nObjCnt; ii++)
    {
        pObj = m_pEdtDesigner->GetObject(ii);
        if (pObj->ObjType == "XXX" && pObj->FontNameCode == "XXX")
        {
            pObj->ObjType = sObjType;
            pObj->FontNameCode = APP_GetCodeIdByName(CbFontName, pObj->FontName);
        }
    }

    PgEdit->ActivePageIndex = 0;
    SelObjectListData();
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::CbFormKindPropertiesChange(TObject *Sender)
{
    CbVmsObjType->Properties->Items->Clear();
    CbObjType->Properties->Items->Clear();

    String sFormType = APP_GetCode(CbFormKind);
    int nFormKind = sFormType.ToIntDef(0);
    TVmsFormObjType *pObj = VmsFormObjTypeManager->Find(nFormKind);
    if (!pObj) return;

    FOR_STL(TVmsCode*, pType, pObj->FLists)
    {
        String sType;
        sType.printf(L"%2d", pType->CODE);
        //sType = pType->CODE;
        CbVmsObjType->Properties->Items->Add(" [" + sType + "] " + pType->NAME);
        CbObjType->Properties->Items->Add(" [" + sType + "] " + pType->NAME);
    }

    CbVmsObjType->ItemIndex = 0;
    CbObjType->ItemIndex = 0;
    //EdFocus->SetFocus();
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::CbFormColorClick(TObject *Sender)
{
    m_pEdtDesigner->SetBkColor(String(CbFormColor->ItemIndex));
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::BtnMoveClick(TObject *Sender)
{
    if (m_bEdit) return;
    TcxButton *pBtn = (TcxButton *)Sender;
    switch(pBtn->Tag)
    {
    case 0: m_pEdtDesigner->StepMoveLeft();  break;
    case 1: m_pEdtDesigner->StepMoveRight(); break;
    case 2: m_pEdtDesigner->StepMoveUp();    break;
    case 3: m_pEdtDesigner->StepMoveDown();  break;
    }
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::BtnAlignClick(TObject *Sender)
{
    if (m_bEdit) return;
    TcxButton *pBtn = (TcxButton *)Sender;
    if (m_pEdtDesigner->GetSelectedObjectCount() < 1) return;
    switch(pBtn->Tag)
    {
    case 0: m_pEdtDesigner->SetLeftAlign(m_pEdtDesigner->GetLeftAlign());     break;
    case 1: m_pEdtDesigner->SetRightAlign(m_pEdtDesigner->GetRightAlign());   break;
    case 2: m_pEdtDesigner->SetTopAlign(m_pEdtDesigner->GetTopAlign());       break;
    case 3: m_pEdtDesigner->SetBottomAlign(m_pEdtDesigner->GetBottomAlign()); break;
    }
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::BtnCenterClick(TObject *Sender)
{
    if (m_bEdit) return;
    TcxButton *pBtn = (TcxButton *)Sender;
    if (m_pEdtDesigner->GetSelectedObjectCount() < 1) return;
    switch(pBtn->Tag)
    {
    case 0: m_pEdtDesigner->SetAlignWidthCenter();  break;
    case 1: m_pEdtDesigner->SetAlignHeightCenter(); break;
    }
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::SePosPropertiesChange(TObject *Sender)
{
    if (m_bEdit) return;
    if (((TcxSpinEdit*)Sender)->Value < ((TcxSpinEdit*)Sender)->Properties->MinValue)
        ((TcxSpinEdit*)Sender)->Value = ((TcxSpinEdit*)Sender)->Properties->MinValue;
    else if(((TcxSpinEdit*)Sender)->Value > ((TcxSpinEdit*)Sender)->Properties->MaxValue &&
        ((TcxSpinEdit*)Sender)->Properties->MaxValue)
        ((TcxSpinEdit*)Sender)->Value = ((TcxSpinEdit*)Sender)->Properties->MaxValue;

    TcxSpinEdit *pPos = (TcxSpinEdit*)Sender;
    if (m_pEdtDesigner->GetSelectedObjectCount() < 1) return;
    int nValue = pPos->Value;
    switch(pPos->Tag)
    {
    case 0: m_pEdtDesigner->MoveLeft(nValue); break;
    case 1: m_pEdtDesigner->MoveUp(nValue);   break;
    }
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::CbBkColorClick(TObject *Sender)
{
    if (m_bEdit) return;
    //if (m_pEdtDesigner->GetSelectedObjectCount() < 1) return;
    m_pEdtDesigner->SetObjectBkColorCode(String(CbBkColor->ItemIndex));
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::ChkBlinkingClick(TObject *Sender)
{
    if (m_bEdit) return;
    //if (m_pEdtDesigner->GetSelectedObjectCount() < 1) return;
    m_pEdtDesigner->SetObjectBlink(ChkBlinking->Checked);
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::EdTextDataKeyPress(TObject *Sender, wchar_t &Key)
{
    if (m_bEdit) return;
    if (Key == '\'')
    {
        Key = '`';
    }
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::EdTextDataPropertiesChange(TObject *Sender)
{
    if (m_bEdit) return;
    //if (m_pEdtDesigner->GetSelectedObjectCount() < 1) return;
    m_pEdtDesigner->SetObejctText(EdTextData->Text);
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::SeFontSizePropertiesChange(TObject *Sender)
{
    if (m_bEdit) return;
    if (((TcxSpinEdit*)Sender)->Value < ((TcxSpinEdit*)Sender)->Properties->MinValue)
        ((TcxSpinEdit*)Sender)->Value = ((TcxSpinEdit*)Sender)->Properties->MinValue;
    else if(((TcxSpinEdit*)Sender)->Value > ((TcxSpinEdit*)Sender)->Properties->MaxValue &&
        ((TcxSpinEdit*)Sender)->Properties->MaxValue)
        ((TcxSpinEdit*)Sender)->Value = ((TcxSpinEdit*)Sender)->Properties->MaxValue;

    //if (m_pEdtDesigner->GetSelectedObjectCount() < 1) return;
    int nFontSize = SeFontSize->Value;
    m_pEdtDesigner->SetObejctFontSize(nFontSize);
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::CbFontNamePropertiesChange(TObject *Sender)
{
    if (m_bEdit) return;
    //if (m_pEdtDesigner->GetSelectedObjectCount() < 1) return;
    String sFontCode = APP_GetCode(CbFontName);
    String sFontName = APP_GetCodeName(CbFontName, sFontCode);

    m_pEdtDesigner->SetObejctFontName(sFontName.Trim());
    m_pEdtDesigner->SetObejctFontNameCode(sFontCode);
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::CbFontColorClick(TObject *Sender)
{
    if (m_bEdit) return;
    //if (m_pEdtDesigner->GetSelectedObjectCount() < 1) return;
#if 0
    m_pEdtDesigner->SetObejctFontColorCode(String(CbFontColor->ItemIndex));
#else
    m_pEdtDesigner->SetObejctFontColorCode(String(VmsFontColrManager->GetColorCode((int)CbFontColor->Selected)));
#endif
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::CbTextAlignPropertiesChange(TObject *Sender)
{
    if (m_bEdit) return;
    //if (m_pEdtDesigner->GetSelectedObjectCount() < 1) return;
    m_pEdtDesigner->SetObejctTextAlign(CbTextAlign->ItemIndex);
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::EdObjIdPropertiesChange(TObject *Sender)
{
    if (m_bEdit) return;
    //if (m_pEdtDesigner->GetSelectedObjectCount() < 1) return;

    try {
        int nObjId;
        TryStrToInt(EdObjId->Text.Trim(), nObjId);
        m_pEdtDesigner->SetObejctId(nObjId);
    } catch(...) {}
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::ChkFontBoldClick(TObject *Sender)
{
    if (m_bEdit) return;
    //if (m_pEdtDesigner->GetSelectedObjectCount() < 1) return;
    m_pEdtDesigner->SetObejctFontBold(ChkFontBold->Checked);
}
//---------------------------------------------------------------------------

bool __fastcall TFrmVmsFormEdit::GetNextVmsImgeId(int &ANmbr)
{
    ANmbr = -1;
    String apiUri = g_AppCfg.sRestApiUri + "/api/vms/manager/symb-sbt0/new-id";
    TMcJsonItem *ObjList = NULL;
    try {
        ObjList = TRestObjectManager::RequestGet(apiUri);
        if (ObjList == NULL) {
            return false;
        }

        if (ObjList->Count > 0) {
            String newId = TRestObjectManager::GetValue(ObjList, "new_id");
            ANmbr = newId.ToIntDef(-1);
        }
    } __finally {
        if (ObjList) delete ObjList;
    }
    if (ANmbr == -1) return false;
    return true;
}
//---------------------------------------------------------------------------

bool __fastcall TFrmVmsFormEdit::InsertVmsImage(String ANmbr, String AExpl, String AFileName, String ATypeCd)
{
    bool result = false;
    String resultVal;
    String key = "abcdefg1234567890x";
    String apiUri = g_AppCfg.sRestApiUri + "/cs-api/vms/form/manage/symb/0/merge/" + key + "/" + ANmbr;
    TMcJsonItem *ObjList = new TMcJsonItem();
    try {
        ObjList->Add("symb_lib_nmbr")->AsInteger = ANmbr.ToIntDef(0);
        ObjList->Add("rgst_dt")->AsString = Now().FormatString("yyyymmddhhnnss");
        ObjList->Add("symb_expl")->AsString = AExpl;
        ObjList->Add("del_yn")->AsString = "N";
        ObjList->Add("imag_size")->AsString = String(FFileSize);
        ObjList->Add("imag_data")->AsString = BitmapToBase64String(ImgEdtTemp->Picture->Bitmap);
        result = TRestObjectManager::RequestPost(apiUri, ObjList->AsJSON, resultVal);
        if (!result) {
            return false;
        }

    } __finally {
        if (ObjList) delete ObjList;
    }

    return result;
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::OpenBmpCanClose(TObject *Sender, bool &CanClose)
{
    String sFName = OpenBmp->FileName;
    //sFName = sFName.UpperCase();

    String sFilePath = ExtractFilePath(sFName);
    String sFileName = ExtractFileName(sFName);
    String sFileExt  = ExtractFileExt(sFName);
    if (sFileExt.UpperCase() != ".BMP")
    {
        if (!APP_CheckBmpFile(sFName, sFName))
        {
            Application->MessageBox(L"이미지 파일을 읽어오는데 실패하였습니다", L"이미지 파일 읽기 실패", MB_OK|MB_ICONERROR|MB_APPLMODAL);
            return;
        }
        sFileExt = ExtractFileExt(sFName);
    }

    sFName = sFName.UpperCase();
	if (sFName.SubString(sFName.Length()-2, 3) != "BMP")
    {
        Application->MessageBox(L"BMP 파일만 적용 가능합니다.",
                                lblImage1->Caption.c_str(),//L"VMS 이미지 선택",
                                MB_OK|MB_ICONWARNING|MB_APPLMODAL);
		return;
	}

    try
    {
        FFileSize = ITSUtil_GetFileSize(sFName);
        if (FFileSize <= 0)
        {
            Application->MessageBox(L"이미지 파일을 읽어 오는데 실패하였습니다.",
                                    lblImage1->Caption.c_str(),//L"VMS 이미지 선택",
                                    MB_OK|MB_ICONWARNING|MB_APPLMODAL);
            return;
        }
#if 0
        if (FFileSize > (1024 * 32))   // Max 32Kbytes
        {
            Application->MessageBox(L"이미지 파일의 최대 크기는 32KBytes를 넘을 수 없습니다.\r\n이미지 파일의 용량을 줄여 주세요.",
                                    lblImage1->Caption.c_str(),//L"VMS 이미지 선택",
                                    MB_OK|MB_ICONWARNING|MB_APPLMODAL);
            return;
        }
#endif

        ImgEdtTemp->Picture->Bitmap->FreeImage();
        ImgEdtTemp->Picture->Bitmap = NULL;
        ImgEdtTemp->Picture->Bitmap->LoadFromFile(sFName);

        String sExpl = EdFormId->Text.Trim();
        int nNmbr;
        if (!GetNextVmsImgeId(nNmbr))
        {
            Application->MessageBox(L"새로운 VMS 이미지정보를 생성하지 못하였습니다.\r\n프로그램 종료후에 다시 시도해 보세요.",
                                    lblImage1->Caption.c_str(),//L"VMS 이미지 선택",
                                    MB_OK|MB_ICONERROR|MB_APPLMODAL);
            return;
        }
        if (!InsertVmsImage(String(nNmbr), sExpl, "", "SBT0"))
        {
            Application->MessageBox(L"새로운 VMS 이미지정보를 저장하지 못하였습니다.\r\n프로그램 종료후에 다시 시도해 보세요.",
                                    lblImage1->Caption.c_str(),//L"VMS 이미지 선택",
                                    MB_OK|MB_ICONERROR|MB_APPLMODAL);
            return;
        }

        TVmsFormObject *pObj = m_pEdtDesigner->AddObject(odtBmp);
        if (!pObj) return;

        int nNewObjSeq = m_pEdtDesigner->GetNewObjectSeq();
        EdObjSeq->Text = String(nNewObjSeq);

        pObj->ObjSeq        = nNewObjSeq;
        pObj->ObjKind       = OBJKIND_IMAGEID;//OBJKIND_IMAGE;    // "1"
        pObj->ObjType       = "1";//"2";
        pObj->ObjSize       = (int)FFileSize;
        pObj->BkColorCode   = m_pEdtDesigner->BkColorCode;
        pObj->Blink         = false;
        pObj->Tag           = "N";

        pObj->SetBitmap(ImgEdtTemp->Picture->Bitmap);

        pObj->Text    = lblFile1->Caption;//"파일이미지";//ExtractShortPathName(sFName).c_str();
        pObj->ImageId = String(nNmbr);
        pObj->SetPos(0, 0);
#ifdef IMAGE_RESIZE
        //pObj->GetImage()->AutoSize= false;
        //pObj->GetImage()->Stretch = true;

        TNotifyEvent evtW = SeImgW->Properties->OnChange;
        TNotifyEvent evtH = SeImgH->Properties->OnChange;
        SeImgW->Properties->OnChange = NULL;
        SeImgH->Properties->OnChange = NULL;

        SeImgW->Value = ImgEdtTemp->Picture->Bitmap->Width;
        SeImgH->Value = ImgEdtTemp->Picture->Bitmap->Height;

        SeImgW->Properties->OnChange = evtW;
        SeImgH->Properties->OnChange = evtH;

        PnlImage->Visible = true;
#endif
        pObj->EditMode = true;
        pObj->Show();

        AddObjectToList(pObj, true);
    }
    catch(...)
    {
        return;
    }
}
//---------------------------------------------------------------------------

bool __fastcall TFrmVmsFormEdit::CheckVideoStreamImage()
{
#if 0
    String sQry;
    TADOQuery *pADO = NULL;

    sQry = "SELECT SYMB_LIB_NMBR, COUNT(1) AS CNT \r\n"
           "  FROM TB_VMS_SYMB_LIB                \r\n"
           " WHERE SYMB_LIB_NMBR IN (200, 300)    \r\n"
           " GROUP BY SYMB_LIB_NMBR               \r\n";

    bool bVideo = false;
    bool bStream = false;
    try
    {
        try
        {
            pADO = new TADOQuery(NULL);
			pADO->Close();
            pADO->Connection = ITSDb_GetConnection();

            ITSDb_SQLText(pADO, sQry);
            ITSDb_SQLOpen(pADO);
            for( ; !pADO->Eof; pADO->Next())
            {
                int SYMB_LIB_NMBR = pADO->FieldByName("SYMB_LIB_NMBR")->AsInteger;
                int CNT = pADO->FieldByName("CNT")->AsInteger;
                if (CNT > 0)
                {
                    if (SYMB_LIB_NMBR == 200) bVideo  = true;
                    else                      bStream = true;
                }
            }

    sQry = "INSERT INTO TB_VMS_SYMB_LIB(SYMB_LIB_NMBR, RGST_DT, SYMB_EXPL, IMAG_DATA, SYMB_FILE_NM, SYMB_TYPE, AVI_DATA, IMAG_SIZE, UPDT_DT, DEL_YN) \r\n"
           "                     VALUES(:p01,          :p02,    :p03,      :p04,      NULL,         'SBT9',    NULL,     :p05,      :p06,    'N'   ) \r\n";

            if (!bVideo)
            {
                TMemoryStream *imgStream  = new TMemoryStream();
               	ImgVideo->Picture->Bitmap->SaveToStream(imgStream);
                try
                {
                    ITSDb_SQLText(pADO, sQry);
                    ITSDb_SQLBind(pADO, "p01", "200");
                    ITSDb_SQLBind(pADO, "p02", Now().FormatString("yyyymmddhhnnss"));
                    if (g_AppCfg.sLang != "kr")
                        ITSDb_SQLBind(pADO, "p03", "@Video file mame");
                    else
                        ITSDb_SQLBind(pADO, "p03", "@동영상파일명");
                    pADO->Parameters->ParamByName("p04")->LoadFromStream(imgStream, ftBlob);
                    ITSDb_SQLBind(pADO, "p05", ImgVideo->Width*ImgVideo->Height);
                    ITSDb_SQLBind(pADO, "p06", Now().FormatString("yyyymmddhhnnss"));
                    pADO->ExecSQL();
                }
                __finally
                {
                    if (imgStream) delete imgStream;
                    imgStream = NULL;
                }
            }

            if (!bStream)
            {
                TMemoryStream *imgStream  = new TMemoryStream();
               	ImgStream->Picture->Bitmap->SaveToStream(imgStream);
                try
                {
                    ITSDb_SQLText(pADO, sQry);
                    ITSDb_SQLBind(pADO, "p01", "300");
                    ITSDb_SQLBind(pADO, "p02", Now().FormatString("yyyymmddhhnnss"));
                    if (g_AppCfg.sLang != "kr")
                        ITSDb_SQLBind(pADO, "p03", "@Stream URL");
                    else
                        ITSDb_SQLBind(pADO, "p03", "@스트리밍영상주소");
                    pADO->Parameters->ParamByName("p04")->LoadFromStream(imgStream, ftBlob);
                    ITSDb_SQLBind(pADO, "p05", ImgStream->Width*ImgStream->Height);
                    pADO->ExecSQL();
                }
                __finally
                {
                    if (imgStream) delete imgStream;
                    imgStream = NULL;
                }
            }

            return true;
        }
        catch(EDatabaseError &E)
        {
            DBERRORMSG("TFrmVmsFormEdit::CheckVideoStreamImage", String(E.ClassName()), E.Message, sQry);
            throw Exception(String(E.ClassName()) + E.Message);
        }
        catch(Exception &e)
        {
            DBERRORMSG("TFrmVmsFormEdit::CheckVideoStreamImage", String(e.ClassName()), e.Message, sQry);
            throw Exception(String(e.ClassName()) + e.Message);
        }
    }
    __finally
    {
        if (pADO)
        {
            pADO->Close();
            delete pADO;
        }
    }
#endif
    return true;
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::MakeDefVideoStreamForm(int AType)
{
    if (CbVmsObjType->ItemIndex < 0) return;

    for (int ii = 0; ii < CbVmsObjType->Properties->Items->Count; ii++)
    {
        CbVmsObjType->ItemIndex = ii;

        String sFormType = APP_GetCode(CbFormKind);
        String sObjType  = APP_GetCode(CbVmsObjType);
        int    nObjType  = sObjType.ToIntDef(0);

        String sObjText = FindObjectTypeName(sFormType, sObjType);

        String sFontName      = "굴림체";
        String sFontNameCode  = "1";
        String sFontColorCode = "2";    //Green
        int    nFontSize      = 22;
        bool   bFontBold      = true;
        if (AType == 90) nFontSize = 14;

        switch(nObjType)
        {
        case 200:   //동영상
        case 300:   //스트리밍영상
            {
                TVmsFormObject *pObj = m_pEdtDesigner->AddObject(odtBmp);
                if (!pObj) return;

                int nNewObjSeq = m_pEdtDesigner->GetNewObjectSeq();
                EdObjSeq->Text = String(nNewObjSeq);
                pObj->EditMode    = false;
                pObj->ObjSeq      = nNewObjSeq;
                pObj->ObjKind     = OBJKIND_IMAGEID;    // "2"
                pObj->ObjType     = sObjType;
                if (nObjType == 200)
                    pObj->ObjSize = ImgVideo->Width * ImgVideo->Height;
                else
                    pObj->ObjSize = ImgStream->Width * ImgStream->Height;
                pObj->BkColorCode = m_pEdtDesigner->BkColorCode;
                pObj->Blink       = false;
                pObj->Tag         = "N";

                pObj->Text        = sObjText;
                pObj->ImageId     = IntToStr(nObjType);
                int nW, nH;
                if (nObjType == 200)
                {
                    pObj->SetBitmap(ImgVideo->Picture->Bitmap);
                    nW = ImgVideo->Width;
                    nH = ImgVideo->Height;
                }
                else
                {
                    pObj->SetBitmap(ImgStream->Picture->Bitmap);
                    nW = ImgStream->Width;
                    nH = ImgStream->Height;
                }

                nW = (FVmsWidth-nW)/2;
                nH = (FVmsHeight-nH)/2;
                pObj->SetPos(nW, nH);

                pObj->Show();
                AddObjectToList(pObj, true);
            }
            break;
        case   0:   //문자열
        case   1:   //심볼
        case   2:   //이미지
        case 406:   //@통합대기등급 이미지
        case 407:   //@미세먼지등급 이미지
        case 408:   //@초미세먼지등급 이미지
        case 413:   //@오존등급이미지
            break;
        default:
            {
                TVmsFormObject *pObj = m_pEdtDesigner->AddObject(odtText);
                if (!pObj) return;

                int nNewObjSeq = m_pEdtDesigner->GetNewObjectSeq();
                EdObjSeq->Text = String(nNewObjSeq);
                pObj->ObjSeq        = nNewObjSeq;
                pObj->ObjType       = sObjType;

                switch(nObjType)
                {
                case 409:   //@통합대기등급
                case 404:   //@PM10등급
                case 405:   //@PM2.5등급
                case 412:   //@오존등급
                    //pObj->TextAlign = 2;    // center
                    pObj->TextAlign = 0;    // left
                    break;
                case 402:   //@PM10
                case 403:   //@PM2.5
                case 410:   //@통합대기
                case 411:   //@오존
                    //pObj->TextAlign = 1;    // right
                    pObj->TextAlign = 0;    // left
                    break;
                default:
                    pObj->TextAlign = 0;    // left
                    break;
                }
                //EdTextData->Properties->ReadOnly = false;

                pObj->ObjSize       = sObjText.Length();
                pObj->BkColorCode   = m_pEdtDesigner->BkColorCode;
                pObj->Blink         = false;

                pObj->Text          = sObjText;
                pObj->EditMode      = true;
                pObj->ObjKind       = OBJKIND_TEXT;
                pObj->FontName      = sFontName;
                pObj->FontNameCode  = sFontNameCode;
                pObj->FontColorCode = sFontColorCode;
                pObj->FontSize      = nFontSize;

                pObj->FontBold      = bFontBold;

                pObj->SetPos(0, 0);
                pObj->Show();
                AddObjectToList(pObj, true);
            }
            break;
        }
    }
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::BtnAddTextClick(TObject *Sender)
{
    if (CbVmsObjType->ItemIndex < 0) return;

    PnlImage->Visible = false;

    String sFormType = APP_GetCode(CbFormKind);
    String sObjType  = APP_GetCode(CbVmsObjType);
    int    nObjType  = sObjType.ToIntDef(0);

    String sObjText = FindObjectTypeName(sFormType, sObjType);

    String sFontName      = "굴림체";
    String sFontNameCode  = "1";
    String sFontColorCode = "2";    //Green
    int    nFontSize      = 14;
    bool   bFontBold      = true;

    switch(nObjType)
    {
    case 201:   //동영상
    case 301:   //스트리밍영상
        {
            TVmsFormObject *pObj = m_pEdtDesigner->AddObject(odtBmp);
            if (!pObj) return;

            int nNewObjSeq = m_pEdtDesigner->GetNewObjectSeq();
            EdObjSeq->Text = String(nNewObjSeq);
            pObj->EditMode    = false;
            pObj->ObjSeq      = nNewObjSeq;
            pObj->ObjKind     = OBJKIND_IMAGE;    // "2"
            pObj->ObjType     = sObjType;
            pObj->ObjSize     = FVmsWidth * FVmsHeight;
            pObj->BkColorCode = m_pEdtDesigner->BkColorCode;
            pObj->Blink       = false;
            pObj->Tag         = "N";

            pObj->Text        = sObjText;
            pObj->ImageId     = "0";
            int nW, nH;
            if (nObjType == 201)
            {
                pObj->SetBitmap(ImgVideo->Picture->Bitmap);
                nW = ImgVideo->Width;
                nH = ImgVideo->Height;
            }
            else
            {
                pObj->SetBitmap(ImgStream->Picture->Bitmap);
                nW = ImgStream->Width;
                nH = ImgStream->Height;
            }
            //pObj->SetSize(FVmsWidth, FVmsHeight);
            nW = (FVmsWidth-nW)/2;
            nH = (FVmsHeight-nH)/2;
            pObj->SetPos(nW, nH);

            pObj->Show();
            AddObjectToList(pObj, true);
        }
        break;
    case   1:   //이미지 심볼
    case   3:   //소통정보배경이미지
    case  17:   //@소통이미지1
    case  27:   //@소통이미지2
    case  37:   //@소통이미지3
    case  47:   //@소통이미지4
    case 406:   //@통합대기등급 이미지
    case 407:   //@미세먼지등급 이미지
    case 408:   //@초미세먼지등급 이미지
    case 413:   //@오존등급이미지
        {
            TVMSM510M *pSelForm  = new TVMSM510M(this);

            switch(nObjType)
            {
            case   1: //이미지 심볼
                pSelForm->FImageType = 0;
                break;
            case   3: //소통정보배경이미지
                pSelForm->FImageType = 1;
                break;
            case  17: //@소통이미지1
            case  27: //@소통이미지2
            case  37: //@소통이미지3
            case  47: //@소통이미지4
                pSelForm->FImageType = 2;
                break;
            case 406: //@통합대기등급 이미지
            case 407: //@미세먼지등급 이미지
            case 408: //@초미세먼지등급 이미지
            case 413: //@오존등급 이미지
                pSelForm->FImageType = 4;
                break;
            default :
                pSelForm->FImageType = 0;
                break;
            }

            String sSymbType = "SBT0";
            switch(nObjType)
            {
            case   1: //이미지 심볼
                sSymbType = "SBT0";
                break;
            case   3: //소통정보배경이미지
                sSymbType = "SBT1";
                break;
            case  17: //@소통이미지1
            case  27: //@소통이미지2
            case  37: //@소통이미지3
            case  47: //@소통이미지4
                sSymbType = "SBT2";
                break;
            case 406: //@통합대기등급 이미지
            case 407: //@미세먼지등급 이미지
            case 408: //@초미세먼지등급 이미지
            case 413: //@오존등급 이미지
                sSymbType = "SBT4";
                break;
            default :
                sSymbType = "SBT0";
                break;
            }
            pSelForm->SYMB_TYPE = sSymbType;
            pSelForm->ShowModal();
            if (!pSelForm->m_bSelected)
            {
                delete pSelForm;
                return;
            }
            TVmsFormObject *pObj = m_pEdtDesigner->AddObject(odtBmp);
            if (!pObj) return;

            int nNewObjSeq = m_pEdtDesigner->GetNewObjectSeq();
            EdObjSeq->Text = String(nNewObjSeq);
            pObj->ObjSeq      = nNewObjSeq;
            pObj->ObjKind     = OBJKIND_IMAGEID;    // "2"
            pObj->ObjType     = sObjType;
            pObj->ObjSize     = pSelForm->ImgPreView->Picture->Bitmap->Width * pSelForm->ImgPreView->Picture->Bitmap->Height;
            pObj->BkColorCode = m_pEdtDesigner->BkColorCode;
            pObj->Blink       = false;
            pObj->Tag         = "N";

            pObj->Text        = sObjText;
            pObj->ImageId     = pSelForm->EdNmbr->Text;
            pObj->SetBitmap(pSelForm->ImgPreView->Picture->Bitmap);

#ifdef IMAGE_RESIZE
            //if (sSymbType == "SBT0")
            {
                //pObj->GetImage()->AutoSize= false;
                //pObj->GetImage()->Stretch = true;

                TNotifyEvent evtW = SeImgW->Properties->OnChange;
                TNotifyEvent evtH = SeImgH->Properties->OnChange;
                SeImgW->Properties->OnChange = NULL;
                SeImgH->Properties->OnChange = NULL;

                SeImgW->Value = pSelForm->ImgPreView->Picture->Bitmap->Width;
                SeImgH->Value = pSelForm->ImgPreView->Picture->Bitmap->Height;

                SeImgW->Properties->OnChange = evtW;
                SeImgH->Properties->OnChange = evtH;

                PnlImage->Visible = true;
            }
#endif

            pObj->SetPos(0, 0);
            if (pObj->Left < 0) pObj->Left = 0;
            if (pObj->Top  < 0) pObj->Top  = 0;
            pObj->Show();
            AddObjectToList(pObj, true);

            delete pSelForm;
        }
        break;
    case 2:    //파일이미지
        OpenBmp->FileName = "";
        OpenBmp->Execute();
        break;
#if 0
    case 17:    //@방향이미지1
    case 27:    //@방향이미지2
    case 37:    //@방향이미지3
    case 47:    //@방향이미지4
        {
            TVmsFormObject *pObj = m_pEdtDesigner->AddObject(odtBmp);
            if (!pObj) return;

            int nNewObjSeq = m_pEdtDesigner->GetNewObjectSeq();
            EdObjSeq->Text = String(nNewObjSeq);

            pObj->ObjSeq      = nNewObjSeq;
            pObj->ObjKind     = OBJKIND_IMAGEID;    // "2"
            pObj->ObjType     = sObjType;
            pObj->ObjSize     = ImgDir->Picture->Bitmap->Width * ImgDir->Picture->Bitmap->Height;
            pObj->BkColorCode = m_pEdtDesigner->BkColorCode;
            pObj->Blink       = false;

            //pObj->Text    = CbVmsObjType->Text;
            pObj->Text        = sObjText;
            pObj->ImageId = "0";
            pObj->SetBitmap(ImgDir->Picture->Bitmap);

            pObj->SetPos(0, 0);
            pObj->Show();
            AddObjectToList(pObj, true);
        }
        break;
#endif
    default:
        {
            TVmsFormObject *pObj = m_pEdtDesigner->AddObject(odtText);
            if (!pObj) return;

            int nNewObjSeq = m_pEdtDesigner->GetNewObjectSeq();
            EdObjSeq->Text = String(nNewObjSeq);
            pObj->ObjSeq   = nNewObjSeq;
            pObj->ObjType  = sObjType;

            if (nObjType ==  91 || nObjType ==  92 ||
                nObjType == 501 || nObjType == 502 ||
               (nObjType >= 401 && nObjType <= 413)
               )
            {
                pObj->Tag = "";
            }
            else
            {
                pObj->Tag = "N";
            }

            pObj->TextAlign = 0;    // left
            if (nObjType == 19) //소통정보(가변)
            {
#ifdef ENG
                sObjText = "@Traffic Fast About 0 Min.";
#else
                sObjText = "@소통원활  약 0 분";
#endif
                pObj->TextAlign = 2;    // center
                EdTextData->Properties->ReadOnly = true;
            }
            else
            {
                EdTextData->Properties->ReadOnly = false;
            }

            pObj->ObjSize       = sObjText.Length();
            pObj->BkColorCode   = m_pEdtDesigner->BkColorCode;
            pObj->Blink         = false;

            pObj->Text          = sObjText;
            pObj->EditMode      = true;
            pObj->ObjKind       = OBJKIND_TEXT;
            pObj->FontName      = sFontName;
            pObj->FontNameCode  = sFontNameCode;
            pObj->FontColorCode = sFontColorCode;
            pObj->FontSize      = nFontSize;

            pObj->FontBold      = bFontBold;

            pObj->SetPos(0, 0);
            pObj->Show();
            AddObjectToList(pObj, true);
        }
        break;
    }
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::BtnObjDeleteClick(TObject *Sender)
{
    if (m_pEdtDesigner->GetSelectedObjectCount() < 1) return;

	String sMsgString;
    sMsgString  = lblText6->Caption;//"선택한 객체 정보를 모두 삭제하시겠습니까?";
    if (Application->MessageBox(sMsgString.c_str(),
                                lblText7->Caption.c_str(),//L"객체 정보 삭제",
                                MB_YESNO|MB_ICONQUESTION|MB_APPLMODAL) != IDYES)
    {
        return;
    }

    bool bUse = false;
    TVmsFormObject *pObj;
    int nObjCnt = m_pEdtDesigner->GetObjectCount();
    for (int ii = nObjCnt-1; ii >= 0; ii--)
    {
        pObj = m_pEdtDesigner->GetObject(ii);
        if (pObj->Selected)
        {
        //TODO
            //TVmsObjUse*pObjUse = NULL;//MyUseManager->FLists.Find(pObj->ObjSeq);
            //if (pObjUse)
            //{
            //    bUse = true;
            //    continue;
            //}
            m_pEdtDesigner->DelObject(ii);
        }
    }

    if (bUse)
    {
        Application->MessageBox(lblText8->Caption.c_str(),//L"VMS 폼 객체 삭제\r\nVMS 폼 객체 중 정보제공구간에 설정된 객체는 삭제할 수 없습니다.",
                                FTitle.c_str(),
                                MB_OK|MB_ICONERROR|MB_APPLMODAL);
    }

    SelObjectListData();
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::ColXGetDataText(TcxCustomGridTableItem *Sender, int ARecordIndex,
          UnicodeString &AText)
{
    if (ARecordIndex < 0) return;
    try
    {
        int nMemPtr = (int)(TvObjList->DataController->Values[ARecordIndex][ColMem->Index]);
        TVmsFormObject *pObj = (TVmsFormObject*)nMemPtr;
        if (pObj)
        {
            AText = pObj->GetLeft();
        }
    } catch(Exception &e) {}
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::ColYGetDataText(TcxCustomGridTableItem *Sender, int ARecordIndex,
          UnicodeString &AText)
{
    if (ARecordIndex < 0) return;
    try
    {
        int nMemPtr = (int)(TvObjList->DataController->Values[ARecordIndex][ColMem->Index]);
        TVmsFormObject *pObj = (TVmsFormObject*)nMemPtr;
        if (pObj)
        {
            AText = pObj->GetTop();
        }
    } catch(Exception &e) {}
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::CbVmsObjTypeClick(TObject *Sender)
{
    if (BtnAddText->CanFocus())
    {
        BtnAddText->SetFocus();
    }
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::EdIfscIdClick(TObject *Sender)
{
    if (FSelObjType == eSelObjIfsc)
    {
        TVMSM530M *pSelForm = new TVMSM530M(this);

        pSelForm->EdNmbr->Text = EdIfscId->Text.Trim();
        pSelForm->ShowModal();
        String sIfscId   = pSelForm->EdNmbr->Text.Trim();
        bool   bSelected = pSelForm->m_bSelected;
        delete pSelForm;
        pSelForm = NULL;

        if (!bSelected)
        {
            return;
        }

        if (sIfscId != "")
        {
            EdIfscId->Text = sIfscId;
        }
        UpdateObjectIfscId();
    }
    else
    if (FSelObjType == eSelObjPark)
    {
        TVMSM540M *pSelForm = new TVMSM540M(this);

        pSelForm->EdNmbr->Text = EdIfscId->Text.Trim();
        pSelForm->ShowModal();
        String sParkNmbr = pSelForm->EdNmbr->Text.Trim();
        bool   bSelected = pSelForm->m_bSelected;
        delete pSelForm;
        pSelForm = NULL;

        if (!bSelected)
        {
            return;
        }

        if (sParkNmbr != "")
        {
            EdIfscId->Text = sParkNmbr;
        }
        UpdateObjectIfscId();
    }
    else
    if (FSelObjType == eSelObjAtmp)
    {
        TVMSM550M *pSelForm = new TVMSM550M(this);

        pSelForm->EdNmbr->Text = EdIfscId->Text.Trim();
        pSelForm->ShowModal();
        String sAtmpNmbr = pSelForm->EdNmbr->Text.Trim();
        bool   bSelected = pSelForm->m_bSelected;
        delete pSelForm;
        pSelForm = NULL;

        if (!bSelected)
        {
            return;
        }

        if (sAtmpNmbr != "")
        {
            EdIfscId->Text = sAtmpNmbr;
        }
        UpdateObjectIfscId();
    }
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::BtnIfscEraseClick(TObject *Sender)
{
    EdIfscId->Text = "";
    UpdateObjectIfscId();
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::UpdateObjectIfscId()
{
    TVmsFormObject *pObj;
    int nObjCnt = m_pEdtDesigner->GetObjectCount();
    for (int ii = nObjCnt-1; ii >= 0; ii--)
    {
        pObj = m_pEdtDesigner->GetObject(ii);
        if (pObj->Selected)
        {
            if (pObj->ObjType.ToIntDef(0) ==  91 ||     //@축통행시간(고정)
                pObj->ObjType.ToIntDef(0) ==  92 ||     //@축소통상황(고정)
                pObj->ObjType.ToIntDef(0) == 501 ||     //@주차가능대수
                pObj->ObjType.ToIntDef(0) == 502 ||       //@주차혼잡도
               (pObj->ObjType.ToIntDef(0) >= 401 && pObj->ObjType.ToIntDef(0) <= 413)
               )
            {
                pObj->Tag = EdIfscId->Text.Trim();
            }
        }
    }
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::BtnCopyAddClick(TObject *Sender)
{
    int nIdx = TvList->DataController->FocusedRecordIndex;
    if (nIdx < 0) return;

	String sFormName = InputBox(lblText9->Caption,//"폼명칭",
                                lblText10->Caption,//"신규 폼명칭 입력하세요(60Byte).",
                                lblText9->Caption);//"폼명칭" );

    sFormName = sFormName.Trim();
	if (sFormName == lblText9->Caption//"폼명칭"
     || sFormName == "")
	{
		return;
	}
	if (AnsiString(sFormName).Length() > 60)
	{
        Application->MessageBox(lblText11->Caption.c_str(),//L"폼명칭은  60Byte를 초과할 수 없습니다.",
                                FTitle.c_str(),
                                MB_OK|MB_ICONERROR|MB_APPLMODAL);
		return;
	}

    String sFormId = EdFormId->Text;
    if (sFormId.IsEmpty())
    {
        Application->MessageBox(lblText12->Caption.c_str(),//L"VMS 폼 복사 추가\r\n복사 추가할 VMS 폼을 목록에서 선택하세요.",
                                FTitle.c_str(),
                                MB_OK|MB_ICONERROR|MB_APPLMODAL);
        return;
    }

    int nFormId = 0;
#if 0
    if (!GetNextVmsFormId(nFormId))
    {
        Application->MessageBox(lblText1->Caption.c_str(),//L"새로운 VMS 폼정보를 생성하지 못하였습니다.\r\n프로그램 종료후에 다시 시도해 보세요.",
                                FTitle.c_str(),
                                MB_OK|MB_ICONERROR|MB_APPLMODAL);
        return;
    }
#endif
    if (CopyFormAdd(sFormId, String(nFormId), sFormName))
    {
        Application->MessageBox(lblText13->Caption.c_str(),//L"VMS 폼 복사 추가\r\nVMS 폼 정보를 복사 추가 하였습니다.",
                                FTitle.c_str(),
                                MB_OK|MB_ICONINFORMATION|MB_APPLMODAL);

        FUpdate = true;

        LoadVmsForm();
        CMM_SetGridRow(CxList, TvList, String(nFormId), Col01->Index);
        DisplayInfo();

        //POST_MSG(Application->MainForm->Handle, WM_DATABASE_REFRESH, WP_MSG_14, 0);

        //CComm_VmsFormUpdate();
    }
}
//---------------------------------------------------------------------------

bool __fastcall TFrmVmsFormEdit::CopyFormAdd(String AOrgFormId, String ANewFormId, String AFormName)
{
    bool result = false;
    String resultVal;
    String key = "abcdefg1234567890x";
    String apiUri = g_AppCfg.sRestApiUri + "/cs-api/vms/form/manage/copy/" + key + "/" + AOrgFormId;
    TMcJsonItem *ObjList = new TMcJsonItem();
    try {
        ObjList->Add("vms_form_id")->AsInteger = AOrgFormId.ToIntDef(0);
        ObjList->Add("vms_form_nm")->AsString = AFormName;
        result = TRestObjectManager::RequestPost(apiUri, ObjList->AsJSON, resultVal);
        if (!result) {
            return false;
        }

    } __finally {
        if (ObjList) delete ObjList;
    }

    return result;
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::BtnUpClick(TObject *Sender)
{
    try
    {
        TvObjList->BeginUpdate();

        int nCurIdx = TvObjList->DataController->FocusedRowIndex;//FocusedRecordIndex;
        if (nCurIdx <= 0)
        {
            return;
        }

        int nUpIdx = nCurIdx-1;

        try
        {
            String sVal1 = VarToStr(TvObjList->DataController->Values[nCurIdx][ColSeq->Index]);
            String sVal2 = VarToStr(TvObjList->DataController->Values[nCurIdx][ColId->Index]);
            String sVal3 = VarToStr(TvObjList->DataController->Values[nCurIdx][ColType->Index]);
            String sVal4 = VarToStr(TvObjList->DataController->Values[nCurIdx][ColData->Index]);
            String sVal5 = VarToStr(TvObjList->DataController->Values[nCurIdx][ColIfscId->Index]);
            int    sVal6 = (TvObjList->DataController->Values[nCurIdx][ColMem->Index]);

            TvObjList->DataController->Values[nCurIdx][ColSeq->Index]    = TvObjList->DataController->Values[nUpIdx][ColSeq->Index];
            TvObjList->DataController->Values[nCurIdx][ColId->Index]     = TvObjList->DataController->Values[nUpIdx][ColId->Index];
            TvObjList->DataController->Values[nCurIdx][ColType->Index]   = TvObjList->DataController->Values[nUpIdx][ColType->Index];
            TvObjList->DataController->Values[nCurIdx][ColData->Index]   = TvObjList->DataController->Values[nUpIdx][ColData->Index];
            TvObjList->DataController->Values[nCurIdx][ColIfscId->Index] = TvObjList->DataController->Values[nUpIdx][ColIfscId->Index];
            TvObjList->DataController->Values[nCurIdx][ColMem->Index]    = TvObjList->DataController->Values[nUpIdx][ColMem->Index];

            TvObjList->DataController->Values[nUpIdx][ColSeq->Index]    = sVal1;
            TvObjList->DataController->Values[nUpIdx][ColId->Index]     = sVal2;
            TvObjList->DataController->Values[nUpIdx][ColType->Index]   = sVal3;
            TvObjList->DataController->Values[nUpIdx][ColData->Index]   = sVal4;
            TvObjList->DataController->Values[nUpIdx][ColIfscId->Index] = sVal5;
            TvObjList->DataController->Values[nUpIdx][ColMem->Index]    = sVal6;

            TvObjList->Controller->ClearSelection();
            TvObjList->Controller->FocusedRowIndex = nUpIdx;
            //TvObjList->Controller->FocusedRecordIndex = nUpIdx;
            TvObjList->ViewData->Records[nUpIdx]->Focused = true;
            TvObjList->ViewData->Records[nUpIdx]->Selected = true;
            CxObjList->SetFocus();
            //TcxCustomGridRow* ARow = TvObjList->ViewData->Rows[TvObjList->DataController->FocusedRowIndex];
        }
        catch(...)
        {
        }
    }
    __finally
    {
        TvObjList->EndUpdate();
    }
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::BtnDownClick(TObject *Sender)
{
    try
    {
        TvObjList->BeginUpdate();

        int nCurIdx = TvObjList->DataController->FocusedRowIndex;//FocusedRecordIndex;
        //int nCurIdx = TvObjList->DataController->FocusedRecordIndex;
        if (nCurIdx < 0)
        {
            return;
        }
        if (nCurIdx == TvObjList->DataController->RecordCount-1)
        {
            return;
        }

        int nDnIdx = nCurIdx+1;

        try
        {
            String sVal1 = VarToStr(TvObjList->DataController->Values[nCurIdx][ColSeq->Index]);
            String sVal2 = VarToStr(TvObjList->DataController->Values[nCurIdx][ColId->Index]);
            String sVal3 = VarToStr(TvObjList->DataController->Values[nCurIdx][ColType->Index]);
            String sVal4 = VarToStr(TvObjList->DataController->Values[nCurIdx][ColData->Index]);
            String sVal5 = VarToStr(TvObjList->DataController->Values[nCurIdx][ColIfscId->Index]);
            int    sVal6 = (TvObjList->DataController->Values[nCurIdx][ColMem->Index]);

            TvObjList->DataController->Values[nCurIdx][ColSeq->Index]    = TvObjList->DataController->Values[nDnIdx][ColSeq->Index];
            TvObjList->DataController->Values[nCurIdx][ColId->Index]     = TvObjList->DataController->Values[nDnIdx][ColId->Index];
            TvObjList->DataController->Values[nCurIdx][ColType->Index]   = TvObjList->DataController->Values[nDnIdx][ColType->Index];
            TvObjList->DataController->Values[nCurIdx][ColData->Index]   = TvObjList->DataController->Values[nDnIdx][ColData->Index];
            TvObjList->DataController->Values[nCurIdx][ColIfscId->Index] = TvObjList->DataController->Values[nDnIdx][ColIfscId->Index];
            TvObjList->DataController->Values[nCurIdx][ColMem->Index]    = TvObjList->DataController->Values[nDnIdx][ColMem->Index];

            TvObjList->DataController->Values[nDnIdx][ColSeq->Index]    = sVal1;
            TvObjList->DataController->Values[nDnIdx][ColId->Index]     = sVal2;
            TvObjList->DataController->Values[nDnIdx][ColType->Index]   = sVal3;
            TvObjList->DataController->Values[nDnIdx][ColData->Index]   = sVal4;
            TvObjList->DataController->Values[nDnIdx][ColIfscId->Index] = sVal5;
            TvObjList->DataController->Values[nDnIdx][ColMem->Index]    = sVal6;

            TvObjList->Controller->ClearSelection();
            TvObjList->Controller->FocusedRowIndex = nDnIdx;
            //TvObjList->Controller->FocusedRecordIndex = nDnIdx;
            TvObjList->ViewData->Records[nDnIdx]->Focused = true;
            TvObjList->ViewData->Records[nDnIdx]->Selected = true;
            CxObjList->SetFocus();
            //TcxCustomGridRow* ARow = TvObjList->ViewData->Rows[TvObjList->DataController->FocusedRowIndex];
        }
        catch(...)
        {
        }
    }
    __finally
    {
        TvObjList->EndUpdate();
    }
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::BtnSaveClick(TObject *Sender)
{
	if (EdFormId->Text.IsEmpty())
	{
        Application->MessageBox(lblText14->Caption.c_str(),//L"VMS 폼 저장\r\nVMS 폼 ID를 입력하세요.",
                                FTitle.c_str(),
                                MB_OK|MB_ICONERROR|MB_APPLMODAL);
		return;
	}
	if (EdFormName->Text.Trim().IsEmpty())
	{
        Application->MessageBox(lblText15->Caption.c_str(),//L"VMS 폼 저장\r\nVMS 폼 이름을 입력하세요.",
                                FTitle.c_str(),
                                MB_OK|MB_ICONERROR|MB_APPLMODAL);
		return;
	}

    int                    nObjType;
    TVmsFormObject        *pObj;
    TcxGridDataController *pGDC = TvObjList->DataController;
    int                    nObjCnt = pGDC->RecordCount;

    String sFormId    = EdFormId->Text;
    //String sVmsType   = FVmsTypeCd;
    String sFormType  = APP_GetCode(CbFormKind);
    String sFormColor = String(CbFormColor->ItemIndex);
    String sName      = EdFormName->Text.Trim();
    String sExpl      = EdFormDesc->Text.Trim();
    String sDispDrct  = APP_GetCode(CbFormDsplDrct);
    String sDispMode  = APP_GetCode(CbFormDsplMthd);
    String sVALID_YN  = "Y";

    if (   sFormType == String(eFormtp_figure)
        || sFormType == String(eFormTp_atmp)
        || sFormType == String(eFormTp_park)
       )
    {
        for (int ii = 0; ii < nObjCnt; ii++)
        {
            String sObjSeq = VarToStr(pGDC->Values[ii][ColSeq->Index]);
            pObj = m_pEdtDesigner->FindObject(sObjSeq.ToInt());
            if (!pObj) continue;

            String sObjId = pObj->Tag;
            nObjType = pObj->ObjType.ToIntDef(0);
            if (nObjType ==  91 || nObjType ==  92)
            {
                //@축통행시간(고정), @축소통상황(고정)
                TVmsIfsc *pIfscObj = VmsIfscManager->Find(sObjId);
                if (!pIfscObj)
                {
                    sVALID_YN = "N";
                    break;
                }
            }
            if (nObjType == 501 || nObjType == 502)
            {
                //@주차가능대수, @주차혼잡도
                TCDSPark *pParkObj = CDSParkManager->FLists.Find(sObjId);
                if (!pParkObj)
                {
                    sVALID_YN = "N";
                    break;
                }
            }
            if (pObj->ObjType.ToIntDef(0) >= 401 && pObj->ObjType.ToIntDef(0) <= 413)
            {
                //대기환경 관측소
                TCDSAtmp *pAtmpObj = CDSAtmpManager->FLists.Find(sObjId);
                if (pAtmpObj)
                {
                    if (pAtmpObj->DEL_YN == "Y")
                    {
                        sVALID_YN = "N";
                        break;
                    }
                }
                else
                {
                    sVALID_YN = "N";
                    break;
                }
            }
        }
    }
    if (sVALID_YN != "Y")
    {
        String sMsg;
        sMsg  = " \r\n";
        sMsg += "<<< VMS 폼 객체 중에 설정되지 않은 정보가 있습니다. >>>\r\n";
        sMsg += "  *** VMS 스케쥴 설정화면에 표출되지 않습니다.\r\n";
        sMsg += "  *** VMS 스케쥴 목록에 이미 등록되어 있는 경우 VMS 메시지가 표출되지 않습니다.\r\n";
        sMsg += " VMS 폼 정보를 저장 하시겠습니까?";
        sMsg += " \r\n";
        if (Application->MessageBox(sMsg.c_str(), L"VMS 폼 유효성 확인", MB_YESNO|MB_ICONQUESTION|MB_APPLMODAL) != IDYES) return;
    }

    bool bResult = false;


    m_pEdtDesigner->GetVmsFormImage(ImgForm);
    bResult = SaveVmsForm(sVALID_YN);

    if (!bResult) return;
    if (bResult)
    {
        Application->MessageBox(lblText16->Caption.c_str(),//L"VMS 폼 정보 저장\r\nVMS 폼 정보를 저장 하였습니다.",
                                FTitle.c_str(),
                                MB_OK|MB_ICONINFORMATION|MB_APPLMODAL);

        FUpdate = true;

        LoadVmsForm();
        CMM_SetGridRow(CxList, TvList, sFormId, Col01->Index);
        DisplayInfo();

        //POST_MSG(Application->MainForm->Handle, WM_DATABASE_REFRESH, WP_MSG_14, 0);

        //CComm_VmsFormUpdate();
    }

    //ReForm->Lines->Clear();
    //ReFormTemp->Lines->Clear();
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::Cb99PropertiesChange(TObject *Sender)
{
    if (m_bEdit) return;
#if 1
    String sFormType  = APP_GetCode(CbFormKind);
    if (sFormType == "15")
    {
        String sFillIn = APP_GetCode(Cb99);
        if (sFillIn == "") sFillIn = "N";

        TVmsFormObject *pObj = m_pEdtDesigner->FindObject(EdObjSeq->Text.ToIntDef(-1), false);
        if (pObj)
        {
            int nObjType = pObj->ObjType.ToIntDef(-1);
            if (nObjType == 0 || nObjType == 1 || nObjType == 2)
            {
                pObj->Tag = sFillIn;
            }
        }
    }
#endif
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::CheckImageSelected()
{
#ifdef IMAGE_RESIZE
    bool selImage = false;
    int  nImgW = 0;
    int  nImgH = 0;

    int nObjCnt = m_pEdtDesigner->GetObjectCount();
    for(int ii = 0; ii < nObjCnt; ii++)
    {
        TVmsFormObject *pObj = m_pEdtDesigner->GetObject(ii);
        if (!pObj) continue;
        if (!pObj->Selected) continue;

#if 0
        if (pObj->ObjType.ToIntDef(0) == 1 || pObj->ObjType.ToIntDef(0) == 2)
        {
            selImage = true;
            nImgW = pObj->GetWidth();
            nImgH = pObj->GetHeight();
        }
        else
        {
            selImage = false;
            break;
        }
#else
        switch(pObj->ObjType.ToIntDef(0))
        {
        case   1: //심볼
        case   2: //이미지
        case   3: //소통정보배경이미지
        case  17: //소통정보이미지1
        case  27: //소통정보이미지2
        case  37: //소통정보이미지3
        case  47: //소통정보이미지4
        case 167: //@우회소통정보이미지
        case 200: //동영상이미지
        case 300: //스트리밍영상이미지
        case 406: //@통합대기등급 이미지
        case 407: //@미세먼지등급 이미지
        case 408: //@초미세먼지등급 이미지
        case 413: //@오존등급이미지
            selImage = true;
            nImgW = pObj->GetWidth();
            nImgH = pObj->GetHeight();
            break;
        default:
            selImage = false;
            break;
        }
        if (selImage == false)
        {
            break;
        }
#endif
    }
    if (selImage)
    {
        TNotifyEvent evtW = SeImgW->Properties->OnChange;
        TNotifyEvent evtH = SeImgH->Properties->OnChange;
        SeImgW->Properties->OnChange = NULL;
        SeImgH->Properties->OnChange = NULL;

        SeImgW->Value = nImgW;
        SeImgH->Value = nImgH;

        SeImgW->Properties->OnChange = evtW;
        SeImgH->Properties->OnChange = evtH;

        PnlImage->Visible = true;
    }
    else
    {
        PnlImage->Visible = false;
    }
#endif
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::SeImgWHPropertiesChange(TObject *Sender)
{
    if (m_bEdit) return;
    if (((TcxSpinEdit*)Sender)->Value < ((TcxSpinEdit*)Sender)->Properties->MinValue)
        ((TcxSpinEdit*)Sender)->Value = ((TcxSpinEdit*)Sender)->Properties->MinValue;
    else if(((TcxSpinEdit*)Sender)->Value > ((TcxSpinEdit*)Sender)->Properties->MaxValue &&
        ((TcxSpinEdit*)Sender)->Properties->MaxValue)
        ((TcxSpinEdit*)Sender)->Value = ((TcxSpinEdit*)Sender)->Properties->MaxValue;

#ifdef IMAGE_RESIZE
    int nImgW = SeImgW->Value;
    int nImgH = SeImgH->Value;

    int nObjCnt = m_pEdtDesigner->GetObjectCount();
    for(int ii = 0; ii < nObjCnt; ii++)
    {
        TVmsFormObject *pObj = m_pEdtDesigner->GetObject(ii);
        if (!pObj) continue;
        if (!pObj->Selected) continue;

#if 0
        if (pObj->ObjType.ToIntDef(0) == 1 || pObj->ObjType.ToIntDef(0) == 2)
        {
            pObj->GetImage()->AutoSize= false;
            pObj->GetImage()->Stretch = true;
            pObj->GetImage()->Width  = nImgW;
            pObj->GetImage()->Height = nImgH;
            pObj->SetSize(nImgW, nImgH);
        }
#else
        switch(pObj->ObjType.ToIntDef(0))
        {
        case   1: //심볼
        case   2: //이미지
        case   3: //소통정보배경이미지
        case  17: //소통정보이미지1
        case  27: //소통정보이미지2
        case  37: //소통정보이미지3
        case  47: //소통정보이미지4
        case 167: //@우회소통정보이미지
        case 200: //동영상이미지
        case 300: //스트리밍영상이미지
        case 406: //@통합대기등급 이미지
        case 407: //@미세먼지등급 이미지
        case 408: //@초미세먼지등급 이미지
        case 413: //@오존등급이미지
            pObj->GetImage()->AutoSize= false;
            pObj->GetImage()->Stretch = true;
            pObj->GetImage()->Width  = nImgW;
            pObj->GetImage()->Height = nImgH;
            pObj->SetSize(nImgW, nImgH);
            break;
        default:
            break;
        }
#endif
    }
#endif
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::PgEditClick(TObject *Sender)
{
    try
    {
        if (PgEdit->Properties->ActivePage == TsDirect)
        {
            if (ReForm->Enabled) ReForm->SetFocus();
        }
    }
    catch(Exception &e)
    {
    }
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::BtrnReFormClearClick(TObject *Sender)
{
    ReForm->Lines->Clear();
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::TvListDataControllerFilterChanged(TObject *Sender)
{
    CMM_SetFilterLike(TvList);
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsFormEdit::BtnRedClick(TObject *Sender)
{
    TcxButton *pClrBtn = (TcxButton*)Sender;
    switch(pClrBtn->Tag)
    {
        case 0 : ReForm->SelAttributes->Color = clLime;     break;
        case 1 : ReForm->SelAttributes->Color = clYellow;   break;
        case 2 : ReForm->SelAttributes->Color = clRed;      break;
    }
}
//---------------------------------------------------------------------------
#include <registry.hpp>
bool __fastcall TFrmVmsFormEdit::UpdateRegistry()
{
    return true;

	//HKEY   hKey       = HKEY_CURRENT_USER;
	HKEY   hKey       = HKEY_LOCAL_MACHINE;
    String sChromeKey = "SOFTWARE\\Policies\\Google\\Chrome";
    String sEdgeKey   = "SOFTWARE\\Policies\\Microsoft\\Edge";
    //String sChromeKey = "SOFTWARE\\Wow6432Node\\Policies\\Google\\Chrome";
    //String sEdgeKey   = "SOFTWARE\\Wow6432Node\\Policies\\Microsoft\\Edge";

    UpdatePoliciesRegistry(hKey, sChromeKey);
    UpdatePoliciesRegistry(hKey, sEdgeKey);
    return true;
}
//---------------------------------------------------------------------------
bool __fastcall TFrmVmsFormEdit::UpdatePoliciesRegistry(HKEY AHKey, String AValueKey)
{
    String APP_NAME   = "its.vmsformedit";
    String ITEM_NAME  = "AutoLaunchProtocolsFromOrigins";
    String ITEM_VALUE = "{\"allowed_origins\": [\"*\"], \"protocol\": \"its.vmsformedit\"}";

    TRegistry *reg = new TRegistry(KEY_WRITE);
    //TRegistry *reg = new TRegistry(KEY_READ|KEY_WRITE|KEY_WOW64_64KEY);
    //TRegistry *reg = new TRegistry(KEY_ALL_ACCESS && KEY_WOW64_64KEY);
    if (reg == NULL) return false;

    reg->RootKey = AHKey;
    try {
        try {
            if (!reg->KeyExists(AValueKey))
            {
                reg->Access = KEY_SET_VALUE;
                if (reg->CreateKey(AValueKey)) {
                    reg->Access = KEY_WRITE;
                    if (reg->OpenKey(AValueKey, true))
                    {
                        reg->WriteString(ITEM_NAME, "[" + ITEM_VALUE + "]");
                        reg->CloseKey();
                    }
                }
            } else {
                if (reg->OpenKeyReadOnly(AValueKey)) {
                    String value = reg->ReadString(ITEM_NAME);
                    reg->CloseKey();
                    value = value.Trim();
                    value = StringReplace(value, " ",  "",  TReplaceFlags() << rfReplaceAll);
                    value = StringReplace(value, "[{", "{", TReplaceFlags() << rfReplaceAll);
                    value = StringReplace(value, "}]", "}", TReplaceFlags() << rfReplaceAll);
                    if (!value.Pos(APP_NAME)) {
                        String newValue = "";
                        if (value == "") {
                            newValue = "[" + ITEM_VALUE + "]";
                        }
                        else {
                            newValue = "[" + value + ", " + ITEM_VALUE + "]";
                        }
                        reg->Access = KEY_WRITE;
                        if (reg->OpenKey(AValueKey, true))
                        {
                            reg->WriteString(ITEM_NAME, newValue);
                            reg->CloseKey();
                        }
                    }
                }
            }
        }
        catch(Exception &e) {
        }
    }
    __finally {
         if (reg) {
            reg->Free();
         }
    }
    return true;
}
//---------------------------------------------------------------------------

