

//[2009.11.20.금][생성!!!]{----------------------
//<find_DialogBox_Form> 을 가지고 새로 생성한다.
//}----------------------------------------------


#include <vcl.h>
#pragma hdrstop

#include "gmrcbasicMake_DialogBox.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TgmrcbasicMake_DialogBox_Form *gmrcbasicMake_DialogBox_Form;
//---------------------------------------------------------------------------


#include "main.h"
#include "ide_main.h"
#include "ide_library.h"
#include "ide_msgbox.h"
#include "gui.h"
#include "editor_edit.h"
#include "ide_BalloonBox.h"

//[2009.12.05.토][추가!!!]
#include "matdol.h"
#include "comport.h"
#include "combus.h"

//[2009.12.07.월][추가!!!]
#include "file.h"

//[2010.04.03.토][추가!!!]
#include "ide_editor.h"


//------------------------------------------------------------------------------
//[서브클래싱]------------------------------------------------------------------
//------------------------------------------------------------------------------

void __fastcall TgmrcbasicMake_DialogBox_Form::WndProc(Messages::TMessage  &Message)
{
  //[설명!!!]{--------------------------------------------------------------------
  //TForm 의 경우는 바탕을 칠하고 OnPaint() 를 발생하게 되므로 실제 _Draw() 를
  //OnPaint() 에서 사용하는 경우는 크기가 변경되는 경우 바로 칠해지지 않아서
  //하얀색 바탕이 그대로 나오게 되어 보기 좋지 않게 된다.
  //따라서 TForm 자체의 바탕을 그리는 WM_ERASEBKGND 에서 바로 _Draw() 를 사용하여
  //그리고 OnPaint() 는 처리하지 않는다.
  //C++Builder 와 같이 완벽하게 처리되는 깜박임이 전혀 없는 화면을 만들수 있다.
  //}-----------------------------------------------------------------------------

  if(Message.Msg == WM_ERASEBKGND)
  {
    _Draw();

    //바로 죵료하지 않으면 WM_ERASEBKGND 메세지가 다음 TForm::WndProc(Message); 에서
    //다시 처리 되어 TForm->Color 로 칠해지게 되어 _Draw() 로 그린 것이 다 지워지므로
    //바로 종료한다.
    return;

  }

  //[기본처리]
  //{
      //기본 메세지는 반드시 처리 되어야 한다.
      TForm::WndProc(Message);
  //}

  return;

}

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

__fastcall TgmrcbasicMake_DialogBox_Form::TgmrcbasicMake_DialogBox_Form(TComponent* Owner)
        : TForm(Owner)
{
  //[VAR]
  //{
      AnsiString  bmp_path;
      int         width, height;

      TRect       colorBoxTRect;
      int         w, h;

      int         i;

      //[2009.11.20.금][추가!!!]
      char        tempWord[OPT_wordStrSize];

  //}

  //[환경변수]
  //{
      //[2007.10.02.화][추가!!!]
      IDE_Get_Option(&_ide_option);

  //}

  //[초기화]
  //{
      //--------------------------------------------------------------------------
      //크기는 표시되는 내용에 따라 자동으로 처리 되지만 일단 임의 값을 기록한다.
      this->Left     = 0;
      this->Top      = 0;
      this->Width    = 505;
      this->Height   = 168;//146;
      this->Color    = clWhite;

      //실제 그림 영역을 생성한다.
      _bmp_ = new Graphics::TBitmap;

      //그림 영역 크기 설정.
      _bmp_->Width       = this->Width;
      _bmp_->Height      = this->Height;

      //24bit bitmap 으로 지정한다.
      _bmp_->PixelFormat = pf24bit;
      //--------------------------------------------------------------------------
  //}

  //[글꼴 설정]
  //{
      //[기본 끌꼴 등록]{------------------------------------------------
      //모든 프로그램에서 기본적으로 사용하는 [system 글꼴] 을 등록한다.
      FONTPACK_SetDefault(&_font);
      //}----------------------------------------------------------------

      //[editor debug margin]
      //{
          _font.margin_size = 0;

      //}

      //문자 margin 을 설정한다.
      _font.offset_left   = 0;
      _font.offset_right  = 0;
      _font.offset_top    = 0;
      _font.offset_bottom = 0;

      //[2010.01.26.화][추가!!!]{---
      _font.en_offset_left  = 0;
      _font.en_offset_right = 0;
      //}---------------------------

  //}

  //[속성초기화]
  //{
      //기본적으로 선택되지 않은 상태.
      _caption_selected = false;

  //}

  //[caption 설정]
  //{
      //caption 문자열.(크게 바뀔일이 없다.)
      STR_Assign(_caption, " G.M.RC.BASiC 자동 제작기 ");

      //높이 지정.
      _caption_height = 22;

      //caption 문자열의 width 를 구한다.
      FONT_Get_StringOutAreaInfo(&_font, d_FONTSTYLE_default, _caption, &width, &height);

      //실제 사용할 caption 폭을 설정한다.
      //_font.margin_size 는 처음 기본값인 0 을 사용한다.(한번만 그려주면 된다.)
      _caption_width = width + (_font.margin_size * 2) + 2;

  //}

  //[기본 부품들]
  //{
      //[닫기 버튼]
      //{
          _close_bmpbtns          = new Tgui_bmpbutton_Form(this);
          _close_bmpbtns->Parent  = this;
          _close_bmpbtns->Visible = true;

          //[초기화]
          //{
              //그림 할당하기.
              bmp_path = ExtractFilePath(Application->ExeName) + "sysbmp\\control\\close.bmp";

              _close_bmpbtns->_Top(0);
              _close_bmpbtns->_Width(12);
              _close_bmpbtns->_Left(0);
              _close_bmpbtns->_Height(12);
              _close_bmpbtns->_Border(true);
              _close_bmpbtns->_Bitmap(bmp_path);
              _close_bmpbtns->_Image_Width(12);
              _close_bmpbtns->_Image_Height(12);

              //동작함수 등록.
              _close_bmpbtns->_EVENT_Click = _EVENT_CloseButton_Click;

          //}

      //}

  //}

  //[내부 부품들]
  //{
      //[제작 버튼]
      //{
          _make_Btn          = new Tgui_button_Form(this);
          _make_Btn->Parent  = this;
          _make_Btn->Visible = true;

          _make_Btn->_Top(26);
          _make_Btn->_Left(8);
          _make_Btn->_Width(200);
          _make_Btn->_Height(20);
          //_make_Btn->_FontColor(_ide_option->color_0);
          _make_Btn->_Caption("G.M.RC.BASiC 영혼 불어넣기");

          _make_Btn->_EVENT_Click = _EVENT_Click_make_Btn;

          //[풍선 도움말 설정]
          //{
              _make_Btn->_BalloonHelpUse(true);
              _make_Btn->_BalloonHelpStr
              ("ATmega88(20Mhz)로 G.M.RC.BASiC을 자동 제작합니다.\r\n"
               "먼저 맷돌(G.MTDL.A)과 ATmega88을 회로도 대로 연결하고\r\n"
               "이 버튼을 누르면 모든 과정이 자동으로 진행됩니다."
              );

          //}

      //}

      //[포트 설정]
      //{
          //[바탕판]
          //{
              _portBase_Label          = new Tgui_Label_Form(this);
              _portBase_Label->Parent  = this;
              _portBase_Label->Visible = true;

              _portBase_Label->_Left(_make_Btn->Left);
              _portBase_Label->_Top(_make_Btn->Top + _make_Btn->Height + 4);
              _portBase_Label->_Width(_make_Btn->Width);
              _portBase_Label->_Height(64);

              _portBase_Label->_FontColor(_ide_option->color_0);
              _portBase_Label->_Caption("");
              _portBase_Label->_Border(true);

              //_portBase_Label->_FontStyle(d_FONTSTYLE_bold);

          //}

          //[포트번호]
          //{
              //[제목]
              //{
                  _portNum_Label          = new Tgui_Label_Form(this);
                  _portNum_Label->Parent  = this;
                  _portNum_Label->Visible = true;

                  _portNum_Label->_Left(_portBase_Label->Left + 4);
                  _portNum_Label->_Top(_portBase_Label->Top + 4);
                  _portNum_Label->_Width(108);
                  _portNum_Label->_Height(16);
                  _portNum_Label->_FontColor(_ide_option->color_0);
                  _portNum_Label->_Caption("맷돌 포트 번호:P");
                  _portNum_Label->_Border(false);

                  //_portNum_Label->_FontStyle(d_FONTSTYLE_bold);

              //}

              //[버튼]
              //{
                  _portNum_Btn          = new Tgui_button_Form(this);
                  _portNum_Btn->Parent  = this;
                  _portNum_Btn->Visible = true;

                  _portNum_Btn->_Top(_portNum_Label->Top);
                  _portNum_Btn->_Left(_portNum_Label->Left + _portNum_Label->Width - 1);
                  _portNum_Btn->_Width(14);
                  _portNum_Btn->_Height(16);
                  //_portNum_Btn->_FontColor(_ide_option->color_0);
                  _portNum_Btn->_Caption("2");

                  _portNum_Btn->_EVENT_Click = _EVENT_Click_portNum_Btn;

                  //[풍선 도움말 설정]
                  //{
                      _portNum_Btn->_BalloonHelpUse(true);
                      _portNum_Btn->_BalloonHelpStr
                      ("ISP 에 사용되는 SPI 포트를 생성할 맷돌의 포트 번호를 설정합니다."
                      );

                  //}

              //}

          //}

          //[MISO 비트 번호]
          //{
              //[제목]
              //{
                  _portMiso_Label          = new Tgui_Label_Form(this);
                  _portMiso_Label->Parent  = this;
                  _portMiso_Label->Visible = true;

                  _portMiso_Label->_Left(_portNum_Label->Left);
                  _portMiso_Label->_Top(_portNum_Label->Top + _portNum_Label->Height + 4);
                  _portMiso_Label->_Width(65);
                  _portMiso_Label->_Height(16);
                  _portMiso_Label->_FontColor(_ide_option->color_0);
                  _portMiso_Label->_Caption("MISO:P2.");
                  _portMiso_Label->_Border(false);

                  //_portMiso_Label->_FontStyle(d_FONTSTYLE_bold);

              //}

              //[버튼]
              //{
                  _portMiso_Btn          = new Tgui_button_Form(this);
                  _portMiso_Btn->Parent  = this;
                  _portMiso_Btn->Visible = true;

                  _portMiso_Btn->_Top(_portMiso_Label->Top);
                  _portMiso_Btn->_Left(_portMiso_Label->Left + _portMiso_Label->Width + 1);
                  _portMiso_Btn->_Width(14);
                  _portMiso_Btn->_Height(16);
                  //_portMiso_Btn->_FontColor(_ide_option->color_0);
                  _portMiso_Btn->_Caption("7");

                  _portMiso_Btn->_EVENT_Click = _EVENT_Click_portMiso_Btn;

                  //[풍선 도움말 설정]
                  //{
                      _portMiso_Btn->_BalloonHelpUse(true);
                      _portMiso_Btn->_BalloonHelpStr
                      ("ISP 에 사용되는 SPI 포트의 MISO 비트 번호를 설정합니다."
                      );

                  //}

              //}

          //}

          //[MOSI 비트 번호]
          //{
              //[제목]
              //{
                  _portMosi_Label          = new Tgui_Label_Form(this);
                  _portMosi_Label->Parent  = this;
                  _portMosi_Label->Visible = true;

                  _portMosi_Label->_Left(_portMiso_Btn->Left + _portMiso_Btn->Width + 32);
                  _portMosi_Label->_Top(_portMiso_Btn->Top);
                  _portMosi_Label->_Width(65);
                  _portMosi_Label->_Height(16);
                  _portMosi_Label->_FontColor(_ide_option->color_0);
                  _portMosi_Label->_Caption("MOSI:P2.");
                  _portMosi_Label->_Border(false);

                  //_portMosi_Label->_FontStyle(d_FONTSTYLE_bold);

              //}

              //[버튼]
              //{
                  _portMosi_Btn          = new Tgui_button_Form(this);
                  _portMosi_Btn->Parent  = this;
                  _portMosi_Btn->Visible = true;

                  _portMosi_Btn->_Top(_portMosi_Label->Top);
                  _portMosi_Btn->_Left(_portMosi_Label->Left + _portMosi_Label->Width + 1);
                  _portMosi_Btn->_Width(14);
                  _portMosi_Btn->_Height(16);
                  //_portMosi_Btn->_FontColor(_ide_option->color_0);
                  _portMosi_Btn->_Caption("6");

                  _portMosi_Btn->_EVENT_Click = _EVENT_Click_portMosi_Btn;

                  //[풍선 도움말 설정]
                  //{
                      _portMosi_Btn->_BalloonHelpUse(true);
                      _portMosi_Btn->_BalloonHelpStr
                      ("ISP 에 사용되는 SPI 포트의 MOSI 비트 번호를 설정합니다."
                      );

                  //}

              //}

          //}

          //[SCK 비트 번호]
          //{
              //[제목]
              //{
                  _portSck_Label          = new Tgui_Label_Form(this);
                  _portSck_Label->Parent  = this;
                  _portSck_Label->Visible = true;

                  _portSck_Label->_Left(_portMiso_Label->Left);
                  _portSck_Label->_Top(_portMiso_Label->Top + _portMiso_Label->Height + 4);
                  _portSck_Label->_Width(65);
                  _portSck_Label->_Height(16);
                  _portSck_Label->_FontColor(_ide_option->color_0);
                  _portSck_Label->_Caption("SCK :P2.");
                  _portSck_Label->_Border(false);

                  //_portSck_Label->_FontStyle(d_FONTSTYLE_bold);

              //}

              //[버튼]
              //{
                  _portSck_Btn          = new Tgui_button_Form(this);
                  _portSck_Btn->Parent  = this;
                  _portSck_Btn->Visible = true;

                  _portSck_Btn->_Top(_portSck_Label->Top);
                  _portSck_Btn->_Left(_portSck_Label->Left + _portSck_Label->Width + 1);
                  _portSck_Btn->_Width(14);
                  _portSck_Btn->_Height(16);
                  //_portSck_Btn->_FontColor(_ide_option->color_0);
                  _portSck_Btn->_Caption("5");

                  _portSck_Btn->_EVENT_Click = _EVENT_Click_portSck_Btn;

                  //[풍선 도움말 설정]
                  //{
                      _portSck_Btn->_BalloonHelpUse(true);
                      _portSck_Btn->_BalloonHelpStr
                      ("ISP 에 사용되는 SPI 포트의 SCK 비트 번호를 설정합니다."
                      );

                  //}

              //}

          //}

          //[RST 비트 번호]
          //{
              //[제목]
              //{
                  _portRst_Label          = new Tgui_Label_Form(this);
                  _portRst_Label->Parent  = this;
                  _portRst_Label->Visible = true;

                  _portRst_Label->_Left(_portMosi_Label->Left);
                  _portRst_Label->_Top(_portMosi_Label->Top + _portMosi_Label->Height + 4);
                  _portRst_Label->_Width(65);
                  _portRst_Label->_Height(16);
                  _portRst_Label->_FontColor(_ide_option->color_0);
                  _portRst_Label->_Caption("RST :P2.");
                  _portRst_Label->_Border(false);

                  //_portRst_Label->_FontStyle(d_FONTSTYLE_bold);

              //}

              //[버튼]
              //{
                  _portRst_Btn          = new Tgui_button_Form(this);
                  _portRst_Btn->Parent  = this;
                  _portRst_Btn->Visible = true;

                  _portRst_Btn->_Top(_portRst_Label->Top);
                  _portRst_Btn->_Left(_portRst_Label->Left + _portRst_Label->Width + 1);
                  _portRst_Btn->_Width(14);
                  _portRst_Btn->_Height(16);
                  //_portRst_Btn->_FontColor(_ide_option->color_0);
                  _portRst_Btn->_Caption("4");

                  _portRst_Btn->_EVENT_Click = _EVENT_Click_portRst_Btn;

                  //[풍선 도움말 설정]
                  //{
                      _portRst_Btn->_BalloonHelpUse(true);
                      _portRst_Btn->_BalloonHelpStr
                      ("ISP 용 RST 비트 번호를 설정합니다."
                      );

                  //}

              //}

          //}

      //}

      //[회로도 보기 버튼]
      //{
          _circuit_Btn          = new Tgui_button_Form(this);
          _circuit_Btn->Parent  = this;
          _circuit_Btn->Visible = true;

          _circuit_Btn->_Top(_portBase_Label->Top + _portBase_Label->Height + 4);
          _circuit_Btn->_Left(8);
          _circuit_Btn->_Width(_make_Btn->Width);
          _circuit_Btn->_Height(20);
          //_circuit_Btn->_FontColor(_ide_option->color_0);
          _circuit_Btn->_Caption("연결 회로도 보기(PDF)");

          _circuit_Btn->_EVENT_Click = _EVENT_Click_circuit_Btn;

          //[풍선 도움말 설정]
          //{
              /*
              _circuit_Btn->_BalloonHelpUse(true);
              _circuit_Btn->_BalloonHelpStr
              ("G.M.RC.BASiC 의 [제어기 번호(DID)] 를 설정합니다.\r\n"
               "버튼을 누르면 설정을 위한 대화상자가 나옵니다."
              );
              */
          //}

      //}

      //[설명 문자열]
      //{
          _text_Label          = new Tgui_Label_Form(this);
          _text_Label->Parent  = this;
          _text_Label->Visible = true;

          _text_Label->_Left(_make_Btn->Left + _make_Btn->Width + 4);
          _text_Label->_Top(_make_Btn->Top);
          _text_Label->_Width(this->Width - _text_Label->Left - 8);
          _text_Label->_Height(this->Height - _text_Label->Top - 8);
          //_text_Label->_FontColor(_ide_option->color_0);
          _text_Label->_Caption
          ("G.M.RC.BASiC 기본 RC 서보모터 제어기를\r\n"
           "자동 제작합니다.\r\n\r\n"
           "맷돌(G.MTDL.A)과 ATmega88(20Mhz)을\r\n"
           "회로도를 참고하여 연결하고 연결된 포트와 핀을\r\n"
           "설정한 뒤에 [G.M.RC.BASiC 영혼 불어넣기]\r\n"
           "버튼을 누르면 G.M.RC.BASiC 이 완성됩니다.\r\n"
           "(G.M.RC.BASiC 2.5.16판)"
          );
          _text_Label->_Border(false);

          //_text_Label->_FontStyle(d_FONTSTYLE_bold);

      //}

      //[진행막대]
      //{
          _make_Progress          = new Tgui_Progress_Form(this);
          _make_Progress->Parent  = this;
          _make_Progress->Visible = false;

          _make_Progress->_Height(_circuit_Btn->Height);
          _make_Progress->_Left(_circuit_Btn->Left);
          _make_Progress->_Width(_circuit_Btn->Width);
          _make_Progress->_Top(_circuit_Btn->Top);
          _make_Progress->_BorderGap(4);

          //진행막대색을 설정한다.
          BMP_Get_Bright_Color(_ide_option->color_0, Ide_Bright_Progress, &(_make_Progress->_progressColor));

      //}

      //[진행 상태 문자열]
      //{
          _make_Label          = new Tgui_Label_Form(this);
          _make_Label->Parent  = this;
          _make_Label->Visible = false;

          _make_Label->_Left(_make_Btn->Left + _make_Btn->Width + 4);
          _make_Label->_Top(_make_Btn->Top);
          _make_Label->_Width(this->Width - _text_Label->Left - 8);
          _make_Label->_Height(this->Height - _text_Label->Top - 8);
          //_make_Label->_FontColor(_ide_option->color_0);
          _make_Label->_Caption
          (""
          );
          _make_Label->_Border(false);

          //_make_Label->_FontStyle(d_FONTSTYLE_bold);

      //}

      //[가상기계(GVMX) 설치]
      //{
          //[_gvmxInstall_Label]
          //{
              _gvmxInstall_Label          = new Tgui_Label_Form(this);
              _gvmxInstall_Label->Parent  = this;
              _gvmxInstall_Label->Visible = true;

              _gvmxInstall_Label->_Left(8);
              _gvmxInstall_Label->_Top(_circuit_Btn->Top + _circuit_Btn->Height + 6);
              _gvmxInstall_Label->_Width(436);
              _gvmxInstall_Label->_Height(16);
              _gvmxInstall_Label->_FontColor(_ide_option->color_0);
              _gvmxInstall_Label->_Caption("[참고] 사용전 [맷돌] 에 대응하는 가상기계(GVMX)를 설치해야 합니다.");
              _gvmxInstall_Label->_Border(false);

          //}

          //[_gvmxInstall_Btn]
          //{
              _gvmxInstall_Btn          = new Tgui_button_Form(this);
              _gvmxInstall_Btn->Parent  = this;
              _gvmxInstall_Btn->Visible = true;

              _gvmxInstall_Btn->_Top(_gvmxInstall_Label->Top - 2);
              _gvmxInstall_Btn->_Left(_gvmxInstall_Label->Left + _gvmxInstall_Label->Width);
              _gvmxInstall_Btn->_Width(55);
              _gvmxInstall_Btn->_Height(20);
              _gvmxInstall_Btn->_Caption("설치");

              _gvmxInstall_Btn->_EVENT_Click = _EVENT_Click_gvmxInstall_Btn;

          //}

      //}

  //}

  //[그리기]
  //{
      _Shape();

  //}

  //[폼 위치 조정]
  //{
      //폼이 항상 화면의 중앙에 나오도록 위치를 조정한다.
      this->Left = Screen->Width/2  - this->Width/2;
      this->Top  = Screen->Height/2 - this->Height/2;

  //}
                               
  return;

}

