Home
Archives
About us...
Advertising
Contacts
Site Map
 

ruby in steel

 

A DELPHI PROGRAM LAUNCHPAD #2

Want a want to organise your favourite programs and documents? Follow Huw Collingbourne’s directions to create a custom application launchpad.

Requirements:
Borland's Delphi 7 or later

 

Download The Source Code:
lpad2.zip

 

In my last Delphi article, I programmed a configurable application launchpad. This demonstrated how to create and delete controls on the fly and give them OnClick event-handlers. I shall now develop this further in order to create program launchers with a more compact user interface based on combo boxes and list views. By the time you’ve worked through this month’s projects you will know how to display graphics and icons in lists and combo boxes. You will also have all the techniques needed for creating a completely customised program launcher.

Load up the Lpad.dpr project from this month’s source code. This is based on the application launchpad I developed previously. The original project took the form of a button bar in which a new file-launching button was created whenever the user dragged a file name or icon from the Windows Explorer or Desktop onto the launchpad. This new version substitutes a TComboBoxEx for the buttons. This has the advantage that it takes up much less screen space.

Countdown to Launch...


My new launchpad is seen here above the Windows Explorer. To add an application (or a file such as one of the JPG graphics shown here) I drag it right out of Explorer and drop it onto the launchpad. The file name is then added to the combo box.


Here you can see I’ve added a number of different files. Note that each file is preceded by its associated icon. I can click the combo box to display the drop-down list. The selected file name will then appear in the ‘text field’ of the combo box


Finally, to open the file I click the Launch button. If the file is an EXE it will be launched. If it is a data file (such as this JPG graphic) it will be launched into its associated application which, in this case, happens to be the Microsoft Office Picture Manager

The TForm1.AddFile() method is called by the RespondToMessage() method when a new item is dropped onto the form. The AddFile() method adds a small icon to an ImageList component using ImageList1.AddIcon() which returns the index of the new icon in the image list. My code then adds the file name and icon to the TComboBoxEx control named CBox. Delphi’s Help shows that AddItem() takes these arguments:

function AddItem(const Caption: String; const ImageIndex, SelectedImageIndex, OverlayImageIndex, Indent: Integer; Data: Pointer): TComboExItem;

Here, Caption is the text to display for the new item in the combo; ImageIndex is the index into the ImageList of the image to display next to the text; SelectedImageIndex is the image to display when the item is selected; OverlayImageIndex is the optional index of a monochrome image which can overlay the displayed image to implement transparency; Indent indicates the indentation level of the item and it is –1 for no indentation; Data is a pointer to some arbitrary piece of data that you might want to associate with this item or nil for no data item. This is my code:

CBox.ItemsEx.AddItem( ExtractFileName(fname), IconIndex, IconIndex, 0,
-1, ItemList.Objects[ItemList.Add(fname)] );

Here the final Data argument adds the pathname to the file as an Object in the TStringList object named ItemList. You will find this declared in the private part of the form definition. To display the most recently added item in edit box of the TComboBoxEx named CBox I set its ItemIndex to its last item (Count-1):

CBox.ItemIndex := CBox.Items.Count-1;

In order to delete a selected item, I delete the object (the string path) from the non-visual ItemList and from the ItemsEx property of CBox. You will find the relevant code in our DeleteMIClick() method.

Launch Box

Naturally, this being an application launchpad, it needs to have some event that starts the file launching process. In my earlier project I used the OnClick event-handlers of a set of buttons to do this. In a ComboBox it might seem that simply selecting an item should be sufficient to launch it in much the same way that an application is run when selected from the Windows Start Menu. In order to do that, you just need to add this single line of code to the CBoxChange() event-handling method:

LaunchFile(ItemList.Strings[CBox.ItemIndex]);

Here, LaunchFile() is the name of a method which you will find earlier in my code. The only trouble with launching an application just by selecting it is that sometimes you might search for an application in the dropdown list but then change your mind and decide that you don’t want to run it after all. For that reason, I’ve provided a toggle that lets the user decide whether or not to run an application immediately on selecting its name. The toggle takes the form of a check-mark against the ‘Launch On Select’ menu item on the File menu. The user can select this menu item to check or uncheck it. This toggle is implemented in the LaunchonSelectMIClick() method:

