📄 listctrldlg.cpp
字号:
hi.mask = HDI_IMAGE | HDI_FORMAT;
hi.fmt |= HDF_IMAGE;
hi.iImage = 0;
header->SetItem (0, &hi);
hi.iImage = 1;
header->SetItem (1, &hi);
hi.iImage = 2;
header->SetItem (2, &hi);
hi.iImage = 3;
header->SetItem (3, &hi);
}
else
{
hi.mask = HDI_FORMAT;
hi.fmt &= ~HDF_IMAGE;
header->SetItem (0, &hi);
header->SetItem (1, &hi);
header->SetItem (2, &hi);
header->SetItem (3, &hi);
}
}
void CListCtrlDlg::OnListctrlBitmap()
{
UpdateData (TRUE);
HDITEM hi;
memset (&hi, '\0', sizeof (HDITEM));
CHeaderCtrl *header = m_ctlList.GetHeaderCtrl ();
hi.mask = HDI_FORMAT;
header->GetItem (0, &hi);
if (m_bBitmap)
{
hi.mask = HDI_BITMAP | HDI_FORMAT;
hi.fmt |= HDF_BITMAP;
hi.fmt &= ~(HDF_STRING | HDF_IMAGE);
hi.hbm = m_hBmpPlanet;
header->SetItem (0, &hi);
hi.hbm = m_hBmpOrbit;
header->SetItem (1, &hi);
hi.hbm = m_hBmpRotate;
header->SetItem (2, &hi);
hi.hbm = m_hBmpDiameter;
header->SetItem (3, &hi);
::EnableWindow (GetDlgItem (IDC_LISTCTRL_TEXT)->m_hWnd, FALSE);
::EnableWindow (GetDlgItem (IDC_LISTCTRL_ICON)->m_hWnd, FALSE);
}
else
{
::EnableWindow (GetDlgItem (IDC_LISTCTRL_TEXT)->m_hWnd, TRUE);
::EnableWindow (GetDlgItem (IDC_LISTCTRL_ICON)->m_hWnd, TRUE);
hi.mask = HDI_FORMAT;
hi.fmt &= ~HDF_BITMAP;
header->SetItem (0, &hi);
header->SetItem (1, &hi);
header->SetItem (2, &hi);
header->SetItem (3, &hi);
if (m_bText)
OnListctrlText();
if (m_bIcon)
OnListctrlIcon();
}
UpdateData (FALSE);
}
void CListCtrlDlg::OnListctrlDisableheader()
{
UpdateData (TRUE);
if (m_bDisableHeader)
m_ctlList.GetHeaderCtrl()->EnableWindow (FALSE);
else
m_ctlList.GetHeaderCtrl()->EnableWindow (TRUE);
}
void CListCtrlDlg::LoadListControl()
{
char *szTitles [] =
{
"Planet",
"Orbit",
"Rotation",
"Diameter"
};
int nWidths [] =
{100, 100, 100, 100};
#define TITLES (sizeof(szTitles)/sizeof(char *))
LV_COLUMN lc;
// HDITEM hi;
m_HeaderIcons.Create (IDB_LISTCTRL_ICONS, 16, 2, RGB(0x00, 0x80, 0x80));
memset (&lc, '\0', sizeof (LV_COLUMN));
lc.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
for (int sub = 0; sub < TITLES; ++sub)
{
lc.iImage = sub;
lc.pszText = szTitles[sub];
lc.cx = nWidths[sub];
lc.iSubItem = sub;
m_ctlList.InsertColumn (sub, &lc);
}
m_SmallPlanets.Create (IDB_LISTCTRL_SMALLPLANETS, 16, 2, RGB(0x00, 0x80, 0x80));
m_LargePlanets.Create (IDB_LISTCTRL_LARGEPLANETS, 32, 2, RGB(0x00, 0x80, 0x80));
m_ctlList.SetImageList (&m_LargePlanets, LVSIL_NORMAL);
m_ctlList.SetImageList (&m_SmallPlanets, LVSIL_SMALL);
//
// Set the header control image list last. If you set it
// to early, the list control will assign its small image
// list to the header control.
//
m_ctlList.GetHeaderCtrl()->SetImageList (&m_HeaderIcons);
for (int i = 0; i < PLANETS; ++i)
AddItem (i, &Planets[i]);
}
#ifndef _USETEXTCALLBACK
//
// NOTA BENE: The following block of code will be compiled
// ONLY if the _USETEXTCALLBACK macro is not defined. The
// definition is at the top of this file.
//
void CListCtrlDlg::AddItem(int nIndex, PLANET *pPlanet)
{
CString string;
LV_ITEM lvitem;
memset ((char *) &lvitem, '\0', sizeof (LV_ITEM));
//
// Insert the planet's name in the first column. This also
// will be the text used by the other three modes.
//
string = pPlanet->Planet;
string += pPlanet->Desc;
lvitem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
lvitem.iItem = nIndex;
lvitem.iSubItem = 0;
lvitem.stateMask = STATEMASK;
lvitem.iImage = pPlanet->nIcon;
lvitem.pszText = (char *)(LPCSTR) string;
lvitem.lParam = nIndex;
m_ctlList.InsertItem (&lvitem);
//
// Insert the orbit into the second column. Beginning
// with Uranus, the orbit in kilometers exceeds the
// limits of a 32-bit signed integer, so the structure
// stores the values in thousand of km. Tack three
// zeros to the end to display the proper number.
//
m_ctlList.FormatNumber (string, pPlanet->Orbit);
string += ",000 km";
lvitem.mask = LVIF_TEXT;
lvitem.iItem = nIndex;
lvitem.iSubItem = 1;
lvitem.pszText = (char *)(LPCSTR) string;
m_ctlList.SetItemText (nIndex, 1, (LPCSTR) string);
//
// The rotation period goes in the third column.
//
if (pPlanet->Rotation.Days)
{
string.Format ("%dd %02dh %02dm",
pPlanet->Rotation.Days,
pPlanet->Rotation.Hours,
pPlanet->Rotation.Minutes);
}
else
{
string.Format ("%02dh %02dm",
pPlanet->Rotation.Hours,
pPlanet->Rotation.Minutes);
}
lvitem.mask = LVIF_TEXT;
lvitem.iItem = nIndex;
lvitem.iSubItem = 2;
lvitem.pszText = (char *)(LPCSTR) string;
m_ctlList.SetItemText (nIndex, 2, (LPCSTR) string);
//
// Finally, the diameter in the fourth column.
//
m_ctlList.FormatNumber (string, pPlanet->Diameter);
string += " km";
lvitem.mask = LVIF_TEXT;
lvitem.iItem = nIndex;
lvitem.iSubItem = 3;
lvitem.pszText = (char *)(LPCSTR) string;
m_ctlList.SetItemText (nIndex, 3, (LPCSTR) string);
}
int CALLBACK CListCtrlDlg::CompareFunction(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
CString strItem1;
CString strItem2;
int nResult;
int nSortOrder = 1;
if (lParamSort < 0)
{
lParamSort *= -1;
nSortOrder = -1;
}
switch (lParamSort)
{
case 0: // Sort by planet name
strItem1 = g_pctlList->GetItemText (lParam1, 0);
strItem2 = g_pctlList->GetItemText (lParam2, 0);
nResult = strItem1.Compare ((LPCSTR) strItem2);
break;
case 1: // Sort by orbit
{
strItem1 = g_pctlList->GetItemText (lParam1, 1);
DWORD dwOne = g_pctlList->UnformatNumber (strItem1);
strItem2 = g_pctlList->GetItemText (lParam2, 1);
DWORD dwTwo = g_pctlList->UnformatNumber (strItem2);
nResult = dwOne - dwTwo;
}
break;
case 2: // Sort by rotation
{
strItem1 = g_pctlList->GetItemText (lParam1, 2);
DWORD dwOne = g_pctlList->UnformatNumber (strItem1);
strItem2 = g_pctlList->GetItemText (lParam2, 2);
DWORD dwTwo = g_pctlList->UnformatNumber (strItem2);
nResult = (int) (dwOne - dwTwo);
}
break;
case 3: // Sort by diameter
{
strItem1 = g_pctlList->GetItemText (lParam1, 3);
DWORD dwOne = g_pctlList->UnformatNumber (strItem1);
strItem2 = g_pctlList->GetItemText (lParam2, 3);
DWORD dwTwo = g_pctlList->UnformatNumber (strItem2);
nResult = (int) (dwOne - dwTwo);
}
break;
default:
nResult = 0;
break;
}
return (nResult * nSortOrder);
}
void CListCtrlDlg::OnDestroy()
{
CPropertyPage::OnDestroy();
}
void CListCtrlDlg::OnColumnclickListctrlListctrl(NMHDR* pNMHDR, LRESULT* pResult)
{
if (!(m_ctlList.GetStyle() & (LVS_SORTDESCENDING | LVS_SORTASCENDING)))
return;
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
int nSortBy = pNMListView->iSubItem;
if (m_ctlList.GetStyle () & LVS_SORTDESCENDING)
nSortBy *= -1;
m_ctlList.SortItems (CompareFunction, nSortBy);
int nCount = m_ctlList.GetItemCount ();
for (int i = 0; i < nCount; ++i)
m_ctlList.SetItemData (i, (LPARAM) i);
*pResult = 0;
}
#else
//
// NOTA BENE: The following block of code implements
// text callback. To implement it, make sure the
// _USETEXTCALLBACK macro is defined. The definition
// is at the top of this file.
//
void CListCtrlDlg::AddItem(int nIndex, PLANET *planet)
{
PLANET *pPlanet;
LV_ITEM lvitem;
memset ((char *) &lvitem, '\0', sizeof (LV_ITEM));
try
{
pPlanet = new PLANET;
}
catch (CMemoryException *e)
{
e->Delete ();
return;
}
memcpy (pPlanet, planet, sizeof (PLANET));
lvitem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
lvitem.iItem = nIndex;
lvitem.iSubItem = 0;
lvitem.stateMask = STATEMASK;
lvitem.iImage = I_IMAGECALLBACK;
lvitem.pszText = LPSTR_TEXTCALLBACK;
lvitem.lParam = (LPARAM) pPlanet;
m_ctlList.InsertItem (&lvitem);
}
int CALLBACK CListCtrlDlg::CompareFunction(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
int nResult;
int nSortOrder = 1;
if (lParamSort < 0)
{
lParamSort *= -1;
nSortOrder = -1;
}
PLANET *pPlanet1 = (PLANET *) lParam1;
PLANET *pPlanet2 = (PLANET *) lParam2;
switch (lParamSort)
{
case 0: // Sort by planet name
nResult = strcmp (pPlanet1->Planet, pPlanet2->Planet);
break;
case 1: // Sort by orbit
nResult = (int) (pPlanet1->Orbit - pPlanet2->Orbit);
break;
case 2: // Sort by rotation
if (pPlanet1->Rotation.Days == pPlanet2->Rotation.Days)
{
if (pPlanet1->Rotation.Hours == pPlanet2->Rotation.Hours)
nResult = pPlanet1->Rotation.Minutes - pPlanet2->Rotation.Minutes;
else
nResult = pPlanet1->Rotation.Hours - pPlanet2->Rotation.Hours;
}
else
nResult = pPlanet1->Rotation.Days - pPlanet2->Rotation.Days;
break;
case 3: // Sort by diameter
nResult = pPlanet1->Diameter - pPlanet2->Diameter;
break;
default:
nResult = 0;
break;
}
return (nResult * nSortOrder);
}
void CListCtrlDlg::OnDestroy()
{
FreeItemMemory ();
CPropertyPage::OnDestroy();
}
void CListCtrlDlg::OnColumnclickListctrlListctrl(NMHDR* pNMHDR, LRESULT* pResult)
{
if (!(m_ctlList.GetStyle() & (LVS_SORTDESCENDING | LVS_SORTASCENDING)))
return;
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
int nSortBy = pNMListView->iSubItem;
if (m_ctlList.GetStyle () & LVS_SORTDESCENDING)
nSortBy *= -1;
m_ctlList.SortItems (CompareFunction, nSortBy);
*pResult = 0;
}
#endif // _USETEXTCALLBACK
void CListCtrlDlg::FreeItemMemory()
{
int nCount = m_ctlList.GetItemCount ();
for (int i = 0; i < nCount; ++i)
delete (PLANET *) m_ctlList.GetItemData (i);
m_ctlList.DeleteAllItems ();
}
//
// The following is the text callback function. It is
// not called unless the text members of any item or
// subitem is set to LPSTR_TEXTCALLBACK
//
void CListCtrlDlg::OnGetdispinfoListctrlListctrl(NMHDR* pNMHDR, LRESULT* pResult)
{
CString string;
PLANET *pPlanet;
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
pPlanet = (PLANET *) pDispInfo->item.lParam;
if (pDispInfo->item.mask & LVIF_TEXT)
{
switch (pDispInfo->item.iSubItem)
{
case 0: // Need Planet name
string = pPlanet->Planet;
{
DWORD dwStyle = m_ctlList.GetStyle () & LVS_TYPEMASK;
if (!(dwStyle & 1))
string += pPlanet->Desc;
}
::lstrcpy (pDispInfo->item.pszText, (LPCSTR) string);
break;
case 1: // Needs Orbit
m_ctlList.FormatNumber (string, pPlanet->Orbit);
string += ",000 km";
::lstrcpy (pDispInfo->item.pszText, (LPCSTR) string);
break;
case 2: // Needs Rotation
if (pPlanet->Rotation.Days)
{
string.Format ("%dd %dh %dm",
pPlanet->Rotation.Days,
pPlanet->Rotation.Hours,
pPlanet->Rotation.Minutes);
}
else
{
string.Format ("%dh %dm",
pPlanet->Rotation.Hours,
pPlanet->Rotation.Minutes);
}
::lstrcpy (pDispInfo->item.pszText, (LPCSTR) string);
break;
case 3: // Needs Diameter
m_ctlList.FormatNumber (string, pPlanet->Diameter);
string += " km.";
::lstrcpy (pDispInfo->item.pszText, (LPCSTR) string);
break;
}
}
if (pDispInfo->item.mask & LVIF_IMAGE)
{
pDispInfo->item.iImage = pPlanet->nIcon;
}
*pResult = 0;
}
//
// Get the index of the first selected item. If you have
// multiple selection set, you can use the pos variable
// to loop through and get all the selected items.
//
int CListCtrlDlg::GetSelectedItem()
{
if (!m_ctlList.GetItemCount ())
return (-1);
POSITION pos = m_ctlList.GetFirstSelectedItemPosition();
if (pos == NULL)
return (-1);
return (m_ctlList.GetNextSelectedItem(pos));
}
//
// Set the selection to focused and selected.
//
int CListCtrlDlg::SetSelectedItem(int nSel)
{
int nOldSel = GetSelectedItem();
m_ctlList.SetItemState (nSel, LVIS_SELECTED | LVIS_FOCUSED,
LVIS_SELECTED | LVIS_FOCUSED);
return (nOldSel);
}
void CListCtrlDlg::OnClickListctrlListctrl(NMHDR* pNMHDR, LRESULT* pResult)
{
if (m_ctlList.GetStyle () & LVS_REPORT)
{
LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW) pNMHDR;
int nIndex;
CPoint point (lpnmlv->ptAction);
point.x = 2;
if ((nIndex = m_ctlList.HitTest (point, NULL)) != -1)
{
m_ctlList.SetItemState (nIndex, LVIS_SELECTED | LVIS_FOCUSED,
LVIS_SELECTED | LVIS_FOCUSED);
}
}
*pResult = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -