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

#include <vcl.h>
#pragma hdrstop

#include "gui_button.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
Tgui_button_Form *gui_button_Form;
//---------------------------------------------------------------------------


#include "ide_main.h"

#include "ide_library.h"

//[2008.02.03.일][추가!!!]
#include "ide_BalloonBox.h"


#include "gui.h"


__fastcall Tgui_button_Form::Tgui_button_Form(TComponent* Owner)
        : TForm(Owner)
{
  //[환경변수]
  //{
      //[2007.10.02.화][추가!!!]
      IDE_Get_Option(&_ide_option);

  //}

  //[property]
  //{
      STR_Assign(_caption, "버튼");
      _caption_x       = 1;
      _caption_y       = 1;
      //기본적으로 문자는 버튼의 중간에 위치한다.
      _caption_autopos = true;

      //버튼이 눌린 상태라면 true.
      _down            = false;

      //기본적으로 마우스가 안에 없는 것이다.
      _in              = false;

      //버튼은 아무것도 눌리지 않은 것이다.
      _mouse_button    = d_mouse_null;

  //}

  //[form]
  //{
      this->Left   = 0 ;
      this->Top    = 0;
      this->Width  = 50;
      this->Height = 16;

      this->Color  = clWhite;
  //}

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

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

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

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

      _font.margin_size   = 0;

      _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;
      //}---------------------------

  //}

  //[풍선도움말]
  //{
      //[2008.02.03.일][추가!!!]
      //처음에는 사용하지 않는다.
      _balloonHelpUse = false;

      //문자열을 초기화 한다.
      _balloonHelpStr = NULL;
      
  //}

  //[문자색]
  //{
      //[2009.04.07.화][추가!!!]
      _fontColor = IDE_COLOR_1;

  //}

  //[문자속성]
  //{
      //[2011.01.15.토][추가!!!]
      _fontStyle = d_FONTSTYLE_default;

  //}

  //[바탕색]
  //{
      //[2009.10.02.금][추가!!!]
      _backColor = IDE_COLOR_2;

  //}

  //[가선택 색]
  //{
      //[2018.04.18.수][추가!!!]
      BMP_Get_Bright_Color(_ide_option->color_0, Ide_Bright_SelBtn, &_selectColor);

  //}

  //[EVENT 함수포인터 초기화]
  //{
      //---------------------------------------------------------
      //외부에서 함수를 등록해서 사용하므로 NULL 로 초기화 한다.
      _EVENT_Down  = NULL;
      _EVENT_Up    = NULL;
      _EVENT_Click = NULL;
      //---------------------------------------------------------
  //}

  //[컨트롤 그리기]
  //{
      //컨트롤을 그려서 모양을 만든다.
      _Shape();
  //}

  return;

}

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

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

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

}

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

void __fastcall Tgui_button_Form::WndProc(Messages::TMessage  &Message)
{
  //[2006.12.12.화][생성!!!]{-----------------------------------------------------
  //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;

  }
  else if(Message.Msg == CM_MOUSEENTER)
  {
    //[Linux:wine 지원]
    //{
        //[2018.04.17.화][추가!!!]{----------------------------------------------
        //[Linux:wine] 지원의 경우는 여기서 처리하지 않고 해당 [타이머] 로 처리.
        //}----------------------------------------------------------------------
        
        if(_ide_option->wine == true) goto lbEnd;

    //}

    //마우스가 안에 있음을 알린다.
    _in = true;

    //[가선택 처리][2018.04.18.수][추가!!!]{---
    _Shape();
    //}----------------------------------------

    //해당 처리 함수사용.
    if(_EVENT_MouseEnter != NULL)
    {
      _EVENT_MouseEnter();

    }

    //[2008.02.03.일][추가!!!]
    //[풍선도움말] 을 설정해 준다.
    if(_balloonHelpUse == true)
    {
      ide_BalloonBox_Form->_BalloonBox(Mouse->CursorPos.x,
                                       Mouse->CursorPos.y,
                                       true,
                                       _balloonHelpStr);

    }

  }
  else if(Message.Msg == CM_MOUSELEAVE)
  {
    //[Linux:wine 지원]
    //{
        //[2018.04.17][화][추가!!!]{---------------------------------------------
        //[Linux:wine] 지원의 경우는 여기서 처리하지 않고 해당 [타이머] 로 처리.
        //}----------------------------------------------------------------------

        if(_ide_option->wine == true) goto lbEnd;

    //}

    //마우스가 안에 없음을 알린다.
    _in = false;

    //[가선택 처리][2018.04.18.수][추가!!!]{---
    _Shape();
    //}----------------------------------------

    //해당 처리 함수사용.
    if(_EVENT_MouseLeave != NULL)
    {
      _EVENT_MouseLeave();

    }

    //[2008.02.03.일][추가!!!]
    //[풍선도움말] 을 감춘다.
    if(_balloonHelpUse == true)
    {
      ide_BalloonBox_Form->_Hide();

    }

  }

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

  return;

}

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

