Deel 3: Oppoetsen van uw Kylix programma venster

Brian Long (www.blong.com)

In dit derde deel van onze Kylix Open Edition cursus serie voegt Brian Long wat schoonheidsmiddelen toe aan onze tekstverwerker en geeft wat tips over het handiger omgaan met Kylix.


Dit artikel verscheen voor het eerst in Linux Format nummer 21, december 2001.

Klik hier om de bestanden verbonden met dit artikel te downloaden.

Inleiding

In het vorige hoofdstuk bouwden we een simpele tekstverwerker die bestanden kan laden en bewaren, zowel als nieuwe bestanden aanmaken. Deze keer gaan we door met dit project om te zien hoe het kan worden verbeterd. Dus open het project van vorige keer (TextEditor.dpr in de verbonden bestanden) en we gaan verder.

Als u niet onlangs aan het project gewerkt hebt, opent u het met File | Open Project..., of met Ctrl+F11. Als u het project wel onlangs hebt geopend, zult u het terugvinden in de history list (File | Reopen), maar merk op dat er twee delen zijn in de lijst. De bestanden aan de top zijn project bestanden (normaliter geopend met File | Open Project...) en die onderaan zijn units (normaliter geopend met File | Open...) - in dit geval moeten we een project openen, dus kies het juiste bestand.

Uitzonderingen – Geen paniek!

Voordat we iets anders doen met het project, moeten we het wellicht eerst over uitzonderingen hebben. CLX gebruikt een rijk fouten-afhandelingsmodel gebaseerd op uitzonderingen, die een programmatische representatie zijn van fouten. Als enig type fout zich voordoet, wordt een uitzondering gestart. Standaard vertoont de applicatie automatisch de uitzondering in de vorm van een meldingsvenster, terwijl bij het wegklikken van de melding het programma gewoon verder gaat. U kunt uw eigen foutafhandeling schrijven voor elke uitzondering die u wenst. Maar ook zonder dat handelt uw programma fouten normaal af.

We laten het bespreken van eigen foutafhandelingen over voor later, maar laten we voor nu eens zien hoe de Kylix IDE omgaat met applicatie uitzonderingen. Start het tekstverwerkingsprogramma door te drukken op F9 (of kies Run | Run). Kies File | Open... in het programma en voer de naam in van een niet bestaand bestand (bijvoorbeeld xyz), en druk dan OK.

Wat er nu gebeurt is dat de IDE op de voorgrond komt met een venster dat meldt dat uw programma een EFOpenError uitzondering heeft veroorzaakt, met een daarbij behorende melding. Ook wordt gemeld, dat uw programma is gestopt en dat u of in de debugger kunt overgaan of het programma toestaan verder te gaan (zie Figuur 1).

Figuur 1: De IDE meldt een applicatie uitzondering

Uitzondering

De situatie is dus als volgt: toen u uw programma startte, begon de Kylix debugger het programma actief te volgen. Toen de debugger ontdekte dat een uitzondering werd veroorzaakt, zette hij het programma onmiddellijk in de wacht, net alsof op die plaats een breakpoint was aangebracht.

Als u een echt programma zou ontwikkelen met heel veel code en u zou een onverwachte uitzondering moeten debuggen, kan dit gemakkelijk zijn omdat de debugger u onmiddellijk brengt bij de twijfelachtige coderegel in de editor. Echter: voor nieuwelingen in Kylix kan deze mogelijkheid een beetje verwarrend zijn.

Wat u nu zou moeten doen is de melding af te sluiten en opnieuw op F9 te drukken om het programma voort te laten gaan met de uitvoering, wat het zal doen met de melding van de fout zelf - dit is normaal. U kunt doorgaan het programma normaal te gebruiken en af te sluiten als u klaar bent.

Als u geen probleem hebt met het opduiken van de debugger telkens als zich een uitzondering in uw programma voordoet, des te beter. Als u liever wilt dat de debugger in deze gevallen zijn mond houdt, kunnen we hem dat duidelijk maken. Kies Tools | Debugger Options... en op de Language Exceptions pagina van de dialoog haalt u het vinkje weg bij Stop on Delphi Exceptions (zie Figuur 2). 

Figuur 2: Laat de debugger applicatie uitzonderingen negeren

Stop On Exceptions

Het plan

