/// ****************************************************************************
/// @file   
/// @author Dr.Neeton
/// @date   2010/X/X - 2017/01/25
/// 
/// @brief  グラフィカルユーザーコンポーネント　基本コンポーネントクラス。
/// 
/// ※ 2013/11/18 CPL_GUC_Base.hより分離。
/// 
/// ****************************************************************************

#pragma once

#include "CPL_GUC_Base.h"
#include "CPL_GUC_Factory.h"
//#include "CPL_GUC_Layer.h"
#include "../Core/Base/CPL_Core_Facotry.h"


namespace CPL {
namespace GUC {

namespace doxycomment
{
/// @param[in] in_sp_component_for_parent
///   : 親コンポーネントのスマートポインタを指定します。
inline void arg_in_sp_component_for_parent(_in<sdptr<Component>> in_sp_component_for_parent){}
/// @param[in] in_position_for_component
///   : コンポーネント座標を指定します。
inline void arg_in_position_for_component( _in<float2> in_position_for_component ){}
/// @param[in] in_movevalue_for_component
///   : コンポーネント座標の移動量を指定します。
inline void arg_in_movevalue_for_component( _in<float2> in_movevalue_for_component ){}
/// @param[in] in_size_for_component
///   : コンポーネントサイズを指定します。
inline void arg_in_size_for_component( _in<float2> in_size_for_component ){}
/// @param[in] in_string_for_label
///   : ラベルに表示する文字列を指定します。
inline void arg_in_string_for_label( pin<td_DefChar> in_string_for_label ){}
/// @param[in] in_value_of_minimum : 最小値を指定します。
inline void arg_in_value_of_minimum( _in<double> in_value_of_minimum ){}
/// @param[in] in_value_of_maximum : 最大値を指定します。
inline void arg_in_value_of_maximum( _in<double> in_value_of_maximum ){}
/// @param[in] in_value_of_initial : 初期値を指定します。
inline void arg_in_value_of_initial( _in<double> in_value_of_initial ){}
/// @param[in] in_position_for_client
///   : 描画クライアントの左上の座標を指定します。\n
///   : 負数を指定した場合、フレーム幅が適用されます。
inline void arg_in_position_for_client( _in<float2> in_position_for_client ){}
/// @param[in] in_size_for_client
///   : 描画クライアントのサイズを指定します。
inline void arg_in_size_for_client( _in<float2> in_size_for_client ){}
/// @param[in] in_width_for_label : ラベルの幅を指定します。
inline void arg_in_width_for_label( _in<float> in_width_for_label ){}
/// @param[in] in_width_for_numbox : 数値ボックスの幅します。
inline void arg_in_width_for_numbox( _in<float> in_width_for_numbox ){}
/// @param[in] in_string_for_button
///   : ボタンに表示する文字列を指定します。
inline void arg_in_string_for_button( pin<td_DefChar> in_string_for_button ){}
/// @param[in] in_string_for_tooltip
///   : ツールチップとして表示する文字列を指定します。
inline void arg_in_string_for_tooltip( pin<td_DefChar> in_string_for_tooltip ){}
/// @param[in] in_offset_position_from_original
///   : オリジナルからのオフセット座標を指定します。
inline void arg_in_offset_position_from_original( _in<float2> in_offset_position_from_original ){}

}


static const float2 kPOS_DEFAULT(0.0f, 0.0f);
static const float2 kSIZE_DEFAULT(-1.0f, -1.0f);

// _____________________________________________________________________________
/// @brief 基本コンポーネントクラス
///
// *****************************************************************************
class Component
  : public Core::IncludeSmartLinkTree< Component >
  , public MouseEventInterface
  , public KeyEventInterface
  , public WindowEventInterface
  , public UseFactorySelfPointer
  , public UseFactoryCallCreate
{
  using td_self = Component;
  friend Factory<td_self>;
  friend CallPrivateConstructor<td_self>;
  friend class Container;
  friend class RenderBox;
protected:
  friend class FrameEvent;
  //friend class Timer;

  // _____________________________________________________________________________
  /// @brief 描画用頂点データ
  ///
  // *****************************************************************************
  struct DrawVtxInfo
  {
    float  x, y, z;
    DX::ColorType color;
    
    DrawVtxInfo(){}
    DrawVtxInfo( float x_, float y_, float z_, DX::ColorType const& color_ )
      : x( x_ ), y( y_ ), z( z_ ), color( color_ )
    {}
  };
  // _____________________________________________________________________________
  /// @brief ２Ｄライン用頂点データ
  ///
  // *****************************************************************************
  struct DrawVtxInfo2
  {
    float  x, y, z, w; // w==width
    DX::ColorType color;
    
    DrawVtxInfo2(){}
    DrawVtxInfo2
    ( _in<float> x_
    , _in<float> y_
    , _in<float> z_
    , _in<float> w_
    , _in<DX::ColorType> color_
    ) : x( x_ ), y( y_ ), z( z_ ), w( w_ ), color( color_ )
    {}
  };

public:
  static sdptr<DrawColorSet> GetDefaultColor_CompBG();
  static sdptr<DrawColorSet> GetDefaultColor_CompFrame();
  static sdptr<DrawColorSet> GetDefaultColor_CompText();
  virtual sdptr<DrawColorSet> GetDefaultColor_BG()   { return GetDefaultColor_CompBG(); }
  virtual sdptr<DrawColorSet> GetDefaultColor_Frame(){ return GetDefaultColor_CompFrame(); }
  virtual sdptr<DrawColorSet> GetDefaultColor_Text() { return GetDefaultColor_CompText(); }

  template<class T>
  sdptr<T> GetSelfPointer() const
  {
    return GetLinkMyself<T>();
  }

private:
  using IdBank = Core::ID_Bank<U8,U32>;
  using ArrayCompPtr = std::vector<Component*>;

  struct zzo_static_param {
    IdBank                      id_bank;
    ArrayCompPtr                comp_table;
    DX::DXDevice*               ptr_d3ddev;
    wkptr<Component>            wp_capture;
    wkptr<Component>            wp_focus;
    wkptr<Component>            wp_active_comp;
    sdptr<DX::RenderCollection> sp_RC_polygon;
    sdptr<DX::FontDrawManager > sp_def_font_mng;
    DX::SpriteDrawManager       def_sprite_mng;
    DX::CpDXShaderResourceView  cp_tex_parts;
    float                       line_height;
    float                       all_applied_draw_alpha;
    sdptr<DX::Layout::Buffer>   sp_layout_buf;

    zzo_static_param();
    ~zzo_static_param(){}
  };
  using SpStaticParam = std::shared_ptr<zzo_static_param>;
  CPL_SINGLETON_INIT( SpStaticParam, sm_param, CPL_MAKE_SHARED(zzo_static_param) )

  static IdBank&       sm_comp_id_bank(){ return sm_param()->id_bank; }
  static ArrayCompPtr& sm_comp_table(){ return sm_param()->comp_table; }

protected:
  static DX::DXDevice*&               sm_ptr_d3ddev()            { return sm_param()->ptr_d3ddev; }
  static sdptr<Component> const       sm_sp_capture()            { return sm_param()->wp_capture.lock(); } // キャプチャ判定用ポインタ
  static sdptr<Component> const       sm_sp_focus()              { return sm_param()->wp_focus.lock(); }
  static sdptr<Component> const       sm_sp_ac_comp()            { return sm_param()->wp_active_comp.lock(); }
  static sdptr<DX::RenderCollection>& sm_sp_RC_polygon()         { return sm_param()->sp_RC_polygon; }
  static sdptr<DX::FontDrawManager >& sm_def_font_mng()          { return sm_param()->sp_def_font_mng; }
  static DX::SpriteDrawManager&       sm_def_sprite_mng()        { return sm_param()->def_sprite_mng; }
  static DX::CpDXShaderResourceView&  sm_tex_parts()             { return sm_param()->cp_tex_parts; }
  static float&                       sm_line_height()           { return sm_param()->line_height; }
  static float&                       sm_all_applied_draw_alpha(){ return sm_param()->all_applied_draw_alpha; }
  static sdptr<DX::Layout::Buffer>&   sm_sp_layout_buf()         { return sm_param()->sp_layout_buf; }
  static void                         sm_sp_capture( _in<wkptr<Component>> in_wp_cap     ){ sm_param()->wp_capture     = in_wp_cap; }
  static void                         sm_sp_focus  ( _in<wkptr<Component>> in_wp_focus   ){ sm_param()->wp_focus       = in_wp_focus; }
  static void                         sm_sp_ac_comp( _in<wkptr<Component>> in_wp_ac_comp ){ sm_param()->wp_active_comp = in_wp_ac_comp; }
  static void                         sm_sp_capture( nullptr_t ){ sm_param()->wp_capture    .reset(); }
  static void                         sm_sp_focus  ( nullptr_t ){ sm_param()->wp_focus      .reset(); }
  static void                         sm_sp_ac_comp( nullptr_t ){ sm_param()->wp_active_comp.reset(); }

  static int zzf_GetClassLevel(){ return 1; }

private:
  U32             m_comp_ID;
  std::string     m_user_ID;
  float4          m_rect; ///< ウィンドウ座標。
  HCURSOR         m_def_cursor;      ///< デフォルトのカーソル。
  float           m_frame_width;     ///< 枠の幅。
  U32             m_initialized_level  : 8; ///< 初期化が終わっているかどうか（そのクラスのレベルが設定される）
  U32             m_flag_visible       : 1; ///< 表示の有無。
  U32             m_flag_draw_owner    : 1; ///< 描画オーナーかどうか。
  U32             m_flag_enable        : 1; ///< 有効かどうか。
  U32             m_flag_update        : 1; ///< 表示バッファの更新が必要かどうか。
  U32             m_flag_draw_bg       : 1; ///< 背景描画コールバック関数を呼び出すかどうか。
  U32             m_flag_draw_frame    : 1; ///< 枠描画コールバック関数を呼び出すかどうか。
  U32             m_flag_draw_client   : 1; ///< クライアント描画コールバック関数を呼び出すかどうか。
  U32             m_flag_clip_child    : 1; ///< 子供に対しカリングが必要かどうか。
  U32             m_flag_throw_mouse   : 1; ///< マウスイベントを無視するかどうか。
  WIN::Component* m_ptr_win_subject; ///< 属するウィンドウコンポーネントのポインタ。

  sdptr<DrawColorSet>  m_sp_color_bg;    ///< 背景カラー。
  sdptr<DrawColorSet>  m_sp_color_frame; ///< フレームカラー。
  sdptr<DrawColorSet>  m_sp_color_text;  ///< テキストカラー。

  /// 自身が属するコンポーネント
  /// ※ 属するとは、座標計算に用いる親を指す。\n
  ///    ノードツリーは描画順序、属するコンポーネントは座標計算に用いる。
  wkptr<Component> m_wp_comp_belong;
  SpStaticParam    m_sp_sparam; // 静的デストラクタ順序問題のため保持
  
/// @cond
private:
  bool  zzf_setupInitialize_();
  bool  zzf_setupStaticInitialize_();
protected:
  bool  On_Create();

  static void
    zzf_DrawPolygon
      ( pin<DrawVtxInfo              > in_ptr_vtx_table
      , _in<size_t                   > in_vtx_num
      , pin<U32                      > in_index_table
      , _in<U32                      > in_index_num
      , _in<DX::DX_PRIMITIVE_TOPOLOGY> in_prim_type
      , _in<DX::Matrix2D             > in_matrix = Initialize_()
      );
  static void
    zzf_DrawPolyLineEx
      ( pin<DrawVtxInfo2> in_ptr_vtx_table
      , _in<size_t      > in_vtx_num
      , _in<bool        > in_is_closed
      );
  static void
    zzf_DrawPolyLineEx2
      ( pin<DrawVtxInfo2> in_ptr_vtx_table
      , _in<size_t      > in_vtx_num
      , _in<bool        > in_is_closed
      , _in<DX::Matrix2D> in_mtx
      );

  void  zzf_DrawRect   ( _in<float4> in_rect, _in<DX::ColorType> in_color );
  void  zzf_DrawRectEx ( _in<float4> in_rect, DX::ColorType in_color_table[4] );
  void  zzf_DrawFrame  ( _in<float4> in_rect, _in<DX::ColorType> in_color );
  void  zzf_DrawFrameEx( _in<float4> in_rect, DX::ColorType in_color_table[4] );
  void  zzf_DrawText
          ( _in<float4         > in_rect
          , pin<td_DefChar     > in_text
          , _in<DX::RectColor4P> in_color
          , _in<float          > in_rotate_z
          , _in<float2         > in_rotate_center
          , _in<DWORD          > in_flags
          );
  void  zzf_DrawParts
          ( _in<float2       > in_pos
          , _in<eImagePartsID> in_parts_ID
          , _in<DX::ColorType> in_color
          , _in<float2       > in_scale = float2(1.0f,1.0f)
          );
  void  zzf_DrawCircle
          ( _in<float2       > in_pos
          , _in<float        > in_R
          , _in<DX::ColorType> in_color
          , _in<bool         > in_flag_fill
          );
  void  zzf_SetInitializedLevel( _in<int> in_my_class_level )
  {
    m_initialized_level = in_my_class_level;
  }
  void  zzf_setupDrawState
          ( _in<bool> in_flag_draw_bg
          , _in<bool> in_flag_draw_frame
          , _in<bool> in_flag_draw_client
          );
  void  zzz_setFlagCullingChild( bool in_flag_cull_child )
  {
    m_flag_clip_child = in_flag_cull_child;
  }
  void zzz_setFlagThrowMouse_( bool in_flag_throw_mouse )
  {
    m_flag_throw_mouse = in_flag_throw_mouse;
  }
  void zzz_setFrameSize_( _in<float> in_frame_size ) noexcept
  {
    m_frame_width = in_frame_size;
  }

/// @endcond
private:
public:
  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  static Component*
    ID_to_Pointer( _in<U32> in_comp_ID );
  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  sdptr<Component>
    FindComponent_by_UserID( _in<std::string> in_user_ID ) const;
  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  sdptr<Component>
    FindComponent_by_UserID( _in<sdptr<Component>> in_sp_component ) const;
  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  template<class T>
  sdptr<T>
    FindComponentT_by_UserID( _in<sdptr<Component>> in_sp_component ) const
  {
    return
      std::dynamic_pointer_cast<T>
        ( FindComponent_by_UserID( in_sp_component )
        );
  }

  // _____________________________________________________________________________
  /// @brief 標準の１行の高さ（ピクセル単位）を取得。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  static float GetLineHeight()
  {
    return sm_line_height();
  }

  // _____________________________________________________________________________
  /// @brief 標準の１行の高さ（ピクセル単位）を設定。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  static void SetLineHeight( _in<float> in_line_height )
  {
    sm_line_height() = in_line_height;
  }

  // _____________________________________________________________________________
  /// @brief DirectXデバイスを設定。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  static void SetD3DDevice( _in<DX::DXDevice*> in_ptr_d3ddev )
  {
    sm_ptr_d3ddev() = in_ptr_d3ddev;
  }

  // _____________________________________________________________________________
  /// @brief マウスキャプチャするコンポーネントを設定。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  static void SetCapture( _in<sdptr<Component>> in_sp_component )
  {
    sm_sp_capture( in_sp_component );
    SetActiveComponent(in_sp_component);
  }

  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  static void SetFocus( _in<sdptr<Component>> in_sp_component );

  // _____________________________________________________________________________
  /// @brief 標準のフォント描画マネージャを設定。
  /// @param[in] in_sp_font : 設定するフォントマネージャのスマートポインタ。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  static void SetDrawFontManager( _in<sdptr<DX::FontDrawManager>> in_sp_font )
  {
    sm_def_font_mng() = in_sp_font;
  }

  // _____________________________________________________________________________
  /// @brief マウスキャプチャ中のコンポーネントを取得。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  static sdptr<Component> GetCapture()
  {
    return sm_sp_capture();
  }

  // _____________________________________________________________________________
  /// @brief フォーカス中のコンポーネントを取得。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  static sdptr<Component> GetFocus()
  {
    return sm_sp_focus();
  }

  // _____________________________________________________________________________
  /// @brief デフォルトのフォント描画マネージャを取得。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  static sdptr<DX::FontDrawManager>
    GetDrawFontManager()
  {
    return sm_def_font_mng();
  }

  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  static void
    MappingPosition
      ( _in<sdptr<Component>> in_sp_comp_from
      , _in<sdptr<Component>> in_sp_comp_to
      , pio<float2          > io_vec_table
      , _in<int             > in_table_num
      );

  // _____________________________________________________________________________
  /// @brief アクティブ（イベントを受け取る）なコンポーネントの設定。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  static void
    SetActiveComponent( _in<sdptr<Component>> in_sp_component )
  {
    sm_sp_ac_comp( in_sp_component );
  }

  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  Component
  ( _in<WIN::Component*> in_ptr_win_subject
  , _in<float2         > in_position_for_component
  , _in<float2         > in_size_for_component
  );

protected:
  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  Component
  ( _in<sdptr<Component>> in_sp_component_for_parent
  , _in<float2          > in_position_for_component
  , _in<float2          > in_size_for_component
  );
  
  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  Component( cref<Component> in_component );

  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  void zzf_SetFlag_DrawOwner( _in<bool> in_flag_draw_owner )
  {
    m_flag_draw_owner = in_flag_draw_owner;
  }

public:
  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual ~Component();

  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual bool
    IsHit( rio<float> io_X, rio<float> io_Y ) const noexcept;

  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual sdptr<Component>
    IsHitChild( rio<float> io_X, rio<float> io_Y ) const noexcept;

  // _____________________________________________________________________________
  /// @brief コンポーネントの左上の座標を取得
  ///
  /// ※ 値は、親コンポーネントからの相対座標となる。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual float2
    GetPosition() const noexcept
  {
    return float2(m_rect.x, m_rect.y);
  }

  // _____________________________________________________________________________
  /// @brief コンポーネントのサイズを取得。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual float2
    GetSize() const noexcept
  {
    return float2(m_rect.Width(), m_rect.Height());
  }

  // _____________________________________________________________________________
  /// @brief コンポーネントの４隅の座標を取得。
  ///
  /// ※ 値は、親コンポーネントからの相対座標となる。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual float4
    GetRectCoord() const noexcept
  {
    return m_rect;
  }

  // _____________________________________________________________________________
  /// @brief コンポーネントの４隅の座標を取得。
  ///
  /// ※ 値は、親コンポーネントからの相対座標となる。
  /// @param[in] out_rect : 格納する変数（float4）への参照。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual void
    GetRectCoord( rout<float4> out_rect ) const noexcept
  {
    out_rect = m_rect;
  }

  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual bool
    SetPosition( _in<float2> in_position_for_component );

  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual bool
    MovePosition( _in<float2> in_move_value_for_component );

  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual bool
    SetSize( _in<float2> in_size_for_component );

  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual bool
    SetRectCoord
      ( _in<float4   > in_rect
      , _in<eRectFlag> in_flag_element = WIN::Component::eRectFlag::All
      );

  // _____________________________________________________________________________
  /// @brief 属するプラットフォームのWin32用コンテナクラスを取得
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual WIN::Component*
    GetSubjectWindow() const noexcept
  {
    return m_ptr_win_subject;
  }

  // _____________________________________________________________________________
  /// @brief 属するプラットフォームのWin32用コンテナクラスを設定
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual void
    SetSubjectWindow( _in<WIN::Component*> in_ptr_win ) noexcept
  {
    m_ptr_win_subject = in_ptr_win;
  }

  // _____________________________________________________________________________
  /// @brief 表示状態のフラグを取得
  /// @retval true  : 表示。
  /// @retval false : 非表示。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual bool
    IsVisible() const noexcept
  {
    return m_flag_visible;
  }

  // _____________________________________________________________________________
  /// @brief コンポーネントが有効かどうかのフラグを取得
  /// @retval true  : 有効。
  /// @retval false : 無効。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual bool
    IsEnable() const noexcept
  {
    return m_flag_enable;
  }

  // _____________________________________________________________________________
  /// @brief 表示更新フラグを取得
  /// @retval true  : 更新の必要あり。
  /// @retval false : 更新なし。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual bool
    IsUpdate() const noexcept
  {
    return m_flag_update;
  }

  // _____________________________________________________________________________
  /// @brief 自身が描画オーナーウィンドウかどうかのフラグを取得
  /// @retval true  : 描画オーナーウィンドウである。
  /// @retval false : 描画オーナーウィンドウではない。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual bool
    IsDrawOwner() const noexcept
  {
    return m_flag_draw_owner;
  }

  //// _____________________________________________________________________________
  ///// @brief 自身が配置オーナーウィンドウかどうかを取得。
  ///// @retval true  : 配置オーナーウィンドウである。
  ///// @retval false : 配置オーナーウィンドウではない。
  //// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  //virtual bool
  //  IsArrangeOwner() const noexcept
  //{
  //  return m_flag_arrange_owner;
  //}

  // _____________________________________________________________________________
  /// @brief 背景描画コールバック関数をコールするかどうかのフラグを取得
  /// @retval true  : コールする。
  /// @retval false : コールしない。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual bool
    IsDrawBG() const noexcept
  {
    return m_flag_draw_bg;
  }

  // _____________________________________________________________________________
  /// @brief 枠描画コールバック関数をコールするかどうかのフラグを取得
  /// @retval true  : コールする。
  /// @retval false : コールしない。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual bool
    IsDrawFrame() const noexcept
  {
    return m_flag_draw_frame;
  }

  // _____________________________________________________________________________
  /// @brief クライアント描画コールバック関数をコールするかどうかのフラグを取得
  /// @retval true  : コールする。
  /// @retval false : コールしない。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual bool
    IsDrawClient() const noexcept
  {
    return m_flag_draw_client;
  }

  // _____________________________________________________________________________
  /// @brief 子供のクリッピング判定を行うかどうかのフラグを取得
  /// @retval true  : クリッピングを行う。
  /// @retval false : クリッピングを行わない。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual bool
    IsClipChild() const noexcept
  {
    return m_flag_clip_child;
  }

  // _____________________________________________________________________________
  /// @brief マウスイベントを無視するかどうかのフラグを取得
  /// @retval true  : クリッピングを行う。
  /// @retval false : クリッピングを行わない。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual bool
    IsThrowMouse() const noexcept
  {
    return m_flag_throw_mouse;
  }

  // _____________________________________________________________________________
  /// @brief コンポーネントIDの取得
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual U32
    GetComponentID() const noexcept
  {
    return m_comp_ID;
  }

  // _____________________________________________________________________________
  /// @brief ユーザーIDの取得
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual cref<std::string>
    GetUserID() const noexcept
  {
    return m_user_ID;
  }

  // _____________________________________________________________________________
  /// @brief 初期化済みかどうかを取得
  /// @retval true  : 初期化済み。
  /// @retval false : 未初期化。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual int
    GetInitialized() const noexcept
  {
    return m_initialized_level;
  }

  // _____________________________________________________________________________
  // 上位コンポーネント検索
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  template<class T>
  sdptr<T> FindComponent_ofType_forUpperClass() const noexcept
  {
    auto sp_comp = GetLinkMyself();

    while( sp_comp )
    {
      if( dynamic_cast<T*>(&*sp_comp) )
      {
        return std::dynamic_pointer_cast<T>(sp_comp);
      }

      sp_comp = sp_comp->GetBelongComponent( eParentType::Render );
    }
    return std::dynamic_pointer_cast<T>(sp_comp); // ヒットなしでnullptrが返る
  }

  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual sdptr<Component>
    GetOwnerWindow() const noexcept;

  template<class T_Owner>
  sdptr<T_Owner>
    GetOwnerWindow() const noexcept
  {
    return FindComponent_ofType_forUpperClass<T_Owner>();
  }

  //// _____________________________________________________________________________
  //// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  //virtual sdptr<Component>
  //  GetDrawOwnerWindow()    const noexcept;

  //// _____________________________________________________________________________
  //// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  //virtual sdptr<Component>
  //  GetArrangeOwnerWindow() const noexcept;

  // _____________________________________________________________________________
  /// @brief 親コンポーネントを取得
  /// 
  /// @param[in] in_type_parent : 取得する親のタイプを指定します。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual sdptr<Component>
    GetBelongComponent( _in<eParentType> in_type_parent ) const noexcept
  {
    switch( in_type_parent )
    {
    case eParentType::Position: return m_wp_comp_belong.lock();
    case eParentType::Render:   return GetLinkParent();
    }
    return nullptr;
  }

  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual size_t
    GetBelongComponent
      ( _in <eParentType                  > in_type_parent
      , rout<std::vector<sdptr<Component>>> out_comp_list
      ) const noexcept;

  //// _____________________________________________________________________________
  ///// @brief 描画関係上の親となるコンポーネントを取得
  /////
  ///// ※ GetLinkParent()と同じ。
  //// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  //virtual sdptr<Component>
  //  GetBelongComponent( eParentType::Render ) const noexcept {
  //    return GetLinkParent(); }

  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  sdptr<Component> GetMasterLayer() const;

  // _____________________________________________________________________________
  /// @brief 背景カラーを取得。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  sdptr<DrawColorSet> GetColorParameterBG() const noexcept
  {
    return m_sp_color_bg;
  }

  // _____________________________________________________________________________
  /// @brief フレームカラーを取得。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  sdptr<DrawColorSet> GetColorParameterFrame() const noexcept
  {
    return m_sp_color_frame;
  }

  // _____________________________________________________________________________
  /// @brief テキストカラーを取得。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  sdptr<DrawColorSet> GetColorParameterText() const noexcept
  {
    return m_sp_color_text;
  }

  // _____________________________________________________________________________
  /// @brief コンポーネントに関連付けられているカーソルを取得。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual HCURSOR
    GetCursor() const noexcept
  {
    return m_def_cursor;
  }

  // _____________________________________________________________________________
  /// @brief 枠の幅を取得。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual float
    GetFrameSize() const noexcept
  {
    return m_frame_width;
  }

  // _____________________________________________________________________________
  /// @brief コンポーネントに関連づけるユーザーIDを設定。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual void
    SetUserID( _in<std::string> in_user_ID ) noexcept
  {
    m_user_ID = in_user_ID;
  }

  // _____________________________________________________________________________
  /// @brief ユーザーIDの自動設定
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual void SetAutoUserID()
  {
    m_user_ID = std::to_string( m_comp_ID ) + std::to_string((size_t)this);
  }


  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual void
    SetStateVisible( _in<bool> in_flag_visible ) noexcept;

  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual void
    SetStateEnable( _in<bool> in_flag_enable ) noexcept;

  // _____________________________________________________________________________
  /// @brief コンポーネントの表示を更新する必要があることを設定する。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual void
    SetUpdated() noexcept
  {
    m_flag_update = false;
  }

  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual void
    SetStateDrawBG( _in<bool> in_flag_draw_bg ) noexcept;

  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual void
    SetStateDrawFrame( _in<bool> in_flag_draw_frame ) noexcept;

  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual void
    SetStateDrawClient( _in<bool> in_flag_draw_client ) noexcept;

  // _____________________________________________________________________________
  /// @brief コンポーネントへカーソルを関連付ける。
  /// @param[in] in_hdl_cursor : 自身の領域に入った際に表示するカーソルを指定する。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual void
    SetCursor( _in<HCURSOR> in_hdl_cursor ) noexcept
  {
    m_def_cursor = in_hdl_cursor;
  }

  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual void
    SetFrameWidth( _in<float> in_frame_width ) noexcept;
  
  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual void
    SetBelongComponent
      ( _in<sdptr<Component>> io_sp_comp_belong
      , _in<eParentType     > in_type_parent
      ) noexcept;

  // _____________________________________________________________________________
  /// @brief 背景カラーパラメーターの設定。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual void
    SetColorParameterBG
      ( _in<sdptr<DrawColorSet>> in_sp_color_bg ) noexcept
  {
    m_sp_color_bg = in_sp_color_bg;
  }

  // _____________________________________________________________________________
  /// @brief フレームカラーパラーメーターの設定。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual void
    SetColorParameterFrame
      ( _in<sdptr<DrawColorSet>> in_sp_color_frame ) noexcept
  {
    m_sp_color_frame = in_sp_color_frame;
  }

  // _____________________________________________________________________________
  /// @brief テキストカラーパラメーターの設定。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual void
    SetColorParameterText( _in<sdptr<DrawColorSet>> in_sp_color_text )
  {
    m_sp_color_text = in_sp_color_text;
  }

  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual void
    Update();
  
  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual void
    UpdateAllWindow();

  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual void
    UpdateSubjectWindow();

  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual size_t
    SendParentMessage
      ( _in<sdptr<Component>> in_sp_component
      , _in<long            > in_msg
      , _in<WPARAM          > in_wparam
      , _in<LPARAM          > in_lparam
      , _in<eParentType     > in_type_parent
      );

  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual void
    SendFrameMessage
      ( _in<long  > in_msg
      , _in<WPARAM> in_wparam
      , _in<LPARAM> in_lparam
      );

  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual bool
    CheckBelongComponent
      ( _in<sdptr<Component>> in_sp_component_for_parent
      , _in<eParentType     > in_flag_parent
      ) noexcept;

  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual U32
    SetTimer
      ( _in<U16> in_timer_ID
      , _in<U32> in_time_interval
      ) noexcept;

  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual bool
    KillTimer( _in<U16> in_timer_ID ) noexcept;

  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual float2
    GetAdjustSize( _in<BOOL> in_flag_show ) const noexcept;

  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual bool
    AdjustSize
      ( _in<float2> in_offs_size = float2(0,0)
      , _in<BOOL  > in_flag_show = true
      );

  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual void ActivateTopOrder();

  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual sdptr<Component>
    CreateClone
      ( _in<sdptr<Component>> in_sp_component_for_parent       = nullptr
      , _in<float2          > in_offset_position_from_original = float2{0,0}
      ) const;
  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  template<class T>
  sdptr<T>
    CreateCloneT
      ( _in<sdptr<Component>> in_sp_component_for_parent       = nullptr
      , _in<float2          > in_offset_position_from_original = float2{0,0}
      ) const
  {
    return
      std::dynamic_pointer_cast<T>
        ( CreateClone
            ( in_sp_component_for_parent
            , in_offset_position_from_original
            )
        );
  }
protected:
  // _____________________________________________________________________________
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  template<class T> sdptr<Component>
    zzz_CreateClone_Basic
      ( _in<sdptr<Component>> in_sp_component_for_parent
      , _in<float2          > in_offset_position_from_original
      ) const
  {
    if( auto ptr_target = dynamic_cast<T const*>(this) )
    {
      if( auto sp_component = Factory<T>::Create(*ptr_target) )
      {
        auto sp_component_for_parent =
          in_sp_component_for_parent
            ? in_sp_component_for_parent
            : GetLinkParent();
        sp_component->SetBelongComponent
          ( sp_component_for_parent
          , eParentType::All
          );
        sp_component->MovePosition( in_offset_position_from_original );
        return sp_component;
      }
    }
    return nullptr;
  }
  //
  void zzz_PasteCloneLink( _in<sdptr<Component>> in_sp_target ) const;
  // 
  virtual float2
    On_Paint
      ( _in<sdptr<Component>> in_sp_draw_owner
      , _in<float2          > in_offset_position_from_parent
      );
  virtual void  On_DrawBackground( _in<float4> in_rect );
  virtual void  On_DrawFrame     ( _in<float4> in_rect );
  virtual void  On_DrawClient    ( _in<float4> in_rect ){}
  // その他
  //virtual eEventReturnID
  //  On_TextChange( SmPtrCRef in_sp_text_box ){
  //    return eEventReturnID::SendParent; }

protected:
  // _____________________________________________________________________________
  /// @copydoc MouseEventInterface::On_MouseDown
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  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
      )
  {
    if( in_sp_component == GetLinkMyself() )
    {
      ActivateTopOrder();
      SetFocus( in_sp_component );
      Update();
    }
    return eEventReturnID::SendParent_Position;
  }
  
