Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:OC Windows & OC Linux. Лабораторные работы по курсу «Операционные системы»
.pdf
return 0;
}
//определение процедуры окна
LRESULT CALLBACK_export WindowProc(HWND hwnd, UINT
msg,
WPARAM wParam, LPARAM lParam)
//обработаем сообщения
switch(msg)
{
//перерисовка окна
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc=BeginPaint(hwnd,&ps)
//начнем вывод
//напечатаем строку
Техtout(hdc,10,10,"Нестираемое сообщение.",22);
EndPaint(hwnd,&ps);
//завершим вывод
break;
}
//нажатие левой кнопки мыши
сазе WM_LBUTTONDOWN:
{
HDC hdc=GetDC(hwnd);
TextOut(hdc,10,50,"Нажата левая кнопка мыши."
,25);
ReleaseDC(hwnd,hdc);
break;
}
//нажатие правой кнопки мыши
case WM_RBUTTONDOWN:
{
HDC hdc=GetDC(hwnd);
TextOut(hdc,10,90,"Нажата правая кнопка мы-
ши.",26);
ReleaseDC(hwnd,hdc);
break;
}
11

//окно закрывается
case WM_CLOSE:
//пошлем сообщение WM_QUIT программе
PostQuitMessage(0);
break;
//остальные сообщения передадим стандартной функции окна
default:
return DefWindowProc(hwnd, msg, wParam, lPa-
rara);
}
return 0;
}
//файл 01_2.def
NAME PROG01_2
EXETYPE WINDOWS
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE MULTIPLE
HEAPSIZE 1024
EXPORTS; ===List your explicitly exported functions here===
Каждое окно создается на основе некоторого класса, который
определяет его поведение. К одному и тому же классу может принадлежать несколько окон. Примерами окон, создаваемых на базе
стандартных классов, являются кнопки, выпадающие списки, полосы прокрутки и т.п. В данном случае программа регистрирует собственный класс окна. Он определяется следующей структурой:
typedef struct tagWNDCLASS {
UINT style; //стили класса
WNDPROC lpfnWndProc; //указатель на процеду-
ру окна
int cbClsExtra; //дополнительная память
под класс
int cbWndExtra; //дополнительная память
под окно
HINSTANCE hInstance; //экземпляр модуля
HICON hIcon; //пиктограмма
HCURSOR hCursor; //курсор HBRUSH
12

hbrBa-ckground; //фон окна
LPCSTR lpszMenuName; //название меню
LPCSTR lpszClassName; //название класса
} WNDCLASS;
Поле style определяет стили класса, влияющие на все окна, создаваемые на его основе. Они задаются комбинацией констант. Среди
них можно отметить следующие:
CS_DBLCLKS – окна различают двойные щелчки мышью,
CS_HREDRAW – при изменении горизонтального размера окна
происходит его полная перерисовка,
CS_VREDRAW – полная перерисовка происходит при измене-
нии вертикального размера,
CS_NOCLOSE – запрещает пункт «Закрыть» в системном меню
окна. В поле lpfnWndProc должен записываться указатель на процедуру, которая будет обрабатывать сообщения для окон, созданных
на базе данного класса. В полях hIcon и hCursor должны находиться
идентификаторы загруженных ресурсов пиктограммы и курсора.
Загрузка производится функциями LoadIcon и LoadCursor:
HICON LoadIcon(hinst, pszIcon)
HINSTANCE hinst; //идентификатор экземпляра
модуля
LPCSTR pszIcon; //имя или идентификатор
ресурса пиктограммы
HCURSOR LoadCursor(hinst, pszCursor)
HINSTANCE hinst; //идентификатор экземпляра
модуля
LPCSTR pszCursor; //имя или идентификатор
ресурса курсора
Программа загружает ресурсы стандартных курсора и пиктограммы, используя для этого константы IDC_ARROW и IDI_APPLICATION. Параметр задает способ закраски фона. Он может содержать либо идентификатор физической кисти, либо один из стандартных цветов, например: COLOR_WINDOW – выбранный в панели управления цвет для фона окна, COLOR_BACKGROUND – цвет
рабочего стола и т.д. Параметр lpszMenuName задает
торое будет выбираться для всех окон, для которых не задано собст-
имя меню, ко-
13

