woensdag 21 januari 2009

Delphi Enumerators: "for o in MyObject do"

Ik gebruik Delphi 2007 nog niet zo heel lang, omdat de huidige klant nog de oude Delphi 6 versie gebruikte. Sowieso zijn er best veel bedrijven die bijvoorbeeld Delphi 7 nog steeds gebruiken (wat vaak gewoon goed bevalt). Best jammer, want Delphi 2007 en 2009 zijn mooie en goede Delphi versies, met veel verbeteringen: IDE, VCL en Language features.

Het nadeel van nieuwe features is echter: je moet ze wel gebruiken :-). Heel gauw ben je geneigd om je oude gewoontes te blijven gebruiken: bijvoorbeeld nog steeds "for i := 0 to stringlist.Count-1 do" gebruiken in plaats van "for s in stringlist".

Ik had al eens een serie interessante blogs gelezen over "fun with enumerators":
http://17slon.com/blogs/gabr/2007/03/fun-with-enumerators-part-1.html
http://17slon.com/blogs/gabr/2007/03/fun-with-enumerators-part-2-multiple.html
http://17slon.com/blogs/gabr/2007/03/fun-with-enumerators-part-3.html
http://17slon.com/blogs/gabr/2007/03/fun-with-enumerators-part-4-external.html
http://17slon.com/blogs/gabr/2007/03/fun-with-enumerators-part-5-class.html

In feite komt het erop neer, dat elke class die een "public GetEnumerator" functie heeft, gebruikt kan worden voor een "for in" loop.
De GetEnumerator functie moet een class teruggeven met de volgende functies (als voorbeeld van TStringList.GetEnumerator):
TStringsEnumerator = class
public
function GetCurrent: string;
function MoveNext: Boolean;
property Current: string read GetCurrent;
end;
Van de volgende code...:
for s in stringlist do
ShowMessage(s);
...maakt Delphi onderwater de volgende code ervan:
enumerator := stringlist.GetEnumerator;
while enumerator.MoveNext do
begin
s := enumerator.Current;
ShowMessage(s);
end;
enumerator.Free;
Je kunt dus ook zelf eenvoudig aan een eigen class deze handige enumerator functionaliteit toevoegen! Of via "class helpers" aan een bestaande class.

Op een gegeven moment was ik het namelijk zat om steeds "for i to count-1" te gebruiken, en toen moest ik weer denken aan de eerder genoemde blogs. Met de bovenstaande code kon ik zelf een veelgebruikte class even uitbreiden met enumerators :-).

Trouwens, "for in" kun je ook gebruiken met arrays en sets:
var i:integer;
c: char;
begin
for i in intergerarray do ;
for c in teststring do ;
end;

vrijdag 16 januari 2009

VMware ThinApp: Package Once, Deploy Everywhere

Met VMware ThinApp kun je willekeurige programma's gebruiken zonder te installeren. Hierbij draait het bewuste programma in een aparte "sandbox": je kunt dus virtualizeren zonder een complete VMware image te gebruiken! Alle harde schijf en Windows Registry toegang wordt afgevangen en geemuleerd.
Zo kun je bijvoorbeeld Microsoft Office 2007 op je USB stick zetten en op elke computer gebruiken, zonder te installeren!

Afhankelijk van de instellingen kun je ervoor kiezen voor een volledige sandbox: alle wijzigingen (behalve "My Documents" en Desktop) worden niet doorgevoerd in de echte Windows installatie, maar zijn alleen actief binnen de sandbox (ook na herstart). Maar er is ook een semi-sandbox mode: alle normale wijzigingen worden doorgevoerd, maar geen systeem wijzigingen. Deze laatste is handig voor Office: je kunt gewoon op de eigen plek je documenten opslaan.

Om een nieuwe ThinApp package te maken, moeten een aantal stappen in de ThinApp creator doorlopen worden:
  1. snapshot maken van Registry en lijst maken van huidige bestanden

  2. je programma installeren en instellen
  3. nieuwe snapshot maken van Registry en lijst maken van gewijzigde en nieuwe bestanden
  4. Alle verschillen tussen 1e en 2e snapshot worden in een aparte directory opgeslagen
  5. Selectie maken van de executables waarvoor een ThinApp koppeling gemaakt moet worden
  6. Isolation mode instellen
  7. Je kunt een MSI installer package maken, of ongecomprimeerd om makkelijk te testen

