Файловые операции в операционной системе Microsoft Windows отличаются от файловых операций MS-DOS следующим:
fges, getc, fscanf и др.). Используемый в Windows способ чтения-записи является более "безопасным" для обработчика данных и операционной системы;Примечание: операции потокового вывода на экран и ввода с клавиатуры можно также осуществить и в Windows, указав опцию в IDE при создании проекта "консольное приложение Windows". Этот вопрос Вы можете изучить самостоятельно [38].
Для создания, открытия и закрытия файлов Windows API использует следующие функции:
| ФУНКЦИЯ | OpenFile |
| СИНТАКСИС: | HFILE WINAPI OpenFile( lpszFileName, lpOpenStruct, fuMode)
|
| НАЗНАЧЕНИЕ: | Открывает файл и связывает с ним |
| ОПИСАНИЕ: | Функция предназначена для создания, открытия, повторного открытия и удаления файлов. В имени файла допускается указывать символы шаблона, такие как "*" и "?". Параметр fuMode используется для определения действий, выполняемых функцией OpenFile, а также задаёт атрибуты файла. Когда функция OpenFile вызывается в первый раз для открытия файла, она заполняет структуру OFSTRUCT, описанную в приложении №1 (смотри пункт 9.4 данной лекции); |
| ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: | Функция возвращает идентификатор файла, который можно (и нужно) использовать во всех последующих операциях с файлом, или -1 при ошибке; |
| ПЕРЕНОСИМОСТЬ: | Версии MS Windows 3.0 и старше; |
| ФУНКЦИЯ | _lopen |
| СИНТАКСИС: | HFILE WINAPI _lopen( LPCSTR lpszFileName, int fuOpenMode)
|
| НАЗНАЧЕНИЕ: | Открывает файл и связывает с ним |
| ОПИСАНИЕ: | Функция предназначена для открытия, повторного открытия файлов. В имени файла допускается указывать символы шаблона, такие как "*" и "?". Параметр fuMode используется для определения действий, выполняемых функцией _lopen ; |
| ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: | Функция возвращает идентификатор файла, который можно (и нужно) использовать во всех последующих операциях с файлом, или HFILE_ERROR при ошибке; |
| ПЕРЕНОСИМОСТЬ: | Версии MS Windows 3.0 и старше; |
| ФУНКЦИЯ | _lclose |
| СИНТАКСИС: | HFILE WINAPI _lclose( hf )
|
| НАЗНАЧЕНИЕ: | Закрывает файл, связанный с соответствующим дескриптором; |
| ОПИСАНИЕ: | Закрывает файл с дескриптором hf ; |
| ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: | Если файл закрыт успешно, _lclose возвращает нулевое значение. При ошибке возвращается значение: HFILE_ERROR ; |
| ПЕРЕНОСИМОСТЬ: | Версии MS Windows 3.0 и старше; |
| ФУНКЦИЯ | _lcreat |
| СИНТАКСИС: | HFILE _lcreat( lpszFileName, fuAttribute)
|
| НАЗНАЧЕНИЕ: | Создаёт файл средствами Win API; |
| ОПИСАНИЕ: | Это более простая, чем OpenFile, функция для создания новых файлов. Имя файла не должно содержать метасимволов шаблона. Если указанный первым параметром файл не существует, функция _lcreat создаёт его и открывает для записи, возвращая его |
| ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: | Идентификатор созданного файла; |
| ПЕРЕНОСИМОСТЬ: | Версии MS Windows 3.0 и старше; |
Отличие функции OpenFile от функции _lopen заключается в поддержке ей расширенной информации о файле, передаваемой структуре OFSTRUCT, и в большем числе поддерживаемых флагов команды. Информацию о флагах функций OpenFile, _lcreate и _lopen смотри в таблице 9.1. Описание функций смотри в приложении №I к данной лекции (пункт 9.4).
| Константа | Описание |
|---|---|
| ФУНКЦИЯ OpenFile | |
OF_READ |
Файл открывается только для чтения. |
OF_WRITE |
Файл открывается только для записи. |
OF_READWRITE |
Файл открывается для чтения и записи. |
OF_SHARE_COMPAT |
Открытие файла в режиме совместимости. В этом режиме несколько приложений могут одновременно открыть файл, причём все эти приложения должны открывать файл в режиме совместимости. |
OF_SHARE_EXCLUSIVE |
Файл открывается в монопольном режиме. Для всех других приложений доступ к этому файлу на чтение и запись запрещён. |
OF_SHARE_DENY_WRITE |
После открытия файла к нему запрещается доступ со стороны других приложений на запись. |
OF_SHARE_DENY_READ |
После открытия файла к нему запрещается доступ со стороны других приложений на чтение. |
OF_SHARE_DENY_NONE |
Для открываемого файла не запрещается доступ к файлу ни на чтение, ни на запись. |
OF_PARSE |
Если указан этот флаг, функция OpenFile не выполняет никаких других действий, кроме заполнения структуры OFSTRUCT. |
OF_DELETE |
Уничтожение существующего файла. |
OF_VERIFY |
Если указан этот флаг, то функция OpenFile сравнивает время и дату, записанную в структуре OFSTRUCT, со временем и датой изменений указанного файла. Если обнаружено несоответствие, функция OpenFile возвращает значение HFILE_ERROR. |
OF_SEARCH |
Операционная система выполняет поиск файла в каталогах даже в том случае, когда текстовая строка, указанная параметром lpszFileName, содержит полный путь к файлу. |
OF_PROMPT |
Если указан этот флаг, то в случае невозможности найти указанный файл Windows выдаёт диалоговую панель с предложением вставить в дисковод A: дискету с файлом. Это флаг используется очень редко. |
OF_CANCEL |
Данный флаг указывается вместе с флагом OF_PROMPT. Если он указан, то в описанную выше диалоговую панель будет добавлена кнопка "Cancel" для отмены открытия файла. Приложение при этом получит код ошибки, соответствующий ненайденному файлу, а пользователь – возможность выйти из затруднительного положения, в которое он попадает при отсутствии дискеты с нужным файлом. |
OF_CREATE |
выполняется создание нового файла. Если указанный файл существует, то он обрезается до нулевой длины. |
OF_EXIST |
При указании этого флага функция OpenFile вначале открывает файл, а потом сразу же его закрывает. Эта операция может быть использована для того, чтобы убедиться в существовании указанного файла на диске. |
OF_REOPEN |
Этот флаг используется при повторном открытии файла на основе информации, хранящейся в структуре OFSTRUCT. |
| ФУНКЦИЯ _lopen | |
OF_READ |
Файл открывается только для чтения. |
OF_WRITE |
Файл открывается только для записи. |
OF_READWRITE |
Файл открывается для чтения и записи. |
OF_SHARE_COMPAT |
Открытие файла в режиме совместимости. В этом режиме несколько приложений могут одновременно открыть файл, причём все эти приложения должны открывать файл в режиме совместимости. |
OF_SHARE_EXCLUSIVE |
Файл открывается в монопольном режиме. Для всех других приложений доступ к этому файлу на чтение и запись запрещён. |
OF_SHARE_DENY_WRITE |
После открытия файла к нему запрещается доступ со стороны других приложений на запись. |
OF_SHARE_DENY_READ |
После открытия файла к нему запрещается доступ со стороны других приложений на чтение. |
OF_SHARE_DENY_NONE |
Для открываемого файла не запрещается доступ к файлу ни на чтение, ни на запись. |
| ФУНКЦИЯ _lcreat | |
0 |
Нормальный файл, для которого разрешено выполнение операций чтения и записи |
1 |
Этот файл можно открыть только для чтения |
2 |
|
3 |
Системный файл |
Для операций чтения-записи в файл Microsoft Windows применяются следующие функции:
| ФУНКЦИЯ | _lread |
| СИНТАКСИС: | UINT WINAPI _lread( hf, hpvBuffer, cbBuffer )
|
| НАЗНАЧЕНИЕ: | Функция читает содержимое файла, определённого дескриптором, в текстовый буфер. Размер буфера ограничен 64 Кбайт; |
| ОПИСАНИЕ: | Функция предназначена для чтения информации из файла в буфер памяти. Через параметр hf функции следует передать идентификатор файла, для которого необходимо сделать операцию чтения. Прочитанные данные будут записаны в буфер hpvBuffer, имеющий размер cbBuffer байт. Этот буфер можно получить динамически, вызвав, например, функцию GlobalAlloc или, что лучше с точки зрения совместимости, LocalAlloc. Размер буфера не должен превышать 65 534 байт. |
| ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: | Функция возвращает количество байт данных, прочитанных из файла. Возвращённое значение может быть меньше затребованного в параметре cbBuffer, если достигнут конец файла. При ошибке функция возвращает значение HFILE_ERROR. |
| ПЕРЕНОСИМОСТЬ: | MS Windows 3.0 и старше; |
| ФУНКЦИЯ | _hread |
| СИНТАКСИС: | long WINAPI _hread( hf, hpvBuffer, cbBuffer )
|
| НАЗНАЧЕНИЕ: | Функция читает содержимое файла, определённого дескриптором, в текстовый буфер. Размер буфера ограничен 2 Гбайт; |
| ОПИСАНИЕ: | Функция предназначена для чтения информации из файла в буфер памяти. Через параметр hf функции следует передать идентификатор файла, для которого необходимо сделать операцию чтения. Прочитанные данные будут записаны в буфер hpvBuffer, имеющий размер cbBuffer байт. Этот буфер можно получить динамически, вызвав функцию GlobalAlloc ; |
| ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: | Функция возвращает количество байт данных, прочитанных из файла. Возвращённое значение может быть меньше затребованного в параметре cbBuffer, если достигнут конец файла. При ошибке функция возвращает значение HFILE_ERROR. |
| ПЕРЕНОСИМОСТЬ: | MS Windows 3.1 и старше; |
| ФУНКЦИЯ | _lwrite |
| СИНТАКСИС: | UINT WINAPI _hread( hf, hpvBuffer, cbBuffer )
|
| НАЗНАЧЕНИЕ: | Функция записывает содержимое текстового буфера в файл, определённого дескриптором. Размер буфера ограничен 64 Кбайт; |
| ОПИСАНИЕ: | Назначение параметров этой функции аналогично назначению параметров функции _lread, Перед вызовом функции _lwrite буфер должен содержать данные, записываемые в файл; |
| ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: | Функция возвращает количество байт данных, записанных в файл, или значение HFILE_ERROR при ошибке; |
| ПЕРЕНОСИМОСТЬ: | MS Windows 3.0 и старше; |
| ФУНКЦИЯ | _hwrite |
| СИНТАКСИС: | long WINAPI _hread( hf, hpvBuffer, cbBuffer )
|
| НАЗНАЧЕНИЕ: | Функция записывает содержимое текстового буфера в файл, определённого дескриптором. Размер буфера ограничен 2 Гбайт; |
| ОПИСАНИЕ: | Назначение параметров этой функции аналогично назначению параметров функции _hread, Перед вызовом функции _lwrite буфер должен содержать данные, записываемые в файл; |
| ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: | Функция возвращает количество байт данных, записанных в файл, или значение HFILE_ERROR при ошибке; |
| ПЕРЕНОСИМОСТЬ: | MS Windows 3.1 и старше; |
| ФУНКЦИЯ | GetDriveType |
| СИНТАКСИС: | UINT WINAPI GetDriveType( DriveNumber )
|
| НАЗНАЧЕНИЕ: | Позволяет определить тип и расположение используемого дискового |
| ОПИСАНИЕ: | Иногда требуется определить тип и расположение используемого |
| ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: | Функция может вернуть нуль при ошибке или одно их следующих значений (смотри таблицу 9.2); |
| ПЕРЕНОСИМОСТЬ: | MS Windows 3.0 и старше; |
| Константа | Описание |
|---|---|
| ФУНКЦИЯ GetDriveType | |
DRIVE_REMOVABLE |
Сменный диск |
DRIVE_FIXED |
Несменный диск |
DRIVE_REMOTE |
Удалённый диск, расположен на другой машине в сети |
Основным способом задания имени файла для его открытия (или сохранения) средствами Windows является не командная строка, а диалоговые окна "Open" (для открытия файла) и "Save As" (для задания имени сохраняемого файла). Эти диалоговые окна вызываются с помощью ниже перечисленных функций:
| ФУНКЦИЯ | GetOpenFileName |
| ОПРЕДЕЛЕНА В: | commdlg.dll (<commdlg.h>) |
| СИНТАКСИС: | BOOL WINAPI GetOpenFileName( lpofn )
|
| НАЗНАЧЕНИЕ: | Вызов диалогового окна "Open…" для получения полного имени для открытия файла; |
| ОПИСАНИЕ: | Функция выводит стандартную диалоговую панель для открытия файлов. Параметры отображения считываются и заносятся в структуру OPENFILENAME ; |
| ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: | Функция возвращает ненулевое значение, если пользователь сделал выбор файла, и ноль, если он отказался от выбора, нажав кнопку "Cancel" или выбрав пункт "Close" из системного меню диалоговой панели. Нулевое значение возвращается также при возникновении ошибок; |
| ПЕРЕНОСИМОСТЬ: | Только MS Windows 3.1. На новых системах (Windows 95 и старше) она, возможно, заменена другими инструментами; |
| ФУНКЦИЯ | GetSaveFileName |
| ОПРЕДЕЛЕНА В: | commdlg.dll (<commdlg.h>) |
| СИНТАКСИС: | BOOL WINAPI GetSaveFileName( lpofn )
|
| НАЗНАЧЕНИЕ: | Вызов диалогового окна "Save As…" для получения полного имени для сохранения файла на диске; |
| ОПИСАНИЕ: | Функция выводит стандартную диалоговую панель для сохранения файлов. Параметры отображения считываются и заносятся в структуру OPENFILENAME ; |
| ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: | Функция возвращает ненулевое значение, если пользователь сделал выбор файла, и ноль, если он отказался от выбора, нажав кнопку "Cancel" или выбрав пункт "Close" из системного меню диалоговой панели. Нулевое значение возвращается также при возникновении ошибок; |
| ПЕРЕНОСИМОСТЬ: | Только MS Windows 3.1. На новых системах (Windows 95 и старше) она, возможно, заменена другими инструментами; |
Описание
Программирование на языке C++ в операционной системе Microsoft Windows условно можно разделить на "высокоуровневое" и "низкоуровневое". К "высокому уровню программирования" на языке C++ можно отнести программирование с использованием библиотеки
При программировании на "низком уровне" пользователю приходится напрямую использовать функции API Windows (что в "высокоуровневых" библиотеках делать запрещено) и "вручную заниматься" выделением памяти, созданием/освобождением/закрытием контекста устройств, описывать реакцию приложения на поступившие сообщения о нажатых клавишах, событий от мыши и
Основной функцией создаваемого приложения Microsoft Windows является функция WinMain. Эта функция - аналог функции "main" для MS-DOS. Её задача - определить класс окна, создать главное окно приложения и "присоединить к нему" функцию обработки сообщений Windows. В отличие от функции main все входящие в неё параметры обязательны.
Схематически алгоритм вызова любой функции WinMain можно описать следующим образом:
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
InitApp для регистрации приложения;"FALSE" ;"FALSE" ;msg.wParam ;Шаблон этой функции, пригодный для создания программ для текстовой обработки данных, представлен в приложениях III и так далее к данной лекции.
Для инициализации приложения Microsoft Windows используется функция InitApp. Назначение этой функции - заполнить структуру WNDCLASS и вызвать функцию регистрации класса окна. В случае неуспешной инициализации функция возвращает значение: "FALSE".
В структуре WNDCLASS заполняются следующие поля:
wc.style - один или несколько предопределённых стилей окна;wc.lpfnWndProc - указатель на функцию обработки сообщений WndProc ;wc.cbClsExtra - размер дополнительной области данных для класса окна;wc.cbWndExtra - размер дополнительной области памяти для каждого окна из данного класса;wc.hInstance - идентификатор приложения;wc.hIcon - идентификатор иконки по-умолчанию;wc.hCursor - идентификатор курсора по-умолчанию;wc.hbrBackground - цвет окна по-умолчанию;wc.lpszMenuName - идентификатор меню для данного класса приложений;wc.lpszClassName - имя класса окна (должно совпадать с классом окна для функции WinMain );Пример шаблона для описания "стандартной функции" инициализации данных в программе, обрабатывающей текстовые данные, смотри в приложении III к данной лекции.
Наконец, рассмотрим функцию WndProc, которая, как нужно особо отметить, не вызывается "явно" из основной функции WinMain, но которая, тем не менее, управляет работой всего приложения Windows. Эта функция представляет собой "описание реакции системы на системные сообщения" операционной системы Microsoft Windows. Вкратце дадим понятие системных сообщений Microsoft Windows.
"Линейная последовательность вычислений", применяемая в MS-DOS, не годится для программирования многозадачных операционных систем, таких как Windows. Во-первых, ресурсы ЭВМ при многозадачной обработке должны быть эффективно распределены между приложениями, а не предоставляться в "монопольное пользование" отдельной программе. Во-вторых, реализация реакции операционной системы MS-DOS на внешние и
Чтобы "обойти" эти недостатки, уже в конце 80-х - начале 90-х годов XX века корпорацией Microsoft был разработан механизм эффективного использования ресурсов ЭВМ на основе архитектуры x86, полностью совместимый с MS-DOS. Этот механизм был использован сначала в файловой оболочке, а затем и в операционной системе Microsoft Windows. В его реализации используются "сообщения", которые генерируются операционной системой Microsoft Windows, ставятся в очередь на исполнение и затем передаются на обработку приложениям. После обработки сообщения приложением оно возвращает результат обратно операционной системе, на основе которого вновь генерируются сообщения и т.д. Поскольку сообщения генерируются постоянно и для всех приложений, им ничего не надо делать, кроме как "слушать" WndProc.
Синтаксис функции WndProc следующий:
LRESULT CALLBACK _export WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
где
hwnd - идентификатор окна, получающего сообщение;msg - wParam - первый параметр lParam - второй параметр Среди
WM_CREATE - сообщение с этим идентификатором передаётся приложению в момент его создания;WM_PAINT - сообщение с этим номером передаётся приложению в момент "отрисовки" его главного окна;WM_COMMAND - сообщение с этим номером передаётся приложению, когда вызывается меню его главного окна (например, пользователь выбрал один из пунктов системного меню);WM_DESTROY - сообщение с этим номером передаётся системе, когда необходимо "уничтожение" окна Windows;Для описания реакции на сообщение Windows алгоритм функции WndProc пишется следующим образом:
msg ;"default". Это означает, что все сообщения, передаваемые операционной системой указанному окну, обработчик которых в программе отсутствует, должны обрабатываться операционной системой по-умолчанию. Эта конструкция обязательно должна иметь вид:default: return DefWindowProc(hwnd, msg, wParam, lParam);
Примечание. Фактически, следуя формулировкам объектно-ориентированного программирования, сообщение "WM_CREATE" является конструктором приложения Windows, сообщение "WM_DESTROY" - деструктор приложения, а все остальные сообщения являются как бы "методами" этого приложения.
Вводя и обрабатывая всё новые сообщения Microsoft Windows, мы можем наращивать функциональность операционной системы, независимо друг от друга и от "внешнего окружения" приложения Windows.
Пример "стандартного каркаса" приложения Microsoft Windows, разработанный для компиляторов Borland C/C++ версий от 3.1 до 5.5, представлен в приложении № III к данной лекции. В приложении № IV представлен пример программы для вывода текстовых строк в окно Windows. В приложениях №№ V и VI представлены те же программы, переписанные для системы Microsoft Visual Studio .Net 2003. Эти программы разработаны для 32-х битного режима Microsoft Windows и рационально используют ресурсы новых ЭВМ на основе технологий Intel и AMD.
На этой лекции Вы познакомились с описанием функций ввода-вывода данных при помощи функций WinAPI, а также с "каркасом" для построения собственных приложений средствами WinAPI. Конечно же, Вы пока не умеете работать с контекстом отображения в Windows, метриками текста и т.д., необходимых для программирования на Си в операционных системах Microsoft Windows. Но начало положено…
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.
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.
| Структура: OPENFILENAME | |
|---|---|
| Имя поля | Назначение поля структуры |
lStructSize |
Перед вызовом функций, использующих эту структуру, в это поле должен быть занесён размер структуры в байтах. |
hwndOwner |
Поле должно содержать идентификатор окна, создающего диалоговую панель. Можно указать значение NULL, при этом диалоговое окно не будет иметь окна-владельца, но в этом случае будет нельзя использовать флаг OFN_SHOWHELP. |
hInstance |
Поле hInstance используется перед вызовом функции для идентификации блока памяти, содержащего шаблон диалоговой панели. Содержимое поля игнорируется в том случае, если не указан флаг OFN_ENABLETEMPLATE или OFN_ENABLETEMPLATEHANDLE. |
lpstrFilter |
В поле должен быть указан адрес текстовой строки, задающий фильтр для выбора имён файлов (шаблоны имён файлов). Фильтр должен состоять из одной или нескольких расположенных непосредственно друг за другом пар строк, закрытых двоичным нулём. Последняя строка должна иметь на конце два двоичных нуля. Первая строка в паре строк описывает название фильтра (например, " ), а во второй строке из пары строк через знак ";" перечисляются возможные шаблоны для имён файлов. |
lpsrCustomFilter |
В поле должен быть указан адрес текстовой строки, задающий фильтр для выбора имён файлов (шаблон для выбора файлов). Фильтр должен состоять из одной расположенных непосредственно друг за другом пары строк, закрытых двоичным нулём. Последняя строка должна иметь на конце два двоичных нуля. Первая строка в паре описывает название фильтра (например, " ), а во второй строке пары через знак ";" перечисляются возможные шаблоны для имён файлов. Этот фильтр используется только в том случае, если в поле lpstrFilter содержится NULL. |
nMaxCustFilter |
Определяет размер буфера в байтах, указанного в поле lpstrCustomFile. Размер этого буфера должен быть не меньше 40 байт. |
nFilterIndex |
Поле определяет номер пары строк, используемых для фильтра, указанного в поле lpstrFilter или lpstrCustomFilter. |
lpstrFile |
Поле должно содержать адрес текстовой строки, в которую будет записан полный путь к выбранному файлу. Если перед вызовом функций, использующих эту структуру, заполнить её значением, содержащем путь к файлу, этот путь будет выбран по-умолчанию при открытии диалоговых панелей "Open…" или "Save As…" ; |
nMaxFile |
Поле должно содержать размер в байтах буфера, расположенного по адресу, указанного в поле lpstrFile. Размер этого буфера должен быть достаточным для записи полного пути к файлу. запрещает использовать для указания пути строку более 128 символов. и другие файловые системы имеют большее предельное значение "путевого имени". |
lpstrFileTitle |
В это поле необходимо записать адрес буфера, в который после выбора будет записано имя файла с расширением, но без пути к файлу. Это поле должно быть использовано приложением для отображения имени выбранного файла. |
nMaxFileTitle |
Поле должно содержать размер указанного буфера (13 для файлов MS-DOS и Windows 16, и до 255 для Windows 32/64). |
lpstrInitialDir |
Поле позволяет указать начальный каталог, который будет выбран для поиска файла сразу после отображения диалоговой панели: "Open…". Если нужно просмотреть файл в текущем каталоге, в это поле необходимо записать значение: NULL. |
lpstrTitle |
В этом поле задаётся "нестандартный" заголовок панели, появляющийся при вызове функции. Если в этом поле содержится значение "NULL", используются заголовки по-умолчанию: "Open…" и "Save As…". |
Flags |
Данное поле позволяет задать различные режимы выбора файла, влияющих на внешний вид диалоговых панелей. Описание этих флагов смотри в таблице D.4.???. |
nFileOffset |
После возврата из функции это поле будет содержать смещение первого символа имени файла относительно начала буфера lpstrFile. Это поможет Вам "разделить" имя файла и путь к нему. |
nFileExtension |
После возврата из функции это поле будет содержать смещение первого символа расширения имени файла относительно начала буфера lpstrFile. |
lpstrDefExt |
Поле указывает на буфер, который содержит расширение имени файла, используемого по-умолчанию. Это расширение добавляется к имени выбранного файла, если при выборе расширения имя указано не было. |
lCustData |
Значение, передаваемой функции фильтра через параметр lParam. |
( |
Указатель на функцию фильтра, обрабатывающую сообщения для диалоговой панели. Функция будет вызываться только в том случае, если указан флаг OFN_ENABLEHOOK. Если фильтр не обрабатывал сообщение, он должен вернуть нулевое значение. Если же он вернёт значение, отличное от нуля, стандартная функция диалога не будет обрабатывать сообщение, которое уже обработано функцией фильтра. |
lpTemplateName |
commdlg.dll. Для ссылки на ресурс можно использовать MAKEINTRESORCE. Для использования OFN_ENABLETEMPLATE. |
| Флаги структуры: OPENFILENAME | |
|---|---|
| Флаг | Описание |
OFN_ALLOWMULTISELECT |
Разрешается выбор нескольких файлов одновременно. Если указан этот флаг, после выбора поле lpstrFile будет указывать на буфер, заполненный именами выбранных файлов (или путями к выбранным файлам), разделёнными пробелом. |
OFN_CREATEPROMPT |
При использовании этого флага, если указанный файл не существует, создаётся диалоговая панель, в которой предлагается создать файл. Этот флаг устанавливается автоматически при использовании флагов OFN_PATHMUSTEXIST и OFN_FILEMUSTEXIST. |
OFN_ENABLEHOOK |
Разрешается использовать функцию фильтра, адрес которой указан в поле lpfnHook. |
OFN_ENABLETEMPLATE |
Если указан этот флаг, для создания диалоговой панели Windows будет использовать шаблон, определяемыйй содержимым полей hInstance и lpTemplateName. |
OFN_ENABLETEMPLATEHANDLE |
При использоваении этого флага поле hInstance используется для идентификации блока памяти, содержащего предварительно загруженный шаблон диалоговой панели. В этом случае содержимое поля lpTemplateName игнорируется. |
OFN_EXTENSIONDIFFERENT |
Устанавливается после возвращения из функции и указывает, что расширение файла отличается от заданного в поле lpstrDefExt. Этот флаг не устанавливается, если перед вызовом функции в поле lpstrDefExt было записано значение NULL, или если файл не имеет расширения имени. |
OFN_FILEMUSTEXIST |
Можно выбирать только имена файлов, которые существуют. Если в поле "File Name" ("Имя файла") диалоговойц панели набрать имя несуществующего файла, на экране появится диалоговая панель с предупреждающим сообщением. |
OFN_HIDEREADONLY |
Убрать переключатель "Read Only" ("Только чтение"). |
OFN_NOCHANGEDIR |
Для выбора используется каталог, который был текущем при вызове функции. |
OFN_NOREADONLYRETURN |
Выбранные файлы не могут иметь атрибут "только чтение" или располагаться в защищённом от записи каталоге. |
OFN_NOTESTFILECREATE |
Перед завершением работы диалоговой панели создание файла не выполняется. Не выполняются и проверки на переполнение диска, защиту записи или наличия доступа в сети. |
OFN_NOVALIDATE |
В возвращаемом имени файла могут присутствовать неразрешённые символы. |
OFN_OVERWRITEPROMPT |
Используется для диалоговой панели "Save as…". Если выбранный файл существует, на экран выводится диалоговая панель с предупреждением. |
OFN_PATHMUSTEXIST |
Можно вводить только существующие пути к файлам. |
OFN_READONLY |
После вызова функции переключатель "Read Only" ("Только чтение") будет находиться во включённом состоянии. |
OFN_SHAREWARE |
Флаг устанавливается после возвращения из функции и указывает, что при вызове функции OpenFile произошла ошибка при |
OFN_SHOWHELP |
Если указан этот флаг, то в диалоговой панели будет создана кнопка "Help" ("Справка"). Если указан это флаг, поле hwndOwner не должно содержать значения NULL. |
/* Файл 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
/* Файл 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);
}
/* Файл TEXTW.CPP */
/**********************************************************
* Функция WndProc
**********************************************************/
#define STRICT
#include <windows.h>
#include <stdio.h>
#include <string.h>
// Задание максимальной длины символьного буфера строки
// для вывода в окно
#ifndef SCREEN_BUFSIZE
#define SCREEN_BUFSIZE 80
#endif
// Прототип функции для печати строки символов
void Print(HDC, char *, int);
void PrintLn(void);
/**********************************************************
* cxChar -- значение ширины для самой широкой литеры
* cyChar -- max высота литеры с учётом междустрочного
* интервала.
* cxCurrentPosition -- текущая гориз. позиция вывода текста
* cyCurrentPosition -- текущая верт. позиция вывода текста
**********************************************************/
static int cxChar, cyChar;
static int cxCurrentPosition;
static int cyCurrentPosition;
LRESULT CALLBACK _export
WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
HDC hdc; // индекс контекста устройства
PAINTSTRUCT ps; // структура для рисовани
static TEXTMETRIC tm; // структура для записи метрик
// шрифта
switch (msg)
{
case WM_CREATE:
{
// Получаем контекст отображения,
// необходимый для определения метрик шрифта
hdc = GetDC(hwnd);
// Заполняем структуру информацией
// о метрике шрифта, выбранного в
// контекст отображени
GetTextMetrics(hdc, tm);
// Запоминаем значение ширины дл
// самого широкого символа
cxChar = tm.tmMaxCharWidth;
// Запоминаем значение высоты букв с
// учётом межстрочного интервала
cyChar = tm.tmHeight + tm.tmExternalLeading;
// Инициализируем текущую позицию
// вывода текста
cxCurrentPosition = cxChar;
cyCurrentPosition = cyChar;
// Освобождаем контекст
ReleaseDC(hwnd, hdc);
return 0;
}
case WM_PAINT:
{
// Инициализируем текущую позицию
// вывода текста
cxCurrentPosition = cxChar;
cyCurrentPosition = cyChar;
hdc = BeginPaint(hwnd, ps);
// Выводим последовательно строки:
Print(hdc, "Первая строка", 0); PrintLn();
Print(hdc, "Вторая строка", 0); PrintLn();
Print(hdc, "Третья строка( смещённая )", 10); PrintLn();
EndPaint(hwnd, ps);
return 0;
}
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
/**********************************************************
* Функция Print
* Функция предназначена для вывода текста
* в окно.
*
* ВХОДНЫЕ ЗНАЧЕНИЯ:
* HDC hdc -- индекс контекста устройства;
* char *str -- указатель на выводимую строку;
* int iOFFSET -- смещение горизонтальной позиции
* вывода текста в окно, указанное в символах;
*
* ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ:
* cxChar -- значение ширины для самой широкой литеры
* cyChar -- max высота литеры с учётом междустрочного
* интервала.
* cxCurrentPosition -- текущая гориз. позиция вывода текста
* cyCurrentPosition -- текущая верт. позиция вывода текста
*
* ФУНКЦИЯ ВОЗВРАЩАЕТ:
* Возвращаемых значений нет.
*
* ПРИМЕЧАНИЕ:
* Эта функция может быть переписана Вами под Ваши
* нужды для вывода не только текста, но и числовых
* значений, а также для форматирования в строке вывода.
*
**********************************************************/
void Print(HDC hdc, char *str, int iOFFSET )
{
char buf[SCREEN_BUFSIZE];
int i;
/* Проверяем смещение на неравенство единице
и корректируем его */
if( iOFFSET < 0 ) iOFFSET = 0;
// Подготавливаем в рабочем буфере
i = strlen(str);
// Проверка, что строка умещается в буфере
if( i < SCREEN_BUFSIZE - 1 )
// и выводим строку в зависимости от проверки
sprintf(buf, "%s", str);
else
sprintf(buf, "%.*s", SCREEN_BUFSIZE-1, str);
// Выводим текст в окно, начиная с текущей позиции
// вывода текста + смещение в максимальном
// количестве символов
TextOut(hdc,
cxCurrentPosition + iOFFSET * cxChar,
cyCurrentPosition,
buf, i);
}
/**********************************************************
* Функция PrintLn
* Функция предназначена для перевода на новую строку
* при выводе в окно.
*
* ВХОДНЫЕ ЗНАЧЕНИЯ:
* Не имеет.
*
* ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ:
* cxChar -- значение ширины для самой широкой литеры
* cyChar -- max высота литеры с учётом междустрочного
* интервала.
* cxCurrentPosition -- текущая гориз. позиция вывода текста
* cyCurrentPosition -- текущая верт. позиция вывода текста
*
* ФУНКЦИЯ ВОЗВРАЩАЕТ:
* Возвращаемых значений нет.
*
* ПРИМЕЧАНИЕ:
* Эта функция может быть переписана Вами под Ваши
* нужды для вывода не только текста, но и числовых
* значений, а также для форматирования в строке вывода.
*
**********************************************************/
void PrintLn( void )
{
// Увеличиваем текущую позицию по
// вертикали на высоту символа
cyCurrentPosition += cyChar;
}
/* Файл TEXTWN.DEF*/
; =============================
; Файл определения модул
; =============================
; Имя приложени
NAME TEXTWIN
; Описание приложени
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
Примечание: Для создания данного приложения средствами Microsoft Visual Studio 2008 вначале создайте "пустой проект", а затем заполните его этими файлами.
/* stdafx.cpp*/
// stdafx.cpp : исходный файл, который включает в себя стандартные заголовочные файлы.
// WINDOW.pch будет заголовком предпроцессора
// stdafx.obj будет содержать информацию предварительной компиляции
#include "stdafx.h"
// Поместите сюда всю дополнительную информацию, которая Вам нужна,
// в этот файл, а ни где-либо ещё.
/* stdafx.h */
// stdafx.h : заголовочный файл, со стандартными системными заголовочными файлами
// или специфичные для всего проекта часто используемые заголовочные файлы,
// но изменяемые не часто
//
#pragma once
#pragma once
// Измените следующие определения, если Вы используете платформу из тех, что обозначена ниже.
// Укажите MSDN последнюю информацию на соответствующее значение для разных платформ.
#ifndef WINVER // Позволяет использовать особенности, характерные для Windows XP и поздних версий.
#define WINVER 0x0501 // Измените значение на соответствующую величину текущей версии Windows.
#endif
#ifndef _WIN32_WINNT // Позволяет использовать особенности, характерные для Windows XP и поздних версий.
#define _WIN32_WINNT 0x0501 // Измените значение на соответствующую величину текущей версии Windows.
#endif
#ifndef _WIN32_WINDOWS // Позволяет использовать особенности, характерные для Windows 98 и поздних версий.
#define _WIN32_WINDOWS 0x0410 // Измените значение на соответствующую величину текущей версии Windows Me or later.
#endif
#ifndef _WIN32_IE // Позволяет использовать особенности, характерные для IE 6.0 и поздних версий.
#define _WIN32_IE 0x0600 // Измените значение на соответствующую величину текущей версии IE.
#endif
#define WIN32_LEAN_AND_MEAN // Не допущение ранее используемого наполнения из заголовка Windows.
// Заголовочный файл Windows:
#include <windows.h>
// Заголовочные файлы C RunTime
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
// TODO: разместите дополнительные заголовки модулей, необходимых для Вашего проекта, здесь
/* WINDOW.h*/
#pragma once
#include "resource.h"
/* WINDOW.cpp */
// WINDOW.cpp : Определяет точку входа для приложения.
//
#include "stdafx.h"
#include "WINDOW.h"
#define MAX_LOADSTRING 100
// Глобальные переменные:
HINSTANCE hInst; // текущий экземпляр класса
TCHAR szTitle[MAX_LOADSTRING]; // Текст главного меню
TCHAR szWindowClass[MAX_LOADSTRING]; // имя класса главного окна
// Далее идут объявления функций, включённых в модуль Code:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
// Отмена определения параметров hPrevInstance (предыдущий
// Экземпляр приложения) и lpCmdLine (командная строка)
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: Поместите свой код здесь.
MSG msg;
HACCEL hAccelTable;
// Инициализация глобальных настроек
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_WINDOW, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Подготовить инициализацию приложения:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOW));
// Основной цикл сообщений:
while (GetMessage(msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, msg))
{
TranslateMessage(msg);
DispatchMessage(msg);
}
}
return (int) msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Регистрирует класс окна.
//
// COMMENTS:
//
// Эта функция и её использование необходимо только
// в том случае, если Вы хотите, чтобы этот код
// был совместим с кодом системы Win32 прежде, чем функция 'RegisterClassEx'
// была добавлена в Windows 95. Очень важно использовать эту функцию так
// чтобы это приложение давала "правильно оформленными" иконками, ассоциированных с ними
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOW));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_WINDOW);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(wcex);
}
//
// FUNCTION: InitInstance(HINSTANCE, int)
//
//
// PURPOSE: Сохраняет экземпляр класса и создаёт основное окно
//
// COMMENTS:
//
// В этой функции мы сохраняем дескриптор экземпляр класса в глобальную переменную и
// создаёт и показывает основное окно программы..
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// PURPOSE: Обработка сообщений для главного окна.
//
// WM_COMMAND - обрабатывает меню приложени
// WM_PAINT - Рисует основное окно
// WM_DESTROY - Посылает завершающее сообщение и выход
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Сканирует раздел меню:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, ps);
// TODO: Добавьте сюда любой "рисующий" код...
EndPaint(hWnd, ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Дескриптор сообщения окна About.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
Примечание: Для создания данного приложения средствами Microsoft Visual Studio 2008 вначале создайте "пустой проект", а затем заполните его этими файлами.
/* stdafx.cpp*/
// stdafx.cpp : исходный файл, который включает в себя стандартные заголовочные файлы.
// textwin.pch будет заголовком предпроцессора
// stdafx.obj будет содержать информацию предварительной компиляции
#include "stdafx.h"
// Поместите сюда всю дополнительную информацию, которая Вам нужна,
// в этот файл, а ни где-либо
/* stdafx.h */
// stdafx.h : заголовочный файл, со стандартными системными заголовочными файлами
// или специфичные для всего проекта часто используемые заголовочные файлы,
// но изменяемые не часто
//
#pragma once
#define WIN32_LEAN_AND_MEAN // Использовать ранее использованный шаблон заголовков Windows
// Windows Заголовочный файл Windows:
#include <windows.h>
// Общие заголовки языка Си
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
// TODO: Укажите здесь дополнительные заголовочные файлы
// для Вашей программы
/* textwin.h */
#pragma once
#include "resource.h"
/* textwin.cpp*/
// textwin.cpp : Определение точек входа в программу.
//
#include "stdafx.h"
#include "textwin.h"
#define MAX_LOADSTRING 100
// Файлы с описанием функций
#ifndef __STDIO_H
#include <stdio.h>
#endif
#ifndef __STRING_H
#include <string.h>
#endif
/* Глобальные константы */
// Задание максимальной длины символьного буфера строки
// для вывода в окно
#ifndef SCREEN_BUFSIZE
#define SCREEN_BUFSIZE 80
#endif
// Прототип функции для печати строки символов
void Print(HDC, char *, int);
void PrintLn(void);
/* Глобальные переменные */
/**********************************************************
* cxChar -- значение ширины для самой широкой литеры
* cyChar -- max высота литеры с учётом междустрочного
* интервала.
* cxCurrentPosition -- текущая гориз. позиция вывода текста
* cyCurrentPosition -- текущая верт. позиция вывода текста
**********************************************************/
static int cxChar, cyChar;
static int cxCurrentPosition;
static int cyCurrentPosition;
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
// Далее находятся описания функций, включённых в модули кода
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
// TODO: Поместите код здесь
MSG msg;
HACCEL hAccelTable;
// Инициализация глобальных строк
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_TEXTWIN, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Подготовка к инициализации приложения:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_TEXTWIN);
// Основной цикл сообщений:
while (GetMessage(msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, msg))
{
TranslateMessage(msg);
DispatchMessage(msg);
}
}
return (int) msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Регистрация класса окна.
//
// COMMENTS:
//
// Эта функция и её использование необходима только
// в том случае, если Вы хотите, чтобы этот код
// был совместим с кодом системы Win32 прежде, чем функция 'RegisterClassEx'
// была добавлена в Windows 95. Очень важно использовать эту функцию так
// чтобы это приложение давала "правильно оформленными" иконками, ассоциированных с ними
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_TEXTWIN);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = (LPCTSTR)IDC_TEXTWIN;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
return RegisterClassEx(wcex);
}
//
// FUNCTION: InitInstance(HANDLE, int)
//
// PURPOSE: Сохраняет экземпляр класса и создаёт основное окно
//
// COMMENTS:
//
// В этой функции мы сохраняем дескриптор экземпляр класса в глобальную переменную и
// создаём и показываем основное окно программы..
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Сохраняем дескриптор экземпляра класса // в нашу глобальную переменную
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Обработка сообщений для главного окна.
//
// WM_COMMAND - обрабатывает меню приложени
// WM_PAINT - Рисует основное окно
// WM_DESTROY - Посылает завершающее сообщение и выход
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps; // структура для рисовани
HDC hdc; // индекс контекста устройства
static TEXTMETRIC tm; // структура для записи метрик
// шрифта
switch (message)
{
case WM_CREATE:
{
// Получаем контекст отображения,
// необходимый для определения метрик шрифта
hdc = GetDC(hWnd);
// Заполняем структуру информацией
// о метрике шрифта, выбранного в
// контекст отображени
GetTextMetrics(hdc, tm);
// Запоминаем значение ширины дл
// самого широкого символа
cxChar = tm.tmMaxCharWidth;
// Запоминаем значение высоты букв с
// учётом межстрочного интервала
cyChar = tm.tmHeight + tm.tmExternalLeading;
// Инициализируем текущую позицию
// вывода текста
cxCurrentPosition = cxChar;
cyCurrentPosition = cyChar;
// Освобождаем контекст
ReleaseDC(hWnd, hdc);
return 0;
}
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Сканируем секцию меню:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, ps);
// TODO: Добавляем код для рисования здесь...
// Инициализируем текущую позицию
// вывода текста
cxCurrentPosition = cxChar;
cyCurrentPosition = cyChar;
// Выводим последовательно строки:
Print(hdc, "Первая строка", 0); PrintLn();
Print(hdc, "Вторая строка", 0); PrintLn();
Print(hdc, "Третья строка( смещённая )", 10); PrintLn();
EndPaint(hWnd, ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Дескриптор диалогового окна сообщения: About.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
/**********************************************************
* Функция Print
* Функция предназначена для вывода текста
* в окно.
*
* ВХОДНЫЕ ЗНАЧЕНИЯ:
* HDC hdc -- индекс контекста устройства;
* char *str -- указатель на выводимую строку;
* int iOFFSET -- смещение горизонтальной позиции
* вывода текста в окно, указанное в символах;
*
* ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ:
* cxChar -- значение ширины для самой широкой литеры
* cyChar -- max высота литеры с учётом междустрочного
* интервала.
* cxCurrentPosition -- текущая гориз. позиция вывода текста
* cyCurrentPosition -- текущая верт. позиция вывода текста
*
* ФУНКЦИЯ ВОЗВРАЩАЕТ:
* Возвращаемых значений нет.
*
* ПРИМЕЧАНИЕ:
* Эта функция может быть переписана Вами под Ваши
* нужды для вывода не только текста, но и числовых
* значений, а также для форматирования в строке вывода.
*
**********************************************************/
void Print(HDC hdc, char *str, int iOFFSET )
{
char buf[SCREEN_BUFSIZE];
int i;
/* Проверяем смещение на неравенство единице
и корректируем его */
if( iOFFSET < 0 ) iOFFSET = 0;
// Подготавливаем в рабочем буфере
i = strlen(str);
// Проверка, что строка умещается в буфере
if( i < SCREEN_BUFSIZE - 1 )
// и выводим строку в зависимости от проверки
sprintf(buf, "%s", str);
else
sprintf(buf, "%.*s", SCREEN_BUFSIZE-1, str);
// Выводим текст в окно, начиная с текущей позиции
// вывода текста + смещение в максимальном
// количестве символов
TextOut(hdc,
cxCurrentPosition + iOFFSET * cxChar,
cyCurrentPosition,
buf, i);
}
/**********************************************************
* Функция PrintLn
* Функция предназначена для перевода на новую строку
* при выводе в окно.
*
* ВХОДНЫЕ ЗНАЧЕНИЯ:
* Не имеет.
*
* ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ:
* cxChar -- значение ширины для самой широкой литеры
* cyChar -- max высота литеры с учётом междустрочного
* интервала.
* cxCurrentPosition -- текущая гориз. позиция вывода текста
* cyCurrentPosition -- текущая верт. позиция вывода текста
*
* ФУНКЦИЯ ВОЗВРАЩАЕТ:
* Возвращаемых значений нет.
*
* ПРИМЕЧАНИЕ:
* Эта функция может быть переписана Вами под Ваши
* нужды для вывода не только текста, но и числовых
* значений, а также для форматирования в строке вывода.
*
**********************************************************/
void PrintLn( void )
{
// Увеличиваем текущую позицию по
// вертикали на высоту символа
cyCurrentPosition += cyChar;
}
Файловые операции в операционной системе Microsoft Windows отличаются от файловых операций MS-DOS следующим:
fges, getc, fscanf и др.). Используемый в Windows способ чтения-записи является более "безопасным" для обработчика данных и операционной системы;Примечание: операции потокового вывода на экран и ввода с клавиатуры можно также осуществить и в Windows, указав опцию в IDE при создании проекта "консольное приложение Windows". Этот вопрос Вы можете изучить самостоятельно [38].
Для создания, открытия и закрытия файлов Windows API использует следующие функции:
| ФУНКЦИЯ | OpenFile |
| СИНТАКСИС: | HFILE WINAPI OpenFile( lpszFileName, lpOpenStruct, fuMode)
|
| НАЗНАЧЕНИЕ: | Открывает файл и связывает с ним |
| ОПИСАНИЕ: | Функция предназначена для создания, открытия, повторного открытия и удаления файлов. В имени файла допускается указывать символы шаблона, такие как "*" и "?". Параметр fuMode используется для определения действий, выполняемых функцией OpenFile, а также задаёт атрибуты файла. Когда функция OpenFile вызывается в первый раз для открытия файла, она заполняет структуру OFSTRUCT, описанную в приложении №1 (смотри пункт 9.4 данной лекции); |
| ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: | Функция возвращает идентификатор файла, который можно (и нужно) использовать во всех последующих операциях с файлом, или -1 при ошибке; |
| ПЕРЕНОСИМОСТЬ: | Версии MS Windows 3.0 и старше; |
| ФУНКЦИЯ | _lopen |
| СИНТАКСИС: | HFILE WINAPI _lopen( LPCSTR lpszFileName, int fuOpenMode)
|
| НАЗНАЧЕНИЕ: | Открывает файл и связывает с ним |
| ОПИСАНИЕ: | Функция предназначена для открытия, повторного открытия файлов. В имени файла допускается указывать символы шаблона, такие как "*" и "?". Параметр fuMode используется для определения действий, выполняемых функцией _lopen ; |
| ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: | Функция возвращает идентификатор файла, который можно (и нужно) использовать во всех последующих операциях с файлом, или HFILE_ERROR при ошибке; |
| ПЕРЕНОСИМОСТЬ: | Версии MS Windows 3.0 и старше; |
| ФУНКЦИЯ | _lclose |
| СИНТАКСИС: | HFILE WINAPI _lclose( hf )
|
| НАЗНАЧЕНИЕ: | Закрывает файл, связанный с соответствующим дескриптором; |
| ОПИСАНИЕ: | Закрывает файл с дескриптором hf ; |
| ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: | Если файл закрыт успешно, _lclose возвращает нулевое значение. При ошибке возвращается значение: HFILE_ERROR ; |
| ПЕРЕНОСИМОСТЬ: | Версии MS Windows 3.0 и старше; |
| ФУНКЦИЯ | _lcreat |
| СИНТАКСИС: | HFILE _lcreat( lpszFileName, fuAttribute)
|
| НАЗНАЧЕНИЕ: | Создаёт файл средствами Win API; |
| ОПИСАНИЕ: | Это более простая, чем OpenFile, функция для создания новых файлов. Имя файла не должно содержать метасимволов шаблона. Если указанный первым параметром файл не существует, функция _lcreat создаёт его и открывает для записи, возвращая его |
| ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: | Идентификатор созданного файла; |
| ПЕРЕНОСИМОСТЬ: | Версии MS Windows 3.0 и старше; |
Отличие функции OpenFile от функции _lopen заключается в поддержке ей расширенной информации о файле, передаваемой структуре OFSTRUCT, и в большем числе поддерживаемых флагов команды. Информацию о флагах функций OpenFile, _lcreate и _lopen смотри в таблице 9.1. Описание функций смотри в приложении №I к данной лекции (пункт 9.4).
| Константа | Описание |
|---|---|
| ФУНКЦИЯ OpenFile | |
OF_READ |
Файл открывается только для чтения. |
OF_WRITE |
Файл открывается только для записи. |
OF_READWRITE |
Файл открывается для чтения и записи. |
OF_SHARE_COMPAT |
Открытие файла в режиме совместимости. В этом режиме несколько приложений могут одновременно открыть файл, причём все эти приложения должны открывать файл в режиме совместимости. |
OF_SHARE_EXCLUSIVE |
Файл открывается в монопольном режиме. Для всех других приложений доступ к этому файлу на чтение и запись запрещён. |
OF_SHARE_DENY_WRITE |
После открытия файла к нему запрещается доступ со стороны других приложений на запись. |
OF_SHARE_DENY_READ |
После открытия файла к нему запрещается доступ со стороны других приложений на чтение. |
OF_SHARE_DENY_NONE |
Для открываемого файла не запрещается доступ к файлу ни на чтение, ни на запись. |
OF_PARSE |
Если указан этот флаг, функция OpenFile не выполняет никаких других действий, кроме заполнения структуры OFSTRUCT. |
OF_DELETE |
Уничтожение существующего файла. |
OF_VERIFY |
Если указан этот флаг, то функция OpenFile сравнивает время и дату, записанную в структуре OFSTRUCT, со временем и датой изменений указанного файла. Если обнаружено несоответствие, функция OpenFile возвращает значение HFILE_ERROR. |
OF_SEARCH |
Операционная система выполняет поиск файла в каталогах даже в том случае, когда текстовая строка, указанная параметром lpszFileName, содержит полный путь к файлу. |
OF_PROMPT |
Если указан этот флаг, то в случае невозможности найти указанный файл Windows выдаёт диалоговую панель с предложением вставить в дисковод A: дискету с файлом. Это флаг используется очень редко. |
OF_CANCEL |
Данный флаг указывается вместе с флагом OF_PROMPT. Если он указан, то в описанную выше диалоговую панель будет добавлена кнопка "Cancel" для отмены открытия файла. Приложение при этом получит код ошибки, соответствующий ненайденному файлу, а пользователь – возможность выйти из затруднительного положения, в которое он попадает при отсутствии дискеты с нужным файлом. |
OF_CREATE |
выполняется создание нового файла. Если указанный файл существует, то он обрезается до нулевой длины. |
OF_EXIST |
При указании этого флага функция OpenFile вначале открывает файл, а потом сразу же его закрывает. Эта операция может быть использована для того, чтобы убедиться в существовании указанного файла на диске. |
OF_REOPEN |
Этот флаг используется при повторном открытии файла на основе информации, хранящейся в структуре OFSTRUCT. |
| ФУНКЦИЯ _lopen | |
OF_READ |
Файл открывается только для чтения. |
OF_WRITE |
Файл открывается только для записи. |
OF_READWRITE |
Файл открывается для чтения и записи. |
OF_SHARE_COMPAT |
Открытие файла в режиме совместимости. В этом режиме несколько приложений могут одновременно открыть файл, причём все эти приложения должны открывать файл в режиме совместимости. |
OF_SHARE_EXCLUSIVE |
Файл открывается в монопольном режиме. Для всех других приложений доступ к этому файлу на чтение и запись запрещён. |
OF_SHARE_DENY_WRITE |
После открытия файла к нему запрещается доступ со стороны других приложений на запись. |
OF_SHARE_DENY_READ |
После открытия файла к нему запрещается доступ со стороны других приложений на чтение. |
OF_SHARE_DENY_NONE |
Для открываемого файла не запрещается доступ к файлу ни на чтение, ни на запись. |
| ФУНКЦИЯ _lcreat | |
0 |
Нормальный файл, для которого разрешено выполнение операций чтения и записи |
1 |
Этот файл можно открыть только для чтения |
2 |
|
3 |
Системный файл |
Для операций чтения-записи в файл Microsoft Windows применяются следующие функции:
| ФУНКЦИЯ | _lread |
| СИНТАКСИС: | UINT WINAPI _lread( hf, hpvBuffer, cbBuffer )
|
| НАЗНАЧЕНИЕ: | Функция читает содержимое файла, определённого дескриптором, в текстовый буфер. Размер буфера ограничен 64 Кбайт; |
| ОПИСАНИЕ: | Функция предназначена для чтения информации из файла в буфер памяти. Через параметр hf функции следует передать идентификатор файла, для которого необходимо сделать операцию чтения. Прочитанные данные будут записаны в буфер hpvBuffer, имеющий размер cbBuffer байт. Этот буфер можно получить динамически, вызвав, например, функцию GlobalAlloc или, что лучше с точки зрения совместимости, LocalAlloc. Размер буфера не должен превышать 65 534 байт. |
| ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: | Функция возвращает количество байт данных, прочитанных из файла. Возвращённое значение может быть меньше затребованного в параметре cbBuffer, если достигнут конец файла. При ошибке функция возвращает значение HFILE_ERROR. |
| ПЕРЕНОСИМОСТЬ: | MS Windows 3.0 и старше; |
| ФУНКЦИЯ | _hread |
| СИНТАКСИС: | long WINAPI _hread( hf, hpvBuffer, cbBuffer )
|
| НАЗНАЧЕНИЕ: | Функция читает содержимое файла, определённого дескриптором, в текстовый буфер. Размер буфера ограничен 2 Гбайт; |
| ОПИСАНИЕ: | Функция предназначена для чтения информации из файла в буфер памяти. Через параметр hf функции следует передать идентификатор файла, для которого необходимо сделать операцию чтения. Прочитанные данные будут записаны в буфер hpvBuffer, имеющий размер cbBuffer байт. Этот буфер можно получить динамически, вызвав функцию GlobalAlloc ; |
| ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: | Функция возвращает количество байт данных, прочитанных из файла. Возвращённое значение может быть меньше затребованного в параметре cbBuffer, если достигнут конец файла. При ошибке функция возвращает значение HFILE_ERROR. |
| ПЕРЕНОСИМОСТЬ: | MS Windows 3.1 и старше; |
| ФУНКЦИЯ | _lwrite |
| СИНТАКСИС: | UINT WINAPI _hread( hf, hpvBuffer, cbBuffer )
|
| НАЗНАЧЕНИЕ: | Функция записывает содержимое текстового буфера в файл, определённого дескриптором. Размер буфера ограничен 64 Кбайт; |
| ОПИСАНИЕ: | Назначение параметров этой функции аналогично назначению параметров функции _lread, Перед вызовом функции _lwrite буфер должен содержать данные, записываемые в файл; |
| ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: | Функция возвращает количество байт данных, записанных в файл, или значение HFILE_ERROR при ошибке; |
| ПЕРЕНОСИМОСТЬ: | MS Windows 3.0 и старше; |
| ФУНКЦИЯ | _hwrite |
| СИНТАКСИС: | long WINAPI _hread( hf, hpvBuffer, cbBuffer )
|
| НАЗНАЧЕНИЕ: | Функция записывает содержимое текстового буфера в файл, определённого дескриптором. Размер буфера ограничен 2 Гбайт; |
| ОПИСАНИЕ: | Назначение параметров этой функции аналогично назначению параметров функции _hread, Перед вызовом функции _lwrite буфер должен содержать данные, записываемые в файл; |
| ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: | Функция возвращает количество байт данных, записанных в файл, или значение HFILE_ERROR при ошибке; |
| ПЕРЕНОСИМОСТЬ: | MS Windows 3.1 и старше; |
| ФУНКЦИЯ | GetDriveType |
| СИНТАКСИС: | UINT WINAPI GetDriveType( DriveNumber )
|
| НАЗНАЧЕНИЕ: | Позволяет определить тип и расположение используемого дискового |
| ОПИСАНИЕ: | Иногда требуется определить тип и расположение используемого |
| ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: | Функция может вернуть нуль при ошибке или одно их следующих значений (смотри таблицу 9.2); |
| ПЕРЕНОСИМОСТЬ: | MS Windows 3.0 и старше; |
| Константа | Описание |
|---|---|
| ФУНКЦИЯ GetDriveType | |
DRIVE_REMOVABLE |
Сменный диск |
DRIVE_FIXED |
Несменный диск |
DRIVE_REMOTE |
Удалённый диск, расположен на другой машине в сети |
Основным способом задания имени файла для его открытия (или сохранения) средствами Windows является не командная строка, а диалоговые окна "Open" (для открытия файла) и "Save As" (для задания имени сохраняемого файла). Эти диалоговые окна вызываются с помощью ниже перечисленных функций:
| ФУНКЦИЯ | GetOpenFileName |
| ОПРЕДЕЛЕНА В: | commdlg.dll (<commdlg.h>) |
| СИНТАКСИС: | BOOL WINAPI GetOpenFileName( lpofn )
|
| НАЗНАЧЕНИЕ: | Вызов диалогового окна "Open…" для получения полного имени для открытия файла; |
| ОПИСАНИЕ: | Функция выводит стандартную диалоговую панель для открытия файлов. Параметры отображения считываются и заносятся в структуру OPENFILENAME ; |
| ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: | Функция возвращает ненулевое значение, если пользователь сделал выбор файла, и ноль, если он отказался от выбора, нажав кнопку "Cancel" или выбрав пункт "Close" из системного меню диалоговой панели. Нулевое значение возвращается также при возникновении ошибок; |
| ПЕРЕНОСИМОСТЬ: | Только MS Windows 3.1. На новых системах (Windows 95 и старше) она, возможно, заменена другими инструментами; |
| ФУНКЦИЯ | GetSaveFileName |
| ОПРЕДЕЛЕНА В: | commdlg.dll (<commdlg.h>) |
| СИНТАКСИС: | BOOL WINAPI GetSaveFileName( lpofn )
|
| НАЗНАЧЕНИЕ: | Вызов диалогового окна "Save As…" для получения полного имени для сохранения файла на диске; |
| ОПИСАНИЕ: | Функция выводит стандартную диалоговую панель для сохранения файлов. Параметры отображения считываются и заносятся в структуру OPENFILENAME ; |
| ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: | Функция возвращает ненулевое значение, если пользователь сделал выбор файла, и ноль, если он отказался от выбора, нажав кнопку "Cancel" или выбрав пункт "Close" из системного меню диалоговой панели. Нулевое значение возвращается также при возникновении ошибок; |
| ПЕРЕНОСИМОСТЬ: | Только MS Windows 3.1. На новых системах (Windows 95 и старше) она, возможно, заменена другими инструментами; |
Описание
Программирование на языке C++ в операционной системе Microsoft Windows условно можно разделить на "высокоуровневое" и "низкоуровневое". К "высокому уровню программирования" на языке C++ можно отнести программирование с использованием библиотеки
При программировании на "низком уровне" пользователю приходится напрямую использовать функции API Windows (что в "высокоуровневых" библиотеках делать запрещено) и "вручную заниматься" выделением памяти, созданием/освобождением/закрытием контекста устройств, описывать реакцию приложения на поступившие сообщения о нажатых клавишах, событий от мыши и
Основной функцией создаваемого приложения Microsoft Windows является функция WinMain. Эта функция - аналог функции "main" для MS-DOS. Её задача - определить класс окна, создать главное окно приложения и "присоединить к нему" функцию обработки сообщений Windows. В отличие от функции main все входящие в неё параметры обязательны.
Схематически алгоритм вызова любой функции WinMain можно описать следующим образом:
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
InitApp для регистрации приложения;"FALSE" ;"FALSE" ;msg.wParam ;Шаблон этой функции, пригодный для создания программ для текстовой обработки данных, представлен в приложениях III и так далее к данной лекции.
Для инициализации приложения Microsoft Windows используется функция InitApp. Назначение этой функции - заполнить структуру WNDCLASS и вызвать функцию регистрации класса окна. В случае неуспешной инициализации функция возвращает значение: "FALSE".
В структуре WNDCLASS заполняются следующие поля:
wc.style - один или несколько предопределённых стилей окна;wc.lpfnWndProc - указатель на функцию обработки сообщений WndProc ;wc.cbClsExtra - размер дополнительной области данных для класса окна;wc.cbWndExtra - размер дополнительной области памяти для каждого окна из данного класса;wc.hInstance - идентификатор приложения;wc.hIcon - идентификатор иконки по-умолчанию;wc.hCursor - идентификатор курсора по-умолчанию;wc.hbrBackground - цвет окна по-умолчанию;wc.lpszMenuName - идентификатор меню для данного класса приложений;wc.lpszClassName - имя класса окна (должно совпадать с классом окна для функции WinMain );Пример шаблона для описания "стандартной функции" инициализации данных в программе, обрабатывающей текстовые данные, смотри в приложении III к данной лекции.
Наконец, рассмотрим функцию WndProc, которая, как нужно особо отметить, не вызывается "явно" из основной функции WinMain, но которая, тем не менее, управляет работой всего приложения Windows. Эта функция представляет собой "описание реакции системы на системные сообщения" операционной системы Microsoft Windows. Вкратце дадим понятие системных сообщений Microsoft Windows.
"Линейная последовательность вычислений", применяемая в MS-DOS, не годится для программирования многозадачных операционных систем, таких как Windows. Во-первых, ресурсы ЭВМ при многозадачной обработке должны быть эффективно распределены между приложениями, а не предоставляться в "монопольное пользование" отдельной программе. Во-вторых, реализация реакции операционной системы MS-DOS на внешние и
Чтобы "обойти" эти недостатки, уже в конце 80-х - начале 90-х годов XX века корпорацией Microsoft был разработан механизм эффективного использования ресурсов ЭВМ на основе архитектуры x86, полностью совместимый с MS-DOS. Этот механизм был использован сначала в файловой оболочке, а затем и в операционной системе Microsoft Windows. В его реализации используются "сообщения", которые генерируются операционной системой Microsoft Windows, ставятся в очередь на исполнение и затем передаются на обработку приложениям. После обработки сообщения приложением оно возвращает результат обратно операционной системе, на основе которого вновь генерируются сообщения и т.д. Поскольку сообщения генерируются постоянно и для всех приложений, им ничего не надо делать, кроме как "слушать" WndProc.
Синтаксис функции WndProc следующий:
LRESULT CALLBACK _export WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
где
hwnd - идентификатор окна, получающего сообщение;msg - wParam - первый параметр lParam - второй параметр Среди
WM_CREATE - сообщение с этим идентификатором передаётся приложению в момент его создания;WM_PAINT - сообщение с этим номером передаётся приложению в момент "отрисовки" его главного окна;WM_COMMAND - сообщение с этим номером передаётся приложению, когда вызывается меню его главного окна (например, пользователь выбрал один из пунктов системного меню);WM_DESTROY - сообщение с этим номером передаётся системе, когда необходимо "уничтожение" окна Windows;Для описания реакции на сообщение Windows алгоритм функции WndProc пишется следующим образом:
msg ;"default". Это означает, что все сообщения, передаваемые операционной системой указанному окну, обработчик которых в программе отсутствует, должны обрабатываться операционной системой по-умолчанию. Эта конструкция обязательно должна иметь вид:default: return DefWindowProc(hwnd, msg, wParam, lParam);
Примечание. Фактически, следуя формулировкам объектно-ориентированного программирования, сообщение "WM_CREATE" является конструктором приложения Windows, сообщение "WM_DESTROY" - деструктор приложения, а все остальные сообщения являются как бы "методами" этого приложения.
Вводя и обрабатывая всё новые сообщения Microsoft Windows, мы можем наращивать функциональность операционной системы, независимо друг от друга и от "внешнего окружения" приложения Windows.
Пример "стандартного каркаса" приложения Microsoft Windows, разработанный для компиляторов Borland C/C++ версий от 3.1 до 5.5, представлен в приложении № III к данной лекции. В приложении № IV представлен пример программы для вывода текстовых строк в окно Windows. В приложениях №№ V и VI представлены те же программы, переписанные для системы Microsoft Visual Studio .Net 2003. Эти программы разработаны для 32-х битного режима Microsoft Windows и рационально используют ресурсы новых ЭВМ на основе технологий Intel и AMD.
На этой лекции Вы познакомились с описанием функций ввода-вывода данных при помощи функций WinAPI, а также с "каркасом" для построения собственных приложений средствами WinAPI. Конечно же, Вы пока не умеете работать с контекстом отображения в Windows, метриками текста и т.д., необходимых для программирования на Си в операционных системах Microsoft Windows. Но начало положено…
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.
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.
| Структура: OPENFILENAME | |
|---|---|
| Имя поля | Назначение поля структуры |
lStructSize |
Перед вызовом функций, использующих эту структуру, в это поле должен быть занесён размер структуры в байтах. |
hwndOwner |
Поле должно содержать идентификатор окна, создающего диалоговую панель. Можно указать значение NULL, при этом диалоговое окно не будет иметь окна-владельца, но в этом случае будет нельзя использовать флаг OFN_SHOWHELP. |
hInstance |
Поле hInstance используется перед вызовом функции для идентификации блока памяти, содержащего шаблон диалоговой панели. Содержимое поля игнорируется в том случае, если не указан флаг OFN_ENABLETEMPLATE или OFN_ENABLETEMPLATEHANDLE. |
lpstrFilter |
В поле должен быть указан адрес текстовой строки, задающий фильтр для выбора имён файлов (шаблоны имён файлов). Фильтр должен состоять из одной или нескольких расположенных непосредственно друг за другом пар строк, закрытых двоичным нулём. Последняя строка должна иметь на конце два двоичных нуля. Первая строка в паре строк описывает название фильтра (например, " ), а во второй строке из пары строк через знак ";" перечисляются возможные шаблоны для имён файлов. |
lpsrCustomFilter |
В поле должен быть указан адрес текстовой строки, задающий фильтр для выбора имён файлов (шаблон для выбора файлов). Фильтр должен состоять из одной расположенных непосредственно друг за другом пары строк, закрытых двоичным нулём. Последняя строка должна иметь на конце два двоичных нуля. Первая строка в паре описывает название фильтра (например, " ), а во второй строке пары через знак ";" перечисляются возможные шаблоны для имён файлов. Этот фильтр используется только в том случае, если в поле lpstrFilter содержится NULL. |
nMaxCustFilter |
Определяет размер буфера в байтах, указанного в поле lpstrCustomFile. Размер этого буфера должен быть не меньше 40 байт. |
nFilterIndex |
Поле определяет номер пары строк, используемых для фильтра, указанного в поле lpstrFilter или lpstrCustomFilter. |
lpstrFile |
Поле должно содержать адрес текстовой строки, в которую будет записан полный путь к выбранному файлу. Если перед вызовом функций, использующих эту структуру, заполнить её значением, содержащем путь к файлу, этот путь будет выбран по-умолчанию при открытии диалоговых панелей "Open…" или "Save As…" ; |
nMaxFile |
Поле должно содержать размер в байтах буфера, расположенного по адресу, указанного в поле lpstrFile. Размер этого буфера должен быть достаточным для записи полного пути к файлу. запрещает использовать для указания пути строку более 128 символов. и другие файловые системы имеют большее предельное значение "путевого имени". |
lpstrFileTitle |
В это поле необходимо записать адрес буфера, в который после выбора будет записано имя файла с расширением, но без пути к файлу. Это поле должно быть использовано приложением для отображения имени выбранного файла. |
nMaxFileTitle |
Поле должно содержать размер указанного буфера (13 для файлов MS-DOS и Windows 16, и до 255 для Windows 32/64). |
lpstrInitialDir |
Поле позволяет указать начальный каталог, который будет выбран для поиска файла сразу после отображения диалоговой панели: "Open…". Если нужно просмотреть файл в текущем каталоге, в это поле необходимо записать значение: NULL. |
lpstrTitle |
В этом поле задаётся "нестандартный" заголовок панели, появляющийся при вызове функции. Если в этом поле содержится значение "NULL", используются заголовки по-умолчанию: "Open…" и "Save As…". |
Flags |
Данное поле позволяет задать различные режимы выбора файла, влияющих на внешний вид диалоговых панелей. Описание этих флагов смотри в таблице D.4.???. |
nFileOffset |
После возврата из функции это поле будет содержать смещение первого символа имени файла относительно начала буфера lpstrFile. Это поможет Вам "разделить" имя файла и путь к нему. |
nFileExtension |
После возврата из функции это поле будет содержать смещение первого символа расширения имени файла относительно начала буфера lpstrFile. |
lpstrDefExt |
Поле указывает на буфер, который содержит расширение имени файла, используемого по-умолчанию. Это расширение добавляется к имени выбранного файла, если при выборе расширения имя указано не было. |
lCustData |
Значение, передаваемой функции фильтра через параметр lParam. |
( |
Указатель на функцию фильтра, обрабатывающую сообщения для диалоговой панели. Функция будет вызываться только в том случае, если указан флаг OFN_ENABLEHOOK. Если фильтр не обрабатывал сообщение, он должен вернуть нулевое значение. Если же он вернёт значение, отличное от нуля, стандартная функция диалога не будет обрабатывать сообщение, которое уже обработано функцией фильтра. |
lpTemplateName |
commdlg.dll. Для ссылки на ресурс можно использовать MAKEINTRESORCE. Для использования OFN_ENABLETEMPLATE. |
| Флаги структуры: OPENFILENAME | |
|---|---|
| Флаг | Описание |
OFN_ALLOWMULTISELECT |
Разрешается выбор нескольких файлов одновременно. Если указан этот флаг, после выбора поле lpstrFile будет указывать на буфер, заполненный именами выбранных файлов (или путями к выбранным файлам), разделёнными пробелом. |
OFN_CREATEPROMPT |
При использовании этого флага, если указанный файл не существует, создаётся диалоговая панель, в которой предлагается создать файл. Этот флаг устанавливается автоматически при использовании флагов OFN_PATHMUSTEXIST и OFN_FILEMUSTEXIST. |
OFN_ENABLEHOOK |
Разрешается использовать функцию фильтра, адрес которой указан в поле lpfnHook. |
OFN_ENABLETEMPLATE |
Если указан этот флаг, для создания диалоговой панели Windows будет использовать шаблон, определяемыйй содержимым полей hInstance и lpTemplateName. |
OFN_ENABLETEMPLATEHANDLE |
При использоваении этого флага поле hInstance используется для идентификации блока памяти, содержащего предварительно загруженный шаблон диалоговой панели. В этом случае содержимое поля lpTemplateName игнорируется. |
OFN_EXTENSIONDIFFERENT |
Устанавливается после возвращения из функции и указывает, что расширение файла отличается от заданного в поле lpstrDefExt. Этот флаг не устанавливается, если перед вызовом функции в поле lpstrDefExt было записано значение NULL, или если файл не имеет расширения имени. |
OFN_FILEMUSTEXIST |
Можно выбирать только имена файлов, которые существуют. Если в поле "File Name" ("Имя файла") диалоговойц панели набрать имя несуществующего файла, на экране появится диалоговая панель с предупреждающим сообщением. |
OFN_HIDEREADONLY |
Убрать переключатель "Read Only" ("Только чтение"). |
OFN_NOCHANGEDIR |
Для выбора используется каталог, который был текущем при вызове функции. |
OFN_NOREADONLYRETURN |
Выбранные файлы не могут иметь атрибут "только чтение" или располагаться в защищённом от записи каталоге. |
OFN_NOTESTFILECREATE |
Перед завершением работы диалоговой панели создание файла не выполняется. Не выполняются и проверки на переполнение диска, защиту записи или наличия доступа в сети. |
OFN_NOVALIDATE |
В возвращаемом имени файла могут присутствовать неразрешённые символы. |
OFN_OVERWRITEPROMPT |
Используется для диалоговой панели "Save as…". Если выбранный файл существует, на экран выводится диалоговая панель с предупреждением. |
OFN_PATHMUSTEXIST |
Можно вводить только существующие пути к файлам. |
OFN_READONLY |
После вызова функции переключатель "Read Only" ("Только чтение") будет находиться во включённом состоянии. |
OFN_SHAREWARE |
Флаг устанавливается после возвращения из функции и указывает, что при вызове функции OpenFile произошла ошибка при |
OFN_SHOWHELP |
Если указан этот флаг, то в диалоговой панели будет создана кнопка "Help" ("Справка"). Если указан это флаг, поле hwndOwner не должно содержать значения NULL. |
/* Файл 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
/* Файл 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);
}
/* Файл TEXTW.CPP */
/**********************************************************
* Функция WndProc
**********************************************************/
#define STRICT
#include <windows.h>
#include <stdio.h>
#include <string.h>
// Задание максимальной длины символьного буфера строки
// для вывода в окно
#ifndef SCREEN_BUFSIZE
#define SCREEN_BUFSIZE 80
#endif
// Прототип функции для печати строки символов
void Print(HDC, char *, int);
void PrintLn(void);
/**********************************************************
* cxChar -- значение ширины для самой широкой литеры
* cyChar -- max высота литеры с учётом междустрочного
* интервала.
* cxCurrentPosition -- текущая гориз. позиция вывода текста
* cyCurrentPosition -- текущая верт. позиция вывода текста
**********************************************************/
static int cxChar, cyChar;
static int cxCurrentPosition;
static int cyCurrentPosition;
LRESULT CALLBACK _export
WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
HDC hdc; // индекс контекста устройства
PAINTSTRUCT ps; // структура для рисовани
static TEXTMETRIC tm; // структура для записи метрик
// шрифта
switch (msg)
{
case WM_CREATE:
{
// Получаем контекст отображения,
// необходимый для определения метрик шрифта
hdc = GetDC(hwnd);
// Заполняем структуру информацией
// о метрике шрифта, выбранного в
// контекст отображени
GetTextMetrics(hdc, tm);
// Запоминаем значение ширины дл
// самого широкого символа
cxChar = tm.tmMaxCharWidth;
// Запоминаем значение высоты букв с
// учётом межстрочного интервала
cyChar = tm.tmHeight + tm.tmExternalLeading;
// Инициализируем текущую позицию
// вывода текста
cxCurrentPosition = cxChar;
cyCurrentPosition = cyChar;
// Освобождаем контекст
ReleaseDC(hwnd, hdc);
return 0;
}
case WM_PAINT:
{
// Инициализируем текущую позицию
// вывода текста
cxCurrentPosition = cxChar;
cyCurrentPosition = cyChar;
hdc = BeginPaint(hwnd, ps);
// Выводим последовательно строки:
Print(hdc, "Первая строка", 0); PrintLn();
Print(hdc, "Вторая строка", 0); PrintLn();
Print(hdc, "Третья строка( смещённая )", 10); PrintLn();
EndPaint(hwnd, ps);
return 0;
}
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
/**********************************************************
* Функция Print
* Функция предназначена для вывода текста
* в окно.
*
* ВХОДНЫЕ ЗНАЧЕНИЯ:
* HDC hdc -- индекс контекста устройства;
* char *str -- указатель на выводимую строку;
* int iOFFSET -- смещение горизонтальной позиции
* вывода текста в окно, указанное в символах;
*
* ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ:
* cxChar -- значение ширины для самой широкой литеры
* cyChar -- max высота литеры с учётом междустрочного
* интервала.
* cxCurrentPosition -- текущая гориз. позиция вывода текста
* cyCurrentPosition -- текущая верт. позиция вывода текста
*
* ФУНКЦИЯ ВОЗВРАЩАЕТ:
* Возвращаемых значений нет.
*
* ПРИМЕЧАНИЕ:
* Эта функция может быть переписана Вами под Ваши
* нужды для вывода не только текста, но и числовых
* значений, а также для форматирования в строке вывода.
*
**********************************************************/
void Print(HDC hdc, char *str, int iOFFSET )
{
char buf[SCREEN_BUFSIZE];
int i;
/* Проверяем смещение на неравенство единице
и корректируем его */
if( iOFFSET < 0 ) iOFFSET = 0;
// Подготавливаем в рабочем буфере
i = strlen(str);
// Проверка, что строка умещается в буфере
if( i < SCREEN_BUFSIZE - 1 )
// и выводим строку в зависимости от проверки
sprintf(buf, "%s", str);
else
sprintf(buf, "%.*s", SCREEN_BUFSIZE-1, str);
// Выводим текст в окно, начиная с текущей позиции
// вывода текста + смещение в максимальном
// количестве символов
TextOut(hdc,
cxCurrentPosition + iOFFSET * cxChar,
cyCurrentPosition,
buf, i);
}
/**********************************************************
* Функция PrintLn
* Функция предназначена для перевода на новую строку
* при выводе в окно.
*
* ВХОДНЫЕ ЗНАЧЕНИЯ:
* Не имеет.
*
* ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ:
* cxChar -- значение ширины для самой широкой литеры
* cyChar -- max высота литеры с учётом междустрочного
* интервала.
* cxCurrentPosition -- текущая гориз. позиция вывода текста
* cyCurrentPosition -- текущая верт. позиция вывода текста
*
* ФУНКЦИЯ ВОЗВРАЩАЕТ:
* Возвращаемых значений нет.
*
* ПРИМЕЧАНИЕ:
* Эта функция может быть переписана Вами под Ваши
* нужды для вывода не только текста, но и числовых
* значений, а также для форматирования в строке вывода.
*
**********************************************************/
void PrintLn( void )
{
// Увеличиваем текущую позицию по
// вертикали на высоту символа
cyCurrentPosition += cyChar;
}
/* Файл TEXTWN.DEF*/
; =============================
; Файл определения модул
; =============================
; Имя приложени
NAME TEXTWIN
; Описание приложени
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
Примечание: Для создания данного приложения средствами Microsoft Visual Studio 2008 вначале создайте "пустой проект", а затем заполните его этими файлами.
/* stdafx.cpp*/
// stdafx.cpp : исходный файл, который включает в себя стандартные заголовочные файлы.
// WINDOW.pch будет заголовком предпроцессора
// stdafx.obj будет содержать информацию предварительной компиляции
#include "stdafx.h"
// Поместите сюда всю дополнительную информацию, которая Вам нужна,
// в этот файл, а ни где-либо ещё.
/* stdafx.h */
// stdafx.h : заголовочный файл, со стандартными системными заголовочными файлами
// или специфичные для всего проекта часто используемые заголовочные файлы,
// но изменяемые не часто
//
#pragma once
#pragma once
// Измените следующие определения, если Вы используете платформу из тех, что обозначена ниже.
// Укажите MSDN последнюю информацию на соответствующее значение для разных платформ.
#ifndef WINVER // Позволяет использовать особенности, характерные для Windows XP и поздних версий.
#define WINVER 0x0501 // Измените значение на соответствующую величину текущей версии Windows.
#endif
#ifndef _WIN32_WINNT // Позволяет использовать особенности, характерные для Windows XP и поздних версий.
#define _WIN32_WINNT 0x0501 // Измените значение на соответствующую величину текущей версии Windows.
#endif
#ifndef _WIN32_WINDOWS // Позволяет использовать особенности, характерные для Windows 98 и поздних версий.
#define _WIN32_WINDOWS 0x0410 // Измените значение на соответствующую величину текущей версии Windows Me or later.
#endif
#ifndef _WIN32_IE // Позволяет использовать особенности, характерные для IE 6.0 и поздних версий.
#define _WIN32_IE 0x0600 // Измените значение на соответствующую величину текущей версии IE.
#endif
#define WIN32_LEAN_AND_MEAN // Не допущение ранее используемого наполнения из заголовка Windows.
// Заголовочный файл Windows:
#include <windows.h>
// Заголовочные файлы C RunTime
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
// TODO: разместите дополнительные заголовки модулей, необходимых для Вашего проекта, здесь
/* WINDOW.h*/
#pragma once
#include "resource.h"
/* WINDOW.cpp */
// WINDOW.cpp : Определяет точку входа для приложения.
//
#include "stdafx.h"
#include "WINDOW.h"
#define MAX_LOADSTRING 100
// Глобальные переменные:
HINSTANCE hInst; // текущий экземпляр класса
TCHAR szTitle[MAX_LOADSTRING]; // Текст главного меню
TCHAR szWindowClass[MAX_LOADSTRING]; // имя класса главного окна
// Далее идут объявления функций, включённых в модуль Code:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
// Отмена определения параметров hPrevInstance (предыдущий
// Экземпляр приложения) и lpCmdLine (командная строка)
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: Поместите свой код здесь.
MSG msg;
HACCEL hAccelTable;
// Инициализация глобальных настроек
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_WINDOW, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Подготовить инициализацию приложения:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOW));
// Основной цикл сообщений:
while (GetMessage(msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, msg))
{
TranslateMessage(msg);
DispatchMessage(msg);
}
}
return (int) msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Регистрирует класс окна.
//
// COMMENTS:
//
// Эта функция и её использование необходимо только
// в том случае, если Вы хотите, чтобы этот код
// был совместим с кодом системы Win32 прежде, чем функция 'RegisterClassEx'
// была добавлена в Windows 95. Очень важно использовать эту функцию так
// чтобы это приложение давала "правильно оформленными" иконками, ассоциированных с ними
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOW));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_WINDOW);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(wcex);
}
//
// FUNCTION: InitInstance(HINSTANCE, int)
//
//
// PURPOSE: Сохраняет экземпляр класса и создаёт основное окно
//
// COMMENTS:
//
// В этой функции мы сохраняем дескриптор экземпляр класса в глобальную переменную и
// создаёт и показывает основное окно программы..
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// PURPOSE: Обработка сообщений для главного окна.
//
// WM_COMMAND - обрабатывает меню приложени
// WM_PAINT - Рисует основное окно
// WM_DESTROY - Посылает завершающее сообщение и выход
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Сканирует раздел меню:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, ps);
// TODO: Добавьте сюда любой "рисующий" код...
EndPaint(hWnd, ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Дескриптор сообщения окна About.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
Примечание: Для создания данного приложения средствами Microsoft Visual Studio 2008 вначале создайте "пустой проект", а затем заполните его этими файлами.
/* stdafx.cpp*/
// stdafx.cpp : исходный файл, который включает в себя стандартные заголовочные файлы.
// textwin.pch будет заголовком предпроцессора
// stdafx.obj будет содержать информацию предварительной компиляции
#include "stdafx.h"
// Поместите сюда всю дополнительную информацию, которая Вам нужна,
// в этот файл, а ни где-либо
/* stdafx.h */
// stdafx.h : заголовочный файл, со стандартными системными заголовочными файлами
// или специфичные для всего проекта часто используемые заголовочные файлы,
// но изменяемые не часто
//
#pragma once
#define WIN32_LEAN_AND_MEAN // Использовать ранее использованный шаблон заголовков Windows
// Windows Заголовочный файл Windows:
#include <windows.h>
// Общие заголовки языка Си
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
// TODO: Укажите здесь дополнительные заголовочные файлы
// для Вашей программы
/* textwin.h */
#pragma once
#include "resource.h"
/* textwin.cpp*/
// textwin.cpp : Определение точек входа в программу.
//
#include "stdafx.h"
#include "textwin.h"
#define MAX_LOADSTRING 100
// Файлы с описанием функций
#ifndef __STDIO_H
#include <stdio.h>
#endif
#ifndef __STRING_H
#include <string.h>
#endif
/* Глобальные константы */
// Задание максимальной длины символьного буфера строки
// для вывода в окно
#ifndef SCREEN_BUFSIZE
#define SCREEN_BUFSIZE 80
#endif
// Прототип функции для печати строки символов
void Print(HDC, char *, int);
void PrintLn(void);
/* Глобальные переменные */
/**********************************************************
* cxChar -- значение ширины для самой широкой литеры
* cyChar -- max высота литеры с учётом междустрочного
* интервала.
* cxCurrentPosition -- текущая гориз. позиция вывода текста
* cyCurrentPosition -- текущая верт. позиция вывода текста
**********************************************************/
static int cxChar, cyChar;
static int cxCurrentPosition;
static int cyCurrentPosition;
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
// Далее находятся описания функций, включённых в модули кода
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
// TODO: Поместите код здесь
MSG msg;
HACCEL hAccelTable;
// Инициализация глобальных строк
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_TEXTWIN, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Подготовка к инициализации приложения:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_TEXTWIN);
// Основной цикл сообщений:
while (GetMessage(msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, msg))
{
TranslateMessage(msg);
DispatchMessage(msg);
}
}
return (int) msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Регистрация класса окна.
//
// COMMENTS:
//
// Эта функция и её использование необходима только
// в том случае, если Вы хотите, чтобы этот код
// был совместим с кодом системы Win32 прежде, чем функция 'RegisterClassEx'
// была добавлена в Windows 95. Очень важно использовать эту функцию так
// чтобы это приложение давала "правильно оформленными" иконками, ассоциированных с ними
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_TEXTWIN);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = (LPCTSTR)IDC_TEXTWIN;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
return RegisterClassEx(wcex);
}
//
// FUNCTION: InitInstance(HANDLE, int)
//
// PURPOSE: Сохраняет экземпляр класса и создаёт основное окно
//
// COMMENTS:
//
// В этой функции мы сохраняем дескриптор экземпляр класса в глобальную переменную и
// создаём и показываем основное окно программы..
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Сохраняем дескриптор экземпляра класса // в нашу глобальную переменную
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Обработка сообщений для главного окна.
//
// WM_COMMAND - обрабатывает меню приложени
// WM_PAINT - Рисует основное окно
// WM_DESTROY - Посылает завершающее сообщение и выход
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps; // структура для рисовани
HDC hdc; // индекс контекста устройства
static TEXTMETRIC tm; // структура для записи метрик
// шрифта
switch (message)
{
case WM_CREATE:
{
// Получаем контекст отображения,
// необходимый для определения метрик шрифта
hdc = GetDC(hWnd);
// Заполняем структуру информацией
// о метрике шрифта, выбранного в
// контекст отображени
GetTextMetrics(hdc, tm);
// Запоминаем значение ширины дл
// самого широкого символа
cxChar = tm.tmMaxCharWidth;
// Запоминаем значение высоты букв с
// учётом межстрочного интервала
cyChar = tm.tmHeight + tm.tmExternalLeading;
// Инициализируем текущую позицию
// вывода текста
cxCurrentPosition = cxChar;
cyCurrentPosition = cyChar;
// Освобождаем контекст
ReleaseDC(hWnd, hdc);
return 0;
}
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Сканируем секцию меню:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, ps);
// TODO: Добавляем код для рисования здесь...
// Инициализируем текущую позицию
// вывода текста
cxCurrentPosition = cxChar;
cyCurrentPosition = cyChar;
// Выводим последовательно строки:
Print(hdc, "Первая строка", 0); PrintLn();
Print(hdc, "Вторая строка", 0); PrintLn();
Print(hdc, "Третья строка( смещённая )", 10); PrintLn();
EndPaint(hWnd, ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Дескриптор диалогового окна сообщения: About.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
/**********************************************************
* Функция Print
* Функция предназначена для вывода текста
* в окно.
*
* ВХОДНЫЕ ЗНАЧЕНИЯ:
* HDC hdc -- индекс контекста устройства;
* char *str -- указатель на выводимую строку;
* int iOFFSET -- смещение горизонтальной позиции
* вывода текста в окно, указанное в символах;
*
* ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ:
* cxChar -- значение ширины для самой широкой литеры
* cyChar -- max высота литеры с учётом междустрочного
* интервала.
* cxCurrentPosition -- текущая гориз. позиция вывода текста
* cyCurrentPosition -- текущая верт. позиция вывода текста
*
* ФУНКЦИЯ ВОЗВРАЩАЕТ:
* Возвращаемых значений нет.
*
* ПРИМЕЧАНИЕ:
* Эта функция может быть переписана Вами под Ваши
* нужды для вывода не только текста, но и числовых
* значений, а также для форматирования в строке вывода.
*
**********************************************************/
void Print(HDC hdc, char *str, int iOFFSET )
{
char buf[SCREEN_BUFSIZE];
int i;
/* Проверяем смещение на неравенство единице
и корректируем его */
if( iOFFSET < 0 ) iOFFSET = 0;
// Подготавливаем в рабочем буфере
i = strlen(str);
// Проверка, что строка умещается в буфере
if( i < SCREEN_BUFSIZE - 1 )
// и выводим строку в зависимости от проверки
sprintf(buf, "%s", str);
else
sprintf(buf, "%.*s", SCREEN_BUFSIZE-1, str);
// Выводим текст в окно, начиная с текущей позиции
// вывода текста + смещение в максимальном
// количестве символов
TextOut(hdc,
cxCurrentPosition + iOFFSET * cxChar,
cyCurrentPosition,
buf, i);
}
/**********************************************************
* Функция PrintLn
* Функция предназначена для перевода на новую строку
* при выводе в окно.
*
* ВХОДНЫЕ ЗНАЧЕНИЯ:
* Не имеет.
*
* ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ:
* cxChar -- значение ширины для самой широкой литеры
* cyChar -- max высота литеры с учётом междустрочного
* интервала.
* cxCurrentPosition -- текущая гориз. позиция вывода текста
* cyCurrentPosition -- текущая верт. позиция вывода текста
*
* ФУНКЦИЯ ВОЗВРАЩАЕТ:
* Возвращаемых значений нет.
*
* ПРИМЕЧАНИЕ:
* Эта функция может быть переписана Вами под Ваши
* нужды для вывода не только текста, но и числовых
* значений, а также для форматирования в строке вывода.
*
**********************************************************/
void PrintLn( void )
{
// Увеличиваем текущую позицию по
// вертикали на высоту символа
cyCurrentPosition += cyChar;
}
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.