De verbeteringen die we gaan aanbrengen in de tekstverwerker omvatten een woord-omslag optie (handig voor tekstverwerkers) en een uitbreiding van de UI met menuplaatjes, een werkbalk die hot images ondersteunt, werktips en een status balk die hint informatie toont.

Laten we beginnen met de omslag optie. Klik dubbel op het menu onderdeel mnuMainMenu om terug te komen in de Menu Designer. Hier zullen we een Options menu invoegen door het selecteren van het Help menu in de Designer en door te drukken op de Insert toets (of rechtermuisknop klikken en selecteren van Insert). Geef een passende plek en naam en klik terug naar de Menu Designer en selecteer het lege menu onderdeel eronder. Geef dit onderdeel een naam van mniWordWrap, een omschrijving van &Word Wrap en een verkorte toetsaanslag van Ctrl+W.

Nu maken we een OnClick event handler voor het onderdeel dat het vinkje aan- en uitzet bij het menu onderdeel en stel de memo WordWrap eigenschap dienovereenkomstig.

procedure TfrmTextEditor.mniWordWrapClick(Sender: TObject);
begin
mniWordWrap.Checked := not mniWordWrap.Checked;
memText.WordWrap := mniWordWrap.Checked
end;

Om de zaak af te sluiten moeten we ons realiseren dat de omslagfunctie standaard aan staat, zodat u of de eigenschap Checked op True (zie Figuur 3) moet zetten of de eigenschap WordWrap op False, om daarmee in overeenstemming te zijn. U kunt ook de ScrollBars eigenchap op ssAutoBoth zetten om te verzekeren dat als er genoeg tekst is ingevoerd er schuifbalken zullen verschijnen om de gebruiker te helpen.

Figuur 3: Toevoegen van een nieuw menu

Menu Designer

Menu plaatjes

Om een visueel aantrekkelijk menu te krijgen met kleine plaatjes links van elk onderdeel moeten we een image list component hebben (van de Common Controls pagina van het componenten palet). Noem hem imlHotImages (we zullen later de betekenis van de term “hot” wel zien) en verbindt de eigenschap Images ermee. Dit stelt de menu onderdelen in de gelegenheid om gebruik te maken van de image list. Nu moeten we nog een paar plaatjes toevoegen.

Als Kylix is geinstalleerd, omvat hij een aantal voorbeeld plaatjes voor knoppen, menu's en dergelijke, geinstalleerd in de images directory van Kylix. Ze zien er nogal gedateerd uit, omdat het dezelfde plaatjes zijn die bij Delphi 1 zaten in 1995, maar omdat ze bij alle Kylix installaties zitten, zullen ze voor nu wel bruikbaar zijn.

Dubbel-klik om de image lijst en de bijbehorende editor wordt gestart. Deze staat u toe nieuwe plaatjes toe te voegen (u kunt dat zien in Figuur 6 en Figuur 7). Druk op de Add... knop en ga naar je Kylix installatie directory, en daarna naar de images/buttons subdirectory. U kunt nu een bitmap bestand uitkiezen om aan de image list toe te voegen. We adviseren u om telkens een image aan de lijst toe te voegen, omdat anders de volgorde in de war raakt en we mogelijk verkeerde plaatjes krijgen.

Het eerste plaatje is filenew.bmp (zie Figuur 4). Als u er naar kijkt ziet u een aantal dingen. Allereerst is er een lelijke olijfgroene achtergrond (die transparant wordt als hij in uw programma wordt gebruikt), en vervolgens is de bitmap feitelijk gemaakt van twee vierkante plaatjes. Het linker plaatje is een gekleurde versie en het rechterplaatje is een kleurloze versie.

Figuur 4: Een van Kylix’s voorbeeld plaatjes (ziet er een beetje uit als een rommeltje)

File New

Alle plaatjes in deze directory zullen deze attributen delen en u zult merken dat u bij het toevoegen van een plaatje aan de lijst, de vraag krijgt of u de bitmap in twee plaatjes wilt splitsen (zie Figuur 5). U dient al dat soort voorstellen te accepteren. De volledige lijst bitmaps voor de menu onderdelen omvat: filenew.bmp, fileopen.bmp, filesave.bmp, dooropen.bmp, cut.bmp, copy.bmp, paste.bmp, npadwrit.bmp (deze is niet erg toepasselijk, maar het was de beste die ik kon vinden).

Figuur 5: De image list editor die een gevoelige vraag stelt

Split Bitmap

