Главная страница

Я да. Лабораторная работа 1_1п. Лабораторная работа основы создания графических приложений в системе windows


Скачать 1.15 Mb.
НазваниеЛабораторная работа основы создания графических приложений в системе windows
Дата13.04.2022
Размер1.15 Mb.
Формат файлаpdf
Имя файлаЛабораторная работа 1_1п.pdf
ТипЛабораторная работа
#469004
страница1 из 4
  1   2   3   4

Лабораторная работа 1.
ОСНОВЫ СОЗДАНИЯ ГРАФИЧЕСКИХ
ПРИЛОЖЕНИЙ В СИСТЕМЕ WINDOWS
Цель работы. Изучение технологии создания программы для Windows с
помощью прикладного интерфейса программирования Windows API
Операционная система Windows является многозадачной операционной системой, что позволяет пользователю работать с несколькими одновременно запущенными приложениями. Для вывода информации, а также для получения информации от пользователя приложения используют окна.
В системе Windows окном называется прямоугольная область экрана, которую приложение использует для вывода информации и получения данных от пользователя. Каждое окно приложения совместно использует экран с окнами других приложений. В один момент времени лишь одно окно может получать данные, вводимые пользователем. Такое окно называется активным. С помощью мыши, клавиатуры и других устройств пользователь может взаимодействовать с окном и создавшим его приложением.
С каждым окном в системе Windows связан дескриптор окна – специальное значение типа
HWND
, которое уникально идентифицирует окно в системе. После создания окна приложение получает его дескриптор и может управлять окном, передавая дескриптор окна в соответствующие функции управления окнами.
Каждое графическое приложение создаёт, по крайней мере, одно окно, называемое главным окном приложения. Данное окно обеспечивает основной интерфейс между пользователем и приложением. Для отображения или получения дополнительной информации, приложение может создавать и другие окна.
Прежде чем создать окно, необходимо задать его свойства, т.е. задать набор атрибутов, которые система будет использовать для создания нового окна.
Каждое окно – это экземпляр одного из зарегистрированных в системе классов окон. Классы окон, определённые в рамках текущего процесса, используются независимо от классов окон, определённых в других процессах.
Для задания свойств окна используется структура
WNDCLASSEX
, содержащая ряд полей данных, в которых содержится соответствующая информация. После заполнения значений полей данных информация передаётся системе Windows в целях создания окна.
Определение структуры
WNDCLASSEX
представлено ниже. typedef struct _WNDCLASSEX{
UINT cbSize; // размер этой структуры в байтах
UINT style; // стили главного окна
WNDPROC lpfnWndProc;// адрес оконной процедуры int cbClsExtra; // количество дополнительных байт,
// занимаемых классом int cbWndExtra; // количество дополнительных байт,
// занимаемых окном
HINSTANCE hInstance;// дескриптор экземпляра

// приложения
HICON hIcon; // дескриптор большой иконки окна
HCURSOR hCursor; // дескриптор курсора окна
HBRUSH hbrBackground; // дескриптор кисти,
// используемой для заливки фона
LPCTSTR lpszMenuName; // имя для меню
LPCTSTR lpszClassName; // имя класса окна
HICON hIconSm; // дескриптор маленькой иконки окна
} WNDCLASSEX;
Смысл полей структуры
WNDCLASSEX
следующий:
• Стили класса окна – набор флагов, определяющих различные аспекты поведения и внешнего вида окна. Стили класса окна можно произвольным образом комбинировать при помощи побитовой операции
«или».
• Оконная процедура – это функция, определяемая приложением, которая служит для обработки сообщений, посылаемых окну. Все окна, создаваемые на основе некоторого класса окна, имеют общую оконную процедуру.
• Дескриптор экземпляра приложения используется для разделения классов окон, создаваемых различными модулями в рамках одного процесса. При запуске графического приложения им передаётся дескриптор экземпляра приложения.
• Дескрипторы иконок задают внешний вид большой и маленькой иконок, отображаемых в панели задач, а также в заголовке окна.
• Дескриптор кисти определяет способ заливки клиентской области окна.
• Имя меню – имя ресурса меню, используемого окнами данного класса.
• Имя класса окна – имя, под которым будет зарегистрирован данный класс окна. При создании нового окна приложение указывает имя класса окна, а также дескриптор экземпляра приложения, в котором данный класс был объявлен.
Прежде чем задать свойства окна сначала необходимо создать объект типа
WNDCLASSEX
:
WNDCLASSEX
wc;
После создание объекта этой структуры следует заполнить поля подходящими значениями. Для создания обычного окна заполнение может выглядеть следующим образом: wc.cbSize = sizeof(wc); wc.style = CS_HREDRAW | CS_VREDRAW ; wc.lpfnWndProc = WinProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInst; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL; wc.lpszClassName = "WinClass"; wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
Первым полем структуры
WNDCLASSEX
является
cbSize
. Эта переменная хранит размер объекта. При передаче объекта по указателю этим значением можно воспользоваться, чтобы определить точный объём памяти, занимаемый объектом. По большей части указание размера является мерой предосторожности, но это поле всегда следует заполнять.
Следующее поле –
style
. Оно определяет поведение окна. Поле заполнено комбинированием констант
CS_HREDRAW
и
CS_VREDRAW
посредством оператора «или». Некоторые из допустимых значений приведены в табл. 1.
Таблица 1. Стили поведения окна
Значение
Действие
CS_HREDRAW
Обновляет изображение всего окна, если перемещение или подстройка размера изменяет ширину окна
CS_VREDRAW
Обновляет изображение всего окна, если перемещение или подстройка размера изменяет высоту окна
CS_OWNDC
Упрощает рисование в окне
CS_DBLCLKS
Посылает сообщение о двойном щелчке, произошедшем в области окна
CS_NOCLOSE
Отключает команду Close (Закрыть) системного меню окна
Следующее поле определяет функцию обработки событий, получаемых от системы Windows wc.lpfnWndProc = WinProc;
В этом объявлении функция названа
WinProc
, хотя она может иметь любое имя. Установка этого значения говорит Windows, какую из функций вызывать, когда для окна имеются входные данные.
Следующее поле,
hInstance
, является дескриптором экземпляра приложения. Windows предоставляет значение этого параметра в качестве аргумента
hInst
, полученным функцией
WinMain
: wc.hInstance = hInst;
Вызов функции Windows
LoadIcon
позволяет инициализировать следующее поле –
hIcon
. Можно использовать произвольную пиктограмму, в примере заполнения структуры
WNDCLASSEX
была использована системная
пиктограмма (то есть поставляемая в составе системы Windows). В табл. 2 перечислены некоторые из доступных системных пиктограмм.

