/// ****************************************************************************
/// @file   
/// @author Dr.Neeton
/// @date   2010/X/X - 2016/09/21
/// 
/// @brief  グラフィカルユーザーコンポーネント基本ヘッダ。
/// 
/// ****************************************************************************

#pragma once

#include <random>

#include "../DX/CPL_DX_Frame.h"
#include "../DX/CPL_DX_Graphics.h"
#include "../DX/CPL_DX_Sprite.h"
#include "../DX/CPL_DX_Font.h"
#include "../DX/CPL_DX_RasterizerState.h"
#include "../DX/CPL_DX_RenderTexture.h"
#include "../CDI/CPL_CDI_Base.h"


namespace CPL {

/// グラフィカルユーザーコンポーネント。\n
/// 環境依存しないための自前のGUIフレームワークですが、現状ではDirectX依存。
namespace GUC {


extern unsigned char Image_Parts[];
extern int           Image_Parts_Size;

// GUCのデフォルト文字タイプ
using td_DefChar   = wchar_t;
using td_DefString = Core::String_X_<td_DefChar>;

#define CPL_GUC_DEF_STR(s) L##s

// 基本カラー
const DX::ColorType kCOLOR_BLACK      ( 0x000000FFu );
const DX::ColorType kCOLOR_DARKGRAY   ( 0x404040FFu );
const DX::ColorType kCOLOR_GRAY       ( 0x808080FFu );
const DX::ColorType kCOLOR_LIGHTGRAY  ( 0xCCCCCCFFu );
const DX::ColorType kCOLOR_WHITE      ( 0xFFFFFFFFu );
const DX::ColorType kCOLOR_ORANGE     ( 0xFFA500FFu );
const DX::ColorType kCOLOR_BROWN      ( 0xA52A2AFFu );
const DX::ColorType kCOLOR_DARKRED    ( 0x8B0000FFu );
const DX::ColorType kCOLOR_RED        ( 0xFF0000FFu );
const DX::ColorType kCOLOR_PINK       ( 0xFFC0CBFFu );
const DX::ColorType kCOLOR_DARKGREEN  ( 0x006400FFu );
const DX::ColorType kCOLOR_GREEN      ( 0x008000FFu );
const DX::ColorType kCOLOR_LIME       ( 0x00FF00FFu );
const DX::ColorType kCOLOR_LIGHTGREEN ( 0x90EE90FFu );
const DX::ColorType kCOLOR_DARKBLUE   ( 0x00008BFFu );
const DX::ColorType kCOLOR_BLUE       ( 0x0000FFFFu );
const DX::ColorType kCOLOR_LIGHTBLUE  ( 0xADD8E6FFu );
const DX::ColorType kCOLOR_CYAN       ( 0x00FFFFFFu );
const DX::ColorType kCOLOR_GREENYELLOW( 0xADFF2FFFu );
const DX::ColorType kCOLOR_OLIVE      ( 0x808000FFu );
const DX::ColorType kCOLOR_YELLOW     ( 0xFFFF00FFu );
const DX::ColorType kCOLOR_LIGHTYELLOW( 0xFFFFE0FFu );
const DX::ColorType kCOLOR_PURPLE     ( 0x800080FFu );
const DX::ColorType kCOLOR_BLUEVIOLET ( 0x8A2BE2FFu );
const DX::ColorType kCOLOR_MAGENTA    ( 0xFF00FFFFu );
const DX::ColorType kCOLOR_GOLD       ( 0xFFD700FFu );
const DX::ColorType kCOLOR_SILVER     ( 0xC0C0C0FFu );

extern const DX::RectColor4P kCOLOR4P_BLACK      ;
extern const DX::RectColor4P kCOLOR4P_DARKGRAY   ;
extern const DX::RectColor4P kCOLOR4P_GRAY       ;
extern const DX::RectColor4P kCOLOR4P_LIGHTGRAY  ;
extern const DX::RectColor4P kCOLOR4P_WHITE      ;
extern const DX::RectColor4P kCOLOR4P_ORANGE     ;
extern const DX::RectColor4P kCOLOR4P_BROWN      ;
extern const DX::RectColor4P kCOLOR4P_DARKRED    ;
extern const DX::RectColor4P kCOLOR4P_RED        ;
extern const DX::RectColor4P kCOLOR4P_PINK       ;
extern const DX::RectColor4P kCOLOR4P_DARKGREEN  ;
extern const DX::RectColor4P kCOLOR4P_GREEN      ;
extern const DX::RectColor4P kCOLOR4P_LIME       ;
extern const DX::RectColor4P kCOLOR4P_LIGHTGREEN ;
extern const DX::RectColor4P kCOLOR4P_DARKBLUE   ;
extern const DX::RectColor4P kCOLOR4P_BLUE       ;
extern const DX::RectColor4P kCOLOR4P_LIGHTBLUE  ;
extern const DX::RectColor4P kCOLOR4P_CYAN       ;
extern const DX::RectColor4P kCOLOR4P_GREENYELLOW;
extern const DX::RectColor4P kCOLOR4P_OLIVE      ;
extern const DX::RectColor4P kCOLOR4P_YELLOW     ;
extern const DX::RectColor4P kCOLOR4P_LIGHTYELLOW;
extern const DX::RectColor4P kCOLOR4P_PURPLE     ;
extern const DX::RectColor4P kCOLOR4P_BLUEVIOLET ;
extern const DX::RectColor4P kCOLOR4P_MAGENTA    ;
extern const DX::RectColor4P kCOLOR4P_GOLD       ;
extern const DX::RectColor4P kCOLOR4P_SILVER     ;



typedef WIN::Component::eMouseButton eMouseButton;
typedef WIN::Component::eRectFlag    eRectFlag;

// _____________________________________________________________________________
/// @brief コールバック関数の戻り値。
/// 
/// - LastCall             : イベントは自身で停止。
/// - SendParent_Render : イベントをそのまま、描画関係上の親へ投げる。
/// - SendParent_Position  : イベントをそのまま、位置関係上の親に投げる。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CPL_SCOPED_ENUM
  ( eEventReturnID, U32
  , LastCall = 0
  , SendParent_Render   = BIT0
  , SendParent_Position = BIT1
  , SendParent_All      = BIT0 | BIT1
  );

//#define VL_GUC_EVENT_RETURN_ID virtual eEventReturnID


// _____________________________________________________________________________
/// @brief 親タイプ識別用フラグ
/// 
/// - Rendering : 描画関係上の親を表します。
/// - Position  : 位置関係上の親を表します。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CPL_SCOPED_ENUM
  ( eParentType, U32
  , Render   = BIT0
  , Position = BIT1
  , All = Render | Position
  );




CPL_SCOPED_ENUM
  ( eID, int
  , Base = WIN::kID_CPL + WIN::kID_CPL_UNIT_VALUE

  , ValueChanged     // インプットコンテナ（wp==値を格納したdoubleへのポインタ  lp==コンテナポインタ）
  , ValueChanging    // ValueChangedと同じ。
  , ValueChangeBegin // ValueChangedと同じ。
  , ScrollBarChangeValue // スクロールバーのデータ変更　wp==value(floatのビット列なので注意)
  , ScrollButtonChangeValue // スクロールボタンのデータ変更　wp==value(floatのビット列なので注意)
  , ScrollButtonChangeValueBegin
  , ScrollButtonChangeValueEnd
  , ActiveViewItemShow // lp == ActiveForm*
  , ActiveViewItemHide // lp == ActiveForm*
  , ActiveSelectorChangeItem // wp==選択インデックス lp==コンテナポインタ
  , ChangeStatus
  , ExpandForm
  , ExpandMenu
  //, UpdateWindowBuffer // ウィンドウの更新通知 lp==ウィンドウポインタ
  , ListBoxChangeItem // wp == 選択インデックス

  , EditMenu
  , EditCut
  , EditCopy
  , EditPaste
  , EditDelete

  // タイマーID
  , Tid_CaretSwitch// カレット点滅用
  , Tid_ActiveFormShow
  , Tid_ActiveSelectorShow
  , Tid_MouseEnterDelay // コンポーネントへマウス進入後、500ms後にタイマー通知
  , Tid_MouseLeaveDelay // コンポーネントからマウス離脱後、500ms後にタイマー通知

  , End
  );

CPL_SCOPED_ENUM
  ( eImagePartsID, int
  , Circle
  , CircleShadow
  , Cross
  , Check
  , TriangleLeft
  , TriangleRight
  , TriangleDown
  , TriangleUp
  , ScrollButtonLeft
  , ScrollButtonRight
  , Plus
  , Minus
  , Box
  );




// _____________________________________________________________________________
/// @brief 状態カラーパラメタ
///
// *****************************************************************************
struct DrawColorSet
{
  DX::RectColor4P color_default;   ///< デフォルトカラー 
  DX::RectColor4P color_highlight; ///< 強調１（ハイライト：マウスオーバー等）
  DX::RectColor4P color_active;    ///< 強調２（アクティブ：何らかのアクション中？）
  DX::RectColor4P color_invalid;   ///< 無効

  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  DrawColorSet( _in<CDI::ColorType> in_color );

  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  DrawColorSet( _in<DX::RectColor4P> in_color4p );

  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  DrawColorSet
  ( _in<CDI::ColorType> in_color_default
  , _in<CDI::ColorType> in_color_highlight
  , _in<CDI::ColorType> in_color_active
  , _in<CDI::ColorType> in_color_invalid
  );

