Connessione al database con Visual Basic NET? Lo trovi su Opentraining.it Visual Basic Italia
Guide e Tutorials:indexed
La funzione GetMenuItemCount (Tutorial completo)
Con questa seconda funzione proseguiamo la trattazione relativa alla manipolazione delle informazioni che i menu contengono al loro interno. Fortunatamente GetMenuItemCount è davvero una funzione semplice (anche se di tutto rispetto, altrimenti non ne parleremmo), parecchio più semplice rispetto a GetMenuItemInfo. Questo dovrebbe spingere molti ad appassionarsi all'argomento e magari specializzarsi in modo particolare proprio in questo campo.
L'utilità di GetMenuItemCount è presto detta, anche se come aveta già notato c'è ben poco da dire: la funzione infatti conta gli oggetti-menu presenti all'interno di un menu. C'è però da tenere presente che la numerazione degli oggeti di un menu, proprio come accade ad esempio per i dati di una listbox, parte da 0 e non da 1 ed arriva all' (n-1)-esimo elemento e non fino all'n-esimo. Quindi se vogliamo contare tutti gli oggetti presenti in un menu, il primo della lista non sarà l'oggetto 1 ma l'oggetto 0 e l'ultimo non sarà l'oggetto n ma l'oggetto (n-1).
In più basta ricordare solo che se tutto funziona correttamente, GetMenuItemCount ritorna il numero di oggetti-menu presenti in un menu, se la funzione incontra degli errori, il valore di ritorno e -1. Questo può essere un indizio utile per elaborare uno schema di gestione degli errori costruito a regola d'arte.
Adesso come è uso fare, vediamo la dichiarazione della funzione:

Declare Function GetMenuItemCount Lib "user32.dll" (ByVal hMenu As Long) As Long

E' giunto il momento anche questa volta di aprire la parentesi ristoratrice:
la funzione GetMenuItemCount supporta queste piattaforme:
Windows 95,98,2000: si
Windows NT: versione 3.1 o successiva
mentre Windows CE: no.
Chiudiamo velocemente la parentesi, dubitando sempre della sua utilità, e concentriamoci nuovamente sulla funzione vera e propria. L'unico parametro contenuto nella funzione è hMenu ossia l'identificativo del menu. Quale menu? Quello di cui si vogliono contare gli oggetti.
Per chiarirci meglio diamo un'occhiata al seguente esempio. Notare che l'esempio riportato di seguito utilizza la funzione GetMenu che verrà trattata a breve ma comunque non in questa lezione.

Cominciamo a dichiarare le funzioni che intervengono nel progetto. Apriamo quindi un nuovo progetto, dopodichè generiamo un modulo. All'interno di tale modulo dovrà essere compresa la struttura MENUITEMINFO:

Type MENUITEMINFO
cbSize As Long
fMask As Long
fType As Long
fState As Long
wID As Long
hSubMenu As Long
hbmpChecked As Long
hbmpUnchecked As Long
dwItemData As Long
dwTypeData As String
cch As Long
End Type

con la dichiarazione pubblica delle costanti che vogliamo poi utilizzare in seguito, che definiscono i parametri dei menu sui quali si vuole andare ad operare. Definiamo di seguito solo quelli che ci interessano per il progetto corrente, ossia:

Public Const MIIM_STATE = &H1
Public Const MIIM_SUBMENU = &H4
Public Const MIIM_TYPE = &H10
Public Const MFT_SEPARATOR = &H800
Public Const MFS_CHECKED = &H8

Se vi sfugge la funzione di tali flags, consigliamo di andare a rivedere la seconda tabella presente nella lezione su MENUITEMINFO.
Adesso passiamo a dichiarare le funzioni, ricordando naturalmente che stiamo sempre lavorando sul modulo. Dichiariamo prima di tutto la funzione GetMenuItemCount:

Declare Function GetMenuItemCount Lib "user32.dll" (ByVal hMenu As Long) As Long

poi passiamo a dichiarare la funzione che abbiamo visto la scorsa lezione ossia GetMenuItemInfo:

Declare Function GetMenuItemInfo Lib "user32.dll" Alias "GetMenuItemInfoA" _
(ByVal hMenu As Long, ByVal uItem As Long, ByVal fByPosition As Long, lpmii _
As MENUITEMINFO) As Long