Таблица 2. Системные пиктограммы
Значение
Действие
IDI_APPLICATION
Стандартная пиктограмма приложения
IDI_ASTERISK
Пиктограмма звёздочки
IDI_EXCLAMATION
Восклицательный знак
IDI_HAND
Пиктограмма с ладонью
IDI_QUESTION
Вопросительный знак
IDI_WINLOGO
Логотип системы Windows
Поле
hCursor
инициализируется практически таким же образом, при помощи функции
LoadCursor
hCursor
указывает, как выглядит указатель мыши, когда находится в области окна. Некоторые из системных курсоров перечислены в табл. 3.
Таблица 3. Системные курсоры
Значение
Действие
IDC_ARRON
Стандартный указатель
IDC_APPSTARTING
Стандартный указатель и маленькие песочные часы
IDC_CROSS
Перекрестие
IDC_IBEAM
Текстовый курсор
IDC_NO
Перечёркнутый круг
IDC_SIZEALL
Четырёхлепестковая стрелка
IDC_SIZENESW
Двулепестковая стрелка, указывающая на северо-восток и юго-запад
IDC_SIZENWSE
Двулепестковая стрелка, указывающая на северо-запад и юго-восток
IDC_SIZENS
Двулепестковая стрелка, указывающая на север и юг
IDC_SIZEWE
Двулепестковая стрелка, указывающая на запад и восток
IDC_UPARROW
Стрелка вверх
IDC_WAIT
Песочные часы
Следующее поле,
hbrBackground
, определяет вид фона окна. Способ закрашивания фона определяется при помощи кистей. Кисть (brush) в системе
Windows – это способ хранения информации о том, как следует заполнять область цветом. Некоторые из стандартных кистей перечислены в табл. 4.
Таблица 4. Системные кисти
Значение
Действие
BLACK_BRUSH
Сплошной чёрный
WHITE_BRUSH
Сплошной белый
GRAY_BRUSH
Сплошной серый
LTGRAY_BRUSH
Сплошной светло-серый
DKGRAY_BRUSH
Сплошной тёмно-серый
NULL_BRUSH
Пустая кисть
Для того, организовать в окне меню, следует использовать поле
lpszMenuName
и определить состав меню, в противном случае следует установить значение
NULL
Следующее поле даёт имя классу, который служит для создания окна.
Каждое окно является объектом. В процессе заполнения структуры
WNDCLASSEX
будет создан новый класс. Затем на основе этого класса создаётся окно. Классу можно дать любое удобное имя, поскольку в действительности это имя особого значения не имеет.
Последнее поле хранит уменьшенную версию пиктограммы. Именно эта версия отображается в заголовке окна и на панели задач. Значение этому полю присваивается так же, как полю
hIcon
: wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
После заполнения полей структуры
WNDCLASSEX
, приложение должно вызвать системную функцию
RegisterClassEx
, передав ей адрес данной структуры. Функция возвращает логическое значение, отражающий результат работы (
true
– функция завершилась успешно,
false
– в противном случае).
Ниже представлен вариант регистрации класса окна. if(!RegisterClassEx(&wc)) {
MessageBox(NULL, "Cannot register class",
"ERROR",MB_OK); return 0;
}
После успешной регистрации окна необходимо создать его экземпляр посредством вызова функции
CreateWindowEx
, которая имеет следующее объявление:
HWND CreateWindowEx (
DWORD dwExStyle, // дополнительные стили
LPCTSTR lpClassName, // имя класса
LPCTSTR lpWindowName, // имя окна
DWORD dwStyle, //стиль int x, // расстояние до окна от левой стороны экрана int у, // расстояние до окна от верхней стороны экрана int nWidth, // ширина окна int nHeight, // высота окна
HWND hWndParent, // дескриптор родительского окна
HMENU hMenu, // дескриптор меню
НINSTANCE hInst, // дескриптор экземпляра приложения
LPVOID lpParam // параметры создания окна
);
Эта функция возвращает значение либо
NULL
, если создание окна прошло неудачно, либо дескриптор созданного окна в противном случае. Чтобы работать с окном впоследствии, для хранения дескриптора необходимо создать переменную
HWND hWnd;
Первый параметр функции,
dwExStyle
, хранит все дополнительные режимы для окна. Если дополнительные режимы не требуются, следует использовать значение
NULL

