Операционная система Microsoft Windows 3.1 для программиста -том 2

         

Произвольные данные


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



Редактирование таблицы строк


При разработке приложения, когда вам доступны его исходные тексты, таблицу строк лучше всего редактировать в файле описания ресурсов обычным текстовым редактором, например, входящим в состав системы разработки приложений Borland C++ for Windows. Однако иногда возникает необходимость отредактировать содержимое таблицы строк или другие ресурсы готового приложения. В этом случае мы рекомендуем вам воспользоваться приложением Resource Workshop.

Этот инструмент обладает широкими возможностями. С его помощью вы можете создать новые ресурсы или отредактировать имеющиеся в загрузочном файле приложения, текстовом или двоичном файле описания ресурсов. Из-за ограниченного объема книги мы не можем привести полное описание приложения Resource Workshop, однако постепенно мы расскажем вам о том, как его использовать для создания или редактирования основных типов ресурсов.

Для начала давайте попробуем использовать Resource Workshop для редактирования строк только что описанного приложения STRING.

Запустите приложение Resource Workshop. Его пиктограмма должна находиться в группе системы разработки приложений Borland C++ for Windows.

Затем из меню "File" выберите строку "Open Project...". На экране появится диалоговая панель "Open Project" (рис. 1.3).

Рис. 1.3. Диалоговая панель "Open Project"

При помощи меню "File Type" вы можете выбрать тип файла, из которого собираетесь загрузить ресурсы для редактирования. Как видно из рисунка, ресурсы могут содержаться в файлах разных типов, например, в библиотеке динамической загрузки DLL или в драйвере устройства DRV.

Так как мы собираемся изменить таблицу строк в готовом приложении Windows, выберите в меню "File Type" строку "EXE application". Затем с помощью меню "Path", "Files" и "Directories" укажите путь к загрузочному файлу приложения. В нашем случае надо выбрать файл string.exe. После этого в главном окне приложения Resource Workshop появится окно с заголовком "string.exe", в котором будут перечислены все имеющиеся в файле ресурсы (рис. 1.4).




Рис. 1.4. Ресурсы из файла string.exe



Файл string. exe содержит только один тип ресурсов - таблицу строк STRINGTABLE. Для редактирования таблицы сделайте двойной щелчок левой клавишей мыши по цифре 1, расположенной в окне "string.exe". В главном окне приложения Resource Workshop появится окно "STRINGTABLE:1" (рис. 1.5).



Рис. 1.5. Окно "STRINGTABLE:1"

В этом окне в столбце "String" вы можете отредактировать текстовые строки.

После редактирования сохраните изменения, выбрав в меню "File" строку "Save Project".

На рис. 1.6 представлен результат "локализации" приложения STRING описанным выше образом. Мы перевели сообщение и заголовок окна на русский язык, не меняя файл описания ресурсов и не выполняя повторную сборку проекта.



Рис. 1.6. Измененное приложение STRING

Однако есть одна небольшая проблема. К сожалению, Resource Workshop, который поставляется вместе с системой разработки Borland C++ for Windows версии 3.1, не понимает русские буквы "ю" и "я". При вводе строк, содержащих эти буквы, на экране появляется сообщение об ошибке (рис. 1.7).



Рис. 1.7. Сообщение об ошибке приложения Resource Workshop

Возможно, в следующих версиях Resource Workshop эта ошибка (или особенность!) будет исправлена, а пока вместо букв "ю" и "я" мы рекомендуем указывать соответствующие им восьмеричные коды. Букве "ю" соответствует код \376, букве "я" - код \377. При этом строка будет выглядеть так:

Возможно, в следу\376щих верси\377х это будет исправлено


Редактор текста


В операционной системе Microsoft Windows зарегистрирован класс окна с именем "edit", на базе которого вы можете создать однострочный или многострочный текстовый редактор. Такой редактор может быть использован для ввода значений текстовых или числовых переменных, а также для создания и редактирования текстовых файлов (без функций форматирования текста). Встроенный текстовый редактор умеет выполнять функции выделения текста, может работать с универсальным буфером обмена Clipboard.

Для того чтобы в среде Windows сделать свой собственный текстовый редактор, вам достаточно создать на базе класса "edit" орган управления, вызвав функцию CreateWindow. После этого функция родительского окна будет получать от редактора сообщение с кодом WM_COMMAND (как и от других аналогичных органов управления). Вместе с этим сообщением в функцию окна будут передаваться коды извещения, отражающие изменения состояния редактора текста. Вы также можете с помощью функции SendMessage посылать текстовому редактору около трех десятков различных управляющих сообщений, с помощью которых можно изменять редактируемый текст, получать отдельные строки, выделять фрагменты текста, копировать выделенный фрагмент текста в Clipboard и т. д.

Использование предопределенного класса "edit" - самый простой способ создания в приложении редактора текста. Фактически в этом случае вы будете использовать готовый текстовый редактор. Вам не придется самостоятельно обрабатывать сообщения от клавиатуры, управлять текстовым курсором, учитывать ширину букв в пропорциональном шрифте, выполнять свертку текста в окне редактирования по вертикали или горизонтали, заниматься выделением фрагментов текста, работать с Clipboard или решать другие задачи, возникающие при создании текстовых редакторов.



Ресурсы


1.1.

1.2.

1.3.

1.4.

1.5.

1.6.

1.7.

Мы уже говорили, что формат загрузочного модуля приложения Windows сложнее формата загрузочного модуля программы MS-DOS. Кроме выполняемого кода и констант в загрузочном модуле приложения Windows находятся дополнительные данные - ресурсы.

Что такое ресурсы?

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

Физически ресурсы находятся внутри exe-файла приложения. Они могут загружаться в оперативную память автоматически при запуске приложения или по запросу приложения (явному или неявному). Такой механизм обеспечивает экономное использование оперативной памяти, так как все редко используемые данные можно хранить на диске и загружать в память только при необходимости.

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

Ресурсы можно редактировать без повторной трансляции программного проекта. Это означает, что вы сможете легко перевести все сообщения и тексты меню вашего (и не только вашего!) приложения на другой национальный язык, отредактировать графические изображения или любые другие ресурсы, даже не имея в своем распоряжении исходные тексты приложения.

Для создания и редактирования ресурсов предназначены специальные приложения. Мы будем использовать приложение Resource Workshop, которое входит в состав системы разработки программного обеспечения Borland C++ for Windows версии 3.1. С помощью этого средства можно создавать новые ресурсы или редактировать уже имеющиеся. В частности, можно отредактировать ресурсы, расположенные внутри загрузочного модуля приложения Windows или внутри библиотеки динамической загрузки DLL.



СB_GETITEMDATA


Получение 32-битового значения, соответствующего заданной строке.

Параметры:

wParam = (WPARAM)nIndex;

lParam = 0L;

nIndex - номер строки, для которой нужно получить значение.

Возвращаемое значение:

Двойное слово, содержащее искомое значение, или код ошибки.



СB_GETITEMHEIGHT


Определение высоты заданной строки в списке, который рисуется родительским окном и имеет переменную высоту элементов. Это сообщение используется в Windows версии 3.1 и более поздних версий.

Параметры:

wParam = (WPARAM)nIndex;

lParam = 0L;

nIndex - номер строки, для которой нужно получить значение.

Возвращаемое значение:

Высота строки в пикселях или код ошибки.



Сообщение WM_COMMAND


Сообщение с кодом WM_COMMAND передается функции родительского окна от органа управления, созданного этим окном. При создании органа управления (например, кнопки на базе класса "button") вы вызываете функцию CreateWindow, которой указываете идентификатор родительского окна и идентификатор органа управления.

Если орган управления изменяет свое состояние (например, когда вы нажали на кнопку), функция родительского окна получает сообщение WM_COMMAND. Вместе с этим сообщением функция родительского окна получает в параметре wParam идентификатор органа управления. Младшее слово параметра lParam содержит идентификатор дочернего окна, т. е. идентификатор окна органа управления. Старшее слово содержит код извещения от органа управления (notification code), по которому можно судить о том, какое действие было выполнено над органом управления.

Когда вы нажимаете на кнопку, родительское окно получает сообщение WM_COMMAND с кодом извещения, равным BN_CLICKED. Получив такое сообщение, приложение определяет, что была нажата кнопка, идентификатор которой находится в параметре wParam.

При использовании кнопки устаревшего стиля BS_USERBUTTON функция родительского окна может получить сообщения с кодами извещения BN_DISABLE, BN_DOUBLECLICKED, BN_HLITE, BN_PAINT, BN_UNHILITE. В новых приложениях эти коды извещения не используются.

Орган управления BS_GROUPBOX не обрабатывает сообщения от мыши или клавиатуры и не посылает в родительское окно сообщение WM_CONTROL. Он используется в качестве объединяющей рамки с заголовком, внутри которой располагаются другие органы управления, такие как кнопки или переключатели.



Сообщения для кнопки


