Home Grootte veranderen MSGBOX Kolommen & TABS DLL bestanden Printen Geluid afspelen PB en de Euro Menu's

Omhoog
Listing 1
Listing 2
Creditcard

Email me

Menu's en resources

 

Ontwerp van Pull-Down Menu's met PBIDLL

Door Alan C. Earnshaw
vertaald door: Henk Broekhuizen

Vorige keer hebben we laten zien hoe resources vanuit een PB/DLL programma kunnen worden gebruikt. In dit laatste artikel in onze drieluik over Windows resources zullen we een blik werpen op pull-down menu’s. We kijken hoe een menu resource wordt gemaakt, hoe een menu wordt getoond, en hoe er gereageerd moet worden op menu selectie. Hoewel menu’s ook handmatig kunnen worden gemaakt met Windows API aanroepen, is het veel gemakkelijker om een resource script te gebruiken om ze te definiëren, dus daarom behandelen we de handmatige aanmaak van menu’s niet in dit artikel.

 

MENU RESOURCES

Voor zover we weten zijn er geen interactieve ontwerp gereedschappen beschikbaar die menu resource scripts kunnen maken. Ze moeten handmatig worden geschreven. Een menu resource is op dezelfde wijze gestructureerd als andere resources, met een naam, het MENU trefwoord en de data die het menu bevat. De verschillende dingen (‘items’) die in het menu verschijnen (we zullen ze in dit artikel menu-items of items noemen) worden omgeven door een paar accolades ( { } ) of tussen de BEGIN en END trefwoorden. Elk item van een menu wordt in het resource script met één van de volgende trefwoorden opgegeven:

MENUITEM "item text", item number [,options] SIZE="2">

of

POPUP "item text"

MENUITEM wordt gebruikt voor items die door de gebruiker kunnen worden gekozen; POPUP wordt gebruikt om aan te geven dat een submenu zal worden geactiveerd als de gebruiker dit item selecteert. Als u een ampersand ( & ) in de tekst van een items zet, zal de letter die onmiddellijk volgt op dit teken als een HOTKEY voor dat item dienst doen (dus Me&nu gebruikt ALT +N als HOTKEY).

De item nummers zijn unieke nummers die zijn toegewezen aan de menu items. Dit nummer wordt in het programma gebruikt om de optie aan te geven die een gebruiker uit het menu heeft geselecteerd.

Onze voorbeeld-code gebruikt zogenaamde hard-coded nummer als item nummers, hetgeen niet per se de beste programmeerstijl is. Een betere benadering is de aanmaak van een include bestand voor het resource script dat ‘#define’ gebruikt om constanten te gebruiken, zoals:

#define 1DM_NEW 1

Daarna maakt u een apart include bestand aan voor uw programma dat PB/DLL constanten gebruikt om dezelfde waardes toe te wijzen aan de namen.

%IDM_NEW = 1

Het gebruik van deze methode maakt uw programma leesbaarder bij zowel het maken van een programma, als bij het debuggen van uw code. Er zijn verschillende mogelijkheden die bij een menu item gebruikt kunnen worden:

GRAYED – Het item is niet-actief en kan niet worden geselecteerd, en de tekst in het menu wordt licht-grijs weergegeven.

INACTIVE – Het item is niet-actief en niet selecteerbaar, maar wordt op normale wijze in het menu getoond.

MENUBREAK – Dit item en de items die volgen worden op een nieuwe regel van het menu getoond (in geval van pop-up menu’s worden ze in een nieuwe kolom getoond).

HELP – Indien gebruikt met "\a" vóór de tekst van het item, wordt deze menutekst rechts-lijnend getoond op de menu balk (wordt meestal gebruikt om de menu-optie HELP helemaal rechts op de balk te krijgen).

Voor pop-up menu’s (die onder de menu balk worden getoond), zijn er nog twee andere mogelijkheden:

CHECKED – Een vinkje (‘check mark’) wordt links vóór de tekst van het item getoond.

MENUBARBREAK – Zoals een MENUBREAK, maar een verticale lijn scheidt de vorige kolom van de nieuwe kolom.

Er is nog een speciaal item dat in pop-up menu’s kan worden gebruikt: MENUITEM SEPARATOR. Dit menu item plaatst een horizontale lijn in het menu. Het wordt vaak gebruikt om groepen items van elkaar te scheiden.

Kijk eens naar het resource script in Listing 1. Het definieert een menu voor ons voorbeeld programma. Zoals u ziet staan er vier items op de menu balk: FILE, EDIT, ACTIONS en HELP. Elk van deze items heeft een submenu, waarvan de definities ingebed zijn in het resource script (listing 1 laat zien hoe de nesting wordt gedaan). Figuur 1 toont het menu bij uitvoering:

 wpeB3F.jpg (26918 bytes)