void __fastcall Tgui_button_Form::_BalloonHelpUse(bool    pUse)
{
  //[2008.02.03.일][생성!!!]{-----------------
  //[풍선도움말] 기능의 사용 유무를 결정한다.
  //}-----------------------------------------

  _balloonHelpUse = pUse;

  return;

}

void __fastcall Tgui_button_Form::_BalloonHelpStr(char   *pStr)
{
  //[2008.02.03.일][생성!!!]{-----------------
  //[풍선도움말] 에 표시할 문자열을 기록한다.
  //지정된 문자열의 길이만큼 동적 생성한다.
  //}-----------------------------------------

  //지금 버퍼에 내용이 있다면 삭제한다.
  if(_balloonHelpStr != NULL) { delete [] _balloonHelpStr; _balloonHelpStr = NULL; }

  //동적으로 공간을 생성한다.
  //_balloonHelpStr = new char [strlen(pStr) + 1];
  //[동적생성단위적용][2021.01.24.일][수정]
  _balloonHelpStr = new char [UnitX(1024, strlen(pStr) + 1)];

  //문자열을 복사한다.
  STR_Assign(_balloonHelpStr, pStr);

  return;

}

void __fastcall Tgui_button_Form::_Shape(void)
{
  //[2006.11.06.월][생성!!!]
  //[2018.04.18.수][수정!!!]

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

  //[caption 문자열 표시위치 계산]
  //{
      //자동 설정인 경우는 항상 버튼의 중간에 위치하도록 한다.
      if(_caption_autopos == true)
      {
        //[출력문자열 영역크기 구하기]{----------------------------------------------
        //버튼 문자의 영역 정보를 얻는다.(표시 문자크기에 맞는 버튼을 만들기 위한것)
        FONT_Get_StringOutAreaInfo(&_font, _fontStyle, _caption, &width, &height);
        //---------------------------------------------------------------------------

        _caption_x = this->Width/2 - width/2;
        _caption_y = this->Height/2 - height/2;

      }
  //}

  //버튼의 상태를 참고하여 그린다.
  if(_down != true)
  {
    //[가선택 구분 처리]
    //{
        //[2018.04.18.수][추가!!!]{-------
        //[기본/가선택] 을 구분하여 처리.
        //}-------------------------------

        if(_in == true)
        {
          //[!]{---------
          //가선택 상태.
          //}------------

          //[바탕색]
          //{
              _bmp_->Canvas->Brush->Color = _selectColor;
              _bmp_->Canvas->FillRect(_bmp_->Canvas->ClipRect);

          //}

          //[caption 출력]
          //{
              //caption 이 버튼 영역을 넘을수 있으므로 문자열을 먼저 출력한다.

              //FONT_Out_String2(_bmp_, &_font, _caption_x, _caption_y, _fontColor, _backColor, true,
              //                 _caption,
              //                 d_FONT_underline_no, true, 0, _fontColor,
              //                 &width, &height);

              //[2011.01.15.토][수정!!!]
              //[문자형식] 을 지정하기 위하여 위 함수에서 이 함수로 바꾼다.
              FONT_Out_StyleString2(_bmp_, &_font, _caption_x, _caption_y,
                                    _fontColor, _backColor, true, _fontStyle,
                                    _caption,
                                    d_FONT_underline_no, true, 0, _fontColor,
                                    &width, &height);

          //}

        }
        else
        {
          //[!]{-------
          //기본 상태.
          //}----------

          //[바탕색]
          //{
              _bmp_->Canvas->Brush->Color = _backColor;
              _bmp_->Canvas->FillRect(_bmp_->Canvas->ClipRect);

          //}

          //[caption 출력]
          //{
              //caption 이 버튼 영역을 넘을수 있으므로 문자열을 먼저 출력한다.

              //FONT_Out_String2(_bmp_, &_font, _caption_x, _caption_y, _fontColor, _backColor, true,
              //                 _caption,
              //                 d_FONT_underline_no, true, 0, _fontColor,
              //                 &width, &height);

              //[2011.01.15.토][수정!!!]
              //[문자형식] 을 지정하기 위하여 위 함수에서 이 함수로 바꾼다.
              FONT_Out_StyleString2(_bmp_, &_font, _caption_x, _caption_y,
                                    _fontColor, _backColor, true, _fontStyle,
                                    _caption,
                                    d_FONT_underline_no, true, 0, _fontColor,
                                    &width, &height);

          //}

        }

    //}

  }
  else
  {
    //반전상태.

    //[바탕색]
    //{
        _bmp_->Canvas->Brush->Color = _ide_option->color_0;
        _bmp_->Canvas->FillRect(_bmp_->Canvas->ClipRect);

    //}

    //[caption 출력]
    //{
        //caption 이 버튼 영역을 넘을수 있으므로 문자열을 먼저 출력한다.

        //FONT_Out_String2(_bmp_, &_font, _caption_x, _caption_y, _backColor, _ide_option->color_0, true,
        //                 _caption,
        //                 d_FONT_underline_no, true, 0, IDE_COLOR_1,
        //                 &width, &height);

        //[2011.01.15.토][수정!!!]
        //[문자형식] 을 지정하기 위하여 위 함수에서 이 함수로 바꾼다.
        FONT_Out_StyleString2(_bmp_, &_font, _caption_x, _caption_y, _backColor, _ide_option->color_0, true, _fontStyle,
                              _caption,
                              d_FONT_underline_no, true, 0, _fontColor,
                              &width, &height);

    //}

  }

  //[테두리 만들기]
  //{
      _bmp_->Canvas->Pen->Color   = _ide_option->color_0;
      _bmp_->Canvas->Pen->Width   = 1;
      _bmp_->Canvas->Brush->Style = bsClear;
      _bmp_->Canvas->Rectangle(_bmp_->Canvas->ClipRect);

  //}

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

  return ;

}

