- 下载class - 204.07 KB
- 下载demo sou
- 下载demo source code VS2005 - 19.0 KB
- 下载demo - 103.54 KB
介绍 为了改进诸如CListCtrl(报告样式)、CListBox甚至CTreeCtrl(尽管最后一个允许标签编辑)等MFC类,人们已经采取了很多方法,从允许用户“内联”编辑他们的项目的意义上讲。这些方法是非常复杂的,并且在处理尽可能多的事件时需要非常小心,以防止不必要的行为。当试图改进旧的应用程序时,用户必须用与所提供的派生类相关的新声明替换他/她的对象的声明,并且应该针对可能不需要的“特性”对应用程序进行广泛的测试。 如果一个类-一个将允许修改,项目基地,所有的CListCtrl, CListBox, CTreeCtrl,甚至CComboBox(毕竟,上节课利用CListBox)应用程序的对象不改变对象的声明和无视风格的组合,可以申请一些或所有的对象吗? 注意:在3月23日的更新之后,CComboBox控件使用的列表框的内容在进行本地输入时是可见的。
LocalInputDlg作为任何应用程序的一种“附加组件”出现,它根本不改变应用程序的行为,而是以一种统一的方式解决“本地编辑”问题。尝试这个类,您将只向应用程序添加两行代码。作为回报,在属于上述类型对象的项上单击鼠标右键,将提供本地编辑它们的可能性。 使用LocalInputDlg 以下是你必须遵循的步骤,以添加“本地编辑”功能到你心爱的应用程序: 将localinputdll .h和localinputdll .cpp文件添加到项目中。如果在应用程序中处理lvnendlabeledit通知,则取消localinputdll .h中LIWNE_USE_LVN_ENDLABELEDIT的注释。在app .h中包含localinputdll .h。使用向导将PreTranslateMessage()虚拟函数添加到app .cpp中。 将LocalInputDlg dlgInput成员添加到app类中。在生成的函数中,在TODO注释行后面写下面一行代码: 隐藏,复制Codeif (dlgInput。(pMsg, true)))返回true; 选择的样式应该是“箭头”,还是: 隐藏,复制Codeif (dlgInput。(pMsg, false))返回TRUE; 对于“内联”样式。 这是所有!编译您的项目,您就看到了! 背后的事情 在其OnInitDialog()函数中,LocalInputDlg根据所单击项目的位置定位自身,并相应地定位和调整其控件的大小。输入字段的宽度反映项目的当前宽度。窗口区域的设置使对话框获得“箭头”样式或“内联编辑”样式。 本地编辑过程首先使用消息指针调用DoLocalInput(),该消息指针由应用程序的PreTranslateMessage()函数提供,作为参数。函数的作用是:检查是否处理WM_RBUTTONDOWN消息(其他消息也可以在适当的地方使用)。对于此消息,该函数决定处理该消息的方式。hwnd句柄用于获得一个指向发布消息的窗口的指针,它被类型转换为一个CListBox*指针。让这个指针是pLB。当pLB- GetCount()返回一个正数时,函数判断它处理的是一个CListBox对象(CComboBox也是这样,因为消息来自一个临时窗口,而这个窗口实际上是一个CListBox)。否则,该函数将获得发布消息的窗口的运行时类(在之前的决策制定中,由于窗口是临时的,所以此操作无法工作)。如果运行时类是CTreeCtrl,则函数处理CTreeCtrl对象。如果运行时类是一个CListCtrl,函数将处理一个CListCtrl对象。根据所做的决策,调用适当的请求处理函数。 隐藏,复制Code
ProcessInputRequest(CListBox *pLB, CPoint point); ProcessInputRequest(CListCtrl *pLC, CPoint point); ProcessInputRequest(CTreeCtrl *pTree, CPoint point);
这些函数中的每一个都估计命中项的位置,并调用模态LocalInputDlg。 支持列表视图控件的LVN_ENDLABELEDIT通知 eFotografo提出了一个很好的观点(参见下面FAQ部分的信息)。在CListCtrl对象的情况下,相应的ProcessInputRequest()处理函数需要发送一个WM_NOTIFY消息到控件的父控件,这样LVN_ENDLABELEDIT可以被处理,如果应用程序需要决定是否接受列表视图中的修改(输入验证)。 隐藏,复制Code
NMLVDISPINFO nminfo; nminfo.hdr.code = LVN_ENDLABELEDIT; nminfo.hdr.hwndFrom = pLC->GetSafeHwnd(); nminfo.hdr.idFrom = pLC->GetDlgCtrlID(); nminfo.item.iItem = info.iItem; nminfo.item.iSubItem = info.iSubItem; nminfo.item.pszText = m_strInput.GetBuffer(0); nminfo.item.mask = LVIF_TEXT; if (pLC->GetParent()->SendMessage(WM_NOTIFY, (WPARAM)IDDLOCALEDIT, (LPARAM)(LPNMHDR)&nminfo)) { pLC->SetItemText(info.iItem, info.iSubItem, m_strInput.GetBuffer(0)); }
根据SendMessage(WM_NOTIFY)返回的值,列表单元格中的文本根据用户输入被修改或者被拒绝修改。这个值(1或0)是由LVN_ENDLABELEDIT通知的处理程序决定的: 隐藏,复制Code
void YourAppDlg::YourHandlerFor_LVN_ENDLABELEDIT (NMHDR* pNMHDR, LRESULT* pResult) { NMLVDISPINFO *pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR); CString itemtext(pDispInfo->item.pszText); // do something with it *pResult = TRUE; // accept the changes MessageBox((LPCTSTR)pDispInfo->item.pszText, (LPCTSTR)"Accepted input"); // testing only }
隐藏,复制Code
void YourAppDlg::YourHandlerFor_LVN_ENDLABELEDIT (NMHDR* pNMHDR, LRESULT* pResult) { NMLVDISPINFO *pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR); CString itemtext(pDispInfo->item.pszText); // do something with it *pResult = FALSE; // reject the changes MessageBox((LPCTSTR)pDispInfo->item.pszText, (LPCTSTR)"Accepted input"); // testing only }
如果在应用程序中没有采取验证操作,则使用LVN_ENDLABELEDIT通知机制,即在应用程序对话框的消息映射中不提供任何条目: 隐藏,复制Code
BEGIN_MESSAGE_MAP(YourAppDlg, CDialog) //{{AFX_MSG_MAP(YourAppDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() <s>ON_NOTIFY(LVN_ENDLABELEDIT, .....)</s> //}}AFX_MSG_MAP END_MESSAGE_MAP()
在ProcessInputRequest()的CListCtrl代码中,pLC- GetParent()- SendMessage(WM_NOTIFY)总是返回0,LocalInputDlg失去功能。因此,在localinputdll .h中使用了LIWNE_USE_LVN_ENDLABELEDIT预处理器变量: 隐藏,复制Code
#ifndef LIWNE_USE_LVN_ENDLABELEDIT //#define LIWNE_USE_LVN_ENDLABELEDIT #endif
假设在应用程序中没有处理LVN_ENDLABELEDIT事件,这个头文件的定义被注释掉了。请取消它的注释,如果你的应用程序处理该事件。这个预处理器变量的出现打开了ProcessInputRequest()中与输入验证相关的CListCtrl的代码。通过删除它,前面提到的代码是关闭和pLC->SetItemText(信息。iItem,信息。getbuffer(0)总是被调用来完成列表视图单元格的本地编辑。 历史 创建:2005年3月21日更新:2005年3月23日,由于jdmulder的欢迎请求和PJ Arends的优秀想法。不属于作者的代码行被标记为“出于……的好意”。更新:2005年4月5日-支持“箭头”样式和“内联”样式更新:2006年3月10日-“使用LocalInputDlg 4.b”一节中的文章内容修正。: dlginter . dolocalinput (pMsg,…)而不是dlgInput(pMsg,…)(幸运的是,源代码是ok的-))更新:2009年10月16日- VS2005源代码和LVN_ENDLABELEDIT通知支持,作为eFotografo的优秀评论 本文转载于:http://www.diyabc.com/frontweb/news289.html