///////////////////////////////
// ECCSkelton
// CLISTVIEWクラス定義ファイル
// Copyright (c) August, 2022
//        By Ysama
///////////////////////////////

class CLISTVIEW : public CCTRL
{
public:
	HIMAGELIST m_hLIList;				//リストビュー用イメージリスト(Large)
	HIMAGELIST m_hSIList;				//リストビュー用イメージリスト(Small)
	int m_imgw1;						//イメージリスト(Large)用イメージの幅
	int m_imgh1;						//イメージリスト(Large)用イメージの高さ
	int m_imgnum1;						//イメージリスト(Large)用イメージの最大数
	int m_ext1;							//イメージリスト(Large)用イメージの拡張数
	int m_imgw2;						//イメージリスト(Small)用イメージの幅
	int m_imgh2;						//イメージリスト(Small)用イメージの高さ
	int m_imgnum2;						//イメージリスト(Small)用イメージの最大数
	int m_ext2;							//イメージリスト(Small)用イメージの拡張数
	LV_COLUMN m_lvCol;					//システム用LV_COLUMN構造体
	LV_ITEM m_lvItem;					//システム用LV_ITEM構造体
	LV_FINDINFO m_lvFind;				//システム用LV_FINDINFOM構造体

public:
	CLISTVIEW();							//コンストラクター（１）
	CLISTVIEW(int, int, int, UINT, int,
			int, int, int, UINT, int);		//コンストラクター（２）
	~CLISTVIEW();							//デストラクター
	bool Create(HWND, HINSTANCE, HMENU, int, 
				int, int, int);				//CLISTVIEWコントロール作成関数
	void Move(int, int, int, int);			//ListViewコントロールの移動
	int AddLargeIcon(LPCTSTR, HINSTANCE);	//イメージリストへのLargeアイコン登録
	int AddSmallIcon(LPCTSTR, HINSTANCE);	//イメージリストへのSmallアイコン登録
	int InsertColumn(int, int, LPTSTR, int, UINT);	//コラムの追加
	int InsertItem(int, LPTSTR, int, LPARAM, UINT);	//アイテムの追加
	int SetItem(int, int, LPTSTR);			//サブアイテムの追加
	int GetItemCount();						//アイテム(行）数を取得
	bool Arrange(UINT);						//アイテムを整列する
	void DisplayLarge();					//Largeアイコンの表示
	void DisplaySmall();					//Smallアイコンの表示
	void DisplayList();						//リスト形式の表示
	void DisplayReport();					//レポート形式の表示
	void Editable();						//ラベルを編集可能にする
	LV_ITEM FAR* GetItem(int);				//アイテム情報の取得
	UINT GetItemState(int, UINT);			//アイテムの状態フラグの取得
	void SetItemState(int, UINT, UINT);		//アイテムの状態フラグの設定
	void GetItemText(int, int, LPWSTR, int);//アイテムの文字列の取得
	void SetItemText(int, int, LPWSTR);		//アイテムの文字列の設定
	int GetNextItem(int, UINT);				//アイテム検索関数
	HWND GetEditControl();					//エディットコントロールのハンドルを返す
	HWND EditLabel(int);					//ラベルを編集する（エディットコントロールのハンドルを返す）
	LV_COLUMN* GetColumn(int, LPWSTR, int);	//コラムの属性情報取得
	bool SetColumn(int, int, int, LPWSTR);	//コラムの属性変更
	void DeleteColumns(int);				//コラムの削除
	bool DeleteAllItems();					//全てのアイテムを削除
	bool DeleteItem(int);					//指定したアイテムを削除
	int FindItem(int, LPWSTR, LPARAM);		//指定したアイテムから（m_lvFindの条件）検索
	bool SortItem(PFNLVCOMPARE, LPARAM);	//アイテムをソートする
};

//コンストラクター（１）
CLISTVIEW::CLISTVIEW() {

	m_hWnd			= 0;
	m_dwExStyle		= WS_EX_CLIENTEDGE;
	m_lpClassName	= L"SYSLISTVIEW32";
	m_dwStyle		= WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_SHOWSELALWAYS;
	m_hLIList = ImageList_Create(m_imgw1 = 0, m_imgh1 = 0, ILC_COLOR4, m_imgnum1 = 0, m_ext1 = 0);
	m_hSIList = ImageList_Create(m_imgw2 = 0, m_imgh2 = 0, ILC_COLOR4 | ILC_MASK, m_imgnum2 = 0, m_ext2 = 0);
}

//コンストラクター（２）
CLISTVIEW::CLISTVIEW(int imgw1, int imgh1, int imgnum1, UINT col1, int ext1,
				int imgw2, int imgh2, int imgnum2, UINT col2, int ext2) {

	m_hWnd			= 0;
	m_dwExStyle		= WS_EX_CLIENTEDGE;
	m_lpClassName	= L"SYSLISTVIEW32";
	m_dwStyle		= WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_SHOWSELALWAYS;
	m_hLIList = ImageList_Create(m_imgw1 = imgw1, m_imgh1 = imgh1, col1, m_imgnum1 = imgnum1, m_ext1 = ext1);
	m_hSIList = ImageList_Create(m_imgw2 = imgw2, m_imgh2 = imgh2, col2, m_imgnum2 = imgnum2, m_ext2 = ext2);
}

