Afleveringen In deze laatste aflevering gaan we de volgende punten behandelen: Genoeg te doen dus. Wanneer we via frmAlarmSettings zaken hebben veranderd en we keren terug naar de klok, dan worden er allerlei globale variabelen van een waarde voorzien. Keren we echter terug naar het Settings-scherm dan zien we deze waarden niet terug. Dit moeten we dus even aanpassen. – Ga naar de code van frmAlarmSettings (Unit4). Na de laatste handeling staat nu de volledige naam van het externe bestand op het venster, inclusief het pad en onze eigen toevoeging FILE:. Dit is niet de bedoeling. We willen alleen de bestandsnaam zien. De padverwijzing kan dan in de Hint (dit is het gele labeltje in Windows als je met de muis iets aanwijst). En uiteraard moet de toevoeging FILE: al helemaal niet zichtbaar zijn. – Ga naar de code van frmAlarmSettings (Unit4). In de property Hint staat wat er in het gele labeltje moet komen te staan. Met de property ShowHint activeert of deactiveert u de Hint. We gaan nu de Snooze-knop implementeren. Als het alarm afgaat en de gebruiker klikt op Snooze dan moet het alarm na 5 minuten nogmaals afgaan. Uiteraard is deze 5 minuten arbitrair en het staat u natuurlijk vrij om hier een andere tijdseenheid voor te kiezen of deze zelfs variabel te maken. Met al uw kennis die u nu heeft moet dat te doen zijn. – Ga naar de code van frmAlarm (Unit5). Het is ook netjes om de datum weer te geven wanneer de klok wordt aangewezen. – Ga naar de code van frmKlokje (Unit1). Dat zowel het Label als de ImageBox de Hint laten zien komt door de property ParentShowHint die default op True staat en de Hint van de Parent (hier frmKlokje) laat zien. – Ga naar tmrTijdTimer. We hebben inmiddels aardig wat menu-opties toegevoegd en velen daarvan hebben nog geen icoontjes. U weet inmiddels hoe u deze kunt toevoegen: Icoontjes toevoegen aan ilstIconen en daarna de juiste index toevoegen aan de property ImageIndex van de menu opties. – Ga naar de code van frmKlokje (Unit1). De kleurtjes staan er. Met de property Brush stelt u, o.a., de kleur in waarmee moet worden “geschilderd”. Met de method FloodFill schildert u de oppervlakte (16×16) van de bitmap. FloodFill heeft 4 paramters. De eerste twee zijn de x- en de y-coördinaat die de positie aangeven vanaf waar geschilderd moet worden. De derde parameter leest de kleur uit op een bepaalde plaats. De vierde parameter bepaalt waar de FloodFill moet stoppen. Als deze fsSurface is dan wordt er gevuld vanuit het aangegeven punt totdat er een andere kleur dan de derde parameter wordt gevonden. Als deze fsBorder is dan wordt er gevuld totdat dezelfde kleur is gevonden. De icoontjes moeten natuurlijk van kleur veranderen als er een andere kleur wordt gekozen. Dit gebeurt in het popAnalogColorsClick event. – Ga naar popAnalogColorsClick. Voeg naar smaak nog andere icoontjes voor de menu opties toe, behalve voor de opties met al dan niet een vinkje! Het kan voorkomen dat bij het starten het klokje niet zichtbaar wordt. Bijvoorbeeld als de laatste keer het klokje op het tweede scherm stond en bij het opnieuw starten het tweede scherm niet actief is. We moeten dus een “reset” mogelijkheid inbouwen. Dit is gelukkig niet zo erg ingewikkeld. We gaan een zogenaamde command-line-switch implementeren: -reset. Wanneer iemand nu klokje.exe -reset gebruikt dan moet het cfg-bestand default-waardes krijgen. Het is dan wel zo netjes om een copy van het bestaande cfg-bestand te bewaren. – Ga naar de code van frmKlokje (Unit1). Even wat uitleg bij de code. Als het klokje is gestart dan ziet u in de taakbalk een knop met het (standaard) icoontje van Lazarus. Uiteraard wilt u hier uw eigen icoon. En dit gaan we nu doen. – Ga in het Lazarus menu naar Project–>Project Opties… . Dit was niet het moeilijkste. En het volgende is dat ook niet. Wanneer u nu in de Verkenner naar de grootte van de executable kijkt dan ziet u dat deze rond de 30 MB zit. Dit komt mede door de resources die we hebben toegevoegd, zoals de icoontjes, de muziekjes en de klokwijzers, maar ook doordat Lazarus nogal wat debug-informatie heeft toegevoegd. Als de applicatie los wordt gebruikt dan heeft u deze debug-informatie niet nodig. Via de compiler-opties kunt u deze informatie “eruit” gooien. – Ga in het Lazarus menu naar Project–>Project Opties… . In de Verkenner kunt u nu zien dat uw klokje nog maar rond de 10 MB groot is, toch een besparing van zo’n 60 à 70%. We zijn klaar met al onze puntjes. Ik hoop dat u er veel van geleerd heeft. Het is een eenvoudig projectje, maar met heel veel technieken die u in een groter project ook zeker zal willen gebruiken. Rest mij niets anders dan u nog alle code te geven: Hieronder de code voor Unit1 t/m Unit5: Unit1 unit Unit1; {$mode objfpc}{$H+} interface uses type { TfrmKlokje } TfrmKlokje = class(TForm) var implementation {$R *.lfm} Uses var { TfrmKlokje } procedure TfrmKlokje.LeesIni; s := ini.ReadString(‘FONT’,’Name’,’Arial’); popOpacity100.Checked := True; popAnalogSizeSmall.Checked := False; s := ini.ReadString(‘ALARM’,’Sound’,”); procedure TfrmKlokje.SchrijfIni; ini.WriteString(‘FONT’,’Name’,lblTijd.Font.Name); if popOpacity100.Checked then case ClockSize of ini.WriteString(‘ALARM’,’Sound’,SoundName); procedure TfrmKlokje.tmrTijdTimer(Sender: TObject); frmKlokje.Canvas.Pen.Color := ColorHour; frmKlokje.Canvas.Pen.Color := ColorMinute; frmKlokje.Canvas.Pen.Color := ColorSecond; procedure TfrmKlokje.lblTijdResize(Sender: TObject); procedure TfrmKlokje.popAboutClick(Sender: TObject); procedure TfrmKlokje.popAlarmSettingsClick(Sender: TObject); procedure TfrmKlokje.popAnalogClockfaceClick(Sender: TObject); procedure TfrmKlokje.popAnalogColorsClick(Sender: TObject); procedure TfrmKlokje.popAnalogOnClick(Sender: TObject); procedure TfrmKlokje.popAnalogSizeClick(Sender: TObject); procedure TfrmKlokje.popFontBackColorClick(Sender: TObject); procedure TfrmKlokje.popFontFontClick(Sender: TObject); procedure TfrmKlokje.popFontForeColorClick(Sender: TObject); procedure TfrmKlokje.popOnTopClick(Sender: TObject); procedure TfrmKlokje.popOpacity100Click(Sender: TObject); procedure TfrmKlokje.popOpacity25Click(Sender: TObject); procedure TfrmKlokje.popOpacity50Click(Sender: TObject); procedure TfrmKlokje.popOpacity75Click(Sender: TObject); procedure TfrmKlokje.popSluitClick(Sender: TObject); procedure TfrmKlokje.lblTijdDblClick(Sender: TObject); procedure TfrmKlokje.FormClose(Sender: TObject; var CloseAction: TCloseAction); procedure TfrmKlokje.FormCreate(Sender: TObject); procedure TfrmKlokje.FormPaint(Sender: TObject); lblTijd.Visible := False; aBitmap := TBitmap.Create; lblTijd.Visible := True; procedure TfrmKlokje.FormActivate(Sender: TObject); procedure TfrmKlokje.lblTijdMouseDown(Sender: TObject; Button: TMouseButton; procedure TfrmKlokje.lblTijdMouseMove(Sender: TObject; Shift: TShiftState; X, procedure TfrmKlokje.lblTijdMouseUp(Sender: TObject; Button: TMouseButton; end. Unit2 unit Unit2; {$mode objfpc}{$H+} interface uses type { TfrmAbout } TfrmAbout = class(TForm) var implementation {$R *.lfm} { TfrmAbout } procedure TfrmAbout.btnOKClick(Sender: TObject); procedure TfrmAbout.lblWebsiteClick(Sender: TObject); end. Unit3 unit Unit3; {$mode objfpc}{$H+} interface uses type { TfrmFaces } TfrmFaces = class(TForm) var implementation {$R *.lfm} Uses var { TfrmFaces } procedure TfrmFaces.BrowseImages; procedure TfrmFaces.FormActivate(Sender: TObject); procedure TfrmFaces.btnLeftClick(Sender: TObject); procedure TfrmFaces.btnCancelClick(Sender: TObject); procedure TfrmFaces.btnOKClick(Sender: TObject); procedure TfrmFaces.btnRightClick(Sender: TObject); end. Unit4 unit Unit4; {$mode objfpc}{$H+} interface uses type { TfrmAlarmSettings } TfrmAlarmSettings = class(TForm) function PlayAlarm(AlarmNaam: String): Boolean; var implementation {$R *.lfm} Uses var function PlayAlarm(AlarmNaam: String): Boolean; function StopAlarm: Boolean; { TfrmAlarmSettings } procedure TfrmAlarmSettings.HintAan; procedure TfrmAlarmSettings.btnCancelClick(Sender: TObject); procedure TfrmAlarmSettings.btnOKClick(Sender: TObject); procedure TfrmAlarmSettings.btnOtherAlarmClick(Sender: TObject); procedure TfrmAlarmSettings.btnPlayClick(Sender: TObject); procedure TfrmAlarmSettings.FormActivate(Sender: TObject); procedure TfrmAlarmSettings.lstAlarmClick(Sender: TObject); initialization end. Unit5 unit Unit5; {$mode objfpc}{$H+} interface uses type { TfrmAlarm } TfrmAlarm = class(TForm) var implementation {$R *.lfm} Uses { TfrmAlarm } procedure TfrmAlarm.FormActivate(Sender: TObject); procedure TfrmAlarm.FormClose(Sender: TObject; var CloseAction: TCloseAction); procedure TfrmAlarm.lblOKClick(Sender: TObject); procedure TfrmAlarm.lblSnoozeClick(Sender: TObject); end. Wellicht tot een volgende serie…We gaan de puntjes op de i zetten.
Alarm-instellingen met de juiste waardes
– Ga naar FromActivate.
– De eerste twee regels moeten worden omgedraaid en als volgt worden aangepast:
– SoundNameTmp := SoundName;
– lblAlarm.Caption := SoundNameTmp;
– Voeg hierna de volgende twee regels toe:
– edtAlarmText.Text := AlarmTekst;
– dtpAlarmTijd.Time := AlarmTijd;
– Run het klokje en experimenteer met de instellingen en kijk of deze nu goed staan wanneer Settings opnieuw wordt geopend.
– Laad tot slot nog even een externe sound en klik daarna op de knop OK.Hints
Nu wordt lblAlarm op drie verschillende plaatsen veranderd. We moeten dus een generieke oplossing voor het Label hebben. We zouden hier profijt hebben als er een Label-OnChange event zou bestaan, maar helaas, deze bestaat niet. Dus maar gewoon een procedure maken.
– Voeg in de class-definitie in de sectie private de volgende regel toe:
– procedure HintAan;
– Ga naar de implementation-sectie en voeg na de function StopAlarm (na { TfrmAlarmSettings }) de volgende code toe:
– procedure TfrmAlarmSettings.HintAan;
– var
– s: String;
– begin
– if LeftStr(UpperCase(SoundNameTmp),5) = ‘FILE:’ then
– begin
– s := Copy(SoundNameTmp,6,Length(SoundNameTmp));
– lblAlarm.Caption := ExtractFileName(s);
– lblAlarm.Hint := ExtractFilePath(s);
– lblAlarm.ShowHint := True;
– end
– else
– begin
– lblAlarm.ShowHint := False;
– lblAlarm.Caption := SoundNamenTmp;
– end;
– end;
– Ga naar het event btnOtherAlarmClick.
– Haal de regel lblAlarm.Caption := … weg.
– Verander de regel SoundNameTmp := … als volgt:
– SoundNameTmp := ‘FILE:’ + dlgOpenFile.FileName;
– Voeg hierna de volgende regel toe:
– HintAan;
– Ga naar FormActivate.
– Vervang de regel lblAlarm.Caption := … door:
– HintAan;
– Ga naar lstAlarmClick.
– Vervang de code door de volgende regels:
– SoundNameTmp := lstAlarm.Items[lstAlarm.ItemIndex];
– HintAan;
– Run het klokje en kijk of bovenstaande werkt.Snooze
– Activeer het event lblSnoozeClick.
– Voeg de volgende variabele toe:
– var
– u,m,s,ms: Word;
– Voeg (na begin) de volgende regels code toe:
– DecodeTime(Now,u,m,s,ms);
– if (m + 5) >= 60 then
– begin
– m := (m + 5) mod 60;
– u := u + 5;
– end
– else
– m := m + 5;
– AlarmTijd := EncodeTime(u,m,s,ms);
– AlarmAan := True;
– close;
– Run de klok en test de code. (Om “snel” te testen kunt u even de regel m := m + 1; voor AlarmTijd := … toevoegen).Datum als Hint
– Ga naar FormActivate.
– Voeg de volgende regel code toe voor de regel LeesIni;:
– frmKlokje.Hint := FormatDateTime(‘dddd dd mmmm yyyy’,Now);
– Ga naar de Obejct Inspector en zet de property ShowHint van frmKlokje op True.
– Merk op dat nu ook (automatisch) de ShowHint-properties van lblTijd ene imgFace op True staan.
– Run de klok en wijs deze aan.
Dit was dus niet moeilijk. Alleen komt er een probleem wanneer de klok 00:00:00 slaat (ofwel op middernacht), want dan verandert de datum. Dit moet worden ondervangen in het Timer event tmrTijdTimer.
– Voeg als laatste regels code toe (dus voor end;):
– if FormatDateTime(‘hh:mm:ss’,Now) = ’00:00:00′ then
– frmKlokje.Hint := FormatDateTime(‘dddd dd mmmm yyyy’,Now);Menu-optie-icoontjes van een kleur voorzien
Het zou mooi zijn als de kleur van de opties Hour, Minute en Second ook als icoontje zichtbaar zou zijn. Dit is echter niet zo eenvoudig.
Nu heeft een menu optie een property Bitmap, waarin een bitmap kan worden geladen als icoontje. En hiervan gaan we gebruik maken.
– Ga naar LeesIni.
– Voeg de volgende variabele toe:
– bm: TBitmap;
– Ga onder de regels staan waar u de indent ColorHour heeft verwerkt.
– Voeg daar de volgende regels toe:
– bm := TBitmap.Create;
– bm.Width := 16;
– bm.Height := 16;
– bm.Canvas.Brush.Color := ColorHour;
– bm.Canvas.FloodFill(8,8,bm.Canvas.Pixels[8,8],fsSurface);
– popAnalogColorsHour.Bitmap := bm;
– bm.Free;
Doe ditzelfde onder de regels voor ColorMinute en ColorSecond, waarbij ColorHour en popAnalogColorsHour natuurlijk mee moeten veranderen.
Run het klokje en wijs in het menu de optie Analog–>Colors aan.FloodFill
Met deze methode kan dus een willekeurig figuur met een bepaalde kleur worden gevuld.
– Voeg in het if dlgColor.Execute then-blok na de case-constructie de volgende regels toe:
– bm := TBitmap.Create;
– bm.Width := 16;
– bm.Height := 16;
– bm.Canvas.Brush.Color := c;
– bm.Canvas.FloodFill(8,8,bm.Canvas.Pixels[8,8],fsSurface);
– (Sender as TMenuItem).Bitmap := bm;
– bm.Free;
– Run het klokje en kijk of de kleur van de icoontjes mee veranderen als u de kleur van een wijzer verandert.Reset klokje
Command-line Switch
Een en ander gaan we implementeren in het FormCreate-event. Dit event wordt uitgevoerd bij het aanmaken van het Form, dus nog voordat het Form is getekend.
– Activeer het FormCreate-event.
– Voeg de volgende variabelen toe:
– var
– pad: string;
– membuf: TMemoryStream;
– cf: TextFile;
– Voeg na begin de volgende code toe:
– if FindCmdLineSwitch(‘reset’,[‘ ‘,’-‘,’\’,’/’],False) then
– begin
– pad := GetAppConfigDir(True);
– if RightStr(pad,1) <> ‘\’ then
– pad := pad + ‘\’;
– if FileExists(pad + ‘klokje.cfg’) then
– begin
– membuf := TMemoryStream.Create;
– membuf.LoadFromFile(pad + ‘klokje.cfg’);
– membuf.SaveToFile(pad + ‘klokje_’ + FormatDateTime(‘yyyymmdd_hh_nn_ss’,Now) + ‘.cfg’);
– membuf.Free;
– end;
– AssignFile(cf,pad + ‘klokje.cfg’);
– ReWrite(cf);
– Writeln(cf,'[CLOCK]’);
– Writeln(cf,’OnTop=-1′);
– Writeln(cf,’Position-X=60′);
– Writeln(cf,’Position-Y=5′);
– Writeln(cf,’Analog=0′);
– Writeln(cf,”);
– Writeln(cf,'[FONT]’);
– Writeln(cf,’Name=Microsoft Sans Serif’);
– Writeln(cf,’Size=16′);
– Writeln(cf,’ForeColor=0′);
– Writeln(cf,’BackColor=536870912′);
– Writeln(cf,’Style=Standard’);
– Writeln(cf,”);
– Writeln(cf,'[OPACITY]’);
– Writeln(cf,’Percentage=75′);
– Writeln(cf,”);
– Writeln(cf,'[ANALOG]’);
– Writeln(cf,’ColorHour=32768′);
– Writeln(cf,’ColorMinute=16711680′);
– Writeln(cf,’ColorSecond=255′);
– Writeln(cf,’ClockFace=0′);
– Writeln(cf,’ClockSize=Medium’);
– Writeln(cf,”);
– Writeln(cf,'[ALARM]’);
– Writeln(cf,’Sound=Alarm01′);
– Writeln(cf,’Text=Wake up!’);
– Writeln(cf,’Time=12:00:00′);
– Writeln(cf,’Fixed=0′);
– Writeln(cf,’On=0′);
– CloseFile(cf);
– ShowMessage(‘Klokje reset. Start program without switches.’);
– Halt(0);
– end;
Met FindCmdLineSwitch wordt er gekeken of de applicatie met een switch is geopend. De eerste parameter geeft de naam van de switch aan, de tweede is een verzameling van mogelijke scheidingstekens tussen de exe en de switch en de derde geeft aan of er onderscheid moet worden gemaakt tussen hoofd– en kleine letters.
Als de switch reset is gebruikt dan wordt er eerste een copy gemaakt van het huidige cfg-bestand. Hiervoor maken we gebruik van de methods LoadFromFile en SaveToFile van een MemoryStream. We gebruiken de MemoryStream dus verder niet.
Vervolgens maken we een nieuw cgf-bestand aan met default-waardes. Hiervoor gebruiken we een gewone TextFile.
Als dit allemaal gedaan is dan laat de applicatie een melding zien.
Tot slot wordt de applicatie weer afgesloten met de opdracht Halt. De parameter 0 geeft aan dat de applicatie goed (zonder fouten) is afgesloten (in Windows wordt deze waarde in ErrorLevel gezet, hiermee kunnen o.a. batch-files hun voordeel mee doen).Klokje krijgt eigen icoon
– Klik op de knop Load Icon.
– Kies een icoon naar keuze (max. 32 x 32 met 32 bits per pixel).
– Klik op de knop OK.
– Run het klokje en kijk in de taakbalk.Exe(cutable) verkleinen
– Klik in de linker Listbox op de optie Debugging.
– Zet het vinkje voor Generate debugging info for GDB uit.
– Zet het vinkje voor de optie Strip symbols from executable aan.
– Klik op de knop OK.
– Run het klokje.
Natuurlijk kunt u het klokje naar believen aanpassen en uitbreiden.Code
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
ExtCtrls, Menus, Unit2, Unit3, Unit4, Unit5;
dlgColor: TColorDialog;
dlgFont: TFontDialog;
ilstIconen: TImageList;
ilstFaces: TImageList;
imgFace: TImage;
lblTijd: TLabel;
popAlarmSettings: TMenuItem;
popAnalogClockface: TMenuItem;
popSep2: TMenuItem;
popAbout: TMenuItem;
popAnalogColorsSecond: TMenuItem;
popAnalogColorsMinute: TMenuItem;
popAnalogColorsHour: TMenuItem;
popAnalogColors: TMenuItem;
popAnalogSizeSmall: TMenuItem;
popAnalogSizeMedium: TMenuItem;
popAnalogSizeBig: TMenuItem;
popAnalogSize: TMenuItem;
popAnalogOn: TMenuItem;
popAnalog: TMenuItem;
popFontForeColor: TMenuItem;
popFontBackColor: TMenuItem;
popFontFont: TMenuItem;
popFont: TMenuItem;
popSluit: TMenuItem;
popSep1: TMenuItem;
popOpacity25: TMenuItem;
popOpacity50: TMenuItem;
popOpacity75: TMenuItem;
popOpacity100: TMenuItem;
popOpacity: TMenuItem;
popOnTop: TMenuItem;
popMenu: TPopupMenu;
tmrTijd: TTimer;
procedure FormActivate(Sender: TObject);
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
procedure FormCreate(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure lblTijdDblClick(Sender: TObject);
procedure lblTijdMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure lblTijdMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure lblTijdMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure lblTijdResize(Sender: TObject);
procedure popAboutClick(Sender: TObject);
procedure popAlarmSettingsClick(Sender: TObject);
procedure popAnalogClockfaceClick(Sender: TObject);
procedure popAnalogColorsClick(Sender: TObject);
procedure popAnalogOnClick(Sender: TObject);
procedure popAnalogSizeClick(Sender: TObject);
procedure popFontBackColorClick(Sender: TObject);
procedure popFontFontClick(Sender: TObject);
procedure popFontForeColorClick(Sender: TObject);
procedure popOnTopClick(Sender: TObject);
procedure popOpacity100Click(Sender: TObject);
procedure popOpacity25Click(Sender: TObject);
procedure popOpacity50Click(Sender: TObject);
procedure popOpacity75Click(Sender: TObject);
procedure popSluitClick(Sender: TObject);
procedure tmrTijdTimer(Sender: TObject);
private
{ private declarations }
procedure LeesIni;
procedure SchrijfIni;
public
{ public declarations }
end;
frmKlokje: TfrmKlokje;
FaceIndex: integer;
SoundName: String;
AlarmAan: Boolean;
AlarmTijd: TDateTime;
AlarmTekst: String;
AlarmFixed: Boolean;
IniFiles, Math;
MD, Analoog: Boolean;
MyX, MyY, ClockSize: integer;
ColorHour, ColorMinute, ColorSecond: TColor;
var
ini: TINIFile;
s, h: String;
i: integer;
bm: TBitmap;
begin
ini := TINIFile.Create(GetAppConfigFile(True));
try
s := ini.ReadString(‘CLOCK’,’OnTop’,”);
if s = ‘-1’ then
begin
frmKlokje.FormStyle := fsSystemStayOnTop;
popOnTop.Checked := True;
end
else
begin
frmKlokje.FormStyle := fsNormal;
popOnTop.Checked := False;
end;
s := ini.ReadString(‘CLOCK’,’Position-X’,”);
if TryStrToInt(s,i) then
frmKlokje.Left := i
else
frmKlokje.Left := 256;
s := ini.ReadString(‘CLOCK’,’Position-Y’,”);
if TryStrToInt(s,i) then
frmKlokje.Top := i
else
frmKlokje.Top := 130;
s := ini.ReadString(‘CLOCK’,’Analog’,”);
Analoog := (s = ‘-1’);
popAnalogOn.Checked := Analoog;
lblTijd.Font.Name := s;
s := ini.ReadString(‘FONT’,’Size’,”);
if TryStrToInt(s,i) then
lblTijd.Font.Size := i
else
lblTijd.Font.Size := 14;
lblTijd.Font.Style := [];
s := ini.ReadString(‘FONT’,’Style’,”);
s := s + ‘,’;
i := Pos(‘,’, s);
while i > 0 do
begin
h := Trim(Copy(s,1,i-1));
if UpperCase(h) = ‘BOLD’ then
lblTijd.Font.Style := lblTijd.Font.Style + [fsBold];
if UpperCase(h) = ‘ITALIC’ then
lblTijd.Font.Style := lblTijd.Font.Style + [fsItalic];
if UpperCase(h) = ‘STRIKEOUT’ then
lblTijd.Font.Style := lblTijd.Font.Style + [fsStrikeOut];
if UpperCase(h) = ‘UNDERLINE’ then
lblTijd.Font.Style := lblTijd.Font.Style + [fsUnderline];
s := Copy(s,i+1,Length(s));
i := Pos(‘,’, s);
end;
s := ini.ReadString(‘FONT’,’ForeColor’,”);
if TryStrToInt(s,i) then
lblTijd.Font.Color := i
else
lblTijd.Font.Color := RGBToColor(0, 0, 0); //zwart
s := ini.ReadString(‘FONT’,’BackColor’,”);
if TryStrToInt(s,i) then
frmKlokje.Color := i
else
frmKlokje.Color := RGBToColor(127, 127, 127); //grijs
popOpacity75.Checked := False;
popOpacity50.Checked := False;
popOpacity25.Checked := False;
frmKlokje.AlphaBlendValue := 255;
s := ini.ReadString(‘OPACITY’,’Percentage’,”);
if s = ’25’ then
begin
popOpacity100.Checked := False;
popOpacity25.Checked := True;
frmKlokje.AlphaBlendValue := 64;
end;
if s = ’50’ then
begin
popOpacity100.Checked := False;
popOpacity50.Checked := True;
frmKlokje.AlphaBlendValue := 128;
end;
if s = ’75’ then
begin
popOpacity100.Checked := False;
popOpacity75.Checked := True;
frmKlokje.AlphaBlendValue := 191;
end;
popAnalogSizeMedium.Checked := False;
popAnalogSizeBig.Checked := False;
s := UpperCase(ini.ReadString(‘ANALOG’,’ClockSize’,”));
case s of
‘MEDIUM’:
begin
ClockSize := 160;
popAnalogSizeMedium.Checked := True;
end;
‘BIG’:
begin
ClockSize := 200;
popAnalogSizeBig.Checked := True;
end
else
begin
ClockSize := 120;
popAnalogSizeSmall.Checked := True;
end;
end;
s := ini.ReadString(‘ANALOG’,’ColorHour’,”);
if TryStrToInt(s,i) then
ColorHour := i
else
ColorHour := clGreen;
bm := TBitmap.Create;
bm.Width := 16;
bm.Height := 16;
bm.Canvas.Brush.Color := ColorHour;
bm.Canvas.FloodFill(8,8,bm.Canvas.Pixels[8,8],fsSurface);
popAnalogColorsHour.Bitmap := bm;
bm.Free;
s := ini.ReadString(‘ANALOG’,’ColorMinute’,”);
if TryStrToInt(s,i) then
ColorMinute := i
else
ColorMinute := clBlue;
bm := TBitmap.Create;
bm.Width := 16;
bm.Height := 16;
bm.Canvas.Brush.Color := ColorMinute;
bm.Canvas.FloodFill(8,8,bm.Canvas.Pixels[8,8],fsSurface);
popAnalogColorsMinute.Bitmap := bm;
bm.Free;
s := ini.ReadString(‘ANALOG’,’ColorSecond’,”);
if TryStrToInt(s,i) then
ColorSecond := i
else
ColorSecond := clRed;
bm := TBitmap.Create;
bm.Width := 16;
bm.Height := 16;
bm.Canvas.Brush.Color := ColorSecond;
bm.Canvas.FloodFill(8,8,bm.Canvas.Pixels[8,8],fsSurface);
popAnalogColorsSecond.Bitmap := bm;
bm.Free;
s := ini.ReadString(‘ANALOG’,’ClockFace’,”);
if TryStrToInt(s,i) then
FaceIndex := i
else
FaceIndex := 0;
ilstFaces.GetBitmap(FaceIndex,imgFace.Picture.Bitmap);
if s <> ” then
SoundName := s
else
SoundName := ‘Alarm01’;
s := ini.ReadString(‘ALARM’,’Text’,”);
if s <> ” then
AlarmTekst := s
else
AlarmTekst := ‘Wake up!!!’;
s := ini.ReadString(‘ALARM’,’Time’,”);
try
if s <> ” then
AlarmTijd := StrToTime(s)
else
AlarmTijd := StrToTime(’12:00:00′);
except
AlarmTijd := StrToTime(’12:00:00′);
end;
s := ini.ReadString(‘ALARM’,’Fixed’,”);
AlarmFixed := (s = ‘-1’);
s := ini.ReadString(‘ALARM’,’On’,”);
AlarmAan := (s = ‘-1’);
finally
ini.Free;
end;
end;
var
ini: TINIFile;
opacperc, fstyle, cs: String;
begin
ini := TINIFile.Create(GetAppConfigFile(True));
try
ini.WriteString(‘CLOCK’,’OnTop’,BoolToStr(frmKlokje.FormStyle = fsSystemStayOnTop));
ini.WriteString(‘CLOCK’,’Position-X’,IntToStr(frmKlokje.Left));
ini.WriteString(‘CLOCK’,’Position-Y’,IntToStr(frmKlokje.Top));
ini.WriteString(‘CLOCK’,’Analog’,BoolToStr(Analoog));
ini.WriteString(‘FONT’,’Size’,IntToStr(lblTijd.Font.Size));
fstyle := ‘Standard, ‘;
if fsBold in lblTijd.Font.Style then
fstyle := fstyle + ‘Bold, ‘;
if fsItalic in lblTijd.Font.Style then
fstyle := fstyle + ‘Italic, ‘;
if fsStrikeOut in lblTijd.Font.Style then
fstyle := fstyle + ‘StrikeOut, ‘;
if fsUnderline in lblTijd.Font.Style then
fstyle := fstyle + ‘Underline, ‘;
fstyle := Copy(fstyle,1,Length(fstyle)-2);
ini.WriteString(‘FONT’,’Style’,fstyle);
ini.WriteString(‘FONT’,’ForeColor’,IntToStr(lblTijd.Font.Color));
ini.WriteString(‘FONT’,’BackColor’,IntToStr(frmKlokje.Color));
opacperc := ‘100’;
if popOpacity75.Checked then
opacperc := ’75’;
if popOpacity50.Checked then
opacperc := ’50’;
if popOpacity25.Checked then
opacperc := ’25’;
ini.WriteString(‘OPACITY’,’Percentage’,opacperc);
160: cs := ‘Medium’;
200: cs := ‘Big’
else
cs := ‘Small’
end;
ini.WriteString(‘ANALOG’,’ClockSize’,cs);
ini.WriteString(‘ANALOG’,’ColorHour’,IntToStr(ColorHour));
ini.WriteString(‘ANALOG’,’ColorMinute’,IntToStr(ColorMinute));
ini.WriteString(‘ANALOG’,’ColorSecond’,IntToStr(ColorSecond));
ini.WriteString(‘ANALOG’,’ClockFace’,IntToStr(FaceIndex));
ini.WriteString(‘ALARM’,’Text’,AlarmTekst);
ini.WriteString(‘ALARM’,’Time’,TimeToStr(AlarmTijd));
ini.WriteString(‘ALARM’,’Fixed’,BoolToStr(AlarmFixed));
ini.WriteString(‘ALARM’,’On’,BoolToStr(AlarmAan));
finally
ini.Free;
end;
end;
const
fhw: Real = 0.4;
fmw: Real = 0.6;
fsw: Real = 0.8;
var
h,m,s,ms: Word;
wx, wy, c: integer;
begin
if Analoog then
begin
c := ClockSize div 2;
frmKlokje.Repaint;
DecodeTime(Now,h,m,s,ms);
frmKlokje.Canvas.Pen.Width := 5;
wx := Round(Cos(DegToRad(h * 30 + (m div 6) * 3 – 90)) * c * fhw) + c;
wy := Round(Sin(DegToRad(h * 30 + (m div 6) * 3 – 90)) * c * fhw) + c;
frmKlokje.Canvas.Line(c,c,wx,wy);
frmKlokje.Canvas.Pen.Width := 3;
wx := Round(Cos(DegToRad(m * 6 – 90)) * c * fmw) + c;
wy := Round(Sin(DegToRad(m * 6 – 90)) * c * fmw) + c;
frmKlokje.Canvas.Line(c,c,wx,wy);
frmKlokje.Canvas.Pen.Width := 1;
wx := Round(Cos(DegToRad(s * 6 – 90)) * c * fsw) + c;
wy := Round(Sin(DegToRad(s * 6 – 90)) * c * fsw) + c;
frmKlokje.Canvas.Line(c,c,wx,wy);
end
else
begin
lblTijd.Caption := FormatDateTime(‘hh:mm:ss’, Now);
end;
if AlarmAan then
if Time > AlarmTijd then
begin
AlarmAan := False;
frmAlarm.ShowModal;
end;
if FormatDateTime(‘hh:mm:ss’,Now) = ’00:00:00′ then
frmKlokje.Hint := FormatDateTime(‘dddd dd mmmm yyyy’,Now);
end;
begin
frmKlokje.Width := lblTijd.Width;
frmKlokje.Height := lblTijd.Height;
end;
begin
frmAbout.ShowModal;
end;
begin
frmAlarmSettings.ShowModal;
end;
begin
frmFaces.ShowModal;
ilstFaces.GetBitmap(FaceIndex,imgFace.Picture.Bitmap);
end;
var
s: String;
c: TColor;
bm: TBitmap;
begin
s := (Sender as TMenuItem).Name;
s := UpperCase(Copy(s,16,Length(s)));
case s of
‘HOUR’: c := ColorHour;
‘MINUTE’: c := ColorMinute;
‘SECOND’: c := ColorSecond;
end;
if s <> ” then
begin
dlgColor.Color := c;
if dlgColor.Execute then
begin
c := dlgColor.Color;
case s of
‘HOUR’: ColorHour := c;
‘MINUTE’: ColorMinute := c;
‘SECOND’: ColorSecond := c;
end;
bm := TBitmap.Create;
bm.Width := 16;
bm.Height := 16;
bm.Canvas.Brush.Color := c;
bm.Canvas.FloodFill(8,8,bm.Canvas.Pixels[8,8],fsSurface);
(Sender as TMenuItem).Bitmap := bm;
bm.Free;
end;
end;
end;
begin
popAnalogOn.Checked := not popAnalogOn.Checked;
Analoog := popAnalogOn.Checked;
frmKlokje.Repaint;
end;
var
s: String;
begin
popAnalogSizeSmall.Checked := False;
popAnalogSizeMedium.Checked := False;
popAnalogSizeBig.Checked := False;
(Sender as TMenuItem).Checked := True;
s := (Sender as TMenuItem).Name;
s := Uppercase(Trim(Copy(s,14,Length(s))));
Case s of
‘MEDIUM’: ClockSize := 160;
‘BIG’: ClockSize := 200;
else
ClockSize := 120;
end;
frmKlokje.Repaint;
end;
begin
dlgColor.Color := lblTijd.Color;
if dlgColor.Execute then
lblTijd.Color := dlgColor.Color;
end;
begin
dlgFont.Font := lblTijd.Font;
if dlgFont.Execute then
lblTijd.Font := dlgFont.Font;
end;
begin
dlgColor.Color := lblTijd.Font.Color;
if dlgColor.Execute then
lblTijd.Font.Color := dlgColor.Color;
end;
begin
popOnTop.Checked := not popOnTop.Checked;
if popOnTop.Checked then
frmKlokje.FormStyle := fsSystemStayOnTop
else
frmKlokje.FormStyle := fsNormal;
end;
begin
popOpacity100.Checked := True;
popOpacity75.Checked := False;
popOpacity50.Checked := False;
popOpacity25.Checked := False;
frmKlokje.AlphaBlendValue := 255;
end;
begin
popOpacity100.Checked := False;
popOpacity75.Checked := False;
popOpacity50.Checked := False;
popOpacity25.Checked := True;
frmKlokje.AlphaBlendValue := 64;
end;
begin
popOpacity100.Checked := False;
popOpacity75.Checked := False;
popOpacity50.Checked := True;
popOpacity25.Checked := False;
frmKlokje.AlphaBlendValue := 128;
end;
begin
popOpacity100.Checked := False;
popOpacity75.Checked := True;
popOpacity50.Checked := False;
popOpacity25.Checked := False;
frmKlokje.AlphaBlendValue := 191;
end;
begin
close;
end;
begin
close;
end;
begin
SchrijfIni;
end;
var
pad: string;
membuf: TMemoryStream;
cf: TextFile;
begin
if FindCmdLineSwitch(‘reset’,[‘ ‘,’-‘,’\’,’/’],False) then
begin
pad := GetAppConfigDir(True);
if RightStr(pad,1) <> ‘\’ then
pad := pad + ‘\’;
if FileExists(pad + ‘klokje.cfg’) then
begin
membuf := TMemoryStream.Create;
membuf.LoadFromFile(pad + ‘klokje.cfg’);
membuf.SaveToFile(pad + ‘klokje_’ + FormatDateTime(‘yyyymmdd_hh_nn_ss’,Now) + ‘.cfg’);
membuf.Free;
end;
AssignFile(cf,pad + ‘klokje.cfg’);
ReWrite(cf);
Writeln(cf,'[CLOCK]’);
Writeln(cf,’OnTop=-1′);
Writeln(cf,’Position-X=60′);
Writeln(cf,’Position-Y=5′);
Writeln(cf,’Analog=0′);
Writeln(cf,”);
Writeln(cf,'[FONT]’);
Writeln(cf,’Name=Microsoft Sans Serif’);
Writeln(cf,’Size=16′);
Writeln(cf,’ForeColor=0′);
Writeln(cf,’BackColor=536870912′);
Writeln(cf,’Style=Standard’);
Writeln(cf,”);
Writeln(cf,'[OPACITY]’);
Writeln(cf,’Percentage=75′);
Writeln(cf,”);
Writeln(cf,'[ANALOG]’);
Writeln(cf,’ColorHour=32768′);
Writeln(cf,’ColorMinute=16711680′);
Writeln(cf,’ColorSecond=255′);
Writeln(cf,’ClockFace=0′);
Writeln(cf,’ClockSize=Medium’);
Writeln(cf,”);
Writeln(cf,'[ALARM]’);
Writeln(cf,’Sound=Alarm01′);
Writeln(cf,’Text=Wake up!’);
Writeln(cf,’Time=12:00:00′);
Writeln(cf,’Fixed=0′);
Writeln(cf,’On=0′);
CloseFile(cf);
ShowMessage(‘Klokje reset. Start program without switches.’);
Halt(0);
end;
end;
var
aBitmap: TBitmap;
begin
if Analoog then
begin
aBitmap := TBitmap.Create;
aBitmap.Width := ClockSize; //frmKlokje.Width;
aBitmap.Height := ClockSize; //frmKlokje.Height;
aBitmap.Canvas.Brush.Color := clWhite;
aBitmap.Canvas.Ellipse(-1,-1,ClockSize+1,ClockSize+1);
SetShape(aBitmap);
aBitmap.Free;
imgFace.Width := ClockSize;
imgFace.Height := ClockSize;
imgFace.Visible := True;
frmKlokje.Width := ClockSize;
frmKlokje.Height := ClockSize;
frmKlokje.Canvas.Pen.Color := clBlack;
frmKlokje.Canvas.Pen.Width := 1;
end
else
begin
imgFace.Visible := False;
frmKlokje.Width := lblTijd.Width;
frmKlokje.Height := lblTijd.Height;
aBitmap.Width := lblTijd.Width;
aBitmap.Height := lblTijd.Height;
aBitmap.Canvas.Brush.Color := clWhite;
aBitmap.Canvas.Rectangle(0,0,lblTijd.Width,lblTijd.Height);
SetShape(aBitmap);
aBitmap.Free;
end;
end;
begin
Analoog := False;
ClockSize := 120;
imgFace.Left := 0;
imgFace.Top := 0;
imgFace.Width := ClockSize;
imgFace.Height := ClockSize;
imgFace.Visible := False;
ColorHour := clGreen;
ColorMinute := clBlue;
ColorSecond := clRed;
FaceIndex := 0;
frmKlokje.Hint := FormatDateTime(‘dddd dd mmmm yyyy’,Now);
LeesIni;
end;
Shift: TShiftState; X, Y: Integer);
begin
MD := (Button = mbLeft);
MyX := X;
MyY := Y;
end;
Y: Integer);
begin
if MD then
begin
frmKlokje.Left := frmKlokje.Left + (X – MyX);
frmKlokje.Top := frmKlokje.Top + (Y -MyY);
end;
end;
Shift: TShiftState; X, Y: Integer);
begin
MD := False;
end;
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls
,lclIntf
;
btnOK: TButton;
Label1: TLabel;
lblWebsite: TLabel;
procedure btnOKClick(Sender: TObject);
procedure lblWebsiteClick(Sender: TObject);
private
{ private declarations }
public
{ public declarations }
end;
frmAbout: TfrmAbout;
begin
close;
end;
begin
OpenURL(‘https://hjgsoft.nl’);
end;
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
StdCtrls;
btnLeft: TButton;
btnRight: TButton;
btnOK: TButton;
btnCancel: TButton;
imgFace: TImage;
lblIndex: TLabel;
procedure btnCancelClick(Sender: TObject);
procedure btnLeftClick(Sender: TObject);
procedure btnOKClick(Sender: TObject);
procedure btnRightClick(Sender: TObject);
procedure FormActivate(Sender: TObject);
private
{ private declarations }
public
{ public declarations }
procedure BrowseImages;
end;
frmFaces: TfrmFaces;
Unit1;
fi: integer;
begin
frmKlokje.ilstFaces.GetBitmap(fi,imgFace.Picture.Bitmap);
lblIndex.Caption := IntToStr(fi);
end;
begin
fi := FaceIndex;
BrowseImages;
end;
begin
Dec(fi);
if fi <0 then
fi := frmKlokje.ilstFaces.Count – 1;
BrowseImages;
end;
begin
close;
end;
begin
FaceIndex := fi;
close;
end;
begin
Inc(fi);
if fi >= frmKlokje.ilstFaces.Count then
fi := 0;
BrowseImages;
end;
Classes, SysUtils, FileUtil, DateTimePicker, Forms, Controls, Graphics,
Dialogs, StdCtrls, EditBtn, Calendar;
btnOtherAlarm: TButton;
btnPlay: TButton;
btnOK: TButton;
btnCancel: TButton;
chkAlarmOn: TCheckBox;
chkFixedTime: TCheckBox;
dtpAlarmTijd: TDateTimePicker;
edtAlarmText: TEdit;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
lblAlarm: TLabel;
lstAlarm: TListBox;
dlgOpenFile: TOpenDialog;
procedure btnCancelClick(Sender: TObject);
procedure btnOKClick(Sender: TObject);
procedure btnOtherAlarmClick(Sender: TObject);
procedure btnPlayClick(Sender: TObject);
procedure FormActivate(Sender: TObject);
procedure lstAlarmClick(Sender: TObject);
private
{ private declarations }
procedure HintAan;
public
{ public declarations }
end;
function StopAlarm: Boolean;
frmAlarmSettings: TfrmAlarmSettings;
Unit1, LResources, MMSystem;
SoundNameTmp: String;
var
s: AnsiString;
begin
Result := True;
if AlarmNaam = ” then
Result := False;
try
if LeftStr(UpperCase(AlarmNaam),5) = ‘FILE:’ then
begin
PlaySound(PChar(Copy(AlarmNaam,6,Length(AlarmNaam))), 0,Snd_Async or Snd_FileName or Snd_NoDefault or Snd_Loop)
end
else
begin
s := LazarusResources.Find(AlarmNaam).Value;
if s <> ” then
PlaySound(@s[1], 0, Snd_Async or Snd_Memory or Snd_Loop)
else
Result := False;
end;
except
Result := False;
end;
end;
begin
Result := True;
try
PlaySound(nil, 0 ,0);
except
Result := False;
end;
end;
var
s: String;
begin
if LeftStr(UpperCase(SoundNameTmp),5) = ‘FILE:’ then
begin
s := Copy(SoundNameTmp,6,Length(SoundNameTmp));
lblAlarm.Caption := ExtractFileName(s);
lblAlarm.Hint := ExtractFilePath(s);
lblAlarm.ShowHint := True;
end
else
begin
lblAlarm.ShowHint := False;
lblAlarm.Caption := SoundNameTmp;
end;
end;
begin
close;
end;
begin
SoundName := SoundNameTmp;
AlarmAan := chkAlarmOn.Checked;
AlarmTijd := dtpAlarmTijd.Time;
AlarmTekst := edtAlarmText.Text;
AlarmFixed := chkFixedTime.Checked;
close;
end;
begin
dlgOpenFile.Filter := ‘WAV|*.WAV’;
if dlgOpenFile.Execute then
begin
lstAlarm.ItemIndex := -1;
SoundNameTmp := ‘FILE:’ + dlgOpenFile.FileName;
HintAan;
end;
end;
begin
if btnPlay.Caption = ‘Play alarm’ then
begin
btnPlay.Caption := ‘Stop alarm’;
lstAlarm.Enabled := False;
if not PlayAlarm(SoundNameTmp) then
begin
ShowMessage(‘Alarm niet gevonden’);
btnPlay.Caption := ‘Play alarm’;
lstAlarm.Enabled := True;
end;
end
else
begin
btnPlay.Caption := ‘Play alarm’;
lstAlarm.Enabled := True;
StopAlarm;
end;
end;
var
i: integer;
u,m,s,ms: Word;
begin
SoundNameTmp := SoundName;
HintAan;
edtAlarmText.Text := AlarmTekst;
dtpAlarmTijd.Time := AlarmTijd;
lstAlarm.Clear;
for i := 1 to 10 do
if i < 10 then
lstAlarm.Items.Add(‘Alarm0’ + IntToStr(i))
else
lstAlarm.Items.Add(‘Alarm10’);
lstAlarm.ItemIndex := 0;
if not AlarmAan and not AlarmFixed then
begin
DecodeTime(Now,u,m,s,ms);
ms := 0;
s := 0;
if m >= 30 then
begin
u := u + 1;
m := 0;
end
else
m := 30;
dtpAlarmTijd.Time := EncodeTime(u,m,s,ms);
end;
end;
begin
SoundNameTmp := lstAlarm.Items[lstAlarm.ItemIndex];
HintAan;
end;
{$I sounds.lrs}
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
lblSnooze: TLabel;
lblOK: TLabel;
lblAlarmText: TLabel;
procedure FormActivate(Sender: TObject);
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
procedure lblOKClick(Sender: TObject);
procedure lblSnoozeClick(Sender: TObject);
private
{ private declarations }
public
{ public declarations }
end;
frmAlarm: TfrmAlarm;
Unit4, Unit1;
begin
lblAlarmText.Caption := AlarmTekst;
PlayAlarm(SoundName);
end;
begin
StopAlarm;
end;
begin
close;
end;
var
u,m,s,ms: Word;
begin
DecodeTime(Now,u,m,s,ms);
if (m + 5) >= 60 then
begin
m := (m + 5) mod 60;
u := u + 5;
end
else
m := m + 5;
AlarmTijd := EncodeTime(u,m,s,ms);
AlarmAan := True;
close;
end;