e per concludere le dichiarazioni generali, aggiungiamo la dichiarazione della funzione GetMenu di cui per adesso non parleremo:

Declare Function GetMenu Lib "user32.dll" (ByVal hWnd As Long) As Long

Fatto ciò aggiungiamo magari un bell'Option Explicit tanto per far vedere che siamo professionisti e inseriamo la funzione che andrà ad elaborare ciascuna voce del menu, passandole una per una:

Public Sub ParlamiDeiMenu (ByVal hMenu As Long, ByVal Livello As Long)

dove hMenu indica il menu al quale ci si riferisce (per questo bisogna fare riferimento alla funzione GetMenu) e livello indica se si parla di oggetti-menu presenti in menu o sottomenu.
All'interno di tale funzione aggiungiamo (ma prima dichiariamo) un semplice contatore che ci serve per processare in modo ordinato ciascuno degli oggetti-menu:

Dim Contatore As Long

Ora definiamo la variabile che riceverà le informazioni relative agli oggetti-menu:

Dim mii As MENUITEMINFO

e la variabile che indica il numero di oggetti-menu compresi nello specifico menu che vogliamo processare:

Dim NumeroOggettiMenu As Long

e per finire definiamo il valore di ritorno (RETurn VALue) come:

Dim Retval As Long

che, ripetiamo per maggiore chiarezza, si riferisce non alla funzione GetMenuItemCount bensì a GetMenuItemInfo e quindi come abbiamo visto la volta scorsa, nel caso in cui la funzione non trovi errori, sarà un numero diverso da zero, mentre nel caso in cui si incontrino errori durante l'elaborazione, sarà proprio il valore 0.

Dopo aver definito tutte le variabili che intervengono nel processo si entra nel vivo della funzione. Vogliamo contare il numero di oggetti-menu presenti nel menu specifico che vogliamo valutare, quello cioè passato alla sottoprocedura corrente tramite hMenu dalla funzione GetMenu:

NumeroOggettiMenu = GetMenuItemCount(hMenu)

Questa operazione non deve preoccuparci perchè successivamente definiremo nell' ambito della Form, come dire a Visual Basic a quale menu fare riferimento per acquisirne le informazioni.
Passiamo avanti. Adesso comincia la verifica uno ad uno degli oggetti-menu:

With mii
.cbSize = Len(mii)

Che cosa significa questo primo passo? Si sta semplicemente definendo le dimensioni della struttura MENUITEMINFO che riceverà le informazioni da ciascun oggetto-menu.
Aggiungiamo alle due linee di codice sopra:

.fMask = MIIM_STATE Or MIIM_TYPE Or MIIM_SUBMENU

che indica quali informazioni vogliamo acquisire dagli oggetti-menu. In questo caso vogliamo sapere di ognuno qual'è lo stato (Checked, Default, Disabled, Enabled, Grayed, Hilite, Unchecked, UnHilite), il tipo (String o Bitmap) e gli eventuali sottomenu presenti.
Adesso comincia la vera iterazione. Per Contatore che va da 0 (in quanto ripetiamo che il conteggio degli elementi parte da 0 e non da 1 ed arriva a (n-1) e non ad n) al totale degli oggetti-menu meno uno:

For Contatore = 0 To NumeroOggettiMenu - 1

Perchè meno uno? Perchè se ad esempio il menu contiene tre voci (es: Files, Nuovo, Apri), NumeroOggettiMenu sarà pari a 3 (1,2,3), mentre Contatore processerà l'oggetto menu in posizione (0,1,2).
Adesso definiamo le dimensioni che dovranno avere dwTypeData che contiene le informazioni relative all'oggetto-menu-stringa o all'oggetto-menu-bitmap ed eventualmente definiamo il numero di caratteri massimo che può essere contenuto in cch:

.dwTypeData = Space(256)
.cch = 256

E' quindi giunto il momento di estrarre le informazioni dal menu hMenu relativamente all'oggetto-menu definito da Contatore ossia nell'esempio precedente: prima l'oggetto in posizione 0 poi quello in posizione 1 e infine quello in posizione 2:

retval = GetMenuItemInfo(hMenu, Contatore, NumeroOggettiMenu, mii)