__fastcall TgmrcbasicMake_DialogBox_Form::~TgmrcbasicMake_DialogBox_Form(void)
{
  //[2012.04.30.월][수정!!!]{---------------
  //안전을 위하여 선언한 역순으로 삭제한다.
  //}---------------------------------------

  if(_gvmxInstall_Btn != NULL) { delete _gvmxInstall_Btn; _gvmxInstall_Btn = NULL; }

  if(_gvmxInstall_Label != NULL) { delete _gvmxInstall_Label; _gvmxInstall_Label = NULL; }

  if(_make_Label != NULL) { delete _make_Label; _make_Label = NULL; }

  if(_make_Progress != NULL) { delete _make_Progress; _make_Progress = NULL; }

  if(_text_Label != NULL) { delete _text_Label; _text_Label = NULL; }

  if(_circuit_Btn != NULL) { delete _circuit_Btn; _circuit_Btn = NULL; }

  if(_portRst_Btn != NULL) { delete _portRst_Btn; _portRst_Btn = NULL; }

  if(_portRst_Label != NULL) { delete _portRst_Label; _portRst_Label = NULL; }

  if(_portSck_Btn != NULL) { delete _portSck_Btn; _portSck_Btn = NULL; }

  if(_portSck_Label != NULL) { delete _portSck_Label; _portSck_Label = NULL; }

  if(_portMosi_Btn != NULL) { delete _portMosi_Btn; _portMosi_Btn = NULL; }

  if(_portMosi_Label != NULL) { delete _portMosi_Label; _portMosi_Label = NULL; }

  if(_portMiso_Btn != NULL) { delete _portMiso_Btn; _portMiso_Btn = NULL; }

  if(_portMiso_Label != NULL) { delete _portMiso_Label; _portMiso_Label = NULL; }

  if(_portNum_Btn != NULL) { delete _portNum_Btn; _portNum_Btn = NULL; }

  if(_portNum_Label != NULL) { delete _portNum_Label; _portNum_Label = NULL; }

  if(_portBase_Label != NULL) { delete _portBase_Label; _portBase_Label = NULL; }

  if(_make_Btn != NULL) { delete _make_Btn; _make_Btn = NULL; }

  if(_close_bmpbtns != NULL) { delete _close_bmpbtns; _close_bmpbtns = NULL; }

  if(_bmp_ != NULL) { delete _bmp_; _bmp_ = NULL; }

}

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

void __fastcall TgmrcbasicMake_DialogBox_Form::_FormCut(void)
{
  //[2006.11.07.화][생성!!!]{----------------------------------------------------
  //폼의 caption 의 모양을 보기 좋게 하기 위하여 caption 의 영역을 제외한 나머지
  //영역의 폼을 제거해 준다.(구멍을 뚫어준다.)
  //여러개의 [사각형] 모양으로 구멍을 뚫어준다.
  //}----------------------------------------------------------------------------

  //[VAR]
  //{
      HRGN    rgn_main,                              //대상 폼.
              rgn_cut_rect,                          //caption 오른쪽 영역 전부.
              rgn_cut_left_line, rgn_cut_left_dot,   //수평line, dot.
              rgn_cut_right_line, rgn_cut_right_dot; //수평line, dot.
  //}


  //[Form 초기화]
  //{
      //포인터 초기화.
      rgn_main = 0;

      //Form 의 영역 정보를 얻는다.
      GetWindowRgn(this->Handle, rgn_main);

      //일단 현재 Form 영역을 지운다.
      DeleteObject(rgn_main);
  //}

  //[영역 생성]
  //{
      //새로운 영역을 생성한다.
      rgn_main = CreateRectRgn(0, 0, this->Width, this->Height);

      //[구멍 뚫을 영역 지정]
      //{
          //caption 오른쪽 영역.
          rgn_cut_rect       = CreateRectRgn(_caption_width, 0, this->Width, 18);

          //좌측 라인.
          rgn_cut_left_line  = CreateRectRgn(0, 0, 2, 1);

          //좌측 점.
          rgn_cut_left_dot   = CreateRectRgn(0, 1, 1, 2);

          //우측 라인.
          rgn_cut_right_line = CreateRectRgn(_caption_width - 2, 0, _caption_width, 1);

          //우측 점.
          rgn_cut_right_dot  = CreateRectRgn(_caption_width - 1, 1, _caption_width, 2);

      //}

      CombineRgn(rgn_main, rgn_main, rgn_cut_rect, RGN_DIFF);
      CombineRgn(rgn_main, rgn_main, rgn_cut_left_line, RGN_DIFF);
      CombineRgn(rgn_main, rgn_main, rgn_cut_left_dot, RGN_DIFF);
      CombineRgn(rgn_main, rgn_main, rgn_cut_right_line, RGN_DIFF);
      CombineRgn(rgn_main, rgn_main, rgn_cut_right_dot, RGN_DIFF);

      SetWindowRgn(this->Handle, rgn_main, TRUE);
      
  //}

  //[구멍 뚫기]
  //{
      //--------------------------------
      //지정 영역에 구멍을 뚫는다.
      DeleteObject(rgn_cut_rect);
      DeleteObject(rgn_cut_left_line);
      DeleteObject(rgn_cut_left_dot);
      DeleteObject(rgn_cut_right_line);
      DeleteObject(rgn_cut_right_dot);
      //--------------------------------
  //}

  return;

}

