Het klokje loopt!

Form verwijderen

Wel zit het klokje nog in een form en dat is niet de bedoeling. Ik bedoel hiermee dat ik het form niet wil zien, maar alleen het label waar de tijd staat. Uiteraard blijft het form wel bestaan maar moet aan het zicht onttrokken worden.

Het klokje moet wel verplaatsbaar blijven en daar zit nu de uitdaging.

Om te beginnen gaan we de knop OK weghalen.

– Klik in de form op de button OK en druk dan op de Del(ete)-toets.

Lazarus verwijdert nu de knop van het form en in de code de verwijzing naar TButton in de class-definitie.

Wat echter niet gebeurt is het weghalen van de event-handler btnOkClick. Dit moeten we zelf doen

– Ga naar het Broncode-venster en verwijder uit de class-definitie de regel met procedure btnOkClick.
– Verwijder in de implementation-sectie de gehele procedure btnOKClick (dus t/m de end;).
– Run de applicatie en sluit deze daarna weer.

Handigheidje: Wanneer u in de code de gehele regel waar de cursor staat wilt verwijderen kunt u Ctrl+y gebruiken (Och, waar is WordStar toch gebleven?).

Nu gaan we vanuit de code het form precies zo groot maken als het label.

Het Label heeft de property AutoSize. Als deze de waarde True heeft dan wordt er automatisch voor gezorgd dat alle tekst in het label past. Ook wanneer het Font wijzigt zal de grootte van het Label worden aangepast. We moeten er dus voor zorgen dat wanneer het Label van grootte verandert het Form dit ook doet. En daarvoor heeft het Label een event OnResize dat “afgaat” wanneer het Label van grootte wijzigt. En dit event moeten we dus gaan afvangen.

– Klik op het form op het Label lblTijd.
– Ga in de Object Inspector naar de tab Gebeurtenissen.
– Zoek de regel met OnResize.
– Dubbelklik in het lege vak rechts naast OnResize.

Het code-venster wordt weer zichtbaar en Lazarus heeft de event-handler lblTijdResize toegevoegd. In deze procedure gaan we het form even groot maken als het label.

– Voeg de volgende regels code toe in de procedure lblTijdResize:
  frmKlokje.Width := lblTijd.Width;
  frmKlokje.Height := lblTijd.Height;
– Run nu het klokje weer.

De hoogte van het form is nu precies goed. De breedte is echter (nog) niet goed:

Dit komt omdat het form zelf nog knoppen heeft in de titel-balk. Deze moeten we eerst weghalen. Probleem wat hier dan bij optreedt is dat we de sluitknop gaan missen en dus het klokje niet meer kunnen afsluiten. Daarvoor gaan we eerst een (tijdelijke) oplossing maken.

– Sluit het klokje.
– Selecteer in de form het label lblTijd.
– Ga in de Object Inspector naar de tab Gebeurtenissen en zoek de regel met OnDblClick.
– Dubbelklik in het vak daar rechts van.
– Voeg in het code-venster de regel close; toe
– Run het project en dubbelklik op de tijd.

Het klokje sluit nu door te dubbel-klikken op de tijd.

Even een paar opmerkingen tussen door.

Opmerking: Ieder component heeft een default-event. Wanneer u in de form dubbelklikt op een component zal Lazarus de default event-handler aanmaken. Voor veel componenten zal dat het OnClick-event zijn, maar voor bijvoorbeeld de Timer is dat het OnTimer-event. Wanneer u een ander event dan het default-event wilt afvangen dan moet dat dus via de Object Inspector in de tab Gebeurtenissen.

Opmerking: Bijna alle events zullen bij het opstarten van de applicatie minimaal 1 keer afgaan. Dit geldt dus ook voor het OnResize-event van het label. Daarom werkt de code ook bij het starten van het klokje ondanks dat u wellicht het idee had dat het Font e.d. niet veranderd waren.

We gaan nu de randen van het form “verwijderen”.

– Klik ergens in de form (dus niet op het label of de timer).
– Ga naar de Object Inspector (tab Eigenschappen).
– Zoek de property BorderStyle en kies uit de combobox de waarde bsNone.
– Run het project en dubbelklik op de tijd om te stoppen. Lukt dit niet dan kunt u ook op de rode vierkante knop in Lazarus klikken.

