Wednesday, November 30, 2005

PocketCaddy gets the ECO treatment 

A while ago I wrote an application to demonstrate the capabilities of the Delphi for .NET Compact Framework preview compiler. This application was designed to keep track of the scores for a round of golf for one or more players, and has been floating around on CodeCentral for a while. It was even given a mention in David Intersimone's blog.

One thing that became apparent very early on in the PocketCaddy development cycle was that it that it is extremely tedious to enter course and player data on a PocketPC device. I decided to use this as an excuse to finally dive head first into the ECO world, and set about creating an administration application which would allow data to be entered on a PC and downloaded to the PocketPC via a web service. I am pleased to announce that this is now downloadable from CodeCentral.

Because this was my first ECO application, I wanted to explore many aspects of ECO development, so as a result it will show examples of the following ECO technologies and techniques :-

Be aware that it was developed using Delphi 2006 and ECO III, so you may be unable to compile it in Delphi 2005. Nevertheless the code should still give insights into many techniques that will work with ECO II. Feel free to offer any feedback, but please be gentle. As I mentioned earlier, this was my first attempt at an ECO app :-)

(14) comments

Thursday, November 24, 2005

Enumerating COM ports in Delphi for .NET 

I needed to enumerate all the available COM ports in a .NET application I was writing the other day. Because the 1.1 version of the .NET Framework has no inbuilt support for serial communications, this meant it was time to Google a solution. To my surprise there were surprisingly few hits, with the only usable solution described on a web site written in Chinese. Not to be discouraged, I used the AltaVista BabelFish translation service to translate it to English, and below is the end result (after converting it from C# with the help of the Borland BabelCode web service). I customized it slightly so that either all ports on the system would be returned, or only COM ports (which is all that I was interested in at the time). I'm posting this here so an easy solution will be a mere Google away for all those English speaking Delphi programmers out there. :-)

unit AvailablePortsUnit;


System.Runtime.InteropServices, System.Collections.Specialized;

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
PORT_INFO_1 = record
pName: string;

function AvailablePorts(const AComPortsOnly: Boolean): StringCollection;


[DllImport('winspool.drv', CharSet=CharSet.Auto)]
function EnumPorts(AName: string; ALevel: Integer; ABuffer: IntPtr;
ACbBuff: Integer; out ANeeded: Integer; out AReturned: Integer): Boolean; external;

function AvailablePorts(const AComPortsOnly: Boolean): StringCollection;
TPortInfoArray = array of PORT_INFO_1;
lIndex: Integer;
lComName: string;
i: Integer;
lCurrent: IntPtr;
lPorts: TPortInfoArray;
lBuffer: IntPtr;
lNeeded: Integer;
lReturned: Integer;
Result := StringCollection.Create;
lBuffer := IntPtr.Zero;
EnumPorts(nil, 1, lBuffer, 0, lNeeded, lReturned);
lBuffer := Marshal.AllocHGlobal((lNeeded + 1));
EnumPorts(nil, 1, lBuffer, lNeeded, lNeeded, lReturned);
SetLength(lPorts, lReturned);
lCurrent := lBuffer;
for i := 0 to lReturned - 1 do
lPorts[i] := (PORT_INFO_1(Marshal.PtrToStructure(lCurrent, TypeOf(PORT_INFO_1))));
if (not AComPortsOnly) or (lPorts[i].pName.StartsWith(
'COM')) then
if AComPortsOnly then
lIndex := lPorts[i].pName.IndexOf(
if (lIndex <> -1) then
lComName := lPorts[i].pName.Remove(lIndex, 1)
lComName := lPorts[i].pName;
lComName := lPorts[i].pName;
lCurrent := IntPtr((Integer(lCurrent) + Marshal.SizeOf(TypeOf(PORT_INFO_1))));

(1) comments

This page is powered by Blogger. Isn't yours?