void __fastcall TgmrcbasicMake_DialogBox_Form::_Border(void)
{
  //[설명!!!]{----------------------------------------------------------------
  //Form 전체의 테두리를 만든다.
  //두께는 4pixel, 동서남 3 면만 그리면 된다.
  //테두리는 직접 보이는 것이고 내용에 영향을 주지 않아야 하므로 직접 그린다.

  //[2007.03.18.일][수정!!!]
  //1 pixel 의 [통합개발환경] 전체 테두리를 마지막에 그려준다.
  //이는 윤곽을 더 뚜렷하게 하기 위한 것이다.
  //}-------------------------------------------------------------------------

  //[VAR]
  //{
      TRect            trect;
  //}

  //[테두리 만들기]
  //{
      //[좌측 테두리]{-------------------------------
      trect.Left   = 0;
      trect.Top    = 0;
      trect.Right  = d_border_width;
      trect.Bottom = _bmp_->Height;

      _bmp_->Canvas->Brush->Color = _ide_option->color_0;
      _bmp_->Canvas->FillRect(trect);
      //[우측 테두리]{-------------------------------
      trect.Left   = _bmp_->Width - d_border_width;
      trect.Top    = 0;
      trect.Right  = _bmp_->Width;
      trect.Bottom = _bmp_->Height;

      _bmp_->Canvas->Brush->Color = _ide_option->color_0;
      _bmp_->Canvas->FillRect(trect);
      //[아래 테두리]{-------------------------------
      trect.Left   = 0;
      trect.Top    = _bmp_->Height - d_border_width;
      trect.Right  = _bmp_->Width;
      trect.Bottom = _bmp_->Height;

      _bmp_->Canvas->Brush->Color = _ide_option->color_0;
      _bmp_->Canvas->FillRect(trect);
      //---------------------------------------------
  //}

  //[윤곽선 만들기]
  //{
      //[2007.03.18.일][추가!!!]
      if(d_OPTION_msgbox_outline)
      {
        //[왼쪽]
        _bmp_->Canvas->Pen->Color = IDE_COLOR_outline;
        _bmp_->Canvas->MoveTo(0, 2);
        _bmp_->Canvas->LineTo(0, this->Height);

        //[오른쪽]
        _bmp_->Canvas->Pen->Color = IDE_COLOR_outline;
        _bmp_->Canvas->MoveTo(this->Width - 1, 0);
        _bmp_->Canvas->LineTo(this->Width - 1, this->Height);

        //[아래쪽]
        _bmp_->Canvas->Pen->Color = IDE_COLOR_outline;
        _bmp_->Canvas->MoveTo(0, this->Height - 1);
        _bmp_->Canvas->LineTo(this->Width - 1, this->Height - 1);

        //[제목줄 위쪽]
        _bmp_->Canvas->Pen->Color = IDE_COLOR_outline;
        _bmp_->Canvas->MoveTo(2, 0);
        _bmp_->Canvas->LineTo(_caption_width-3, 0);

        //[오늘쪽 위쪽]
        _bmp_->Canvas->Pen->Color = IDE_COLOR_outline;
        _bmp_->Canvas->MoveTo(_caption_width -1 , _caption_height - d_border_width);
        _bmp_->Canvas->LineTo(this->Width - 1, _caption_height - d_border_width);

        //[제목줄 오른쪽]
        _bmp_->Canvas->Pen->Color = IDE_COLOR_outline;
        _bmp_->Canvas->MoveTo(_caption_width -1 , 2);
        _bmp_->Canvas->LineTo(_caption_width -1, _caption_height - d_border_width);

        //[제목줄 왼쪽위 모서리]
        _bmp_->Canvas->Pen->Color = IDE_COLOR_outline;
        _bmp_->Canvas->MoveTo(2 , 0);
        _bmp_->Canvas->LineTo(0, 2);

        //[제목줄 오른쪽위 모서리]
        _bmp_->Canvas->Pen->Color = IDE_COLOR_outline;
        _bmp_->Canvas->MoveTo(_caption_width-3 , 0);
        _bmp_->Canvas->LineTo(_caption_width -1, 2);

      }

  //}

  return;

}

void __fastcall TgmrcbasicMake_DialogBox_Form::_Shape(void)
{
  //[2007.09.26.수][생성!!!]{---
  //컨트롤의 모양을 만든다.
  //}---------------------------

  //[VAR]
  //{
      TRect  rect;
      TRect  rect_caption;

      int    w, h;

      int    width, height;

  //}

  //[제목줄 폭 구하기]
  //{
      //caption 문자열의 width 를 구한다.
      FONT_Get_StringOutAreaInfo(&_font, d_FONTSTYLE_default, _caption, &width, &height);

      //실제 사용할 caption 폭을 설정한다.
      //_font.margin_size 는 처음 기본값인 0 을 사용한다.(한번만 그려주면 된다.)
      _caption_width = width + (_font.margin_size * 2) + 2;

  //}

  //[수정]
  //{
      //[닫기] 버튼의 폭과 배치를 반영하여 폭을 늘려준다.
      _caption_width += (_close_bmpbtns->Width + 4);

  //}

  //[폼 오려내기]
  //{
      _FormCut();

  //}

  //[모양 그리기]
  //{
      //[전체 배경 처리]
      //{
          //[영역정보]{-------------------
          rect = _bmp_->Canvas->ClipRect;
          //}-----------------------------

          //[바탕 지우기]{---------------------------
          _bmp_->Canvas->Brush->Color = IDE_COLOR_2;
          _bmp_->Canvas->FillRect(rect);
          //}----------------------------------------

      //}

      //[caption 처리]
      //{
          //[caption 영역]{----------------------
          rect_caption = rect;
          rect_caption.Bottom = _caption_height;
          //}------------------------------------

          //[caption 바탕 지우기]{-------------------
          _bmp_->Canvas->Brush->Color = _ide_option->color_0;
          _bmp_->Canvas->FillRect(rect_caption);
          //}----------------------------------------

          //[caption 문자열]
          //{
              //----------------------------------------------------------------------------------
              _font.margin_size = 0;

              //FONT_Out_String2(_bmp_, &_font, 0, 5, IDE_COLOR_3, _ide_option->color_0, true,
              //                 _caption,
              //                 d_FONT_underline_no, true, 0, IDE_COLOR_1,
              //                 &w, &h);

              //[2007.12.15.토][수정!!!]
              //위의 함수를 [형식] 을 적용할수 있는 이 함수로 바꾼다.
              FONT_Out_StyleString2(_bmp_, &_font, 0, 5, IDE_COLOR_3, _ide_option->color_0, true,
                                    d_FONTSTYLE_default,
                                    _caption,
                                    d_FONT_underline_no, true, 0, IDE_COLOR_1,
                                    &w, &h);
              //----------------------------------------------------------------------------------
          //}

      //}

      //[닫기 단추 배치]
      //{
          _close_bmpbtns->_Top(5);
          _close_bmpbtns->_Left(_caption_width - _close_bmpbtns->Width - 5);

          //[단추 배경 지우기]
          //{
              rect.Left   = _close_bmpbtns->Left - 1;
              rect.Top    = _close_bmpbtns->Top  - 1;
              rect.Right  = _close_bmpbtns->Left + _close_bmpbtns->Width  + 1;
              rect.Bottom = _close_bmpbtns->Top  + _close_bmpbtns->Height + 1;

              _bmp_->Canvas->Brush->Color = IDE_COLOR_2;
              _bmp_->Canvas->FillRect(rect);

          //}

      //}

  //}

  //[테두리]
  //{
      _Border();
  //}

  //[view]{-------------
  //그린 것을 보여준다.
  _Draw();
  //}-------------------

  return;

}

void __fastcall TgmrcbasicMake_DialogBox_Form::_Draw(void)
{
  BitBlt(this->Canvas->Handle, 0, 0,
         this->Width, this->Height,
         _bmp_->Canvas->Handle, 0, 0, SRCCOPY);

  return;

}

void __fastcall TgmrcbasicMake_DialogBox_Form::_Caption(char  *pCaption)
{
  //[2007.12.14.금][생성!!!]{-------------------------------------------------------
  //[제목줄] 문자열을 지정된 문자열로 바꾸어 주고 전체를 다시 그려준다.
  //[제목줄] 이 달라지면 폼을 다시 오려 주어야 하므로 다시 전체를 그려 주어야 한다.
  //}-------------------------------------------------------------------------------

  //[VAR]
  //{
      int            width, height;

  //}

  //[caption 설정]
  //{
      //caption 문자열.(크게 바뀔일이 없다.)
      STR_Assign(_caption, pCaption);

      //높이 지정.
      _caption_height = 22;

      //caption 문자열의 width 를 구한다.
      FONT_Get_StringOutAreaInfo(&_font, d_FONTSTYLE_default, _caption, &width, &height);

      //실제 사용할 caption 폭을 설정한다.
      //_font.margin_size 는 처음 기본값인 0 을 사용한다.(한번만 그려주면 된다.)
      _caption_width = width + (_font.margin_size * 2) + 2;

  //}

  //[그리기]
  //{
      _Shape();

  //}

  return;

}

void __fastcall TgmrcbasicMake_DialogBox_Form::_Width(int  pWidth)
{
  //[2007.12.14.금][생성!!!]{-----------------------------------------------------------
  //폭을 바꾸어 주고 _bmp_ 등 관련 부분도 다 수정하고 폼도 다시 오려주고 다시 그려준다.
  //}-----------------------------------------------------------------------------------

  //[크기 조정]
  //{
      //지정 폭으로 폭을 조정한다.
      _bmp_->Width = pWidth;

      this->Width  = pWidth;

  //}

  //[그리기]
  //{
      _Shape();

  //}

  return;

}

void __fastcall TgmrcbasicMake_DialogBox_Form::_Height(int  pHeight)
{
  //[2007.12.14.금][생성!!!]{-------------------------------------------------------------
  //높이를 바꾸어 주고 _bmp_ 등 관련 부분도 다 수정하고 폼도 다시 오려주고 다시 그려준다.
  //}-------------------------------------------------------------------------------------

  //[크기 조정]
  //{
      //지정 폭으로 폭을 조정한다.
      _bmp_->Height = pHeight;

      this->Height  = pHeight;

  //}

  //[그리기]
  //{
      _Shape();

  //}

  return;

}

//------------------------------------------------------------------------------
//[동작홤수들]------------------------------------------------------------------
//------------------------------------------------------------------------------

void __fastcall TgmrcbasicMake_DialogBox_Form::_EVENT_CloseButton_Click(void)
{
  //[2007.09.26.수][생성!!!]{---
  //이 폼을 닫는다.
  //}---------------------------

  this->Close();

  return;

}

void __fastcall TgmrcbasicMake_DialogBox_Form::_EVENT_Click_make_Btn(void)
{
  //[2009.12.06.일][생성!!!]{---------------------------
  //G.M.RC.BASiC 을 자동 제작 과정을 순서대로 실행한다.
  //간단하게 전용함수로 처리한다.
  //}---------------------------------------------------

  //[VAR]
  //{
      //[통신포트 처리용]
      //{
          //[2011.11.14.월][추가!!!]
          class  COMPORT  *comPort;

          //통신포트 위치 얻기.
          COMPORT_GetPtr(d_ComportID_Vmos, &comPort);

      //}

  //}

  //[통신포트 수신 저장소 비우기]
  //{
      //[2011.11.14.월][추가!!!]{-----------------------------------------
      //맷돌이 재기동후 [SysCom] 으로 예측되지 않은 몇바이트를 전송하므로
      //PC 쪽 통신포트의 [수신저장소] 를 확실하게 비우고 시작한다.
      //}-----------------------------------------------------------------

      comPort->Clear_RxdBuf();

  //}

  //[기본 처리]
  //{
      //[2011.09.09.금][추가!!!]{------------------------------------------------------------------
      //맷돌에 설치된 가상기계의 중요 변수 위치 등을 얻는다.
      //원래는 <ide_main:Ide_System_Mtdl_GmRcBasic_Make()> 에서 맷돌에 해당 [가상기계] 를
      //설치후 한번만 처리하게 돼 있으나, 이 대화상자가 나온 상태에서 다른 VMOS 를 설치하는
      //경우에는 이미 읽어들인 [절대주소] 와 다른 위치가 돼므로 제대로 동작하지 않는다.
      //따라서, 어떤 경우라도 확실하게 동작 되도록 [만들기] 때마다 계속 읽어들이는 것으로
      //수정한다.
      //
      //G.M.RC.BASiC 용 ISP 가 Win7(64비트) 에서는 제대로 동작이 안돼서, 맷돌을 사용하여
      //G.M.RC.BASiC 을 제작하려다가, VMOS 속도가 이전보다 빨라져서 단순하게 구현한 [시간지연]
      //함수의 ms 시간이 정확하지 않고 빨라져 제대로 ISP 안되는 것을 확인하여, [시간지연] 함수를
      //[타이머] 를 사용하여 확실하게 구현후 이를 확인하는 과정에서, 이 대화상자를 열어놓은 상태로
      //VMOS 를 교체한뒤 제대로 [제작] 이 안되는 원인을 확인하다가 이를 알고 수정하는 것이다.
      //}------------------------------------------------------------------------------------------

      if(Table_VarAdrTable_Read() != true) return;

  //}

  if(Mtdl_GMRCBASiC_Make() != true) return;

  return;

}