  // _____________________________________________________________________________
  /// @copydoc MouseEventInterface::On_MouseUp
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  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
      )
  {
    if( in_sp_component == GetLinkMyself() )
    {
      Update();
    }
    return eEventReturnID::SendParent_Position;
  }

  // _____________________________________________________________________________
  /// @copydoc MouseEventInterface::On_MouseEnter
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual eEventReturnID
    On_MouseEnter
      ( _in<sdptr<Component>> in_sp_comp_enter
      , _in<sdptr<Component>> in_sp_comp_leave
      )
  {
    if( in_sp_comp_enter == GetLinkMyself() )
    {
      Update();
    }
    return eEventReturnID::SendParent_Position;
  }

  // _____________________________________________________________________________
  /// @copydoc MouseEventInterface::On_MouseLeave
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual eEventReturnID
    On_MouseLeave
      ( _in<sdptr<Component>> in_sp_comp_leave
      , _in<sdptr<Component>> in_sp_comp_enter
      )
  {
    if( in_sp_comp_leave == GetLinkMyself() )
    {
      Update();
    }
    return eEventReturnID::SendParent_Position;
  }

  // _____________________________________________________________________________
  /// @copydoc WindowEventInterface::On_Show
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  virtual eEventReturnID
    On_Show
      ( _in<sdptr<Component>> in_sp_component
      , _in<BOOL            > in_show_flag
      )
  {
    auto sp_self = GetLinkMyself();
    if( in_sp_component == sp_self )
    {
      auto sp_focus = sm_sp_focus();
      if( in_show_flag == false  &&  sp_focus == sp_self )
      {
        SetFocus( nullptr );
      }
    }
    return WindowEventInterface::On_Show( in_sp_component, in_show_flag );
  }


