C++ C++ C# C# ASP.NET Security ASP.NET Security ASM ASM Скачать Скачать Поиск Поиск Хостинг Хостинг  
  Программа для работы с LPT портом...
Язык: .NET — ©Alexey...
  "ASP.NET Atlas" – AJAX в исполнении Micro...
Язык: .NET — ©legigor@mail.ru...
  "Невытесняющая" Многопоточность...
Язык: C/C++ — ©...
  01.05.2010 — Update World C++: Сборник GPL QT исходников
  15.12.2007 — Весь сайт целиком можно загрузить по ссылкам из раздела Скачать
Хостинг:
Windows 2003, ASP.NET 2.0
бесплатный и от 80 руб./мес


   Отправить письмо
Кулабухов Артем, Беларусь




 Урок 25. Передаем данные по ссылке / Уроки MFC / Visual C++

Visual C++. MFC
Урок 25. Передаем данные по ссылке

В уроке 19 мы с вами посмотрели, как передаются данные в диалоговое окно и из него. Напомним приблизительную схему - заводим пару переменных (одну в классе диалогового окна и другую, наример, в классе гланого окна). После этого вызываем диалог с помощью DoModal, передавая данные перед и после этого вызова:

    ...
    CSomeDlg dlg;
    dlg.m_SomeData=m_SomeData;
    dlg.DoModal();
    m_SomeData=dlg.m_SomeData;
    ...

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

Создайте проект основанный на диалоговом окне. Для этого проще всего воспользоваться AppWizard'ом (для создания EXE):

Содание нового проекта

На первом шаге мастера в качестве типа приложения выберите тип Single Document, и уберите галочку для поддержки архитектуры Документ-Вид (зачем нам разные усложнения):

Выбор типа проекта

Далее до шага 4 оставляем все параметры по умолчанию. На шаге 4 уберите лишние галочки для панели инструментов и для строки состояния (Docking toolbar и Initial status bar), после чего можно сразу нажать на Finish.

После создания заготовки переходим к содержательной части нашего кода.

Создаем ресурс для нового диалогового окна. Для этого нажимаем Ctrl+R, выбираем среди ресурсов Dialog, нажимаем на кнопочку New. В редакторе диалога добавьте на него Edit:

Редактор диалога

Вызываем далее ClassWizard (Ctrl+W), в появившемся диалоговом окне выбираем радиокнопку Создать новый класс:

Создание нового класса

В качестве имени класса задаем CDlg, после чего закрываем окошко New Class и ClassWizard. Далее с помощью редактора меню добавляем новое меню (назовем его Dialog и добавим в меню File), и в его обработчик (созданный с помощью ClassWizard) вставляем следующий код:

void CMainFrame::OnFileDialog() 
{
    // TODO: Add your command handler code here
    CDlg dlg(this);
    dlg.DoModal();
}

Не забудьте в начале этого файла добавить нужный include, чтобы компилятор не ругался, что он не знает, что такое CDlg:

...
#include "Dlg.h"
#include "MainFrm.h"
...

Обратите внимание, что это весь необходимый код для передачи данных в диалоговое окно и из него. Мы ничего не передаем ни до вызова DoModal(), ни после него. Также обратите внимание, что мы конструируем экземпляр нашего класса CDlg с параметром this. Тем самым мы передаем в dlg указатель на класс окна-рамки. Разумеется такой конструктор с параметром типа CMainFrame * должен существовать в классе CDlg. Добавьте его. Его реализация будет такой:

CDlg::CDlg(CMainFrame *pMainFrame):CDialog (IDD_DIALOG1, pMainFrame)
{
    m_pMainFrame=pMainFrame;
}

Обратите внимание, что для данного конструктора мы вызываем в том числе и конструктор базового класса CDialog.

Так как наш конструктор использует указатель на родительский класс, то его надо добавить (в заголовочный файл класса CDlg, разумеется):

...
#include "MainFrm.h" //Надо подключить
...
class CDlg : public CDialog
{
    ...
public:
    CDlg (CMainFrame* pMainFrame);
    CDlg(CWnd* pParent = NULL);   // standard constructor
    CMainFrame *m_pMainFrame;// Указатель на главное окно приложения
    ...

Теперь займемся данными. Добавьте в класс окна-рамки CMainFrame следующую переменную (в ней как раз и хранится большой объем данных, для которых мы не хотим делать копии в классе CDlg):

    ...
public:
    CString m_sBigData;
    ...

В конструкторе класса CMainFrame что-нибудь запишите в эту переменную:

CMainFrame::CMainFrame()
{
    // TODO: add member initialization code here
    m_sBigData="Большие данные";
}

Теперь займемся непосредственно обменом. Для этого добавьте в метод DoDataExchange класса CDlg вызов DDX_Text(...):

void CDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CDlg)
        // NOTE: the ClassWizard will add DDX and DDV calls here
    //}}AFX_DATA_MAP
    DDX_Text(pDX, IDC_EDIT1, m_pMainFrame->m_sBigData);
}

Что мы тут делаем? Мы осуществляем обмен между полем IDC_EDIT1 и переменной m_sBigData из класса окна-рамки, на которую указывает m_pMainFrame.

Запускайте программу и заходите в наше меню. В edit'е появится строка, взятая из окна рамки:

Диалоговое окно со старым значением

Если в нем напечатать что-нибудь другое, нажать на OK и затем вновь вызвать наше диалоговое окно, то будет уже новое значение:

Диалоговое окно с новым значением

Таким образом наша ссылка работает!