A utilização de menus permite navegar
nas diversas opções de uma aplicação de uma forma organizada. É normal que as aplicações
utilizem menus e, quando assim se justifique, menus de atalho. Estes menus (popupmenu)
são normalmente específicos para um determinado objecto e resultam do clicar com
o botão direito do rato (botão de opções).
Além de mais específicos estão próximos
do(s) objecto(s) e utilizam muitas vezes opções personalizadas. Para isso é necessário
criá-los dinamicamente, ou seja, criar o menu através de código no decorrer do programa.
Por exemplo, ao seleccionarmos um item de uma lista podemos queres associar ao menu
o texto dele.
A criação de um menu através do “Menu Editor” e chama-lo através da instrução
PopupMenu limita-nos ao itens predefinidos.
Para a criação de menus dinamicamente pode-se utilizar alguns dos API’s disponíveis
e tornar estes versáteis e mais próximos das necessidades do utilizador.

Vamos ver um exemplo simples da criação
de menus e sub-menus utilizando API’s:
Option Explicit
' Declaração das funções
API's
' Cria um novo menu
vazio
Private Declare Function
CreatePopupMenu Lib "user32" ()
As Long
' Elimina um específico
menu, libertando a memória usada por ele
Private Declare Function
DestroyMenu Lib "user32" (ByVal
hMenu As Long) As Long
' Adiciona um novo item
a um menu existente
Private Declare Function
AppendMenu Lib "user32"
Alias "AppendMenuA" (ByVal hMenu
As Long, ByVal
wFlags As Long, ByVal
wIDNewItem As Long, ByVal
lpNewItem As Any) As Long
' Permite verificar
qual o menu que foi seleccionado
Private Declare Function
TrackPopupMenu Lib "user32" (ByVal
hMenu As Long, ByVal
wFlags As Long, ByVal
X As Long, ByVal
Y As Long, ByVal
nReserved As Long, ByVal
hwnd As Long, lprc As Any)
As Long
' Verifica a posição
do cursor no ecrã
Private Declare Function
GetCursorPos Lib "user32" (lpPoint
As PointAPI) As Long
' Declaração das constantes.
Estas constantes não estão todas usadas
' mas são as disponíveis
para a utilização de menus dinâmicos
Private Const MF_INSERT As Long =
&H0&
Private Const MF_CHANGE As Long =
&H80&
Private Const MF_APPEND As Long =
&H100&
Private Const MF_DELETE As Long =
&H200&
Private Const MF_REMOVE As Long =
&H1000&
Private Const MF_BYCOMMAND As Long
= &H0&
Private Const MF_BYPOSITION As Long
= &H400&
Private Const MF_SEPARATOR As Long
= &H800&
Private Const MF_ENABLED As Long =
&H0&
Private Const MF_GRAYED As Long =
&H1&
Private Const MF_DISABLED As Long
= &H2&
Private Const MF_UNCHECKED As Long
= &H0&
Private Const MF_CHECKED As Long =
&H8&
Private Const MF_USECHECKBITMAPS As Long
= &H200&
Private Const MF_STRING As Long =
&H0&
Private Const MF_BITMAP As Long =
&H4&
Private Const MF_OWNERDRAW As Long
= &H100&
Private Const MF_POPUP As Long = &H10&
Private Const MF_MENUBARBREAK As Long
= &H20&
Private Const MF_MENUBREAK As Long
= &H40&
Private Const MF_UNHILITE As Long
= &H0&
Private Const MF_HILITE As Long =
&H80&
Private Const MF_SYSMENU As Long =
&H2000&
Private Const MF_HELP As Long = &H4000&
Private Const MF_MOUSESELECT As Long
= &H8000&
Private Const TPM_RETURNCMD As Long
= &H100&
' Tipo para a posição
do rato no ecrã
Private Type PointAPI
X As
Long
Y As
Long
End Type
Private
menu As Long
Private submenu As Long
' No evento MouseDown
do Form cria o menu
Private Sub Form_MouseDown(Button As Integer,
Shift As Integer, X As Single,
Y As Single)
Dim
cursor As PointAPI
Dim result
As Long
' Caso tenha sido usado o botão direito do rato
If Button = vbRightButton Then
' Cria o sub
popup menu
submenu = CreatePopupMenu()
Call AppendMenu(submenu, MF_STRING, 10, "Sub-Menu 1")
Call AppendMenu(submenu, MF_STRING, 11, "Sub-Menu 2")
' Cria o popup menu
menu = CreatePopupMenu()
Call AppendMenu(menu, MF_STRING, 1, "Menu
1")
Call AppendMenu(menu, MF_GRAYED, 2, "Menu 2")
Call AppendMenu(menu, MF_SEPARATOR, 3, "")
' Insere o sub-menu no menu
Call AppendMenu(menu, MF_POPUP, submenu,
"Menu 3")
Call AppendMenu(menu, MF_CHECKED, 4, "Menu 4")
' Recolhe a informação do cursor do rato
Call GetCursorPos(cursor)
' Verifica o resultado seleccionado de acordo
com o índice
result = TrackPopupMenu(menu, TPM_RETURNCMD, cursor.X,
cursor.Y, 0, Me.hwnd, 0)
' De acordo com o resultado (escolha) executa
algo. Neste
'
caso mostra apenas na janela “Immediate”
Select Case result
Case 1
Debug.Print
"Menu 1"
Case 2
Debug.Print
"Menu 2"
Case 4
Debug.Print
"Menu 4"
Case 10
Debug.Print
"Sub-Menu 1"
Case 11
Debug.Print
"Sub-Menu 2"
End Select
End If
End Sub
‘ No evento Unload do
Form limpa os menus
Private Sub Form_Unload(Cancel As Integer)
' Limpa os menus criados da memória
Call DestroyMenu(menu)
Call
DestroyMenu(submenu)
End Sub
Este exemplo pretende mostrar a simplicidade
e utilidade deste menus e como melhorar as aplicações com a adição destes. Este
código poderá ser adaptado e colocado num módulo ou classe para ser reutilizado
na aplicação.
PS: Como sempre, qualquer dúvida,
comentário ou correcção ao artigo é sempre bem vinda!
4 comentários:
Olá...
Gostei muito deste menu!
Tem como colocar imagens na frente das opções?
Pergunto isso pois quando o windows esta com o tema AERO ativada, o menu apresenta uma nova "coluna" na frente das opções. Acredito eu que seja para por imagens.
grato.
Olá,
Vê nesta página que existem excelentes soluções com imagens (icones) http://www.vbaccelerator.com/home/VB/Code/Controls/Menus/index.asp
Obrigado Jorge Paulino...
Muito complicado os menus do vbAccelerator. Vou deixar sem icones mesmo...
grato
Esse Valores que são atribuídos as variáveis, qual a logica? já mudei o valor e parece que não sofre alteração no resultado
Enviar um comentário