  //// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  //DrawColorSet
  //( _in<SpColor4p> in_sp_color_default
  //, _in<SpColor4p> in_sp_color_highlight
  //, _in<SpColor4p> in_sp_color_active
  //, _in<SpColor4p> in_sp_color_invalid
  //);

  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  DrawColorSet
  ( _in<DX::RectColor4P> in_color4p_default
  , _in<DX::RectColor4P> in_color4p_highlight
  , _in<DX::RectColor4P> in_color4p_active
  , _in<DX::RectColor4P> in_color4p_invalid
  );

  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  DrawColorSet( cref<DrawColorSet> in_dcs );
};


// _____________________________________________________________________________
/// @brief カラーパターン。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
namespace ColorPattern
{
  // グラデーション。
  static DX::RectColor4P GradationNormal( float in_alpha = 1.0f );

  // 通常の静的なコンポーネント（マウス等で反応しないパターン）
  static DrawColorSet StaticBG   ( float in_alpha = 1.0f );
  static DrawColorSet StaticFrame( float in_alpha = 1.0f );
  static DrawColorSet StaticText ( float in_alpha = 1.0f );
  
  // 動的なコンポーネント。
  static DrawColorSet DynamicBG   ( float in_alpha = 1.0f );
  static DrawColorSet DynamicFrame( float in_alpha = 1.0f );
  static DrawColorSet DynamicText ( float in_alpha = 1.0f );
} // namespace ColorPattern


// _____________________________________________________________________________
/// @brief GUC初期化。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
  Initialize
    ( _in<DX::DXDevice*             > in_ptr_d3ddev
    , _in<sdptr<DX::FontDrawManager>> in_sp_font
    );


class Component;

// _____________________________________________________________________________
/// @brief マウスイベント用インターフェイス
///
// *****************************************************************************
class MouseEventInterface
{
protected:
  // _____________________________________________________________________________
  /// @brief マウスダウンイベント
  /// 
  /// @param[in] in_sp_component : クリックされたコンポーネントのポインタが渡されます。
  /// @param[in] in_mouse_x : in_sp_component基準のX座標が渡されます。
  /// @param[in] in_mouse_y : in_sp_component基準のY座標が渡されます。
  /// @param[in] in_type_mouse_btn : マウスのどのボタンが押されたかが渡されます。
  /// 
  /// @return
  /// 呼び出し元に対する要請としてeEventReturnIDを返します。\n
  /// 詳しくはeEventReturnIDを参照してください。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual eEventReturnID
    On_MouseDown
      ( _in<sdptr<Component>> in_sp_component
      , _in<float           > in_mouse_x
      , _in<float           > in_mouse_y
      , _in<eMouseButton    > in_type_mouse_btn
      )
  {
    return eEventReturnID::SendParent_Position;
  }
  