void __fastcall Tgui_button_Form::_Left(int  pLEFT)
{
  //[2006.11.06.월][생성!!!]

  this->Left = pLEFT;

  return ;

}

void __fastcall Tgui_button_Form::_Top(int  pTOP)
{
  //[2006.11.06.월][생성!!!]

  this->Top = pTOP;

  return ;

}

void __fastcall Tgui_button_Form::_Width(int  pWIDTH)
{
  //[2006.11.06.월][생성!!!]

  this->Width = pWIDTH;

  //[bmp 크기 조정]
  //{
      //다른 컨트롤과 달리 크기 조정이 될수 있으므로 이 경우 bmp 도 같이 조정한다.
      _bmp_->Width = this->Width;
  //}

  //높이가 바뀌었으므로 다시 그려준다.
  _Shape();

  return ;

}

void __fastcall Tgui_button_Form::_Height(int  pHEIGHT)
{
  //[2006.11.06.월][생성!!!]

  this->Height = pHEIGHT;

  //[bmp 크기 조정]
  //{
      //다른 컨트롤과 달리 크기 조정이 될수 있으므로 이 경우 bmp 도 같이 조정한다.
      _bmp_->Height = this->Height;
  //}

  //높이가 바뀌었으므로 다시 그려준다.
  _Shape();

  return ;

}

void __fastcall Tgui_button_Form::_Caption(char  *pCAPTION)
{
  //[2006.11.06.월][생성!!!]

  //caption 문자열을 할당한다.
  STR_Assign(_caption, pCAPTION);

  //높이가 바뀌었으므로 다시 그려준다.
  _Shape();

  return ;

}

void __fastcall Tgui_button_Form::_Caption_X(int  pCAPTIONx)
{
  //[2006.11.06.월][생성!!!]

  this->_caption_x = pCAPTIONx;

  //높이가 바뀌었으므로 다시 그려준다.
  _Shape();

  return ;

}

