Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Programming_Windows_95_Part_I.pdf
Скачиваний:
96
Добавлен:
05.06.2014
Размер:
4.61 Mб
Скачать

300

Раньше при обсуждении битовых образов говорилось, что 0 необязательно означает черный цвет, а 1 необязательно означает белый. Как вы можете теперь видеть, это зависит от того, как Windows использует битовые образы.

В программе RESOURC1 мы определили класс окна так, чтобы фон рабочей области был COLOR_WINDOW. Вы можете изменить цвет окна с помощью программы Control Panel, чтобы увидеть, как меняются цвета значка и курсора.

Получение описателя значков

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

myicon ICON iconfile.ico

где ICONFILE.ICO — имя файла значка. В этой инструкции значку присваивается имя "myicon". В программе на С для получения описателя значка используется функция LoadIcon. В функции LoadIcon имеется два параметра. Первым является описатель экземпляра вашей программы, который в WinMain обычно называется hInstance. Этот описатель требуется для Windows, чтобы определить, в каком файле с расширением .EXE содержится ресурс значка. Вторым параметром является имя значка из описания ресурсов, заданное в виде указателя на оканчивающуюся нулем строку. Возвращаемым значением функции LoadIcon является значение типа HICON, которое определяется в WINDOWS.H.

Имеется связь между именем значка в описании ресурсов и в инструкции, содержащей функцию LoadIcon вашей программы на С:

Описание ресурсов:

myicon ICON iconfile.ico

Исходный текст программы:

hIcon = LoadIcon (hInstance, "myicon");

Не беспокойтесь о том, в верхнем или нижнем регистре задано имя значка. Компилятор преобразует в файле описания ресурсов имя значка в символы верхнего регистра и вставляет это имя в таблицу ресурсов в заголовке файла программы с расширением .EXE. При первом вызове функции LoadIcon, Windows преобразует строку, заданную вторым параметром в символы верхнего регистра и отыскивает в таблице ресурсов файла с расширением

.EXE совпадающее с этой строкой имя.

Вместо имени вы также можете использовать число (16-разрядное беззнаковое WORD). Это число называется идентификатором (ID) значка. Ниже показано как это делается:

Описание ресурсов:

125 ICON iconfile.ico

Исходный текст программы:

hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (125));

MAKEINTRESOURCE (make an integer into a resourse string — преобразовать целое в строку ресурса) является макросом, определенным в заголовочных файлах Windows, который преобразует число в указатель, но со старшими 16 разрядами, установленными в нуль. Так Windows узнает, что второй параметр функции LoadIcon является числом, а не указателем на символьную строку.

В примерах программ, представленных ранее в этой книге, использовались предопределенные значки:

LoadIcon(NULL, IDI_APPLICATION);

Поскольку параметр hInstance установлен в NULL, Windows узнает, что этот значок является предопределенным. IDI_APPLICATION также определяется в заголовочных файлах Windows с использованием макроса

MAKEINTRESOURCE:

#define IDI_APPLICATION MAKEINTRESOURCE(32512)

Предопределенные значки и курсоры являются частью файла драйвера дисплея.

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

Описание ресурсов:

125 ICON iconfile.ico

Исходный текст программы:

hIcon = LoadIcon (hInstance, "#125");

По символу # операционная система Windows определяет, что далее следует число в ASCII-коде.

Как насчет четвертого способа? В этом способе используется макроопределение в заголовочном файле, который включается (с помощью директивы #include) и в файл описания ресурсов, и в вашу программу:

Заголовочный файл:

#define myicon 125

Описание ресурсов:

myicon ICON iconfile.ico

301

Исходный текст программы: hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (myicon));

При использовании этого способа будьте внимательны! Хотя регистр символов при использовании строки в качестве имени значка не имеет значения, он приводит к различию идентификаторов, генерируемых с помощью инструкций #define.

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

Использование значков в вашей программе

Хотя для обозначения программ Windows использует значки несколькими способами, во множестве программ для Windows значок задается только при определении класса окна:

wndclass.hIcon = LoadIcon(hInstance, "MyIcon");

.

.

.

wndclass.hIconSm = LoadIcon(hInstance, "MySmIcon");

Вы можете в обеих инструкциях сослаться на один и тот же значок стандартного размера, и Windows при выводе маленького значка на экран просто приведет его к необходимому размеру. Если в дальнейшем вы захотите изменить значок программы, это можно сделать с помощью функции SetClassLong. Предположим, что у вас в описании ресурсов был второй значок:

