Visual Basic 6. Руководство разработчика

       

Создание элементов меню, содержащих растровые изображения


Элементы меню, создаваемые средствами Menu Editor (Редактор меню) Visual Basic, не всегда содержат только текст. В некоторых прикладных программах может потребоваться, чтобы элемент меню содержал растровое изображение. Добавить растровые изображения к элементам меню можно с помощью нескольких API-функции. Разработка таких элементов меню занимает немало времени, но результат того стоит Приложение MenuBMP (рис 13.4) позволяет создавать элементы меню с растровыми изображениями.

VB6 в действии: проект MenuBMP

В этом приложении используются такие API-функции:

• GetMenu()

• GetSubMenu()

• ModifyMenu()

• CreateCompatibleDC()

• CreateCompatibleBitmap()

• Select0bject()

Рис. 13.4. Приложение MenuBMP

Чтобы манипулировать элементами меню с помощью API-функций, необхо­димо получить дескриптор элемента меню. Элементы меню являются объектами, и поэтому им поставлены в соответствие дескрипторы, которые идентифицируют их с точки зрения операционной системы (точно так идентифицируются формы и растровые изображения). Более того, можно манипулировать элементами меню других приложений, запущенных в настоящий момент, если получить дескриптор этого элемента меню.

Для получения дескриптора элемента меню используется функция GetMenu(). Объявим ее:

Private Declare Function GetMenu Lib "user32" (ByVal hWnd _

As Long) As Long

Параметр

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

MenuHandle = GetMenu(Me.hWnd)

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

GetSubMenu().

Private Declare Function GetSubMenu Lib "user32" _

(ByVal hMenu As Long, ByVal nPos As Long) As Long

Параметр

hMenu - это дескриптор меню, возвращаемый функцией GetMenu(), а параметр nPos — номер текущей позиции подменю. Если значение параметра nPos равно 0, то функция GetSubMenu() возвращает дескриптор первого подменю (им часто оказывается меню File (Файл)).


После того как дескриптор подменю получен, его можно модифицировать с помощью функции

ModifyMenu().

Private Declare Function ModifyMenu Lib "user32" Alias _

"ModifyMenuA" (ByVal hMenu As Long, ByVal nPosition _

As Long, ByVal wFlags As Long, ByVal wIDNewItem As _

Long, ByVal IpString As Any) As Long

Эта функция позволяет изменить элемент меню. Поясним это. Параметр hMenu — это дескриптор подменю, полученный с помощью функции GetSubMenu() Параметр nPosition

идентифицирует элемент меню, который требуется изменить. Если в параметре wFlags установлен флаг MF_BYCOMMAND, то этот параметр относится к ID (Идентификатору) команды меню, которая будет изменена. Если же установлен флаг MF_BYPOSITION, то параметр определяет номер позиции элемента подменю. Параметр wFlags является комбинацией флагов, описанных в табл. 13.4.

Таблица 13.4. Флаги меню

Значение

Описание

MF_BITMAP

Указывает, что элемент меню содержит растровое

изображение. Растровое изображение остается в

памяти, пока используется указанный элемент меню

MF_BYCOMMAND

Определяет элемент меню командой ID меню

MF_BYPOSITION

Определяет элемент меню его позицией в подменю:

номер позиции первого объекта равен нулю

MF_CHECKED

Отображает метку выбора, устанавливая ее слева от

элемента меню

MF_DISABLED

Делает элемент меню недоступным

MF_ENABLED

Делает элемент меню доступным

MF_G RAYED,

Делает элемент меню недоступным и выводит его,

заливая изображение серым цветом (вместо того, чтобы

сделать его невидимым)

M F_MENUBARBREAK

Помещает элемент меню в новый столбец, отделяя его

вертикальной линией

MF_MENUBREAK

Помещает элемент меню в новый столбец

MF_POPUP

Подключает дополнительное раскрывающееся меню к

элементу меню

MF_SEPARATOR

Помещает горизонтальную линию разделителя под

элементом меню

MF_STRING

Помещает строку в элемент меню

MF_JJNCHECKED

Снимает метку выбора слева от элемента меню (если

элемент был выделен)

<


Чтобы связать растровое изображение с пунктом меню, необходимо установить флаг MF_BITMAP в параметре wFlags

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

Набор данных, состав­ляющих растровое изображение (обычно это BMP-файл), загружается в скрытый элемент управления PictureBox. Из него растровое изображение копируется в контекст устройства с помощью функции CreateCompatibleBitmap(). После того как растровое изображение помещено в контекст устройства, его можно связать с элементом меню, как строку текста Фрагмент программы 13.5 содержит код, реализующий добавление растрового изображения к элементу меню приложения MenuBMP.

Обратите внимание размеры растрового изображения должны быть переданы как параметры функции CreateCompatibleBitmap(). Создавая растровое изображение с помощью графического редактора, необходимо задавать изображению такие размеры, чтобы они соответствовали размерам элемента меню. Не следует делать его слишком высоким или слишком узким Растровые изображения в рассматри­ваемых примерах были созданы в программе PaintShopPro. Для создания растровых изображений можно использовать любой графический редактор, включая ImageEdit (папка Tools прилагаемого компакт-диска).

Меню Bitmaps приложения MenuBMP содержит три команды, соответствующие трем различным шрифтам (см. рис. 13.4). Три растровых изображения хранятся в файлах Verdana.bmp, Serif.bmp и Comic.bmp в той же папке, что и приложение. После разработки растровых изображений можно начинать работать с программой. Полный текст программы MenuBMP приведен ниже.