Для управления кнопкой вы можете использовать сообщение BM_SETSTATE, которое позволяет установить кнопку в нажатое или отжатое состояние.

Для установки кнопки в нажатое состояние следует передать ей сообщение BM_SETSTATE с параметром wParam, равным TRUE, и lParam, равным 0:

SendMessage(hButton, BM_SETSTATE, TRUE, 0L);

Для возврата кнопки в исходное состояние передайте ей то же самое сообщение, но с параметром wParam, равным FALSE:

SendMessage(hButton, BM_SETSTATE, FALSE, 0L);



Сообщения для органов управления


Органы управления, расположенные на поверхности диалоговой панели, посылают в функцию диалога сообщение WM_COMMAND. В свою очередь, приложение может посылать различные сообщения органам управления, вызывая функцию SendMessage.



Сообщения для редактора текста


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



Сообщения для списка


Для управления списком приложение посылает ему сообщения, вызывая функцию SendMessage. Эта функция возвращает значение, которое зависит от выполняемой функции или коды ошибок LB_ERRSPACE (ошибка при получении дополнительной памяти), LB_ERR (затребованная операция не может быть выполнена).

В файле windows.h определены сообщения, специально предназначенные для работы со списком. Символические имена этих сообщений имеют префикс LB_. Приведем список таких сообщений.


Для управления списком "combobox" используется набор сообщений, аналогичный набору сообщений для списка "listbox" и редактора текста "edit". Функция SendMessage, посылающая сообщения списку "combobox", возвращает значение, которое зависит от выполняемой функции или коды ошибок CB_ERRSPACE (ошибка при получении дополнительной памяти), CB_ERR (затребованная операция не может быть выполнена). Если операция выполнена без ошибок, возвращается значение CB_OKAY.

В файле windows.h определены сообщения, специально предназначенные для работы со списком "combobox". Символические имена этих сообщений имеют префикс CB_. Приведем список таких сообщений.



Сообщения от полосы просмотра


Все горизонтальные полосы просмотра, определенные для окна (одним из описанных выше способов) посылают в окно сообщение WM_HSCROLL, а все вертикальные - WM_VSCROLL.

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

Параметр wParam сообщений полосы просмотра содержит так называемый код полосы просмотра. Этот код соответствует действию, совершенном пользователем над полосой просмотра. Возможны следующие значения (символические константы для них определены в файле windows.h).

Код полосы просмотра Описание
SB_LEFT, SB_TOP (используются одинаковые значения констант для разных символических имен) Сдвиг влево в начало документа (горизонтальная полоса просмотра), сдвиг вверх в начало документа (вертикальная полоса просмотра)
SB_LINELEFT, SB_LINEUP Сдвиг влево на одну строку, сдвиг вверх на одну строку
SB_LINERIGHT, SB_LINEDOWN Сдвиг вправо на одну строку, сдвиг вниз на одну строку
SB_PAGELEFT, SB_PAGEUP Сдвиг на одну страницу влево, сдвиг на одну страницу вверх
SB_PAGERIGHT, SB_PAGEDOWN Сдвиг на одну страницу вправо, сдвиг на одну страницу вниз
SB_RIGHT, SB_BOTTOM Сдвиг вправо в конец документа, сдвиг вниз в конец документа
SB_THUMBPOSITION Сдвиг в абсолютную позицию. Текущая позиция определяется младшим словом параметра lParam
SB_ENDSCROLL Сообщение приходит в тот момент, когда вы отпускаете клавишу мыши после работы с полосой просмотра. Это сообщение обычно игнорируется (передается функции DefWindowProc)
SB_THUMBTRACK Перемещение ползунка полосы просмотра. Текущая позиция определяется младшим словом параметра lParam

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

Для сообщений SB_THUMBTRACK и SB_THUMBPOSITION младшее слово параметра lParam определяет текущую позицию ползунка на полосе просмотра.
Для других сообщений полосы просмотра младшее слово параметра lParam не используется.

Старшее слово параметра lParam содержит идентификатор окна для полосы просмотра (если временное окно имеет полосу просмотра, старшее слово параметра lParam не используется).

Несмотря на то, что в файле windows.h определены константы SB_LEFT, SB_TOP, SB_RIGHT, SB_BOTTOM, полоса просмотра никогда не посылает сообщений со значением параметра wParam, равным этим константам. Однако приложению имеет смысл предусмотреть обработчик для таких сообщений. Это нужно для подключения к полосе просмотра клавиатурного интерфейса.

Если запустить любое стандартное приложение Windows, работающее с текстовыми документами, можно убедится в том, что для свертки окна, отображающего документ, можно использовать не только полосу просмотра, но и клавиши. Обычно это клавиши перемещения курсора и клавиши <PgUp>, <PgDn>. Как правило, с помощью клавиш <Home> и <End> вы можете перейти, соответственно, в начало и в конец документа.

Так как действия, выполняемые при свертке, одинаковы для полосы просмотра и дублирующих ее клавиш, имеет смысл предусмотреть единый обработчик сообщений от полосы просмотра. Для добавления клавиатурного интерфейса обработчик клавиатурного сообщения WM_KEYDOWN может посылать в функцию окна сообщения полосы просмотра. Например, если обработчик сообщения WM_KEYDOWN обнаружил, что вы нажали клавишу <PgUp>, он может послать в функцию окна сообщение WM_VSCROLL со значением wParam, равным SB_PAGEUP. Результат будет в точности такой же, как будто для свертки документа на одну страницу вверх вы воспользовались полосой просмотра, а не клавиатурой.

Если же обработчик клавиатурного сообщения WM_KEYDOWN обнаружил, что вы нажали клавишу <Home> или <End>, он может послать в функцию окна, соответственно, сообщение WM_VSCROLL со значением wParam, равным SB_TOP или SB_BOTTOM. Если в приложении имеются обработчики этих сообщений, они выполнят переход в начало или в конец документа.

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


Создание диалоговой панели


Диалоговая панель обычно представляет собой временное (pop-up) окно, хотя допустимо использовать и перекрывающиеся (overlapped) окна. Для создания диалоговой панели вам не требуется вызывать функцию CreateWindow, так как в программном интерфейсе Windows определены функции, специально предназначенные для создания диалоговых панелей.

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

Помимо шаблона, перед созданием диалоговой панели вам следует определить специальную функцию диалога, в которую будут поступать сообщения от функции окна диалоговой панели (которые, в свою очередь, поступают туда от органов управления). Функция диалога похожа на функцию таймера (получающую сообщения от таймера). Так же, как и функция таймера (а также функция окна), функция диалога является функцией обратного вызова и должна быть описана с использованием ключевого слова _export. Вместо этого имя функции обратного вызова можно занести в раздел EXPORTS файла определения модуля.

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

создать шаблон диалога;

определить функцию диалога;

вызвать одну из функций создания диалога.



Создание и уничтожение немодальных диалоговых панелей


Для создания немодальных диалоговых панелей используются описанные нами ранее функции CreateDialog, CreateDialogParam, CreateDialogIndirect, CreateDialogIndirectParam.

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

Для обеспечения автоматического отображения немодальной диалоговой панели сразу после создания стиль панели, описанный в шаблоне, должен включать в себя константу WS_VISIBLE. В противном случае для отображения диалоговой панели придется вызывать функцию ShowWindow. Стиль DS_MODALFRAME используется только для модальных диалоговых панелей, поэтому его указывать не надо.

Завершение работы немодальной диалоговой панели следует выполнять с помощью функции DestroyWindow, указав ей в качестве параметра идентификатор окна панели, полученный от функции CreateDialog или от аналогичной функции, создающей немодальную диалоговую панель. Функция EndDialog должна использоваться только для завершения работы модальных диалоговых панелей.



Создание изображения типа bitmap


Для создания изображения bitmap запустите Resource Workshop и из меню "File" выберите строку "New Project". В появившейся диалоговой панели включите переключатель ".BMP" и нажмите кнопку "OK". На экране появится диалоговая панель "New bitmap Attributes" (рис. 1.13).

Рис. 1.13. Диалоговая панель "New bitmap Attributes"

В этой диалоговой панели вам надо выбрать ширину изображения в пикселях (поле "Width in pixels"), высоту изображения в пикселях (поле "Height in pixels"), количество цветов в изображении (2, 16 или 256). После выбора нажмите кнопку "OK". В главном окне Resource Workshop появятся окна для редактирования изображения (рис. 1.14).

Рис. 1.14. Создание изображения типа bitmap

При создании изображения bitmap используются те же инструменты, что и при создании пиктограммы или курсора. Вы можете выбрать в окне "Colors" любой доступный цвет, однако нельзя сделать прозрачные участки пиктограммы или участки, инвертирующие цвет фона.

Если размеры создаваемого изображения невелики, можно увеличить масштаб отображения при редактировании, выбрав из меню "View" строку "Zoom in". Для возврата к прежнему масштабу отображения выберите из этого же меню строку "Zoom out".

Для сохранения созданного изображения в файле выберите из меню "File" строку "Save file as..." и укажите имя файла.