  // _____________________________________________________________________________
  /// @brief マウスアップイベント
  /// 
  /// @param[in] in_sp_component : クリックされたコンポーネントのポインタが渡されます。
  /// @param[in] in_mouse_x : in_sp_component基準のX座標が渡されます。
  /// @param[in] in_mouse_y : in_sp_component基準のY座標が渡されます。
  /// @param[in] in_type_mouse_btn : マウスのどのボタンが押されたかが渡されます。
  /// 
  /// @return
  /// 呼び出し元に対する要請としてeEventReturnIDを返します。\n
  /// 詳しくはeEventReturnIDを参照してください。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual eEventReturnID
    On_MouseUp
      ( _in<sdptr<Component>> in_sp_component
      , _in<float           > in_mouse_x
      , _in<float           > in_mouse_y
      , _in<eMouseButton    > in_type_mouse_btn
      )
  {
    return eEventReturnID::SendParent_Position;
  }

  // _____________________________________________________________________________
  /// @brief マウス移動イベント
  /// 
  /// @param[in] in_sp_component : キャプチャされたコンポーネントのポインタが渡されます。
  /// @param[in] in_mouse_x : in_sp_component基準のX座標が渡されます。
  /// @param[in] in_mouse_y : in_sp_component基準のY座標が渡されます。
  /// 
  /// @return
  /// 呼び出し元に対する要請としてeEventReturnIDを返します。\n
  /// 詳しくはeEventReturnIDを参照してください。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual eEventReturnID
    On_MouseMove
      ( _in<sdptr<Component>> in_sp_component
      , _in<float           > in_mouse_x
      , _in<float           > in_mouse_y
      )
  {
    return eEventReturnID::SendParent_Position;
  }

