=================================版权声明=================================
版权声明:本文为博主原创文章 未经许可不得转载
请通过右侧公告中的“联系邮箱(wlsandwho@foxmail.com)”联系我
未经作者授权勿用于学术性引用。
未经作者授权勿用于商业出版、商业印刷、商业引用以及其他商业用途。
本文不定期修正完善,为保证内容正确,建议移步原文处阅读。 <--------总有一天我要自己做一个模板干掉这只土豆
本文链接:http://www.cnblogs.com/wlsandwho/p/4736907.html
耻辱墙:http://www.cnblogs.com/wlsandwho/p/4206472.html
=======================================================================
我用的是VS2010,并没有打SP1包。
=======================================================================
MFC中CVSListBox看起来很好的样子,其实并不是像看起来那样。这个控件封装的很严密,在向导里并不能添加消息响应事件之类的东西。
微软MSDN上也没有什么有用的信息,只说了句类似“要文档没有,爱用用、不用Gun,想用自己看源文件”的话。
幸好略微提供了一个源码,说了怎样写派生类。
网址(https://msdn.microsoft.com/en-us/library/bb984191.aspx)中的New Controls给了一个简单的示例。
既然如此,那我就自己写一个吧。
=======================================================================
我知道并没有人想知道怎样实现的,我也没做过开源,可是,可是这次我就github了一次。
https://github.com/Simon-Wong/CVSListBoxWLS
这里只贴头文件吧。
=======================================================================
头文件:
1 #pragma once 2 // VSListBoxWLS.h : 定义文件 3 #include"afxvslistbox.h" 4 ////////////////////////////////////////////////////////////////////////// 5 // CVSListBoxWLS 6 //by wls 7 //The memory leaks is made by MFC,not me,for the little buttons in CVSListBox called CMFCToolTipCtrl or something named XXXButton. 8 //If you change the Appearance of CVSListBox to false,it will work with no memory leaks. 9 //That means HEHE. 10 11 typedef BOOL (*FUNCDOSOMETHING)(LPVOID /*lpRawData*/,LPVOID /*lpNewData*/,CObject* /*pObj*/);//by wls You know that 12 13 BOOL FuncDoNothing(LPVOID,LPVOID,CObject*);//by wls An idle function to do nothing 14 15 class CVSListBoxWLS : public CVSListBox 16 { 17 DECLARE_DYNAMIC(CVSListBoxWLS) 18 19 public: 20 CVSListBoxWLS(); 21 virtual ~CVSListBoxWLS(); 22 23 private: 24 BOOL m_bEnableRepeatText;////by wls True for enable to insert repeat text,false for disable. 25 BOOL m_bDoAfterAddItemWhenever;////by wls True for enable to do something whenever really insert text or not due to m_bEnableRepeatText,false for only really inserting text 26 BOOL m_bDoAfterRenameWhenever;////by wls The usage like above 27 BOOL m_bAddItem; 28 BOOL m_bCheckTextLen; 29 BOOL m_nTextLen; 30 31 CString m_strWhenSelecting;//by wls The raw string 32 CString m_strAfterOp;//by wls The new string 33 CObject* m_pObjforOperatingFunc; 34 35 FUNCDOSOMETHING m_fdsBeforeRemoveItem; 36 FUNCDOSOMETHING m_fdsAfterAddItemNoRepeat; 37 FUNCDOSOMETHING m_fdsAfterAddItemWhenever; 38 FUNCDOSOMETHING m_fdsAfterRenameItemNoRepeat; 39 FUNCDOSOMETHING m_fdsAfterRenameItemWhenever; 40 41 private: 42 BOOL IsExistText(CString strText); 43 void GetItemTextAfterOp(int nItem); 44 45 public: 46 CString GetTextWhenSelecting(); 47 48 void EnableRepeatText(BOOL bRepeat=FALSE);//by wls It depends the client code in where you save all the data to the very end. 49 void EnableDoAfterAddItemWhenever(BOOL bRepeat=FALSE); 50 void EnableDoAfterRenameWhenever(BOOL bRepeat=FALSE); 51 52 void EnableCheckTextLen(BOOL bChk=FALSE); 53 void SetTextLegalLength(int nLen=10); 54 55 void SetObjforOperation(CObject* obj=NULL); 56 57 void SetOperationBeforeRemoveItem(FUNCDOSOMETHING fds); 58 void SetOperationAfterAddItemNoRepeat(FUNCDOSOMETHING fds); 59 void SetOperationAfterAddItemWhenever(FUNCDOSOMETHING fds); 60 void SetOperationAfterRenameItemNoRepeat(FUNCDOSOMETHING fds); 61 void SetOperationAfterRenameItemWhenever(FUNCDOSOMETHING fds); 62 63 public: 64 void SetItemText(int nIndex, const CString& strText); 65 66 BOOL OnBeforeRemoveItem(int iItem); 67 void OnAfterAddItem(int nItem); 68 void OnAfterRenameItem(int nItem); 69 void OnSelectionChanged(); 70 71 protected: 72 DECLARE_MESSAGE_MAP() 73 };
=======================================================================
一定会有人吐槽我不写详细注释,不解释了。
=======================================================================
使用起来很简单。
Enable开头的函数设置功能开关,默认关闭状态。
SetOp开头的函数设置类似回调函数的功能,默认执行空操作。
SetObj开头的函数设置类似回调函数中执行功能时可能用到的外部类变量。
Get和Set不解释。
On开头的函数是重写了基类的响应函数。
=======================================================================
任何个人开发人员都能使用我的这个类创建自己的免费或付费应用。
请勿用于公司企业的商业用途。
=======================================================================
20170326 00:28
贴上cpp文件
1 // VSListBoxWLS.cpp : 实现文件 2 // 3 4 #include "stdafx.h" 5 #include "VSListBoxWLS.h" 6 7 BOOL FuncDoNothing(LPVOID,LPVOID,CObject*){return TRUE;} 8 // CVSListBoxWLS 9 10 IMPLEMENT_DYNAMIC(CVSListBoxWLS, CVSListBox) 11 12 CVSListBoxWLS::CVSListBoxWLS() 13 { 14 m_bEnableRepeatText=FALSE; 15 m_bDoAfterAddItemWhenever=FALSE; 16 m_bDoAfterRenameWhenever=FALSE; 17 m_bAddItem=FALSE; 18 19 m_bCheckTextLen=FALSE; 20 m_nTextLen=10; 21 22 m_fdsBeforeRemoveItem=FuncDoNothing; 23 m_fdsAfterAddItemNoRepeat=FuncDoNothing; 24 m_fdsAfterAddItemWhenever=FuncDoNothing; 25 m_fdsAfterRenameItemNoRepeat=FuncDoNothing; 26 m_fdsAfterRenameItemWhenever=FuncDoNothing; 27 28 m_strWhenSelecting=TEXT(""); 29 m_strAfterOp=TEXT(""); 30 31 m_pObjforOperatingFunc=NULL; 32 } 33 34 CVSListBoxWLS::~CVSListBoxWLS() 35 { 36 } 37 38 BEGIN_MESSAGE_MAP(CVSListBoxWLS, CVSListBox) 39 END_MESSAGE_MAP() 40 41 void CVSListBoxWLS::SetTextLegalLength(int nLen/*=10*/) 42 { 43 m_nTextLen=nLen; 44 } 45 46 void CVSListBoxWLS::EnableDoAfterRenameWhenever(BOOL bRename) 47 { 48 m_bDoAfterRenameWhenever=bRename; 49 } 50 51 void CVSListBoxWLS::EnableRepeatText(BOOL bRepeat) 52 { 53 m_bEnableRepeatText=bRepeat; 54 } 55 56 void CVSListBoxWLS::EnableDoAfterAddItemWhenever(BOOL bRepeat) 57 { 58 m_bDoAfterAddItemWhenever=bRepeat; 59 } 60 61 void CVSListBoxWLS::EnableCheckTextLen(BOOL bChk/*=FALSE*/) 62 { 63 m_bCheckTextLen=bChk; 64 } 65 66 void CVSListBoxWLS::OnSelectionChanged() 67 { 68 m_strWhenSelecting=GetItemText(GetSelItem()); 69 OutputDebugString(TEXT("[")+m_strWhenSelecting+TEXT("]\n")); 70 } 71 72 void CVSListBoxWLS::SetItemText(int nIndex, const CString& strText) 73 { 74 CString strPrompt; 75 if (m_bEnableRepeatText==FALSE && IsExistText(strText)) 76 { 77 strPrompt.Format(TEXT("【%s】已存在"),strText); 78 MessageBox(strPrompt,TEXT("提示"),MB_ICONINFORMATION|MB_OK); 79 80 m_bAddItem=FALSE; 81 82 return; 83 } 84 85 if (strText==TEXT("")) 86 { 87 strPrompt.Format(TEXT("未输入内容"),strText); 88 MessageBox(strPrompt,TEXT("提示"),MB_ICONINFORMATION|MB_OK); 89 90 m_bAddItem=FALSE; 91 } 92 93 if (m_bCheckTextLen==TRUE && strText.GetLength()>m_nTextLen) 94 { 95 strPrompt.Format(TEXT("请输入%d个以内的字符"),m_nTextLen); 96 MessageBox(strPrompt,TEXT("提示"),MB_ICONINFORMATION|MB_OK); 97 98 m_bAddItem=FALSE; 99 100 return; 101 } 102 103 m_bAddItem=TRUE; 104 105 CVSListBox::SetItemText(nIndex,strText); 106 } 107 108 BOOL CVSListBoxWLS::OnBeforeRemoveItem(int nItem) 109 { 110 GetItemTextAfterOp(nItem); 111 112 CString strPrompt; 113 strPrompt.Format(TEXT("确定删除【%s】吗?"),m_strAfterOp); 114 if (MessageBox(strPrompt,TEXT("提示"),MB_ICONQUESTION|MB_OKCANCEL)==IDOK) 115 { 116 //by wls op 117 m_fdsBeforeRemoveItem((LPVOID)&m_strWhenSelecting,(LPVOID)&m_strAfterOp,m_pObjforOperatingFunc); 118 119 return TRUE; 120 } 121 122 return FALSE; 123 } 124 125 CString CVSListBoxWLS::GetTextWhenSelecting() 126 { 127 return m_strWhenSelecting; 128 } 129 130 void CVSListBoxWLS::GetItemTextAfterOp(int nItem) 131 { 132 m_strAfterOp=GetItemText(nItem); 133 } 134 135 void CVSListBoxWLS::OnAfterAddItem(int nItem) 136 { 137 GetItemTextAfterOp(nItem); 138 139 if (m_bDoAfterAddItemWhenever==FALSE && m_bAddItem==TRUE) 140 { 141 OutputDebugString(TEXT("不重复 成功\n")); 142 //by wls op 143 m_fdsAfterAddItemNoRepeat((LPVOID)&m_strWhenSelecting,(LPVOID)&m_strAfterOp,m_pObjforOperatingFunc); 144 145 return; 146 } 147 else 148 if (m_bDoAfterAddItemWhenever==TRUE /*&& m_bAddItem==TRUE*/) 149 { 150 OutputDebugString(TEXT("重复+不重复 成功\n")); 151 //by wls op 152 m_fdsAfterAddItemWhenever((LPVOID)&m_strWhenSelecting,(LPVOID)&m_strAfterOp,m_pObjforOperatingFunc); 153 } 154 155 if (m_strAfterOp==TEXT("")) 156 { 157 RemoveItem(nItem);//by wls Remove the item with no text 158 } 159 } 160 161 void CVSListBoxWLS::OnAfterRenameItem(int nItem) 162 { 163 GetItemTextAfterOp(nItem); 164 165 if (m_bDoAfterRenameWhenever==FALSE && m_bAddItem==TRUE) 166 { 167 OutputDebugString(TEXT("重命 不重复 值\n")); 168 //by wls op 169 m_fdsAfterRenameItemNoRepeat((LPVOID)&m_strWhenSelecting,(LPVOID)&m_strAfterOp,m_pObjforOperatingFunc); 170 171 return; 172 } 173 else 174 if (m_bDoAfterAddItemWhenever==TRUE) 175 { 176 //by wls op 177 m_fdsAfterRenameItemWhenever((LPVOID)&m_strWhenSelecting,(LPVOID)&m_strAfterOp,m_pObjforOperatingFunc); 178 } 179 } 180 181 BOOL CVSListBoxWLS::IsExistText(CString strText) 182 { 183 for (int i=0;i<GetCount();i++) 184 { 185 if (strText==GetItemText(i)) 186 { 187 return TRUE; 188 } 189 } 190 191 return FALSE; 192 } 193 194 void CVSListBoxWLS::SetObjforOperation(CObject* obj) 195 { 196 m_pObjforOperatingFunc=obj; 197 } 198 199 void CVSListBoxWLS::SetOperationBeforeRemoveItem(FUNCDOSOMETHING fds) 200 { 201 m_fdsBeforeRemoveItem=fds; 202 } 203 void CVSListBoxWLS::SetOperationAfterAddItemNoRepeat(FUNCDOSOMETHING fds) 204 { 205 m_fdsAfterAddItemNoRepeat=fds; 206 } 207 void CVSListBoxWLS::SetOperationAfterAddItemWhenever(FUNCDOSOMETHING fds) 208 { 209 m_fdsAfterAddItemWhenever=fds; 210 } 211 void CVSListBoxWLS::SetOperationAfterRenameItemNoRepeat(FUNCDOSOMETHING fds) 212 { 213 m_fdsAfterRenameItemNoRepeat=fds; 214 } 215 void CVSListBoxWLS::SetOperationAfterRenameItemWhenever(FUNCDOSOMETHING fds) 216 { 217 m_fdsAfterRenameItemWhenever=fds; 218 }