Шаг 15 - Стандартный диалог открытия файлов

Создание проекта

Продолжаем развивать проект остановленный на шаге "Шаг 13 - Обмен данными с диалоговой панелью без DDX". Нам необходимо создать пункт меню Open в меню File с идентификатором ID_OPEN.

15_1.gif (3064 b)

Создаем код

Реакция на событие выбора меню.

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.

15_2.gif (4085 b)

Описание

В 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));// пока есть выбранные файлы
}

Так выглядит диалог в режиме выбора нескольких файлов.

15_3.gif (5781 b)

При выборе нескольких файлов может возникнуть ситуация, что Вы не можете выбрать файлов больше некоторого количества. Выход в увеличении внутреннего буфера, вот так это можно сделать.

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();

Вот так это выглядит:

15_4.gif (4166 b)

Добавление расширения для сохранения файлов. Как видите теперь установлена 2-я переменная. Это расширение, которое будет добавляться в конец файла.

CFileDialog fileDialog(FALSE,"obj","*.obj");

Шпаргалка

Создайте класс и настройте параметры:

CFileDialog fileDialog(TRUE,NULL,"*.cpp");

Запустите окно диалога:

int result = fileDialog.DoModal();

Получите имя файла:

if (result==IDOK)
{
	AfxMessageBox(fileDialog.GetPathName()); // показать полный путь 
	......
}

Загрузить проект | Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Каев Артем - 07.09.99 (обновлено 29.06.2001)