根据 stackoverflow How to get text from CEdit 控件,CEdit 不是 Microsoft 标准 ATL 的一部分,而是Windows 模板库 (WTL) 扩展。
似乎listview
和treeview
通用控件确实具有 Microsoft 的 ATL 支持。
从您提到的错误中,听起来您正在将 MFC 组件与解决方案中的 MFC 相关属性一起拉入您的构建中。您需要检查您是否仅在构建中使用 ATL 包含以及属性和库。检查您的标准包含文件stdafx.h
是否使用 ATL 包含。
这是一些需要考虑的源代码。这是来自我一直在使用 ATL 执行的示例应用程序,它显示了一个简单的对话框,其中包含一个列表视图控件,其中两列显示来自 Windows 注册表中一个键的数据。该对话框允许用户双击listview
控件的特定行,然后获取与字符串值键关联的值并允许编辑字符串值值。
我正在使用wchar_t
并std::wstring
保存我的文本数据,因为 Windows API 都是宽字符。
.rc 文件包含以下对话框模板。我使用 Visual Studio 资源视图中可用的标准对话框设计工具将控件拖放到对话框上并修改它们的属性。我还使用对话框设计工具为按钮单击和其他事件添加事件处理程序。该工具会将事件处理框架添加到源文件并更新消息映射。
IDD_PROVDIALOG DIALOGEX 0, 0, 224, 209
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Provision control"
FONT 8, "MS Sans Serif", 0, 0, 0x0
BEGIN
DEFPUSHBUTTON "OK",IDOK,167,7,50,16
PUSHBUTTON "Cancel",IDCANCEL,167,26,50,16
CONTROL "",IDC_LIST1,"SysListView32",LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,7,154,155
EDITTEXT IDC_EDIT_PROP,7,179,154,23,ES_MULTILINE | ES_AUTOHSCROLL
PUSHBUTTON "Save",IDC_BUTTON_SAVE,179,180,38,22
END
listview
填写对话框并将对话框呈现给用户。然后我有以下两个事件处理程序。第一个事件处理程序用于单击“保存”按钮时。第二个事件处理程序用于当用户双击listview
控件的一行(实际上是第一列)时。
数据存储在 ATL 简单地图中,创建对话框时,我们提供指向地图的指针。所以对话框有一个指向注册表数据的指针CSimpleMap <std::wstring, std::wstring> *m_RegistryData;
这是保存按钮单击事件处理程序,它从编辑控件中提取文本并更新数据映射。一旦数据映射被更新,我们就会告诉它listview
自己更新。
LRESULT CProvDialog::OnBnClickedButtonSave(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL & bHandled)
{
CWindow pEdit = GetDlgItem (IDC_EDIT_PROP);
int iTextSize = pEdit.GetWindowTextLength ();
if (iTextSize > 0 && m_EditKey.length () > 0) {
wchar_t myText[128];
pEdit.GetWindowText(myText, 127);
m_RegistryData->SetAt (m_EditKey, myText);
m_EditKey.clear(); // clear the key area since we have done an update
pEdit.SetWindowText (L""); // clear the edit box before returning for user feedback.
CWindow pListView = GetDlgItem(IDC_LIST1); // Get the listview control window handle
pListView.RedrawWindow(NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
}
bHandled = TRUE;
return 1;
}
在这里要完整的是控件中双击的处理程序listview
。这会进行基本的完整性检查以确保双击有效,然后使用双击行的行号,这是一个从零开始的值,我们从地图数据结构的相应行中提取键和值。我们保存密钥以便稍后进行更新,并将与密钥关联的值放入编辑框中。
a 的使用reinterpret_cast
来自使用 Microsoft MSDN 库示例中的示例。有关reinterpret_cast
查看 stackoverflow的讨论何时使用 reinterpret_cast?
LRESULT CProvDialog::OnNMDblclkList1(int idCtrl, LPNMHDR pNMHDR, BOOL & bHandled)
{
// Handle a double click in the listview control.
// "The iItem, iSubItem, and ptAction members of this
// structure [NMITEMACTIVATE] contain information about the item."
LPNMITEMACTIVATE plvdi = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
if (plvdi->iItem >= 0) {
// we have a valid listview row number so lets update our edit box
CWindow pEdit = GetDlgItem (IDC_EDIT_PROP);
pEdit.SetWindowText (m_RegistryData->GetValueAt(plvdi->iItem).c_str());
m_EditKey = m_RegistryData->GetKeyAt(plvdi->iItem);
}
bHandled = TRUE;
return 1;
}
附带说明一下,这里有一些允许显示 multi-column 的源代码listview
。该控件需要打开详细信息视图,因此为了确保启用多列视图,我在对话框及其组件的初始化过程中使用了以下代码。
// First of all lets make sure that the listview is in Details or Report style.
// If the control is not in Details or Report style then even though we add columns
// only the first column will be displayed. Multiple columns only available in Details view.
ULONG ulWinStyle = pListView.GetWindowLong (GWL_STYLE);
ulWinStyle |= LVS_REPORT;
pListView.SetWindowLong (GWL_STYLE, ulWinStyle);
该listview
控件由对话框初始化中的以下源代码创建。我们与消息LPSTR_TEXTCALLBACK
处理程序一起使用NMLVDISPINFOW
以填充listview
控件。
// Initialize LVITEM members that are common to all items.
LVITEM lvI = {0};
lvI.pszText = LPSTR_TEXTCALLBACK; // Sends an LVN_GETDISPINFO message.
lvI.mask = LVIF_TEXT | LVIF_STATE | LVCF_SUBITEM;
lvI.stateMask = 0;
lvI.state = 0;
// Initialize LVITEM members that are different for each item.
int iCount = m_RegistryData->GetSize();
for (int index = 0; index < iCount; index++)
{
// Insert the item row with the first column into the list.
lvI.iItem = index;
lvI.iSubItem = 0;
if (ListView_InsertItem (pListView.m_hWnd, &lvI) != -1) {
// insert the second column into the listview.
lvI.iSubItem = 1;
ListView_SetItem (pListView.m_hWnd, &lvI);
}
}