> 文章列表 > MFC - 控件 - VSLISTBOX

MFC - 控件 - VSLISTBOX

MFC - 控件 - VSLISTBOX

VSListBox 控件

VSListBox与其它list控件不同,它们的类从CStatic的继承时已经分开了,并且vslistbox比较封闭,没有提供任何消息时间和命令,我们使用该控件的唯一方法子类化CVSListBox类,通过重载其中虚函数的方式来实现我们的功能。虽然vslistbox非常封闭,但是我们依然可以从微软MSDN的文档中窥见一隅,实现一些并不十分复杂的功能。

VSLISTBOX的继承:CStatic  —-  CVSListBoxBase  —-  CVSListBox  —-  CVSLIST(我们自己从CVSListBox中继承的类)

MFC中CVSListBox看起来很好的样子,其实并不是像看起来那样。这个控件封装的很严密,在向导里并不能添加消息响应事件之类的东西。
微软MSDN上也没有什么有用的信息,幸好略微提供了一个源码,说了怎样写派生类。

#pragma once
// VSListBoxWLS.h : 定义文件
#include"afxvslistbox.h"
//
// CVSListBoxWLS
//by wls 作者
//The memory leaks is made by  MFC,not me,for the little buttons in CVSListBox called CMFCToolTipCtrl or something named XXXButton.
//内存泄漏是由MFC,而不是我,为CVSListBox中称为CMFCToolTipCtrl或命名为XXXButton的小按钮。
//If you change the Appearance of CVSListBox to false,it will work with no memory leaks.
// 如果您将CVSListBox的Appearance更改为false,它将在没有内存泄漏的情况下工作。// 注:wls是作者写的// 函数指针
typedef BOOL (*FUNCDOSOMETHING)(LPVOID /*lpRawData*/,LPVOID /*lpNewData*/,CObject* /*pObj*/); //You know thatBOOL FuncDoNothing(LPVOID,LPVOID,CObject*);//An idle function to do nothingclass CVSListBoxWLS : public CVSListBox
{DECLARE_DYNAMIC(CVSListBoxWLS)public:CVSListBoxWLS();virtual ~CVSListBoxWLS();private:BOOL m_bEnableRepeatText;	// True for enable to insert repeat text,false for disable.启用插入重复文本为True,禁用为false。BOOL m_bDoAfterAddItemWhenever;// True for enable to do something whenever really insert text or not due to m_bEnableRepeatText, false for only really inserting text// 由于m_bEnableRepeatText,当真正插入文本或不插入文本时启用为True,仅真正插入文本为falseBOOL m_bDoAfterRenameWhenever;// The usage like aboveBOOL m_bAddItem;BOOL m_bCheckTextLen;BOOL m_nTextLen;CString m_strWhenSelecting;		// The raw stringCString m_strAfterOp;			// The new stringCObject* m_pObjforOperatingFunc;FUNCDOSOMETHING m_fdsBeforeRemoveItem;FUNCDOSOMETHING m_fdsAfterAddItemNoRepeat;FUNCDOSOMETHING m_fdsAfterAddItemWhenever;FUNCDOSOMETHING m_fdsAfterRenameItemNoRepeat;FUNCDOSOMETHING m_fdsAfterRenameItemWhenever;private:BOOL IsExistText(CString strText);void GetItemTextAfterOp(int nItem);public:CString GetTextWhenSelecting();void EnableRepeatText(BOOL bRepeat=FALSE);// It depends the client code in where you save all the data to the very end.// 这取决于你把所有数据保存到最后的客户端代码。void EnableDoAfterAddItemWhenever(BOOL bRepeat=FALSE);		// 添加新item之后,作用呢?void EnableDoAfterRenameWhenever(BOOL bRepeat=FALSE);		// 改名之前??void EnableCheckTextLen(BOOL bChk=FALSE);		// 检查文本长度void SetTextLegalLength(int nLen=10);			// 设置合法长度void SetObjforOperation(CObject* obj=NULL);		// 设置对象操作属性void SetOperationBeforeRemoveItem(FUNCDOSOMETHING fds);				// 移除操作之前 操作void SetOperationAfterAddItemNoRepeat(FUNCDOSOMETHING fds);			// 添加item 没有重复void SetOperationAfterAddItemWhenever(FUNCDOSOMETHING fds);			// 添加itemvoid SetOperationAfterRenameItemNoRepeat(FUNCDOSOMETHING fds);		// 重命名item 没有重复void SetOperationAfterRenameItemWhenever(FUNCDOSOMETHING fds);		// 重命名itempublic:void SetItemText(int nIndex, const CString& strText);				// 更改item内容BOOL OnBeforeRemoveItem(int iItem);									// 移除 item 之前void OnAfterAddItem(int nItem);										// 添加 itemvoid OnAfterRenameItem(int nItem);									// 重命名 itemvoid OnSelectionChanged();											// 更改选中itemprotected:DECLARE_MESSAGE_MAP()
};

