Продолжаем развивать проект остановленный на шаге "Шаг 13 - Обмен данными с диалоговой панелью без DDX". Нам необходимо создать пункт меню Open в меню File с идентификатором ID_OPEN.
Реакция на событие выбора меню.
BEGIN_MESSAGE_MAP(CMainWnd, CFrameWnd) // таблица откликов на сообщения ...... ON_WM_PAINT() ON_COMMAND(ID_OPEN,OnOpen) // Реакция на выбор меню Open ON_COMMAND(ID_FILE_EXIT,MenuExit) // Вот она, обработка реакции на выбор меню ...... END_MESSAGE_MAP()
Описание функции реакции:
class CMainWnd : public CFrameWnd { public: CMainWnd(); // Конструктор по умолчанию void OnOpen(); // эта функция вызовется при выборе меню Open afx_msg void OnLButtonDblClk(UINT, CPoint); ...... }
И реализация:
void CMainWnd::OnOpen() { CFileDialog fileDialog(TRUE,NULL,"*.cpp"); //объект класса выбора файла int result = fileDialog.DoModal(); //запустить диалоговое окно if (result==IDOK) //если файл выбран { AfxMessageBox(fileDialog.GetPathName()); // показать полный путь } }
Вот такое диалоговое окно появится при выборе пункта меню File -> Open.
В MFC есть стандартный класс для открытия и сохранения файлов CFileDialog. Смотрите, в функции OnOpen() объявляем класс, первый параметр простой TRUE - диалог открытия, FALSE диалог сохранения. Следующий параметр нам сейчас не нужен, он есть ниже. И расширения для открытия. Функция DoModal() вам знакома, если она возвращает код кнопки OK, то получаем имя файла функцией с названием, которое даже переводить не хочется.
Диалог сохранения файла:
CFileDialog fileDialog(FALSE,NULL,"*.cpp");
Выбор нескольких файлов в диалоговом окне:
CFileDialog fileDialog(TRUE,NULL,"*.*",OFN_ALLOWMULTISELECT); int result = fileDialog.DoModal(); if (result==IDOK) { POSITION ps=fileDialog.GetStartPosition(); // получить начальную позицию while (ps) AfxMessageBox(fileDialog.GetNextPathName(ps));// пока есть выбранные файлы }
Так выглядит диалог в режиме выбора нескольких файлов.
При выборе нескольких файлов может возникнуть ситуация, что Вы не можете выбрать файлов больше некоторого количества. Выход в увеличении внутреннего буфера, вот так это можно сделать.
int iBufferSize = 100000; CFileDialog fileDialog(TRUE,NULL,"*.*",OFN_ALLOWMULTISELECT | OFN_NOVALIDATE ); // выбор нескольких файлов fileDialog.m_ofn.nMaxFile = iBufferSize; // устанавливаем размер буфера char* cNewBuffer = new char[iBufferSize]; // выделяем место fileDialog.m_ofn.lpstrFile = cNewBuffer; // даем указатель на новое место fileDialog.m_ofn.lpstrFile[0] = NULL; // ничего нет int result = fileDialog.DoModal(); if (result==IDOK) { POSITION ps=fileDialog.GetStartPosition(); // получить начальную позицию while (ps) AfxMessageBox(fileDialog.GetNextPathName(ps));// пока есть выбранные файлы } delete []cNewBuffer;// освобождаем выделенную память
После расширения можно указывать параметры окна диалога, вот я и указал, выбирай несколько файлов. А вот дальше мы должны получить позицию в переменную типа POSITION, эта переменная передается как указатель в функцию GetNextPathName(), а она выдает строку по этой позиции, и заодно уменьшает позицию. Когда файлов нет позиция станет равной 0.
Фильтр на несколько файлов:
CFileDialog fileDialog(TRUE,NULL,"*.mak;*.rc");
Как видите, через точку с запятой можно передавать несколько расширений. Это не MFC придумало естественно. В Windows функция открытия файлов уже есть, и эта возможность взята из Win32 описания.
Выбор типа. За типом указан фильтр. Расширения для открытия ограничены скобками |*.mak|.
CFileDialog fileDialog(TRUE,NULL,"*.mak",NULL,"File Mak (*.mak)|*.mak|Resouce Files (*.res)|*.res|"); int result = fileDialog.DoModal();
Вот так это выглядит:
Добавление расширения для сохранения файлов. Как видите теперь установлена 2-я переменная. Это расширение, которое будет добавляться в конец файла.
CFileDialog fileDialog(FALSE,"obj","*.obj");
Создайте класс и настройте параметры:
CFileDialog fileDialog(TRUE,NULL,"*.cpp");
Запустите окно диалога:
int result = fileDialog.DoModal();
Получите имя файла:
if (result==IDOK) { AfxMessageBox(fileDialog.GetPathName()); // показать полный путь ...... }