  template<class T_Func, class... T_Params>
  friend bool call_On_EventX_(T_Func,Component*,T_Params&&...);
  template<class T_Func, class... T_Params>
  friend bool call_On_EventX_forMouse_
    (T_Func,_in<sdptr<Component>> in_sp_component,Component*,float,float,T_Params&&...);

  bool call_On_MouseDown ( _in<sdptr<Component>> in_sp_component, _in<float> in_mouse_x, _in<float> in_mouse_y, _in<eMouseButton> in_type_mouse_btn );
  bool call_On_MouseUp   ( _in<sdptr<Component>> in_sp_component, _in<float> in_mouse_x, _in<float> in_mouse_y, _in<eMouseButton> in_type_mouse_btn );
  bool call_On_MouseMove ( _in<sdptr<Component>> in_sp_component, _in<float> in_mouse_x, _in<float> in_mouse_y );
  bool call_On_MouseWheel( _in<sdptr<Component>> in_sp_component, _in<WORD> in_fw_keys, _in<short> in_z_delta );
  bool call_On_MouseEnter( _in<sdptr<Component>> in_sp_comp_enter, _in<sdptr<Component>> in_sp_comp_leave );
  bool call_On_MouseLeave( _in<sdptr<Component>> in_sp_comp_leave, _in<sdptr<Component>> in_sp_comp_enter );
  bool call_On_KeyDown   ( _in<sdptr<Component>> in_sp_component, _in<int> in_virtual_key_code );
  bool call_On_KeyUp     ( _in<sdptr<Component>> in_sp_component, _in<int> in_virtual_key_code );
  bool call_On_Char      ( _in<sdptr<Component>> in_sp_component, _in<TCHAR> in_char_code, _in<int> in_key_data );
  bool call_On_Show      ( _in<sdptr<Component>> in_sp_component, _in<BOOL> in_show_flag );
  bool call_On_Size      ( _in<sdptr<Component>> in_sp_component );
  bool call_On_Move      ( _in<sdptr<Component>> in_sp_component );
  //bool call_On_Timer     ( _in<int> ID );
  bool call_On_UserProc  ( _in<sdptr<Component>> in_sp_component, _in<long> in_message, _in<WPARAM> in_wparam, _in<LPARAM> in_lparam );

public:

