Добавление поля редактирования в диалог ATL с помощью ATL CEdit в CAxDialogImpl

У меня есть проект на ATL (C ++) VS2010. Я создал класс диалога. С двумя кнопками и хотите добавить что-то вроде текстового поля. Я прочитал, что отвечает за этот компонент CEdit.

CEdit* pEdit = (CEdit*)GetDlgItem(IDC_EDIT1);

1. Но нигде не упоминается как ресурс объявления IDC_EDIT1.

2. Необходимо подключить afxwin.h. Я подключил библиотеку в stdafx.h сверху.

Он выдал мне ошибку:

Building MFC application with /MD[d] (CRT dll version) requires MFC
shared dll version. Please #define _AFXDLL or do not use /MD[d]

Я думал, что проблема в этом.
error Пожалуйста, введите #define _AFXDLL или не используйте / MD [d], даже после внесения изменений в свойства проекта

Тогда я получил ошибку:

#error directive: WINDOWS.H already included. MFC apps must not #include

Я удалил все ссылки WINDOWS.H, но ошибка осталась.

Есть ли решение без использования CEdit.

CWindow textBox(GetDlgItem(IDC_EDIT1));
textBox.SetWindowTextW(L"hello");

Но вопрос остается. В качестве ресурса указать IDC_EDIT1?
В общем, где это должно быть указано, как указано, есть ли примеры. Я не мог ничего найти. Возможно из-за моего плохого английского.

Я добавляю в Resource.h

#define IDC_EDIT1                       113

В файле .rc у меня есть две кнопки:

DEFPUSHBUTTON   "OK",IDOK,209,179,50,14
PUSHBUTTON      "Cancel",IDCANCEL,263,179,50,14

Как добавить мой IDC_EDIT1 в файл .rc?

????     "text",IDC_EDIT1,263,179,50,14

1

Решение

По данным stackoverflow Как получить текст из элемента управления CEdit CEdit не является частью стандартного ATL от Microsoft, но вместо этого Расширение библиотеки шаблонов Windows (WTL).

Похоже, что listview и treeview общие элементы управления имеют поддержку ATL от Microsoft.

Судя по упомянутым вами ошибкам, вы извлекаете компоненты MFC в сборку вместе со свойствами, связанными с MFC, в своем решении. Вам необходимо убедиться, что вы используете только ATL-включения, а также свойства и библиотеки в вашей сборке. Проверьте ваш стандартный файл включения stdafx.h использует ATL включает.

Вот некоторый исходный код для рассмотрения. Это из примера приложения, которое я делал с использованием ATL, которое отображает простое диалоговое окно с элементом управления списком с двумя столбцами, показывающими данные из ключа в реестре Windows. Диалог позволяет пользователю дважды щелкнуть по определенной строке listview control, а затем принимает значение, связанное с ключом строкового значения, и позволяет редактировать значение строкового значения.

я использую 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 контроль. При этом выполняется базовая проверка работоспособности, чтобы убедиться, что двойной щелчок действителен, а затем, используя номер строки, в которой дважды щелкнули мышью, это значение на основе нуля, мы извлекаем ключ и значение из соответствующей строки структуры данных карты. Мы сохраняем ключ, чтобы мы могли выполнить обновление позже, и помещаем значение, связанное с ключом, в поле редактирования.

Использование 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;
}

В качестве дополнительного примечания приведу немного исходного кода, необходимого для отображения нескольких столбцов. 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);
}
}
1

Другие решения