венное меню. Параметр lpszClassName указывает на имя класса, которое будет его однозначно идентифицировать и использоваться при
создании окон.
После описания класса необходимо его зарегистрировать в системе. Для этого используется функция RegisterClass:
ATOM RegisterClass(lpwc)
const WNDCLASS FAR* lpwc; //адрес структуры с данными класса
В случае успеха она возвращает значение-атом, идентифицирующее этот класс, в случае ошибки – нулевое значение.
Для того чтобы создать окно, используется функция CreateWin-
dow:
HWND CreateWindow(lpszClassName, lpszWindowName, dwStyle, x, y, nWidth, nHeight, hwndParent,hmenu, hinst, lpvParam)
LPCSTR lpszClassName; //имя класса окна
LPCSTR lpszWindowName; //название окна (показы-
вается в заголовке) DWORD dwStyle;
//стили окна
int x; //горизонтальная позиция
окна
int у; //вертикальная позиция
окна
int nWidth; //ширина окна
int nHeight; //высота окна
HWND hwndParent; //родительское OKHO
HMENU hmenu; //идентификатор меню или
дочернего окна
HINSTANCE hinst; //идентификатор экземпляра
приложения void FAR* lpvParam;
//дополнительные параметры
Параметр lpszClassName должен указывать на имя классаосновы окна; lpszWindowName – указатель на строку-имя окна, показываемое в его заголовке; dwStyle – стили окна, WS_O VERLAPРЕDWINDOW определяет стандартное перекрывающееся окно с
рамкой, заголовком, системным меню, кнопкой минимизации и максимизации; для параметров х, у, nWidth и nHeight задано значение
14

CW_USEDEFAULT, устанавливающее размеры и положение окна
по умолчанию; в качестве значения hwndParent указана константа
HWND_DESKTOP, указывающая, что родительское окно у дан-
ного окна – рабочий стол.
После того как окно создано, оно должно быть показано на экране. Для этого используется функция ShowWindow, а затем функция UpdateWindow, которая обновляет его содержимое:
BOOL ShowWindow(hwnd, nCmdShow)
HWND hwnd; //идентификатор окна
int nCmdShow; //команда void UpdateWindow
(hwnd)
HWND hwnd; //идентификатор окна
Параметр nCmdShow определяет то, что надо сделать с окном.
Его значения могут быть те же, что и у последнего параметра функции WinMain. SW_HIDE, например, означает – скрыть окно, SW_
SHOW – показать в текущей позиции и размере, SW_SHOWMA
XIMIZED – максимизировать и т.д.
Процедура окна WinclowProc – это функция, которая вызывается системой при поступлении сообщений окнам, за которые она отвечает. Она должна быть объявлена как экспортируемая (_export).
Параметр hwnd определяет идентификатор окна, для которого послано сообщение, msg – номер сообщения (для их обозначения используются константы, например, событию нажатия левой кнопки
мыши соответствует WM_LBUTTONDOWN, закрытию окна – WM_
CLOSE и т.п.). В данном примере производится обработка четырех
сообщений.
Сообщение WM_PAINT посылается окну, когда его внутренняя
область должна быть перерисована, например, когда оно всплывает
из-под других окон или после вызова функции UpdateWindow. Для
того чтобы отобразить необходимую информацию, программа должна получить контекст устройства, используемого всеми функциями
рисования. Он возвращается функцией BeginPaint:
HDC BeginPaint(hwnd, lpps)HWNDhwnd; //иденти-
фикатор окна
PAINTSTRUCT FAR* lpps; //структура,
описывающая зарисовываемую область
15

