2015-07-06 4 views
1

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

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 Please #define _AFXDLL or do not use /MD[d] occurs even after making changes in Project Properties

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

#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 
+0

Вы можете добавить редактируемый элемент управления в Visual Studio. Затем вы можете проверить файл .RC для изменений. Элемент управления будет создан автоматически как часть шаблона диалога. Затем в коде вы можете добавить 'GetDlgItem' для« захвата »элемента управления. –

+0

Эта статья MSDN [Классы окон ATL 3.0: введение] (https://msdn.microsoft.com/en-us/library/Aa260759 (v = VS.60) .aspx) содержит примеры использования ATL для окон и диалогов , Я работаю в этой же области, поэтому, когда у меня есть код, я отправлю ответ. Сейчас похоже, что Windows API отправляет сообщения в окно редактирования. –

+0

Эта статья кодекса, одна из серии на WTL и ATL, содержит примеры и примеры исходного кода с использованием CEdit и других классов http: //www.codeproject.com/Articles/4028/WTL-for-MFC-Programmers-Part-IV-Dialogs-and-Contro и из сообщений об ошибках похоже, что вы смешиваете заголовки MFC с заголовками WTL/ATL или ваши свойства проекта смешиваются в Библиотеки MFC, которые вызывают ошибки сборки. –

ответ

0

Согласно StackOverflow How to get text from CEdit control CEdit не является частью стандартной библиотеки ATL от Microsoft, но вместо этого Windows Template Library (WTL) extension.

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

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

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

Использование reinterpret_cast приведено в примере из примеров библиотеки Microsoft MSDN. Для обсуждения reinterpret_cast см StackOverflow When to use 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); 
    } 
}