Als ze allemaal zijn toegevoegd, krijgt u een image list met gekleurde en kleurloze versies van acht bitmaps (zie Figuur 6). Nu moeten we de image list component dupliceren, dus nadat u de image list op de Form Designer hebt geselecteerd, kiest u voor Edit | Copy en Edit | Paste, en u noemt de nieuwe image lijst daarna imlImages.

Figuur 6: Alle images zijn toegevoegd, zowel in- als uitgeschakelde

Full Image List

In de image list editor voor imlHotImages, kiest u elke uitgeschakelde image en u wist het. Daarna wist u alle ingeschakelde images in imlImages. Nu heeft u een image list van gekleurde, oftewel “hot” images en een exemplaar met kleurloze images.

Figuur 7: De hot image list

Hot Image List

Nu kunnen we de images toewijzen aan elk menu onderdeel. Dubbel-klik op de mnuMainMenu component en, in de Menu Designer, selecteert u elk menu onderdeel dat een image moet gaan krijgen en u stelt de ImageIndex eigenschap daarvan op de corresponderende image index (die u kunt doorscannen in de image list editor, zoals getoond in Figuur 7). Nu ziet het applicatiemenu er een stuk professioneler uit (zie Figuur 8), hoewel we nog geen gebruik hebben gemaakt van de kleurloze images.

Figuur 8: Het menu ziet er kleurrijker uit

Menu Images

Status balk hints

U vindt een statusbalk component op de Common Controls pagina van het Componenten Palet. Sleep een ervan op je formulier (geef hem de naam sbInfo) en hij kleeft aan de onderkant van je formulier omdat zijn Align eigenschap standaard staat op alBottom. De Kylix editor gebruikt een statusbalk component om verschillende stukjes informatie te tonen, zoals de cursor locatie, of een bestand gewijzigd is of niet en of u in invoeg- of in overschrijfmodus bent. Elk stuk informatie wordt vertoond in een apart statuspaneel op de statusbalk.

Om statuspanelen toe te voegen aan de statusbalk, gebruikt u de status paneel collectie editor, die gestart wordt door te dubbelklikken op de statusbalk of door de eigenschap editor te starten voor de Panels eigenschap. Druk twee keer op de gele knop van de collection editor (of de Insert toets) en u zult twee statuspanelen hebben, elk voorgesteld als een object.

Als een status paneel is geselecteerd in de collectie editor toont de Object Inspector zijn eigenschappen waardes (zie Figuur 9). De instance lijst bovenaan de Object Inspector informeert u ook over de vereiste syntax om te verwijzen naar dit speciale status panel object. Figuur 9 toont het eerste geselecteerde status paneel, waarnaar verwezen kan worden als sbInfo.Panels[0]. Verander de breedte van dit status paneel in  200 pixels (standaard is het 50).

Figuur 9: Eigenschappen van een area op een statusbalk

Status Panel Properties

Dit eerste paneel wordt gebruikt om hint informatie te tonen over onderdelen onder de muis cursor (zoals menu onderdelen en later gereedschapsknoppen). Dit gebeurt automatisch als u de AutoHint eigenschap van de status balk op True zet. Om dit uit te proberen, gaat u zoveel menu onderdelen terug als u wilt in de Menu Designer (of u selecteert ze met de Object Inspector’s instance lijst) en u voert een zinnige string in voor de Hint eigenschap.

Vervolgens zouden we het tweede paneel ergens voor moeten gebruiken, misschien om datum en tijd te tonen. Omdat dit elke seconde bijgewerkt moet worden, moet er een tijdklok component gebruikt worden van het Componenten Palet op de Additional pagina. Geef het de naam timClock e n een Interval van 250 (dit is gemeten in miliseconden, dus staat voor 1/4 seconde). Elke kwart van een seconde wordt de OnTimer event uitgevoerd, dus maakt u een event handler voor OnTimer (u kunt dubbelklikken op de tijdklok component op de Form Designer om dit te bereiken) en u voert deze code in:

procedure TfrmTextEditor.timClockTimer(Sender: TObject);
begin
sbInfo.Panels[1].Text := FormatDateTime(
'h:nn:ss am/pm "on" ddd, d mmm, yyy', Now)
end;