Она подготавливает окно для рисования, создает для него контекст устройства и возвращает его идентификатор. После рисования
он должен быть обязательно освобожден при помощи функции End-
Paint:
void bndPaint(hwnd, lpps)HWND hwnd; //иденти-
фикатор окна
const PAINTSTRUCT FAR* lpps; //указатель
на структуру с данными перерисовываемой области
Эта пара функций должна вызываться только в ответ на сообщение WM_PAINT. При выводе в других ситуациях должны быть
использованы следующие функции:
HDC GetDC(hwnd) HWND hwnd; //идентифи-
катор окна
int ReleaseDQhwnd, hdc) HWND hwnd; //иденти-
фикатор окна
HDC hdc; //контекст
освобождаемого устройства
Для вывода текста используется функция
TextOut: BOOL TextOut(hdc, nXStart, nYStart.
lpszString, cbString)
HDC hdc; //идентификатор контекста
устройства
int nXStart; //Х-координата начальной по-
зиции вывода
int nYStart; //У-координата начальной по-
зиции вывода
LPCSTR lpszString; //указатель на выводимую
строку int cbString;
cbString //длина строки в символах
В качестве первого параметра она принимает контекст идентификатор контекста устройства, полученный при помощи функций
BeginPaint или GetDC, второй и третий – координаты точки, от ко-
16

торой рисуется строка (по умолчанию левый верхний угол внутренней области окна имеет координаты (0,0)), третий и четвертый – это
указатель на выводимую строку и ее длина в символах.
Сообщение WM_CLOSE посылается окну, когда оно должно
быть закрыто. Когда закрывается главное окно программы, она
должна завершить свою работу. Обычно для этого используется сообщение WM_QUIT, помещаемое в очередь приложения функци-
ей PostQuitMessage:
void PostQuitMessage(nExitCode)
int nExitCode; //код завершения
PostQuitMessage извещает систему о том, что программа скоро
закончит свою работу, посылает WM_QUIT и тотчас же возвращает
управление назад.
Все необработанные сообщения должны быть переданы стандартной процедуре обработки. Она вызывается функцией DefWindowProc, которая принимает те же параметры, что и процедура окна:
LRESULT DefWindowProc(hwnd, uMsg, wParam, lParam)
HWND hwnd; //идентификатор окна
UINT uMsg; //код сообщения
WPARAM wParam; //дополнительные параметры,
их значение
LPARAM lParam; //зависит от сообщения
17

ЛАБОРАТОРНАЯ РАБОТА № 2
РЕСУРСЫ WINDOWS
Введение
Приложение Windows может хранить в виде ресурсов текстовые
строки, пиктограммы, курсоры различной формы, произвольные
матричные графические изображения, меню, диалоговые панели,
произвольные массивы данных и т.д.
Физически ресурсы находятся внутри ехе-файла приложения.
Они могут загружаться в оперативную память автоматически при
запуске приложения или по запросу приложения (явному или неявному
). Такой механизм обеспечивает экономное использование оперативной памяти, так как все редко используемые данные можно
хранить на диске и загружать в память только при необходимости.
Цель работы: ознакомить студентов с работой ресурсов
WINDOWS – данных, которые добавляются в файл загрузочного
модуля приложения Windows и могут при необходимости загружаться в оперативную память. Расположение
их в ресурсах прило-
жения позволяет достичь более эффективного использования памяти.
ОПИСАНИЕ РАБОТЫ
1.1. Включение ресурсов
Для включения ресурсов в загрузочный модуль приложения вам
надо создать текстовый файл описания ресурсов.
Файл описания ресурсов имеет расширение имени .rc. Его необходимо включить в проект приложения наряду с файлами исходных текстов и файлом определения модуля.
В процессе сборки загрузочного модуля файл описания ресурсов компилируется
специальным компилятором ресурсов rc.ехе.
Компилятор ресурсов поставляется вместе с системой разработки
приложений Windows. Он преобразует входной текстовый файл
описания ресурсов в двоичный файл с расширением имени .res (вы
можете указывать в проекте либо текстовый, либо двоичный вариант файла описания ресурсов, однако лучше использовать текстовый
вариант, так как его можно редактировать). Перед
запуском компилятора ресурсов система разработки приложений Windows запускает
препроцессор текстового описания – ресурсов rcpp.ехе, который об-
18