Создание кисти для закрашивания окна


Одно из простых применений изображений bitmap - раскрашивание фона окна. С этой целью вы можете использовать изображения размером 8х8 точек, созданные при помощи Resource Workshop.

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

После загрузки изображения функцией LoadBitmap приложение должно создать из этого изображения кисть, вызвав функцию CreatePatternBrush:

HBRUSH WINAPI CreatePatternBrush(HBITMAP hBmp);

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

Функция CreatePatternBrush возвращает идентификатор кисти, который можно использовать при регистрации класса окна. Значение этого идентификатора следует записать в поле hbrBackground структуры wndclass, используемой для регистрации класса окна.

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



Создание кнопки


Для создания кнопки вам надо вызвать функцию CreateWindow. Мы уже рассказывали вам об этой функции в предыдущем томе. С помощью нее мы создавали окна во всех наших приложениях. Для удобства приведем прототип функции CreateWindow еще раз:

HWND CreateWindow(LPCSTR lpszClassName, LPCSTR lpszWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hwndParent, HMENU hmenu, HINSTANCE hinst, void FAR* lpvParam);

Параметр функции lpszClassName - указатель на строку, содержащую имя класса, на базе которого создается окно. Для создания кнопки необходимо указать имя класса "button".

Параметр функции lpszWindowName - указатель на строку, содержащую заголовок окна (Title Bar). Эта строка будет написана на кнопке.

Параметр dwStyle - стиль создаваемого окна. Этот параметр задается как логическая комбинация отдельных битов. Для кнопки следует задать стиль как комбинацию констант WS_CHILD, WS_VISIBLE и константы, определяющей один из возможных стилей кнопки.

Парамеры x и y функции CreateWindow определяют горизонтальную (x) и вертикальную (y) координату кнопки относительно верхнего левого угла родительского окна.

Параметры nWidth и nHeight определяют, соответственно, ширину и высоту создаваемой кнопки.

Параметр hwndParent определяет идентификатор родительского окна, на поверхности которого создается кнопка.

Параметр hmenu - идентификатор меню или идентификатор порожденного (child) окна. Для каждого создаваемого вами дочернего окна вы должны определить собственный идентификатор. Родительское окно будет получать от дочерних окон сообщения. При помощи идентификатора дочернего окна функция родительского окна сможет определить дочернее окно, пославшее сообщение родительскому окну.

Параметр hinst - идентификатор приложения, которое создает окно. Необходимо использовать значение, передаваемое функции WinMain через параметр hInstance.

Последний параметр функции (lpvParam) представляет собой дальний указатель на область данных, определяемых приложением. Этот параметр передается в функцию окна вместе с сообщением WM_CREATE при создании окна.
Для кнопки вы должны указать значение NULL.

Для создания кнопки с надписью "Help" в точке с координатами (10, 30) и размерами (40, 20) можно использовать, например, такой вызов функции CreateWindow:

hHelpButton = CreateWindow("button", "Help", WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, 10, 30, 40, 20, hWnd, (HMENU)IDB_Help, hInstance, NULL);

Стиль кнопки влияет на ее внешний вид и поведение:

Стиль кнопки Внешний вид Описание
BS_3STATE
Переключатель, который может находится в одном из трех состояний: включенном (квадратик перечеркнут), выключенном (квадратик не перечеркнут), неактивном (квадратик отображается серым цветом)
BS_AUTO3STATE
Аналогично стилю BS_3STATE, но внешний вид кнопки изменяется автоматически при ее переключении
BS_AUTOCHECKBOX
Переключатель, который может находиться в одном из двух состояний: включенном или выключенном. Внешний вид кнопки изменяется автоматически при ее переключении
BS_AUTORADIOBUTTON
Переключатель, который может находиться в одном из двух состояний: включенном (внутри окружности имеется жирная черная точка) или выключенном (окружность не закрашена). Внешний вид кнопки изменяется автоматически при ее переключении
BS_CHECKBOX
Переключатель, который может находиться в одном из двух состояний: включенном или выключенном.
BS_DEFPUSHBUTTON
Стандартная кнопка с толстой рамкой вокруг
BS_GROUPBOX
Прямоугольная область, внутри которой могут находиться другие кнопки. Обычно используется в диалоговых панелях. Этот орган управления не воспринимает сообщения от мыши или клавиатуры
BS_LEFTTEXT
Этот стиль указывается вместе с другими и означает, что текст, расположенный около кнопки, должен находиться слева, а не справа от кнопки
BS_OWNERDRAW Внешний вид определяется родительским окном Внешний вид кнопки определяется родительским окном, которое само рисует кнопку во включенном, выключенном или неактивном состоянии
BS_PUSHBUTTON
Стандартная кнопка без рамки
BS_RADIOBUTTON
Переключатель, который может находиться в одном из двух состояний: включенном или выключенном.
BS_USERBUTTON Внешний вид определяется родительским окном Устаревший стиль, аналогичный по назначению стилю BS_OWNERDRAW. Не рекомендуется к использованию. Этот стиль не описан в документации SDK для Windows версии 3.1, но определен в файле windows.h
Некоторые стили кнопок, описанные в этой таблице, используются для создания переключателей. Переключатели мы рассмотрим позже.

Таким образом, указав функции CreateWindow класс окна "button", мы создаем кнопку. Но с помощью класса "button" можно реализовать несколько перечисленных видов кнопок. Для уточнения вида кнопки мы дополнительно в стиле окна определяем стиль кнопки, указывая константу с префиксом имени BS_. За исключением константы BS_LEFTTEXT, допустимо указывать только одну из перечисленных выше констант. Константа BS_LEFTTEXT используется совместно с другими стилями кнопок, как правило, при создании кнопок в виде переключателей с текстом, расположенным слева от квадратика или кружка переключателя.


Создание курсора


Для создания файла, содержащего курсор, запустите приложение Resource Workshop. Из меню "File" выберите строку "New project...". В появившейся диалоговой панели включите переключатель ".CUR" и нажмите кнопку "OK".

На экране появятся окна, аналогичные используемым для редактирования пиктограмм (рис. 1.11).

Рис. 1.11. Редактирование курсора

После того как курсор будет нарисован, его следует сохранить в файле с расширением имени cur. Для этого выберите из меню "File" строку "Save file as...".



Создание пиктограммы


Приложение Resource Workshop позволяет вам создать пиктограммы размером 32х16 пикселов (для отображения на мониторах CGA), 32х32 пиксела (для отображения в стандартном режиме VGA) и 64х64 пиксела (для режимов SVGA с большим разрешением). Вы можете создать монохромную или цветную пиктограмму. Цветная пиктограмма содержит 8, 16 или 256 цветов (Windows версии 3.0 не умеет работать с пиктограммами, содержащими 256 цветов).

В одном файле *.ico допускается хранить несколько пиктограмм различного размера и с различным количеством цветов. В этом случае при выводе пиктограммы Windows сделает правильный выбор для текущего режима работы видеоадаптера.

Для того чтобы создать файл *.ico, запустите Resource Workshop и из меню "File" выберите строку "New Project...". В появившейся диалоговой панели выберите переключатель ".ICO" и нажмите кнопку "OK". На экране появится диалоговая панель "New icon image" (рис. 1.8).

Рис. 1.8. Диалоговая панель "New icon image"

В этой диалоговой панели вы должны выбрать нужный вам размер пиктограммы (переключатель "Size") и количество цветов, используемых в пиктограмме (переключатель "Colors").

Сделав выбор, нажмите кнопку "OK". На экране появятся окна, показанные на рис. 1.9.

Рис. 1.9. Создание новой пиктограммы

Большое окно с заголовком "ICON:ICON_1 32x32 2 Colors" предназначено для редактирования графического изображения пиктограммы и имеет полосу с инструментами, аналогичными используемым в стандартном для Windows приложении Paint Brush.

Фактически для пиктограммы любого формата используется два битовых изображения. Одно изображение является маской, второе - собственно графическим изображением пиктограммы. Накладывая маску, вы можете создать пиктограмму произвольной формы (а не только прямоугольную).

При помощи левой клавиши мыши вы можете выбрать цвет для изображения (на рисунке обозначен как FG), а при помощи левой - для фона пиктограммы (на рисунке обозначен как BG). Можно выбрать слово "Transparent", в этом случае будет использоваться "прозрачный" цвет. Участки пиктограммы, нарисованные с использованием режима "Inverted" (инвертировать) будут инвертировать цвет фона окна, над которым находится пиктограмма.

Для того чтобы добавить в файл *.ico еще один вариант пиктограммы, сделайте текущим окно "ICON:ICON_1" и из меню "Images" (появится после того как указанное выше окно станет активным) выберите строку "New Image...". Выберите нужное вам разрешение и приступайте к созданию нового варианта пиктограммы. Для этого сделайте двойной щелчок левой клавишей мыши по новой строке, появившейся в окне "ICON:ICON_1".