void __fastcall Tgui_button_Form::_Caption_Y(int  pCAPTIONy)
{
  //[2006.11.06.월][생성!!!]

  this->_caption_y = pCAPTIONy;

  //높이가 바뀌었으므로 다시 그려준다.
  _Shape();

  return ;

}

void __fastcall Tgui_button_Form::_Caption_AutoPos(bool  pAUTOPOS)
{
  //[2006.11.09.목][생성!!!]

  this->_caption_autopos = pAUTOPOS;

  //높이가 바뀌었으므로 다시 그려준다.
  _Shape();

  return ;

}

void __fastcall Tgui_button_Form::_Draw(void)
{
  //[2006.11.06.월][생성!!!]

  BitBlt(this->Canvas->Handle, 0, 0,
         this->Width, this->Height,
         _bmp_->Canvas->Handle, 0, 0, SRCCOPY);

  return;

}

void __fastcall Tgui_button_Form::_BtnUp(void)
{
  //[2007.11.30.금][생성!!!]{-------------------------
  //단지 버튼을 올라온 모양으로 다시 그려주기만 한다.
  //}-------------------------------------------------

  //[버튼 다시 그리기]
  //{
      _down = false;
      _Shape();
      _mouse_button = d_mouse_null;

  //}

  return;

}

void __fastcall Tgui_button_Form::_FontColor(int  pFontColor)
{
  //[2009.04.07.화][생성!!!]{---
  //[문자색] 을 지정한다.
  //}---------------------------

  _fontColor = pFontColor;

  _Shape();

  return;

}

void __fastcall Tgui_button_Form::_FontStyle(int  pFontStyle)
{
  //[2011.01.15.토][생성!!!]{----------
  //[문자형식(일반/굵은)] 을 지정한다.
  //}----------------------------------

  _fontStyle = pFontStyle;

  _Shape();

  return;

}

void __fastcall Tgui_button_Form::_BackColor(int  pBackColor)
{
  //[2009.10.01.금][생성!!!]{---
  //[바탕색] 을 지정한다.
  //}---------------------------

  _backColor = pBackColor;

  _Shape();

  return;

}

void __fastcall Tgui_button_Form::_SelectColor(int  pSelectColor)
{
  //[2018.04.18.수][생성!!!]{--------------------------------------------
  //[선택색] 을 지정(화면지정자가 올려져 있을때 가선택임을 보여주는 색).
  //}--------------------------------------------------------------------

  _selectColor = pSelectColor;

  _Shape();

  return;

}

//[EVENT]-----------------------------------------------------------------------

