Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

Простое приложение Windows. Оболочка для всех приложений. Эффективное использование описателей. Компоненты приложения Windows. Функция WinMain(). Регистрация класса окна.

Читайте также:
  1. Cоциальный паспорт класса
  2. II. По выполняемым функциям
  3. II. Прием, регистрация, исполнение обращений граждан
  4. II. Функция «холокоста в мире после 1945 г.
  5. II. Цели и задачи организации учебно-воспитательной работы кадетского класса
  6. III. Организация деятельности кадетского класса
  7. RASH Использование отражений для остановки ВД

Простое приложение Windows.

ПростейшееWindows-приложение"Hello, World!"

Приложение, которое выводит на экран диалоговое окно "Hello, World!" вполне можно считать аналогом классической программы"Hello, World!".

 

#include <windows.h>

int WINAPI WinMain(HINSTANCE d1, HINSTANCE d2, LPSTR d3, int d4)

{

MessageBox(NULL, "Hello, World!", "", MB_OK);

return 0;

}

 

C точки зрения программирования у этого"приложения" довольно сложное поведение. Традиционная консольная версия"Hello, World!" выводит сообщение на экран и заканчивает работу. Windows-приложение после вывода сообщения продолжает работать. На экране присутствует диалоговое окно, которое можно переместить по экрану мышью. Мышью можно нажать кнопку OK для завершения работы приложения. Если нажать мышью кнопку OK, но не отпускать левую кнопку мыши, то на экране будет видна кнопка OK, нарисованная в нажатом состоянии. Если, не отпуская кнопку мыши, перемещать указатель то на кнопку OK, то вне ее, эта кнопка будет менять свой внешний вид. У окна приложения есть небольшое меню(с единственной командой Переместить), которое можно вызвать нажатием комбинации Alt+Пробел или щелчком правой кнопки на заголовке окна. Приложение можно завершить клавишей Enter, Escape или пробел.

Компоненты приложения для Windows

Существует несколько этапов, общих при разработке любых приложений Windows:

- Создать функцию WinMain() и вспомогательные для нее в программе на С, либо применить MFC, например, CWinAPP, в программе на C++.

- Создать описание меню, окон диалога и других ресурсов и поместить их в файл описания ресурсов.

- (При необходимости) При помощи редактора ресурсов из пакета Visual C++ создать собственные курсоры, значки и растровые изображения.

- (При необходимости) При помощи редактора ресурсов из пакета Visual C++ создать окна диалогов.

- Создать описание модуля (только для 16-разрядных приложений) и поместить его в файл определения модуля (module definition file).

- Откомпилировать и скомпоновать тексты на C/C++.

- Откомпилировать файл описания ресурсов и включить его в исполняемый файл.

Функция WinMain()

Функция WinMain() должна быть в каждом приложении Windows 95 или Windows NT. Это место, в котором выполнение программы начинается и, как правило, заканчивается. Функция WinMain() отвечает за:

- регистрацию класса окна для приложения;

- проведение необходимой инициализации;

- создание и запуск цикла обработки сообщений приложения, который обращается к очереди сообщений приложения;

- завершение программы, обычно по получении сообщения WM_QUIT.

 

Windows 95 и Windows NT передают функции WinMain() четыре параметра. Эти параметры перечислены в следующем фрагменте текста WIN32SWP:

 

int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPreInst, LPSTR lpszCmdLine,int nCmdShow)

 

Первый параметр, передаваемый WinMain(), это hInst, содержащий описатель экземпляра приложения. Это целое число однозначно определяет программу, работающую под управлением Windows 95 или Windows NT.

Второй параметр, hPreInst, всегда равен NULL, показывая этим, что предыдущего экземпляра приложения нет.

Третий параметр, lpszCmdLine, содержит указатель на буфер параметров командной строки, заканчивающийся нулем. Если приложение запущено командой Run (выполнить) системы Windows 95 или Windows NT, этот параметр обычно равен NULL.