anothericon ICON iconfil2.ico

С помощью следующей инструкции вы можете заменить этот значок значком "myicon":

SetClassLong( hwnd, GCL_HICON, LoadIcon(hInstance, "anothericon") );

Маленький значок можно заменить с помощью GCL_HICONSM. Если вы сохранили описатель значка, возвращенный функцией LoadIcon, то вы также можете и нарисовать значок в рабочей области вашего окна:

DrawIcon(hdc, x, y, hIcon);

Сама Windows использует функцию DrawIcon при выводе значка вашей программы в соответствующее место. Windows получает описатель значка из структуры класса окна. Вы можете получить описатель тем же способом:

DrawIcon(hdc, x, y, GetClassLong(hwnd, GCL_HICON));

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

resourc1 ICON resourc1.ico

Поскольку символьная строка "Resourc1" хранится в массиве szAppName и уже используется программой в качестве имени класса окна, функция LoadIcon вызывается просто:

LoadIcon(hInstance, szAppName);

Можно заметить, что функция LoadIcon для одного и того же значка вызывается трижды, дважды при определении класса окна в WinMain и еще раз при получении описателя значка во время обработки сообщения WM_CREATE в WndProc. Троекратный вызов функции LoadIcon не создает проблем, поскольку возвращаемым значением функции является один и тот же описатель. Фактически, Windows только однажды загружает значок из файла с расширением .EXE.

Использование альтернативных курсоров

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

Описание ресурсов: mycursor CURSOR cursfile.cur

Исходный текст программы: hCursor = LoadCursor (hInstance, "mycursor");

Другие способы, показанные для значков (использование идентификаторов и MAKEINTRESOURCE), также работают и для курсоров. В заголовочные файлы Windows включается определение typedef HCURSOR, которое вы можете использовать для хранения описателя курсора.

Вы можете использовать описатель курсора, полученный при вызове функции LoadCursor, при задании поля hCursor структуры класса окна:

302

wndclass.hCursor = LoadCursor(hInstance, "mycursor");

Это заставляет курсор мыши, если он оказывается в рабочей области вашего окна, превращаться в ваш пользовательский курсор.

Если вы используете дочерние окна, можно сделать так, чтобы курсор выглядел по-разному в разных окнах. Если в вашей программе определяются классы этих дочерних окон, то для каждого класса вы можете использовать свой курсор путем соответствующей установки поля hCursor в каждом классе окна. А если вы используете предопределенные дочерние элементы управления, то изменить поле hCursor класса окна можно с помощью функции:

SetClassLong(hwndChild, GCL_HCURSOR, LoadCursor(hInstance, "childcursor"));

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

SetCursor(hCursor);

Функцию SetCursor следует вызывать при обработке сообщения WM_MOUSEMOVE. В противном случае для перерисовки курсора при его движении Windows использует курсор, ранее заданный в классе окна.

В программе RESOURC1 для задания имени курсора используется имя программы:

resourc1 CURSOR resourc1.cur

Когда в исходном тексте программы RESOURC1.С задается класс окна, переменная szAppName используется следующим образом в функции LoadCursor:

wndclass.hCursor = LoadCursor(hInstance, szAppName);

Битовые образы: картинки в пикселях

Мы уже говорили об использовании битовых образов в значках и курсорах. В Windows также включен тип ресурсов с именем BITMAP.

Битовые образы используются в двух главных целях. Первая — рисование на экране картинок. Например, файлы драйверов дисплеев в Windows содержат массу крошечных битовых образов, которые используются для рисования стрелок в полосах прокрутки, галочек в раскрывающихся меню, изображений на кнопках изменения размеров окна, флажках и переключателях. Вы можете использовать битовые образы в меню (как показано в главе 10) и панелях инструментов приложений (как показано в главе 12). В таких программах, как Paint, битовые образы используются для изображения графического меню.

Вторая цель использования битовых образов — создание кистей. Кисти, как вы уже знаете, являются шаблонами пикселей, которые Windows использует для закрашивания изображаемых на экране областей.

Использование битовых образов и кистей

Программа RESOURC2, приведенная на рис. 9.2, является модернизированной версией программы RESOURC1, включающей в себя ресурс монохромного битового образа, используемый для создания кисти фона рабочей области. С помощью редактора изображений был создан битовый образ размерами 8 на 8 пикселей, что является минимальным размером для кисти.