void __fastcall TgmrcbasicMake_DialogBox_Form::_EVENT_Click_portNum_Btn(void)
{
  //[2009.12.06.일][생성!!!]{-----------------------------
  //SPI 포트를 생성할 맷돌의 포트번호를 설정한다.
  //이 경우는 다른 핀번호 라벨도 전부 수정해 주어야 한다.
  //
  //[2018.03.06.화][수정!!!]------------------------------
  //}-----------------------------------------------------

  //[VAR]
  //{
      char   tempStr[OPT_wordStrSize];
      int    tempVal;

  //}

  //[현재 설정값 보여주기]{-------------------------------------------
  //현재 설정되 있는 값을 다시 대화상자에 표시해 준다.
  ide_msgbox_Form->_edit_Edit->_EDIT_TextOut(_portNum_Btn->_caption);
  //}-----------------------------------------------------------------

  //[wine 모달유사 지원][2018.03.06.화][추가!!!]{----------
  //if(_ide_option->wine == true) { this->Enabled = false; }
  //}------------------------------------------------------

  //[항목 종류 구분]
  //{

      if(ide_msgbox_Form->_MsgBox_Edit(d_MSGBOX_default,
                                       "SPI 포트를 생성할 맷돌 포트 번호는 \r\n"
                                       "0 - 2 사이의 값을 가져야 합니다.") == true)
      {
        //[10진수 인가?]{---------------------------------------------------------
        if(STR_Is_Dec(ide_msgbox_Form->_edit_Edit->_editbuf) != true) goto lbEnd;
        //
        //[문자열 => 값 으로 변환]------------------------------------------------
        CONV_DecStr_To_IntVal(ide_msgbox_Form->_edit_Edit->_editbuf, &tempVal);
        //
        //[값 범위 확인]----------------------------------------------------------
        if(!((0 <= tempVal) && (tempVal <= 2)))
        {
          ide_msgbox_Form->_MsgBox(d_MSGBOX_error,
                                   "0 - 2 사이의 값만 사용할수 있습니다.");

          //[2018.03.06.화][추가!!!]
          goto lbEnd;

        }
        //[값 => 문자열로 변환]---------------------------------------------------
        CONV_LongVal_To_Str(tempVal, 1, false, tempStr);
        //
        //[문자열 합성/표시]------------------------------------------------------
        _portNum_Btn->_Caption(tempStr);
        //}-----------------------------------------------------------------------

      }

  //}

  //[비트 라벨 정리]
  //{
      //[!]{---------------------------------------------
      //현재 포트번호에 맞게 비트번호 라벨을 변경해준다.
      //}------------------------------------------------

      //[MISO]
      //{
          STR_Assign(tempStr, "MISO:P");
          STR_Add(tempStr, _portNum_Btn->_caption);
          STR_Add(tempStr, ".");

          _portMiso_Label->_Caption(tempStr);

      //}

      //[MOSI]
      //{
          STR_Assign(tempStr, "MOSI:P");
          STR_Add(tempStr, _portNum_Btn->_caption);
          STR_Add(tempStr, ".");

          _portMosi_Label->_Caption(tempStr);

      //}

      //[SCK]
      //{
          STR_Assign(tempStr, "SCK :P");
          STR_Add(tempStr, _portNum_Btn->_caption);
          STR_Add(tempStr, ".");

          _portSck_Label->_Caption(tempStr);

      //}

      //[RST]
      //{
          STR_Assign(tempStr, "RST :P");
          STR_Add(tempStr, _portNum_Btn->_caption);
          STR_Add(tempStr, ".");

          _portRst_Label->_Caption(tempStr);

      //}

  //}

  lbEnd:

  //[wine 모달유사 지원][2018.03.06.화][추가!!!]{---------
  //if(_ide_option->wine == true) { this->Enabled = true; }
  //}-----------------------------------------------------

  return;

}

void __fastcall TgmrcbasicMake_DialogBox_Form::_EVENT_Click_portMiso_Btn(void)
{
  //[2009.12.06.일][생성!!!]{---
  //MISO 핀번호를 설정한다.
  //
  //[2018.03.06.화][수정!!!]----
  //}---------------------------

  //[VAR]
  //{
      char   tempStr[OPT_wordStrSize];
      int    tempVal;

  //}

  //[현재 설정값 보여주기]{--------------------------------------------
  //현재 설정되 있는 값을 다시 대화상자에 표시해 준다.
  ide_msgbox_Form->_edit_Edit->_EDIT_TextOut(_portMiso_Btn->_caption);
  //}------------------------------------------------------------------

  //[wine 모달유사 지원][2018.03.06.화][추가!!!]{----------
  //if(_ide_option->wine == true) { this->Enabled = false; }
  //}------------------------------------------------------

  //[항목 종류 구분]
  //{
      if(ide_msgbox_Form->_MsgBox_Edit(d_MSGBOX_default,
                                       "MISO 사용 비트 번호를 설정합니다.\r\n"
                                       "0 - 7 사이의 값을 가져야 합니다.\r\n\r\n"
                                       "맷돌(G.MTDL.A)의 P0.0/P0.1/P0.5 3 개 핀은 5V 입력을 허용하지\r\n"
                                       "않으므로 이 3개 핀은 MISO 핀으로 사용하지 않아야 합니다.") == true)
      {
        //[10진수 인가?]{---------------------------------------------------------
        if(STR_Is_Dec(ide_msgbox_Form->_edit_Edit->_editbuf) != true) goto lbEnd;
        //
        //[문자열 => 값 으로 변환]------------------------------------------------
        CONV_DecStr_To_IntVal(ide_msgbox_Form->_edit_Edit->_editbuf, &tempVal);
        //
        //[값 범위 확인]----------------------------------------------------------
        if(!((0 <= tempVal) && (tempVal <= 7)))
        {
          ide_msgbox_Form->_MsgBox(d_MSGBOX_error,
                                   "0 - 7 사이의 값만 사용할수 있습니다.");

          goto lbEnd;

        }
        //[값 => 문자열로 변환]---------------------------------------------------
        CONV_LongVal_To_Str(tempVal, 1, false, tempStr);
        //
        //[문자열 합성/표시]------------------------------------------------------
        _portMiso_Btn->_Caption(tempStr);
        //}-----------------------------------------------------------------------

      }

  //}

  lbEnd:

  //[wine 모달유사 지원][2018.03.06.화][추가!!!]{---------
  //if(_ide_option->wine == true) { this->Enabled = true; }
  //}-----------------------------------------------------

  return;

}

void __fastcall TgmrcbasicMake_DialogBox_Form::_EVENT_Click_portMosi_Btn(void)
{
  //[2009.12.06.일][생성!!!]{---
  //MOSI 핀번호를 설정한다.
  //
  //[2018.03.06.화][수정!!!]----
  //}---------------------------

  //[VAR]
  //{
      char   tempStr[OPT_wordStrSize];
      int    tempVal;

  //}

  //[현재 설정값 보여주기]{--------------------------------------------
  //현재 설정되 있는 값을 다시 대화상자에 표시해 준다.
  ide_msgbox_Form->_edit_Edit->_EDIT_TextOut(_portMosi_Btn->_caption);
  //}------------------------------------------------------------------

  //[wine 모달유사 지원][2018.03.06.화][추가!!!]{----------
  //if(_ide_option->wine == true) { this->Enabled = false; }
  //}------------------------------------------------------

  //[항목 종류 구분]
  //{
      if(ide_msgbox_Form->_MsgBox_Edit(d_MSGBOX_default,
                                       "MOSI 사용 비트 번호를 설정합니다.\r\n"
                                       "0 - 7 사이의 값을 가져야 합니다.") == true)
      {
        //[10진수 인가?]{---------------------------------------------------------
        if(STR_Is_Dec(ide_msgbox_Form->_edit_Edit->_editbuf) != true) goto lbEnd;
        //
        //[문자열 => 값 으로 변환]------------------------------------------------
        CONV_DecStr_To_IntVal(ide_msgbox_Form->_edit_Edit->_editbuf, &tempVal);
        //
        //[값 범위 확인]----------------------------------------------------------
        if(!((0 <= tempVal) && (tempVal <= 7)))
        {
          ide_msgbox_Form->_MsgBox(d_MSGBOX_error,
                                   "0 - 7 사이의 값만 사용할수 있습니다.");

          goto lbEnd;

        }
        //[값 => 문자열로 변환]---------------------------------------------------
        CONV_LongVal_To_Str(tempVal, 1, false, tempStr);
        //
        //[문자열 합성/표시]------------------------------------------------------
        _portMosi_Btn->_Caption(tempStr);
        //}-----------------------------------------------------------------------

      }

  //}

  lbEnd:

  //[wine 모달유사 지원][2018.03.06.화][추가!!!]{---------
  //if(_ide_option->wine == true) { this->Enabled = true; }
  //}-----------------------------------------------------

  return;

}

void __fastcall TgmrcbasicMake_DialogBox_Form::_EVENT_Click_portSck_Btn(void)
{
  //[2009.12.06.일][생성!!!]{---
  //SCK 핀번호를 설정한다.
  //
  //[2018.03.06.화][수정!!!]----
  //}---------------------------

  //[VAR]
  //{
      char   tempStr[OPT_wordStrSize];
      int    tempVal;

  //}

  //[현재 설정값 보여주기]{-------------------------------------------
  //현재 설정되 있는 값을 다시 대화상자에 표시해 준다.
  ide_msgbox_Form->_edit_Edit->_EDIT_TextOut(_portSck_Btn->_caption);
  //}-----------------------------------------------------------------

  //[wine 모달유사 지원][2018.03.06.화][추가!!!]{----------
  //if(_ide_option->wine == true) { this->Enabled = false; }
  //}------------------------------------------------------

  //[항목 종류 구분]
  //{
      if(ide_msgbox_Form->_MsgBox_Edit(d_MSGBOX_default,
                                       "SCK 사용 비트 번호를 설정합니다.\r\n"
                                       "0 - 7 사이의 값을 가져야 합니다.") == true)
      {
        //[10진수 인가?]{---------------------------------------------------------
        if(STR_Is_Dec(ide_msgbox_Form->_edit_Edit->_editbuf) != true) goto lbEnd;
        //
        //[문자열 => 값 으로 변환]------------------------------------------------
        CONV_DecStr_To_IntVal(ide_msgbox_Form->_edit_Edit->_editbuf, &tempVal);
        //
        //[값 범위 확인]----------------------------------------------------------
        if(!((0 <= tempVal) && (tempVal <= 7)))
        {
          ide_msgbox_Form->_MsgBox(d_MSGBOX_error,
                                   "0 - 7 사이의 값만 사용할수 있습니다.");

          goto lbEnd;

        }
        //[값 => 문자열로 변환]---------------------------------------------------
        CONV_LongVal_To_Str(tempVal, 1, false, tempStr);
        //
        //[문자열 합성/표시]------------------------------------------------------
        _portSck_Btn->_Caption(tempStr);
        //}-----------------------------------------------------------------------

      }

  //}

  lbEnd:

  //[wine 모달유사 지원][2018.03.06.화][추가!!!]{---------
  //if(_ide_option->wine == true) { this->Enabled = true; }
  //}-----------------------------------------------------

  return;

}

void __fastcall TgmrcbasicMake_DialogBox_Form::_EVENT_Click_portRst_Btn(void)
{
  //[2009.12.06.일][생성!!!]{---
  //SCK 핀번호를 설정한다.
  //
  //[2018.03.06.화][수정!!!]----
  //}---------------------------

  //[VAR]
  //{
      char   tempStr[OPT_wordStrSize];
      int    tempVal;

  //}

  //[현재 설정값 보여주기]{-------------------------------------------
  //현재 설정되 있는 값을 다시 대화상자에 표시해 준다.
  ide_msgbox_Form->_edit_Edit->_EDIT_TextOut(_portRst_Btn->_caption);
  //}-----------------------------------------------------------------

  //[wine 모달유사 지원][2018.03.06.화][추가!!!]{----------
  //if(_ide_option->wine == true) { this->Enabled = false; }
  //}------------------------------------------------------

  //[항목 종류 구분]
  //{
      if(ide_msgbox_Form->_MsgBox_Edit(d_MSGBOX_default,
                                       "SCK 사용 비트 번호를 설정합니다.\r\n"
                                       "0 - 7 사이의 값을 가져야 합니다.") == true)
      {
        //[10진수 인가?]{---------------------------------------------------------
        if(STR_Is_Dec(ide_msgbox_Form->_edit_Edit->_editbuf) != true) goto lbEnd;
        //
        //[문자열 => 값 으로 변환]------------------------------------------------
        CONV_DecStr_To_IntVal(ide_msgbox_Form->_edit_Edit->_editbuf, &tempVal);
        //
        //[값 범위 확인]----------------------------------------------------------
        if(!((0 <= tempVal) && (tempVal <= 7)))
        {
          ide_msgbox_Form->_MsgBox(d_MSGBOX_error,
                                   "0 - 7 사이의 값만 사용할수 있습니다.");

          goto lbEnd;

        }
        //[값 => 문자열로 변환]---------------------------------------------------
        CONV_LongVal_To_Str(tempVal, 1, false, tempStr);
        //
        //[문자열 합성/표시]------------------------------------------------------
        _portRst_Btn->_Caption(tempStr);
        //}-----------------------------------------------------------------------

      }

  //}

  lbEnd:

  //[wine 모달유사 지원][2018.03.06.화][추가!!!]{---------
  //if(_ide_option->wine == true) { this->Enabled = true; }
  //}-----------------------------------------------------

  return;

}

void __fastcall TgmrcbasicMake_DialogBox_Form::_EVENT_Click_circuit_Btn(void)
{
  //[2009.12.06.일][생성!!!]{---
  //[회로도] 를 보여준다.
  //}---------------------------

  //[확장자 연결로 열기]
  //{
       //어떤 문서이든 해당 확장자에 연결된 프로그램으로 자동적으로 열어준다.
       //이것은 직접 해당 문서를 마우스로 더블클릭하여 열어 주는 것과 같다.
	   ShellExecute(0, "open", ((AnsiString)Ide_System_GmRcBasicCircuit_Path).c_str(), "", "", SW_NORMAL);

  //}

  return;

}