После создания файла пиктограммы сохраните его, выбрав из меню "File" строку "Save file as...". В появившейся диалоговой панели вам нужно указать путь и имя файла, использовав расширение имени *.ico.



Создание полосы просмотра


Существует два способа создания полос просмотра в окне приложения.

Во-первых, вы можете создать полосу просмотра с помощью функции CreateWindow, указав предопределенный класс окна "scrollbar". Этот способ аналогичен используемому при создании кнопок или статических органов управления. Во-вторых, при создании окна на базе своего собственного класса вы можете указать, что окно должно иметь горизонтальную, вертикальную или обе полосы просмотра.



Создание редактора текста


Для создания редактора текста (однострочного или многострочного) следует вызвать функцию CreateWindow, передав ей в качестве первого параметра указатель на строку "edit":

hwndEdit = CreateWindow("edit", NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT, 30, 30, 300, 30, hwnd, (HMENU) ID_EDIT, hInst, NULL);

Заголовок окна не используется, поэтому второй параметр следует указать как NULL.

Если при создании текстового редактора не указать стиль окна WS_BORDER, область редактирования не будет выделена. Это неудобно для пользователя, особенно если в окне имеется несколько редакторов. При использовании стиля WS_BORDER вокруг редактора будет нарисована рамка.

Кроме обычных стилей окна для текстового редактора указывают стили, символическое имя которых начинается с префикса ES_. Это стили редактора текста. Они влияют на внешний вид редактора и выполняемые им функции. Подробно стили редактора текста будут описаны в следующем разделе.

Остальные параметры функции CreateWindow указываются так же, как и для других органов управления. Параметры с четвертого по седьмой используются для определения расположения и размеров текстового редактора. Восьмой параметр - идентификатор родительского окна, в функцию которого будет поступать сообщение WM_COMMAND. Девятый параметр определяет идентификатор редактора текста. Десятый указывает идентификатор копии приложения. Последний параметр должен быть задан как NULL.



Создание шаблона диалога


Для создания шаблона диалога лучше всего воспользоваться редактором диалога Borland Resource Workshop или Microsoft Dialog Editor. Опишем процесс создания диалога с помощью редактора диалога, входящего в состав приложения Resource Workshop.



Создание списка


Для создания списка приложение должно вызвать функцию CreateWindow, передав в качестве первого параметра указатель на строку "listbox":

hListBox = CreateWindow("listbox", NULL, WS_CHILD | WS_VISIBLE | LBS_STANDARD | LBS_WANTKEYBOARDINPUT, 30, 30, 200, 100, hwnd, (HMENU) ID_LIST, hInst, NULL);

Второй параметр функции должен быть указан как NULL.

Дополнительно к стилям окна WS_CHILD и WS_VISIBLE при создании списка указываются специальные стили списка, символические имена которых имеют префикс LBS_.

Остальные параметры функции CreateWindow указываются так же, как и для других органов управления. Параметры с четвертого по седьмой используются для определения расположения и размеров списка. Восьмой параметр - идентификатор родительского окна, в функцию которого будет поступать сообщение WM_COMMAND. Девятый параметр определяет идентификатор списка. Десятый указывает идентификатор копии приложения. Последний параметр должен быть задан как NULL.



Создание списка COMBOBOX


Для того чтобы создать список класса "combobox" приложение должно вызвать функцию CreateWindow, передав в качестве первого параметра указатель на строку "combobox":

hComboBox = CreateWindow("ComboBox", NULL, WS_CHILD | WS_VISIBLE | WS_VSCROLL | CBS_AUTOHSCROLL | CBS_SIMPLE, 30, 30, 200, 200, hwnd, (HMENU) ID_LIST, hInst, NULL);

Второй параметр функции должен быть указан как NULL.

При создании списка "combobox" указываются специальные стили списка, символические имена которых имеют префикс CBS_.

Остальные параметры функции CreateWindow указываются так же, как и для списка класса "listbox".



Создание статического органа управления


Для создания статического органа управления вы должны использовать функцию CreateWindow. В качестве первого параметра этой функции следует указать класс окна "static":

HWND hStatic; hStatic = CreateWindow("static", NULL, WS_CHILD | WS_VISIBLE | SS_BLACKFRAME, 20, 40, 100, 50, hWnd, (HMENU)-1, hInstance, NULL);

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

В третьем параметре следует указать один из стилей статического органа управления. В нашем примере указан стиль SS_BLACKFRAME.

Так как статический орган управления не посылает сообщения родительскому окну, в качестве девятого параметра (идентификатор органа управления) можно указать любое число, например,­1.



Создание таблицы


Для создания таблицы строк текстовый файл описания ресурсов должен содержать оператор STRINGTABLE:

STRINGTABLE [параметры загрузки][тип памяти] BEGIN StringID, строка ... ... ... END

В качестве параметров загрузки можно указывать значения PRELOAD или LOADONCALL (используется по умолчанию). Ресурс с параметром загрузки LOADONCALL загружается в память при обращении к нему со стороны приложения. Ресурс типа PRELOAD загружается сразу после запуска приложения.

Тип памяти, выделяемой при загрузки ресурса, может быть FIXED или MOVABLE. Дополнительно для ресурсов типа можно указать MOVABLE тип DISCARDABLE. Если указан тип FIXED, ресурс будет находиться в памяти по постоянному адресу. Ресурс типа MOVABLE может перемещаться Windows при необходимости уплотнения памяти. Если для перемещаемого ресурса указан тип DISCARDABLE, Windows может забрать у приложения память, выделенную для ресурса. Если ресурс потребуется приложению, Windows загрузит его повторно из exe-файла приложения.

Операторы BEGIN и END определяют границы таблицы строк в файле описания ресурсов. Между ними находятся строки с идентификаторами StringID:

STRINGTABLE BEGIN 1, "Файл %s не найден" 2, "Ошибка при записи в файл %s" 3, "Ошибка ввода/вывода" END



Список класса COMBOBOX


В этом разделе мы рассмотрим орган управления, создаваемый на базе предопределенного класса "combobox". Этот орган является комбинацией списка и однострочного редактора текста, поэтому для списка "combobox" используются стили, коды извещения и сообщения, аналогичные списку "listbox", а также некоторые сообщения, специфические для редактора текста класса "edit".



Список класса LISTBOX


Перед программистом часто встает задача организации списка, предназначенного для выбора строки из некоторого определенного заранее набора строк. Например, вам может потребоваться список файлов из текущего каталога, список названий цветов для раскраски какого-либо объекта приложения, список режимов работы приложения и т. д. Стандартные диалоговый панели "Open" и "Save As" содержат списки файлов, каталогов и дисковых устройств.

Операционная система Windows имеет мощное средство организации списков - органы управления класса "listbox" и "combobox". В этом разделе мы рассмотрим список, созданный на базе класса "listbox". О том, как создавать и использовать список класса "combobox", вы узнаете из раздела с названием "Список класса COMBOBOX".

С помощью класса "listbox" вы можете создавать одноколоночные и многоколоночные списки, имеющие вертикальную (для одноколоночных списков) и горизонтальную (для многоколоночных списков) полосу просмотра. Родительское окно может само рисовать элементы списка, аналогично тому, как оно рисует кнопки.



Статический орган управления


Статический орган управления - это окно, создаваемое на базе предопределенного класса "static". Строго говоря, статический орган управления нельзя использовать для управления работой приложения, так как он не воспринимает щелчки мыши и не способен обрабатывать сообщения от клавиатуры. Статический орган управления не посылает родительскому окну сообщение WM_COMMAND.

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

Зачем же нужен такой орган управления, который ничем не управляет?

Обычно этот орган управления используется для оформления внешнего вида диалоговых панелей или окон приложения. Задавая различные стили, вы можете создать статический орган управления в виде закрашенного или незакрашенного прямоугольника, а также строки текста. Статические органы управления могут использоваться внутри диалоговых панелей для отображения пиктограмм.



Стили полосы просмотра


При создании полосы просмотра функцией CreateWindow вы можете указать в третьем параметре следующие стили.

