日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

MFC CListControl 点击列头排序的实现

發布時間:2023/12/29 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MFC CListControl 点击列头排序的实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?????? SetItemData可以為每一行綁定一個DWORD類型的變量。用GetItemData可以獲得這個變量。
舉個例子,假設CListCtrl中你需要顯示某個數據表中的記錄,該表有個流水號主鍵ID,一般這個ID值本身沒有什么意義,用戶也不需要看,因此在CListCtrl的可見列中,你不需要顯示。但往往做具體查詢等操作時,你又需要用這個ID來完成。這時,用SetItemData將其綁定到每一行,將非常方便,用戶操作哪一行,則用GetItemData可以得到對應記錄的ID,直接用來做操作。

??????SetItemData未綁定對象,可直接綁定行號進行排序。

????? 排序類

????? ListCtrl_Sortable.h

#pragma onceclass CListCtrl_Sortable : public CListCtrl { public:bool m_Ascending;int m_SortCol;DECLARE_MESSAGE_MAP();afx_msg BOOL OnHeaderClick(NMHDR* pNMHDR, LRESULT* pResult);void PreSubclassWindow();public:CListCtrl_Sortable():m_Ascending(false),m_SortCol(-1){}int GetColumnData(int col) const;void SetSortArrow(int col, bool ascending);bool IsAscending() const { return m_Ascending; }void ResetSortOrder();virtual bool SortColumn(int columnIndex, bool ascending);static int g_columnIndex;static bool g_ascending; };

????? ListCtrl_Sortable.cpp