Четвертый и последний параметр WinMain() — nCmdShow. Целое значение, передаваемое этим параметром, представляет собой одну из предопределенных в Windows 95 и Windows NT констант, задающих способ отображения окна, например SW_SHOWNORMAL, SW_SHOWMAXIMIZED или SW_MINIMIZED.

Регистрация класса окна

WinMain() отвечает за регистрацию класса главного окна приложения. Каждый класс окна задает набор стилей, шрифтов, строк заголовка, значков, размеров, положений и так далее. Класс окна служит образцом, по которому определяются эти атрибуты.

Windows 95 и Windows NT требуют, чтобы каждый экземпляр (каждая копия приложения) сам регистрировал класс окна для себя.

Для всех классов окна используется в основном одна и та же структура C/C++. Следующий текст взят из WINUSER.H — файла, включаемого в WINDOWS.Н. Этот заголовочный файл содержит объявление typedef, определяющее структуру типа WNDCLASSW (UNICODE-совместимую), от которой порождается структура WNDCLASS.

 

typedef struct tagWNDCLASSW {

UINT style;

WNDPROC lpfnWndProc;

int cbClsExtra;

int cbWndExtra;

HANDLE hInstance;

HICON hIcon;

HCURSOR hCursor;

HBRUSH hbrBackground;

LPCWSTR lpszMenuName;

LPCWSTR lpszClassName;

} WNDCLASSW, *PWNDCLASSW, NEAR *NPWNDCLASSW, FAR *LPWNDCLASSW;

 

Windows 95 вводит расширенную структуру класса, называемую WNDCLASSEX, которая позволяет применять для приложений маленький значок. Структура WNDCLASSEX определяется таким образом:

 

typedef struct _WNDCLASSEX {

UINT style;

WNDPROC lpfnWndProc;

int cbClsExtra;

int cbWndExtra;

HANDLE hInstance;

HICON hIcon;

HCURSOR hCursor;

HBRUSH hbrBackground;

LPCTSTR lpszMenuName;

LPCTSTR lpszClassName;

HICON hIconSm;

} WNDCLASSEX;

Как видно, эти две структуры идентичны за исключением того, что WNDCLASSEX дополнительно содержит поле hIconSm, где находится описатель маленького значка, связанного с классом окна.

Windows 95 и Windows NT дают несколько предопределенных классов окна, но большинство приложений определяют собственный класс окна. Для этого в программе объявляется структура соответствующего типа, в элементы которой заносится информация о классе окна. Следующий листинг, взятый из программы WIN32SWP, демонстрирует объявление и инициализацию структуры WNDCLASS.

 

char szProgName[]="ProgName";

 

 

WNDCLASS wcApp;

if(!hPreInst)

{

wcApp.lpszClassName = szProgName;

wcApp.hInstance = hInst;

wcApp.lpfnWndProc = WndProc;

wcApp.hCursor = LoadCursor(NULL,IDC_ARROW);

wcApp.hIcon = NULL;

wcApp.lpszMenuName = NULL;

wcApp.hbrBackground = GetStockObject(WHITE_BRUSH);

wcApp.style = CS_HREDRAW|CS_VREDRAW;

wcApp.cbClsExtra = 0;

wcApp.cbWndExtra = 0;

if(!RegisterClass (&wcApp))

return FALSE;

}

 

Шаблону WIN32SWP дается имя szProgName, которое также присваивается элементу wcApp. lpszClassName.

Следующее поле структуры WNDCLASS, wcApp.hInstance, получает значение, которое было передано функции WinMain() параметром hInst, то есть описатель экземпляра приложения. Элементу lpfnWndProc присваивается адрес функции окна, в данном примере это WndProc.

ПРИМЕЧАНИЕ. Имя WndProc определяется программистом — это не предопределенное имя. Прототип этой функции должен появляться раньше точки присваивания.

В поле wcApp.hCursor заносится описатель курсора приложения, в данном примере это IDC_ARROW (представляющий системный курсор в виде наклонной стрелочки). Программа получает описатель путем обращения к функции LoadCursor() Поскольку у приложения WIN32SWP нет своего значка, элемент wcApp.hIcon получает значение NULL.