LaunchonSelectMI.Checked :=  not(LaunchonSelectMI.Checked);

Here the use of the not operator returns the opposite of the LaunchonSelectMI menu item’s current checked state. If it is checked, then False is returned. If it is unchecked, True is returned. This opposite value is then assigned to LaunchonSelectMI.Checked, thereby reversing its former state.

Use the File menu to toggle ‘Launch On Select’. This menu also lets you save the lauch paths of the icons in your ‘IconBar’ list or restore a previously saved list.

If you choose not to launch an application upon selection, you can use the Launch button to do it. I’ve assigned a popup menu to the form and this can be use to delete or display information on the selected file. I’ve also added a ‘Show All Files’ item to the File menu to display a list of all the file names and paths currently loaded. This is mainly useful as a debugging aid to check file paths are added and deleted as and when you expect them to be.

On The List

There are other components that might also be used to implement a launchpad. For example, if you don’t care for the drop-down list of a combo box, you could display a list in a ListView. Load up the Lpad2.dpr project which uses a List View. If you run it you will see that the list view displays the file names and precedes each with the appropriate icon.


My second launchpad uses a ListView. This has the advantage of letting you see numerous files without having to navigate through items in a dropdown list.

Remarkably little code is needed to do this. I simply created a new TListItem object for each item in the list, added this object to the ListView control, set its caption to the file name and its icon to the appropriate index in the ImageList. Here is the code as it appears in my AddFile() method:

NewItem := ListView.Items.Add;
NewItem.Caption := ExtractFileName(fname);
NewItem.ImageIndex := IconIndex;

To launch an item in the list when it is double-clicked I obtain the ItemIndex of the ListView to index into ItemList, a TStringList of paths, as before. This code is found in the ListViewDblClick() method. Deleting an item is done in DeleteMIClick() by first deleting the item from the non-visual ItemList and then deleting the selected item from the ListView.

By default, the ViewStyle of my ListView is vsList. This displays items in a fixed order with the icon before the caption. However, this ViewStyle has one unfortunate side-effect: when a new item is added the column width automatically resizes to fit the new caption. If this is shorter than previous captions, they will appear to be truncated. A simple way around this is to toggle ViewStyles to vsSmallIcon and back to vsList when a new item is added. This sizes the column to the widest caption in the list. To prevent any repaints, which might cause a flickering effect, I prevent updating of the view by placing the ‘view toggle’ between the ListView.Items.BeginUpdate and ListView.Items.EndUpdate methods. You will find this code in TForm1.AddFile().

I Want To Be Selected!

Finally we need to deal with the selection in the ListView to ensure that we don’t try to delete an item or launch an application when no item is selected. In the DeleteMIClick() method I always select the item at the same index as the deleted item or at the previous index if the deleted item was the last entry in the list. If there are no items left after the deletion, I do not attempt to select anything but, instead, I display the string ‘Nothing selected’ in a label above the ListView. If the ListView was empty when the Delete menu item was selected, then the ItemIndex is –1 and so I exit the method without doing anything.


As an added bonus you can right-click to pop up this menu which lets you delete the selected item or display some basic file information

We also need to set the Selection when we reload a list of items from disk. This is done in ReloadItems() with this code which places the selection on the first item at index 0:

if ListView.Items.Count > 0 then
    ListView.Items[0].Selected := true;

There are, of course, many other components which could be used as the basis of a launchpad. For example, you could use MainMenu or PopupMenu controls. While I’ve concentrated on creating a user-configurable launchpad in these two articles, there are, in fact, many other ways in which you could use the basic techniques which I’ve described. For example, if you don’t care for the Windows Start Menu, you could create your own, more civilized alternative. Maybe, for example, you would prefer to have your applications arranged as icons in overlapping windows - rather in the manner of the old Windows 3.1 Program Manager. I shall explain how to do this in a new series starting next month…

(See also Part One of this series)

December 2005

 


Home | Archives | Contacts

Copyright © 2006 Dark Neon Ltd. :: not to be reproduced without permission