Россия |
Опубликован: 15.11.2010 | Уровень: для всех | Доступ: платный
Лекция 9:
Ввод-вывод с использованием WinAPI
9.4. Приложение № I. Описание функций создания и открытия файлов
typedef struct tagOFSTRUCT { BYTE cBytes; BYTE fFixedDisk; UINT nErrCode; BYTE reserved[4]; char szPathName[128]; } OFSTRUCT;
Поле cBytes содержит размер самой структуры OFSTRUCT в байтах.
С помощью поля fFixedDisk приложение может определить, находится ли открытый файл на жёстком диске, на флоппи-диске или другом съёмном носителе. Если содержимое этого поля отлично от нуля, то файл находится на жёстком диске.
Если при открытии файла произошла ошибка, в поле nErrCode записывается код ошибки. Возможные значения для кода ошибки приведены в приложении №I к книге [37].
Поле reserved зарезервировано, и не должно использоваться.
В поле szPathName находится полный путь к файлу в кодировке OEM.
9.5. Приложение № II. Основные опции стандартных диалогов GetOpenFileName и GetSaveFileName
typedef struct tagOFN { DWORD lStructSize; HWND hwndOwner; HINSTANCE hInstance; LPCSTR lpstrFilter; LPSTR lpstrCustomFilter; DWORD nMaxCustFilter; DWORD nFilterIndex; LPSTR lpstrFile; DWORD nMaxFile; LPSTR lpstrFileTitle; DWORD nMaxFileTitle; LPCSTR lpstrInitialDir; LPCSTR lpstrTitle; DWORD Flags; UINT nFileOffset; UINT nFileExtension LPCSTR lpstrDefExt; LPARAM lCustData; UINT (CALLBACK *lpfnHook) (HWND, UINT, WPARAM, LPARAM); LPCSTR lpTemplateName; } OPENFILENAME;
В таблице 9.3 представлено назначение полей данной структуры. В таблице 9.4 представлено описание и расшифровка режимов вывода файлов, записанных в переменную Flags.
9.6. Приложение № III
/* Файл INIT.CPP */ /********************************************************** * Каркас приложений Windows, * на основе которого можно строить более * сложные приложения MS WINDOWS. * Каркас использует правила для написани * программ на платформе Turbo C++ 3.1 * 16-ти разрядных версий Windows. * * Более подробную информацию о "низкоуровневом" написании * программ для Microsoft Windows смотри А.В. Фролов, Г.В. * Фролов, "Операционная система Microsoft Windows 3.1. * для программиста". -- М. "ДИАЛОГ-МИФИ", 1994 г. и др. * книги этих авторов. **********************************************************/ #define STRICT #include <windows.h> #include <mem.h> // Прототипы функций // Первая функция - для инициализации // приложения Windows, вторая функция - // для обработки системных сообщений. BOOL InitApp(HINSTANCE); LRESULT CALLBACK _export WndProc(HWND, UINT, WPARAM, LPARAM); /* Значения класса и заголовка впоследствии нужно заменить */ // Имя класса окна char const szClassName[] = "WindowAppClass"; // Заголовок окна char const szWindowTitle[] = "Window Application"; // ===================================== /*************************************** * Функция WinMain * Получает управление при запуске * приложени ***************************************/ // ===================================== #pragma argsused int PASCAL WinMain(HINSTANCE hInstance, // идентификатор текущей // копии приложени HINSTANCE hPrevInstance, // идентификатор предыдущей // копии приложени LPSTR lpszCmdLine, // указатель на командную строку int nCmdShow) // способ отображения главного // окна приложени { MSG msg; // структура для работы с сообщениями HWND hwnd; // идентификатор главного окна приложени // Проверяем, не запускалось ли это приложение ранее // if(!hPrevInstance) // { // Если не запускалось, вызываем функцию InitApp // для инициализации приложения. /***************************************************** * Вызываем функцию InitApp * для инициализации приложения. * Если инициализацию выполнить не удалось, * завершаем приложение *****************************************************/ if(!InitApp(hInstance)) return FALSE; // } /**************************************************** * После успешной инициализации приложения создаём * главное окно приложени ****************************************************/ hwnd = CreateWindow( szClassName, // имя класса окна (см. Выше ) szWindowTitle, // заголовок окна (см. Выше) WS_OVERLAPPEDWINDOW, // стиль окна /**************************************************** * В данном случае это перекрывающееся окно, но эту * опцию можно изменить для других типов окон *****************************************************/ CW_USEDEFAULT, // задаём размеры и расположение CW_USEDEFAULT, // окна, принятые по умолчанию CW_USEDEFAULT, CW_USEDEFAULT, 0, // идентификатор родительского окна // Для главного окна его менять нельз 0, // идентификатор меню /********************************************************** * В случае, если у окна необходимо создать меню, вместо * нуля сюда вставляется идентификатор меню (тип HMENU), * созданный с помощью функции LoadMenu. * * Если меню подключается как ресурс приложения в функции * InitApp, в этом поле также нужно оставить 0 **********************************************************/ hInstance, // идентификатор приложени NULL); // указатель на дополнительные // параметры /********************************************************** * Далее код лучше не менять * **********************************************************/ // Если создать окно не удалось, завершаем приложение if(!hwnd) return FALSE; /********************************************************** * В случае если Вам не нужно рисовать главное окно * приложения (например, Вы пишете программу мастер) * две нижеперечисленные функции: ShowWindow и * UpdateWindow, указывать не надо **********************************************************/ // Рисуем окно. Для этого после функции ShowWindow, рисующей // окно, вызываем функцию UpdateWindows, посылающую // сообщение WM_PAINT в функцию окна ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); /********************************************************** * Далее до конца функции код лучше не менять * **********************************************************/ // Запускаем цикл обработки сообщений while(GetMessage(&msg, 0, 0, 0)) { DispatchMessage(&msg); } // Возвращаем значение WParam, переданное // в качестве параметра функции PostQuitMessage // в процессе инициирования завершения работы // приложения из функции окна. // Затем завершаем работу приложени return msg.wParam; } /* Конец функции WinMain *| // ===================================== /********************************************************** * Функция InitApp * Вызывается из функции WinMain дл * инициализации приложения. * Выполняет регистрацию класса окна **********************************************************/ // ===================================== BOOL InitApp(HINSTANCE hInstance) { ATOM aWndClass; // атом для кода возврата WNDCLASS wc; // структура для регистрации // класса окна // Записываем нулевые значения во все поля структуры memset(&wc, 0, sizeof(wc)); // Стиль окна /********************************************************** * Поле style задаёт стиль класса окна и задаётся в виде * констант, описанных в файле <windows.h>. Описани * констант стилей начинается с префикса CS_. Стиль окна * задаёт реакцию окна на изменения его размера, на * выполнение в окне операции двойного щелчка мышью, а * также задаёт другие характеристики окна. * Если в главное окно предполагается вывод информации, * необходимо указать, по крайней мере: * wc.style = CS_HREDRAW | CS_REDRAW; * в противном случае записать: * wc.style = 0; **********************************************************/ wc.style = 0; // Указатель на функцию окна, обрабатывающую // сообщения, предназначенные для всех окон, // созданных на основе данного класса /* Желательно не менять! */ wc.lpfnWndProc = (WNDPROC) WndProc; // Размер дополнительной области данных, // зарезервированной в описании класса окна /* Желательно не менять! */ wc.cbClsExtra = 0; // Размер дополнительной области данных, // зарезервированной для каждого окна, // созданного на основе данного класса /* Желательно не менять! */ wc.cbWndExtra = 0; // Идентификатор приложения, которое // создало данный класс /* Желательно не менять! */ wc.hInstance = hInstance; // Идентификатор пиктограммы, используемой // для окно данного класса /********************************************************** * Иконки создаются или "подгружаются" из специальных * файлов с "ресурсами", с помощью команды LoadIcon. * Первый параметр функции содержит идентификатор * приложения, в котором ищется иконка (значение NULL дл * системных областей), второй параметр задаёт имя ресурса- * пиктограммы. Если Вы не уверены, то этот параметр * менять не нужно. **********************************************************/ wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); // Идентификатор курсора, используемого // для окна данного класса /********************************************************** * Курсоры создаются или "подгружаются" из специальных * файлов с "ресурсами", с помощью команды LoadCursor. * Первый параметр функции содержит идентификатор * приложения, в котором ищется курсор (значение NULL дл * системных областей), второй параметр задаёт имя ресурса- * курсора. Если Вы не уверены, то этот параметр менять * не нужно (оставляем стандартный курсор в виде стрелки). **********************************************************/ wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Цвет фона окна /* Желательно не менять, оставить системный цвет */ wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); // Идентификатор меню /********************************************************** * В случае если у окна необходимо создать меню, в это * поле нужно указать адрес текстовой строки, содержащей * имя шаблона меню в файле ресурсов. Все перекрывающиеся и * временные окна, созданные на базе этого класса, будут * иметь меню, определённое данным шаблоном. Пример: * wc.lpszMenuName = "APP_MENU"; * Если для идентификации шаблона использовать целые * числа, необходимо использовать макрокоманду * MAKEINTRESOURCE. Например, в файле описания ресурсов и в * файле исходного приложения определена константа: * #define APP_MENU 123 * В этом случае строка примет вид: * wc.lpszMenuName = MAKEINTRESOURCE( APP_MENU ); * Если в окне меню не нужно, оставьте параметр без * изменения. **********************************************************/ wc.lpszMenuName = (LPSTR)NULL; /* Желательно не менять остальные операторы до конца функции */ // Имя, которое присваивается создаваемому // классу и используется при создании // окон данного класса wc.lpszClassName = (LPSTR)szClassName; // Регистрация класса aWndClass = RegisterClass(&wc); // Возвращаем результат регистрации класса return (aWndClass != 0); } /* Файл WinProc.cpp */ #define STRICT #include <windows.h> #include <mem.h> // ===================================== /********************************************************** * Функция WndProc * НЕ ВЫЗЫВАЕТСЯ ни из одной функции приложения. * Эту функцию вызывает Windows в процессе * обработки сообщений. Для этого адрес функции WndProc * указывается при регистрации класса окна. * Функция выполняет обработку сообщений главного * окна приложени * * Более подробную информацию о "низкоуровневом" написании * программ для Microsoft Windows смотри А.В. Фролов, Г.В. * Фролов, "Операционная система Microsoft Windows 3.1. * для программиста". -- М. "ДИАЛОГ-МИФИ", 1994 г. и др. * книги этих авторов. **********************************************************/ // ===================================== LRESULT CALLBACK _export WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { // Выполняем обработку сообщений. Идентификатор // сообщения передаётся через параметр msg switch (msg) { /********************************************************** * Это сообщение приходит, когда создаётся окно приложени * Здесь нужно вызвать контекст экрана, сохранить в * переменных его метрики и освободить его. **********************************************************/ case WM_CREATE: { // Получаем контекст отображения, // необходимый для определения метрик. return 0; } /********************************************************** * Это сообщение приходит, когда "рисуется" окно приложения. * Здесь нужно вызвать контекст экрана, вывести необходимые * данные на экран, и освободить контекст. **********************************************************/ case WM_PAINT: { // Инициализируем текущую позицию вывода текста // Получаем контекст экрана // Освобождаем контекст экрана return 0; } /********************************************************* // Это сообщение приходит, когда вы поместили курсор // мыши в область главного окна приложения и нажали // левую клавишу мыши case WM_LBUTTONDOWN: { return 0; } // Это сообщение приходит, когда вы поместили курсор // мыши в область главного окна приложения и нажали // правую клавишу мыши case WM_RBUTTONDOWN: { return 0; } **********************************************************/ /********************************************************** * Это сообщение приходит, когда вы завершаете * работу приложения стандартным дл * Windows способом **********************************************************/ case WM_DESTROY: { // Инициируем завершение работы приложения, // помещая в очередь приложения сообщение // WM_QUIT. Это приведёт к завершению // цикла обработки сообщений в функции WinMain PostQuitMessage(0); return 0; } } // Все сообщения, которые не обрабатываются нашей // функцией окна, ДОЛЖНЫ передаваться функции // DefWindowProc return DefWindowProc(hwnd, msg, wParam, lParam); } /* Файл WINDOW.DEF */ ; ============================= ; Файл определения модул ; ============================= ; Имя приложени NAME WINDOW ; Описание приложени DESCRIPTION 'Приложение WINDOW, (C) 1994, Frolov A.V.' ; Определение типа загрузочного модуля как ; приложения Windows EXETYPE windows ; Программа, которая будет записана в начало файла ; приложения. Эта программа получит управление ; при попытке запуска приложения в среде MS-DOS STUB 'winstub.exe' ; Размер стека в байтах STACKSIZE 5120 ; Размер локальной кучи памяти приложения в байтах HEAPSIZE 1024 ; Атрибуты сегмента кода CODE preload moveable discardable ; Атрибуты сегмента данных DATA preload moveable multiple