Стиль Описание
SBS_BOTTOMALIGN Создается горизонтальная полоса просмотра, высота которой равна высоте системной полосы просмотра. Выполняется выравнивание нижнего края полосы просмотра по нижнему краю прямоугольника, координаты и размер которого определен при вызове функции CreateWindow. Этот стиль должен использоваться вместе со стилем SBS_HORZ
SBS_HORZ Создается горизонтальная полоса просмотра. Размер и расположение полосы просмотра определяются при вызове функции CreateWindow
SBS_LEFTALIGN Создается вертикальная полоса просмотра, ширина которой равна ширина системной полосы просмотра. Левый край полосы просмотра выравнивается по левому краю прямоугольника, координаты и размер которого определен при вызове функции CreateWindow. Этот стиль должен использоваться вместе со стилем SBS_VERT
SBS_RIGHTALIGN Создается вертикальная полоса просмотра, ширина которой равна ширина системной полосы просмотра. Правый край полосы просмотра выравнивается по правому краю прямоугольника, координаты и размер которого определен при вызове функции CreateWindow. Этот стиль должен использоваться вместе со стилем SBS_VERT
SBS_SIZEBOX Создается орган управления с небольшим прямоугольником серого цвета (Size Box). Если вы установите курсор мыши внутрь органа управления, нажмете левую клавишу мыши и будете перемещать мышь, родительское окно будет получать сообщения, аналогичные сообщениям от рамки, предназначенной для изменения размера окна.
SBS_SIZEBOXBOTTOMRIGHTALIGN Аналогично предыдущему, но правый нижний угол прямоугольника выравнивается по правому нижнему углу прямоугольника, координаты и размер которого определен при вызове функции CreateWindow. Этот стиль должен использоваться вместе со стилем SBS_SIZEBOX. Для высоты и ширины органа управления используются системные значения
SBS_SIZEBOXTOPLEFTALIGN Аналогично SBS_SIZEBOX, но верхний левый угол прямоугольника выравнивается по верхнему левому углу прямоугольника, координаты и размер которого определен при вызове функции CreateWindow. Этот стиль должен использоваться вместе со стилем SBS_SIZEBOX. Для высоты и ширины органа управления используются системные значения
SBS_TOPALIGN Создается горизонтальная полоса просмотра, высота которой равна высоте системной полосы просмотра. Выполняется выравнивание верхнего края полосы просмотра по верхнему краю прямоугольника, координаты и размер которого определен при вызове функции CreateWindow. Этот стиль должен использоваться вместе со стилем SBS_HORZ
SBS_VERT Создается вертикальная полоса просмотра. Размер и расположение полосы просмотра определяются при вызове функции CreateWindow



Стили редактора текста


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

Стиль Описание
ES_AUTOHSCROLL Выполняется автоматическая свертка текста по горизонтали. Когда при наборе текста достигается правая граница окна ввода, весь текст сдвигается влево на 10 символов
ES_AUTOVSCROLL Выполняется автоматическая свертка текста по вертикали. Когда при наборе текста достигается нижняя граница окна ввода, весь текст сдвигается вверх на одну строку
ES_CENTER Центровка строк по горизонтали в многострочном текстовом редакторе
ES_LEFT Выравнивание текста по левой границе окна редактирования
ES_LOWERCASE Выполняется автоматическое преобразование введенных символов в строчные (маленькие)
ES_MULTILINE Создается многострочный редактор текста
ES_NOHIDESEL Если редактор текста теряет фокус ввода, при использовании данного стиля выделенный ранее фрагмент текста отображается в инверсном цвете. Если этот стиль не указан, при потере фокуса ввода выделение фрагмента пропадает и появляется вновь только тогда, когда редактор текста вновь получает фокус ввода
ES_OEMCONVERT Выполняется автоматическое преобразование кодировки введенных символов из ANSI в OEM и обратно. Обычно используется для ввода имен файлов
ES_PASSWORD Этот стиль используется для ввода паролей или аналогичной информации. Вместо вводимых символов отображается символ "*" или другой, указанный при помощи сообщения EM_SETPASSWORDCHAR (см. ниже раздел, посвященный сообщениям для редактора текста)
ES_READONLY Создаваемый орган управления предназначен только для просмотра текста, но не для редактирования. Этот стиль можно использовать в версии 3.1 операционной системы Windows или в более поздней версии
ES_RIGHT Выравнивание текста по правой границе окна редактирования
ES_UPPERCASE Выполняется автоматическое преобразование введенных символов в заглавные (большие)
ES_WANTRETURN Стиль используется в комбинации со стилем ES_MULTILINE. Используется только в диалоговых панелях. При использовании этого стиля клавиша <Enter> действует аналогично кнопке диалоговой панели, выбранной по умолчанию. Этот стиль можно использовать в версии 3.1 операционной системы Windows или в более поздней версии

Для создания однострочного редактора текста достаточно указать стиль ES_LEFT (который, кстати, определен в файле windows.h как 0). Для обеспечения свертки текста по горизонтали используйте дополнительно стиль ES_AUTOHSCROLL.

Если вам нужен многострочный редактор текста, укажите стиль ES_MULTILINE. Для обеспечения автоматической свертки текста по горизонтали и вертикали следует также указать стили ES_AUTOHSCROLL и ES_AUTOVSCROLL.

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

Многострочный редактор текста может иметь вертикальную и горизонтальную полосы просмотра. Для создания полос просмотра достаточно в стиле редактора указать константы WS_HSCROLL и WS_VSCROLL.



Стили списка


Приведем список стилей, которые используются для создания органа управления класса "listbox".

Имя стиля Описание
LBS_DISABLENOSCROLL Если в одноколоночном списке помещаются все строки, вертикальная полоса просмотра изображается в неактивном состоянии. Без указания стиля LBS_DISABLENOSCROLL в аналогичной ситуации вертикальная полоса просмотра пропадает. Этот стиль можно указывать для Windows версии 3.1 и более поздних версий
LBS_EXTENDEDSEL Можно выделять не только отдельные строки, но и сразу несколько расположенных рядом строк. Для этого можно использовать клавишу <Shift> или мышь
LBS_HASSTRINGS Создание списка, содержащего строки. Этот стиль используется для всех списков, за исключением тех, которые рисуются родительским окном
LBS_MULTICOLUMN Создание многоколоночного списка. Для того чтобы задать количество колонок, в список необходимо послать сообщение LB_SETCOLUMNWIDTH
LBS_MULTIPLESEL Можно выделять в списке несколько строк сразу. Выделенные строки могут находиться в любом месте списка, а не только рядом (как при использовании стиля LBS_EXTENDEDSEL)
LBS_NOINTEGRALHEIGHT Допустимо частичное отображение строк (например, в нижней части списка можно отображать верхнюю половину строки)
LBS_NOREDRAW Для списка не выполняется перерисовка содержимого при добавлении или удалении строк. Этот стиль может быть динамически добавлен или удален посылкой списку сообщения WM_SETREDRAW
LBS_NOTIFY Родительское окно, создавшее список, получит извещение, если пользователь выполнит в списке двойной щелчок мышью по строке
LBS_OWNERDRAWFIXED Создается список, который рисуется родительским окном, причем все элементы в списке имеют одинаковую высоту
LBS_OWNERDRAWVARIABLE Аналогично предыдущему, но элементы списка могут иметь разную высоту
LBS_SORT Строки списка будут отсортированы
LBS_STANDARD Комбинация наиболее употребительных стилей списка: LBS_NOTIFY, LBS_SORT, WS_BORDER и WS_VSCROLL
LBS_USETABSTOPS При выводе строк списка будет выполняться преобразование символов табуляции. По умолчанию один символ табуляции расширяется на 32 единицы ширины (эти единицы используются в диалоговых панелях)
LBS_WANTKEYBOARDINPUT При использовании этого стиля родительское окно, создавшее список, будет получать сообщения WM_VKEYTOITEM или WM_CHARTOITEM, если список имеет фокус ввода и пользователь работает со списком при помощи клавиатуры
<
Для создания простейшего одноколоночного списка имеет смысл использовать стиль LBS_STANDARD. В этом случае, если все строки списка не помещаются в окне, у списка появится вертикальная полоса просмотра. Если при удалении из списка некоторого количества строк размеры окна списка станут достаточны для одновременного отображения всех строк, полоса просмотра исчезнет.

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

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

Небольшое замечание относительно использования стиля LBS_WANTKEYBOARDINPUT. Если указан этот стиль, то сообщения WM_KEYDOWN и WM_CHAR, получаемые списком (имеющим фокус ввода), создают сообщения WM_VKEYTOITEM или WM_CHARTOITEM. Эти сообщения попадают в функцию родительского окна, благодаря чему последнее может отслеживать операции, выполняемые пользователем над списком при помощи клавиатуры.

Если список имеет стиль LBS_HASSTRINGS, родительское окно будет получать сообщение WM_VKEYTOITEM, а если не имеет - сообщение WM_CHARTOITEM.

Параметр wParam сообщения WM_VKEYTOITEM содержит виртуальный код нажатой клавиши. Например, если пользователь выделит строку в списке и нажмет клавишу <Enter>, родительское окно получит сообщение WM_VKEYTOITEM со значением параметра wParam, равным VK_RETURN. При этом оно может получить из списка выбранную строку и выполнить над ней необходимые действия.

Если родительское окно получает сообщение WM_CHARTOITEM, параметр wParam содержит код символа, соответствующего нажатой клавише.


Стили статического органа управления


Стили статического органа управление определяют внешний вид и применение органа.



Таблица текстовых строк


Мы начнем изучение ресурсов с самого простого в использовании - таблицы строк. Таблица строк содержит текстовые строки, закрытые двоичным нулем, на которые можно ссылаться по идентификатору. Идентификатор представляет собой обыкновенное целое число. Вместо чисел обычно используют символические имена, определенные с помощью директивы #define.



Текст