Door de property BorderStyle van het form op bsNone te zetten worden de randen van het form onzichtbaar. En dit is precies wat we wilden.

Klokje verplaatsen

Het enige dat we in deze aflevering nog moeten doen is ervoor zorgen dat het klokje naar een andere plaats kan worden versleept.

Daarvoor hebben we drie events en een paar globale variabelen nodig.

De werkwijze komt op het volgende neer:

  1. Als er met de muis op de klok wordt geklikt dan moet dit worden gedetecteerd en moet de positie worden bewaard;
  2. Als de linker muis-knop weer wordt losgelaten dan moet dit ook worden gedetecteerd;
  3. Als er met de muis op de klok wordt gesleept dan moet de positie van de klok met de muis meegaan.

Regel 1 en 2 zijn nodig voor regel 3. Er wordt namelijk gesleept als de linker muis-knop wordt ingedrukt.

Gelukkig hebben we genoeg soorten events om e.e.a. te laten werken. De events die we gaan gebruiken zijn: OnMouseDown (gaat af als een muisknop wordt ingedrukt), OnMouseUp (gaat af als een muisknop weer wordt losgelaten) en OnMouseMove (gaat af als de muis wordt bewogen).

Omdat de verschillende events de muis-knop-status (op of neer) moeten weten gaan we gebruik maken van een globale variabele binnen het implementation-deel van de unit.

– Ga naar het Code-venster.
– Voeg twee regels toe in het implementation-deel onder {$R *.lfm}.
– Voeg de volgende regels code toe:
–   var
    MD: Boolean;
    MyX, MyY: integer;

De variabele MD (MouseDown) gaat onthouden of de muisknop is ingedrukt (MD := True) of niet (MD := False). De variabelen MyX en MyY gaan de positie van de klok onthouden wanneer de muis-knop wordt ingedrukt.

– Klik in de form op het label lblTijd.
– Activeer in de Object Inspector het event OnMouseDown.
– Voeg de volgende regels code toe:
  MD := True;
  MyX := X;
  MyY := Y;
– Activeer (in de Object Inspector) het event OnMouseMove.
– Voeg de volgende regels code toe:
  if MD then
    begin
      frmKlokje.Left := frmKlokje.Left + (X – MyX);
      frmKlokje.Top := frmKlokje.Top + (Y – MyY);
    end;
– Activeer het event OnMouseUp.
– Voeg de volgende regel code toe:
  MD := False;
– Run het klokje en probeer het eens te verplaatsen.
– Sluit het klokje weer door erop te dubbel-klikken.

De events OnMouseDown en OnMouseMove (en ook OnMouseUp, maar dat is nu niet interessant) hebben een aantel parameters, waaronder X en Y. Deze bevatten de huidige X en Y positie van het label op het scherm. Bij de OnMouseDown worden deze onthouden in MyX en MyY.
Bij OnMouseMove worden de X en Y positie van het form (resp. in Left en Top) bijgewerkt met de X en Y van de OnMouseMove t.o.v. de X en Y van de OnMouseDown. Daardoor kunt u nu de klok met de muis verplaatsen.

De puristen onder u hebben wellicht gemerkt dat de klok versleepbaar is met, om het even, welke muisknop ingedrukt dan ook. Dus ook met de rechter muisknop of het muiswieltje of een combinatie van knoppen ingedrukt is de klok te verslepen.

Als u alleen de klok wilt verslepen met de linker muisknop ingedrukt dan moet u de eerste regel code in het OnMouseDown-event als volgt veranderen:

  MD := (Button = mbLeft);

In de parameter Button zit namelijk de waarde(s) van de ingedrukte knop(pen).

We hebben ons doel bereikt. Het klokje loopt zonder form en is keurig versleepbaar.

In de volgende aflevering gaan we een pop-up-menu toevoegen, ervoor zorgen dat het klokje doorzichtbaar wordt en altijd zichtbaar blijft.

Naar de volgende aflevering…