  virtual void MakeTag( rout<TBTag> out_tag, _in<U64> in_types );
  virtual void LoadTag( _in<TBTag> in_tag, _in<U64> in_types );
  virtual void On_LoadTagItem( _in<TBTag> in_tag ){};

  //// _____________________________________________________________________________
  ///// @brief Component Pimpl実装用クラス
  /////
  //// *****************************************************************************
  //class Binder
  //{
  //protected:
  //  SpBaseComponent impl;

  //  Component*       getEntity()       {
  //                      return dynamic_cast<Component*      >(&*impl); }
  //  Component const* getEntity() const {
  //                      return dynamic_cast<Component const*>(&*impl); }

  //  Binder( Component* in_ptr_comp )
  //    : impl( in_ptr_comp ) {}

  //public:
  //  Binder(
  //        SpCompCRef  in_sp_component_for_parent,
  //        short2_cptr in_ptr_pos,
  //        short2_cptr in_ptr_size )
  //    : impl( CPL_NEW Component( in_sp_component_for_parent, in_ptr_pos, in_ptr_size ) ) {}

  //  virtual bool
  //    IsVisible()           const {
  //      return getEntity()->IsVisible(); } ///< @copydoc CPL::GUC::Component::IsVisible
  //  virtual bool
  //    IsHit( int x, int y ) const {
  //      return getEntity()->IsHit( x, y ); } ///< @copydoc CPL::GUC::Component::IsHit
  //  virtual bool
  //    IsEnable()            const {
  //      return getEntity()->IsEnable(); } ///< @copydoc CPL::GUC::Component::IsEnable
  //  virtual bool
  //    IsUpdate()            const {
  //      return getEntity()->IsUpdate(); } ///< @copydoc CPL::GUC::Component::IsUpdate
  //  virtual bool
  //    IsDrawOwner()         const {
  //      return getEntity()->IsDrawOwner(); } ///< @copydoc CPL::GUC::Component::IsDrawOwner
  //  virtual bool
  //    IsArrangeOwner()      const {
  //      return getEntity()->IsArrangeOwner(); } ///< @copydoc CPL::GUC::Component::IsArrangeOwner
  //  virtual int
  //    IsDrawBG() const noexcept {
  //      return getEntity()->IsDrawBG(); } ///< @copydoc CPL::GUC::Component::IsDrawBG
  //  virtual int
  //    IsDrawFrame() const noexcept {
  //      return getEntity()->IsDrawFrame(); } ///< @copydoc CPL::GUC::Component::IsDrawFrame
  //  virtual int
  //    IsDrawText() const noexcept {
  //      return getEntity()->IsDrawText(); } ///< @copydoc CPL::GUC::Component::IsDrawText