Статические органы управления удобно использовать для вывода текста. Вы можете использовать пять базовых стилей SS_LEFT, SS_RIGHT, SS_CENTER, SS_LEFTNOWORDWRAP, SS_SIMPLE и один модификатор SS_NOPREFIX.

При использовании стиля SS_LEFT приложение задает размер органа управления, внутри которого будет выведен текст. Орган управления выводит текст (используя для этого функцию DrawText), выравнивая его влево и выполняя свертку слов. Текст, который не поместился в окне, обрезается. Выполняется замена символов табуляции на пробелы.

Стили SS_RIGHT и SS_CENTER используются аналогично, но текст выравнивается, соответственно, по правой границе органа управления или центрируется.

При использовании стиля SS_LEFTNOWORDWRAP текст выводится без использования свертки слов и выравнивается по левой границе. Часть текста, которая не поместилась в окне, обрезается. Выполняется замена символов табуляции на пробелы.

Стиль SS_SIMPLE похож на стиль SS_LEFTNOWORDWRAP, но вывод текста выполняется быстрее (используется функция TextOut) и замена символов табуляции на пробелы не выполняется. Часть текста, которая не поместилась в окне, обрезается. При повторном выводе текста содержимое окна не стирается, поэтому новая строка не должна быть короче той, которая была выведена в окно раньше. Этот стиль имеет смысл комбинировать со стилем SS_NOPREFIX. В этом случае для вывода текста используется более быстрая функция ExtTextOut.

Модификатор SS_NOPREFIX используется также в тех случаях, когда необходимо отменить специальную обработку символа "&". Обычно этот символ не выводится статическими органами управления на экран, а следующий за ним символ изображается подчеркнутым (для изображения символа "&" его надо повторить два раза подряд).



Управление кнопкой из приложения


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



Управление полосой просмотра


Для установки ползунка в заданную позицию следует использовать функцию SetScrollPos:

int WINAPI SetScrollPos(HWND hwnd, int fnBar, int nPos, BOOL fRepaint);

Параметры hwnd и fnBar определяют, соответственно, идентификатор окна или органа управления и тип полосы просмотра.

Параметр nPos определяет новое положение ползунка. Значение этого параметра должно находиться в пределах установленного диапазона.

Параметр fRepaint определяет, нужно ли перерисовывать полосу просмотра после установки новой позиции. Если указано TRUE, полоса будет перерисована, если FALSE - нет.

Функция SetScrollPos возвращает значение предыдущей позиции или 0 в случае ошибки.

Для определения текущей позиции надо вызвать функцию GetScrollPos:

int WINAPI GetScrollPos(HWND hwnd, int fnBar);

Параметры этой функции определяют, соответственно, идентификатор окна или органа управления и тип полосы просмотра

Функция возвращает текущую позицию или 0, если идентификатор окна указан неправильно или окно не имеет полосы просмотра.

Иногда бывает нужно убрать из окна одну или обе полосы просмотра. Это нужно, например, в тех случаях, когда, например, после изменения размера окна документ поместился в нем целиком. С помощью функции ShowScrollBar вы можете скрывать или показывать полосы просмотра:

void WINAPI ShowScrollBar(HWND hwnd, int fnBar, BOOL fShow);

Параметр hwnd определяет идентификатор окна, имеющего полосу просмотра, или идентификатор полосы просмотра, созданного как орган управления.

Параметр fnBar определяет тип полосы просмотра, для которой выполняется установка диапазона изменения значений позиции. Кроме описанных нами ранее констант SB_CTL, SB_HORZ и SB_VERT вы можете использовать константу SB_BOTH. Эта константа предназначена для работы сразу с обеими полосами просмотра, определенными в стиле окна.

Параметр fShow определяет действие, выполняемое функцией. Если этот параметр равен TRUE, полоса просмотра (или обе полосы просмотра, если указано SB_BOTH) появляются в окне. Если же указать значение FALSE, полоса просмотра исчезнет.


Программный интерфейс операционной системы Windows версии 3.1 имеет в своем составе функцию EnableScrollBar, позволяющую разрешать или запрещать работу полосы просмотра:

BOOL WINAPI EnableScrollBar(HWND hwnd, int fnBar, UINT fuArrowFlag);

Первые два парамера этой функции аналогичны параметрам функции ShowScrollBar.

Параметр fuArrowFlag определяет, какие из кнопок полосы просмотра должны быть заблокированы или разблокированы:

Значение Описание
ESB_ENABLE_BOTH Обе кнопки полосы просмотра разблокированы
ESB_DISABLE_BOTH Обе кнопки полосы просмотра заблокированы
ESB_DISABLE_LEFT, ESB_DISABLE_UP, ESB_DISABLE_LTUP Заблокирована левая кнопка горизонтальной полосы просмотра или верхняя кнопка вертикальной полосы просмотра
ESB_DISABLE_RIGHT, ESB_DISABLE_DOWN, ESB_DISABLE_RTDN Заблокирована правая кнопка горизонтальной полосы просмотра или нижняя кнопка вертикальной полосы просмотра
Функция возвращает значение TRUE при успешном завершении или FALSE при ошибке (если, например, кнопки уже находятся в требуемом состоянии).


Включение изображения bitmap в файл описания ресурсов


Для включения изображения типа bitmap в файл описания ресурсов используется такой же способ, как и для включения пиктограмм. Файл описания ресурсов должен содержать оператор BITMAP:

BitmapID BITMAP [параметры загрузки] [тип памяти] имя файла

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

AppBitmap BITMAP mybrush.bmp

Идентификатор изображения bitmap BitmapID можно указывать как символическое имя или как целое число - идентификатор ресурса.



Включение курсора в файл описания ресурсов


Для включения курсора в файл описания ресурсов используется оператор CURSOR, аналогичный оператору ICON:

CursorID CURSOR [параметры загрузки] [тип памяти] имя файла

В качестве параметров загрузки можно указывать значения PRELOAD или LOADONCALL (используется по умолчанию). Ресурс с параметром загрузки LOADONCALL загружается в память при обращении к нему со стороны приложения. Ресурс типа PRELOAD загружается сразу после запуска приложения.

Тип памяти, выделяемой при загрузки ресурса, может быть FIXED или MOVEABLE. Дополнительно для ресурсов типа можно указать MOVEABLE тип DISCARDABLE. Если указан тип FIXED, ресурс будет находиться в памяти по постоянному адресу. Ресурс типа MOVEABLE может перемещаться Windows при необходимости уплотнения памяти. Если для перемещаемого ресурса указан тип DISCARDABLE, Windows может забрать у приложения память, выделенную для ресурса. Если ресурс потребуется приложению, Windows загрузит его повторно из exe-файла приложения.

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

AppCursor CURSOR mycursor.cur

Идентификатор курсора CursorID можно указывать как символическое имя (см. предыдущую строку) или как целое число - идентификатор ресурса:

789 CURSOR custom.cur

После сборки проекта файл курсора будет вставлен в исполняемый файл приложения Windows.

Для загрузки курсора следует использовать функцию LoadCursor:

HCURSOR WINAPI LoadCursor(HINSTANCE hInst, LPCSTR lpszCursor);

Для загрузки нового курсора из ресурсов приложения в качестве параметра hInst необходимо указать идентификатор приложения, полученный через параметр hInstance функции WinMain. Параметр lpszCursor должен при этом указывать на идентификатор ресурса.

Если в файле описания ресурсов идентификатор ресурса представлен символьной строкой, адрес этой строки необходимо указать в параметре lpszCursor:

HCURSOR hCustomCursor; hCustomCursor = LoadCursor(hInstance, "AppCursor");

Если же в качестве идентификатора ресурса-курсора использовано целое число, следует использовать макрокоманду MAKEINTRESOURCE:

HCURSOR hCustomCursor; hCustomCursor = LoadCursor(hInstance, MAKEINTRESOURCE(789));



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


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

IconID ICON [параметры загрузки] [тип памяти] имя файла

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

AppIcon ICON myicon.ico

Идентификатор пиктограммы IconID можно указывать как символическое имя (см. предыдущую строку) или как целое число - идентификатор ресурса:

456 ICON great.ico

После сборки проекта файл пиктограммы будет вставлен в исполняемый файл приложения Windows.



Включение произвольных данных в ресурсы приложения


Для включения произвольных данных в ресурсы приложения файл описания ресурсов должен содержать один или несколько операторов следующего вида:

RId [тип ресурса] [параметры загрузки] [тип памяти] имя файла

RId является идентификатором ресурса. Можно использовать любое имя или число.

Для типа ресурса вы можете выбрать любое обозначение. Разумеется, не следует выбирать названия предопределенных ресурсов, такие как ICON или CURSOR.

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

Hello SOUND hello.wav

Вся работа по подготовке файла с данными выполняется программистом перед сборкой проекта.



Включение ресурсов


Для включения ресурсов в загрузочный модуль приложения вам надо создать текстовый файл описания ресурсов. Этот файл может быть создан либо текстовым редактором (например, встроенным в Borland C++ for Windows), либо при помощи приложения Resource Workshop.