void __fastcall TgmrcbasicMake_DialogBox_Form::_EVENT_Click_gvmxInstall_Btn(void)
{
  //[2011.11.13.일][생성!!!]{--------------------------------------------
  //[맷돌(G.MTDL.X)] 에 대응하는 [가상기계(GVMX)] 를 설치한다.
  //
  //AVR-ISP 기능은 <맷돌:SPI> 기능을 사용하므로, 현재 맷돌에 설치돼 있는
  //VMOS 가 SPI 를 지원하는 종류인지 확인하는 부분을 추가한다.
  //
  //[2018.03.06.화][수정!!!]---------------------------------------------
  //}--------------------------------------------------------------------

  //[!]{---------------------------------------------------------------------------
  //원래 <맷돌C:API> 에서 맷돌(G.MTDL.X) 에 가상기계(GVMX) 를 기록하기 위하여 만든
  //함수인데, 여기서 빌려 사용한다.
  //
  //설치시 진행 상황은 [맷돌-개발환경] 자체에 표시된다(일반적인 경우와 동일).
  //}------------------------------------------------------------------------------

  //[VAR]
  //{
      //[통신포트 처리용]
      //{
          //[2011.11.14.월][추가!!!]
          class  COMPORT  *comPort;

          //통신포트 위치 얻기.
          COMPORT_GetPtr(d_ComportID_Vmos, &comPort);

      //}

  //}

  //[통신포트 수신 저장소 비우기]
  //{
      //[2011.11.14.월][추가!!!]{-----------------------------------------
      //맷돌이 재기동후 [SysCom] 으로 예측되지 않은 몇바이트를 전송하므로
      //PC 쪽 통신포트의 [수신저장소] 를 확실하게 비우고 시작한다.
      //}-----------------------------------------------------------------

      comPort->Clear_RxdBuf();

  //}

  //[<VMOS:API> 적합성 검사]
  //{
      //[2011.11.14.월][추가!!!]{----------------------------------------------------
      //현재 맷돌에 설치돼 있는 VMOS 가 "SPI" 를 지원하는지 확인한다.
      //단, 사용하는 <API 종류구분 단어> 는 정확하게 정의된 것을 사용해야 한다.
      //[대/소] 문자 구분은 하지 않는다.
      //각 <[운영체제].ginf> 문서에 단어별로 지원되는 <API 종류구분 단어> 가
      //정의돼 있다.
      //}----------------------------------------------------------------------------

      if(Ide_Mtdl_Vmos_Api_Match("Spi") != true)
      {
        //[wine 모달유사 지원][2018.03.06.화][추가!!!]{----------
        //if(_ide_option->wine == true) { this->Enabled = false; }
        //}------------------------------------------------------

        ide_msgbox_Form->_MsgBox
        (d_MSGBOX_error,
         "현재 맷돌(G.MTDL.X)에 설치된 운영체제(VMOS)가 <API_Spi> 계열을\r\n"
         "지원하지 않거나 지원 여부를 확인할수 없는 상태입니다.\r\n\r\n"
         "맷돌(G.MTDL.X)과 통신에 문제가 없다면 맷돌에 해당 API 를 지원하는\r\n"
         "운영체제(VMOS)를 먼저 설치하기 바랍니다.\r\n"
         "{ 메뉴 : 설정->맷돌 [운영체제] 설치 }\r\n");

        //[wine 모달유사 지원][2018.03.06.화][추가!!!]{---------
        //if(_ide_option->wine == true) { this->Enabled = true; }
        //}-----------------------------------------------------

        return;

      }

  //}

  //[설치]
  //{
	  if(Ide_API_GVMX_Install(((AnsiString)Ide_System_GmRcBasicGvmx_Path).c_str(), false, NULL) != true) return;

  //}

  //[확인]
  //{
      if(Ide_API_GVMX_Verify(((AnsiString)Ide_System_GmRcBasicGvmx_Path).c_str(), NULL) != true) return;

  //}

  //[재기동]
  //{
      if(Ide_Mdl_Reset(false) != true) return;

  //}

  //[초기화 시간 대기]
  //{
      //[2011.11.14.월][추가!!!]{------------------------------
      //[재기동] 후에 맷돌에 설치된 [가상기계(GVMX)] 가 완전히
      //[동작대기] 상태가 될때가지 대기한다.
      //}------------------------------------------------------

      Sleep(500);

  //}

}

//------------------------------------------------------------------------------
//[BCB 자체 동작함수]-----------------------------------------------------------
//------------------------------------------------------------------------------

void __fastcall TgmrcbasicMake_DialogBox_Form::FormMouseDown(TObject *Sender,
      TMouseButton Button, TShiftState Shift, int X, int Y)
{
  //[2007.09.26.수][생성!!!]{-------
  //현재 [폼 이동] 처리에 사용한다.
  //}-------------------------------

  //[VAR]
  //{
      //[2018.03.17.토][추가!!!]
      TPoint  mousePos;

  //}

  //[전광판]
  //{
      //[2010.04.03.토][추가!!!]{-----------------------------
      //[전광판] 을 일시 정지 시킨다.
      //이는 이동, 크기조정시 끊어짐 현상을 막기 위한 것이다.
      //}-----------------------------------------------------

      ide_editor_Form->_GDotMatrix_RotateTemp(false);

  //}

  //[캡션바] 영역에서만 처리되어야 한다.
  if(((0 <= X) && (X < _caption_width)) &&
     ((0 <= Y) && (Y < _caption_height)))
  {
    if(Button == mbLeft)
    {
      //[위치 기록]
      //{
          //[2018.03.17.토][수정!!!]{-----------------------------------------------------
          //[전체화면] 을 대상으로한 위치 사용.
          //이는 <GVmos> 등 다른 Form 안에 생성되는 경우에도 동일하게 동작 시키기 위한것.
          //}-----------------------------------------------------------------------------

          //[전체화면] 을 대상으로 마우스 위치 얻기.
          GetCursorPos(&mousePos);

          //현재 <this> 위치와 [마우스] 위치 간의 거리 얻기.
          //항상 같은 거리를 유지하는 방법으로 [제목줄 이동] 을 구현하기 위한것.
          deltaLeft = mousePos.x - this->Left;
          deltaTop  = mousePos.y - this->Top;

      //}

      //caption 이 선택된 것을 알린다.
      _caption_selected = true;

      //[wine 지원]
      //{
          //[2018.03.04.일][추가!!!]{---------
          //[제목줄] 이동을 위한 타이머 켜기.
          //}---------------------------------

          if(_ide_option->wine == true)
          {
            captionMoveTimer->Enabled = true;

          }

      //}

    }

  }

  return;

}

void __fastcall TgmrcbasicMake_DialogBox_Form::FormMouseMove(TObject *Sender,
      TShiftState Shift, int X, int Y)
{
  //[2007.09.26.수][생성!!!]{----------------------
  //마우스로 caption 을 집어 끄는 경우를 처리한다.
  //}----------------------------------------------

  //[VAR]
  //{
      //[2018.03.17.토][추가!!!]
      TPoint  mousePos;

  //}

  //[캡션바 이동]
  //{
      //[캡션바] 영역에서만 처리되어야 한다.
      if(((0 <= X) && (X < _caption_width)) &&
         ((0 <= Y) && (Y < _caption_height)) ||
         //마우스로 집어  끄는 경우 영역을 벗어난 경우도 처리 되어야 한다.
         //이는 집어 끌다가 놓치는 경우를 막기 위한 것이다.
         (Shift.Contains(ssLeft)))
      {
        if((Shift.Contains(ssLeft)) && (_caption_selected == true))
        {
          //caption 을 마우스로 집어끄는 경우 Form 을 이동 시켜야 한다.

          //[wine 지원]
          //{
              //[2018.03.04.일][추가!!!]{-------------------------------
              //<Linux:wine> 에서 구동 중이라면 여기서 처리하지 않는다.
              //<captionMoveTimerTimer()> 안에서 처리된다.
              //}-------------------------------------------------------

              if(_ide_option->wine == true)
              {
                //[Linux:wine]
                //이 경우 아래에서 사용하는 <Left>, <Top> 값은 <captionMoveTimer> 안에서
                //수정되고 있는 정확한 값으로 처리.

              }
              else
              {
                //[윈도우]

                //[위치 이동]
                //{
                    //[2018.03.17.토][수정!!!]{-----------------------------------------------------
                    //[전체화면] 을 대상으로한 위치 사용.
                    //이는 <GVmos> 등 다른 Form 안에 생성되는 경우에도 동일하게 동작 시키기 위한것.
                    //}-----------------------------------------------------------------------------

                    //[전체화면] 을 대상으로 마우스 위치 얻기.
                    GetCursorPos(&mousePos);

                    //현재 <this> 위치와 [마우스] 위치 간의 거리를
                    //항상 같은 거리로 유지하는 방법으로 [제목줄 이동] 을 구현.
                    this->Left = mousePos.x - deltaLeft;
                    this->Top  = mousePos.y - deltaTop;

                //}

              }

          //}

        }

      }

  //}

  return;

}

void __fastcall TgmrcbasicMake_DialogBox_Form::FormMouseUp(TObject *Sender,
      TMouseButton Button, TShiftState Shift, int X, int Y)
{
  //[2007.09.26.수][생성!!!]

  //[wine 지원]
  //{
      //[2018.03.04.일][추가!!!]{---------
      //[제목줄] 이동을 위한 타이머 끄기.
      //}---------------------------------

      if(_ide_option->wine == true)
      {
        //<FormMouseUp> 에서는 무조건 타이머 정지.
        captionMoveTimer->Enabled = false;

      }

  //}

  //[전광판]
  //{
      //[2010.02.23.화][추가!!!]{--------------
      //[전광판] 을 다시 정지에서 해제시킨다.
      //}--------------------------------------

      ide_editor_Form->_GDotMatrix_RotateTemp(true);

  //}

  if(((0 <= X) && (X < _caption_width)) &&
     ((0 <= Y) && (Y < _caption_height)))
  {
    if(Button == mbRight)
    { 

    }

  }

  //[해제]
  //{
      //caption 선택을 해제한다.
      _caption_selected = false;

  //}

  return;

}

void __fastcall TgmrcbasicMake_DialogBox_Form::FormShow(TObject *Sender)
{
  //[2009.05.08.금][생성!!!]{---------
  //[찾을 문자열] 에 촛점을 맞춰준다.
  //}---------------------------------




  return;

}

//------------------------------------------------------------------------------
//[대화상자 처리 관련 함수]-----------------------------------------------------
//------------------------------------------------------------------------------

bool __fastcall TgmrcbasicMake_DialogBox_Form::Dlg_Spi_Pin(DTU1  *rPortNum,
                                                           DTU1  *rMisoNum,
                                                           DTU1  *rMosiNum,
                                                           DTU1  *rSckNum,
                                                           DTU1  *rRstNum)
{
  //[2009.12.06.일][생성!!!]{------------------------------------------------------
  //대화상자의 SPI 포트관련 각각의 핀들의 번호가 [중복] 되지 않았는지 확인하고,
  //각각 핀의 정보를 [배열] 로 반환한다.
  //
  //[2009.12.07.월][수정!!!]-------------------------------------------------------
  //맷돌(G.MTDL.A) 는 P0.0/P0.1/P0.5 3 개 핀은 5V 입력을 지원하지 않으므로 이 핀은
  //MISO 에서 제외시켜야 한다.
  //
  //[2018.03.06.화][수정!!!]-------------------------------------------------------
  //}------------------------------------------------------------------------------

  //[VAR]
  //{
      int    portNum;
      int    misoNum;
      int    mosiNum;
      int    sckNum;
      int    rstNum;

  //}

  //[해당 값 변환]
  //{
      //해당 문자열을 값으로 변환하여 저장한다.
      CONV_DecStr_To_IntVal(_portNum_Btn->_caption,  &portNum);
      CONV_DecStr_To_IntVal(_portMiso_Btn->_caption, &misoNum);
      CONV_DecStr_To_IntVal(_portMosi_Btn->_caption, &mosiNum);
      CONV_DecStr_To_IntVal(_portSck_Btn->_caption,  &sckNum);
      CONV_DecStr_To_IntVal(_portRst_Btn->_caption,  &rstNum);

  //}

  //[중복 검사]
  //{
      //각 핀의 값이 서로 겹치면 안된다.
      if((misoNum == mosiNum) || (misoNum == sckNum)  || (misoNum == rstNum) ||
         (mosiNum == misoNum) || (mosiNum == sckNum)  || (mosiNum == rstNum) ||
         (sckNum  == misoNum) || (sckNum  == mosiNum) || (sckNum  == rstNum) ||
         (rstNum  == misoNum) || (rstNum  == mosiNum) || (rstNum  == sckNum))
      {
        //[!]{--------------------------------------------------------
        //이 경우는 한개라도 겹치는 것이 있는 것이므로 바로 종료한다.
        //}-----------------------------------------------------------

        //[wine 모달유사 지원][2018.03.06.화][추가!!!]{----------
        //if(_ide_option->wine == true) { this->Enabled = false; }
        //}------------------------------------------------------

        ide_msgbox_Form->_MsgBox(d_MSGBOX_error,
                                 "SPI 포트의 각 핀은 서로 같은 비트 번호를 사용할수 없습니다.");

        //[wine 모달유사 지원][2018.03.06.화][추가!!!]{---------
        //if(_ide_option->wine == true) { this->Enabled = true; }
        //}-----------------------------------------------------

        return(false);

      }

  //}

  //[MISO 설정 핀 검사]
  //{
      //[2009.12.07.월][추가!!!]{--------------------------------------------------
      //MISO 핀이 P0.0/P0.1/P0.5 3개에 할당됬다면 오류로 간주하고 수정을 요구한다.
      //}--------------------------------------------------------------------------

      if((portNum == 0) && ((misoNum == 0) || (misoNum == 1) || (misoNum == 5)))
      {
        //[!]{-------------------------------------------------------------
        //이 경우는 오류로 간주하고 MISO 핀을 다른 곳으로 옮기게 유도한다.
        //}----------------------------------------------------------------

        //[wine 모달유사 지원][2018.03.06.화][추가!!!]{----------
        //if(_ide_option->wine == true) { this->Enabled = false; }
        //}------------------------------------------------------
        
        ide_msgbox_Form->_MsgBox(d_MSGBOX_error,
                                 "맷돌(G.MTDL.A)의 P0.0/P0.1/P0.5 3개 핀은 5V 입력이 지원되지\r\n"
                                 "않으므로 이 3개 핀은 MISO 핀으로 지정할수 없습니다.\r\n"
                                 "다른 비트 번호로 지정해 주십시요.");

        //[wine 모달유사 지원][2018.03.06.화][추가!!!]{---------
        //if(_ide_option->wine == true) { this->Enabled = true; }
        //}-----------------------------------------------------
        
        return(false);

      }

  //}

  //[반환]
  //{
      //정리한 값을 반환한다.
      (*rPortNum) = portNum;
      (*rMisoNum) = misoNum;
      (*rMosiNum) = mosiNum;
      (*rSckNum)  = sckNum;
      (*rRstNum)  = rstNum;

  //}

  return(true);

}

