#pragma once
// WAC.com Class Liblary for Visual C++
// Copyright (C) WAC.com Inc. All rights reserved.
//
// This file is a part of the WAC.com Class Liblary.
// The use and distribution terms for this software are covered by the
// Common Public License 1.0 (http://opensource.org/licenses/cpl.php)
// which can be found in the file CPL.TXT at the root of this distribution.
// By using this software in any fashion, you are agreeing to be bound by
// the terms of this license. You must not remove this notice, or
// any other, from this software.
// 05.06.23 : 新規作成 (oka)
// 05.11.28 : コードのブラッシュアップ (sha)
// 05.12.13 : _SetComboBoxCurSelFromDataの作成 (sug)
// 05.12.13 : コードのブラッシュアップ (sug)
// 05.12.22 : LoadComboBoxの仕様変更とブラッシュアップ (sug)
// 06.01.04 : コードの整備 (sug)
// 06.02.09 : コードの整備 (sug)
// 06.04.18 : CDataComboBoxHelperに名称変更 (sha)
// 06.04.19 : CDataComboBoxの作成 (sha)
// 06.05.23 : CDataComboBoxHelperの廃止 (sha)
// 06.05.26 : コードの整備 (sha)
// 06.10.18 : コードの整備 (sha)
// 07.04.19 : CDataComboBoxT::Load()の不具合の修正 (sha)
// 07.04.25 : コードの整備 (sha)
// 07.05.08 : WAC1380 : メモ/カテゴリ カテゴリのメニューが表示されないの修正(imatsu)
// 07.06.20 : コードの整備 (sha)
#include <map>
#include <vector>
////////////////////////////////////////////////////////////////////////////////
// CDataComboBoxT
template <class TKey, class TVal, class TBase>
class CDataComboBoxT : public TBase
{
protected:
typedef CDataComboBoxT thisClass;
public:
CDataComboBoxT()
{
}
CDataComboBoxT(HWND hWnd) : TBase(hWnd)
{
}
virtual ~CDataComboBoxT()
{
}
public:
HRESULT Load(std::map<TKey, TVal>& Vals)
{
USES_CONVERSION;
// リストボックスの初期化
this->ResetContent();
for (std::map<TKey, TVal>::iterator iter = Vals.begin(); iter != Vals.end(); iter++)
{
#ifdef UNICODE
int nIndex = (int)::SendMessageA(m_hWnd, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)W2A(iter->second));
#else
// NOTE: 第一引数に -1 を設定すると文字列を最後尾に追加する
// int nIndex = this->InsertString(-1, iter->second);
int nIndex = this->AddString(iter->second);
#endif
if (nIndex == LB_ERR)
{
ATLASSERT(0);
continue;
}
else if (nIndex == LB_ERRSPACE)
{
// 文字列を追加する領域の不足
ATLASSERT(0);
continue;
}
this->SetItemDataPtr(nIndex, (LPVOID)&iter->first);
}
if (this->GetCount() == 0)
{
return S_FALSE;
}
// 最初のアイテムを選択する
int nCurSel = this->SetCurSel(0);
if (nCurSel == CB_ERR)
{
// 何も行わない。。
ATLASSERT(0);
}
return S_OK;
}
HRESULT Load(std::map<TKey, TVal>& Vals, std::vector<TKey> Keys)
{
USES_CONVERSION;
// リストボックスの初期化
this->ResetContent();
for (int i = 0 ; i < (int)Keys.size(); i++)
{
TKey& Key = Keys[i];
std::map<TKey, TVal>::iterator iter = Vals.find(Key);
if (iter == Vals.end())
{
ATLASSERT(0);
continue;
}
#ifdef UNICODE
int nIndex = (int)::SendMessageA(m_hWnd, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)W2A(iter->second));
#else
// NOTE: 第一引数に -1 を設定すると文字列を最後尾に追加する
// int nIndex = this->InsertString(-1, iter->second);
int nIndex = this->AddString(iter->second);
#endif
if (nIndex == LB_ERR)
{
ATLASSERT(0);
continue;
}
else if (nIndex == LB_ERRSPACE)
{
// 文字列を追加する領域の不足
ATLASSERT(0);
continue;
}
this->SetItemDataPtr(nIndex, (LPVOID)&iter->first);
}
if (this->GetCount() == 0)
{
return S_FALSE;
}
// 最初のアイテムを選択する
int nCurSel = this->SetCurSel(0);
if (nCurSel == CB_ERR)
{
// 何も行わない。。
ATLASSERT(0);
}
return S_OK;
}
public:
TKey GetCurData(TKey defaultKey)
{
int nCurSel = this->GetCurSel();
if (nCurSel < 0)
{
// NOTE: Edit入力の場合は、ここに入ります。
// ATLASSERT(0);
return defaultKey;
}
return this->GetData(nCurSel, defaultKey);
}
int SetCurData(TKey Key)
{
int nIndex = this->GetIndexFromData(Key);
if (nIndex == -1)
{
// ATLASSERT(0);
return -1;
}
return this->SetCurSel(nIndex);
}
public:
CString GetText(LPCTSTR szDefaultText = _T(""))
{
CString strResult;
UINT nr = __super::GetWindowText(strResult);
if (!nr)
{
// ATLASSERT(0);
return szDefaultText;
}
return strResult;
}
public:
#if 0
int GetCurSel()
{
return this->TBase::GetCurSel();
}
int SetCurSel(int nSelect)
{
return this->TBase::SetCurSel(nSelect);
}
#endif
TKey GetData(int nIndex, const TKey& defaultKey)
{
TKey* p = (TKey*)this->GetItemDataPtr(nIndex);
if (p == NULL)
{
ATLASSERT(0);
return defaultKey;
}
return (*p);
}
// NOTE: TKey::operator ==() が定義されていること
int GetIndexFromData(const TKey& Key)
{
int nIndex = -1;
for (int i = 0; i < this->GetCount(); i++)
{
TKey* p = (TKey*)this->GetItemDataPtr(i);
if (*p == Key)
{
nIndex = i;
break;
}
}
return nIndex;
}
};
////////////////////////////////////////////////////////////////////////////////
// CDataComboBox
template <class TKey, class TVal>
class CDataComboBox : public CDataComboBoxT<TKey, TVal, CComboBox>
{
protected:
typedef CDataComboBoxT thisClass;
public:
CDataComboBox()
{
}
CDataComboBox(HWND hWnd) : CDataComboBoxT<TKey, TVal, CComboBox>(hWnd)
{
}
};