#include "stdafx.h"#include "CListCtrl_Sortable.h" #include "Resource.h"#include <shlwapi.h>int CListCtrl_Sortable::g_columnIndex = 0; bool CListCtrl_Sortable::g_ascending = false;BEGIN_MESSAGE_MAP(CListCtrl_Sortable, CListCtrl)ON_NOTIFY_REFLECT_EX(LVN_COLUMNCLICK, OnHeaderClick) // Column Click END_MESSAGE_MAP()namespace {bool IsThemeEnabled(){HMODULE hinstDll;bool XPStyle = false;bool (__stdcall *pIsAppThemed)();bool (__stdcall *pIsThemeActive)();// Test if operating system has themes enabledhinstDll = ::LoadLibrary("UxTheme.dll");if (hinstDll){(FARPROC&)pIsAppThemed = ::GetProcAddress(hinstDll, "IsAppThemed");(FARPROC&)pIsThemeActive = ::GetProcAddress(hinstDll,"IsThemeActive");::FreeLibrary(hinstDll);if (pIsAppThemed != NULL && pIsThemeActive != NULL){if (pIsAppThemed() && pIsThemeActive()){// Test if application has themes enabled by loading the proper DLLhinstDll = LoadLibrary("comctl32.dll");if (hinstDll){DLLGETVERSIONPROC pDllGetVersion = (DLLGETVERSIONPROC)::GetProcAddress(hinstDll, "DllGetVersion");::FreeLibrary(hinstDll);if (pDllGetVersion != NULL){DLLVERSIONINFO dvi;ZeroMemory(&dvi, sizeof(dvi));dvi.cbSize = sizeof(dvi);HRESULT hRes = pDllGetVersion ((DLLVERSIONINFO *) &dvi);if (SUCCEEDED(hRes))XPStyle = dvi.dwMajorVersion >= 6;}}}}}return XPStyle;}LRESULT EnableWindowTheme(HWND hwnd, LPCWSTR app, LPCWSTR idlist){HMODULE hinstDll;HRESULT (__stdcall *pSetWindowTheme)(HWND hwnd, LPCWSTR pszSubAppName, LPCWSTR pszSubIdList);HANDLE (__stdcall *pOpenThemeData)(HWND hwnd, LPCWSTR pszClassList);HRESULT (__stdcall *pCloseThemeData)(HANDLE hTheme);hinstDll = ::LoadLibrary("UxTheme.dll");if (hinstDll){(FARPROC&)pOpenThemeData = ::GetProcAddress(hinstDll, TEXT("OpenThemeData"));(FARPROC&)pCloseThemeData = ::GetProcAddress(hinstDll, TEXT("CloseThemeData"));(FARPROC&)pSetWindowTheme = ::GetProcAddress(hinstDll, TEXT("SetWindowTheme"));::FreeLibrary(hinstDll);if (pSetWindowTheme && pOpenThemeData && pCloseThemeData){HANDLE theme = pOpenThemeData(hwnd,L"ListView");if (theme!=NULL){VERIFY(pCloseThemeData(theme)==S_OK);return pSetWindowTheme(hwnd, app, idlist);}}}return S_FALSE;} }BOOL CListCtrl_Sortable::OnHeaderClick(NMHDR* pNMHDR, LRESULT* pResult) {NMLISTVIEW* pLV = reinterpret_cast<NMLISTVIEW*>(pNMHDR);SetFocus(); // Ensure other controls gets kill-focusint colIndex = pLV->iSubItem;if (m_SortCol==colIndex){m_Ascending = !m_Ascending;}else{m_SortCol = colIndex;m_Ascending = true;}if (SortColumn(m_SortCol, m_Ascending))SetSortArrow(m_SortCol, m_Ascending);return FALSE; // Let parent-dialog get chance }void CListCtrl_Sortable::SetSortArrow(int colIndex, bool ascending) {if (IsThemeEnabled()){ #if (_WIN32_WINNT >= 0x501)for(int i = 0; i < GetHeaderCtrl()->GetItemCount(); ++i){HDITEM hditem = {0};hditem.mask = HDI_FORMAT;VERIFY( GetHeaderCtrl()->GetItem( i, &hditem ) );hditem.fmt &= ~(HDF_SORTDOWN|HDF_SORTUP);if (i == colIndex){hditem.fmt |= ascending ? HDF_SORTDOWN : HDF_SORTUP;}VERIFY( CListCtrl::GetHeaderCtrl()->SetItem( i, &hditem ) );} #endif}else{UINT bitmapID = m_Ascending ? IDB_DOWNARROW : IDB_UPARROW; //IDB_DOWNARROW,表示向下箭頭IDB位圖;IDB_UPARROW,表示向上箭頭IDB位圖for(int i = 0; i < GetHeaderCtrl()->GetItemCount(); ++i){HDITEM hditem = {0};hditem.mask = HDI_BITMAP | HDI_FORMAT;VERIFY( GetHeaderCtrl()->GetItem( i, &hditem ) );if (hditem.fmt & HDF_BITMAP && hditem.fmt & HDF_BITMAP_ON_RIGHT){if (hditem.hbm){DeleteObject(hditem.hbm);hditem.hbm = NULL;}hditem.fmt &= ~(HDF_BITMAP|HDF_BITMAP_ON_RIGHT);VERIFY( CListCtrl::GetHeaderCtrl()->SetItem( i, &hditem ) );}if (i == colIndex){hditem.fmt |= HDF_BITMAP|HDF_BITMAP_ON_RIGHT;hditem.hbm = (HBITMAP)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(bitmapID), IMAGE_BITMAP, 0,0, LR_LOADMAP3DCOLORS); VERIFY( hditem.hbm!=NULL );VERIFY( CListCtrl::GetHeaderCtrl()->SetItem( i, &hditem ) );}}} }void CListCtrl_Sortable::PreSubclassWindow() {CListCtrl::PreSubclassWindow();// Focus retangle is not painted properly without double-buffering #if (_WIN32_WINNT >= 0x501)SetExtendedStyle(LVS_EX_DOUBLEBUFFER | GetExtendedStyle()); #endifSetExtendedStyle(GetExtendedStyle() | LVS_EX_FULLROWSELECT);SetExtendedStyle(GetExtendedStyle() | LVS_EX_HEADERDRAGDROP);EnableWindowTheme(GetSafeHwnd(), L"Explorer", NULL); }void CListCtrl_Sortable::ResetSortOrder() {m_Ascending = true;m_SortCol = -1;SetSortArrow(m_SortCol, m_Ascending); }// The column version of GetItemData(), one can specify an unique // identifier when using InsertColumn() int CListCtrl_Sortable::GetColumnData(int col) const {LVCOLUMN lvc = {0};lvc.mask = LVCF_SUBITEM;VERIFY( GetColumn(col, &lvc) );return lvc.iSubItem; }// 比較函數 static int CALLBACK MyCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) {// 從參數中提取所需比較lc的兩行數據int row1 = (int) lParam1;int row2 = (int) lParam2;CListCtrl* lc = (CListCtrl*)lParamSort;CString lp1 = lc->GetItemText(row1,CListCtrl_Sortable::g_columnIndex);CString lp2 = lc->GetItemText(row2,CListCtrl_Sortable::g_columnIndex);// 文字型比較if (CListCtrl_Sortable::g_ascending)return lp1.CompareNoCase(lp2);elsereturn lp2.CompareNoCase(lp1);return 0; }bool CListCtrl_Sortable::SortColumn(int columnIndex, bool ascending) {//排序g_columnIndex = columnIndex;g_ascending = ascending;int count = GetItemCount();for (int i=0;i<count;i++){SetItemData(i,i); // 每行的比較關鍵字,此處為列序號(點擊的列號),可以設置為其他 比較函數的第一二個參數}SortItems(MyCompareProc, (DWORD_PTR)this);return true; }