Vervolgens kun je een koppeling starten (zelfde icoontje etc, alleen executable start intern ThinApp op) en gebruiken. Het programma kan vervolgens alle bestanden op je computer normaal benaderen (lezen), maar wijzigingen worden (afhankelijk van instellingen) alleen binnen de sandbox opgeslagen. Alle registry instellingen die tijdens de installatie gemaakt zijn, zijn voor het programma binnen de sandbox gewoon transparant beschikbaar. Hierdoor denkt bijvoorbeeld MS Office 2007 dat het gewoon normaal op de computer geinstalleerd is.

Als je met bijvoorbeeld Process Explorer kijkt, zie je verder geen verschil tussen andere programma's. Het gebruikt alleen een extra dll, die waarschijnlijk de virtualisatie van Registry en Filesystem regelt:

dinsdag 13 januari 2009

Delphi Prism & Compact Framework

Met Delphi Prism kan ook voor het .Net Compact Framework gecompileerd worden.
Hiermee kan eenvoudig .Net applicaties voor mobile apparaten gemaakt worden.
Hoewel het Compact Framework beperkter is, kan met de nieuwste 3.5 versie ook bijv. LINQ
gebruikt worden.


Een nadeel echter is dat de Form designer door Microsoft hard-coded voor C# en VB gemaakt is.
(hopelijk dat dit in de 2010 versie van Visual Studio verholpen is). Hier is wel eenvoudig omheen
te werken: de normale WinForms designer kan namelijk ook gebruikt worden, met de hand moet
eenmalig de niet ondersteunde properties verwijderd worden.

Als eerste moet het .Net Compact Framework 3.5 geïnstalleerd worden:
http://msdn.microsoft.com/en-us/netframework/aa497280.aspx

Vervolgens kan in Delphi Prism een Windows Forms project gemaakt worden:

Project properties

Open na het maken van het project de properties van het project:

Hierin moet het "Framework folder" verwijzen naar het Compact Framework:
C:\Program Files\Microsoft.NET\SDK\CompactFramework\v3.5\WindowsCE


Voor het gemak veranderen we gelijk het "Output path" naar een gedeelde directory, zodat we later eenvoudig in de Mobile Emulator het programma kunnen testen.

Om te voorkomen dat we tijdens het runnen een ResourceNotFound exception krijgen, verwijderen we het icoon:

References

Nu zal het project nog niet compileren: omdat voor het Compact Framework gecompileerd wordt, moeten de references aangepast worden. Selecteer alle references, rechtermuis klik, en dan "Properties":

Verander vervolgens de "Ignore version" van "False" naar "True":

Test scherm

We gaan nu een test scherm maken. Omdat de resolutie van ons mobiel apparaat niet zo groot is, stellen we ons form hierop in: 240x400

We plaatsen nu een aantal controls op het form, bijvoorbeeld:

Om de test compleet te maken, dubbel klikken we op de "Add to list" knop en voegen we de volgende regel code toe:

Main.pas

...

method MainForm.button1_Click(sender: System.Object; e: System.EventArgs);

begin

listBox1.Items.Add( textBox1.Text );

end;

Compileren

Nu zal het project nog steeds niet willen compileren, maar we zijn er bijna. Eerst moeten de regels code waar de compiler over struikelt uitgeschakeld worden, omdat het Compact Framework deze niet ondersteunt. Bijvoorbeeld: STAThread, Application.EnableVisualStyles, ThreadException, etc:

Program.pas

//[STAThread]

class method Program.Main;

begin

//Application.EnableVisualStyles();

//Application.SetCompatibleTextRenderingDefault(false);

//Application.ThreadException += OnThreadException;

using lMainForm := new MainForm do

Application.Run(lMainForm);

end;

In de Form designer bijvoorbeeld FormattingEnabled, AutoSize, etc:

Main.Designer.pas

...
//self.comboBox1.FormattingEnabled := true;//self.checkBox1.AutoSize := true;

//self.checkBox1.UseVisualStyleBackColor := true;

//self.listBox1.FormattingEnabled := true;

...

//self.PerformLayout();

We verwijderen nog een aantal regels, totdat alles compileert. Vervolgens kunnen we ons programma testen:

Op deze manier kun je eenvoudig en snel testen en debuggen: je hebt hiervoor geen mobiel apparaat of emulator nodig!

Mobile Emulator

Nu is het tijd om ons programma op een mobiel apparaat te testen. Het makkelijkste is om hiervoor een emulator te gebruiken. Installeer hiervoor de nieuwste emulator images:
Windows Mobile 6.1.4 Emulator Images