RESOURC2.MAK

#------------------------

# RESOURC2.MAK make file

#------------------------

resourc2.exe : resourc2.obj resourc2.res $(LINKER) $(GUIFLAGS) -OUT:resourc2.exe \

resourc2.obj resourc2.res $(GUILIBS) resourc2.obj : resourc2.c

$(CC) $(CFLAGS) resourc2.c

resourc2.res : resourc2.rc resourc2.ico resourc2.cur resourc2.bmp

$(RC) $(RCVARS) resourc2.rc

RESOURC2.C

/*-----------------------------------------------------------

RESOURC2.C -- Icon and Cursor Demonstration Program No. 2

(c) Charles Petzold, 1996

303

-----------------------------------------------------------*/

#include <windows.h>

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

char

szAppName[] = "Resourc2";

HINSTANCE

hInst;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)

{

 

HBITMAP

hBitmap;

HBRUSH

hBrush;

HWND

hwnd;

MSG

msg;

WNDCLASSEX

wndclass;

hBitmap = LoadBitmap(hInstance, szAppName); hBrush = CreatePatternBrush(hBitmap);

wndclass.cbSize

= sizeof(wndclass);

wndclass.style

= CS_HREDRAW | CS_VREDRAW;

wndclass.lpfnWndProc

= WndProc;

wndclass.cbClsExtra

= 0;

wndclass.cbWndExtra

= 0;

wndclass.hInstance

= hInstance;

wndclass.hIcon

= LoadIcon(hInstance, szAppName);

wndclass.hCursor

= LoadCursor(hInstance, szAppName);

wndclass.hbrBackground

= hBrush;

wndclass.lpszMenuName

= NULL;

wndclass.lpszClassName

= szAppName;

wndclass.hIconSm

= LoadIcon(hInstance, szAppName);

RegisterClassEx(&wndclass);

hInst = hInstance;

hwnd = CreateWindow(szAppName, "Icon and Cursor Demo", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);

ShowWindow(hwnd, iCmdShow);

UpdateWindow(hwnd);

while(GetMessage(&msg, NULL, 0, 0))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

DeleteObject((HGDIOBJ)

hBrush);

// clean-up

DeleteObject((HGDIOBJ)

hBitmap);

 

return msg.wParam;

}

LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)

{

static HICON hIcon;

static int cxIcon, cyIcon, cxClient, cyClient; HDC hdc;

304

PAINTSTRUCT

ps;

int

x, y;

switch(iMsg)

{

case WM_CREATE :

hIcon = LoadIcon(hInst, szAppName); cxIcon = GetSystemMetrics(SM_CXICON); cyIcon = GetSystemMetrics(SM_CYICON); return 0;

case WM_SIZE :

cxClient = LOWORD(lParam); cyClient = HIWORD(lParam); return 0;

case WM_PAINT :

hdc = BeginPaint(hwnd, &ps);

for(y = cyIcon; y < cyClient; y += 2 * cyIcon) for(x = cxIcon; x < cxClient; x += 2 * cxIcon)

DrawIcon(hdc, x, y, hIcon);

EndPaint(hwnd, &ps); return 0;

case WM_DESTROY : PostQuitMessage(0); return 0;

}

return DefWindowProc(hwnd, iMsg, wParam, lParam);

}

RESOURC2.RC

/*-----------------------------

RESOURC2.RC resource script

-----------------------------

 

 

*/

 

 

 

 

resourc2

ICON

resourc2.ico

 

 

resourc2

CURSOR

resourc2.cur

 

 

resourc2

BITMAP

resourc2.bmp

 

 

RESOURC2.ICO

RESOURC2.CUR

RESOURC2.BMP

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Рис. 9.2 Программа RESOURC2, содержащая значок, курсор и битовый образ

Битовый образ включается в файл описания ресурсов в том же формате, что значок или курсор:

resourc2 BITMAP resourc2.bmp

Используемая в WinMain функция LoadBitmap аналогична функциям LoadIcon и LoadCursor. Ее возвращаемым значением является описатель битового образа:

hBitmap = LoadBitmap(hInstance, szAppName);

Этот описатель затем используется для создания шаблонной кисти (pattern brush). Основой кисти является битовый образ:

hBrush = CreatePatternBrush(hBitmap);

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

Соседние файлы в предмете Операционные системы