Так как значение элемента wcApp.lpszMenuName равно NULL, Windows 95 и Windows NT понимают, что окна данного класса не имеют меню. Если окну необходимо было бы меню, то вместо NULL здесь стояло бы имя меню в кавычках. Функция GetStockObject() возвращает описатель кисти для заполнения фона рабочей области окон этого класса. В данном примере используется стандартная белая кисть Windows 95 или Windows NT, WHITE_BRUSH.

Стиль класса, задаваемый элементом wcApp.style, получает значение CS_HREDRAW|CS_VREDRAW. Все константы, используемые для стиля класса, определены в WINUSER.H и имеют префикс "CS_". Каждый из них задает битовый флаг, который комбинируются операцией | (поразрядное ИЛИ). Параметры CS_HREDRAW и CS_VREDRAW указывают Windows, что при изменении горизонтального или вертикального размеров окна вся рабочая область должна быть перерисована.

Последние два элемента, wcApp.cbClsExtra и wcApp.cbWndExtra, обычно равны нулю. Эти поля иногда используются для указания количества дополнительных байт, зарезервированных после самой структуры класса окна (wcApp.cbClsExtra) и после структуры параметров окна (wcApp.cbWndExtra).

Под управлением Windows 95 и Windows NT программа проверяет значение hPreInst, которое всегда равно NULL, и затем регистрирует класс окна.

 

if (!hPreInst)

{

 

if (!RegisterClass(&wcApp))

return FALSE;

}

 

В этом тексте два оператора if. Внешний if управляет инициализацией структуры WNDCLASS, если данный экземпляр программы — первый. Внутренний оператор if регистрирует класс окна, передавая дальний указатель на структуру класса в функцию RegisterClass(). Если Windows не может зарегистрировать класс окна (например, если недостаточно памяти), RegisterClass() вернет 0, и программа завершится.

 

84. Простое приложение Windows. Оболочка(каркас) для всех приложений. Эффективное использование описателей. Компоненты приложения Windows(???). Функция WinMain(). Регистрация класса окна.

* (???) - обозначение того, что материал не найден или нет конкретики, требуется дополнение.

 

Пример(описание)Windows-приложение "Hello, World!"

Приложение, которое выводит на экран диалоговое окно, пока-

занное на рис, вполне можно считать аналогом классической программы «Hello, World!».

 

 

#include <windows.h>

int WINAPI WinMain(HINSTANCE d1, HINSTANCE d2, LPSTR d3, int d4)

{

MessageBox(NULL, "Hello, World!", "", MB_OK);

return 0;

}

C точки зрения программирования у этого "приложения" довольно сложное поведение. Традиционная консольная версия "Hello, World!" выводит сообщение на экран и заканчивает работу. Windows-приложение после вывода сообщения продолжает работать. На экране присутствует диалоговое окно, которое можно переместить по экрану мышью. Мышью можно нажать кнопку OK для завершения работы приложения. Если нажать мышью кнопку OK, но не отпускать левую кнопку мыши, то на экране будет видна кнопка OK, нарисованная в нажатом состоянии. Если, не отпуская кнопку мыши, перемещать указатель то на кнопку OK, то вне ее, эта кнопка будет менять свой внешний вид. У окна приложения есть небольшое меню (с единственной командой Переместить), которое можно вызвать нажатием комбинации Alt+Пробел или щелчком правой кнопки на заголовке окна. Приложение можно завершить клавишей Enter, Escape или пробел.

 

Windows можно отнести к классу многозадачных ОС, основанных на передаче сообщений. В "глубине" ОС реализован механизм, преобразующий информацию от различных устройств ввода/вывода (события) в некоторую структуру данных – сообщение. Примерами событий являются нажатие клавиши, перемещение мыши, тик таймера. Типичное приложение (так обычно называются прикладные программы для Windows) строится на базе каркаса, содержащего цикл обработки сообщений. В этом цикле выполняется прием сообщений и передача их в соответствующие функции-обработчики сообщений. Сообщения, хотя и посылаются приложениям, но адресуются не им, а другим важнейшим компонентам ОС – окнам. Окно – это не просто прямоугольная область на экране, а некоторый объект, предназначенный для организации взаимодействия между пользователем и приложением.

 