рабатывает разделители комментариев и директивы препроцессора
Си.
На финальном этапе сборки загрузочного модуля компилятор
ресурсов rc.eхe вызывается еще раз для записи ресурсов в загрузочный модуль. Дополнительно компилятор ресурсов формирует специальную таблицу ресурсов, расположенную в заголовке ехе-файла.
Таблица ресурсов используется Windows для поиска и загрузки ресурсов в оперативную память
Исходные тексты приложения Windows, составленные на языках программирования С, C++ или на языке Ассемблера, компилируются в объектные модули *.obj. С помощью утилиты tlib.exe объектные модули могут быть собраны в библиотеки *.lib. Далее редактор связей, входящий в систему разработки приложений Windows,
собирает из объектных модулей промежуточный вариант загрузочного модуля, не
определения модуля *.def.
Файл описания ресурсов *.rc компилируется утилитой rc.ехе в
двоичный файл *.res. На последней стадии формирования загрузочного модуля промежуточный вариант ехе-файла комбинируется с
файлом ресурсов для получения окончательного варианта загрузочного модуля.
Таблица строк содержит текстовые
нулем, на которые можно ссылаться по идентификатору. Идентификатор представляет собой обыкновенное целое число. Вместо чисел
обычно используют символические имена, определенные с помощью директивы #define.
1.2.1. Создание таблицы
Для создания таблицы строк текстовый файл описания ресурсов
должен содержать оператор STRINGTABLE:
STRINGTABLE [параметры загрузки][тип памяти]
BEGIN StringID, строка
...
...
...
END
содержащий ресурсов. При этом используется файл
1.2. Таблица текстовых строк
.
строки, закрытые двоичным
19

Операторы BEGIN и END определяют границы таблицы строк в
файле описания ресурсов. Между ними находятся строки с идентификаторами StringID.
1.2.2. Загрузка строки из таблицы
Для загрузки строки в оперативную память необходимо использовать функцию LoadString:
int WINAPI LoadString(
HINSTANCE hinst, // идентификатор приложения
UINT idResource, // идентификатор ресурса
LPSTR lpszBuffer, // адрес буфера
int cbBuffer); // размер буфера в байтах
Параметр hInst определяет идентификатор запущенного приложения,
вую строку.
Вы должны использовать одно из значений, заданных в файле описания ресурсов.
загружена строка. Размер буфера должен быть задан через параметр
cbBuffer. Если размер строки окажется больше указанного размера
буфера,
ных в буфер, или 0, если файл загрузочного модуля не содержит
строки с указанным идентификатором (или если в этом файле вообще нет таблицы строк).
1.2.3. Функции для работы с текстовыми строками
вызывать стандартные функции библиотеки компилятора
strcat или strcopy. Однако лучше использовать функции для работы с
текстовыми строками, определенные в программном интерфейсе
Windows. Эти функции используют дальние указатели на строки и
учитывают специфику национальных алфавитов. Кроме того, указанные функции находятся в ядре Windows, поэтому при их использовании не происходит увеличения размера файла загрузочного модуля
из загрузочного файла которого необходимо извлечь тексто-
Параметр idResource указывает идентификатор нужной строки.
Указатель lpszBuffer определяет адрес буфера, в который будет
строка будет обрезана.
Функция LoadString возвращает количество символов, записан-
Для работы с текстовыми строками приложения Windows могут
, такие, как
приложения.
20
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