//IDB_DOWNARROW,表示向下箭頭IDB位圖;IDB_UPARROW,表示向上箭頭IDB位圖。


????? SetItemData綁定對象排序。

????? 如果SetItemData綁定的數據是一個對象時,需要在SortColumn函數的比較函數中做處理。通過GetItemData讀取對象,遍歷CListCtrl所有行,與對象比較,找到某兩行。然后再獲取這兩行對應列的文本,進行比較排序。

???? ListCtrl_Sortable_ItemObject.h

???

#pragma once #include "listctrl_sortable.h"class CListCtrl_Sortable_ItemObject : public CListCtrl_Sortable { public:CListCtrl_Sortable_ItemObject(void);virtual ~CListCtrl_Sortable_ItemObject(void);virtual bool SortColumn(int columnIndex, bool ascending); };

???? ListCtrl_Sortable_ItemObject.cpp

#include "StdAfx.h" #include "ListCtrl_Sortable_ItemObject.h"CListCtrl_Sortable_ItemObject::CListCtrl_Sortable_ItemObject(void) { }CListCtrl_Sortable_ItemObject::~CListCtrl_Sortable_ItemObject(void) { }//比較函數 static int CALLBACK ItemObjectCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) {// 從參數中提取所需比較lc的兩行數據void * pRow1 = (void *) lParam1;void * pRow2 = (void *) lParam2;if(pRow1 == NULL || pRow2 == NULL)return 0;CListCtrl* lc = (CListCtrl*)lParamSort;void * pTempObject = NULL;int nItemCount = lc->GetItemCount();int nn = 0,nRow1 = -1,nRow2 = -1;for(nn=0; nn<nItemCount; nn++){pTempObject = (void *)lc->GetItemData(nn);if(pTempObject == pRow1){nRow1 = nn;}else if(pTempObject == pRow2){nRow2 = nn;}if(nRow1 != -1 && nRow2 != -1){break;}}if(nRow1 == -1 || nRow2 == -1)return 0;CString lp1 = lc->GetItemText(nRow1,CListCtrl_Sortable_ItemObject::g_columnIndex);CString lp2 = lc->GetItemText(nRow2,CListCtrl_Sortable_ItemObject::g_columnIndex);// 文字型比較if (CListCtrl_Sortable_ItemObject::g_ascending)return lp1.CompareNoCase(lp2);elsereturn lp2.CompareNoCase(lp1);return 0; }bool CListCtrl_Sortable_ItemObject::SortColumn(int columnIndex, bool ascending) {//排序g_columnIndex = columnIndex;g_ascending = ascending;SortItems(ItemObjectCompareProc, (DWORD_PTR)this);return true; }


總結

以上是生活随笔為你收集整理的MFC CListControl 点击列头排序的实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。