Hier wordt de BaseCLX routine Now aangeroepen, die datum en tijd retourneert als een TDateTime waarde, en doorgeeft aan FormatDateTime om een zelfgemaakte string representatie daarvan te geven, gebaseerd op de simpele invulling van bekende tekens (u kunt meer info over deze routines vinden in de Kylix helpfunctie). Merk op dat het woord 'on' een willekeurig worod is dat we in het resultaat willen zien, zodat het wordt ingesloten in dubbele aanhalingstekens om te voorkomen dat de letters worden vervangen.

Draai het programma en zie de resultaten. Figuur 10 toont de status balk die de hint toont voor het geselecteerde File | Exit menu onderdeel, evenals datum en tijd.

Figuur 10: Automatische hint vertoond op een statusbalk

Status Bar Hints

Toevoegen van een werkbalk

De volgende verbetering is het toevoegen van een werkbalk component, die kan worden gevonden op de Palet Common Controls pagina. Deze zal automatisch naar de top van het formulier gaan dankzij de standaard waarde van de eigenschap Align, op alTop staat. Verander de naam in  tbMainToolBar, zet Flat op True (dit geeft het effect van een compleet vlakke werkbalk, zoals die in Kylix, waarvan de knoppen 3D worden als de muis er overheen beweegt.), ShowCaptions op True (de werkknoppen op de balk kunnen een tekst tonen alsmede een plaatje) en AutoSize op True.

Een rechter muisklik op de werkbalk onhult twee nieuwe menu onderdelen: New Button en New Separator. Voeg net zoveel knoppen toe als u wenst (elk ervan zal een shortcut zijn voor een menu onderdeel), terwijl u de verschillende onderdelen van elkaar scheidt met separators. Voor elke werkbalkknop is de routine die moet worden aangeroepen de vorige keer al geimplementeerd in de event handlers van menu onderdeel OnClick.

Een handig extraatje van Kylix is dat we event handlers kunnen delen tussen verschillende events van verschillende componenten, tenzij de verwachte event handlers incompatibele parameter lijsten hebben. Liever dan een nieuwe event handler te maken voor elke nieuwe knop, kunnen we zijn OnClick event koppelen aan een bestaande event handler door een passend exemplaar te kiezen uit de lijst (zie Figuur 11).

Figuur 11: Een prima gelegenheid voor hergebruik van code

Shared Event Handler

Het voorbeeld project TextEditor2.dpr heeft werkknoppen met de volgende eigenschappen (we hebben de scheidingslijnen in de lijst genegeerd):

Name=tbnNew,	 Caption=New,	 OnClick=mniNewClick
Name=tbnOpen, Caption=Open, OnClick=mniOpenClick
Name=tbnSave, Caption=Save, OnClick=mniSaveClick
Name=tbnCut, Caption=Cut, OnClick=mniCutClick
Name=tbnCopy, Caption=Copy, OnClick=mniCopyClick
Name=tbnPaste, Caption=Paste, OnClick=mniPasteClick
Name=tbnWordWrap, Caption=Wrap, OnClick=mniWordWrapClick

Enkele laatste aanpassingen zijn nodig om de klus af te ronden. Bijvoorbeeld moet de Word Wrap werkknop omhoog of omlaag staan om de status aan te geven van de memo WordWrap eigenschap. Om hem omhoog en omlaag te kunnen laten gaan zet je de Grouped eigenschap op True, en daarna zet je Down op True (aangenomen dat je de memo WordWrap eerder al op True hebt gelaten).

Nu kunnen we de werkknoppen op de werkbalk vragen om de plaatjes te gebruiken in de image lists die we eerder hebben opgezet. Verbind de werkbalk Images eigenschap met imlImages en zijn HotImages eigenschap met imlHotImages. Veel werkbalken zullen alleen een Images eigenschap gebruiken, om de plaatjes te verschaffen vereist door de werkknoppen.

De HotImages eigenschap levert een extra mogelijkheid waarbij als de muis over een werkknop beweegt, de image wordt vervangen door de corresponderende hot image, om het feit te benadrukken dat hij beschikbaar is en onder de muis. Hot images dienen de gebruiker te helpen bij het nagaan wat er gebeurt. We hebben al eerder de  Flat eigenschap ingesteld, wat wil zeggen dat de vlakke werkknop 3D wordt als de muis er overheen gaat, maar met de HotImages eigenschap ingesteld als we hebben gedaan, verandert de werkknop ook van een kleurloze plaat naar een gekleurde image.

Toevoegen van werktips

The last item on the agenda for this month is to get some tooltips showing for the toolbuttons. We already have control hints being displayed automatically in the status bar, but we can also have real tooltips (popup hint windows) if we choose.