//------------------------------------------------------------------------------
//[G.M.RC.BASiC 자동제작용]-----------------------------------------------------
//------------------------------------------------------------------------------

bool __fastcall TgmrcbasicMake_DialogBox_Form::Table_VarAdrTable_Read(void)
{
  //[2009.12.05.토][생성!!!]{---------------------------------------------
  //[맷돌] 에 설치된 가상기계의 중요 [변수주소목록] 을 읽어들여 각 변수의
  //[VMOS:절대주소] 를 읽어 들여 해당 [주소관리변수] 에 할당한다.
  //}---------------------------------------------------------------------

  //[VAR]
  //{
      int  i;

  //}

  //[@DATA 읽기]
  //{
      //전역변수 시작위치인 @DATA 를 읽어 들인다.

      //8Byte 수신-------------------------v
      if(ComBus_Read(d_CB_TS_S, d_CB_AK_B, 3, d_Map_Vmos_RegDATA, (DTU1 *)(&_regDATA)) != true) return(false);

  //}

  //[<포트번호> 변수 VMOS:절대주소 읽기]
  //{
      //[!]{--------------------------------------------------
      //8바이트 단위 절대주소값을 반드시 순서대로 읽어들인다.
      //[@DATA + 8*x] 위치.
      //}-----------------------------------------------------

      //순서대로 돼있는 DTU8[] 과 같다.
      for(i = 0; i < 15; i++)
      {
        //크기는 전부 8바이트다.-------------v
        if(ComBus_Read(d_CB_TS_S, d_CB_AK_V, 3, _regDATA + 8*i, (DTU1 *)(&(_tableX[i]))) != true) return(false);

      }

  //}

  //여기까지 현재 맷돌에 설치된 <gmrcbasic_make.gprj> 안의 필요한 전역변수 주소 목록을 얻었다.

  return(true);

}

bool __fastcall TgmrcbasicMake_DialogBox_Form::Table_WR(//테이블 번호.
                                                        int    pTableIndex,
                                                        //쓰기/읽기.
                                                        int    pWrRd,
                                                        //직렬버스상 크기(2^지수 표현).
                                                        //항상 pSize 보다 큰 크기여야 한다.
                                                        int    pCBSize,
                                                        //쓰기/읽기 자료(pTableIndex/pWrRd 에 따라 의미가 달라진다 ).
                                                        void  *prStream)
{
  //[2009.12.05.토][생성!!!]{-----------------------------------------------------
  //맷돌에 설치된 가상기계의 해당 전역변수에 직접 접근하여 쓰기/읽기를 할수 있다.
  //}-----------------------------------------------------------------------------

  if(pWrRd == d_Wr)
  {
    //[쓰기]

    //[직렬버스:V] 를 사용하여 해당 변수에 직접 기록한다.
    if(ComBus_Write(d_CB_TS_S, d_CB_AK_V, pCBSize, _tableX[pTableIndex], (DTU1 *)prStream) != true) return(false);

  }
  else
  {
    //[읽기]

    //[직렬버스:V] 를 사용하여 해당 변수에 직접 기록한다.
    if(ComBus_Read(d_CB_TS_S, d_CB_AK_V, pCBSize, _tableX[pTableIndex], (DTU1 *)prStream) != true) return(false);

  }

  return(true);

}

bool __fastcall TgmrcbasicMake_DialogBox_Form::Mtdl_FlashBuf_Fill(void)
{
  //[2009.12.06][생성!!!]{--------------------------------------------------------------
  //<Ide_System_GmRcBasicGhostFlash_Path> 경로의 <flash.bin> 을 읽어서 맷돌에 설치된
  //가상기계의 해당 공간에 기록해 준다.
  //
  //맷돌자체의 [전용통신포트] 의 저장소는 [1+8+1024] 크기로 최대 1024 바이트를 한꺼번에
  //처리 가능하므로 G.M.RCBASiC 의 영혼 8K 바이트를 8개로 나누어 처리해야 한다.
  //}-----------------------------------------------------------------------------------

  //[VAR]
  //{
      unsigned char  tempBuf[1024*8];

      int            i, j;

      //[2009.12.07.월]
      int            hexFileStartAdr, hexFileEndAdr;


  //}

  //[<flash.hex> 읽기]
  //{
      //[2009.12.07.월][수정!!!]{---
      //tempBuf[] 에 정리해 준다.
      //}---------------------------

      //<flash.hex> 를 읽어서 저장소에 저장한다.
      HEXFILE_Open_InBuffer(Ide_System_GmRcBasicGhostFlash_Path,
                            tempBuf,
                            &hexFileStartAdr,
                            &hexFileEndAdr);

      //[남는 저장소 초기화]
      //{
          //남은 영역은 전부 0xff 로 초기화 한다.
          for(i = (hexFileEndAdr + 1); i < (1024*8); i++) { tempBuf[i] = 0xff; }

      //}

  //}

  //[전송]
  //{
      //[!]{-------------------------------------------------------------------------
      //G.M.RC.BASiC 용 영혼은 총 8K 바이트 이므로 1K 바이트 단위로 나누어 처리한다.
      //}----------------------------------------------------------------------------

      _make_Progress->_Min(0);
      _make_Progress->_Max(7);
      _make_Progress->_Progress(0);
      _make_Progress->Visible = true;

      for(i = 0; i < 8; i++)
      {
        //1024 바이트 단위--------------------v
        if(ComBus_Write(d_CB_TS_S, d_CB_AK_V, 10, _tableX[d_FlashBuf_a2] + (1024*i), (DTU1 *)(&(tempBuf[1024*i]))) != true) goto lbError;

        _make_Progress->_Progress(i);

      }

      _make_Progress->Visible = false;

  //}

  lbOk:
  //{
      //여기까지 모두 전송하였다.
      return(true);

  //}

  lbError:
  //{
      _make_Progress->Visible = false;


      return(false);

  //}

}

bool __fastcall TgmrcbasicMake_DialogBox_Form::Mtdl_EEpBuf_Fill(void)
{
  //[2009.12.06][생성!!!]{-------------------------------------------------------
  //<Ide_System_GmRcBasicGhostEEp_Path> 경로의 <eep.bin> 을 읽어서 맷돌에 설치된
  //가상기계의 해당 공간에 기록해 준다.
  //}----------------------------------------------------------------------------

  //[VAR]
  //{
      unsigned char  tempBuf[512];

      int            i;

      //[2009.12.07.월]
      int            hexFileStartAdr, hexFileEndAdr;

  //}

  //[<eeprom.hex> 읽기]
  //{
      //[2009.12.07.월][수정!!!]{---
      //tempBuf[] 에 정리해 준다.
      //}---------------------------

      //<eeprom.hex> 를 읽어서 저장소에 저장한다.
      HEXFILE_Open_InBuffer(Ide_System_GmRcBasicGhostEEp_Path,
                            tempBuf,
                            &hexFileStartAdr,
                            &hexFileEndAdr);

      //[남는 저장소 초기화]
      //{
          //남은 영역은 전부 0xff 로 초기화 한다.
          for(i = (hexFileEndAdr + 1); i < 512; i++) { tempBuf[i] = 0xff; }

      //}

  //}

  //[전송]
  //{
      //[!]{------------------------------------------------------------------
      //G.M.RC.BASiC 용 EEPROM 은 512 바이트크기 이므로 한번에 처리 가능하다.
      //}---------------------------------------------------------------------

      _make_Progress->_Min(0);
      _make_Progress->_Max(1);
      _make_Progress->_Progress(0);
      _make_Progress->Visible = true;

      //512 바이트 ------------------v
      if(Table_WR(d_EEpBuf_a1, d_Wr, 9, (DTU1 *)tempBuf) != true) goto lbError;

      _make_Progress->_Progress(1);
      _make_Progress->Visible = false;

  //}

  lbOk:
  //{
      //여기까지 모두 전송하였다.
      return(true);

  //}

  lbError:
  //{
      _make_Progress->Visible = false;


      return(false);

  //}

}