Если заглянуть в раздел MSDN \Platform SDK\ Win32\ Overview of the Win32 API, то можно увидеть, что Win32 API подразделяются на следующие группы.

· Base Services - базовые сервисы отвечают за обеспечение доступа к ресурсам компьютера и интерфейс для работы с памятью, файлами, устройствами, процессами и потоками.

· Common Control Library - библиотека общих элементов управления для разработки оконных интерфейсов.

· Graphics Device Interface - вывод графики на дисплей и другие устройства.

· Network Services - сетевые сервисы.

· User Interface - интерфейс пользователя.

· Windows Shell - функции для работы с оболочкой.

· Windows System Information - информация о конфигурации системы Windows.

 

 

Каркас Windows-приложения

 

Чтобы иметь возможность работать с оконным интерфейсом, в заготовке (или каркасе) Windows-приложения необходимо выполнить некоторые стандартные действия:

1. Определить класс окна.

2. Зарегистрировать класс окна в ОС.

3. Создать окно (объект данного класса окна).

4. Отобразить окно на экране.

5. Организовать цикл обработки сообщений ОС создаваемому приложению.

 

Рассмотрим сначала, как можно создать минимальное Win32-приложение. В IDE Visual Studio С++, выполним команду File | New | Project... и выберем тип проекта – Win32 Project. В раскрывающемся списке Location выберем путь к рабочей папке (например, C:\programs), а в поле Name – имя проекта (например, api1):

 

 

Нажмём кнопку OK.

В следующем диалоговом окне нажимаем кнопку Next:

В окне установок проекта (Application Settings) выберем флажок Empty project (Пустой проект) и нажмём кнопку Finish – создан пустой проект, в котором нет ни одного файла.

 

С помощью контекстного меню добавим файл для кода приложения (C++ File,.cpp), имя файла введём в ходе диалога выбора шаблона объекта (тот же диалог можно получить по команде меню Project | Add New Item....).

 

 

Введём в окно редактора программу с минимальным кодом каркаса Windows-приложения:

 

// Листинг 23.1

#include <windows.h>

#include <tchar.h>

 

// Прототип оконной процедуры

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

 

TCHAR WinName[]=_T("MainFrame"); // Строка - имя класса окна

 

int APIENTRY _tWinMain (

HINSTANCE This, // Дескриптор текущего приложения

HINSTANCE Prev, // В современных системах всегда 0

LPTSTR cmd, // Указатель на командную строку

int mode) // Режим отображения окна

{

HWND hWnd; // Дескриптор главного окна приложения

MSG msg; // Структура для хранения сообщения

WNDCLASS wc; // Класс окна

 

// ИНИЦИАЛИЗАЦИЯ

// Определение объекта класса окна

wc.hInstance = This;

wc.lpszClassName = WinName; // Имя класса окна

wc.lpfnWndProc = WndProc; // Функция окна

wc.style = CS_HREDRAW | CS_VREDRAW; // Стиль окна

wc.hIcon = LoadIcon(NULL,IDI_ASTERISK);// Стандартная иконка

wc.hCursor = LoadCursor(NULL,IDC_ARROW);// Стандартный курсор

wc.lpszMenuName = NULL; // нет меню

wc.cbClsExtra = 0; // нет дополнительных данных класса

wc.cbWndExtra = 0; // нет дополнительных данных окна

// заполнение окна белым цветом

wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);

 

if (!RegisterClass(&wc)) // Регистрация класса окна

return 0;

 

// РЕАЛИЗАЦИЯ (создание и вывод на экран окна)

