Шаг 24.
Библиотека OWL.
Диалоговое окно Open (Открытие файла)

    На этом шаге мы рассмотрим использование диалогового окна Open.

    Вероятно, в Windows нет функции, применяемой в приложениях чаще, чем открытие документа. Так как эта функция требуется очень часто, и разработчики среды Windows хотели, чтобы данная задача обрабатывалась одинаково в различных приложениях, начиная с версии Windows 3.1 было добавлено стандартное диалоговое окно "Открытие файла" ("Open"). OWL инкапсулирует это диалоговое окно в класс TFileOpenDialog. TFileOpenDialog является производным классом от класса TOpenSaveDialog, который определяет базовые функции стандартных диалоговых окон "Открытие файла" ("Open") и "Сохранение файла" ("Save").

    Все классы стандартных диалоговых окон библиотеки OWL, в том числе и TOpenSaveDialog, включают встроенный класс с названием TData. TData представляет собой структуру, которая содержит информацию о том, как должно выглядеть стандартное диалоговое окно и как оно должно работать. Каждое стандартное диалоговое окно требует класс TData различного типа. Например, класс TData объекта TOpenSaveDialog содержит такую информацию, как задаваемое по умолчанию имя файла, шаблоны имени файла, заданное по умолчанию расширение файла и первоначально выбранный каталог. С другой стороны, объект класса TData, относящийся к диалоговому окну TChooseColorDialog, содержит такую информацию, как цвет, задаваемый по умолчанию, и массив цветов, определяемых пользователем.

    За исключением соответствующего классу объекта типа TData, вам не нужен доступ к каким-либо членам-данным либо функциям-членам класса TOpenSaveDialog. Фактически вам даже не нужно использовать конструктор TOpenSaveDialog. Вместо него вам следует вызвать конструкторы окон TFileOpenDialog или TFileSaveDialog. Следующий пример показывает, как использовать стандартное диалоговое окно "Открытие файла" ("Open").

#include <owl\applicat.h>
#include <owl\framewin.h>
#include <owl\opensave.h>
#include "pr24_1.rc"

//Класс приложения
class TApp: public TApplication
{
  public:
	 TApp():TApplication(){}
	 void InitMainWindow();
};

//Класс основного окна
class TWndw:public TFrameWindow
{
  public:
	 TWndw(TWindow *parent, const char far *title);
  protected:
	 void CmFileOpen();

	 DECLARE_RESPONSE_TABLE (TWndw);
};

DEFINE_RESPONSE_TABLE1 (TWndw, TFrameWindow)
  EV_COMMAND(CM_FILEOPEN, CmFileOpen),
END_RESPONSE_TABLE;

TWndw::TWndw(TWindow *parent, const char far *title):
		  TFrameWindow(parent,title)
{
	// Добавить меню к главному окну.
	AssignMenu("MENU_1");
	// Определить расположение и размеры окна.
	Attr.X=50;
	Attr.Y=50;
	Attr.W=GetSystemMetrics(SM_CXSCREEN)/3;
	Attr.H=GetSystemMetrics(SM_CXSCREEN)/4;
}

// TWndw::CmFileOpen()
// Эта функция реагирует на команду Open File
// из пункта меню File, отображая диалоговое окно "Открыть".
void TWndw::CmFileOpen()
{
  char errorMsg[81];
  // Создать объект TData диалогового окна. 
  TOpenSaveDialog::TData fileData (OFN_FILEMUSTEXIST | OFN_HIDEREADONLY 
      | OFN_PATHMUSTEXIST, 
     "Все файлы (*.*)|*.*|Текстовые файлы (*.txt)|*.txt|", 0, 0, "*");
  // Создать диалоговое окно Open. 
  TFileOpenDialog *dialog = new TFileOpenDialog(this, fileData);
  // Отобразить диалоговое окно Open. 
  int result = dialog->Execute();
  // Ответить на кнопку "OK" диалогового окна. 
  if (result == IDOK)
       MessageBox(fileData.FileName, "Результат выбора", MB_OK); 
  else if (fileData.Error != 0)
       {
         wsprintf(errorMsg,"Возникла ошибка #%ld.", fileData.Error); 
         MessageBox(errorMsg, "Ошибка",  MB_OK | MB_ICONEXCLAMATION);
       }
}


void TApp::InitMainWindow()
{
  TFrameWindow *wndw= new TWndw(0,"Диалоговое окно \"Открытие файла\"");
  SetMainWindow(wndw);
}