Файл описания ресурсов имеет расширение имени .rc. Его необходимо включить в проект приложения наряду с файлами исходных текстов и файлом определения модуля.

В процессе сборки загрузочного модуля файл описания ресурсов компилируется специальным компилятором ресурсов rc.exe. Компилятор ресурсов поставляется вместе с системой разработки приложений Windows. Он преобразует входной текстовый файл описания ресурсов в двоичный файл с расширением имени .res (вы можете указывать в проекте либо текстовый, либо двоичный вариант файла описания ресурсов, однако лучше использовать текстовый вариант, так как его можно редактировать). Перед запуском компилятора ресурсов система разработки приложений Windows запускает препроцессор текстового описания ресурсов rcpp.exe, который обрабатывает разделители комментариев и директивы препроцессора Си.

На финальном этапе сборки загрузочного модуля компилятор ресурсов rc.exe вызывается еще раз для записи ресурсов в загрузочный модуль. Дополнительно компилятор ресурсов формирует специальную таблицу ресурсов, расположенную в заголовке exe-файла. Таблица ресурсов используется Windows для поиска и загрузки ресурсов в оперативную память.

На рис. 1.1 схематически изображен процесс сборки загрузочного модуля приложения Windows.

Рис. 1.1. Сборка загрузочного модуля приложения Windows

Исходные тексты приложения Windows, составленные на языках программирования С, С++ или на языке ассемблера, компилируются в объектные модули *.obj. С помощью утилиты tlib.exe объектные модули могут быть собраны в библиотеки *.lib. Далее редактор связей, входящий в систему разработки приложений Windows, собирает из объектных модулей промежуточный вариант загрузочного модуля, не содержащий ресурсов. При этом используется файл определения модуля *.def. Файл описания ресурсов *.rc компилируется утилитой rc.exe в двоичный файл *.res. На последней стадии формирования загрузочного модуля промежуточный вариант exe-файла комбинируется с файлом ресурсов для получения окончательного варианта загрузочного модуля.

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



Встроенные курсоры


Приложение Windows может использовать несколько встроенных курсоров. Приведем список идентификаторов встроенных курсоров.

Курсор Идентификатор Применение
IDC_ARROW Стандартный курсор в виде стрелки
IDC_IBEAM Текстовый курсор
IDC_WAIT Курсор в виде песочных часов. Используется при выполнении длительных операций
IDC_CROSS Курсор в виде перекрестия
IDC_UPARROW Курсор в виде вертикальной стрелки
IDC_SIZE Индикация изменения размера
IDC_ICON Пустая пиктограмма
IDC_SIZENWSE Индикация изменения размера
IDC_SIZENESW Индикация изменения размера
IDC_SIZEWE Индикация изменения размера
IDC_SIZENS Индикация изменения размера

Идентификаторы встроенных курсоров описаны в файле windows.h:

#define IDC_ARROW MAKEINTRESOURCE(32512) #define IDC_IBEAM MAKEINTRESOURCE(32513) #define IDC_WAIT MAKEINTRESOURCE(32514) #define IDC_CROSS MAKEINTRESOURCE(32515) #define IDC_UPARROW MAKEINTRESOURCE(32516) #define IDC_SIZE MAKEINTRESOURCE(32640) #define IDC_ICON MAKEINTRESOURCE(32641) #define IDC_SIZENWSE MAKEINTRESOURCE(32642) #define IDC_SIZENESW MAKEINTRESOURCE(32643) #define IDC_SIZEWE MAKEINTRESOURCE(32644) #define IDC_SIZENS MAKEINTRESOURCE(32645)

Обратите внимание, что для встроенных пиктограмм и встроенных курсоров используются идентификаторы с одинаковым значением. Например, идентификатор курсора IDC_ARROW и идентификатор пиктограммы IDI_APPLICATION определены одинаково:

#define IDC_ARROW MAKEINTRESOURCE(32512) #define IDI_APPLICATION MAKEINTRESOURCE(32512)

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



Встроенные пиктограммы


Операционная система Windows содержит пять встроенных пиктограмм, которые вы можете использовать при необходимости в своих приложениях. Приведем список идентификаторов встроенных пиктограмм.

Пиктограмма Идентификатор Применение
IDI_APPLICATION Пиктограмма, назначаемая главному окну приложения по умолчанию
IDI_ASTERISK Используется в информирующих сообщениях
IDI_EXCLAMATION Используется в предупреждающих сообщениях
IDI_HAND Используется в критических предупреждающих сообщениях
IDI_QUESTION Означает вопрос или запрос дополнительных данных

С идентификатором IDI_APPLICATION вы уже встречались при регистрации класса окна:

wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);

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

Идентификаторы встроенных пиктограмм определены в файле windows.h следующим образом:

#define IDI_APPLICATION MAKEINTRESOURCE(32512) #define IDI_HAND MAKEINTRESOURCE(32513) #define IDI_QUESTION MAKEINTRESOURCE(32514) #define IDI_EXCLAMATION MAKEINTRESOURCE(32515) #define IDI_ASTERISK MAKEINTRESOURCE(32516)



Мы надеемся, что после прочтения


Мы надеемся, что после прочтения первой части книги "Операционная система Microsoft Windows 3.1 для программиста" вы получили представление о том, что такое Windows с точки зрения программиста и научились создавать простейшие приложения. Вы, вероятно, смогли убедиться в том, что создание приложений для Windows - трудная, но вполне выполнимая задача.
Во второй части мы продолжим изучение программного интерфейса Windows. Будут рассмотрены ресурсы, стандартные (предопределенные) классы окон, а также диалоговые панели.
Первая глава посвящена ресурсам. Ресурсы - это данные, которые добавляются в файл загрузочного модуля приложения Windows и могут при необходимости загружаться в оперативную память. Расположение данных в ресурсах приложения позволяет достичь более эффективного использования памяти. Программы MS-DOS были вынуждены загружать, например, строки сообщений, в оперативную память или реализовывать собственную логику для их динамической загрузки из файлов. Для приложений Windows существует более элегантный способ, исключающий перегрузку памяти ненужными данными и избавляющий программиста от необходимости динамической загрузки данных из файлов.
Из второй главы вы узнаете о том, как пользоваться стандартными и "самодельными" органами управления, такими как кнопки, переключатели, списки, редакторы текста и т. д. Все эти органы управления создаются на базе предопределенных классов окон, зарегистрированных самой операционной системой Windows. Такой подход сильно облегчает труд программиста, так как за внешнее поведение органов управления отвечает соответствующая функция окна, расположенная в Windows. Программист только создает орган управления, описывая его внешний вид и другие атрибуты, работа органа управления обеспечивается ядром Windows. Например, вы можете создать орган управления, который представляет из себя ни много ни мало... полноценный редактор текста с вертикальной и горизонтальной полосой просмотра, способный работать с универсальным буфером обмена Clipboard и обеспечивающий стандартный интерфейс с клавиатурой и мышью.


Третья глава посвящена описанию средств объединения органов управления - диалоговым панелям. Как пользователь Windows вы, безусловно, работали с различными диалоговыми панелями, предназначенными для выбора файлов, шрифтов, для определения параметров работы приложения и т. д. Диалоговые панели создаются с помощью специальных графических редакторов, позволяющих нарисовать диалоговую панель, а также определить характеристики расположенных на ней органов управления. Диалоговые панели - мощное средство организации пользовательского интерфейса.
В следующих томах мы продолжим изучение программного интерфейса Windows. Прежде всего вы научитесь работать с меню, функциями управления памятью, с графическими функциями и шрифтами. Мы также расскажем вам об использовании библиотек динамической загрузки DLL, о средствах обмена данными между приложениями и о многом другом.
Вместе с книгой продается дискета, содержащая исходные тексты всех приложений.
Авторы выражают благодарность сотрудникам АО "ДИАЛОГ-МИФИ" Виноградовой Елене, Голубеву Олегу Александровичу, Дмитриевой Наталье, Кузьминовой Оксане, Синеву Максиму, Ноженко Сергею, корректору Кустову Виктору, принимавшим активное участие в подготовке этой книги, а также остальных томов "Библиотеки системного программиста".

Вызов функций управления окном


Для перемещения органа управления внутри окна можно воспользоваться функцией MoveWindow, описанной нами ранее. Функция MoveWindow определяет новое расположение и размеры окна:

BOOL WINAPI MoveWindow(HWND hwnd, int nLeft, int nTop, int nWidth, int nHeight, BOOL fRepaint);

Параметр hwnd указывает идентификатор перемещаемого окна. Для перемещения органа управления вам необходимо указать его идентификатор, полученный от функции CreateWindow.

Параметр nLeft указывает новую координату левой границы окна, параметр nTop - новую координату нижней границы окна. Эти параметры определяют новое положение органа управления в системе координат, связанной с родительским окном. Напомним, что при перемещении обычного перекрывающегося (overlapped) или временного (pop-up) окна используется экранная система координат.