KOPPELEN VAN MENU’S AAN WINDOWS

Een resource script kan een aantal menu’s bevatten. Er zijn drie methodes om een menu uit uw resource script te laden. U kunt het menu definiëren in de Window class definitie, u kunt het menu instellen als u de CreateWindow functie aanroept, of u kunt de SetMenu aanroep van de Windows API gebruiken.
NB: een window kan maar één menu bevatten dat een gegeven moment kan worden gebruikt. Hoewel u dynamisch items kunt toevoegen aan of verwijderen uit uw menu, kan er slechts één menu aan een scherm worden gekoppeld.

Om een menu in de Window class definitie te laden, slaat u de naam van het menu (zoals gespecificeerd in het resource script) op in een ASCIIZ string variabele, waarna u een pointer naar de ASCIIZ string plaatst in het lpszMenuName-veld van de Window class variabele. Bijvoorbeeld:

DIM szMenuName AS ASCIIZ * 20 szMenuName = "MainMenu"

wClass . ].pszMenuName = VARPTR (szMenuName)

associeert het menu met de naam MainMenu aan het scherm zoals gedefinieerd in de wClass type variabele.

Als u het menu wilt instellen bij de aanroep van de CreateWindow functie behoort u het lpszMenuName-veld in de Window class definitie op %NULL in te stellen. Daarna vervangt u de negende parameter van de CreateWindow functie door de menu handle (=variabele die het menu identificeert) die naar uw menu wijst. Eerst laadt u het menu uit uw programma’s resource en verkrijgt u de handle ernaar:

DIM hMenu AS WORD

hMenu = LoadMenu(hlnstance, "MainMenu") SIZE="2">

Vervolgens gebruikt u de verkregen handle voor de aanroep in de CreateWindow aanroep:

hWnd = CreateWindow(szClassName, _

szCaption, Style&, %CW_USEDEFAULT, _

%CW USEDEFAULT, %CW USEDEFAULT, _

%cWusEDEFAuLT, %NULL, hMenu, _

hlnstance, %NULL)

Als u %NULL gebruikt voor het lpszMenuName-veld in de Window class en %NULL als de menu handle in de aanroep van de CreateWindow functie, zal er geen menu met het huidige scherm (‘window’) worden verbonden. Om een menu aan een scherm te verbinden, dient u eerst het menu uit de resource te laden en de handle ernaar verkrijgen:

DIM hMenu AS WORD

hMenu = Loadl4enu(hlnstance, "MainMenu")

Daarna roept u de SetMenu functie uit de Windows API aan met de scherm-handle van het betreffende scherm:

SetMenu hWnd, hMenu

Door de SetMenu functie te gebruiken, kunt u het menu van het scherm geheel veranderen.

Windows verwijdert automatisch het menu van een scherm als dat scherm wordt gesloten (in Windows houdt dit in dat Windows een resource uit het geheugen verwijdert en dat geheugen teruggeeft aan Windows voor algemeen gebruik). Menu’s die niet zijn verbonden aan een scherm moeten handmatig worden verwijderd via de DestroyMenu functie, want anders blijven ze in het geheugen totdat uw programma is beëindigd. Hoewel dit normaal gesproken geen probleem is, zal Windows conform uw opdracht bij elke scherm aanmaak en weer verwijderen een nieuwe kopie van het menu in het geheugen laden. Als uw programma lang genoeg draait, zullen deze wees-menu’s uiteindelijk alle Windows geheugen in beslag nemen. Weesjes (zoals deze wees-menu’s) zijn de nummer 1 oorzaak van geheugen-lekken in Windows programma’s.

 

REAGEREN OP MENU SELECTIES

Uw menu is gekoppeld aan een scherm, dus nu is het tijd om code aan de scherm-procedure toe te voegen zodat op elke menu item selectie gereageerd wordt. Als een menu item wordt geselecteerd stuurt Windows een %WM-COMMAND boodschap naar uw scherm-procedure. De wParam% parameter bevat het menu item nummer dat aangeeft welk menu item werd geselecteerd.

Ons voorbeeld programma in Listing 2 vertoont een redelijk standaard menu in het programma-scherm. Voor de meeste items in het menu zal de scherm-procedure eenvoudigweg een message-box tonen met de boodschap welk menu item werd geselecteerd. Het HELP/ABOUT menu item vertelt u dat het programma afkomstig is van BASICally Speaking, en het File/Exit menu item vertelt u welk item werd geselecteerd en beëindigt het programma.) In uw eigen programma kunt u in plaats van deze message-boxen aanroepen naar andere functies en procedures doen (zowel in uw programma als in DLLs), die het uiteindelijke werk van uw programma doen.

 

VINKJES (CHECK MARKS) EN GEBLOKKEERDE MENU ITEMS

