Before Xmas I started implementing code checks and metrics in my Browse and Doc It plug-in to help me write better code and where I’m maintaining legacy code, tell me where I need to refactor the code. So there are many files I have which are littered with hard coded integers, numbers and string which later on, may cause issues If I don’t update all the references at the same time.

Today I’ve been working on my Integrated Testing Helper plug-in as its long over due for some TLC. In one of the forms I’m using a TListView to display information about processes to run before or after the main application has compiled and these were indexed using hard coded integers. So I thought to replace them with an enumerate as below:

Type TITHColumn = ( coTitle , coEXE , coParams , coDir ) ;

However to use these enumerates I have to cast them to integers. Also the TListView has SubItems where the index is out by one so I was writing code as follows:

strProgramme := Item . SubItems [ Pred ( Integer ( coEXE ) ) ] ;

and…

LV . Columns [ Integer ( coExe ) ] . Width := Trunc ( i * dblEXEPctWidth ) ;

While walking to the local shops, I thought there must be a better way of doing this! Can I write a (record) helper to do all of this for me and also make it more readable for maintenance. So once I was back, I found I could write a record helper for my enumerate as follows:

Type TITHColumnHelper = Record Helper For TITHColumn Function ColumnIndex : Integer ; Function SubItemIndex : Integer ; End ;

The implementations for the two functions are as follows:

Function TITHColumnHelper . ColumnIndex : Integer ; Begin Result := Integer ( Self ) ; End ; Function TITHColumnHelper . SubItemIndex : Integer ; Begin Result := Pred ( Integer ( Self ) ) ; End ;

This then allows me to simplify the coding in the form as shown in the following 2 examples:

Procedure TfrmITHConfigureDlg . btnEditClick ( Sender : TObject ) ; Var iIndex : Integer ; strTitle , strProgramme , strParameters , strWorkingDirectory : String ; Item : TListItem ; Begin iIndex := lvCompile . ItemIndex ; If iIndex > - 1 Then Begin Item := lvCompile . Items [ iIndex ] ; strTitle := Item . Caption ; strProgramme := Item . SubItems [ coEXE . SubItemIndex ] ; strParameters := Item . SubItems [ coParams . SubItemIndex ] ; strWorkingDirectory := Item . SubItems [ coDir . SubItemIndex ] ; If TfrmITHProgrammeInfo . Execute ( strTitle , strProgramme , strParameters , strWorkingDirectory , FGlobalOps . INIFileName ) Then Begin Item . Caption := strTitle ; Item . SubItems [ coEXE . SubItemIndex ] := strProgramme ; Item . SubItems [ coParams . SubItemIndex ] := strParameters ; Item . SubItems [ coDir . SubItemIndex ] := strWorkingDirectory ; End ; End ; End ; Procedure TfrmITHConfigureDlg . lvResize ( Sender : TObject ) ; Const dblTitlePctWidth = 0.15 ; dblEXEPctWidth = 0.35 ; dblParamsPctWidth = 0.20 ; dblDirPctWidth = 0.30 ; Var i : Integer ; LV : TListView ; Begin LV := Sender As TListView ; i := LV . ClientWidth ; LV . Columns [ coTitle . ColumnIndex ] . Width := Trunc ( i * dblTitlePctWidth ) ; LV . Columns [ coExe . ColumnIndex ] . Width := Trunc ( i * dblEXEPctWidth ) ; LV . Columns [ coParams . ColumnIndex ] . Width := Trunc ( i * dblParamsPctWidth ) ; LV . Columns [ coDir . ColumnIndex ] . Width := Trunc ( i * dblDirPctWidth ) ; End ;

Now I know I can do this, it opens up a number of options for simplifying column layouts in Virtual String Trees and the like.

regards

Dave.