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 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()
};

说明:

  • Enable开头的函数设置功能开关,默认关闭状态。
  • SetOperation开头的函数设置类似回调函数的功能,默认执行空操作。
  • SetObjfor开头的函数设置类似回调函数中执行功能时可能用到的外部类变量
  • Get和Set不解释。
  • On开头的函数是重写了基类的响应函数
// 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

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 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();
		}

你可能感兴趣的:(mfc,c++,microsoft)