  //  virtual U32
  //    GetComponentID()        const noexcept {
  //      return getEntity()->GetComponentID();        } ///< @copydoc CPL::GUC::Component::GetComponentID
  //  virtual U32
  //    GetUserID()             const noexcept {
  //      return getEntity()->GetUserID();             } ///< @copydoc CPL::GUC::Component::GetUserID
  //  virtual int
  //    GetInitialized()        const noexcept {
  //      return getEntity()->GetInitialized();        } ///< @copydoc CPL::GUC::Component::GetInitialized
  //  virtual WIN::Component*
  //    GetSubjectWindow()      const noexcept {
  //      return getEntity()->GetSubjectWindow();      } ///< @copydoc CPL::GUC::Component::GetSubjectWindow
  //  virtual SpComponent
  //    GetOwnerWindow()        const noexcept {
  //      return getEntity()->GetOwnerWindow();        } ///< @copydoc CPL::GUC::Component::GetOwnerWindow
  //  virtual SpComponent
  //    GetDrawOwnerWindow()    const noexcept {
  //      return getEntity()->GetDrawOwnerWindow();    } ///< @copydoc CPL::GUC::Component::GetDrawOwnerWindow
  //  virtual SpComponent
  //    GetArrangeOwnerWindow() const noexcept {
  //      return getEntity()->GetArrangeOwnerWindow(); } ///< @copydoc CPL::GUC::Component::GetArrangeOwnerWindow
  //  virtual SpComponent
  //    GetBelongComponent()    const noexcept {
  //      return getEntity()->GetBelongComponent();    } ///< @copydoc CPL::GUC::Component::GetBelongComponent
  //  virtual float2
  //    GetPosition()            const noexcept {
  //      return getEntity()->GetPosition();            } ///< @copydoc CPL::GUC::Component::GetPosition
  //  virtual float2
  //    GetSize()           const noexcept {
  //      return getEntity()->GetSize();           } ///< @copydoc CPL::GUC::Component::GetSize
  //  virtual float4
  //    GetRectCoord()           const noexcept {
  //      return getEntity()->GetRectCoord();           } ///< @copydoc CPL::GUC::Component::GetRectCoord
  //  virtual void
  //    GetRectCoord( float4& out_rt ) const noexcept {
  //      getEntity()->GetRectCoord( out_rt );   } ///< @copydoc CPL::GUC::Component::GetRectCoord
  //  virtual HCURSOR
  //    GetCursor()             const noexcept {
  //      return getEntity()->GetCursor();             } ///< @copydoc CPL::GUC::Component::GetCursor