hWnd = CreateWindow(

WinName, // имя класса окна

_T("Каркас Windows-приложения"), // заголовок окна

WS_OVERLAPPEDWINDOW, // стиль окна

CW_USEDEFAULT, // координата x лев.верхн.угла

CW_USEDEFAULT, // координата y лев.верхн.угла

300, // ширина окна Width, можно CW_USEDEFAULT

200, // высота окна Height можно CW_USEDEFAULT

HWND_DESKTOP, // или NULL - дескриптор родительского окна

NULL, // дескриптор меню – нет меню

This, // дескриптор приложения

NULL); // дополнительной информации нет

 

ShowWindow(hWnd, mode); // Показать окно

UpdateWindow(hWnd); // Обновить окно

 

// ЦИКЛ ОБРАБОТКИ СООБЩЕНИЙ

while (GetMessage(

&msg,

NULL, // Дескриптор окна, которому адресуется

// сообщение (если NULL, для всех окон)

 

0, 0))// Диапазон кодов сообщений (если 0,0,

// то для всех кодов)

{

TranslateMessage(&msg); // Функция трансляции сообщения,

// например, кодов нажатых клавиш

DispatchMessage(&msg); // Посылка сообщения назад ОС для

// передачи его функции WndProc()

}

return 0;

}

 

// Оконная процедура вызывается операционной системой

// и получает сообщения из очереди для данного приложения

LRESULT CALLBACK WndProc(// Возвращает long int

HWND hWnd, // Дескр-р окна, которому адрес.сообщ-е

UINT message, // Передаваемое сообщение

WPARAM wParam, // Дополнительные параметры сообщения

LPARAM lParam)

{

// Обработчик сообщений

switch (message)

{

case WM_DESTROY: PostQuitMessage(0);

break; // Завершение приложения

 

// Обработка сообщения по умолчанию

default: return DefWindowProc(hWnd, message, wParam, lParam);

}

return 0;

}

 

Запустим программу на выполнение (F7, <Ctrl+F5>), получим пустое окно приложения, имеющее заголовок ("Каркас Windows-приложения") и набор стандартных кнопок:

 

 

Исследование каркаса Windows-приложения

 

Рассмотрим текст программы. Первая строка содержит включение заголовочного файла, который обязательно присутствует во всех Windows-программах:

 

#include <windows.h>

 

Если в ранних версиях Visual Studio этот файл содержал основные определения, то сейчас он служит для вызова других файлов включений, основные из которых: windef.h, winbase.h, wingdi.h, winuser.h, а также несколько других файлов, в которые помещены определения API-функций, констант и макросов.

Дополнительно подключим файл tchar.h, в котором содержатся определения некоторых полезных макросов, например, макрос _T() служит для создания строки Unicode на этапе компиляции и определён примерно так:

 

#ifdef _UNICODE

 

#define __T(x) L ## x

 

#else /* ndef _UNICODE */

 

#define __T(x) x

 

#endif /* _UNICODE */

 

#define _T(x) __T(x)

 

Макрос преобразуется в оператор "L", который является инструкцией компилятору для образования строки символами Unicode, если определена константа _UNICODE, и в "пустой оператор", если константа не определена. Константа _UNICODE устанавливается в зависимости от установок свойства проекта Character Set. Для установки этого свойства щёлкаем по вкладке Property Manager, затем правой кнопкой мыши по Debug|Win32, в контекстном меню выбираем Properties. В появившемся окне Debug Property Pages слева выбираем General, а справа в свойстве Character Set должно быть установлено Use Unicode Character Set (или Not Set в противном случае). Этот макрос позволяет компилировать проект как в кодировке Unicode (wchar_t), так и в однобайтовой кодировке (char).

 

 

 

Далее в программе следует прототип оконной процедуры (оконной функции):

 

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

 

Оконная процедура является функцией обратного вызова, что связано с некоторыми особенностями организации вызовов операционной системы. Эта функция для данного приложения регистрируется в системе, а её вызов осуществляет операционная система, когда требуется обработать сообщение, посланное приложению. Тип возвращаемого значения функции lresult эквивалентен long int для Win32-проeкта.

 

