

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


#include <vcl.h>
#pragma hdrstop

#include "servoZero_DialogBox.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TservoZero_DialogBox_Form *servoZero_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.11.21.토][추가!!!]
#include "matdol.h"

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


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

void __fastcall TservoZero_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 TservoZero_DialogBox_Form::TservoZero_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    = 500;
      this->Height   = 172;
      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, " RC서보모터 영점조정 대화상자 ");

      //높이 지정.
      _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;

          //}

      //}

  //}

  //[내부 부품들]
  //{
      //[PWM 선택 라벨]
      //{
          _pwmSelect_Label          = new Tgui_Label_Form(this);
          _pwmSelect_Label->Parent  = this;
          _pwmSelect_Label->Visible = true;

          _pwmSelect_Label->_Width(this->Width - 20);
          _pwmSelect_Label->_Left(8);
          _pwmSelect_Label->_Top(28);
          _pwmSelect_Label->_FontColor(_ide_option->color_0);
          _pwmSelect_Label->_Caption("현재 대상 PWM 채널 : [ PWM00 ]");
          _pwmSelect_Label->_Border(false);

      //}

      //[줄이동자 관련 설정]
      //{
          //[시작값 라벨]
          //{
              _pwmDutyStart_Label          = new Tgui_Label_Form(this);
              _pwmDutyStart_Label->Parent  = this;
              _pwmDutyStart_Label->Visible = true;

              _pwmDutyStart_Label->_Width(50);
              _pwmDutyStart_Label->_Left(_pwmSelect_Label->Left);
              _pwmDutyStart_Label->_Top(_pwmSelect_Label->Top + _pwmSelect_Label->Height + 4);
              _pwmDutyStart_Label->_FontColor(_ide_option->color_0);
              _pwmDutyStart_Label->_Caption("0");
              _pwmDutyStart_Label->_Border(false);

          //}

          //[듀티값 보기 문자열]
          //{
              _pwmDuty_Edit          = new Tgui_edit_Form(this);
              _pwmDuty_Edit->Parent  = this;
              _pwmDuty_Edit->Visible = true;

              //[초기화]{-------------------------------------------------------------------
              _pwmDuty_Edit->_Width(36);
              _pwmDuty_Edit->Left = (this->Width/2 - _pwmDuty_Edit->Width/2);
              _pwmDuty_Edit->Top  = (_pwmSelect_Label->Top + _pwmSelect_Label->Height + 4);
              _pwmDuty_Edit->_EDIT_TextOut("1500");
              //}---------------------------------------------------------------------------

              //[2009.05.09.토][추가!!!]
              _pwmDuty_Edit->_EVENT_KeyEnter = _EVENT_KeyEnter_pwmDuty_Edit;

          //}

          //[끝값 라벨]
          //{
              _pwmDutyEnd_Label          = new Tgui_Label_Form(this);
              _pwmDutyEnd_Label->Parent  = this;
              _pwmDutyEnd_Label->Visible = true;

              _pwmDutyEnd_Label->_Width(36);
              _pwmDutyEnd_Label->_Left(this->Width - _pwmDutyEnd_Label->Width - 8);
              _pwmDutyEnd_Label->_Top(_pwmSelect_Label->Top + _pwmSelect_Label->Height + 4);
              _pwmDutyEnd_Label->_FontColor(_ide_option->color_0);
              _pwmDutyEnd_Label->_Caption("5000");
              _pwmDutyEnd_Label->_Border(false);

          //}

          //[듀티값 줄이동자]
          //{
              //전체 설정을 수직으로 줄이동할 [수직 줄이동자] 를 배치한다.

              _pwmDuty_ScrollH          = new Tgui_scroll_h_Form(this);
              _pwmDuty_ScrollH->Parent  = this;
              _pwmDuty_ScrollH->Visible = true;

              _pwmDuty_ScrollH->_Left(8);
              _pwmDuty_ScrollH->_Top(_pwmDuty_Edit->Top + _pwmDuty_Edit->Height + 4);
              _pwmDuty_ScrollH->_Width(this->Width - 16);

              _pwmDuty_ScrollH->_Min(0);
              _pwmDuty_ScrollH->_Max(5000);
              _pwmDuty_ScrollH->_DesignSize(500);
              _pwmDuty_ScrollH->_Position(1500);

              //[EVENT 함수]
              //{
                  _pwmDuty_ScrollH->_EVENT_Scroll = _EVENT_Scroll_pwmDuty_ScrollH;

              //}

          //}

      //}

      //[PWM 선택 라디오버튼]
      //{
          for(i = 0; i < 12; i++)
          {
            //[라벨 설정]
            //{
                _pwm_Label[i]          = new Tgui_Label_Form(this);
                _pwm_Label[i]->Parent  = this;
                _pwm_Label[i]->Visible = true;

                _pwm_Label[i]->_Width(20);
                _pwm_Label[i]->_Height(12);
                _pwm_Label[i]->_Left(9 + (this->Width/12 + 1)*i);
                _pwm_Label[i]->_Top(_pwmDuty_ScrollH->Top + _pwmDuty_ScrollH->Height + 8);
                _pwm_Label[i]->_FontXY(0,0);
                _pwm_Label[i]->_FontColor(_ide_option->color_0);

                //[PWM 번호 구하기]
                //{
                    CONV_LongVal_To_Str(((i/4)*10) + (i%4), 2, false, tempWord);

                _pwm_Label[i]->_Caption(tempWord);

            //}

            //[라디오 버튼 ]
            //{
                _pwm_RadioBtn[i]          = new Tgui_radio_button_Form(this);
                _pwm_RadioBtn[i]->Parent  = this;
                _pwm_RadioBtn[i]->Visible = true;

                _pwm_RadioBtn[i]->_Left(_pwm_Label[i]->Left + 4);
                _pwm_RadioBtn[i]->_Top(_pwm_Label[i]->Top + _pwm_Label[i]->Height + 2);

                _pwm_RadioBtn[i]->_EVENT_Down = _EVENT_Down_pwm_RadioBtn;
                _pwm_RadioBtn[i]->_EVENT_Click = _EVENT_Click_pwm_RadioBtn;

            //}

          }

      //}

      //[PWM 선택 설명 라벨]
      //{
          //[2009.11.21.토][추가!!!]{----------
          //기능자체의 간단한 설명을 추가한다.
          //}----------------------------------

          _pwmText_Label          = new Tgui_Label_Form(this);
          _pwmText_Label->Parent  = this;
          _pwmText_Label->Visible = true;

          _pwmText_Label->_Width(this->Width - 16);
          _pwmText_Label->_Height(46);
          _pwmText_Label->_Left(8);
          _pwmText_Label->_Top(_pwm_RadioBtn[0]->Top + _pwm_RadioBtn[0]->Height + 6);

          _pwmText_Label->_FontXY(2,2);

          //_pwmText_Label->_FontColor(_ide_option->color_0);
          _pwmText_Label->_Caption
          ("RC 서보모터가 연결된 PWM 채널을 선택후 [수평줄이동자] 를 움직이면 해당\r\n"
           "서보가 움직이게 됩니다. 이때 가운데 나오는 값이 현재 [듀티값] 으로 해당\r\n"
           "각도위치에서 이 값을 [영점값] 으로 사용하면 됩니다.");
          _pwmText_Label->_Border(false);

      //}

  //}

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

  //}

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

  //}
                               
  return;

}

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

  //[VAR]
  //{
      int  i;

  //}

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

  for(i = 0; i < 12; i++)
  {
    if(_pwm_Label[i] != NULL) { delete _pwm_Label[i]; _pwm_Label[i] = NULL; }

    if(_pwm_RadioBtn[i] != NULL) { delete _pwm_RadioBtn[i]; _pwm_RadioBtn[i] = NULL; }

  }

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

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

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

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

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

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

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

}

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