//デストラクター
CLISTVIEW::~CLISTVIEW() {

	//すべてのリストビューアイテムを削除
	ListView_DeleteAllItems(m_hWnd);
	//ツリービューで作成したイメージリストを廃棄する
	ImageList_Destroy(m_hLIList);
	ImageList_Destroy(m_hSIList);
}

//CLISTVIEWコントロール作成関数
bool CLISTVIEW::Create(HWND hWnd, HINSTANCE hInstance, HMENU ID,
				int x = 0, int y = 0, int w = 0, int h = 0) {

	m_hInstance = hInstance;
	bool res = CCTRL::Create(L"", m_dwStyle, m_dwExStyle, hWnd, ID, x, y, w, h);
	//リストビューを1行、グリッド表示にする
	INITCOMMONCONTROLSEX ic;
	ic.dwSize = sizeof(INITCOMMONCONTROLSEX);
	ic.dwICC = ICC_LISTVIEW_CLASSES;
	InitCommonControlsEx(&ic);
	ListView_SetExtendedListViewStyle(m_hWnd,
			ListView_GetExtendedListViewStyle(m_hWnd) |
			LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
	//ツリービューにイメージコントロールをセット
	ListView_SetImageList(m_hWnd, m_hLIList, LVSIL_NORMAL);
	ListView_SetImageList(m_hWnd, m_hSIList, LVSIL_SMALL);
	return res;
}

//CLISTVIEWコントロールの移動
void CLISTVIEW::Move(int x, int y, int w, int h) {

	MoveWindow(m_hWnd, x, y, w, h, TRUE);
}

//イメージリストへのLargeアイコン登録
int CLISTVIEW::AddLargeIcon(LPCTSTR ID, HINSTANCE hInstance = 0) {

	if(!hInstance)	hInstance = m_hInstance;
	return ImageList_AddIcon(m_hLIList, LoadIcon(hInstance, ID));
}

//イメージリストへのSmallアイコン登録
int CLISTVIEW::AddSmallIcon(LPCTSTR ID, HINSTANCE hInstance = 0) {

	if(!hInstance)	hInstance = m_hInstance;
	return ImageList_AddIcon(m_hSIList, LoadIcon(hInstance, ID));
}

//コラムの追加
int CLISTVIEW::InsertColumn(int Col, int cx, LPWSTR pszText, int fmt = LVCFMT_LEFT,
							UINT mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM) {

	m_lvCol.mask = mask;
	m_lvCol.fmt = fmt;
	m_lvCol.cx = cx;
	m_lvCol.pszText = pszText;
	m_lvCol.iSubItem = Col;
	return ListView_InsertColumn(m_hWnd, Col, &m_lvCol);
}

//アイテムの追加
int CLISTVIEW::InsertItem(int Item, LPTSTR pszText, int Image = -1,
				LPARAM lParam = -1, UINT mask = LVIF_TEXT) {

	m_lvItem.mask = mask;
	if(Image != -1)		m_lvItem.mask |= LVIF_IMAGE;
	if(lParam != -1)	m_lvItem.mask |= LVIF_PARAM;
	m_lvItem.pszText = pszText;
	m_lvItem.iItem = Item;
	m_lvItem.iSubItem = 0;
	m_lvItem.iImage = Image;		//maskの値で無視される
	m_lvItem.lParam = lParam;		//maskの値で無視される
	return ListView_InsertItem(m_hWnd, &m_lvItem);
}

//サブアイテムの追加
int CLISTVIEW::SetItem(int Item, int SubItem, LPTSTR pszText) {

	m_lvItem.mask = LVIF_TEXT;
	m_lvItem.pszText = pszText;
	m_lvItem.iItem = Item;
	m_lvItem.iSubItem = SubItem;
	return ListView_SetItem(m_hWnd, &m_lvItem);
}

//アイテム(行）数を取得
int CLISTVIEW::GetItemCount() {

	return ListView_GetItemCount(m_hWnd);
}

//アイテムを整列する
bool CLISTVIEW::Arrange(UINT code) {

	return ListView_Arrange(m_hWnd, code);
}

//Largeアイコンの表示
void CLISTVIEW::DisplayLarge() {

	SetWindowLong(m_hWnd, GWL_STYLE, WS_CHILD | WS_VISIBLE | LVS_EDITLABELS | LVS_ICON);
	Arrange(LVA_ALIGNLEFT);
}

//Smallアイコンの表示
void CLISTVIEW::DisplaySmall() {

	SetWindowLong(m_hWnd, GWL_STYLE, WS_CHILD | WS_VISIBLE | LVS_SMALLICON);
	Arrange(LVA_ALIGNLEFT);
}

//リスト形式の表示
void CLISTVIEW::DisplayList() {

	SetWindowLong(m_hWnd, GWL_STYLE, WS_CHILD | WS_VISIBLE | LVS_LIST);
	Arrange(LVA_ALIGNLEFT);
}

//レポート形式の表示
void CLISTVIEW::DisplayReport() {

	SetWindowLong(m_hWnd, GWL_STYLE, WS_CHILD | WS_VISIBLE | LVS_REPORT);
	Arrange(LVA_ALIGNLEFT);
}

//ラベルを編集可能にする
void CLISTVIEW::Editable() {

	SetWindowLong(m_hWnd, GWL_STYLE,
					GetWindowLong(m_hWnd, GWL_STYLE) | LVS_EDITLABELS);
	Arrange(LVA_ALIGNLEFT);
}

//アイテム情報の取得
LV_ITEM FAR* CLISTVIEW::GetItem(int item) {

	m_lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE | LVIF_PARAM;
	ListView_GetItem(m_hWnd, &m_lvItem);
   return &m_lvItem;
}

//アイテムの状態フラグの取得
UINT CLISTVIEW::GetItemState(int item, UINT mask) {

	return (UINT)SendMessage(m_hWnd, LVM_GETITEMSTATE, (WPARAM)item, (LPARAM)mask);
}

//アイテムの状態フラグの設定
void CLISTVIEW::SetItemState(int item, UINT data, UINT mask) {

	ListView_SetItemState(m_hWnd, item, data, mask);
}

//アイテムの文字列の取得
void CLISTVIEW::GetItemText(int item, int SubItem, LPWSTR pszText, int max) {

	m_lvItem.mask = LVIF_TEXT;
	m_lvItem.iItem = item;
	m_lvItem.iSubItem = SubItem;
	m_lvItem.pszText = pszText;
	m_lvItem.cchTextMax = max;
	SendMessage(m_hWnd, LVM_GETITEMTEXT , (WPARAM)item, (LPARAM)&m_lvItem); 
}

//アイテムの文字列の設定
void CLISTVIEW::SetItemText(int Item, int SubItem, LPWSTR str) {

	ListView_SetItemText(m_hWnd, Item, SubItem, str);
}

//アイテム検索関数
int CLISTVIEW::GetNextItem(int start, UINT flag) {

	return ListView_GetNextItem(m_hWnd, start, flag);
}

//エディットコントロールのハンドルを返す
HWND CLISTVIEW::GetEditControl() {

	return ListView_GetEditControl(m_hWnd);
}

//ラベルを編集する（エディットコントロールのハンドルを返す）
HWND CLISTVIEW::EditLabel(int item) {

	return ListView_EditLabel(m_hWnd, item);
}

//コラムの属性情報取得
LV_COLUMN* CLISTVIEW::GetColumn(int Col, LPWSTR pszText, int max) {

	m_lvCol.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;
	m_lvCol.pszText = pszText;
	m_lvCol.cchTextMax = max;
	ListView_SetColumn(m_hWnd, Col, &m_lvCol);
	return &m_lvCol;
}

//コラムの属性変更
bool CLISTVIEW::SetColumn(int Col, int fmt, int cx, LPWSTR pszText) {

	m_lvCol.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;
	m_lvCol.fmt = fmt;
	m_lvCol.cx = cx;
	m_lvCol.pszText = pszText;
	return ListView_SetColumn(m_hWnd, Col, &m_lvCol);
}

//コラムの削除
void CLISTVIEW::DeleteColumns(int Col) {

	ListView_DeleteColumn(m_hWnd, Col);
}

//全てのアイテムを削除
bool CLISTVIEW::DeleteAllItems() {

	return ListView_DeleteAllItems(m_hWnd);
}

//指定したアイテム（行）を削除
bool CLISTVIEW::DeleteItem(int hitem) {

	return ListView_DeleteItem(m_hWnd, hitem);
}

//指定したアイテムから（m_lvFindの条件）検索
int CLISTVIEW::FindItem(int item, LPWSTR str = NULL, LPARAM lParam = -1) {

	if(str) {
		m_lvFind.flags = LVFI_PARTIAL | LVFI_STRING;	// | LVFI_WRAP不要
		m_lvFind.psz = str;
		if(lParam != -1) {
			m_lvFind.flags |= LVFI_PARAM;
			m_lvFind.lParam = lParam;
		}
	}
	else {
		if(lParam != -1)
			m_lvFind.flags = LVFI_PARAM;
			m_lvFind.lParam = lParam;
	}
	return ListView_FindItem(m_hWnd, item, &m_lvFind);
}

//アイテムをソートする
bool CLISTVIEW::SortItem(PFNLVCOMPARE CmpProc, LPARAM lParam) {

	return ListView_SortItems(m_hWnd, CmpProc, lParam);
}