  //  virtual void
  //    SetUserID( U32 in_user_ID ) noexcept {
  //      getEntity()->SetUserID( in_user_ID ); } ///< @copydoc CPL::GUC::Component::SetUserID
  //  virtual bool
  //    SetPosition( float2 in_pos ) noexcept {
  //      return getEntity()->SetPosition( in_pos ); } ///< @copydoc CPL::GUC::Component::SetPosition
  //  virtual bool
  //    SetSize( float2 in_size ) noexcept {
  //      return getEntity()->SetSize( in_size ); } ///< @copydoc CPL::GUC::Component::SetSize
  //  virtual bool
  //    SetRectCoord( float4 in_rect, WINRt_FLAG in_flag_element = WIN::Component::eRectFlag::All ) noexcept {
  //      return getEntity()->SetRectCoord( in_rect, in_flag_element ); } ///< @copydoc CPL::GUC::Component::SetRectCoord
  //  virtual void
  //    SetStateVisible( bool in_flag_visible ) noexcept {
  //      getEntity()->SetStateVisible( in_flag_visible ); } ///< @copydoc CPL::GUC::Component::SetStateVisible
  //  virtual void
  //    SetStateEnable( bool in_flag_enable ) noexcept {
  //      getEntity()->SetStateEnable ( in_flag_enable  ); } ///< @copydoc CPL::GUC::Component::SetStateEnable
  //  virtual void
  //    SetStateDrawBG( bool in_flag_drawframe ) noexcept {
  //      getEntity()->SetStateDrawFrame( in_flag_drawframe ); } ///< @copydoc CPL::GUC::Component::SetStateDrawFrame
  //  virtual void
  //    SetStateDrawFrame( bool in_flag_drawframe ) noexcept {
  //      getEntity()->SetStateDrawFrame( in_flag_drawframe ); } ///< @copydoc CPL::GUC::Component::SetStateDrawFrame
  //  virtual void
  //    SetStateDrawText( bool in_flag_drawframe ) noexcept {
  //      getEntity()->SetStateDrawFrame( in_flag_drawframe ); } ///< @copydoc CPL::GUC::Component::SetStateDrawFrame
  //  virtual void
  //    SetUpdated() noexcept {
  //      getEntity()->SetUpdated(); } ///< @copydoc CPL::GUC::Component::SetUpdated
  //  virtual void
  //    SetCursor( HCURSOR in_hdl_cursor ) noexcept {
  //      getEntity()->SetCursor( in_hdl_cursor ); } ///< @copydoc CPL::GUC::Component::SetCursor
  //  virtual void
  //    SetBelongComponent( SpComponent io_sp_comp_belong, bool in_flag_change_node = true ){
  //      getEntity()->SetBelongComponent( io_sp_comp_belong, in_flag_change_node ); } ///< @copydoc CPL::GUC::Component::SetBelongComponent
  //  virtual void
  //    SetColorParameterBG( sdptr<DrawColorSet> const& in_sp_color_bg ){
  //      getEntity()->SetColorParameterBG( in_sp_color_bg ); } ///< @copydoc CPL::GUC::Component::SetColorParameterBG
  //  virtual void
  //    SetColorParameterFrame( sdptr<DrawColorSet> const& in_sp_color_frame ){
  //      getEntity()->SetColorParameterFrame( in_sp_color_frame ); } ///< @copydoc CPL::GUC::Component::SetColorParameterFrame
  //  virtual void
  //    SetColorParameterText( sdptr<DrawColorSet> const& in_sp_color_text ){
  //      getEntity()->SetColorParameterText( in_sp_color_text ); } ///< @copydoc CPL::GUC::Component::SetColorParameterText