Программа 13.5. Приложение MenuBMP

Option Explicit

Private Declare Function GetMenu Lib "user32" _

(ByVal hwnd As Long) As Long

Private Declare Function GetSubMenu Lib "user32"



( ByVal hMenu As Long, ByVal nPos As Long) As Long

Private Declare Function GetMenuItemID Lib "user32"

(ByVal hMenu As Long, ByVal nPos As Long) As Long

Private Declare Function ModifyMenu Lib "user32"

Alias "ModifyMenuA" (ByVal hMenu As Long, _

ByVal nPosition As Long, ByVal wFlags As Long, _

ByVal wIDNewItem As Long, ByVal IpString As Any) As Long

Private Declare Function CreateCompatibleDC Lib "gdi32" _

(ByVal hdc As Long) As Long

Private Declare Function CreateCompatibleBitmap Lib "gdi32" _

(ByVal hdc As Long, ByVal nWidth As Long,

_

ByVal nHeight As Long) As Long

Private Declare Function SelectObject Lib "gdi32" _

(ByVal hdc As Long, ByVal hObject As Long) As Long

Private Declare Function BitBIt Lib "gdi32" _

(ByVal hDestDC As Long, ByVal x As Long, ByVal у As Long, _

ByVal nWidth As Long, ByVal nHeight As Long, _

ByVal hSrcDC As Long, ByVal xSrc As Long, _

ByVal ySrc As Long, ByVal dwRop As Long) As Long

Private Declare Function DeleteDC Lib "gdi32" _

(ByVal hdc As Long) As Long

Const SRCCOPY   &HCC0020

Const MF_BYPOSITION - &H400&

Const MF_BITMAP   &H4&

Private Sub Form_Load()

Dim Width As Integer, Height As Integer

Dim hTmpDC As Long, hMenuID As Long

Dim hBitmap As Long, retValue As Long

Dim tmpID As Long

Dim fileName As String

Dim menuPos As Integer, menuID As Long

‘ Установка позиции меню и имени файла

menuPos = 0

fileName = App.Path & "\verdana.bmp"

Picturel.Picture = LoadPicture(fileName)

Width = 64

Height = 16

‘ Получение дескриптора меню

hMenuID = GetSubMenu(GetMenu(Me.hwnd), menuPos)

‘ Создание контекста устройства для хранения растрового

‘изображения

hTmpDC = CreateCompatibleDC(Picturel.hdc)

‘ Создание растрового изображения

hBitmap = CreateCompatibleBitmap(Picturel.hdc, Width, Height)

‘ Выбор растрового изображения во временный контекст

tmpID = SelectObject(hTmpDC, hBitmap)

‘ Копирование содержимого из элемента управления в   контекст



‘ устройства

retValue = BitBIt(hTmpDC, 0, 0, Width, Height, _

Picturel.hdc, 0, 0, SRCCOPY)

‘ Отмена выбора

tmpID = SelectObject(hTmpDC, tmpID)

‘ Модификация меню

menuID = GetMenuItemID(hMenuID, menuPos)

retValue = ModifyMenu(hMenuID, menuPos, _

MF_BYPOSITION Or MF_BITMAP, menuID, hBitmap)

‘ Второй пункт меню

menuPos = 1

fileName = App.Path & "\serif.bmp"

Picture1.Picture = LoadPicture(fileName)

‘ Создание растрового изображения для элемента меню

hBitmap = CreateCompatibleBitmap(Picturel.hdc. Width, Height)

‘ Выбор растрового изображения во временный контекст

‘ устройства

tmpID = SelectObject(hTmpDC, hBitmap)

retValue = BitBIt(hTmpDC, 0, 0, Width, Height, _

Picture1.hdc. О, О, SRCCOPY)

tmpID = SelectObject(hTmpDC, tmpID)

menuID = GetMenuItemID(hMenuID, menuPos)

retValue = ModifyMenu(hMenuID, menuPos,

MF_BYPOSITION Or MF_BITMAP, menuID, hBitmap)

‘Третий пункт меню menu

Pos = 2

fileName = App.Path & "\comic.bmp"

Picture1.Picture = LoadPicture(fileName)

‘ Создание растрового изображения для элемента меню

hBitmap = CreateCompatibleBitmap(Picturel.hdc, Width, Height)

‘ Выбор растрового изображения во временный контекст устройства

tmpID = SelectObject(hTmpDC, hBitmap)

retValue = BitBIt(hTmpDC, 0, 0, Width, Height, _

Picturel.hdc. О, О, SRCCOPY)

tmpID = SelectObject(hTmpDC, tmpID)

menuID = GetMenuItemID(hMenuID, menuPos)

retValue = ModifyMenu(hMenuID, menuPos, _

MF_BYPOSITION Or MF_BITMAP, menuID, hBitmap)

‘ Очистка

retValue = DeleteDC(hTmpDC)

End Sub

Private Sub MyMenu Click(Index As Integer)

Dim fName(3) As String

fName(0) = "Verdana"

fName(l) = "Serif"

fName(2) = "Comic Sans MS"

Me.CIs

Me.CurrentX = (Me.ScaleWidth - TextWidth(fName(Index)))/2

Me.CurrentY = (Me.ScaleHeight - TextHeight(fName(Index)))/2

Me.Font.Name = fName(Index)

Me.Print fName(Index)

End Sub


Содержание раздела