bool __fastcall TgmrcbasicMake_DialogBox_Form::Mtdl_GMRCBASiC_Make(void)
{
  //[2009.12.06.일][생성!!!]{------
  //G.M.RC.BASiC 을 자동 완성한다.
  //
  //[2018.03.06.화][수정!!!]-------
  //}------------------------------

  //[VAR]
  //{
      //처리 과정 상태를 알려줄 문자열을 저장한다.
      char  makeStr[OPT_lineStrSize];

      char  errorStr[OPT_lineStrSize];


      DTU1  portNum;
      DTU1  misoNum;
      DTU1  mosiNum;
      DTU1  sckNum;
      DTU1  rstNum;

      DTU1  tempVal;

      DTU4  flashPageCount;
      DTU4  eep16Count;

      int   i;

      //[오류정보]
      //{
          DTU4  eorAdr;
          DTU4  eorWrData;
          DTU4  eorRdData;

      //}

  //}
  
  //[SPI 포트 설정 중복 검사]
  //{
      //[!]{------------------------------------------------------------------
      //현재 설정한 SPI 각 핀들의 비트 번호의 [중복] 여부를 검사하면서 동시에
      //해당 비트 번호값을 전달 받는다.
      //}---------------------------------------------------------------------

      if(Dlg_Spi_Pin(&portNum, &misoNum, &mosiNum, &sckNum, &rstNum) != true) goto lbError;

  //}

  //[<flash.bin> 전송/저장]
  //{
      if(Mtdl_FlashBuf_Fill() != true) goto lbError;

  //}

  //[<eep.bin> 전송/저장]
  //{
      if(Mtdl_EEpBuf_Fill() != true) goto lbError;

  //}

  //[SPI 포트 생성]
  //{
      //검사하면서 얻는 SPI 설정 정보를 사용하여 SPI 포트를 생성한다.

      if(Table_WR(d_PortNum_1, d_Wr, 0, (DTU1 *)(&portNum)) != true) goto lbError;
      if(Table_WR(d_MisoBit_1, d_Wr, 0, (DTU1 *)(&misoNum)) != true) goto lbError;
      if(Table_WR(d_MosiBit_1, d_Wr, 0, (DTU1 *)(&mosiNum)) != true) goto lbError;
      if(Table_WR(d_SckBit_1, d_Wr, 0, (DTU1 *)(&sckNum)) != true) goto lbError;
      if(Table_WR(d_CsBit_1, d_Wr, 0, (DTU1 *)(&rstNum)) != true) goto lbError;

      //[명령처리]
      //{
          //[명령전달]{---------------------------------------------------------------
          tempVal = d_Msg_SpiPortCreat;
          if(Table_WR(d_Msg_1, d_Wr, 0, (DTU1 *)(&tempVal)) != true) goto lbError;
          //
          //[명령처리 요청]-----------------------------------------------------------
          tempVal = true;
          if(Table_WR(d_MsgExe_1, d_Wr, 0, (DTU1 *)(&tempVal)) != true) goto lbError;
          //
          //[<ACK> 확인]--------------------------------------------------------------
          if(ComBus_TimeOut_FwByte(d_CBFW_ACK, 3000) != true) goto lbError;
          //}-------------------------------------------------------------------------

          //[명령 처리 결과 확인]
          //{
              //제대로 처리되지 않은 경우는 여기서 중단한다.
              if(Table_WR(d_MsgResult_1, d_Rd, 0, (DTU1 *)(&tempVal)) != true) goto lbError;

              if(tempVal != true)
              {
                //처리 결과에 오류가 있다.

                //[wine 모달유사 지원][2018.03.06.화][추가!!!]{----------
                //if(_ide_option->wine == true) { this->Enabled = false; }
                //}------------------------------------------------------

                ide_msgbox_Form->_MsgBox(d_MSGBOX_error,
                                         "ISP 에 사용할 SPI 포트를 생성하지 못했습니다.");

                //[wine 모달유사 지원][2018.03.06.화][추가!!!]{---------
                //if(_ide_option->wine == true) { this->Enabled = true; }
                //}-----------------------------------------------------

                goto lbError;

              }

          //}

      //}

  //}

  _make_Label->_Caption("");
  _make_Label->Visible = true;

  //[ISP 상태 진입]
  //{
      STR_Assign(makeStr, "ISP 상태 진입 시작 => ");
      _make_Label->_Caption(makeStr);

      //[명령처리]
      //{
          //[명령전달]{---------------------------------------------------------------
          tempVal = d_MsgIspMode;
          if(Table_WR(d_Msg_1, d_Wr, 0, (DTU1 *)(&tempVal)) != true) goto lbError;
          //
          //[명령처리 요청]-----------------------------------------------------------
          tempVal = true;
          if(Table_WR(d_MsgExe_1, d_Wr, 0, (DTU1 *)(&tempVal)) != true) goto lbError;
          //
          //[<ACK> 확인]--------------------------------------------------------------
          if(ComBus_TimeOut_FwByte(d_CBFW_ACK, 3000) != true) goto lbError;
          //}-------------------------------------------------------------------------

          //[명령 처리 결과 확인]
          //{
              //제대로 처리되지 않은 경우는 여기서 중단한다.
              if(Table_WR(d_MsgResult_1, d_Rd, 0, (DTU1 *)(&tempVal)) != true) goto lbError;

              if(tempVal != true)
              {
                //처리 결과에 오류가 있다.

                //[wine 모달유사 지원][2018.03.06.화][추가!!!]{----------
                //if(_ide_option->wine == true) { this->Enabled = false; }
                //}------------------------------------------------------

                ide_msgbox_Form->_MsgBox(d_MSGBOX_error,
                                         "ISP 시작 상태로 진입하지 못했습니다.");

                //[wine 모달유사 지원][2018.03.06.화][추가!!!]{---------
                //if(_ide_option->wine == true) { this->Enabled = true; }
                //}-----------------------------------------------------

                goto lbError;

              }

          //}

      //}

      STR_Add(makeStr, "완료!\r\n");
      _make_Label->_Caption(makeStr);

  //}

  //[ATmega88 연결 확인]
  //{
      STR_Add(makeStr, "ATmega88 연결 확인 시작 => ");
      _make_Label->_Caption(makeStr);

      //[명령처리]
      //{
          //[명령전달]{---------------------------------------------------------------
          tempVal = d_Msg_IsATmega88;
          if(Table_WR(d_Msg_1, d_Wr, 0, (DTU1 *)(&tempVal)) != true) goto lbError;
          //
          //[명령처리 요청]-----------------------------------------------------------
          tempVal = true;
          if(Table_WR(d_MsgExe_1, d_Wr, 0, (DTU1 *)(&tempVal)) != true) goto lbError;
          //
          //[<ACK> 확인]--------------------------------------------------------------
          if(ComBus_TimeOut_FwByte(d_CBFW_ACK, 3000) != true) goto lbError;
          //}-------------------------------------------------------------------------

          //[명령 처리 결과 확인]
          //{
              //제대로 처리되지 않은 경우는 여기서 중단한다.
              if(Table_WR(d_MsgResult_1, d_Rd, 0, (DTU1 *)(&tempVal)) != true) goto lbError;

              if(tempVal != true)
              {
                //처리 결과에 오류가 있다.

                //[wine 모달유사 지원][2018.03.06.화][추가!!!]{----------
                //if(_ide_option->wine == true) { this->Enabled = false; }
                //}------------------------------------------------------
                
                ide_msgbox_Form->_MsgBox(d_MSGBOX_error,
                                         "생성된 SPI 포트에 ATmega88(20 Mhz)이 연결돼 있지 않습니다.");

                //[wine 모달유사 지원][2018.03.06.화][추가!!!]{---------
                //if(_ide_option->wine == true) { this->Enabled = true; }
                //}-----------------------------------------------------
                                         
                goto lbError;

              }

          //}

      //}

      STR_Add(makeStr, "완료!\r\n");
      _make_Label->_Caption(makeStr);

  //}

  //[전체 지우기]
  //{
      STR_Add(makeStr, "전체 지우기 시작 => ");
      _make_Label->_Caption(makeStr);

      //[명령처리]
      //{
          //[명령전달]{---------------------------------------------------------------
          tempVal = d_Msg_Erase;
          if(Table_WR(d_Msg_1, d_Wr, 0, (DTU1 *)(&tempVal)) != true) goto lbError;
          //
          //[명령처리 요청]-----------------------------------------------------------
          tempVal = true;
          if(Table_WR(d_MsgExe_1, d_Wr, 0, (DTU1 *)(&tempVal)) != true) goto lbError;
          //
          //[<ACK> 확인]--------------------------------------------------------------
          if(ComBus_TimeOut_FwByte(d_CBFW_ACK, 3000) != true) goto lbError;
          //}-------------------------------------------------------------------------

          //[명령 처리 결과 확인]
          //{
              //제대로 처리되지 않은 경우는 여기서 중단한다.
              if(Table_WR(d_MsgResult_1, d_Rd, 0, (DTU1 *)(&tempVal)) != true) goto lbError;

              if(tempVal != true)
              {
                //처리 결과에 오류가 있다.

                //[wine 모달유사 지원][2018.03.06.화][추가!!!]{----------
                //if(_ide_option->wine == true) { this->Enabled = false; }
                //}------------------------------------------------------

                ide_msgbox_Form->_MsgBox(d_MSGBOX_error,
                                         "[전체 지우기] 가 제대로 수행되지 못했습니다.");

                //[wine 모달유사 지원][2018.03.06.화][추가!!!]{---------
                //if(_ide_option->wine == true) { this->Enabled = true; }
                //}-----------------------------------------------------

                goto lbError;

              }

          //}

      //}

      STR_Add(makeStr, "완료!\r\n");
      _make_Label->_Caption(makeStr);

  //}

  //[Flash 기록]
  //{
      STR_Add(makeStr, "FLASH 기록 시작 => ");
      _make_Label->_Caption(makeStr);

      //[FLASH 페이지 총 수 구하기]
      //{
          //[!]{--------------------------------------------------------------
          //맷돌에 설치된 가상기계에 정리되 있는 <Flash 페이지 총수를 구한다.
          //이는 <페이지 단위> 로 기록하기 때문이다.
          //}-----------------------------------------------------------------

          if(Table_WR(d_FlashPageCount_4, d_Rd, 2, (DTU1 *)(&flashPageCount)) != true) goto lbError;

      //}

      //[명령처리]
      //{
          _make_Progress->_Min(0);
          _make_Progress->_Max(flashPageCount - 1);
          _make_Progress->_Progress(0);
          _make_Progress->Visible = true;

          for(i = 0; i < flashPageCount; i++)
          {
            if(i == 0)
            {
              //[명령전달]{---------------------------------------------------------------
              tempVal = d_Msg_FlashWrite;
              if(Table_WR(d_Msg_1, d_Wr, 0, (DTU1 *)(&tempVal)) != true) goto lbError;
              //
              //[명령처리 요청]-----------------------------------------------------------
              tempVal = true;
              if(Table_WR(d_MsgExe_1, d_Wr, 0, (DTU1 *)(&tempVal)) != true) goto lbError;
              //}-------------------------------------------------------------------------

            }
            else
            {
              //[명령전달]{---------------------------------------------------------------
              tempVal = d_Msg_Next;
              if(Table_WR(d_Msg_1, d_Wr, 0, (DTU1 *)(&tempVal)) != true) goto lbError;
              //
              //[명령처리 요청]-----------------------------------------------------------
              tempVal = true;
              if(Table_WR(d_MsgExe_1, d_Wr, 0, (DTU1 *)(&tempVal)) != true) goto lbError;
              //}-------------------------------------------------------------------------

            }

            //[<ACK> 확인]{---------------------------------------------------
            if(ComBus_TimeOut_FwByte(d_CBFW_ACK, 3000) != true) goto lbError;
            //}---------------------------------------------------------------

            //[명령 처리 결과 확인]
            //{
                //제대로 처리되지 않은 경우는 여기서 중단한다.
                if(Table_WR(d_MsgResult_1, d_Rd, 0, (DTU1 *)(&tempVal)) != true) goto lbError;

                if(tempVal != true)
                {
                  //[명령전달]{---------------------------------------------------------------
                  //오류가 난 경우는 아직 [무한반복문] 에 들어있을수 있으므로 강제종료시킨다.
                  tempVal = d_Msg_Quit;
                  if(Table_WR(d_Msg_1, d_Wr, 0, (DTU1 *)(&tempVal)) != true) goto lbError;
                  //}-------------------------------------------------------------------------

                  //처리 결과에 오류가 있다.

                  //[wine 모달유사 지원][2018.03.06.화][추가!!!]{----------
                  //if(_ide_option->wine == true) { this->Enabled = false; }
                  //}------------------------------------------------------

                  ide_msgbox_Form->_MsgBox(d_MSGBOX_error,
                                           "[FLASH 기록] 이 제대로 수행되지 못했습니다.");

                  //[wine 모달유사 지원][2018.03.06.화][추가!!!]{---------
                  //if(_ide_option->wine == true) { this->Enabled = true; }
                  //}-----------------------------------------------------

                  goto lbError;

                }

            //}

            _make_Progress->_Progress(i);

          }
          
          _make_Progress->Visible = false;

      //}

      STR_Add(makeStr, "완료!\r\n");
      _make_Label->_Caption(makeStr);

  //}

  //[Flash 확인]
  //{
      STR_Add(makeStr, "FLASH 확인 시작 => ");
      _make_Label->_Caption(makeStr);

      //[명령처리]
      //{
          _make_Progress->_Min(0);
          _make_Progress->_Max(flashPageCount - 1);
          _make_Progress->_Progress(0);
          _make_Progress->Visible = true;

          for(i = 0; i < flashPageCount; i++)
          {
            if(i == 0)
            {
              //[명령전달]{---------------------------------------------------------------
              tempVal = d_Msg_FlashVerify;
              if(Table_WR(d_Msg_1, d_Wr, 0, (DTU1 *)(&tempVal)) != true) goto lbError;
              //
              //[명령처리 요청]-----------------------------------------------------------
              tempVal = true;
              if(Table_WR(d_MsgExe_1, d_Wr, 0, (DTU1 *)(&tempVal)) != true) goto lbError;
              //}-------------------------------------------------------------------------

            }
            else
            {
              //[명령전달]{---------------------------------------------------------------
              tempVal = d_Msg_Next;
              if(Table_WR(d_Msg_1, d_Wr, 0, (DTU1 *)(&tempVal)) != true) goto lbError;
              //
              //[명령처리 요청]-----------------------------------------------------------
              tempVal = true;
              if(Table_WR(d_MsgExe_1, d_Wr, 0, (DTU1 *)(&tempVal)) != true) goto lbError;
              //}-------------------------------------------------------------------------

            }

            //[<ACK> 확인]{---------------------------------------------------
            if(ComBus_TimeOut_FwByte(d_CBFW_ACK, 3000) != true) goto lbError;
            //}---------------------------------------------------------------

            //[명령 처리 결과 확인]
            //{
                //제대로 처리되지 않은 경우는 여기서 중단한다.
                if(Table_WR(d_MsgResult_1, d_Rd, 0, (DTU1 *)(&tempVal)) != true) goto lbError;

                if(tempVal != true)
                {
                  //[명령전달]{---------------------------------------------------------------
                  //오류가 난 경우는 아직 [무한반복문] 에 들어있을수 있으므로 강제종료시킨다.
                  tempVal = d_Msg_Quit;
                  if(Table_WR(d_Msg_1, d_Wr, 0, (DTU1 *)(&tempVal)) != true) goto lbError;
                  //
                  //[명령처리 요청]-----------------------------------------------------------
                  tempVal = true;
                  if(Table_WR(d_MsgExe_1, d_Wr, 0, (DTU1 *)(&tempVal)) != true) goto lbError;
                  //}-------------------------------------------------------------------------

                  //[오류 정보 읽기]
                  //{
                      if(Table_WR(d_EorAdr_4,    d_Rd, 2, (DTU1 *)(&eorAdr))    != true) goto lbError;
                      if(Table_WR(d_EorWrData_4, d_Rd, 2, (DTU1 *)(&eorWrData)) != true) goto lbError;
                      if(Table_WR(d_EorRdData_4, d_Rd, 2, (DTU1 *)(&eorRdData)) != true) goto lbError;

                  //}

                  //[오류 문자열 만들기]
                  //{
                      STR_Assign(errorStr, "FLASH 확인 중 오류가 발견 되었습니다.\r\n\r\n");

                      STR_Add(errorStr, "[주소값] : 0x");
                      CONV_LongVal_To_Hex(eorAdr, 8, &(errorStr[STR_Length(errorStr)]));
                      STR_Add(errorStr, "\r\n");

                      STR_Add(errorStr, "[쓰기값] : 0x");
                      CONV_LongVal_To_Hex(eorWrData, 4, &(errorStr[STR_Length(errorStr)]));
                      STR_Add(errorStr, "\r\n");

                      STR_Add(errorStr, "[읽기값] : 0x");
                      CONV_LongVal_To_Hex(eorRdData, 4, &(errorStr[STR_Length(errorStr)]));
                      STR_Add(errorStr, "\r\n");

                  //}

                  //처리 결과에 오류가 있다.

                  //[wine 모달유사 지원][2018.03.06.화][추가!!!]{----------
                  //if(_ide_option->wine == true) { this->Enabled = false; }
                  //}------------------------------------------------------

                  ide_msgbox_Form->_MsgBox(d_MSGBOX_error, errorStr);

                  //[wine 모달유사 지원][2018.03.06.화][추가!!!]{---------
                  //if(_ide_option->wine == true) { this->Enabled = true; }
                  //}-----------------------------------------------------
                
                  goto lbError;

                }

            //}

            _make_Progress->_Progress(i);

          }
          
          _make_Progress->Visible = false;

      //}

      STR_Add(makeStr, "완료!\r\n");
      _make_Label->_Caption(makeStr);

  //}

  //[EEprom 기록]
  //{
      STR_Add(makeStr, "EEPROM 기록 시작 => ");
      _make_Label->_Caption(makeStr);

      //[EEPROM 페이지 총 수 구하기]
      //{
          //[!]{--------------------------------------------------------------
          //맷돌에 설치된 가상기계에 정리되 있는 <Flash 페이지 총수를 구한다.
          //이는 <페이지 단위> 로 기록하기 때문이다.
          //}-----------------------------------------------------------------

          if(Table_WR(d_EEp16Count_4, d_Rd, 2, (DTU1 *)(&eep16Count)) != true) goto lbError;

      //}

      //[명령처리]
      //{
          _make_Progress->_Min(0);
          _make_Progress->_Max(eep16Count - 1);
          _make_Progress->_Progress(0);
          _make_Progress->Visible = true;

          for(i = 0; i < eep16Count; i++)
          {
            if(i == 0)
            {
              //[명령전달]{---------------------------------------------------------------
              tempVal = d_Msg_EEpromWrite;
              if(Table_WR(d_Msg_1, d_Wr, 0, (DTU1 *)(&tempVal)) != true) goto lbError;
              //
              //[명령처리 요청]-----------------------------------------------------------
              tempVal = true;
              if(Table_WR(d_MsgExe_1, d_Wr, 0, (DTU1 *)(&tempVal)) != true) goto lbError;
              //}-------------------------------------------------------------------------

            }
            else
            {
              //[명령전달]{---------------------------------------------------------------
              tempVal = d_Msg_Next;
              if(Table_WR(d_Msg_1, d_Wr, 0, (DTU1 *)(&tempVal)) != true) goto lbError;
              //
              //[명령처리 요청]-----------------------------------------------------------
              tempVal = true;
              if(Table_WR(d_MsgExe_1, d_Wr, 0, (DTU1 *)(&tempVal)) != true) goto lbError;
              //}-------------------------------------------------------------------------

            }

            //[<ACK> 확인]{---------------------------------------------------
            if(ComBus_TimeOut_FwByte(d_CBFW_ACK, 3000) != true) goto lbError;
            //}---------------------------------------------------------------

            //[명령 처리 결과 확인]
            //{
                //제대로 처리되지 않은 경우는 여기서 중단한다.
                if(Table_WR(d_MsgResult_1, d_Rd, 0, (DTU1 *)(&tempVal)) != true) goto lbError;

                if(tempVal != true)
                {
                  //[명령전달]{---------------------------------------------------------------
                  //오류가 난 경우는 아직 [무한반복문] 에 들어있을수 있으므로 강제종료시킨다.
                  tempVal = d_Msg_Quit;
                  if(Table_WR(d_Msg_1, d_Wr, 0, (DTU1 *)(&tempVal)) != true) goto lbError;
                  //}-------------------------------------------------------------------------

                  //처리 결과에 오류가 있다.

                  //[wine 모달유사 지원][2018.03.06.화][추가!!!]{----------
                  //if(_ide_option->wine == true) { this->Enabled = false; }
                  //}------------------------------------------------------

                  ide_msgbox_Form->_MsgBox(d_MSGBOX_error,
                                           "[EEPROM 기록] 이 제대로 수행되지 못했습니다.");

                  //[wine 모달유사 지원][2018.03.06.화][추가!!!]{---------
                  //if(_ide_option->wine == true) { this->Enabled = true; }
                  //}-----------------------------------------------------

                  goto lbError;

                }

            //}

            _make_Progress->_Progress(i);

          }
          
          _make_Progress->Visible = false;

      //}

      STR_Add(makeStr, "완료!\r\n");
      _make_Label->_Caption(makeStr);

  //}

  //[EEprom 확인]
  //{
      STR_Add(makeStr, "EEPROM 확인 시작 => ");
      _make_Label->_Caption(makeStr);

      //[명령처리]
      //{
          _make_Progress->_Min(0);
          _make_Progress->_Max(eep16Count - 1);
          _make_Progress->_Progress(0);
          _make_Progress->Visible = true;

          for(i = 0; i < eep16Count; i++)
          {
            if(i == 0)
            {
              //[명령전달]{---------------------------------------------------------------
              tempVal = d_Msg_EEpromVerify;
              if(Table_WR(d_Msg_1, d_Wr, 0, (DTU1 *)(&tempVal)) != true) goto lbError;
              //
              //[명령처리 요청]-----------------------------------------------------------
              tempVal = true;
              if(Table_WR(d_MsgExe_1, d_Wr, 0, (DTU1 *)(&tempVal)) != true) goto lbError;
              //}-------------------------------------------------------------------------

            }
            else
            {
              //[명령전달]{---------------------------------------------------------------
              tempVal = d_Msg_Next;
              if(Table_WR(d_Msg_1, d_Wr, 0, (DTU1 *)(&tempVal)) != true) goto lbError;
              //
              //[명령처리 요청]-----------------------------------------------------------
              tempVal = true;
              if(Table_WR(d_MsgExe_1, d_Wr, 0, (DTU1 *)(&tempVal)) != true) goto lbError;
              //}-------------------------------------------------------------------------

            }

            //[<ACK> 확인]{---------------------------------------------------
            if(ComBus_TimeOut_FwByte(d_CBFW_ACK, 3000) != true) goto lbError;
            //}---------------------------------------------------------------

            //[명령 처리 결과 확인]
            //{
                //제대로 처리되지 않은 경우는 여기서 중단한다.
                if(Table_WR(d_MsgResult_1, d_Rd, 0, (DTU1 *)(&tempVal)) != true) goto lbError;

                if(tempVal != true)
                {
                  //[명령전달]{---------------------------------------------------------------
                  //오류가 난 경우는 아직 [무한반복문] 에 들어있을수 있으므로 강제종료시킨다.
                  tempVal = d_Msg_Quit;
                  if(Table_WR(d_Msg_1, d_Wr, 0, (DTU1 *)(&tempVal)) != true) goto lbError;
                  //
                  //[명령처리 요청]-----------------------------------------------------------
                  tempVal = true;
                  if(Table_WR(d_MsgExe_1, d_Wr, 0, (DTU1 *)(&tempVal)) != true) goto lbError;
                  //}-------------------------------------------------------------------------

                  //[오류 정보 읽기]
                  //{
                      if(Table_WR(d_EorAdr_4,    d_Rd, 2, (DTU1 *)(&eorAdr))    != true) goto lbError;
                      if(Table_WR(d_EorWrData_4, d_Rd, 2, (DTU1 *)(&eorWrData)) != true) goto lbError;
                      if(Table_WR(d_EorRdData_4, d_Rd, 2, (DTU1 *)(&eorRdData)) != true) goto lbError;

                  //}

                  //[오류 문자열 만들기]
                  //{
                      STR_Assign(errorStr, "EEPROM 확인 중 오류가 발견 되었습니다.\r\n\r\n");

                      STR_Add(errorStr, "[주소값] : 0x");
                      CONV_LongVal_To_Hex(eorAdr, 8, &(errorStr[STR_Length(errorStr)]));
                      STR_Add(errorStr, "\r\n");

                      STR_Add(errorStr, "[쓰기값] : 0x");
                      CONV_LongVal_To_Hex(eorWrData, 4, &(errorStr[STR_Length(errorStr)]));
                      STR_Add(errorStr, "\r\n");

                      STR_Add(errorStr, "[읽기값] : 0x");
                      CONV_LongVal_To_Hex(eorRdData, 4, &(errorStr[STR_Length(errorStr)]));
                      STR_Add(errorStr, "\r\n");

                  //}

                  //처리 결과에 오류가 있다.

                  //[wine 모달유사 지원][2018.03.06.화][추가!!!]{----------
                  //if(_ide_option->wine == true) { this->Enabled = false; }
                  //}------------------------------------------------------

                  ide_msgbox_Form->_MsgBox(d_MSGBOX_error, errorStr);

                  //[wine 모달유사 지원][2018.03.06.화][추가!!!]{---------
                  //if(_ide_option->wine == true) { this->Enabled = true; }
                  //}-----------------------------------------------------

                  goto lbError;

                }

            //}

            _make_Progress->_Progress(i);

          }
          
          _make_Progress->Visible = false;

      //}

      STR_Add(makeStr, "완료!\r\n");
      _make_Label->_Caption(makeStr);

  //}

  //[보안설정]
  //{
      STR_Add(makeStr, "보안 설정 시작 => ");
      _make_Label->_Caption(makeStr);

      //[명령처리]
      //{
          //[명령전달]{---------------------------------------------------------------
          tempVal = d_Msg_Lock;
          if(Table_WR(d_Msg_1, d_Wr, 0, (DTU1 *)(&tempVal)) != true) goto lbError;
          //
          //[명령처리 요청]-----------------------------------------------------------
          tempVal = true;
          if(Table_WR(d_MsgExe_1, d_Wr, 0, (DTU1 *)(&tempVal)) != true) goto lbError;
          //
          //[<ACK> 확인]--------------------------------------------------------------
          if(ComBus_TimeOut_FwByte(d_CBFW_ACK, 3000) != true) goto lbError;
          //}-------------------------------------------------------------------------

          //[명령 처리 결과 확인]
          //{
              //제대로 처리되지 않은 경우는 여기서 중단한다.
              if(Table_WR(d_MsgResult_1, d_Rd, 0, (DTU1 *)(&tempVal)) != true) goto lbError;

              if(tempVal != true)
              {
                //처리 결과에 오류가 있다.

                //[wine 모달유사 지원][2018.03.06.화][추가!!!]{----------
                //if(_ide_option->wine == true) { this->Enabled = false; }
                //}------------------------------------------------------

                ide_msgbox_Form->_MsgBox(d_MSGBOX_error,
                                         "[보안 설정] 이 제대로 수행되지 못했습니다.");

                //[wine 모달유사 지원][2018.03.06.화][추가!!!]{---------
                //if(_ide_option->wine == true) { this->Enabled = true; }
                //}-----------------------------------------------------

                goto lbError;

              }

          //}

      //}

      STR_Add(makeStr, "완료!\r\n");
      _make_Label->_Caption(makeStr);

  //}

  //[SPI 포트 생성]
  //{
      //ISP 에 사용한 SPI 포트를 동적 삭제한다.

      //[명령처리]
      //{
          //[명령전달]{---------------------------------------------------------------
          tempVal = d_Msg_SpiPortDelete;
          if(Table_WR(d_Msg_1, d_Wr, 0, (DTU1 *)(&tempVal)) != true) goto lbError;
          //
          //[명령처리 요청]-----------------------------------------------------------
          tempVal = true;
          if(Table_WR(d_MsgExe_1, d_Wr, 0, (DTU1 *)(&tempVal)) != true) goto lbError;
          //
          //[<ACK> 확인]--------------------------------------------------------------
          if(ComBus_TimeOut_FwByte(d_CBFW_ACK, 3000) != true) goto lbError;
          //}-------------------------------------------------------------------------

          //[명령 처리 결과 확인]
          //{
              //제대로 처리되지 않은 경우는 여기서 중단한다.
              if(Table_WR(d_MsgResult_1, d_Rd, 0, (DTU1 *)(&tempVal)) != true) goto lbError;

              if(tempVal != true)
              {
                //처리 결과에 오류가 있다.

                //[wine 모달유사 지원][2018.03.06.화][추가!!!]{----------
                //if(_ide_option->wine == true) { this->Enabled = false; }
                //}------------------------------------------------------

                ide_msgbox_Form->_MsgBox(d_MSGBOX_error,
                                         "ISP 에 사용한 SPI 포트를 삭제하지 못했습니다.");

                //[wine 모달유사 지원][2018.03.06.화][추가!!!]{---------
                //if(_ide_option->wine == true) { this->Enabled = true; }
                //}-----------------------------------------------------

                goto lbError;

              }

          //}

      //}

  //}

  lbOk:
  //{
      //잠깐 동안 출력 상태를 보여준다.
      Sleep(500);

      _make_Label->Visible    = false;
      _make_Progress->Visible = false;

      return(true);

  //}

  lbError:
  //{
      _make_Label->Visible    = false;
      _make_Progress->Visible = false;

      return(false);

  //}

}