Vervolgens starten we de 240x400 image op:

Om ons programma te kunnen testen moeten we onze gedeelde directory instellen, via Configure:

En dan de "Shared Folder" in de "General" tab:

We kunnen nu deze map openen in de "File Explorer" door de "Storage Card" te selecteren:

Voordat we ons test programma kunnen testen, moet eerst het Compact Framework nog in de emulator geïnstalleerd worden. Hiervoor heb ik het bestand "NETCFv35.wm.armv4i.cab" in de gedeelde map gekopieerd. Dit bestand staat normaal gesproken in installatie map van het Compact Framework:
c:\Program Files\Microsoft.NET\SDK\CompactFramework\v3.5\WindowsCE\NETCFv35.wm.armv4i.cab

Nadat het Compact Framework geïnstalleerd is, kunnen we ons test programma starten:

Tip: Sluiten ipv minimize

Standaard worden mobiele programma's niet afgesloten (door te klikken op het X rechtsbovenin), maar geminimaliseerd: als de gebruiker het programma weer opstart, verschijnt het programma direct omdat het nog in het geheugen staat. Dit voorkomt dat de gebruiker elke keer een poos moet wachten totdat het programma weer gestart is.
Voor debuggen is dit natuurlijk lastig: je moet elke keer je programma "killen" via de "Task Manager". Verander hiervoor de propertie "MinimizeBox" van het form, en zet deze op "False", nu verschijnt een "Ok" knop in plaats van een "X" knop op het scherm, en wordt het programma afgesloten in plaats van geminimaliseerd!

dinsdag 16 december 2008

Delphi Prism: XNA, LINQ, .Net CF en meer!

Aangezien Delphi Prism een volledige .Net taal is, ondersteunt het zonder problemen het MS XNA Framework (voor oa game ontwikkeling).
Voor een demo van de "XNA Tutorial 1" in Delphi Prism:
http://blogs.codegear.com/pawelglowacki/2008/12/11/38629

Verder ondersteunt Delphi Prism gewoon LINQ.
Voor een demo van "LINQ to Objects":
http://www.monien.net/blog/index.php/2008/12/delphi-can-do-linq/
En een demo van "LINQ to SQL":
http://www.monien.net/blog/index.php/2008/12/delphi-can-even-linq-to-sql/

En met een paar kleine aanpassingen kun je Delphi Prism ook gewoon gebruiken met het .Net Compact Framework (video):
http://cc.codegear.com/Item/26379

CodeGear heeft ook een handig overzicht gemaakt van Delphi Prism gemaakt, waarbij de belangrijkste features uitlegd worden:
"Delphi Prism Reviewers Guide"
http://dn.codegear.com/article/39113

Met Delphi Prism is Delphi weer helemaal terug, en vooral "Cross Platform":
http://www.infoq.com/news/2008/11/Delphi-Prism

Naast de "Class Completion" die de Delphi ontwikkelaars goed kennen, heeft Prism nu ook "Variable Completion" en "Method Completion":
http://prismwiki.codegear.com/en/Variable_Completion
http://prismwiki.codegear.com/en/Method_completion

Ook "Sync Editing" is een handige extra feature:
http://prismwiki.codegear.com/en/Sync_Editing
http://www.monien.net/blog/index.php/2008/12/enable-sync-editing-in-delphi-prism/

Trouwens, de wiki help van Delphi Prism ondersteunt ook RSS feeds (te zien aan het oranje feeds symbool in Firefox).
Dan kun je makkelijk zien wat er gewijzigd is, als er iets verandert:
http://prismwiki.codegear.com/en-w/index.php?title=Special:RecentChanges&feed=rss

maandag 15 december 2008

Delphi Object Repository gebruiken

Bij mijn huidige klant moest ik even uitzoeken hoe de "Object Repository" van Delphi gebruikt kan worden, zodat bepaalde framework templates (forms, frames, datamodules, maar ook complete template projecten) door de ontwikkelaars gebruikt kunnen worden. Ik kon voor Delphi 2007 op internet niet direct iets vinden hoe dit nou werkt en hoe je dit in kunt stellen (wel voor oudere versies). In de CodeGear Help stond gelukkig wel het een en ander (trouwens, niet via de "help" knoppen in Delphi zelf, daar heb je niks aan).

Shared Repository instellen

Als eerste maak je een bepaalde map aan, bijvoorbeeld "P:\Lib\Repository". Dit kan een gesharede netwerk map zijn, maar kan ook een lokale map zijn die je via een versie beheer systeem beheert. Vervolgens moet in Delphi de eerder gemaakte map als “Shared Repository” ingesteld worden:
Delphi 2007 Tools Options:













Delphi 2007 verwacht het bestand “BorlandStudioRepository.xml” in deze directory. Dit XML bestand bevat de items die Delphi kan gebruiken uit de repository. Dit bestand is overigens zelf eenvoudig aan te passen (namen, bestanden, etc). Delphi maakt dit bestand zelf niet aan, maar verwacht wel dit bestand (anders werkt het niet!). Het beste is om het huidige bestand te gebruiken: deze staat in de map "C:\Documents and Settings\\Application Data\Borland\BDS\5.0\". Kopieer deze in de eerder gemaakt directory, en start Delphi opnieuw op (!).

Repository gebruiken

De items die in de repository staan, kunnen gebruikt worden via:
Delphi → File → New → Other:











Het volgende scherm wordt dan getoond:

Selecteer een item en "Inherit" en druk op “OK”.

Items toevoegen aan de repository

Er kunnen 2 soorten items aan de repository toegevoegd worden: losse items (forms, frames, datamodules) en complete projecten.

Project toevoegen

Een project kan aan de repository toegevoegd worden via:
Delphi → Project → Add to repository:
























Los item toevoegen

Een los item kan aan de repository toegevoegd worden, door in de “Form manager” (form, frame of datamodule) met de rechtermuisknop te klikken, en dan “Add to Repository”:












Repository beheren

Items in de repository kunnen bewerkt of verwijderd worden via:
Delphi Tools Repository












Alleen items kunnen bewerkt worden, de categorieën zelf niet (hiervoor moet je “BorlandStudioRepository.xml” zelf aanpassen).

donderdag 11 december 2008

Random things & tips #2

Even weer een "dump" van mijn bezigheden, ontdekkingen en ervaringen tijdens het programmeren :-)
  • TThread.Queue (asynchroon!)
    Sinds Delphi 2007 (?) kun in plaats van "Synchronize" ook de "Queue" functie gebruiken. Nadeel van "Synchronize" is dat de huidige thread geblokkeerd wordt totdat de main thread de functie uitgevoerd heeft (synchroon). Met "Queue" kun je asynchroon de functie laten uitvoeren in de main thread! (de huidige thread gaat dus gewoon door).
  • TryStrToInt, StrToIntDef
    Vaak kom ik de volgende code tegen:
    try
    i := StrToInt( s );
    except
    i := 0;
    end;
    Beter is om TryStrToInt of StrToIntDef te gebruiken!
  • "Pretty Print" XML (netjes inspringen etc)
    Dit kan eenvoudig met de functie "FormatXMLData" uit de unit "XMLDoc".

  • Delphi uitbreidingen en unsupported fixes:
    http://andy.jgknet.de/blog/
    - DDevExtensions 1.9.2 (handige plugin!)
    - DelphiSpeedUp 2.78 (sneller opstarten)
    - IDE Fix Pack 2007 2.1 (IDE bugfixes)
    - VCL Fix Pack 1.0 (VCL runtime fixes)
  • Stomme laptop "Fn" toets zit vast!
    Dit bleek een "numlock" functie te zijn van mijn Acer Aspire: Fn + F11 om aan/uit te zetten
  • ModelMaker tutorials
    Voor diegene die nog nooit ModelMaker gebruikt heeft:
    http://www.thoughtsmithy.com/mmjump/MMGettingStarted_Intro.html
    ModelMaker is echt een hele mooi en goede tool voor ontwikkeling (UML diagrammen, eenvoudig en snel classes en properties maken, etc), maar ook voor documentatie: UML diagrammen genereren van de classes van je code!
  • Tip: Low prio programma starten
    Om een programma in een batch bestand (of gewoon command line) met lage prio uit te voeren, kan het "start" commando gebruikt worden. Bijvoorbeeld: 7zip in batch bestand, low prio, 1 voor 1, geminimaliseerd:
    start /LOW /WAIT /MIN C:\7za\7za.exe a -tzip -mx9 files.7z *.txt

dinsdag 9 december 2008

Delphi Prism beschikbaar!

