Borland Delphi


Knowing when to use semicolons

In Object Pascal, semicolons are statement separators. Accordingly, you need to have semicolons only where you want to separate statements or declarations.
For example, if you write a complex, nested set of statements such as


procedure nest;
  begin
    if True then
    begin
      if True then
      begin
      { do nothing }
      end
    end
    else
    begin
    { do nothing }
    end
  end;

you aren't required to place semicolons after the "end" statements because there's not another statement following any of them. In each case, the "begin..end" clause is nested inside another "begin..end" clause.


Know when to use the correct combo box

Delphi provides three types of combo box styles you can include in your user interface. They share some common traits, but they have their differences. Knowing what the differences are will allow you to choose the correct combo box for the job.

All combo box styles are a combination of a list box and an edit control. The user can choose from the list or type in a value in the edit portion. When the user chooses from the list, that item is placed in the edit portion. Their different features determine their appearance and user interaction. Two of the styles use a minimum of space and one style prevents the addition of new items. The chart below describes the unique features of each style.

 Style  Description
 Simple  The simple style of the combo box is nothing more than an edit control placed on top of a list box. The user can choose from the list or type text in the edit portion.
 Drop-down  Similar to the simple type, except the list box portion isn't initially displayed. A drop-down button is provided so that the user can view the list and choose an item. The user can also type text in the edit portion.

Drop-down list The most restrictive type of combo box. As with the drop-down style, the list isn't initially exposed. The user can click the drop-down button to expose the list and chose an item from the list, but can't enter text in the edit portion.

Use the Simple style when you have the extra space on your form or the list is short. When form real estate is at a premium or when the list is long, use the Drop-down style. Use the Drop-down list style when you want the user to select only from a predetermined set of choices.


Add a horizontal scrollbar to TListBox

Delphi's TListBox component automatically implements a vertical scrollbar. The scrollbar appears when the list box isn't tall enough to display all its items. However, the list box doesn't display a horizontal scrollbar when its items are wider than its width. Of course, there's a way for you to add the horizontal scrollbar.

Add the following code to the OnCreate event of your form.


procedure TForm1.FormCreate(Sender: TObject);
var
  i, MaxWidth: integer;
begin
  MaxWidth := 0;
  for i := 0 to ListBox1.Items.Count - 1 do
  if MaxWidth < ListBox1.Canvas.TextWidth(ListBox1.Items.Strings[i]) then
    MaxWidth := ListBox1.Canvas.TextWidth(ListBox1.Items.Strings[i]);
  SendMessage(ListBox1.Handle, LB_SETHORIZONTALEXTENT, MaxWidth+2, 0);
end;

The code finds the width, in pixels, of the longest string in the list box. Then, it uses the LB_SETHORIZONTALEXTENT message to set the horizontal scrollable width, in pixels, of the list box. The two extra pixels added to MaxWidth help offset narrow characters from the right edge of the list box.


Adding a Book Shelf tool

Many Delphi help topics can be viewed by pressing F1 while in the IDE. This method quickly opens a help window containing links to the topic reference. Unfortunately, this handy access isn't available for the various FAQs or 3rd party tools you may use. However, you can provide access to them in your Tools menu with only a few seconds worth of effort. Here's how.

From the Tools menu, select Configure Tools.... Doing so will open a dialog box containing a list of available tools. Click the Add… button to open the Tool Properties dialog box. Set the Title to My Delphi FAQ, the Program to winhlp32.exe, and the Parameters to MyDelphiFAQ.hlp, then click OK. Click Close to close the Configure Tools dialog box.


Determining the Windows OS

Microsoft may eventually create a single desktop operating system. Until that happens, your applications probably need to be flexible enough to run on all Windows versions. Of course, you can use conditional compilation and create an executable for each target platform.

However, your application may need to dynamically determine the Windows OS. There's a simple technique for doing just that. You can use the GetVersionEx Windows API call. GetVersionEx accepts a single variable parameter of type TOSVersionInfo. Then, you can interrogate the return values. Here's an example:


procedure TForm1.Button1Click(Sender: TObject);
var
  VersionInfo: TOSVersionInfo;
begin
  VersionInfo.dwOSVersionInfoSize := Sizeof(TOSVersionInfo);

  GetVersionEx(VersionInfo);

  case VersionInfo.dwPlatformID of
    VER_PLATFORM_WIN32S:
      Do_SomeThing;
    VER_PLATFORM_WIN32_WINDOWS:
      Do_SomeOtherThing;
    VER_PLATFORM_WIN32_NT:
      Do_SomeThingElse;
    end;

end;

The GetVersionEx call returns additional information in the TOSVersionInfo structure as shown below.