Параметры nWidth и nHeight определяют, соответственно, ширину и высоту окна. Если при перемещении органа управления необходимо сохранить его размеры, укажите значения, использованные при создании этого органа управления.

Последний параметр fRepaint представляет собой флаг, определяющий, надо ли перерисовывать окно после его перемещения. Если значение этого параметра равно TRUE, функция окна после перемещения окна получит сообщение WM_PAINT. Если указать это значение как FALSE, никакая часть окна не будет перерисована. При перемещении органа управления в качестве этого параметра следует указать TRUE.

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

Для блокирования и разблокирования органа управления следует пользоваться функцией EnableWindow:

BOOL WINAPI EnableWindow(HWND hWnd, BOOL fEnable);


Функция EnableWindow позволяет разрешать или запрещать поступление сообщений от клавиатуры или мыши в окно или орган управления, идентификатор которого задан параметром hWnd.

Параметр fEnable определяет, будет ли указанное окно заблокировано или наоборот, разблокировано. Для того чтобы заблокировать окно (или орган управления) необходимо для этого парамера указать значение FALSE. Если надо разблокировать окно, используйте значение TRUE.

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

BOOL WINAPI IsWindowEnabled(HWND hWnd);

В качестве единственного параметра этой функции надо указать идентификатор проверяемого окна или органа управления. Для заблокированного окна функция возвращает значение FALSE, для разблокированного - TRUE.

Можно вообще убрать орган управления из окна, скрыв его при помощи функции ShowWindow:

BOOL ShowWindow(HWND hwnd, int nCmdShow);

Функция отображает окно, идентификатор которого задан параметром hwnd, в нормальном, максимально увеличенном или уменьшенном до пиктограммы виде, в зависимости от значения параметра nCmdShow. Если использовать эту функцию для органа управления, вы можете его скрыть, указав в параметре nCmdShow значение SW_HIDE.

Для восстановления органа управления надо вызвать эту функцию с параметром SW_SHOWNORMAL.

Можно изменить текст, написанный на кнопке. Для этого следует использовать функцию SetWindowText:

void WINAPI SetWindowText(HWND hWnd, LPCSTR lpszString);

Эта функция устанавливает новый текст для заголовка окна (или органа управления), идентификатор которого указан при помощи параметра hWnd. Параметр lpszString является дальним указателем на строку символов, закрытую двоичным нулем, которая будет использована в качестве нового заголовка.

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

BOOL WINAPI DestroyWindow(HWND hWnd);

Функция DestroyWindow уничтожает окно, идентификатор которого задан в качестве параметра hWnd, и освобождает все связанные с ним ресурсы.

Возвращаемое значение равно TRUE в случае успеха или FALSE при ошибке.


WM_CLEAR


Удаление выделенного текста без записи в Clipboard. Удаленный текст можно восстановить, если послать в редактор сообщение EM_UNDO.

Параметры: wParam = 0; lParam = 0L;

Возвращаемое значение: не используется



WM_COPY


Копирование выделенного фрагмента текста в универсальный буфер обмена Clipboard.

Параметры: wParam = 0; lParam = 0L;

Возвращаемое значение: не используется



WM_CUT


Удаление выделенного текста с записью его в Clipboard. Удаленный текст можно восстановить, если послать в редактор сообщение EM_UNDO.

Параметры: wParam = 0; lParam = 0L;

Возвращаемое значение: не используется



WM_PASTE


Вставка текста из буфера обмена Clipboard в текущую позицию редактируемого текста.

Параметры: wParam = 0; lParam = 0L;

Возвращаемое значение: не используется



Загрузка изображения bitmap


Для загрузки изображения bitmap вы должны использовать функцию LoadBitmap:

HBITMAP WINAPI LoadBitmap(HINSTANCE hInst,LPCSTR lpszBitmap);

Назначение параметров этой функции аналогично назначению параметров функций LoadIcon и LoadCursor. Параметр hInst указывает идентификатор текущей копии приложения, параметр lpszBitmap - идентификатор bitmap в файле описания ресурсов.

Функция возвращает идентификатор изображения, который следует использовать для рисования bitmap.

Перед завершением работы приложение должно удалить загруженное изображение, вызвав функцию DeleteObject:

BOOL WINAPI DeleteObject(HGDIOBJ hGDIObj);

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



Загрузка произвольных данных из ресурсов приложения


Получение идентификатора произвольных данных из ресурсов приложения - трехступенчатый процесс. Вначале с помощью функции FindResource необходимо определить расположение ресурса в файле приложения:

HRSRC WINAPI FindResource(HINSTANCE hInst, LPCSTR lpszName, LPCSTR lpszType);

Параметр hInst является идентификатором модуля, содержащего ресурс. Для извлечения ресурса из приложения вы должны указать его идентификатор, передаваемый функции WinMain через параметр hInstance.

Параметр lpszName должен содержать адрес имени ресурса. Для загрузки произвольных данных в качестве этого параметра следует передать указатель на строку, содержащую идентификатор ресурса. В приведенном выше примере используется идентификатор "Hello".

Параметр lpszType - адрес строки, содержащий тип ресурса. Для нашего примера это должна быть строка "SOUND".

Таким образом, поиск ресурса, описанного как

Hello SOUND hello.wav

должен выполняться следующим образом:

HRSRC hRsrc; hRsrc = FindResource(hInstance, "Hello", "SOUND");

Функции FindResource в качестве третьего параметра можно передавать идентификаторы предопределенных типов ресурсов, список которых приведен ниже (некоторые из перечисленных типов ресурсов вам пока незнакомы, мы расскажем о них позже).

Идентификатор ресурса Название ресурса
RT_ACCELERATOR Таблица акселераторов
RT_BITMAP Изображение bitmap
RT_CURSOR Курсор
RT_DIALOG Диалоговая панель
RT_FONT Шрифт
RT_FONTDIR Каталог шрифтов
RT_ICON Пиктограмма
RT_MENU Меню
RT_RCDATA Произвольные данные
RT_STRING Таблица строк

Вы можете использовать функцию FindResource для загрузки таких ресурсов, как пиктограммы или курсоры, указав ей тип ресурса, соответственно, RT_ICON или RT_CURSOR. Однако в документации к SDK сказано, что загрузку предопределенных ресурсов, таких как пиктограммы и курсоры, следует выполнять специально предназначенными для этого функциями (LoadIcon, LoadCursor и т. д.).

На втором этапе, после того как ресурс найден, его следует загрузить, вызвав функцию LoadResource:


HGLOBAL WINAPI LoadResource(HINSTANCE hinst, HRSRC hrsrc);

Параметр hinst представляет собой идентификатор модуля, из файла которого загружается ресурс. Если ресурс загружается из файла вашего приложения, используйте значение hInstance, полученное через соответствующий параметр функции WinMain.

В качестве второго параметра этой функции следует передать значение, полученное от функции FindResource.

Третий этап заключается в фиксировании ресурса в оперативной памяти функцией LockResource:

void FAR* WINAPI LockResource(HGLOBAL hGlb);

В качестве параметра hGlb функции LockResource следует передать идентификатор ресурса, полученный от функции LoadResource.

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

После того как приложение использовало ресурс и он стал ненужен, следует расфиксировать память ресурса, вызвав функцию UnlockResource. Функция определена через функцию GlobalUnlock следующим образом:

BOOL WINAPI GlobalUnlock(HGLOBAL hGlb); #define UnlockResource(h) GlobalUnlock(h)

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

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

BOOL WINAPI FreeResource(HGLOBAL hGlb);

В качестве параметра hGlb следует передать идентификатор ресурса, полученный от функции LoadResource.


Загрузка строки из таблицы


Для загрузки строки в оперативную память необходимо использовать функцию LoadString:

int WINAPI LoadString( HINSTANCE hInst, // идентификатор приложения UINT idResource, // идентификатор ресурса LPSTR lpszBuffer, // адрес буфера int cbBuffer); // размер буфера в байтах

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

Параметр idResource указывает идентификатор нужной строки. Вы должны использовать одно из значений, заданных в файле описания ресурсов.

Указатель lpszBuffer определяет адрес буфера, в который будет загружена строка. Размер буфера должен быть задан через параметр cbBuffer. Если размер строки окажется больше указанного размера буфера, строка будет обрезана.

Функция LoadString возвращает количество символов, записанных в буфер, или 0, если файл загрузочного модуля не содержит строки с указанным идентификатором (или если в этом файле вообще нет таблицы строк).



Закрашенные прямоугольники


Для создания закрашенных прямоугольников используются стили SS_BLACKRECT, SS_GRAYRECT и SS_WHITERECT. Эти стили позволяют создать статические органы управления в виде закрашенных прямоугольников, соответственно, черного, серого и белого цветов (используются системные цвета, как это описано выше).

Для этих стилей текст заголовка окна не используется. Соответствующий параметр функции CreateWindow следует указать как NULL.