Delphi Prism is de nieuwste Delphi .Net versie. Het is echter een geheel andere versie dan vorige Delphi .Net versies: het is een soort plug-in in de Visual Studio Shell. Hierover zijn de meningen nogal verdeeld, vooral omdat het geen echte nieuwe Delphi .Net "versie" is maar een geheel nieuw en ander product. Anderzijds is het nu een volledige up-to-date .Net taal, met volledige ondersteuning voor de allerlaatste .Net technieken (LINQ, WPF, WCF, etc). Het heeft ALLE features van C#, PLUS extra handige uitbreidingen! Voor een vergelijking
met C#: http://prismwiki.codegear.com/en/Delphi_Prism_vs._CSharp


Vooral deze extra uitbreidingen maken Delphi Prism interessant. Zo kan nu heel gemakkelijk een blok code of functie asynchroon c.q. parallel uitgevoerd worden via "async
" blokken en "future" variabelen. Dit is veel makkelijker dat dan met C# en Parallel Framework! Verder kan makkelijker met "nullable types" en nil objecten gewerkt worden. "Locked" properties, "Property Notification","Exception filters" etc etc, allemaal handige verbeteringen voor programmeurs.
Nog een voordeel ten opzicht van standaard Visual Studio, is de support voor Linux en Mac OS X
, door middel van Mono.
En ja, de Wiki van Delphi Prism is erg interessant: http://prismwiki.codegear.com
.

Wat dat betreft biedt Delphi Prism veel meer .Net mogelijkheden dan de vorige Delphi .Net versies. Borland heeft wel geprobeerd om te concurreren met Microsoft, ook met C# Builder, maar dit was een bijna onmogelijk taak. Vooral omdat met .Net de ontwikkelomgeving heel nauw samenwerkt met het framework. Zoals de designers voor Winforms en WPF, ondersteuning voor LINQ, Parallel Framework, etc. De ontwikkelingen gingen zo snel, en Borland moest steeds het wiel opnieuw uitvinden c.q. implementeren, zodat het altijd een stuk achter zou lopen. Vandaar: "If you can't beat them, join them". Door de Visual Studio Shell te gebruiken, hoeft men niet meer alles zelf te maken, maar kan direct gebruik gemaakt worden van de aanwezige designers en technieken.

De taal Delphi zelf is wel wat veranderd en uitgebreid. Het sluit nu beter met .Net aan. De reden hiervoor is dat de Win32 en .Net ontwikkelingen steeds meer uiteen lopen. Als men de beide Delphi's zou proberen compatibel te houden met elkaar, zou dat alleen maar vertragen en hinderen. Nu kunnen beide versies ontwikkeld en geoptimaliseerd worden voor hun eigen doelgebieden. Marc Hoffman licht dit ook toe in een interview:
http://www.bitwisemag.com/2/Delphi-Prism-Visual-Studio-Pascal


Als Delphi ontwikkelaar vind ik de VS Shell enerzijds wel jammer, ik had ook liever een echte Delphi IDE gehad ipv VS Shell. Ook het missen van de VCL is jammer. Aan de andere kant is de VCL voor .Net overbodig geworden door WinForms en al helemaal met WPF. De situatie is nu anders dan destijds met Windows 3.11 tot Windows XP. Trouwens, de volgende Visual Studio wordt helemaal WPF based:
http://blogs.msdn.com/ricom/archive/2008/11/18/the-visual-studio-tech-roadmap-starring-visual-studio-2010.aspx

Dus de volgende versie van Delphi Prism kan hiervan gelijk profiteren!

Bestaande Delphi projecten kunnen dus niet 1 op 1 in Delphi Prism geopend worden. Wel zijn ze bezig met een tool die het converteren makkelijker moet maken, namelijk Oxidizer:
http://prismwiki.codegear.com/en/Oxidizer

Ook een Delphi compatible RTL is in ontwikkeling, ShineOn:
http://prismwiki.codegear.com/en/ShineOn

Trouwens, C++ en VB programmeurs moeten een veel grotere omslag maken, die moeten helemaal "opnieuw" beginnen.

Hoewel het voor bestaande Delphi.Net gebruikers jammer is voor deze omslag, heb ik in deze stap van CodeGear meer vertrouwen. Nu kan men zich volledig richten op extra features en uitbreidingen, gericht op de ontwikkelaars.En deze lijst is met verbeteringen is groot:
http://prismwiki.codegear.com/en/Delphi_Prism_Syntax_compared_with_Win32_Delphi


Delphi is onder CodeGear weer sterk bezig met grote opmars. Met Prism is het weer modern en klaar voor de toekomst!

Delphi Prism kan als .iso gedownload worden:
http://cc.codegear.com/free/radstudio

ftp://ftpd.codegear.com/download/RADStudio2009/DelphiPrismISO.iso