typedef struct _OSVERSIONINFO{ 

    DWORD dwOSVersionInfoSize; 
    DWORD dwMajorVersion; 
    DWORD dwMinorVersion; 
    DWORD dwBuildNumber; 
    DWORD dwPlatformId; 
    TCHAR szCSDVersion[ 128 ]; 
} OSVERSIONINFO;


The transparent pixel

When you place a glyph (a picture, generally a BMP file) on a button, be aware that the color of the pixel in the glyph's lower-left corner will be used as the transparent color. Any pixels of that color, will be transparent on the button. If you don't want any transparent pixels on your button bitmaps, you must be sure to use a color in the lower-left corner that you don't use anywhere else in the glyph.


How's your memory?

Here's a technique for determining the amount of available memory on your system. More importantly, your application can use this technique to detect the available memory of their client machine. Armed with that information, your application can dynamically change its processes to optimize performance. For example, to perform bitmap manipulation with double buffering on machines with ample memory, you can use the GlobalMemoryStatus Windows API call. GlobalMemoryStatus accepts a single variable parameter of type TMemoryStatus. Then, you can interrogate the return values. Here's an example:


procedure TForm1.Button1Click(Sender: TObject);
var
  MemoryStatus: TMemoryStatus;
begin
  MemoryStatus.dwLength := sizeof(MemoryStatus);
  GlobalMemoryStatus(MemoryStatus);
  Label1.Caption := 'Total Physical Memory: ' +
IntToStr(MemoryStatus.dwTotalPhys);
end;

The GlobalMemoryStatus call returns additional information in the MemoryStatus structure as shown below.


typedef struct _MEMORYSTATUS { // mst  
    DWORD dwLength;        // sizeof(MEMORYSTATUS) 
    DWORD dwMemoryLoad;    // percent of memory in use 
    DWORD dwTotalPhys;     // bytes of physical memory 
    DWORD dwAvailPhys;     // free physical memory bytes 
    DWORD dwTotalPageFile; // bytes of paging file 
    DWORD dwAvailPageFile; // free bytes of paging file 
    DWORD dwTotalVirtual;  // user bytes of address space 
    DWORD dwAvailVirtual;  // free user bytes 
} MEMORYSTATUS, *LPMEMORYSTATUS;


Cancel that drag operation!

Have you ever started moving a component while designing your form and realized you selected the wrong component? No doubt, you can think of other instances when you would like to cancel a design-time drag operation you've already begun. Here's a tip that let's you do just that.

After you've begun the drag but before you release the mouse button, press the Esc key. The control will snap back to its original position!


Don't interrupt me

Delphi's integrated debugger watches for run-time errors while you test your application. When the debugger identifies an error, Delphi interrupts the application and returns you to the design-time environment. Next, Delphi displays a dialog box describing the error. After you close the error message, you can reset your program, [Ctrl-F2], or continue testing it, [F9].

While the integrated debugger can be helpful, it can also be annoying. For example, when you're testing your custom exception handling code, it would be nice to see the exception as your user will see it. Here's a simple way to prevent integrated debugger interruptions.

Select Environment Options... from Delphi's Tools menu. On the Preferences page, remove the checkmark from the Integrated debugging option. Now, when you test your application, the debugger won't return you to the design environment.


Time is running out

A common use for measuring elapsed time is when you're benchmarking performance or tracking the rate of user responses. In either case, most developers resort to using a TDateTime variable and the Now function.

However, using the Windows API GetTickCount call is even easier. The GetTickCount function retrieves the number of milliseconds that have elapsed since Windows was started. If the function succeeds, the return value is the number of milliseconds that have elapsed since Windows was started. Here's an example that illustrates how to use this technique.


procedure TForm1.Button1Click(Sender: TObject);
var
  i: longint;
  StartTime, EndTime: Double;
const
  CLOCK_TICK: Double = 1000;

begin
  i := 0;
  StartTime := GetTickCount;
  while (i < 10000000) do
    i:= i+1;
  EndTime := GetTickCount - StartTime;
  ShowMessage(Format('Elapsed Time: %0.2f seconds',[EndTime/CLOCK_TICK]));
end;


Primary Colors

When you choose a value for the Color property, Delphi allows you to create your own color. This could be important when you're trying to match the color in a client’s logo. There are only a few steps to creating your own custom colors.

First, double-click on the Color property of the component, instead of clicking the list arrow. After you double-click, the Color dialog appears. Click the basic color closest to the final color you want, then click Define Custom Colors>> button. The Color dialog expands to display a spectrum of colors. The color spectrum has cross hairs that you move until the color you want is displayed. When you're satisfied with your choice, click the Add to Custom Colors buttons. Now your unique color is stored in the Color dialog box.

For your convenience, custom colors remain in the color dialog for the current project. Even as you start new projects or visit older ones, your color one-of-a-kind color remains part of the Color dialog.