Every control that can display a tooltip has a ShowHint property, which defaults to False. If you set the form’s ShowHint property to True, it will propagate down through all the child controls on the form (thanks to the common ParentShowHint property defaulting to True). This is the first step.

The next thing to do is to give each toolbutton a descriptive tooltip string to display (this is again controlled by the Hint property). However, if you think about it (or indeed test it), this will cause the hint string to be displayed twice for every toolbutton, once in the status bar and once in a tooltip.

To improve upon this situation, the Hint property of any control can optionally contain two strings, separated by a pipe sign. For example, the Open toolbutton in the supplied version of this project has a Hint property of:

Open file|Open an existing document

The status bar displays the second (typically lengthier) string, whilst the tooltip displays the first string. You can see the final version of the program running in Figuur 12, showing a tooltip, a status bar hint and also the Open toolbutton’s hot image.

Figuur 12: Toolbars, menu images, tooltips, status bars and hints... what more do you want?

Nice UI

Appendix A: Kylix Tips

Figuur 13: A quick way of getting the recent file list

Reopen Menu

Appendix B: Aanbevolen instellingen

Er zijn een aantal opties in de Kylix IDE die naar onze mening kunnen zorgen voor een soepeler ontwikkelingsomgeving. Hier zijn er een paar:

Figuur 14: De Environment Options dialoog met een stel nuttige instellingen

Environment Options

Samenvatting

We hebben de UI van onze tekstverwerker met sprongen vooruit zien gaan, dank zij de rijke componenten en eigenschappen beschikbaar in de CLX bibliotheek. Toch zijn er nog gebieden die voor verbetering in aanmerking komen.

Bijvoorbeeld, als we willen dat de werkbalk en het menusysteem contekst-gevoelig zijn, zodat knoppen en onderdelen alleen geactiveerd zijn als ze relevant zijn, wordt het wel wat ingewikkeld. Elke keer dat er iets gebeurt in het programma moeten we zowel het menu onderdeel als de bijbehorende knop in- of uitschakelen (en elke andere bestuursonderdelen die hetzelfde gedrag kunnen beinvloeden).

In het volgende hoofdstuk kijken we naar actions, dat zijn CLX objecten die speciaal ontworpen zijn om precies dit soort situaties te stroomlijnen.

Voor we afsluiten moet ik nog melden, dat alles wat we tot dusver gedaan hebben met Kylix Open Edition en praktisch alles wat je er mee kunt doen, ook gedaan kan worden met Delphi, Borland's commerciele applicatie ontwikkelingssysteem voor Microsoft Windows. Delphi 6 Enterprise Edition is een product vergelijkbaar met Kylix 1 Server Developer en Kylix 2 Enterprise Edition, Delphi 6 Professional Edition is vergelijkbaar met Kylix 1 Desktop Developer en Kylix 2 Professional Edition, en Delphi 6 Personal Edition is gelijkend op Kylix 1 en 2 Open Edition, maar heeft niet de mogelijkheid tot het maken van GPL applicaties en geeft ook geen mogelijkheid tot het distribueren van applicaties.

U kunt onze Kylix projecten nemen en ze direct in Delphi inladen en ze draaien als Windows applicaties vanwege de cross-platform eigenschappen van de CLX component bibliotheek op source niveau.

Over Brian Long

Brian Long werkte eertijds voor Borland UK, waar hij een heel aantal verplichtingen had waaronder Technische Ondersteuning voor alle programmeer applicaties. Sinds hij in 1995 wegging, heeft Brian training en consultancy diensten verleend aan de Delphi en C++Builder gemeenschappen, en de zich nieuw vormende Kylix gemeenschap.

Als u training nodig hebt in deze producten, of oplossingen moet hebben voor problemen ermee, neem dan contact op, of bezoek Brian's Web site.

Behalve het schrijven van een Borland Pascal probleem-oplossend book gepubliceerd in 1994, is Brian een regelmatige columnist in The Delphi Magazine en heeft hij talloze artikelen gepubliceerd in Developer's Review, Computing, Delphi Developer's Journal en EXE Magazine. Hij werd genomineerd voor de Spirit of Delphi 2000 prijs.

In zijn vrije tijd (en tijdens het wachten op de compilatie van zijn C++ programma's) heeft Brian zichzelf de kunst van het jongleren aangeleerd en het maken van opblaasbare origami papieren kikkers.




Back to top