Второй параметр – имя класса, используемого для создания окна. В нашем случае –
"WinClass"
Третий параметр – текстовый заголовок окна.
Четвертый параметр,
dwStyle
, определяет вид и поведение окна. Стили окна можно произвольным образом комбинировать при помощи побитовой операции «или». Некоторые из значений перечислены в табл. 5.
Таблица 4. Стили окон
Значение
Действие
WS_POPUP
Всплывающее окно
WS_OVERLAPED
Перекрываемое окно с заголовком и границами
WS_OVERLAPEDWINDOW
Перекрываемое окно со стилями
WS_DVERLAPPED
,
WS_CAPTION
,
WS_SYSMENU
,
WS_THICKFRAME
,
WS_MINIMIZEBOX
и
WS_MAXIHIZEBOX
WS_VISIBLE
Изначально видимое окно
WS_SYSMENU
Системное меню доступно в заголовке окна (по щелчку на маленькой пиктограмме). Должен использоваться стиль
WS_CAPTION
WS_BORDER
Окно с тонкими границами
WS_CAPTION
Окно с заголовком (стиль
WS_BORDER
включается автоматически)
WS_MINIMISE
Окно изначально свёрнуто
WS_MAXIMIZE
Окно изначально имеет максимальный размер
Параметры
x
и
y
определяют расстояние от левого верхнего угла экрана до левого верхнего угла окна. Чтобы оставить эти параметры на усмотрение
Windows, можно воспользоваться значением
CW_USEDEFAULT
вместо конкретного числа.
Параметры
nWidth
и
nHeight
определяют ширину и высоту окна. Можно воспользоваться константой
CW_USEDEFAULT
, чтобы система задала их самостоятельно.
Параметр
hWndParent
определяет дескриптор родительского окна, если таковое существует. Значение
NULL
делает родительским окном рабочий стол
Windows.
Параметр
hMenu
определяет дескриптор связанного с окном меню. При передаче
NULL
в качестве данного параметра, создаваемое окно не будет иметь меню.
Параметр
hInst
указывает на дескриптор экземпляра приложения, который передаётся в
WinMain
Параметр
lpParam
содержит дополнительные параметры, например, данные связанные с окном. Данный параметр используется также при создании окон в приложениях с многодокументным интерфейсом. По умолчанию этот параметр выставляется в
NULL
Окончательный вызов функции
CreateWindowEx
может выглядеть следующим образом:
hWnd = CreateWindowEx (
NULL, //дополнительные стили "WinClass", //имя класса "Простое окно", //заголовок окна
WS_OVERLAPPEDWINDOW | WS_VISIBLE, //стили
CW_USEDEFAULT, CW_USEDEFAULT, //начальное положение
CW_USEDEFAULT, CW_USEDEFAULT, //начальный размер
NULL, //родительским окном является рабочий стол
NULL, //меню отсутствует hInst, //дескриптор экземпляра приложения
NULL); //дополнительные параметры
При успешном создании окна функция возвращает дескриптор созданного окна, который приложение может использовать для управления окном.
В примере вызова функции
CreateWindowEx
был использован стиль
WS_VISIBLE
, который делает окно изначально видимым. В отсутствие этого стиля чтобы отобразить окно необходимо вызвать функцию
ShowWindow
Функция
ShowWindow
имеет два параметра: дескриптор окна и аргумент
nCmdShow
, полученный функцией
WinMain
. Вот так можно самостоятельно отобразить окно:
ShowWindow(hWnd, nCmdShow);
И в заключение следует вызвать функцию
UpdateWindow
, которая сразу же обновляет окно на экране:
UpdateWindow(hWnd);
Эта функция посылает событие
WM_PAINT
, которое сообщает, что клиентская область окна или её часть нуждается в перерисовке.
После создания окна необходимо приступить к обработке поступающих событий. Для этого используется функция, указанная в поле
lpfnWndProc
структуры
WNDCLASSEX
. В рассмотренном выше примере заполнения структуры
WNDCLASSEX
эта функция названа
WinProc
Для получения событий, которые подлежат обработке, предназначена функция
GetMessage
. Эта функция помещается в условие цикла, и работа цикла зависит от значений, которая она возвращает. Любое ненулевое значение, возвращаемое функцией
GetMessage
, означает, что очередь событий не пуста.
Объявление функции
GetMessage
следующее:
BOOL GetMessage (LPMSG lpMsg, HWND hWnd,
UINT wMsgFilterMin, UINT wMsgFilterMax);
Функция заполняет структуру
lpMsg
информацией о полученном сообщении. Оставшиеся три параметра можно игнорировать. Они задействованы только в очень сложных программах.
В качестве первого аргумента следует передать ссылку на структуру
MSG
: typedef struct tagMSG {
HWND hwnd; // окно, в котором создано сообщение

UINT message; // идентификатор сообщения
WPARAM wParam; // дополнительная информация
LPARAM lParam; // дополнительная информация
DWORD time; // время создания сообщения
POINT pt; // координаты указателя мыши
} MSG;
До передачи функции
GetMessage
объект необходимо создать, после чего реализовать цикл, в котором происходит получение событий, поступаемых от системы Windows. Это может выглядеть следующим образом:
MSG msg; while (GetMessage(&msg, NULL, 0, 0)) {
}
После получения сообщений необходимо выполнить их обработку, которая может быть реализована при помощи функций
TranslateMessage
и
DispatchMessage
. Аргументом каждой из них является ссылка на объект
MSG
Функция
TranslateMessage
производит предварительную обработку полученной информации, а функция
DispatchMessage
посылает сообщение, подлежащее обработке, функции
WinProc
. Таким образом, код обработки сообщений выглядит следующим образом:
MSG msg; while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
Окончательный вариант функции
WinMain
будет следующим int WINAPI WinMain (HINSTANCE hInst,
HINSTANCE hPrevInst,
LPSTR lpCmdLine, int nCmdShow)
{
HWND hWnd;
MSG msg;
WNDCLASSEX wc; wc.cbSize = sizeof(wc); wc.style = CS_HREDRAW | CS_VREDRAW ; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.lpfnWndProc = WinProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInst; wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszClassName = "WinClass"; wc.lpszMenuName = NULL; wc.hIconSm = LoadIcon(NULL, IDI_WINLOGO);
if(!RegisterClassEx(&wc)) {
MessageBox(NULL, "Cannot register class",
"ERROR",MB_OK); return 0;
} hWnd = CreateWindowEx (NULL, "WinClass",
"Простое окно", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInst, NULL); if(!hWnd){
MessageBox(NULL, "Cannot create window",
"ERROR",MB_OK); return 0;
}
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd); while(GetMessage(&msg,NULL,0,0)){
TranslateMessage(&msg);
DispatchMessage(&msg);
} return msg.wParam;
}
При необходимости передать приложению некоторую информацию, операционная система уведомляет приложение, посылая необходимое сообщение в соответствующее окно приложения. Каждое окно имеет особую функцию, называемую оконной процедурой, которую система вызывает всякий раз, когда для окна имеются входные данные. Оконная процедура объявляется следующим образом:
LRESULT CALLBACK WinProc(
HWND hWnd, // дескриптор окна
UINT uMsg, // идентификатор сообщения
WPARAM wParam, // дополнительный параметр 1
LPARAM lParam); // дополнительный параметр 2
Квалификатор
  1   2   3   4


написать администратору сайта