  //  virtual void
  //    Update(){ getEntity()->Update(); } ///< @copydoc CPL::GUC::Component::Update
  //  virtual void
  //    UpdateAllWindow(){ getEntity()->UpdateAllWindow(); } ///< @copydoc CPL::GUC::Component::UpdateAllWindow
  //  virtual void
  //    UpdateSubjectWindow(){
  //      getEntity()->UpdateSubjectWindow(); } ///< @copydoc CPL::GUC::Component::UpdateSubjectWindow
  //  virtual void
  //    SendParentMessage( SpCompCRef in_sp_component, long in_msg, WPARAM in_wparam, LPARAM in_lparam ){
  //      getEntity()->SendParentMessage( in_sp_component, in_msg, in_wparam, in_lparam ); } ///< @copydoc CPL::GUC::Component::SendParentMessage
  //  virtual void
  //    SendFrameMessage( long in_msg, WPARAM in_wparam, LPARAM in_lparam ){
  //      getEntity()->SendFrameMessage( in_msg, in_wparam, in_lparam ); } ///< @copydoc CPL::GUC::Component::SendFrameMessage
  //  virtual bool
  //    CheckBelongComponent( SpCompCRef in_sp_check_comp ) noexcept {
  //      return getEntity()->CheckBelongComponent( in_sp_check_comp ); } ///< @copydoc CPL::GUC::Component::CheckBelongComponent