На глобальном уровне описывается имя класса окна приложения в виде текстовой строки:

 

TCHAR WinName[] = _T("MainFrame");

 

Тип tchar также преобразуется в wchar_t, если определена константа _ unicode, и в char, если константа не определена. Типwchar_t эквивалентен 16-битному типу short и служит для хранения символов в кодировке Unicode.

Имя класса окна используется операционной системой для его идентификации. Имя может быть произвольным, в частности, содержать кириллический текст.

 

Рассмотрим заголовок главной функции:

 

int APIENTRY _tWinMain (

HINSTANCE This, // Дескриптор текущего приложения

HINSTANCE Prev, // В современных системах всегда 0

LPTSTR cmd, // Указатель на командную строку

int mode) // Режим отображения окна

 

Для Windows-приложений с Unicode она носит имя wwinMain (), а в 8-битной кодировке – winMain(), выбор варианта определяется префиксом _t, что также является стандартным приёмом в библиотеке API-функций. Функция имеет четыре параметра, устанавливаемых при загрузке приложения:

- This – дескриптор, присваиваемый операционной системой при загрузке экземпляра приложения;

- Prev – параметр предназначен для хранения дескриптора предыдущего экземпляра приложения, уже загруженного системой. Сейчас он потерял свою актуальность и сохранен лишь для совместимости со старыми приложениями (начиная с Windows 95 параметр всегда устанавливается в нулевое значение);

- cmd – указатель на командную строку, но без имени запускаемой программы. Тип lptstr эквивалентен tchar *;

- mode – режим отображения окна (распахнутым на весь экран или нормального размера).

Дескриптор (описатель) – Windows-тип данных, который используется для описания объектов операционной системы. Дескриптор напоминает индекс хеш-таблицы и позволяет отслеживать состояние объекта в памяти при его перемещении по инициативе операционной системы. Предусмотрено много типов дескрипторов: hinstance, hwnd и др., все они являются 32-разрядными целыми числами.

 

В теле главной функции описаны три переменные:

- hwnd – предназначена для хранения дескриптора главного окна программы;

- msg – это структура, в которой хранится информация о сообщении, передаваемом операционной системой окну приложения:

- wc – структура, содержащая информацию по настройке окна.

 

В зоне инициализации главной функции требуется заполнить следующие её поля:

· Дескриптор текущего приложения:

wc.hInstance = This;

· Имя класса окна:

wc.lpszClassName = WinName;

· Имя оконной функции для обработки сообщений:

wc.lpfnWndProc = WndProc;

· Стиль, определяющий автоматическую перерисовку окна при изменении его ширины или высоты:

wc.style = CS_HREDRAW | CS_VREDRAW;

· Дескриптор пиктограммы (иконки) приложения:

wc.hIcon = LoadIcon(NULL, IDI_ASTERISK);

Функция LoadIcon() обеспечивает её загрузку. Если первый параметр null, используется системная пиктограмма, которая выбирается по второму параметру из следующего набора:

- idi_application – стандартная иконка;

- idi_asterisk – звездочка;

- idi_exclamation – восклицательный знак;

- idi_hand – ладонь;

- idi_question – вопросительный знак;

- idi_winlogo – логотип Windows;

· Графический образ курсора:

wc.hCursor = LoadCursor(NULL, IDC_ARROW);

Функция LoadCursor () обеспечивает загрузку графического образа курсора, где нулевой первый параметр также означает использование системного курсора, вид которого можно выбрать из списка:

- idc_arrow – стандартный курсор;

- idc_appstarting – стандартный курсор и маленькие песочные часы;

- idc_cross – перекрестие;

- idc_ibeam – текстовый курсор;

- idc_no – перечеркнутый круг;

- idc_sizeall – четырехлепестковая стрелка;

- idc_sizenesw – двухлепестковая стрелка, северо-восток и юго-запад;

- idc_sizenwse – двухлепестковая стрелка, северо-запад и юго-восток;

- idc_sizens – двухлепестковая стрелка, север и юг;

- idc_sizewe – двухлепестковая стрелка, запад и восток;

