#ifndef CTLLOGIC_H #define CTLLOGIC_H #include "dlglogic.h" #define MAX_ITEMTEXTLEN 50 #define MAX_TILETEXT 50 HRESULT _GetListViewSelectedLPARAM(HWND hwndList, LPARAM* plparam); HRESULT _GetComboBoxSelectedLRESULT(HWND hwndComboBox, LRESULT* plr); // ListView template class CDLUIDataLVItem : public CDLUIData { public: virtual ~CDLUIDataLVItem() {} virtual HRESULT GetText(LPWSTR pszText, DWORD cchText) PURE; virtual HRESULT GetIconLocation(LPWSTR pszIconLocation, DWORD cchIconLocation) PURE; virtual HRESULT GetTileText(int i, LPWSTR pszTileText, DWORD cchTileText) { return E_NOTIMPL; } }; template class CUILListView { public: ~CUILListView(); CUILListView(); HRESULT Init(HWND hwndListView); HRESULT InitTileInfo(const UINT auTileSubItems[], DWORD cTileSubItems); HRESULT AddItem(CDLUIDataLVItem* plvitem); // Note: Caller needs to Release *ppdata at some point HRESULT GetSelectedItemData(TData** ppdata); // Assume Single select listview. Also assume that no other item is selected HRESULT SelectFirstItem(); HRESULT ResetContent(); protected: HWND _hwndList; private: const UINT* _auTileSubItems; int _cTileSubItems; }; template class CUILListViewSelect : public CUILListView { public: HRESULT SelectItem(TCompareData comparedata) { HRESULT hr = E_FAIL; LVITEM lvitem = {0}; int iCount = 0; lvitem.mask = LVIF_PARAM; iCount = ListView_GetItemCount(_hwndList); for (lvitem.iItem = 0; lvitem.iItem < iCount; ++lvitem.iItem) { if (ListView_GetItem(_hwndList, &lvitem)) { CDLUIDataLVItem* plvitem = (CDLUIDataLVItem*)lvitem.lParam; TData* pdata = plvitem->GetData(); if (pdata) { int iResult; hr = pdata->Compare(comparedata, &iResult); pdata->Release(); if (SUCCEEDED(hr) && !iResult) { break; } } } } if (lvitem.iItem == iCount) { //No Match found, Select first item anyway lvitem.iItem = 0; hr = S_FALSE; } lvitem.mask = LVIF_STATE; lvitem.stateMask = LVIS_SELECTED | LVIS_FOCUSED; lvitem.state = LVIS_SELECTED | LVIS_FOCUSED; ListView_SetItem(_hwndList, &lvitem); ListView_EnsureVisible(_hwndList, lvitem.iItem, FALSE); return hr; } }; // ComboBox template class CDLUIDataCBItem : public CDLUIData { public: virtual ~CDLUIDataCBItem() {} virtual HRESULT GetText(LPWSTR pszText, DWORD cchText) PURE; virtual HRESULT GetIconLocation(LPWSTR pszIconLocation, DWORD cchIconLocation) PURE; }; template class CUILComboBox { public: ~CUILComboBox(); HRESULT Init(HWND hwndComboBox); HRESULT AddItem(CDLUIDataCBItem* pcbitem); // Note: Caller needs to Release *ppdata at some point HRESULT GetSelectedItemData(TData** ppdata); HRESULT SelectFirstItem(); HRESULT ResetContent(); private: HWND _hwndCombo; }; template class CUILComboBoxEx { public: ~CUILComboBoxEx(); HRESULT Init(HWND hwndComboBox); HRESULT AddItem(CDLUIDataCBItem* pcbitem); // Note: Caller needs to Release *ppdata at some point HRESULT GetSelectedItemData(TData** ppdata); HRESULT SelectFirstItem(); HRESULT ResetContent(); private: HWND _hwndCombo; }; // Implementations template CUILListView::CUILListView() : _cTileSubItems(0) {} template CUILListView::~CUILListView() { ResetContent(); } template inline HRESULT CUILListView::Init(HWND hwndListView) { _hwndList = hwndListView; return S_OK; } template inline HRESULT CUILListView::InitTileInfo(const UINT auTileSubItems[], DWORD cTileSubItems) { _auTileSubItems = auTileSubItems; _cTileSubItems = cTileSubItems; return S_OK; } template inline HRESULT CUILListView::AddItem(CDLUIDataLVItem* plvitem) { WCHAR szText[MAX_ITEMTEXTLEN]; int iImage; LVITEM lvitem = {0}; HRESULT hr = plvitem->GetText(szText, ARRAYSIZE(szText)); if (SUCCEEDED(hr)) { WCHAR szIconLocation[MAX_PATH + 12]; hr = plvitem->GetIconLocation(szIconLocation, ARRAYSIZE(szIconLocation)); if (SUCCEEDED(hr)) { int iIcon = PathParseIconLocation(szIconLocation); iImage = Shell_GetCachedImageIndex(szIconLocation, iIcon, 0); } } if (SUCCEEDED(hr)) { int iItem; lvitem.mask = LVIF_IMAGE | LVIF_TEXT | LVIF_PARAM; lvitem.pszText = szText; lvitem.iItem = ListView_GetItemCount(_hwndList); lvitem.iImage = iImage; lvitem.lParam = (LPARAM)plvitem; iItem = ListView_InsertItem(_hwndList, &lvitem); if (-1 != iItem) { if (_cTileSubItems) { LVTILEINFO lvti = {0}; lvti.cbSize = sizeof(LVTILEINFO); lvti.iItem = iItem; lvti.cColumns = ARRAYSIZE(_auTileSubItems); lvti.puColumns = (UINT*)_auTileSubItems; ListView_SetTileInfo(_hwndList, &lvti); for (int i = 0; i < _cTileSubItems; ++i) { WCHAR szTileText[MAX_TILETEXT]; hr = plvitem->GetTileText(i, szTileText, ARRAYSIZE(szTileText)); // 1 based ListView_SetItemText(_hwndList, iItem, i + 1, szTileText); } } } else { hr = E_FAIL; } } return hr; } template inline HRESULT CUILListView::GetSelectedItemData(TData** ppdata) { HRESULT hr; BOOL fFound = FALSE; int iCount = ListView_GetItemCount(_hwndList); LVITEM lvitem = {0}; lvitem.mask = LVIF_PARAM | LVIF_STATE; lvitem.stateMask = LVIS_SELECTED | LVIS_FOCUSED; for (int j = 0; !fFound && (j < iCount); ++j) { lvitem.iItem = j; ListView_GetItem(_hwndList, &lvitem); if (lvitem.state & (LVIS_SELECTED | LVIS_FOCUSED)) { fFound = TRUE; } } if (fFound) { CDLUIDataLVItem* plvitem = (CDLUIDataLVItem*)lvitem.lParam; *ppdata = plvitem->GetData(); hr = ((*ppdata) ? S_OK : S_FALSE); } else { *ppdata = NULL; hr = E_FAIL; } return hr; } template inline HRESULT CUILListView::SelectFirstItem() { LVITEM lvitem = {0}; lvitem.iItem = 0; lvitem.mask = LVIF_STATE; lvitem.stateMask = LVIS_SELECTED | LVIS_FOCUSED; lvitem.state = LVIS_SELECTED | LVIS_FOCUSED; ListView_SetItem(_hwndList, &lvitem); ListView_EnsureVisible(_hwndList, lvitem.iItem, FALSE); return S_OK; } template HRESULT CUILListView::ResetContent() { int iCount = 0; LVITEM lvitem = {0}; // go through all the items in the listview and delete the strings // dynamically allocated lvitem.mask = LVIF_PARAM; lvitem.iSubItem = 0; iCount = ListView_GetItemCount(_hwndList); for (lvitem.iItem = 0; lvitem.iItem < iCount; ++lvitem.iItem) { ListView_GetItem(_hwndList, &lvitem); CDLUIDataLVItem* plvitem = (CDLUIDataLVItem*) lvitem.lParam; if (plvitem) { delete plvitem; } } ListView_DeleteAllItems(_hwndList); return S_OK; } // CUILComboBox template CUILComboBox::~CUILComboBox() { ResetContent(); } template HRESULT CUILComboBox::Init(HWND hwndComboBox) { _hwndCombo = hwndComboBox; return S_OK; } template HRESULT CUILComboBox::AddItem(CDLUIDataCBItem* pcbitem) { WCHAR szText[MAX_ITEMTEXTLEN]; HRESULT hr = pcbitem->GetText(szText, ARRAYSIZE(szText)); if (SUCCEEDED(hr)) { int i = ComboBox_AddString(_hwndCombo, szText); if (CB_ERR != i) { ComboBox_SetItemData(_hwndCombo, i, pcbitem); } } return hr; } template HRESULT CUILComboBox::GetSelectedItemData(TData** ppdata) { HRESULT hr; int iCurSel = ComboBox_GetCurSel(_hwndCombo); LRESULT lr = ComboBox_GetItemData(_hwndCombo, iCurSel); if (CB_ERR != lr) { CDLUIDataCBItem* pcbitem = (CDLUIDataCBItem*)lr; *ppdata = pcbitem->GetData(); hr = ((*ppdata) ? S_OK : S_FALSE); } else { *ppdata = NULL; hr = E_FAIL; } return hr; } template HRESULT CUILComboBox::ResetContent() { int c = ComboBox_GetCount(_hwndCombo); for (int i = 0; i < c; ++i) { CDLUIDataCBItem* pcbitem = (CDLUIDataCBItem*) ComboBox_GetItemData(_hwndCombo, i); if (pcbitem) { delete pcbitem; } } ComboBox_ResetContent(_hwndCombo); return S_OK; } template HRESULT CUILComboBox::SelectFirstItem() { ComboBox_SetCurSel(_hwndCombo, 0); return S_OK; } // CUILComboBoxEx template CUILComboBoxEx::~CUILComboBoxEx() { ResetContent(); } template HRESULT CUILComboBoxEx::Init(HWND hwndComboBox) { _hwndCombo = hwndComboBox; return S_OK; } template HRESULT CUILComboBoxEx::AddItem(CDLUIDataCBItem* pcbitem) { WCHAR szText[MAX_ITEMTEXTLEN]; int iImage; HRESULT hr = pcbitem->GetText(szText, ARRAYSIZE(szText)); if (SUCCEEDED(hr)) { WCHAR szIconLocation[MAX_PATH + 12]; hr = pcbitem->GetIconLocation(szIconLocation, ARRAYSIZE(szIconLocation)); if (SUCCEEDED(hr)) { int iIcon = PathParseIconLocation(szIconLocation); iImage = Shell_GetCachedImageIndex(szIconLocation, iIcon, 0); } } if (SUCCEEDED(hr)) { int iItem; COMBOBOXEXITEM cbitem = {0}; cbitem.mask = CBEIF_IMAGE | CBEIF_SELECTEDIMAGE | CBEIF_TEXT | CBEIF_LPARAM; cbitem.pszText = szText; cbitem.iItem = ComboBox_GetCount(_hwndCombo); cbitem.iImage = iImage; cbitem.iSelectedImage = iImage; cbitem.lParam = (LPARAM)pcbitem; iItem = SendMessage(_hwndCombo, CBEM_INSERTITEM, 0, (LPARAM)&cbitem); if (-1 != iItem) { hr = S_OK; } else { hr = E_FAIL; } } return hr; } template HRESULT CUILComboBoxEx::GetSelectedItemData(TData** ppdata) { HRESULT hr; COMBOBOXEXITEM cbitem = {0}; cbitem.mask = CBEIF_LPARAM; cbitem.iItem = ComboBox_GetCurSel(_hwndCombo); if (SendMessage(_hwndCombo, CBEM_GETITEM, 0, (LPARAM)&cbitem)) { CDLUIDataCBItem* pcbitem = (CDLUIDataCBItem*)cbitem.lParam; *ppdata = pcbitem->GetData(); hr = ((*ppdata) ? S_OK : S_FALSE); } else { *ppdata = NULL; hr = E_FAIL; } return hr; } template HRESULT CUILComboBoxEx::ResetContent() { int c = ComboBox_GetCount(_hwndCombo); for (int i = 0; i < c; ++i) { CDLUIDataCBItem* pcbitem = (CDLUIDataCBItem*) ComboBox_GetItemData(_hwndCombo, i); if (pcbitem) { delete pcbitem; } } ComboBox_ResetContent(_hwndCombo); return S_OK; } template HRESULT CUILComboBoxEx::SelectFirstItem() { ComboBox_SetCurSel(_hwndCombo, 0); return S_OK; } #endif // CTLLOGIC_H