void __fastcall Tgui_button_Form::FormMouseDown(TObject *Sender,
      TMouseButton Button, TShiftState Shift, int X, int Y)
{
  //[2006.11.06.월][생성!!!]

  switch(Button)
  {
    case  mbLeft :
    {
      //[버튼 기록]{----------------
      _mouse_button = d_mouse_left;
      //}---------------------------

      //버튼을 눌린 상태로 표시한다.
      _down = true;

      _Shape();

    } break;

    case  mbRight :
    {
      //[버튼 기록]{-----------------
      _mouse_button = d_mouse_right;
      //}----------------------------

    } break;

    case  mbMiddle :
    {
      //[버튼 기록]{------------------
      _mouse_button = d_mouse_middle;
      //}-----------------------------

    } break;

  }

  //해당 처리 함수사용.
  if(_EVENT_Down != NULL)
  {
    //[풍선도움말 감추기][2008.04.05.토][추가!!!]{----------------
    //다른 기능이 동작한다면 표시하지 않아야 한다.
    if(_balloonHelpUse == true) { ide_BalloonBox_Form->_Hide(); }
    //}-----------------------------------------------------------

    _EVENT_Down();

  }

  return;

}

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

  //[OnClick 발생]
  //{
      //[2006.12.08.목][추가!!!]{------------------------------------------
      //Form 의 OnClick-Event 는 동작 속도가 늦고 제대로 동작되지 않으므로
      //아예 직접 만든다. OnDown, OnUp 은 다른 것과 같이 빠르게 동작된다.
      //((_down == true) && (_in == true)) 인 경우만 발생한다.
      //}------------------------------------------------------------------

      //[2009.04.19.일][수정!!!]{---------------------------------------------------------------------
      //BCB6 에서와 달리 TC2006 은 이 처리를 반드시 해 주어야 한다.
      //그래야 UP 이 되었을 경우 버튼 밖에 [표시지정자] 가 있는 경우에 [동작함수] 가 구동되지 않는다.
      if(!(((0 <= X) && (X <= this->Width)) && ((0 <= Y) && (Y <= this->Height)))) { _in = false; }
      //}---------------------------------------------------------------------------------------------

      /*
      //[2018.04.15.일][주석처리!!!]{-------------------------------------------------------------
      //[Linux:wine] 에서는 직접 메세지 방식을 만든 <Click> 이 제대로 동작하지 않는 경우가 발생.
      //{ [마우스:down] -> [버튼 영역 밖으로 이동] -> [1초이상 경과] -> [마우스:UP] } 의 경우
      //다음부터는 아예 <CM_MOUSEENTER/CM_MOUSELEAVE> 가 발생하지 않아 메세지 방식으로 처리 불가.
      //그러나, BCB 제공 기본 <OnClick()> 은 제대로 동작하므로 이것으로 대체.
      //}-----------------------------------------------------------------------------------------

      if((_down == true) && (_in == true))
      {
        //OnClick 을 발생시킨다.
        if(_EVENT_Click != NULL)
        {
          //[풍선도움말 감추기][2008.04.05.토][추가!!!]{----------------
          //다른 기능이 동작한다면 표시하지 않아야 한다.
          if(_balloonHelpUse == true) { ide_BalloonBox_Form->_Hide(); }
          //}-----------------------------------------------------------

          _EVENT_Click();

        }

      }
      */

  //}

  //버튼이 올라온 상태로 표시한다.
  _down = false;

  _Shape();

  //해당 처리 함수사용.
  if(_EVENT_Up != NULL)
  {
    //[풍선도움말 감추기][2008.04.05.토][추가!!!]{----------------
    //다른 기능이 동작한다면 표시하지 않아야 한다.
    if(_balloonHelpUse == true) { ide_BalloonBox_Form->_Hide(); }
    //}-----------------------------------------------------------

    _EVENT_Up();

  }

  //[버튼 기록]{----------------
  //모두 해제한다.
  _mouse_button = d_mouse_null;
  //}---------------------------

  return;

}

void __fastcall Tgui_button_Form::FormMouseMove(TObject *Sender,
      TShiftState Shift, int X, int Y)
{
  //[2008.02.03.일][추가!!!]{--------------------------------------------------
  //[풍선도움말] 을 설정해 준다.
  ide_BalloonBox_Form->_BalloonBoxPos(Mouse->CursorPos.x, Mouse->CursorPos.y);
  //}--------------------------------------------------------------------------

  //[Linux:wine 지원]
  //{
      //[2018.04.17.화][추가!!!]{-------------------------
      //<CM_MOUSEENTER> 부분 처리.
      //<FormMouseMove()> 시작을 <CM_MOUSEENTER> 로 간주.
      //}-------------------------------------------------

      if(_ide_option->wine == true)
      {
        //[처음 진입 인가?]
        //{
            //<CM_MOUSEENTER> 은 처음 한번만 처리.
            if(_in == true) return;

        //}

        //마우스가 안에 있음을 알린다.
        _in = true;

        //[가선택 처리][2018.04.18.수][추가!!!]{---
        _Shape();
        //}----------------------------------------

        //해당 처리 함수사용.
        if(_EVENT_MouseEnter != NULL)
        {
          _EVENT_MouseEnter();

        }

        //[2008.02.03.일][추가!!!]
        //[풍선도움말] 을 설정해 준다.
        if(_balloonHelpUse == true)
        {
          ide_BalloonBox_Form->_BalloonBox(Mouse->CursorPos.x,
                                           Mouse->CursorPos.y,
                                           true,
                                           _balloonHelpStr);

        }

        //[<CM_MOUSELEAVE> 관련 처리]
        //{
            //[!]{--------------------------------------------------------
            //<CM_MOUSELEAVE> 는 <FormMouseMove()> 만으로는 알수 없으므로
            //<mouseLeaveTimer> 를 사용하여 직접 감지 처리.
            //타이머 해제는 <CM_MOUSELEAVE> 동작이 완료시 처리.
            //}-----------------------------------------------------------

            mouseLeaveTimer->Enabled = true;

        //}

      }

  //}

  return;

}