E veniamo al risultato dell'esempio:
Nel caso in cui questa funzione, nel processare i vari elementi del menu, trovi un elemento separatore (la "-" che si inserisce nel menu per creare la separazione tra due voci), allora visualizzerà una msgbox con la linea "---". Subito prima di "---", individuerà il livello nel quale è posto l'elemento separatore e scriverà tre puntini per livello, proprio come Visual Basic. Ad esempio, immaginiamo di avere il menu:
Files
...Nuovo
...Apri
...Chiudi
......Chiudi avvisando
......-
......Chiudi senza avviso
allora la linea "---" nella msgbox sarà preceduta da sei puntini (una coppia di tre)

If mii.fType = MFT_SEPARATOR Then
MsgBox " " & String(3 * level, ".") & "-----"

Altrimenti:

Else

se l'oggetto-menu è una stringa di testo, la funzione apre una msgbox contenente il testo della voce del menu:

MsgBox String(3 * Livello, ".") & Left(.dwTypeData, .cch)

Come ultima cosa gestiamo il passaggio di livelli, passando a valutare la funzione ParlamiDeiMenu ad un livello superiore di uno (Livello + 1)

If .hSubMenu <> 0 Then
ParlamiDeiMenu .hSubMenu, Livello + 1
End If

Adesso chiudiamo il modulo coi consueti:

End If
End If
Next Contatore
End With
End Sub

ed passiamo alla Form sulla quale aggiungiamo un pulsante (Command1), gestendo l'evento in questo modo:

Private Sub Command1_Click()
Dim hMenu As Long
hMenu = GetMenu(Form1.hWnd)
ParlamiDeiMenu hMenu, 0
End Sub

ossia definendo l'identificatore del menu, richiamando il menu appropriato tramite la funzione GetMenu e richiamando la nostra funzione principale ParlamiDeiMenu.
L'esempio è terminato. Basterà soltanto aggiungere menu a piacere nella form, avviare l'applicazione e premere il pulsante per visualizzare il contenuto dei menu ed i livelli nei quali sono stati posizionati gli oggetti-menu.
Per una maggiore comprensione comunque riuniamo di seguito le singole linee di codice del modulo viste prima e componiamo l'intero listato del programma (escluso quello relativo alla form che è tutto qua sopra):

Type MENUITEMINFO
cbSize As Long
fMask As Long
fType As Long
fState As Long
wID As Long
hSubMenu As Long
hbmpChecked As Long
hbmpUnchecked As Long
dwItemData As Long
dwTypeData As String
cch As Long
End Type

Public Const MIIM_STATE = &H1
Public Const MIIM_SUBMENU = &H4
Public Const MIIM_TYPE = &H10
Public Const MFT_SEPARATOR = &H800
Public Const MFS_CHECKED = &H8

Declare Function GetMenuItemCount Lib "user32.dll" (ByVal hMenu As Long) As Long
Declare Function GetMenuItemInfo Lib "user32.dll" Alias "GetMenuItemInfoA" _
(ByVal hMenu As Long, ByVal uItem As Long, ByVal fByPosition As Long, lpmii _
As MENUITEMINFO) As Long
Declare Function GetMenu Lib "user32.dll" (ByVal hWnd As Long) As Long

Public Sub ParlamiDeiMenu (ByVal hMenu As Long, ByVal Livello As Long)
Dim Contatore As Long
Dim mii As MENUITEMINFO
Dim NumeroOggettiMenu As Long
Dim Retval As Long

NumeroOggettiMenu = GetMenuItemCount(hMenu)

With mii
.cbSize = Len(mii)
.fMask = MIIM_STATE Or MIIM_TYPE Or MIIM_SUBMENU
For Contatore = 0 To NumeroOggettiMenu - 1
.dwTypeData = Space(256)
.cch = 256
retval = GetMenuItemInfo(hMenu, Contatore, NumeroOggettiMenu, mii)
If mii.fType = MFT_SEPARATOR Then
MsgBox " " & String(3 * Livello, ".") & "-----"
Else
MsgBox String(3 * Livello, ".") & Left(.dwTypeData, .cch)
If .hSubMenu <> 0 Then
ParlamiDeiMenu .hSubMenu, Livello + 1
End If
End If
Next Contatore
End With
End Sub




Bene, per ora è tutto...alla prossima!

Archivio:
Lezioni Commenta questa lezione Invia la tua guida Avviso per le nuove lezioni
Proponi un argomento

Visual Basic Italia© copyright 2000 - tutti i diritti riservati
E-mail:
vbitalia@libero.it