Eerder gaf ik aan dat u een vinkje links vóór de tekst van een menu item kunt plaatsen met de CHECKED optie in het resource script. Om een vinkje om te schakelen, dient u de CheckMenultem functie uit de Windows API te gebruiken. Eerst moet u een handle naar het menu van het uitverkoren scherm krijgen:

 

DIM hMenu AS WORD

hMenu = GetMenu(hWnd)

Deze functie kunt u alleen gebruiken als het menu al is geladen en met het scherm is verbonden. Daarna roept u de CheckMenultem functie aan, gebruik makend van de wParam% waarde en %MF_UNCHECKED (om het vinkje te verwijderen) of %MF_CHECKED (om het vinkje te plaatsen):

wSelection% = wParam%

CheckMenultem hMenu, wSelection%, %MF_UNCHECKED SIZE="2">

Naast het initieel niet-actief maken van een menu item in het resource script, kunt u ook de actief-status tijdens de uitvoering van uw programma veranderen met behulp van de EnableMenultem functie. Deze functie heeft een handle naar het menu nodig en het item nummer. Om de status van een menu item te veranderen gebruikt u %MF_ENABLED om een menu item actief te maken en %MF_GRAYED om een menu item niet-actief en grijs te maken:

EnableMenultem hMenu, %IDM NEW, %MF_GRAYED

‘disable "New"

EnableMenultem hMenu, %IDM NEW, %MF ENABLED

‘enable "New"

GEADVANCEEERDE MENU OPTIES

Windows biedt u de mogelijkheid om menu’s nog anders te gebruiken. U kunt bijvoorbeeld een pop-up menu gebruiken zonder een menu-balk (dit wordt vaak gebruikt als de gebruiker met de rechter muistoets klikt op een icoontje of een plaatje), items in een menu toevoegen, verwijderen van items uit menu’s, de tekst in menu’s veranderen, plaatjes gebruiken in uw menu’s, het lettertype van de tekst van menu items veranderen, het systeem menu veranderen (het systeem menu wordt vertoond als u op de menu control-knop links boven in uw menu klikt – het bevat meestal MINIMIZE, MOVE, CLOSE etc) en items toevoegen en/of verwijderen, en zelfs een tabel met accelerators (HOTKEYS die automatisch items selecteren uit uw menu zonder dat een gebruiker door de menu structuur hoeft te navigeren om de items te selecteren).

De meeste windows programmeer referentie boeken verklaren hoe deze taken uitgevoerd moeten worden, of u kunt, met geduld en een proberen het Windows API help bestand gebruiken om uit te puzzelen hoe dit soort zaken te doen.

 

CONCLUSIE

Menu’s zijn een centrale mogelijkheid van de meeste Windows programma’s. Met behulp van resource scripts kunt u deze menu’s eenvoudig aan uw programma toevoegen en met een paar aanroepen naar de Windows API op eenvoudige wijze uw programma er goed uit laten zien.

 

 

TOEVOEGING OVER HANDLES

Men kan geen boek over Windows openslaan of er wordt gesproken over handles. Wat is nu een handle? Een handle is eigenlijk letterlijk een handvat. En waarvoor gebruikt men een handvat normaal gesproken? Om dingen vast te pakken en te manipuleren, zoals een hete pan van het fornuis te halen.
Een Windows handle is niets anders dan een getal dat gekoppeld is aan een bepaalde Windows component. Die component kunnen we eenvoudig en eenduidig aanduiden met een uniek getal dat Windows vertelt over welk scherm we het hebben, of over welk menu, of welke knop.

Bij de aanmaak van bijvoorbeeld een scherm (‘window’) geeft Windows dit scherm een uniek nummer. Dit nummer krijgen we normaal gesproken niet te weten, tenzij we Windows vragen met welk uniek nummer het scherm wordt aangeduid. Dit unieke nummer kunnen we daarna gebruiken om aan de hand van dat nummer iets te doen met het scherm, bijvoorbeeld om aan te geven dat een bepaald menu moet worden toegevoegd aan ons scherm. Aangezien we niet per se meteen na het aanmaken van een scherm een menu hoeven toe te voegen, zou het kunnen zijn dat we eerst 4 schermen aanmaken en daarna pas het menu aan scherm 1 gaan toekennen (ziet u trouwens hoe ik het nummer ‘1’ koppel aan een bepaald scherm, dit nummer is in dit geval te beschouwen als een handle). Om Windows eenduidig te vertellen welk scherm het nieuwe menu moet krijgen, vragen we de handle op van het scherm en geven dit als parameter op bij de menu-koppeling.

 

Bezoek het PB forum in het Nederlands en/of teken mijn gastenboek.

Datum laatste aanpassing:
29 december 2003 03:42:06

Email mij voor reacties,
aanvullingen en correcties