int OwlMain(int,char *[])
{
  return TApp().Run();
}

    Файл ресурсов:

#ifndef WORKSHOP_INVOKED
#include "windows.h"
#endif

#define CM_EXIT       24310
#define CM_FILEOPEN     108


#ifdef RC_INVOKED

MENU_1 MENU
{
 POPUP "&File"
 {
  MENUITEM "&Open File...", CM_FILEOPEN
  MENUITEM "E&xit", CM_EXIT
 }
}

#endif
Текст этого приложения можно взять здесь.

    При запуске этой программы вы увидите окно, показанное на рис.1.


Рис.1. Результат работы приложения

    Это окно имеет единственный пункт меню File, который содержит команды Open File и Exit. Выберите команду Open File, чтобы отобразить в Windows окно диалога Open, приведенное на рис.2.


Рис.2. Диалоговое окно "Открытие файла"

    Как видно из рисунка, это диалоговое окно содержит все элементы управления, необходимые для выбора каталогов, дисководов, фильтров и имен файлов. Сначала выберите файл, а затем нажмите кнопку ОК диалогового окна. После того, как вы это сделаете, появится окно сообщений, показывающее выбранный вами файл.

    Обратите внимание на находящуюся в начале текста программы строку:

    #include <owl\opensave.h>

    Вы должны включать заголовочный файл OPENSAVE.H в любую программу, которая использует классы диалоговых окон, производные от TOpenSaveDialog. Однако, в отличие от класса ТInputDialog, вам не нужно добавлять файл ресурсов к своему проекту для стандартных диалоговых окон. Это вызвано тем, что стандартные диалоговые окна находятся в COMMDLG.DLL - библиотеке диалоговых окон, включенной в Windows.

    Вам не нужно внимательно изучать класс главного окна в этом примере. Он очень похож на такой же класс из ранее рассмотренных примеров, только здесь появляется функция отклика на сообщение CmFileOpen(). Когда пользователь выбирает команду Open File из пункта меню File, OWL вызывает класс CmFileOpen():

void TWndw::CmFileOpen()
{
  char errorMsg[81];
  // Создать объект TData диалогового окна. 
  TOpenSaveDialog::TData fileData (OFN_FILEMUSTEXIST | OFN_HIDEREADONLY 
      | OFN_PATHMUSTEXIST, 
     "Все файлы (*.*)|*.*|Текстовые файлы (*.txt)|*.txt|", 0, 0, "*");
  // Создать диалоговое окно Open. 
  TFileOpenDialog *dialog = new TFileOpenDialog(this, fileData);
  // Отобразить диалоговое окно Open. 
  int result = dialog->Execute();
  // Ответить на кнопку "OK" диалогового окна. 
  if (result == IDOK)
       MessageBox(fileData.FileName, "Результат выбора", MB_OK); 
  else if (fileData.Error != 0)
       {
         wsprintf(errorMsg,"Возникла ошибка #%ld.", fileData.Error); 
         MessageBox(errorMsg, "Ошибка",  MB_OK | MB_ICONEXCLAMATION);
       }
}

    Эта функция сначала конструирует объект TData для диалогового окна. Версия объекта TData для класса TOpenSaveDialog имеет конструктор, требующий пять аргументов. Первым является набор флагов, которые определяют, как диалоговое окно будет выглядеть и работать. Таблица 1 содержит список констант, являющихся значениями этих флагов. Чтобы придать диалоговому окну Open такой вид, какой вы хотите, вы должны произвести операцию логического сложения (OR) над соответствующими флагами. В приведенном примере флаги указывают, что пользователь не может выбрать (создать) несуществующие файлы и пути, и кнопка-переключатель "только чтение" ("read-only") не будет показана в этом диалоговом окне.