- idc_uparrow – стрелка вверх;

- idc_wait – песочные часы;

· Ссылка на строку главного меню, при его отсутствии null

wc.lpszMenuName = NULL;

· Дополнительные параметры класса окна:

wc.cbClsExtra = 0;

· Дополнительные параметры окна:

wc.cbWndExtra = 0;

· Дескриптор кисти:

wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);

Кисть используется для заполнения цветом окна. Стандартная конструкция, создаёт системную кисть белого цвета white_brush. Требуется явное преобразование типа к hbrush.

 

После того как определены основные характеристики окна, в зоне реализации главной функции можно это окно создать при помощи API-функции CreateWindow(), которой передаются параметры:

- WinName – имя, которое присвоено классу окна.

- _T("Каркас Windows-приложения") – заголовок окна в виде строки Unicode либо С-строки.

- WS_OVERLAPPEDWINDOW – макрос, определяющий стиль отображения стандартного окна верхнего уровня (не имеющего родительского окна), содержащего системное меню, заголовок, рамку для изменения размеров, а также кнопки минимизации, развёртывания и закрытия. Это стиль главного окна приложения, он определён так:

 

#define WS_OVERLAPPEDWINDOW(WS_OVERLAPPED|WS_CAPTION| WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX)

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

- ws_overlapped – стандартное окно с рамкой;

- ws_caption – окно с заголовком;

- ws_thickframe – окно с рамкой;

- ws_maximizebox – кнопка распахивания окна;

- ws_minimizebox – кнопка минимизации;

- ws_sysmenu – системное меню;

- ws_hscroll – горизонтальная панель прокрутки;

- ws_vscroll – вертикальная панель прокрутки;

- ws_visible – окно отображается;

- ws_child – дочернее окно;

- ws_popup – всплывающее окно;

 

Кроме стиля WS_OVERLAPPEDWINDOW существуют ещё 2 стандартных стиля:

 

WS_POPUPWINDOW – «всплывающее» окно, имеет родительское окно, но может «плавать» в области экрана перед родительским окном и перемещаться вне экранной области родительского окна; используется для диалоговых окон.

 

WS_CHILDWINDOW – может перемещаться только внутри экранной области родительского окна; используется для оконных элементов управления (кнопок, флажков, шкал прокрутки и т.д.).

 

- Следующие два параметра функции CreateWindow() определяют координаты левого верхнего угла окна (х, у), ещё два параметра: Width – ширину и Height – высоту окна в пикселах. Задание параметра cw_usedefault означает, что система сама выберет для отображения окна наиболее (с её точки зрения) удобное место и размер.

- Следующий параметр – дескриптор родительского окна, или null, при его отсутствии.

- Следующий параметр – указатель на структуру меню, или null, при её отсутствии.

- Далее требуется указать дескриптор приложения, владельца окна – This (или hInstance).

- И, наконец, указатель на дополнительную информацию, в нашем случае – null.

 

Окно создано, и с ним можно работать, но пока оно не отображается. Для того чтобы окно увидеть на экране, необходимо его отобразить с помощью функции ShowWindow(hwnd, mode), которая принимает два параметра: hwnd – дескриптор окна и mode – режим отображения. В данном случае используется значение, полученное при открытии приложения в виде параметра главной функции.

Для ускорения отображения окна с помощью необязательной функции UpdateWindow(hwnd) операционной системе даётся команда «Делай сейчас!».

 

Далее – заключительная часть главной функции – цикл обработки сообщений. Он задаётся оператором while, который проверяет возвращаемое значение функцией GetMessage(&msg,NULL,0,0). Такой цикл является обязательным для всех Windows-приложений, его цель – получение и обработка сообщений, передаваемых операционной системой. Операционная система ставит сообщения в очередь, откуда они извлекаются функцией GetMessage() по мере готовности приложения:

- первым параметром функции является & msg – указатель на структуру msg, в которую помещается информация о сообщении;

