Wednesday, 23 May 2007

Delphi 2007 is in the House

This week I installed delphi 2007 on my work computer. Some initial comments:

Man, the difference in loading is light speed compared to 2006.

Hey ... The help actually works!!

DelForExp, the "in IDE" source code formatter that I use, doesn't work in 2007 yet, despite the statement that it does on the website. It jams up everything with non-ending errors. Bummer, I'll have to wait for that to be fixed. GExperts seems to work fine though.

Why oh why has CodeGear gone away from offering example code in its help screens? This applies to Delphi 2006 as well, but as you will know, its help, well.. didn't.

Overall impression: Its fast, it works, its a must have update. Sad to say, Delphi 2005 and 2006 did not qualify for the "must have update" statement. So if you are still working away with the tried and true, trusty old Delphi 7 - now's the time to upgrade and boost your productivity folks.

Back to work Steve.

Roadmaps to start with Delphi in June

Jim Douglas, CEO of CodeGear, has set up his own Blog site. Today he tells us that Roadmaps of the major product lines will be published starting in June. Delphi gets the main attention as the first Roadmap to be published.

This will make interesting reading.

Tuesday, 22 May 2007

Global Variable Rant

Taking over someone else's programs is never an easy task. I'm not about to judge the programmer as I was not there for the decisions made, or the time pressures and stress that was going on at the time.

However, I will ask every fledgling and seasoned programmer out there to spare a thought for best practice techniques. Trying to read code where extensive use of global variables are used is well nigh an impossible task.

Instead, create objects and define limits within those objects using such things as Sets (e.g. TMyStatus = (stActive, stInactive, stPaused);) and/or comments which allow another person to know what is happening. Please use variable names that can give some indication as to what its used for. Variable names like glbBoolsghSet02 (I made that one up) tells another programmer nothing.

Good commenting IS needed even in good Delphi code. I'll leave explaining what I mean by good commenting in another blog a little later.

Enjoy life, there's reason in that madness - its just buried a little deeper in some objects.

Too many tabs? Too much code?

I've been working on a project that has a number of tabs on the form. With two or three tabs, the full code for these can be included in the forms unit without a problem. But when you are adding more and more tabs, either you are going to have to rethink your user interface or have one big mother of a unit with a gazillion lines of code.

There is another way that I learned a number of years ago - place each tab on a different form. "What? But that's nonsense Steve, you've been smoking something!", I hear you say. Not so. Follow along for a tricky bit of coding.

Create your form with all your tabs - just don’t put anything in them for the moment. Now for each tab, create a totally separate form, place a TPanel on the form and align it to Client. Give that Panel the same name for each form so you'll remember it, like MainPanel. Then create all your components onto the MainPanel and add your logic code to that form.

Now, going back to the main form with all the tabs, in the OnChange event of the Tabs, place something like the following code...

procedure TfrmMain.pcMainTabChange(Sender: TObject);
case pcMainTab.TabIndex of
1: FrmOne.MainPanel.Parent := tsOne;
2: FrmTwo.MainPanel.Parent := tsTwo;
3: FrmThree.MainPanel.Parent := tsThree;

And there you have it. Simple isn't it?

the tsOne, tsTwo etc are the names you can give to the individual TTabSheet you want the form's components to appear on.

What is happening here is that you are changing the parent of the MainPanel to the TTabSheet of the tab you want it to appear in. By changing the parent, you are actually telling it that it now lives on that new tabsheet instead of the form. All the code will still apply.

All the logic code for each tab is in a separate form, kept tidy and easier to follow.

You can add code to create the form at runtime if you wish, but remember to free it again in the OnChanging event.

God bless and have a wonderful day.

Monday, 21 May 2007

Accessing multiple edit Components

I was asked by a friend how he could access all his components without a long and hard to maintain list in the Source Code. He had a number of Edits on his form and he wanted to add all the edits up, knowing the were all set to receive integer values.

Here's how he can do it...

function GetEdits : Integer;
i : integer;
comp : TComponent;
result := '';
// fMain is the main form.
for i := 0 to fMain.ComponentCount - 1 do
Comp := fMain.Components[i];
if (Comp is TEdit) then // its an edit component
if (Comp as TEdit).Text <> '' then
Result := result + StrToInt((Comp as TEdit).Text);
result := -1; // Oops, that edit was not a number

Monday, 14 May 2007

But I don't wanna Project Group!

I've been head down on an important change to the system so have reluctantly put aside the blog. Have no fear though as I am back onto it again.

While I was working away I came across a Delphi frustration that caused some concern. I've only recently taken over a very large amount of code from a previous programmer who used the "New Directory" theory of version control. This creating a new directory for each release.

His directory structure looks something like this...


When version 01d is released, the entire directory would by copied into a new ..\01e\ directory and work would continue there.

This works fine until I set up proper version control here. However Delphi starts to insist on changing code in the previous directory even when you are working on the new one. It also starts to insist - yes absolutely INSIST, that it must create a Project Group that includes the project in the old directory.

To get around this, I deleted the *.dsk file. These are text files that hold specific directory information that Delphi uses. Delphi will recreate this file when it next loads.

Some have suggested that I also delete *.cfg and *.dof files as well, but so far these files have been innocent.