void __fastcall TservoZero_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 TservoZero_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 TservoZero_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 TservoZero_DialogBox_Form::_Draw(void)
{
  BitBlt(this->Canvas->Handle, 0, 0,
         this->Width, this->Height,
         _bmp_->Canvas->Handle, 0, 0, SRCCOPY);

  return;

}

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

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

      this->Width  = pWidth;

  //}

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

  //}

  return;

}

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

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

      this->Height  = pHeight;

  //}

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

  //}

  return;

}

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

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

  this->Close();

  return;

}

void __fastcall TservoZero_DialogBox_Form::_EVENT_KeyEnter_pwmDuty_Edit(void)
{
  //[2009.11.21.토][생성!!!]{--------------------------------------------------
  //듀티값을 직접 사용자가 설정할수 있도록 해당 문자열을 검사하고, 값의 범위를
  //검사하여 이상이 없는 경우는 최종적으로 이 [듀티값] 을 실제 설정해 준다.
  //
  //[수평줄이동자] 에 즉시 반영하면 이 수평줄이동자의 [동작함수] 에서 자동으로
  //해당 값에 해당하는 [듀티값] 이 맷돌에 설정되므로 여기서 맷돌에 직접 설정할
  //필요는 없다.
  //}--------------------------------------------------------------------------

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

      int    nowDuty;
      int    i;

  //}

  //[현재 설정 듀티값 저장]
  //{
      //설정이 잘못된 경우 복구하기 위한 현재 설정값을 저장한다.
      nowDuty = _pwmDuty_ScrollH->_position;

  //}

  //[10진수 인지 학인]
  //{
      if(STR_Is_Dec(_pwmDuty_Edit->_editbuf) != true)
      {
        //[!]{-------------------------------------------------------
        //10진수 문자열이 아닌 것이다.
        //오류 알림글은 STR_Is_Dec() 함수 내부적으로 자동 처리 된다.
        //}----------------------------------------------------------

        goto lbError;

      }

  //}

  //[문자열 => 값 으로 변환]
  //{
      CONV_DecStr_To_IntVal(_pwmDuty_Edit->_editbuf, &tempVal);

  //}

  //[값 범위 확인]
  //{
      if((0 <= tempVal) && (tempVal <= 5000))
      {
        //이상없는 값을 여기서 할당한다.
        goto lbOk;

      }
      else
      {
        //이전 설정값이 그대로 남아 있게 된다.
        ide_msgbox_Form->_MsgBox(d_MSGBOX_error,
                                 "0 - 5000 사이의 값만 사용할수 있습니다.");

        goto lbError;

      }

  //}

  lbOk:
  //{
      //이상없이 완료된 경우.

      //[값 => 문자열로 변환]
      //{
          CONV_LongVal_To_Str(tempVal, 4, false, tempStr);

      //}

      //4개 자리수로 표시해준다.
      _pwmDuty_Edit->_EDIT_TextOut(tempStr);


      //[수평줄이동자 설정]
      //{
          _pwmDuty_ScrollH->_Position(tempVal);

      //}

      //[현재 듀티값 맷돌에 설정]
      //{
          //[!]{---------------------------------------------------------------
          //실제 맷돌에 [직렬버스] 를 사용하여 설정하므로 전용함수를 사용한다.
          //단, 선택된 PWM 채널이 있는 경우만 처리해야 한다.
          //}------------------------------------------------------------------

          for(i = 0; i < 12; i++)
          {
            if(_pwm_RadioBtn[i]->_checked == true)
            {
              //PWM번호(i/4), 채널번호(i%4) 가 된다.

              //[듀티값 설정]
              //{
                  Matdol_Pwm_Duty_Write(i/4, i%4, _pwmDuty_ScrollH->_position);

              //}

              //선택된 것만 처리하고 종료한다.
              return;

            }

          }

      //}

      return;

  //}

  lbError:
  //{
      //처리중 오류가 생긴 경우는 원래 값으로 돌려 놓는다.

      //[값 => 문자열로 변환]
      //{
          CONV_LongVal_To_Str(nowDuty, 4, false, tempStr);

      //}

      //원상복구.
      _pwmDuty_Edit->_EDIT_TextOut(tempStr);

      return;

  //}

}