Таблица 1. Константы флагов TOpenSaveDialog::TData
Имя Описание
OFN_ALLOWMULTISELECT Разрешает множественный выбор файлов.
OFN_CREATEPROMPT Спрашивать, желает ли пользователь создать файл, если он не существует.
OFN_EXTENSIONDIFFERENT Извещает вызывающую программу о том, что выбранный файл имеет расширение, отличное от заданного по умолчанию.
OFN_FILEMUSTEXIST Запрещает производить выбор несуществующего файла.
OFN_HIDEREADONLY Препятствует отображению кнопки-переключателя "read-only" ("только чтение").
OFN_NOVALIDATE Не проверять имя выбранного файла.
OFN_NOCHANGEDIR Переустанавливает каталог в текущий каталог в момент запуска окна диалога.
OFN_NOREADONLYRETURN Извещать вызывающую программу, когда выбранный файл не помечен только для чтения и не защищен от записи.
OFN_NOTESTFILECREATE Устанавливает режим создания файла без предварительного контроля таких ошибок как полный или недоступный диск.
OFN_OVERWRITEPROMPT Запрашивает у пользователя разрешение на перезапись существующего файла.
OFN_SHAREAWARE Возвращает имя выбранного файла, даже если существует конфликт при совместном использовании файлов.
OFN_SHOWHELP Показывает кнопку "Help" диалогового окна.

    Большинство этих параметров можно задать после создания объекта TData. В конце этого шага мы приведем структуру объекта TData для класса TOpenSaveDialog.

    Понятно, что большинство флагов, приведенных в таблице 1, не используются в диалоговом окне Open, так как выбранный пользователем файл открывается для чтения, а не для записи. Однако, так как класс TOpenSaveDialog является базовым для классов TFileOpenDialog и TFileSaveDialog диалоговых окон, то объект TDatа должен поддерживать задачи как открытия, так и сохранения файлов.

    Второй аргумент в конструкторе TOpenSaveDialog::TData представляет собой список фильтров имен файлов, которые должны будут появиться в окне списка фильтров имен файлов окна диалога. Вы можете включать столько фильтров, сколько вам необходимо, но каждый фальтр должен быть записан в следующей форме:

    text   |   filter  |

где text представляет собой описание фильтра файла, которое появляется в окне списка, a filter - реальный фильтр DOS. В приведенном примере фильтр для выбора любого файла представлен текстом Все файлы (*.*) и фильтром DOS *.*. Так же определен фильтр для текстовых файлов. Этот фильтр содержит текст Текстовые файлы (*.txt) и фильтр DOS *.txt. Вы можете перечислить столько таких фильтров, сколько захотите.

    Третий аргумент в конструкторе TOpenSaveDialog::TData позволяет вам добавить указатель к буферу для хранения заданных пользователем фильтров. Этот буфер почти всегда устанавливается в нулевое значение (NULL). Четвертый аргумент - это начальный каталог, в котором будет открываться диалоговое окно. Для текущего каталога установите этот аргумент в 0. Наконец, пятый аргумент - это расширение, которое будет добавляться к любому имени файла, вводимому пользователем без расширения. Например, если вы ожидаете, что пользователь должен выбрать текстовый файл с расширением ТХТ, вы можете задать ТХТ по умолчанию в TData. Тогда, если пользователь введет STORY1 в качестве имени файла, эта функция возвратит STORY1.TXT.

    После того, как функция создала объект TData, возвратимся к CmFileOpen(). Она конструирует диалоговое окно Open. Для этого программа вызывает конструктор класса TOpenFileDialog, который требует в качестве аргументов указатель родительского окна создаваемого диалогового окна и ссылку на объект TData диалогового окна. Вызов функции Execute() диалогового окна активизирует окно диалога и разрешает пользователю использовать его управляющие элементы для выбора файла.

    Пользователь может выйти из диалогового окна Open с помощью кнопок ОК или Cancel. Если пользователь выходит по кнопке ОК, то он выбрал файл, который надо открыть и имя которого хранится в элементе TData.FileName (fileData.FileName в приведенном примере). В этом пункте CmFileOpen() в действительности не открывает файл, а выводит выбранное имя файла в окне сообщений.

    Если пользователь выходит по кнопке Cancel, CmFileOpen() не производит никаких действий. Однако значение результата IDCANCEL из диалогового окна не обязательно означает, что пользователь выбрал кнопку Cancel. Это может означать также, что диалоговое окно Open возвращает ошибку. Чтобы различить эти ситуации, программа проверяет значене члена-данного TData.Error. Если значение Error равно 0, ошибки не произошло. В противном случае Error содержит номер ошибки. Как следует из примера, если произошла ошибка, CmFileOpen() отображает ее в окне сообщений.

    Приведем описание структуры объекта TData для класса TOpenSaveDialog.

    На следующем шаге мы рассмотрим использование диалогового окна Save.




Предыдущий шаг Содержание Следующий шаг