Delphi tools: Align component editorGeplaatst door Baldo op 10-04-03Erik Stok (aka Baldo)
Delphi’s open tools api (OTA) biedt geweldige mogelijkheden om de IDE
uit te breiden met handigheden van jezelf. Er is veel over de OTA te vinden
op het web, maar veel artikelen vertellen vooral wat er kan en verzuimen een
praktisch toepasbaar voorbeeld te geven van het gebruik van de OTA. NLDelphi
is een plaats die draait om Delphi in de praktijk, dus een betere plaats om
de praktische kan van de OTA te beschrijven kan ik me niet indenken. Dit tweede
artikel beschrijft het bouwen van een component editor.
Het idee
RSI is een niet te onderschatten risico in het vak van de programmeur. Voor
mezelf was het gebruik van de muis tijdens het ontwerpen van schermen vaak een
net iets te zware belasting. Toen ik zag dat ik vaak dezelfde handelingen aan
het verrichten was, ging het instinct van de programmeur alweer kriebelen om
dit te automatiseren. De align component editor was geboren.
De schermen die ik bouw bestaan veelal uit een aantal wincontrols met daarvoor
een label met wat er in deze wincontrols kan worden ingevuld. Tussen de wincontrols
wordt een afstand gehouden van 4 pixels, de labels ervoor worden links uitgelijnd
en de wincontrols worden links uitgelijnd op afstand van 4 pixels van het breedste
label. Onderstaande afbeelding is hiervan een voorbeeld.

Vaak liggen deze wincontrols in een container zoals een panel, groupbox of
tabsheet. De tabvolgorde van de wincontrols loopt van boven naar beneden.
Wat ik wilde doen was ervoor zorgen dat ik voor een aantal containers een functie
kon starten die de wincontrols zou uitlijnen volgens de genoemde regels.
Het meest gemakkelijk leek mij een rechtsklik op de container waar de controls
in liggen. Een component editor lag voor de hand dus. In dit artikel zal ik
de bouw van deze component editor behandelen.
Component editors
In de DesignEditors unit (terug te vinden in de Delphi map onder Source\ToolsAPI)
zit een class genaamd TComponentEditor. Door een afgeleide van deze class te
maken en bepaalde methods te overriden is het eenvoudig een eigen component
editor te maken. Als in de Delphi help gezocht wordt op TComponentEditor dan
staat vrij expliciet uitgelegd wat de TComponentEditor allemaal kan. Ik ga hier
dan ook niet verder in op de details van TComponentEditor, behalve die details
die noodzakelijk zijn om de align component editor te bouwen.
Het zal geen verrassing zijn dat de class definition voor de align component
editor er als volgt uitziet:
TAlignEditor = class(TComponentEditor) function GetVerbCount: Integer; override; function GetVerb(Index: Integer): string; override; procedure ExecuteVerb(Index: Integer); override; end;
Via de GetVerbCount method kunnen we aangeven hoeveel acties er kunnen
worden uitgevoerd met de component editor. In dit geval is er één
actie voor de component editor geïmplementeerd: align.
Om het pop-up menu te kunnen vullen zal voor het aantal acties opgegeven in
GetVerbCount de GetVerb van de component editor aangeroepen worden
om de captions van de menu items op te halen. In dit geval is er maar één
menu-item dus kan worden volstaan met het resultaat ‘Align’.
De executeverb method zal worden aangeroepen voor de in het pop-up menu
geselecteerde menu-item. In dit geval is er maar één mogelijke
actie, dus kan altijd de align worden uitgevoerd.
Voorwaarden voor uitlijnen
Het is eenvoudig om de wincontrols uit te lijnen op basis
van de tabvolgorde. Het maken van een lijst van wincontrols, het sorteren van
deze lijst op tabvolgorde en de contols in de lijst en het links uitlijnen is
voldoende om dat gedaan te krijgen. De moeilijkheid zit hem in de labels voor
de controls. Hoe komt de component editor te weten welk label bij welk control
hoort zodat deze mee uitgelijnd kan worden?
De oplossing ligt in de focuscontrol property van het label. Indien
een label wordt aangemaakt om voor (of boven) een control te plaatsen dan is
het vestandig om in de focuscontrol property van het label in te vullen
voor welk control het label van toepassing is. Indien in de caption van
het label namelijk een shortcut verwerkt wordt, dan zorgt de focuscontrol
property ervoor dat bij het intoetsen van de shortcut de focus naar het overeenkomstige
control gezet wordt. Veel programmeurs gebruiken deze property niet en plaatsen
maar wat labels voor controls, maar het is aan te raden gebruik te maken van
deze functionaliteit. Sterker nog: om het uitlijnen te laten werken is het zelfs
noodzakelijk om hiervan gebruik te maken.
Uitlijnen
Door voor ieder item in de lijst van uit te lijnen wincontrols van de container
te kijken welk label er via de focuscontrol property gekoppeld is, is
het mogelijk om parallel aan de lijst van wincontrols een lijst van labels samen
te stellen. Zodra beide lijsten bekend zijn is het eenvoudig om de positie van
de labels te bepalen en de controls achter de labels te plaatsen.
Het package waarin de broncode staat
voor de simpele versie van de component editor kan worden geïnstalleerd
net als ieder ander designtime package. Het is mogelijk om de component editor
te registreren voor ieder container die afgeleidt is van TWinControl.
Selectief uitlijnen
Er zijn natuurlijk gevallen waarin er wincontrols in de container staan waar
geen uitlijning op gewenst is. Als deze controls al juist uitgelijnd staan (bijvoorbeeld
een set buttons onderaan het scherm) dan moet het mogelijk zijn om deze buiten
beschouwing te laten bij het uitlijnen. Om dit te kunnen bewerkstelligen kan
er een selectiescherm voor het daadwerkelijke uitlijnen worden getoond waarin
de gebruiker kan aangeven welke wincontrols dienen te worden uitgelijnd.
Het package waarin de broncode
staat voor deze versie van de component editor kan worden geïnstalleerd
net als ieder ander designtime package.
Conclusie
Het is duidelijk dat de Delphi open tools api op eenvoudige wijze toestaat
handige IDE extensies te maken die het leven vereenvoudigen. En het mooiste
is: alles kan worden geprogrammeerd in de bekende Delphi syntax. De align component
editor is een voorbeeld hiervan dat menige ontwikkelaar zal aanspreken vanwege
zijn eenvoud en toepasbaarheid.
|