void __fastcall TservoZero_DialogBox_Form::_EVENT_Scroll_pwmDuty_ScrollH(void)
{
  //[2009.11.20.금][생성!!!]{---------------------------------------------
  //현재 듀티비를 보여주고 맷돌에 직접 해당 채널에 직접 설정해 준다.
  //이는 맷돌에 직접 직렬버스로 접근하므로 전용 함수를 사용하여 처리한다.
  //}---------------------------------------------------------------------

  //[VAR]
  //{
      char  tempStr[OPT_lineStrSize] = {""};

      int   tempVal;

      int   i;

  //}

  //[중복 확인]
  //{
      //현재 표시 문자열을 값으로 바꾼다.
      CONV_DecStr_To_IntVal(_pwmDuty_Edit->_editbuf, &tempVal);

      //값에 변화가 없는 경우는 처리하지 않는다.
      if(_pwmDuty_ScrollH->_position == tempVal) return;

  //}

  //[현재 듀티값 표시해주기]
  //{
      //값을 문자열로 변환한다.
      CONV_LongVal_To_Str(_pwmDuty_ScrollH->_position, 4, false, tempStr);

      _pwmDuty_Edit->_EDIT_TextOut(tempStr);

  //}

  //[현재 듀티값 맷돌에 설정]
  //{
      //[!]{---------------------------------------------------------------
      //실제 맷돌에 [직렬버스] 를 사용하여 설정하므로 전용함수를 사용한다.
      //단, 선택된 PWM 채널이 있는 경우만 처리해야 한다.
      //}------------------------------------------------------------------

      for(i = 0; i < 12; i++)
      {
        if(_pwm_RadioBtn[i]->_checked == true)
        {
          //PWM번호(i/4), 채널번호(i%4) 가 된다.

          //[듀티값 설정]
          //{
              Matdol_Pwm_Duty_Write(i/4, i%4, _pwmDuty_ScrollH->_position);

          //}

          //선택된 것만 처리하고 종료한다.
          return;

        }

      }

  //}

  return;

}

