谁有可以隐藏列的ListCtrl,就像Window7任务管理器那样的? 1 设置 那列 宽度=0;2. http://blog.csdn.net/schlafenhamster/article/details/7461186锁定 列宽 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 mfcGridContrl 或者使用bcg提供的Grid的 CListCtrl Which Can Show and Hide Columnshttp://www.codeproject.com/Articles/28787/CListCtrl-Which-Can-Show-and-Hide-Columns 1、CListCtrl::SetColumnWidth(int nCol, int nWidth)2、自己去处理单击表头消息事件#pragma once#include "afxcmn.h"enum DATA_TYPE{INT_TYPE = 0, STRING_TYPE };class CMySortListCtrl :public CListCtrl{public: CMySortListCtrl(void); virtual ~CMySortListCtrl(void); static int CALLBACK ListCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);public: //是否为升序 bool m_bAscending; //当前排列的序 int m_nSortCol; int m_lnum; DECLARE_MESSAGE_MAP()public: afx_msg void OnLvnColumnclick(NMHDR *pNMHDR, LRESULT *pResult);};#include "MySortListCtrl.h"CMySortListCtrl::CMySortListCtrl(void):m_bAscending(FALSE),m_nSortCol(0),m_lnum(0){}CMySortListCtrl::~CMySortListCtrl(void){}BEGIN_MESSAGE_MAP(CMySortListCtrl, CListCtrl) ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, &CMySortListCtrl::OnLvnColumnclick)END_MESSAGE_MAP()int CALLBACK CMySortListCtrl::ListCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort){ CMySortListCtrl *pSortList= (CMySortListCtrl*)lParamSort; ++pSortList->m_lnum; long lItem1,lItem2=0; LVFINDINFO findInfo;//查找时所需要的信息结构体 findInfo.flags = LVFI_PARAM; //搜索类型 findInfo.lParam = lParam1; lItem1 = pSortList->FindItem(&findInfo); findInfo.lParam = lParam2; lItem2 = pSortList->FindItem(&findInfo); if(-1 == lItem1 || -1 ==lItem2) { return 0; } CString strItem1(_T("")); CString strItem2(_T("")); strItem1 = pSortList->GetItemText(lItem1,pSortList->m_nSortCol); strItem2 = pSortList->GetItemText(lItem2,pSortList->m_nSortCol); HDITEM headerItem; headerItem.mask = HDI_LPARAM; //与列相关联的lParam索引 CHeaderCtrl *pHeaderCtrl = pSortList->GetHeaderCtrl(); pHeaderCtrl->GetItem(pSortList->m_nSortCol,&headerItem); UINT dataType = (UINT)(headerItem.lParam); int nFlag = 0; switch(dataType) { case 1: case 3: { long lDataItem1,lDataItem2 = 0; lDataItem1 = _wtol(strItem1); lDataItem2 = _wtol(strItem2); if(lDataItem1>lDataItem2) { nFlag = 1; } else if(lDataItem1<lDataItem2) { nFlag = -1; } else { nFlag = 0; } } break; case 2: { //strItem1.MakeLower(); //strItem2.MakeLower(); nFlag = strItem1.CompareNoCase(strItem2); } } if(pSortList->m_bAscending) { return nFlag; } else { return nFlag*(-1); } return 0;}void CMySortListCtrl::OnLvnColumnclick(NMHDR *pNMHDR, LRESULT *pResult){ LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR); if(pNMLV->iSubItem == m_nSortCol) { m_bAscending = !m_bAscending; } else { m_bAscending = TRUE; m_nSortCol = pNMLV->iSubItem; } SortItems(ListCompare, (DWORD)this); //该函数返回-1代表第一项排应在第二项前面,返回代表第一项排应在第二项后面,返回代表两项相等 int x = this->m_lnum; UpdateData(FALSE); *pResult = 0;} Thanks oyljerry..我查看了这个代码,很好。它将需要隐藏的列都移到第0列,并设定宽度为0,并且禁止拖动。但是还有一个瑕疵,就是当鼠标移到第0列的时候,仍然会出现可拖动到光标。和Windows7任务管理器相比还有一定的差距。 MFC基本控件,貌似没LISTVIEW吧。。 case WM_SETCURSOR: return 0;检查列号 是0 再 return 0;否则 break 昨天我就已经试过了,结果还可以。不过还是有瑕疵的,因为WM_SERCURSOR是系统定期发送的,并不是每一次Move到item==0的时候才发送的。所以当我鼠标快速的在(Item==0)上移动的时候,偶尔还是会出现那种可拖拉的Cursor的。虽然如此,不过还能接受。 我的代码是:WNDPROC OldHeadProc;LRESULT CALLBACK NewHeadProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ HDHITTESTINFO hti; switch(uMsg) { case WM_SETCURSOR: { // do hit test hti.pt.x = LOWORD(lParam); hti.pt.y = HIWORD(lParam); ::GetCursorPos(&hti.pt); ::ScreenToClient(hWnd, &hti.pt); SendMessage(hWnd, HDM_HITTEST, 0, (LPARAM) &hti); if( hti.iItem == 1 ) { return 0; } if( hti.flags | HHT_ONDIVOPEN ) { int a=2; int b=a; } } break;}...............} “WM_SERCURSOR是系统定期发送的”否!是 窗口 HitTes t的 结果 Thank you very much!! I got it.我对你的回复验证了一下,果然是NcHitTest的时候系统还发送了WM_SETCURSOR和WM_MOUSEMOVE消息的。但是瑕疵(偶尔会闪一下分割图标)依然存在。下面是我的代码:BOOL COMHeaderCtrl::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message){ // TODO: Add your message handler code here and/or call default TRACE(_T("OnSetCursor\n")); if( !m_bDefaultCursor ) { return TRUE; } return CHeaderCtrl::OnSetCursor(pWnd, nHitTest, message);}LRESULT COMHeaderCtrl::OnNcHitTest(CPoint point){ // TODO: Add your message handler code here and/or call default TRACE(_T("OnNcHitTest\n")); CPoint pt(point); ScreenToClient(&pt); HDHITTESTINFO hti; hti.flags = HHT_ONDIVIDER | HHT_ONDIVOPEN ; hti.pt = pt; ::SendMessage(GetSafeHwnd(), HDM_HITTEST, 0, (LPARAM) &hti); m_bDefaultCursor = TRUE; if( hti.iItem != -1 ) { POM_HEADER_CTRL_ITEM_STATE pState = &(m_arrItemStates[hti.iItem]); if( !pState->bVisible ) { m_bDefaultCursor = FALSE; pState->iItemState = 2; } } return CHeaderCtrl::OnNcHitTest(point);} 你已经 作完了, 不要 return CHeaderCtrl::OnNcHitTest(point);return 一个 合适的值 LRESULT COMHeaderCtrl::OnNcHitTest(CPoint point){ // TODO: Add your message handler code here and/or call default TRACE(_T("OnNcHitTest\n")); CPoint pt(point); ScreenToClient(&pt); HDHITTESTINFO hti; hti.flags = HHT_ONDIVIDER | HHT_ONDIVOPEN ; hti.pt = pt; ::SendMessage(GetSafeHwnd(), HDM_HITTEST, 0, (LPARAM) &hti); m_bDefaultCursor = TRUE; if( hti.iItem != -1 ) { POM_HEADER_CTRL_ITEM_STATE pState = &(m_arrItemStates[hti.iItem]); if( !pState->bVisible ) { m_bDefaultCursor = FALSE; pState->iItemState = 2;// 法一:return TRUE;// 法二:return FALSE;// 法三:// do nothing } } return CHeaderCtrl::OnNcHitTest(point);}在你的建议下,我试了上述的三种方法。法1和法3差不多,我在隐藏的第0列左右快速移动,偶尔(40%)的概率会出现 分割图标。法2,就只有5%的概率出现分割图标。效果提升不少,只要用户不是有意为之,基本上不会出现分割图标了。Thank you............ 疑惑:COMMAND消息传递过程中,VIEW DOCUMENT等有机会检查自己的MESSAGE MAP吗? Clist 使用问题 求MFC窗口详细的创建和结束过程? VC中怎么实现喷枪及任意形状的栽剪 一个简单的CEDIT问题 多文档视图中子视图如何在开始显示时就最大化? 人脸识别的高手们,可否给我点你们的资料,源程序最好 如何得到一个线程类自己的HWND 用Xtreme Toolkit类库作Outlook风格界面,如果消息映射左边竖排的按钮啊 请问各位GG,JJ,DD,MM学C语言有没有前途,能做什么方面的东西??? 依然是滚动条问题 简单的焦点问题???
http://www.codeproject.com/Articles/28787/CListCtrl-Which-Can-Show-and-Hide-Columns
2、自己去处理单击表头消息事件#pragma once
#include "afxcmn.h"enum DATA_TYPE{INT_TYPE = 0, STRING_TYPE };class CMySortListCtrl :public CListCtrl
{
public:
CMySortListCtrl(void);
virtual ~CMySortListCtrl(void);
static int CALLBACK ListCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
public:
//是否为升序
bool m_bAscending;
//当前排列的序
int m_nSortCol;
int m_lnum; DECLARE_MESSAGE_MAP()public:
afx_msg void OnLvnColumnclick(NMHDR *pNMHDR, LRESULT *pResult);
};#include "MySortListCtrl.h"CMySortListCtrl::CMySortListCtrl(void):m_bAscending(FALSE),m_nSortCol(0),m_lnum(0)
{
}CMySortListCtrl::~CMySortListCtrl(void)
{
}
BEGIN_MESSAGE_MAP(CMySortListCtrl, CListCtrl)
ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, &CMySortListCtrl::OnLvnColumnclick)
END_MESSAGE_MAP()
int CALLBACK CMySortListCtrl::ListCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
CMySortListCtrl *pSortList= (CMySortListCtrl*)lParamSort;
++pSortList->m_lnum;
long lItem1,lItem2=0; LVFINDINFO findInfo;//查找时所需要的信息结构体
findInfo.flags = LVFI_PARAM; //搜索类型
findInfo.lParam = lParam1;
lItem1 = pSortList->FindItem(&findInfo); findInfo.lParam = lParam2;
lItem2 = pSortList->FindItem(&findInfo); if(-1 == lItem1 || -1 ==lItem2)
{
return 0;
} CString strItem1(_T(""));
CString strItem2(_T(""));
strItem1 = pSortList->GetItemText(lItem1,pSortList->m_nSortCol);
strItem2 = pSortList->GetItemText(lItem2,pSortList->m_nSortCol);
HDITEM headerItem;
headerItem.mask = HDI_LPARAM; //与列相关联的lParam索引
CHeaderCtrl *pHeaderCtrl = pSortList->GetHeaderCtrl();
pHeaderCtrl->GetItem(pSortList->m_nSortCol,&headerItem); UINT dataType = (UINT)(headerItem.lParam); int nFlag = 0;
switch(dataType)
{
case 1:
case 3:
{
long lDataItem1,lDataItem2 = 0;
lDataItem1 = _wtol(strItem1);
lDataItem2 = _wtol(strItem2);
if(lDataItem1>lDataItem2)
{
nFlag = 1;
}
else if(lDataItem1<lDataItem2)
{
nFlag = -1;
}
else
{
nFlag = 0;
}
}
break; case 2:
{
//strItem1.MakeLower();
//strItem2.MakeLower();
nFlag = strItem1.CompareNoCase(strItem2);
}
}
if(pSortList->m_bAscending)
{
return nFlag;
}
else
{
return nFlag*(-1);
}
return 0;
}
void CMySortListCtrl::OnLvnColumnclick(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
if(pNMLV->iSubItem == m_nSortCol)
{
m_bAscending = !m_bAscending;
}
else
{
m_bAscending = TRUE;
m_nSortCol = pNMLV->iSubItem;
} SortItems(ListCompare, (DWORD)this); //该函数返回-1代表第一项排应在第二项前面,返回代表第一项排应在第二项后面,返回代表两项相等
int x = this->m_lnum;
UpdateData(FALSE); *pResult = 0;
}
它将需要隐藏的列都移到第0列,并设定宽度为0,并且禁止拖动。但是还有一个瑕疵,就是当鼠标移到第0列的时候,仍然会出现可拖动到光标。和Windows7任务管理器相比还有一定的差距。
return 0;检查列号 是0 再 return 0;
否则 break
虽然如此,不过还能接受。
我的代码是:
WNDPROC OldHeadProc;
LRESULT CALLBACK NewHeadProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDHITTESTINFO hti;
switch(uMsg)
{
case WM_SETCURSOR:
{
// do hit test
hti.pt.x = LOWORD(lParam);
hti.pt.y = HIWORD(lParam);
::GetCursorPos(&hti.pt);
::ScreenToClient(hWnd, &hti.pt);
SendMessage(hWnd, HDM_HITTEST, 0, (LPARAM) &hti);
if( hti.iItem == 1 ) {
return 0;
}
if( hti.flags | HHT_ONDIVOPEN ) {
int a=2;
int b=a;
}
}
break;
}...............
}
我对你的回复验证了一下,果然是NcHitTest的时候系统还发送了WM_SETCURSOR和WM_MOUSEMOVE消息的。但是瑕疵(偶尔会闪一下分割图标)依然存在。下面是我的代码:BOOL COMHeaderCtrl::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
// TODO: Add your message handler code here and/or call default
TRACE(_T("OnSetCursor\n"));
if( !m_bDefaultCursor ) {
return TRUE;
}
return CHeaderCtrl::OnSetCursor(pWnd, nHitTest, message);
}LRESULT COMHeaderCtrl::OnNcHitTest(CPoint point)
{
// TODO: Add your message handler code here and/or call default
TRACE(_T("OnNcHitTest\n"));
CPoint pt(point);
ScreenToClient(&pt);
HDHITTESTINFO hti;
hti.flags = HHT_ONDIVIDER | HHT_ONDIVOPEN ;
hti.pt = pt;
::SendMessage(GetSafeHwnd(), HDM_HITTEST, 0, (LPARAM) &hti);
m_bDefaultCursor = TRUE;
if( hti.iItem != -1 ) {
POM_HEADER_CTRL_ITEM_STATE pState = &(m_arrItemStates[hti.iItem]);
if( !pState->bVisible ) {
m_bDefaultCursor = FALSE; pState->iItemState = 2;
}
}
return CHeaderCtrl::OnNcHitTest(point);
}
return 一个 合适的值
{
// TODO: Add your message handler code here and/or call default
TRACE(_T("OnNcHitTest\n"));
CPoint pt(point);
ScreenToClient(&pt);
HDHITTESTINFO hti;
hti.flags = HHT_ONDIVIDER | HHT_ONDIVOPEN ;
hti.pt = pt;
::SendMessage(GetSafeHwnd(), HDM_HITTEST, 0, (LPARAM) &hti);
m_bDefaultCursor = TRUE;
if( hti.iItem != -1 ) {
POM_HEADER_CTRL_ITEM_STATE pState = &(m_arrItemStates[hti.iItem]);
if( !pState->bVisible ) {
m_bDefaultCursor = FALSE;
pState->iItemState = 2;
// 法一:return TRUE;
// 法二:return FALSE;
// 法三:// do nothing
}
}
return CHeaderCtrl::OnNcHitTest(point);
}在你的建议下,
我试了上述的三种方法。
法1和法3差不多,我在隐藏的第0列左右快速移动,偶尔(40%)的概率会出现 分割图标。
法2,就只有5%的概率出现分割图标。效果提升不少,只要用户不是有意为之,基本上不会出现分割图标了。Thank you............