  // _____________________________________________________________________________
  /// @brief マウスホイールイベント
  /// 
  /// @param[in] in_sp_component
  ///   : ホイールされたコンポーネントのポインタが渡されます。
  /// @param[in] in_fw_keys
  ///   : マウス（一部キーを含む）の状態が渡されます。\n
  ///   : 詳しくは「WM_MOUSEWHEEL」を検索してください。
  /// @param[in] in_z_delta
  ///   : マウスの回転量が渡されます。
  /// 
  /// @return
  /// 呼び出し元に対する要請としてeEventReturnIDを返します。\n
  /// 詳しくはeEventReturnIDを参照してください。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual eEventReturnID
    On_MouseWheel
      ( _in<sdptr<Component>> in_sp_component
      , _in<WORD            > in_fw_keys
      , _in<short           > in_z_delta
      )
  {
    return eEventReturnID::SendParent_Position;
  }

  // _____________________________________________________________________________
  /// @brief マウス侵入イベント
  /// 
  /// @param[in] in_sp_comp_enter
  ///   : マウスカーソルが侵入したコンポーネントのスマートポインタが渡されます。
  /// @param[in] in_sp_comp_leave
  ///   : マウスカーソルが離脱したコンポーネントのスマートポインタが渡されます。
  /// 
  /// @return
  /// 呼び出し元に対する要請としてeEventReturnIDを返します。\n
  /// 詳しくはeEventReturnIDを参照してください。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual eEventReturnID
    On_MouseEnter
      ( _in<sdptr<Component>> in_sp_comp_enter
      , _in<sdptr<Component>> in_sp_comp_leave
      )
  {
    return eEventReturnID::SendParent_Position;
  }

  // _____________________________________________________________________________
  /// @brief マウス離脱イベント
  /// 
  /// @param[in] in_sp_comp_leave
  ///   : マウスカーソルが離脱したコンポーネントのスマートポインタが渡されます。
  /// @param[in] in_sp_comp_enter
  ///   : マウスカーソルが侵入したコンポーネントのスマートポインタが渡されます。
  /// 
  /// @return
  /// 呼び出し元に対する要請としてeEventReturnIDを返します。\n
  /// 詳しくはeEventReturnIDを参照してください。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual eEventReturnID
    On_MouseLeave
      ( _in<sdptr<Component>> in_sp_comp_leave
      , _in<sdptr<Component>> in_sp_comp_enter
      )
  {
    return eEventReturnID::SendParent_Position;
  }
};

// _____________________________________________________________________________
/// @brief キーイベント用インターフェイス
///
// *****************************************************************************
class KeyEventInterface
{
protected:

  // _____________________________________________________________________________
  /// @brief キーダウンイベント
  /// 
  /// @param[in] in_sp_component
  ///   : イベント発生元コンポーネントのスマートポインタが渡されます。
  /// @param[in] in_virtual_key_code
  ///   : 押されたキーのコードが渡されます。
  /// 
  /// @return
  /// 呼び出し元に対する要請としてeEventReturnIDを返します。\n
  /// 詳しくはeEventReturnIDを参照してください。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual eEventReturnID
    On_KeyDown
      ( _in<sdptr<Component>> in_sp_component
      , _in<int             > in_virtual_key_code
      )
  {
    return eEventReturnID::SendParent_Position;
  }

  // _____________________________________________________________________________
  /// @brief キーアップイベント
  /// 
  /// @param[in] in_sp_component
  ///   : イベント発生元コンポーネントのスマートポインタが渡されます。
  /// @param[in] in_virtual_key_code
  ///   : 離されたキーのコードが渡されます。
  /// 
  /// @return
  /// 呼び出し元に対する要請としてeEventReturnIDを返します。\n
  /// 詳しくはeEventReturnIDを参照してください。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual eEventReturnID
    On_KeyUp
      ( _in<sdptr<Component>> in_sp_component
      , _in<int             > in_virtual_key_code
      )
  {
    return eEventReturnID::SendParent_Position;
  }
};

// _____________________________________________________________________________
/// @brief ウィンドウイベントインターフェイス
///
// *****************************************************************************
class WindowEventInterface
{
protected:

