VB Tip: Criando menu de modo fácil - MenuCreator
Autor: Diego Silva | Publicado: 2011-08-08T21:23:00-03:00

Olá. 
Neste artigo irei disponibilizar uma nova classe/livraria que criei, chamada MenuCreator, cuja classe chama-se cMenu. O objetivo principal dele é criar e manipular menus de modo bem simples. O link dele é https://skydrive.live.com/?cid=b278d5e7a71b5dca&sc=documents&nl=1&uc=1&id=B278D5E7A71B5DCA%21146# (pasta do SkyDrive). Nele há cinco métodos, entre eles: 
Add (menuh as Long, Pos as Long, Text as String, [Flags as long, lpimage as stdpicture]): Adiciona um item à um menu existente. 
Menuh recebe o endereço handle do menu.
Pos recebe um número que posteriormente será identificado por sua função, número este maior que 0. 
Text recebe o texto do item.
Flags (opcional) recebe as opções do item, listadas abaixo (que podem ser combinadas com o operador binário OR):
* MF_DISABLED = &H2& - Desabilita o item (mas não o torna cinza, veremos isso depois);
* MF_GRAYED = &H1& - Torna o item cinza (mas não o torna desabilitado; para desabilitá-lo e torná-lo cinza, use (MF_DISABLED OR MF_GRAYED).);
* MF_SEPARATOR = &H800& (NÃO COMBINÁVEL!) - Torna o item em uma barra horizontal de separação de itens.
* MF_POPUP = &H10& - Inicia um novo menu ao lado.




Count (menuh as Long) as Long: Retorna a quantidade de itens em um determinado menu. Menuh recebe o endereço handle do menu.
Create () As Long: Cria um novo menu, e retorna seu handle para ser manipulado pelas outras quatro funções.

Destroy (menuHandle as Long): remove um menu da memória, menu este determinado pelo endereço handle em menuHandle. 

Show (menuh as Long, owner as Long, x as Double, y as Double) as Long: Exibe um menu. Menuh recebe o endereço handle do menu, owner recebe o endereço handle do formulário pai (Me.hWnd), x e y recebem a posição absoluta (em pixels) do menu, na tela.


Para o valor de x e y no método show, usamos uma das duas APIs seguintes:
* ClientToScreen - Transforma uma coordenada local do formulário em uma coordenada absoluta da tela.
* GetCursorPos - Obtém a posição atual do cursor do mouse.
Ambos usam a estrutura POINTAPI, cujos elementos são X, como LONG, e Y, também LONG.
Abaixo vai um exemplo. Crie um form em um projeto do tipo Standard Exe, adicione um botão no topo esquerdo do form e adicione o seguinte código no formulário:

Private Type POINTAPI
        x As Long
        y As Long
End Type

Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
Private Declare Function ClientToScreen Lib "user32" (ByVal hwnd As Long, lpPoint As POINTAPI) As Long

Private Sub Command1_Click()
Me.ScaleMode = vbPixels
Dim pt As POINTAPI
Dim r As Long
Dim h As Long
Dim m As New cMenu
h = m.Create
    For i = 1 To 20
    m.Add h, i, "Meu item " & CStr(i)
    Next i
pt.x = Command1.Left
pt.y = Command1.Top
ClientToScreen Me.hwnd, pt
r = m.Show(h, Me.hwnd, pt.x, pt.y)
m.Destroy h
Set m = Nothing
    Select Case r
    Case 1 To 20
    MsgBox "Você selecionou o item " & CStr(r)
    Case Else
    MsgBox "Você não selecionou nenhum item"
    End Select
End Sub

"h=m.create" cria um novo menu e atribui o endereço do novo menu ao h. m.add adiciona os itens de 1 a 20 no menu criado. pt.x, pt.y, e clienttoscreen transformam a posição do botão em coordenadas absolutas da tela. 
"r=m.show" exibe o menu na tela e retorna o item selecionado, e, caso nenhum item for selecionado, retorna zero. Daí a necessidade dos itens adicionados terem identificação (Pos as long) maior que 0.
"m.destroy" e "set m=nothing" são necessários para liberar memória, tanto do menu (destroy h) quanto da classe cMenu (set m=nothing).
Para manipulações mais complexas como por exemplo, adição de linhas verticais no menu para dispô-los em colunas, deve-se usar APIs externas à classe, como SetMenuItemInfo e similares. 

Com essa classe, você pode criar um menu customizado para um formulário borderless (BorderStyle=0), abaixo do que seria o título.

Enfim, você poderá usar essa classe para facilitar a programação com menus. 
Em breve, nova versão do Multisystem com formulários renovados e com menus, com auxílio dessa nova classe por mim criada.
É isso, pessoal.
Até o próximo artigo!