- второй параметрhwnd – определяет окно, для которого предназначено сообщение; если необходимо перехватить сообщения, предназначенные для всех окон данного приложения, он должен быть равен null;

- остальные два параметра определяют [min, mах] диапазон кодов получаемых сообщений. Чаще всего необходимо обработать все сообщения, тогда эти параметры должны быть равны 0.

 

Внутри цикла расположены две функции:

 

TranslateMessage(&msg);

DispatchMessage(&msg);

 

Первая из них транслирует код нажатой клавиши в клавиатурные сообщения wm_char. При этом в переменную wParam структуры msg помещается код нажатой клавиши в Windows-кодировке СР-1251, в младшее слово lparam – количество повторений этого сообщения в результате удержания клавиши в нажатом состоянии, а в старшее слово – битовая карта со значениями, приведенными в табл. 23.2. Использование функции TranslateMessage() не обязательно и нужно только для обработки сообщений от клавиатуры.

 

Таблица 23.2. Битовая карта клавиатуры, HIWORD (lParam)

Номер бита Значение
  1, если клавиша отпущена, 0 – если нажата
  1, если клавиша была нажата перед посылкой сообщения
  1, если нажата клавиша <Alt>
12-9 Резерв
  1, если нажата функциональная клавиша
7-0 Scan-код клавиши

 

Вторая функция, DispatchMessage(&msg), обеспечивает возврат преобразованного сообщения обратно операционной системе и инициирует вызов оконной процедуры данного приложения для его обработки.

 

Рассмотрим оконную процедуру WndProc().

Основной компонент этой функции – оператор-переключатель switch,обеспечивающий выбор соответствующего обработчика сообщения по его коду message. В разобранном примере предусмотрена обработка лишь одного сообщения wm_destroy. Это сообщение посылается, когда пользователь завершает программу. Получив его, оконная процедура вызывает функцию PostQuitMessage(0), которая завершает приложение и передаёт операционной системе код возврата 0. Точнее, генерируется сообщение WM_QUIT, получив которое функция GetMessage() возвращает нулевое значение (false). В результате цикл обработки сообщений прекращается и происходит завершение работы приложения.

Все остальные сообщения обрабатываются по умолчанию функцией DefWindowProc(), имеющей аналогичные оконной процедуре список параметров и возвращаемое значение, поэтому её вызов помещается в операторе return ветви default.

 

 

Простейшее Windows-приложение состоит как минимум из двух функций:

· главная функция WinMain (имя зарезервировано), которая содержит зону инициализации, зону реализации, цикл обработки сообщений операционной системы и с которой начинается выполнение любого приложения;

· оконная процедура (функция обратного вызова, задаётся спецификатором CALLBACK), которую вызывает ОС, транслируя ей сообщения, предназначенные данному приложению. Имя оконной процедуры задаётся произвольно. Windows регистрирует это имя, связывая его с данным приложением. В теле функции обычно размещается оператор-переключатель switch, внутри которого и определяется обработка соответствующих сообщений.

 

В функции MyRegisterclass() после заполнения полей структуры WNDCLASSEX происходит регистрация класса окна RegisterClassEx().


Дата добавления: 2015-09-03; просмотров: 144 | Нарушение авторских прав


Читайте в этой же книге: Требования к программному и аппаратному обеспечению Windows приложений. Требования к программному обеспечению. Требования к аппаратуре. | Логическая система координат | Доступ к оболочке Windows. Поля вывода. Изменение пределов поля вывода и окна. Координаты, определяемые пользователем. Выбор начальных атрибутов окна. | Некоторые функции, имеющие отношение к сообщению WM_PAINT. | Вывод окна. Изменение вида окна. Часто используемые элементы управления и диалоговые окна. Статические элементы управления. Элементы управления - кнопки. | Модальная диалоговая панель | Обмен данными диалога | Немодальная диалоговая панель | Статические органы управления | Вывод окна |
<== предыдущая страница | следующая страница ==>
Окончание работ| Норма времени на один кронштейн, чел.ч

mybiblioteka.su - 2015-2024 год. (0.094 сек.)