  // _____________________________________________________________________________
  /// @brief サイズ変更イベント
  /// 
  /// @param[in] in_sp_component
  ///   : サイズが変更されたコンポーネントのスマートポインタが渡されます。
  /// 
  /// @return
  /// 呼び出し元に対する要請としてeEventReturnIDを返します。\n
  /// 詳しくはeEventReturnIDを参照してください。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual eEventReturnID
    On_Size( _in<sdptr<Component>> in_sp_component )
  {
    return eEventReturnID::SendParent_Position;
  }

  // _____________________________________________________________________________
  /// @brief 移動イベント
  /// 
  /// @param[in] in_sp_component
  ///   : 移動されたコンポーネントのスマートポインタが渡されます。
  /// 
  /// @return
  /// 呼び出し元に対する要請としてeEventReturnIDを返します。\n
  /// 詳しくはeEventReturnIDを参照してください。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual eEventReturnID
    On_Move( _in<sdptr<Component>> in_sp_component )
  {
    return eEventReturnID::SendParent_Position;
  }

  // _____________________________________________________________________________
  /// @brief 表示状態変更イベント
  /// 
  /// @param[in] in_sp_component
  ///   : 表示または非表示となったコンポーネントのスマートポインタが渡されます。
  /// @param[in] in_show_flag
  ///   : 表示状態フラグが渡されます。\n
  ///   : true  - 表示\n
  ///   : false - 非表示
  /// 
  /// @return
  /// 呼び出し元に対する要請としてeEventReturnIDを返します。\n
  /// 詳しくはeEventReturnIDを参照してください。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual eEventReturnID
    On_Show
      ( _in<sdptr<Component>> in_sp_component
      , _in<BOOL            > in_show_flag
      )
  {
    return eEventReturnID::SendParent_Position;
  }

  // _____________________________________________________________________________
  /// @brief タイマーイベント
  /// 
  /// @param[in] in_timer_ID
  ///   : タイマーIDが渡されます。
  /// 
  /// @return
  /// 呼び出し元に対する要請としてeEventReturnIDを返します。\n
  /// 詳しくはeEventReturnIDを参照してください。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual eEventReturnID
    On_Timer( _in<int> in_timer_ID )
  {
    return eEventReturnID::LastCall;
  }

  // _____________________________________________________________________________
  /// @brief WM_CHAR対応イベント
  /// 
  /// @param[in] in_sp_component
  ///   : 移動されたコンポーネントのスマートポインタが渡されます。
/// @param[in] in_char_code
///   : キャラコードが渡されます。
/// @param[in] in_key_data
///   : キーデータが渡されます。\n
///   : 詳しくはWM_CHARのlParamを検索してください。
  /// 
  /// @return
  /// 呼び出し元に対する要請としてeEventReturnIDを返します。\n
  /// 詳しくはeEventReturnIDを参照してください。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual eEventReturnID
    On_Char
      ( _in<sdptr<Component>> in_sp_component
      , _in<TCHAR           > in_char_code
      , _in<int             > in_key_data
      )
  {
    return eEventReturnID::LastCall;
  }

  // _____________________________________________________________________________
  /// @brief ユーザー独自プロシージャ対応イベント
  /// 
  /// @param[in] in_sp_component
  ///   : 移動されたコンポーネントのスマートポインタが渡されます。
  /// @param[in] in_message : メッセージIDが渡されます。
  /// @param[in] in_wparam  : WPARAM値が渡されます。
  /// @param[in] in_lparam  : LPARAM値が渡されます。
  /// 
  /// @return
  /// 呼び出し元に対する要請としてeEventReturnIDを返します。\n
  /// 詳しくはeEventReturnIDを参照してください。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual eEventReturnID
    On_UserProc
      ( _in<sdptr<Component>> in_sp_component
      , _in<long            > in_message
      , _in<WPARAM          > in_wparam
      , _in<LPARAM          > in_lparam
      )
  {
    return eEventReturnID::SendParent_Position;
  }
};



} // namespace GUC

TBTag ToTag( _in<GUC::DrawColorSet> in_color_set );

// _____________________________________________________________________________
/// GUC::DrawColorSetからタグを取得
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
inline TBTag&
  operator << ( rio<TBTag> tag, _in<GUC::DrawColorSet> in_color_set )
{
  tag = ToTag( in_color_set );
  return tag;
}

// _____________________________________________________________________________
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
GUC::DrawColorSet& operator << ( rio<GUC::DrawColorSet> c, _in<TBTag> in_tag );

CPL_DEF_CORE_TAG_RSHIFT_INOUT( GUC::DrawColorSet )

} // namespace CPL
