Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

OC Windows & OC Linux. Лабораторные работы по курсу «Операционные системы»

.pdf
Скачиваний:
0
Добавлен:
06.09.2026
Размер:
2 Мб
Скачать
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 functi­ons 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_APPLI­CATION. Параметр задает способ закраски фона. Он может содер­жать либо идентификатор физической кисти, либо один из стан­дартных цветов, например: COLOR_WINDOW – выбранный в пане­ли управления цвет для фона окна, COLOR_BACKGROUND – цвет рабочего стола и т.д. Параметр lpszMenuName задает торое будет выбираться для всех окон, для которых не задано собст-
имя меню, ко-
13
венное меню. Параметр lpszClassName указывает на имя класса, ко­торое будет его однозначно идентифицировать и использоваться при создании окон.
После описания класса необходимо его зарегистрировать в сис­теме. Для этого используется функция RegisterClass:
ATOM RegisterClass(lpwc) const WNDCLASS FAR* lpwc; //адрес структуры с данными класса
В случае успеха она возвращает значение-атом, идентифици­рующее этот класс, в случае ошибки – нулевое значение.
Для того чтобы создать окно, используется функция CreateWin-
dow:
HWND CreateWindow(lpszClassName, lpszWindow­Name, dwStyle, x, y, nWidth, nHeight, hwndPar­ent,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 и тотчас же возвращает управление назад.
Все необработанные сообщения должны быть переданы стан­дартной процедуре обработки. Она вызывается функцией DefWin­dowProc, которая принимает те же параметры, что и процедура окна:
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