  //  virtual U32
  //    SetTimer( U16 in_timer_ID, U32 in_time_interval ) noexcept {
  //      return getEntity()->SetTimer( in_timer_ID, in_time_interval ); } ///< @copydoc CPL::GUC::Component::SetTimer
  //  virtual bool
  //    KillTimer( U16 in_timer_ID ) noexcept {
  //      return getEntity()->KillTimer( in_timer_ID ); } ///< @copydoc CPL::GUC::Component::KillTimer

  //  virtual float2
  //    GetAdjustSize( BOOL in_flag_show ) const noexcept {
  //      return getEntity()->GetAdjustSize( in_flag_show ); } ///< @copydoc CPL::GUC::Component::GetAdjustSize
  //  virtual bool
  //    AdjustSize( float2 in_offs_size = float2(0,0), BOOL in_flag_show = true ){
  //      return getEntity()->AdjustSize( in_offs_size, in_flag_show ); } ///< @copydoc CPL::GUC::Component::AdjustSize
  //};
}; // class Component



//class DrawButton;
//class DrawGroup;
//class DrawTabWindow;
//class DrawTextBox;
//class DrawScrollBar;
//class DrawListBox;
//class DrawActiveSelector;
//class DrawActiveMenu;






} // namespace GUC
} // namespace CPL