void __fastcall TgmrcbasicMake_DialogBox_Form::captionMoveTimerTimer(
      TObject *Sender)
{
  //[2018.03.04.일][생성!!!]{---------------------------
  //[Linux:wine] 에서 [제목줄:이동] 을 지원하기 위한것.
  //}---------------------------------------------------

  //[VAR]
  //{
      TPoint  mousePos;

  //}

  //[위치 수정]                  
  //{
      //[!]{-----------------------------------------------------------------------------
      //이전 방식은 <Linux:wine> 에서는 빠르게 이동하는 경우 [떨림] 현상이 생기고
      //이동이 끊어지는 문제가 발생.
      //이는 <Linux:wine> 에서 [제목줄] 밖으로 [화면지정자] 가 나가는 경우를 제대로
      //처리하지 못하는 문제인듯.
      //따라서, 기존처럼 [상대좌표] 를 사용하지 않고 [절대좌표] 를 사용하는 것으로 수정.
      //}--------------------------------------------------------------------------------

      //[마우스 절대 위치 얻기]
      //{
          //화면상의 [마우스] 절대 위치를 얻는다.
          GetCursorPos(&mousePos);

      //}

      //[이동]
      //{
          //[2018.03.17.토][수정!!!]{---------------------------------
          //현재 <this> 위치와 [마우스] 위치 간의 거리를
          //항상 같은 거리로 유지하는 방법으로 [제목줄 이동] 을 구현.
          //자세한 내용은 [제목줄 이동] 관련 부분 설명 연관 참고.
          //}---------------------------------------------------------
          
          this->Left = mousePos.x - deltaLeft;
          this->Top  = mousePos.y - deltaTop;

      //}

  //}

}