void __fastcall TservoZero_DialogBox_Form::_EVENT_Down_pwm_RadioBtn(void)
{
  //[2009.11.20.금][생성!!!]{---------------------------------------------------
  //PWM 채널중 선택된것만 남기고 나머지는 전부 해제한다.
  //각각의 버튼은 배타적인 속성을 가지므로 아직 선택되기 전인 <EVENT_Down> 에서
  //이를 처리해 주어야 한다.
  //여기서는 특별한 설정 없이 이 해제만 수행하면 된다.
  //}---------------------------------------------------------------------------

  //[VAR]
  //{
      int  i;

  //}

  //[모두 해제]
  //{
      for(i = 0; i < 12; i++)
      {
        //먼저 이전에 설정되 있던 PWM 채널 핀을 닫아준다.

        if(_pwm_RadioBtn[i]->_checked == true)
        {
          //[!]{-------------------------------------------------------------
          //PWM번호(i/4), 채널번호(i%4) 가 된다.
          //현재 선택된 PWM 채널 핀을 전용함수를 사용하여 출력으로 설정한다.
          //}----------------------------------------------------------------

          Matdol_Pwm_Pin_OnOff(i/4, i%4, false);

        }

      }

      for(i = 0; i < 12; i++) { _pwm_RadioBtn[i]->_Checked(false); }

  //}

  return;

}

void __fastcall TservoZero_DialogBox_Form::_EVENT_Click_pwm_RadioBtn(void)
{
  //[2009.11.20.금][생성!!!]{-------------------------------------------------
  //PWM 채널중 선택된것만 남기고 나머지는 전부 해제한다.
  //해당 채널의 장치번호, 채널번호에 해당하는 PWM 출력핀을 출력으로 설정한다.
  //이는 맷돌에 직렬버스로 직접 접근하므로 전용함수를 사용하여 처리한다.
  //}-------------------------------------------------------------------------

  //[VAR]
  //{
      char            tempStr[OPT_lineStrSize] = {""};

      int             i, selIndex;

      unsigned short  dutyValue;

  //}

  //[선택된 것 찾기]
  //{
      //현재 어떤 것이 선택된 것인지 확인한다.
      for(i = 0; i < 12; i++)
      {
        if(_pwm_RadioBtn[i]->_checked == true) { selIndex = i; break; }

      }

  //}

  //[현재 선택된 것 알려주기]
  //{
      //표시할 문자열 합성.
      STR_Assign(tempStr, "현재 대상 PWM 채널 : [ PWM");
      STR_Add(tempStr, _pwm_Label[selIndex]->_caption);
      STR_Add(tempStr, " ]");

      _pwmSelect_Label->_Caption(tempStr);

  //}

  //[설정]
  //{
      //[!]{-------------------------------------------------------------
      //실제 맷돌의 해당 PWM 출력핀을 출력으로 설정하여 PWM 을 출력한다.
      //다른 핀은 전부 입력으로 설정해준다.
      //}----------------------------------------------------------------

      for(i = 0; i < 12; i++)
      {
        if(_pwm_RadioBtn[i]->_checked == true)
        {
          //[!]{-------------------------------------------------------------
          //PWM번호(i/4), 채널번호(i%4) 가 된다.
          //현재 선택된 PWM 채널 핀을 전용함수를 사용하여 출력으로 설정한다.
          //}----------------------------------------------------------------

          Matdol_Pwm_Pin_OnOff(i/4, i%4, true);

          //[현재 해당 채널의 <듀티값> 표시]
          //{
              //현재 <듀티값> 을 읽어들인다.
              Matdol_Pwm_Duty_Read(i/4, i%4, &dutyValue);

              //[표시]
              //{
                  //값을 문자열로 변환한다.
                  CONV_LongVal_To_Str(dutyValue, 4, false, tempStr);

                  //표시한다.
                  _pwmDuty_Edit->_EDIT_TextOut(tempStr);

              //}

              //[줄이동자 설정]
              //{
                  _pwmDuty_ScrollH->_Position(dutyValue);

              //}

          //}

          //이미 선택된 것을 처리하였으므로 더이상 처리하지 않는다.
          return;

        }

      }

      //여기까지 온것은 아무것도 선택된 것이 없으므로 처리하지 않는다.

  //}

  return;

}

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

void __fastcall TservoZero_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 TservoZero_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 TservoZero_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 TservoZero_DialogBox_Form::FormShow(TObject *Sender)
{
  //[2009.05.08.금][생성!!!]{---------
  //[찾을 문자열] 에 촛점을 맞춰준다.
  //}---------------------------------

  _pwmDuty_Edit->SetFocus();

  return;

}

void __fastcall TservoZero_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;

      //}

  //}

}