void __fastcall Tgui_button_Form::FormClick(TObject *Sender)
{
  //[2018.04.15.일][생성!!!]

  //OnClick 을 발생시킨다.
  if(_EVENT_Click != NULL)
  {
    //[풍선도움말 감추기][2008.04.05.토][추가!!!]{----------------
    //다른 기능이 동작한다면 표시하지 않아야 한다.
    if(_balloonHelpUse == true) { ide_BalloonBox_Form->_Hide(); }
    //}-----------------------------------------------------------

    _EVENT_Click();

  }
  
}

void __fastcall Tgui_button_Form::mouseLeaveTimerTimer(TObject *Sender)
{
  //[2018.04.17.화][생성!!!]{-----------------------------------------------------------------
  //[Linux:wine] 에서는 직접 메세지 방식을 만든 <Click> 이 제대로 동작하지 않는 경우가 발생.
  //{ [마우스:down] -> [버튼 영역 밖으로 이동] -> [1초이상 경과] -> [마우스:UP] } 의 경우
  //다음부터는 아예 <CM_MOUSEENTER/CM_MOUSELEAVE> 가 발생하지 않아 메세지 방식으로 처리 불가.
  //그러나, BCB 제공 기본 <OnClick()> 은 제대로 동작하므로 이것으로 대체.
  //
  //<CM_MOUSEENTER> 는 <FormMouseMove()> 에서 처리하므로 여기서는 <CM_MOUSELEAVE> 만 처리.
  //
  //1) 계속 현재 영역(절대좌표)을 감시.
  //2) 영역을 벗어나는 순간 <CM_MOUSELEAVE> 로 간주 해당 처리.
  //3) mouseLeaveTimer 정지. 
  //}-----------------------------------------------------------------------------------------

  //[VAR]
  //{
      TPoint  thisPos;

      TPoint  mousePos;

  //}

  //[<그림부품:절대위치> 얻기]
  //{
      //[주의!!!]{------------------------------------------------------------------
      //<ClientOrigin> 는 정확한 값이나, 같은 기능으로 알려진 <ClientToScreen()> 은
      //정확하지 않다.
      //}---------------------------------------------------------------------------
      
      thisPos = this->ClientOrigin;

  //}

  //[<화면지정자:절대위치> 얻기]
  //{
      //[참고!!!]{------------------------------------------------------------
      //<GetCursorPos()> 대신에 <Mouse->CursorPos.x/y> 를 간단하게 사용 가능.
      //}---------------------------------------------------------------------
      
      GetCursorPos(&mousePos);

  //}

  //[영역을 벗어났나?]
  //{
      //[화면지정자] 가 [그림부품:절대영역] 을 벗어난 경우는 <CM_MOUSELEAVE> 로 간주.

      if(!((thisPos.x <= mousePos.x) && (mousePos.x < (thisPos.x + this->Width)) &&
           (thisPos.y <= mousePos.y) && (mousePos.y < (thisPos.y + this->Height))))
      {
        //[!]{---------------------------------------------------------------------------
        //영역을 벗어난 경우이므로 <CM_MOUSELEAVE> 관련 처리 수행.
        //단, 버튼이 눌려있는 상태인 경우는 아직 [안] 으로 간주(윈도우와 같게 유지)한다.
        //}------------------------------------------------------------------------------

        //[버튼이 눌린 상태인가?]
        //{
            if(_down == true) return;

        //}

        //마우스가 안에 없음을 알린다.
        _in = false;

        //[가선택 처리][2018.04.18.수][추가!!!]{---
        _Shape();
        //}----------------------------------------

        //해당 처리 함수사용.
        if(_EVENT_MouseLeave != NULL)
        {
          _EVENT_MouseLeave();

        }

        //[2008.02.03.일][추가!!!]
        //[풍선도움말] 을 감춘다.
        if(_balloonHelpUse == true)
        {
          ide_BalloonBox_Form->_Hide();

        }

        //타이머 해제.
        mouseLeaveTimer->Enabled = false;

      }

  //}

}