说明:

  • Enable开头的函数设置功能开关,默认关闭状态。
  • SetOperation开头的函数设置类似回调函数的功能,默认执行空操作。
  • SetObjfor开头的函数设置类似回调函数中执行功能时可能用到的外部类变量
  • Get和Set不解释。
  • On开头的函数是重写了基类的响应函数
// VSListBoxWLS.cpp : 实现文件
//#include "stdafx.h"
#include "VSListBoxWLS.h"BOOL FuncDoNothing(LPVOID,LPVOID,CObject*){return TRUE;}
// CVSListBoxWLSIMPLEMENT_DYNAMIC(CVSListBoxWLS, CVSListBox)CVSListBoxWLS::CVSListBoxWLS()
{m_bEnableRepeatText=FALSE;m_bDoAfterAddItemWhenever=FALSE;m_bDoAfterRenameWhenever=FALSE;m_bAddItem=FALSE;m_bCheckTextLen=FALSE;m_nTextLen=10;m_fdsBeforeRemoveItem=FuncDoNothing;m_fdsAfterAddItemNoRepeat=FuncDoNothing;m_fdsAfterAddItemWhenever=FuncDoNothing;m_fdsAfterRenameItemNoRepeat=FuncDoNothing;m_fdsAfterRenameItemWhenever=FuncDoNothing;m_strWhenSelecting=TEXT("");m_strAfterOp=TEXT("");m_pObjforOperatingFunc=NULL;
}CVSListBoxWLS::~CVSListBoxWLS()
{
}BEGIN_MESSAGE_MAP(CVSListBoxWLS, CVSListBox)
END_MESSAGE_MAP()void CVSListBoxWLS::SetTextLegalLength(int nLen/*=10*/)
{m_nTextLen=nLen;
}void CVSListBoxWLS::EnableDoAfterRenameWhenever(BOOL bRename)
{m_bDoAfterRenameWhenever=bRename;
}void CVSListBoxWLS::EnableRepeatText(BOOL bRepeat)
{m_bEnableRepeatText=bRepeat;
}void CVSListBoxWLS::EnableDoAfterAddItemWhenever(BOOL bRepeat)
{m_bDoAfterAddItemWhenever=bRepeat;
}void CVSListBoxWLS::EnableCheckTextLen(BOOL bChk/*=FALSE*/)
{m_bCheckTextLen=bChk;
}void CVSListBoxWLS::OnSelectionChanged()
{m_strWhenSelecting=GetItemText(GetSelItem());OutputDebugString(TEXT("[")+m_strWhenSelecting+TEXT("]\\n"));
}void CVSListBoxWLS::SetItemText(int nIndex, const CString& strText)
{CString strPrompt;if (m_bEnableRepeatText==FALSE && IsExistText(strText)){strPrompt.Format(TEXT("【%s】已存在"),strText);MessageBox(strPrompt,TEXT("提示"),MB_ICONINFORMATION|MB_OK);m_bAddItem=FALSE;return;}if (strText==TEXT("")){strPrompt.Format(TEXT("未输入内容"),strText);MessageBox(strPrompt,TEXT("提示"),MB_ICONINFORMATION|MB_OK);m_bAddItem=FALSE;}if (m_bCheckTextLen==TRUE && strText.GetLength()>m_nTextLen){strPrompt.Format(TEXT("请输入%d个以内的字符"),m_nTextLen);MessageBox(strPrompt,TEXT("提示"),MB_ICONINFORMATION|MB_OK);m_bAddItem=FALSE;return;}m_bAddItem=TRUE;CVSListBox::SetItemText(nIndex,strText);
}BOOL CVSListBoxWLS::OnBeforeRemoveItem(int nItem)
{GetItemTextAfterOp(nItem);CString strPrompt;strPrompt.Format(TEXT("确定删除【%s】吗?"),m_strAfterOp);if (MessageBox(strPrompt,TEXT("提示"),MB_ICONQUESTION|MB_OKCANCEL)==IDOK){//by wls opm_fdsBeforeRemoveItem((LPVOID)&m_strWhenSelecting,(LPVOID)&m_strAfterOp,m_pObjforOperatingFunc);return TRUE;}return FALSE;
}CString CVSListBoxWLS::GetTextWhenSelecting()
{return m_strWhenSelecting;
}void CVSListBoxWLS::GetItemTextAfterOp(int nItem)
{m_strAfterOp=GetItemText(nItem);
}void CVSListBoxWLS::OnAfterAddItem(int nItem)
{GetItemTextAfterOp(nItem);if (m_bDoAfterAddItemWhenever==FALSE && m_bAddItem==TRUE){OutputDebugString(TEXT("不重复 成功\\n"));//by wls opm_fdsAfterAddItemNoRepeat((LPVOID)&m_strWhenSelecting,(LPVOID)&m_strAfterOp,m_pObjforOperatingFunc);return;}else if (m_bDoAfterAddItemWhenever==TRUE /*&& m_bAddItem==TRUE*/){OutputDebugString(TEXT("重复+不重复 成功\\n"));//by wls opm_fdsAfterAddItemWhenever((LPVOID)&m_strWhenSelecting,(LPVOID)&m_strAfterOp,m_pObjforOperatingFunc);}if (m_strAfterOp==TEXT("")){RemoveItem(nItem);//by wls Remove the item with no text}
}void CVSListBoxWLS::OnAfterRenameItem(int nItem)
{GetItemTextAfterOp(nItem);if (m_bDoAfterRenameWhenever==FALSE && m_bAddItem==TRUE){OutputDebugString(TEXT("重命 不重复 值\\n"));//by wls opm_fdsAfterRenameItemNoRepeat((LPVOID)&m_strWhenSelecting,(LPVOID)&m_strAfterOp,m_pObjforOperatingFunc);return;}elseif (m_bDoAfterAddItemWhenever==TRUE){//by wls opm_fdsAfterRenameItemWhenever((LPVOID)&m_strWhenSelecting,(LPVOID)&m_strAfterOp,m_pObjforOperatingFunc);}
}BOOL CVSListBoxWLS::IsExistText(CString strText)
{for (int i=0;i<GetCount();i++){if (strText==GetItemText(i)){return TRUE;}}return FALSE;
}void CVSListBoxWLS::SetObjforOperation(CObject* obj)
{m_pObjforOperatingFunc=obj;
}void CVSListBoxWLS::SetOperationBeforeRemoveItem(FUNCDOSOMETHING fds)
{m_fdsBeforeRemoveItem=fds;
}
void CVSListBoxWLS::SetOperationAfterAddItemNoRepeat(FUNCDOSOMETHING fds)
{m_fdsAfterAddItemNoRepeat=fds;
}
void CVSListBoxWLS::SetOperationAfterAddItemWhenever(FUNCDOSOMETHING fds)
{m_fdsAfterAddItemWhenever=fds;
}
void CVSListBoxWLS::SetOperationAfterRenameItemNoRepeat(FUNCDOSOMETHING fds)
{m_fdsAfterRenameItemNoRepeat=fds;
}
void CVSListBoxWLS::SetOperationAfterRenameItemWhenever(FUNCDOSOMETHING fds)
{m_fdsAfterRenameItemWhenever=fds;
}

MFC VSListBox遍历文件目录、ShellList Control浏览文件目录相关操作

VSListBox、ShellList控件


/*!
* 获取exe所在目录
*/
CString CFilesSelecterDlg::getExePath()
{CString path;GetModuleFileName(NULL, path.GetBufferSetLength(MAX_PATH + 1), MAX_PATH);//!<得到exe的完整路径path.ReleaseBuffer();int pos = path.ReverseFind('\\\\');path = path.Left(pos);//!< exe所在路径return path;//MessageBox(path);
}void CFilesSelecterDlg::OnBnClickedButton1()
{CString exePath = getExePath();//!< 应用程序目录int pos = exePath.ReverseFind('\\\\');teachFilePath = exePath.Left(pos);teachFilePath += "\\\\project";//!< txt文件所在路径// MFC ShellList Controlm_shelllistL.DisplayFolder(teachFilePath);//!< 可选项列表显示// MFC VSListBox//CString filename = _T("");//CString fullname = _T("");//CFileFind find;//BOOL IsFind = find.FindFile(teachFilePath + _T("/*.txt"));//while (IsFind)//遍历txt所在文件夹//{//	IsFind = find.FindNextFile();//	if (find.IsDots())//	{//		continue;//	}//	else//	{//		filename = find.GetFileName();//		fullname = teachFilePath + filename;//		m_selections.AddItem(filename);//!< 添加到文件列表//	}//}
}void CFilesSelecterDlg::OnBnClickedButton2()
{int index = m_shelllistL.GetNextItem(-1, LVIS_SELECTED);//获取当前选中项的索引CString selPath;m_shelllistL.GetItemPath(selPath, index);if (0 == m_selected.GetCount()){m_selected.AddItem(selPath);return;}for (int index = 0; index < m_selected.GetCount(); index++){CString temp = m_selected.GetItemText(index);if (0 == temp.Compare(selPath))//!< 如果有重复项直接返回{return;}}m_selected.AddItem(selPath);//!< 到此说明没有重复项,添加
}

CStdioFile读取TXT文件

CString allCodes = "";for (int index = 0; index < teachFiles.size(); index++){CStdioFile stdFile(teachFiles.at(index), CFile::typeBinary | CFile::modeRead);CString temp = "";while (true){if (stdFile.ReadString(temp))//!< 按行读取,读取完成返回flase{allCodes += temp;allCodes += "\\n";temp = "";continue;}break;}stdFile.Close();}