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 that
BOOL FuncDoNothing(LPVOID,LPVOID,CObject*);//An idle function to do nothing
class 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,仅真正插入文本为false
BOOL m_bDoAfterRenameWhenever;// The usage like above
BOOL m_bAddItem;
BOOL m_bCheckTextLen;
BOOL m_nTextLen;
CString m_strWhenSelecting; // The raw string
CString m_strAfterOp; // The new string
CObject* 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); // 添加item
void SetOperationAfterRenameItemNoRepeat(FUNCDOSOMETHING fds); // 重命名item 没有重复
void SetOperationAfterRenameItemWhenever(FUNCDOSOMETHING fds); // 重命名item
public:
void SetItemText(int nIndex, const CString& strText); // 更改item内容
BOOL OnBeforeRemoveItem(int iItem); // 移除 item 之前
void OnAfterAddItem(int nItem); // 添加 item
void OnAfterRenameItem(int nItem); // 重命名 item
void OnSelectionChanged(); // 更改选中item
protected:
DECLARE_MESSAGE_MAP()
};
说明:
// VSListBoxWLS.cpp : 实现文件
//
#include "stdafx.h"
#include "VSListBoxWLS.h"
BOOL FuncDoNothing(LPVOID,LPVOID,CObject*){return TRUE;}
// CVSListBoxWLS
IMPLEMENT_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 op
m_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 op
m_fdsAfterAddItemNoRepeat((LPVOID)&m_strWhenSelecting,(LPVOID)&m_strAfterOp,m_pObjforOperatingFunc);
return;
}
else if (m_bDoAfterAddItemWhenever==TRUE /*&& m_bAddItem==TRUE*/)
{
OutputDebugString(TEXT("重复+不重复 成功\n"));
//by wls op
m_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 op
m_fdsAfterRenameItemNoRepeat((LPVOID)&m_strWhenSelecting,(LPVOID)&m_strAfterOp,m_pObjforOperatingFunc);
return;
}
else
if (m_bDoAfterAddItemWhenever==TRUE)
{
//by wls op
m_fdsAfterRenameItemWhenever((LPVOID)&m_strWhenSelecting,(LPVOID)&m_strAfterOp,m_pObjforOperatingFunc);
}
}
BOOL CVSListBoxWLS::IsExistText(CString strText)
{
for (int i=0;i
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 Control
m_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();
}