MFC - Controls - VSLISTBOX

VSListBox control

VSListBox is different from other list controls. Their classes have been separated from CStatic, and vslistbox is relatively closed, without providing any message time and commands. The only way we use this control is to subclass the CVSListBox class, by overloading it The way of virtual function to realize our function. Although vslistbox is very closed, we can still get a glimpse of it from the Microsoft MSDN documentation and realize some not very complicated functions.

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

The CVSListBox in MFC looks good, but it's not what it looks like. This control is tightly encapsulated, and things like message response events cannot be added in the wizard.
There is no useful information on Microsoft MSDN. Fortunately, a source code is slightly provided, which tells how to write derived classes.

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

illustrate:

  • The function at the beginning of Enable sets the function switch, which is disabled by default.
  • The function at the beginning of SetOperation sets a function similar to a callback function, and performs a null operation by default.
  • The functions beginning with SetObjfor set external class variables that may be used when performing functions similar to callback functions .
  • Get and Set are not interpreted.
  • The function starting with On is to override the response function of the base class .
// 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<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 traverses the file directory, ShellList Control browses the file directory related operations

VSListBox, ShellList controls


/*!
* 获取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 reads TXT files

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

Guess you like

Origin blog.csdn.net/wu_zhiyuan/article/details/130158512