The Unofficial Newsletter of Delphi Users - Banner

Downloadable UNDU Issues Delphi User Groups

News Page

June 30, 1998

In under the wire... Two new articles: The first is from Kevin Gallagher on Extending the StatusBar component. Pretty neat stuff. Also today, a great article by Grahame Marsh on helper components for dragging and dropping files to and from your Delphi apps. You can read all about it in Drop File Helper Components. This is one of the more requested capabilities I get from readers, so I am glad Grahame put this together!

Also, I am integrating the Articles page into the Tips & Tricks page. Sometimes it is hard to determine what is an "article" and what is a "tip or trick". Better to put them in one spot I suppose...

June 26, 1998

Added the new Delphi Job Sites link on the UNDU home page. Thanks to everyone for their excellent input on this. Remember, everything that someone submits to me that I use on the site is entered in the random prize drawing at the end of each month. So everyone who submitted a Delphi Jobs site will be in this months drawing! If anyone knows of others that aren't listed, please let me know!

There also was some confusion about how to email me, so I have added an email link button as well.

June 16, 1998

Atanas Stoyanov - astoyanov@nidlink.com has announced the release of a free Memory and Resource leaks debugger called MemProof. You can learn more about this product at his web site: http://www.nidlink.com/~astoyanov/index.htm.

I have received a significant number of emails lately regarding Delphi Job positions. Currently, I am aware of only one Delphi-only Job Site (http://www.inthemiddle.co.uk/jobhunter/delphi/default.htm). If you know of any others, please let me know and I will group them together here for everyone to see.

Also today, Eamonn Mulvihill (I spelled it right this time...) presents an interesting extension to a previous article about highlighting edit boxes that have the focus. His alternate method is called Highlighting Edit Boxes.

And lastly, Matt Hamilton shows a simple technique for archiving data in Tables or Query's out to a Comma-Separated text file. His article is entitled Archiving Data in TTables and TQueries.

June 15, 1998

Don't worry... things will be smoothing out here shortly... I am in the last 2-3 weeks of building our new house (in the lot adjacent to the one we are living in), so it is quite a distraction for me lately. I am planning on getting back to my 2-3 updates a week schedule pretty darn soon...

You have all probably been checking in loyally to see who the randomly selected winner is this month. Well, the winner is... (drum roll...) Alexander Mehlhorn for his article on Dynamically Loading Packages at Runtime. Alexanders prize is a copy of Hidden Paths of Delphi 3, an excellent book by Ray Lischner illustrating the techniques needed to develop experts, wizards, and more using the Open Tools API in Delphi. Remember folks, each month, I randomly select one contributor for that month to receive a prize. During the month of May, there were 6 contributors, so it was just a 1 in 6 chance. Also, most months I will award more than one prize... just depends what I have on hand! Doesn't matter what you contribute. If I use it, you are in the drawing!

Now on to the new stuff...

Jaffar Sulemani brings us an interesting debugging component that allows you to browse through any Table or Query in your application at runtime. Often times we may be inclined to throw a grid on a form just so we can see what is happening while the code is running. Jaffar's solution puts an end to that... Check it out in Sneaking a Peek at Data-Access Components.

Grahame Marsh put together an extension of Jorge Turiel's article on multi-line hints. Grahame presents... The MultiLine Hint Property Editor!

In order to keep the size of the News Page to a minimum, I will be archiving previous months and listing them at the bottom.
News Page for May, 1998
News Page for April, 1998
News Page for March, 1998
News Page for February, 1998


The Unofficial Newsletter of Delphi Users - Tips & Tricks

Articles, Tips & Tricks

Below is a comprehensive list of links to all the Articles, Reviews, and Tips & Tricks published in The Unofficial Newsletter of Delphi Users. Because of the number of articles and tips & tricks in past issues, this will be a work in progress, so please keep checking back for updated links.

06/30/98 - Drop File Helper Components
06/30/98 - Extending the StatusBar Component
06/16/98 - Highlighting Edit Boxes
06/16/98 - Archiving Data in TTables and TQueries
06/15/98 - Sneaking a Peek at Data-Access Components
06/15/98 - Multi-Line Hint Property Editor
05/25/98 - Multi-Line Hints
05/25/98 - A Universal TDateTime Class
05/25/98 - Here Thar Be Dragons!
05/25/98 - Getting to the Bottom of FAT32
05/11/98 - Dynamically Loading Packages
04/22/98 - Controlling Application Startup in Delphi 3
04/22/98 - Inside the Delphi 3 Package
04/22/98 - Digital Sound in Delphi Part II
04/17/98 - Multiple Lines of Text in a String Grid - Improved!
04/17/98 - Auto Upgrading!
04/17/98 - Piggybacking Event Handlers with Components
04/15/98 - Using TDataSource to Improve Your User-Interface
04/15/98 - Hooking Into the VCL
03/26/98 - Using TMediaPlayer to Manage Multiple CDRoms
03/26/98 - Beziers and Paths
03/26/98 - Windows Hooks
03/25/98 - WinHelp Office Review
03/18/98 - Creating Shortcuts in Delphi
03/18/98 - Can't Have Too Much WinInfo!
03/18/98 - Drawing on a TEdit Control
03/18/98 - Borland's Tech Sheets
03/17/98 - Extending the Moving/Resizing Technique
03/17/98 - Using the Clipboard with WAV Files
03/11/98 - Determining CPU Type
03/11/98 - Compressing 256 Color BMPs
03/06/98 - Moving and Sizing Controls at Runtime
02/28/98 - Digital Sound & Music in Delphi
02/26/98 - Accessing the Win95 FindFiles Dialog
02/23/98 - Improving Cut, Copy & Paste
02/23/98 - Giving Your EditBoxes Some Attention
02/21/98 - Delphi 3's Code Parameters
02/21/98 - CD Change Notifications
Issue #24 - Speeding Up Master-Detail Tables
Issue #24 - Beginners Block: An Introduction to Pointers
Issue #24 - NIL Pointers: How Delphi Frees Objects
Issue #24 - RGB & HSL Colour Models
Issue #24 - More on Moving From VB to Delphi
Issue #24 - A Second Look at MicroEdge's Visual SlickEdit
Issue #24 - Delphi and the Year 2000
Issue #23 - Playing and Recording Sounds in Delphi
Issue #23 - An Immediate IF Function
Issue #23 - Two Lines of Text in a String Grid
Issue #23 - A Simple Drawing Program
Issue #23 - Finding the Cursor Coordinates in a Memo Control
Issue #23 - A Browse Directory Component
Issue #23 - Changing Event Handlers at Runtime
Issue #23 - Book Review: Hidden Paths of Delphi 3
Issue #23 - Book Review: Building Delphi 2 Database Applications
Issue #23 - Review: Raize Components
Issue #23 - Making the Move: VB to Delphi
Issue #23 - Add a Web Search Engine to Your Application
Issue #22 - Bitmaps in String Grids
Issue #22 - A Cure for Previous Instance Problems
Issue #22 - A Word Search Tip
Issue #22 - Unbridled Acceleration
Issue #22 - Showing the Caret Position
Issue #22 - Using the Win95 Registry
Issue #22 - Wallpapering MDI Forms
Issue #22 - The InputQueryEx Function
Issue #22 - Exceeding the Data Segment
Issue #22 - Delphi 2.0 and 3.0 on the Same Computer
Issue #22 - Review: Programmers Guild Animated Tray Icon
Issue #22 - Review: MicroEdge's Visual SlickEdit
Issue #22 - Review: IniOut Component
Issue #22 - Review: Addict 2.2 Spell Checker for Delphi
Issue #22 - Getting Control of the Control Panel
Issue #21 - Low-Level Windows Stuff
Issue #21 - Listing Procedures
Issue #21- Hiding Apps from the TaskBar
Issue #21 - Excel OLE Tips
Issue #21 - Playing Sounds Asynchronously
Issue #21 - Bitmaps on StringGrids
Issue #21 - How to Find Up-To-Date Delphi Books
Issue #21 - Using the Margin Marker in Delphi 1 & 2
Issue #21 - Lock Violations Revisited
Issue #21 - Object Creation Tip
Issue #21 - How To Compress a Bitmap
Issue #21 - The TEndSession Component
Issue #21 - Video Capture and Delphi
Issue #21 - Review: Delphi Component Design
Issue #20 - Is Someone Else Running? Revisited!
Issue #20 - InputQueryEx Function
Issue #20 - Multi-Colored Text in a String Grid
Issue #20 - Converting Pascal Source to HTML
Issue #20 - Processing Large Database Tables
Issue #20 - Making Your App Look Normal at Different Resolutions
Issue #20 - How to Make Your EXE's Lighter!
Issue #20 - Win95 Shell Operations - Update
Issue #20 - Form Aspect Ratio
Issue #20 - Previous Instances - Revisited
Issue #20 - Printing Raw Data
Issue #20 - Implementing a "Tip Of The Day" Component
Issue #20 - TFieldPanel
Issue #20 - TPageControl - Update
Issue #20 - Learning How To Drive: Disk Information in Delphi
Issue #20 - Delphi Books and Periodicals
Issue #19 - Using Win95's SHFileOperation to Move/Copy/Delete Files
Issue #19 - How to Create a Polygon Splash Screen
Issue #19 - Is Someone Else Running?
Issue #19 - Lock Violation Errors in Paradox
Issue #19 - Printing Directly to the Printer
Issue #19 - Refreshing MDI Menus
Issue #19 - Extending the Background Bitmap Technique
Issue #19 - Paradox File Size Limits
Issue #19 - Safer Use of Enumerated Types
Issue #19 - Simplifying Code Management with Include
Issue #19 - A Look at the TreeView Component
Issue #19 - Aligning Text in a Grid
Issue #19 - TPageControl
Issue #19 - Big Bitmaps
Issue #19 - Transparency Masks
Issue #19 - Review: SpeedDaemon Code Profiler
Issue #19 - A Look at MagiKit
Issue #19 - Humor: Are you Computer Illiterate?
Issue #18 - Storing Fonts in INI files
Issue #18 - Sorting Columns in a DBGrid
Issue #18 - Adding UNDU to an Edit Menu
Issue #18 - Put Anything in Your Delphi EXE!
Issue #18 - A Simple Clipboard Viewer
Issue #18 - Object Express by OopSoft
Issue #18 - Announcement: IniOut Component
Issue #18 - Book Review: Delphi Component Design by Dany Thorpe

More links to come! To see the material in Issues 1 through 17, click here.


A Multiline Hint Property Editor

The Unofficial Newsletter of Delphi Users - by Robert Vivrette

A Multiline Hint Property Editor

by Grahame Marsh - gsmarsh@aol

In the 25th May issue of UNDU, Jorge Turiel showed a simple, but effective way of obtaining multiline hints. The disadvantage of his method is that the
hint is placed in the code associated with the form and not in the component's hint property in the object inspector. What is obviously needed is a hint property editor that allows the hint property to have multiple lines.

So having been given the "hint" by Jorge, I have written a simple property editor. It includes a TPanel to show what the hint text currently looks like. If you want to make the editor memo to look like the hint text then you need to include the following FormCreate event handler.

    procedure THintStringEditDialog.FormCreate(Sender: TObject);
    var
      NCM: TNonClientMetrics;
    begin
      with Memo do
      begin
        NCM.cbSize := sizeof (TNonClientMetrics);
        if SystemParametersInfo (SPI_GETNONCLIENTMETRICS, 0, @NCM, 0) then
          Font.Handle := CreateFontIndirect (NCM.lfStatusFont)
        else
          Font.Size := 8;
        Font.Color := clInfoText;
        Brush.Style := bsClear;
        Color := clInfoBk
      end
    end;

Enjoy, and thanks to Jorge for the original idea. You can download the code for this by clicking here...

    unit HintProp;

    interface

    uses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, DsgnIntf,
      ExtCtrls, StdCtrls, ComCtrls;

    type
      THintStringEditDialog = class(TForm)
        Bevel1: TBevel;
        LineCounter: TLabel;
        Memo: TRichEdit;
        CancelButton: TButton;
        OkButton: TButton;
        ShowPanel: TPanel;
        procedure MemoChange(Sender: TObject);
      private
      public
      end;

    procedure Register;

    implementation

    {$R *.DFM}

    procedure THintStringEditDialog.MemoChange(Sender: TObject);
    begin
      ShowPanel.Hint := Memo.Text;
      LineCounter.Caption := Format ('%d Lines', [Memo.Lines.Count])
    end;

    type
THintProperty = class (TStringProperty)
private
public
procedure Edit; override;
function GetAttributes: TPropertyAttributes;
  override;
end;

    procedure THintProperty.Edit;
    begin
      with THintStringEditDialog.Create (Application) do
      try
        Memo.Text := GetValue;
        if ShowModal = mrOk then
          SetValue (Memo.Text)
      finally
        Free
      end
    end;

    function THintProperty.GetAttributes: TPropertyAttributes;
    begin
      Result := [paDialog]
    end;

    procedure Register;
    begin
      RegisterPropertyEditor (TypeInfo (string), nil, 'Hint', THintProperty)
    end;

    end.

    //******************************************************************************

    object HintStringEditDialog: THintStringEditDialog
      Left = 400
      Top = 131
      BorderStyle = bsDialog
      Caption = 'Hint string editor'
      ClientHeight = 277
      ClientWidth = 428
      Font.Charset = DEFAULT_CHARSET
      Font.Color = clWindowText
      Font.Height = -11
      Font.Name = 'MS Sans Serif'
      Font.Style = []
      PixelsPerInch = 96
      TextHeight = 13
      object Bevel1: TBevel
        Left = 8
        Top = 8
        Width = 413
        Height = 229
        Shape = bsFrame
      end
      object LineCounter: TLabel
        Left = 16
        Top = 16
        Width = 34
        Height = 13
        Caption = '0 Lines'
      end
      object Memo: TRichEdit
        Left = 16
        Top = 32
        Width = 397
        Height = 197
        HideScrollBars = False
        ScrollBars = ssBoth
        TabOrder = 0
        WordWrap = False
        OnChange = MemoChange
      end
      object CancelButton: TButton
        Left = 344
        Top = 248
        Width = 75
        Height = 25
        Caption = 'Cancel'
        ModalResult = 2
        TabOrder = 1
      end
      object OkButton: TButton
        Left = 264
        Top = 248
        Width = 75
        Height = 25
        Caption = 'Ok'
        ModalResult = 1
        TabOrder = 2
      end
      object ShowPanel: TPanel
        Left = 8
        Top = 246
        Width = 105
        Height = 29
        BevelInner = bvLowered
        Caption = 'Show me'
        Font.Charset = DEFAULT_CHARSET
        Font.Color = clWindowText
        Font.Height = -11
        Font.Name = 'MS Sans Serif'
        Font.Style = []
        ParentFont = False
        ParentShowHint = False
        ShowHint = True
        TabOrder = 3
      end
    end


Sneaking A Peek at Data-Access Components

by Jaffar Sulemani - jaffarsulemani@usa.net

Have you ever had to take a peek at what was going on in a particular table or query? The idea behind this component was to have a debug form which will give a peep hole into the data-access components which a programmer may have dropped on their forms or datamodules. This form can be shown at any time with a procedure:

    procedure.DataAccessDebugBox1.DisplayDebug(FComponent : TComponent);

This procedure will accept paramater which will be either 'Self' or the 'form/Datamodule' name for which dataaccess components have to be browsed.

Let me know if any new features a programmer would like to have on the component.

See u for now...

Download Files for this project.

    unit DebugBox;

    interface

    uses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      DB, Menus, ExtCtrls, StdCtrls, Mask, DBCtrls,
      Grids, DBGrids,  ComCtrls, DBTables;

    type
      TPositions = (poTopLeft,poBottomLeft,poTopRight,poBottomRight);

      TDataAccessDebugBox = class(TComponent)
private
FPosition : TPositions;
FWidth    : Integer;
FHeight   : Integer;
DebugForm : TForm;
FClassname : TComponent;
procedure SetPosition(A: TPositions);
procedure SetWidth(A: Integer);
procedure SetHeight(A: Integer);
function  ReadFClassName : TComponent;
procedure WriteFClassName(FComponent : TComponent);
property  DAComponentsOn : TComponent Read
  ReadFClassName write WriteFClassName default nil;
public
constructor Create(AOwner: TComponent); override;
procedure DisplayDebug(FComponent : TComponent);
published
property Position: TPositions read FPosition write
  SetPosition default poTopRight;
property Width: Integer read FWidth write SetWidth
  default 550;
property Height: Integer read FHeight write
  SetHeight default 200;
end;

    procedure Register;

    implementation

    uses DisplayDebug;

    procedure Register;
    begin
      RegisterComponents('Samples', [TDataAccessDebugBox]);
    end;

    constructor TDataAccessDebugBox.Create(AOwner: TComponent);
    begin
      inherited Create(AOwner);
      FPosition := poTopRight;
      FWidth := 250;
      FHeight := 200;
      if not (csDesigning in ComponentState) then
        begin
          DebugForm := TFormMDIDisplayDebug.Create(Application);
          with DebugForm do
            begin
              Visible  := False;
              FormStyle := fsStayOnTop;
              BorderStyle := bsSizeable;
              BorderIcons := [biSystemMenu];
            end;
        end;
    end;

    procedure TDataAccessDebugBox.SetPosition(A: TPositions);

    begin
      FPosition := A;
      if not (csDesigning in ComponentState) then with DebugForm do
        case A of
          poTopLeft     : SetBounds(0,0,Width,Height);
          poBottomLeft  : SetBounds(0,Screen.Height-Height,Width,Height);
          poTopRight    : SetBounds(Screen.Width-Width,0,Width,Height);
          poBottomRight : SetBounds(Screen.Width-Width,Screen.Height-Height,Width,Height);
        end;
    end;

    procedure TDataAccessDebugBox.DisplayDebug(FComponent :
  TComponent);
begin
if not (csDesigning in ComponentState) then
begin
if FComponent <> nil then
DAComponentsOn :=
  FComponent
else
DAComponentsOn := Owner;
DebugForm.Hide;
Width := Self.Width;
Height := Self.Height;
SetPosition(FPosition);
DebugForm.Caption := ' Data Access
  Components on ' + TComponent(DAComponentsOn).Name;
DebugForm.Visible := True;
DebugForm.Show;
TFormMDIDisplayDebug(DebugForm).ReadPara(DAComponentsOn);
end;
end;

    procedure TDataAccessDebugBox.SetWidth(A: Integer);
    begin
      FWidth := A;
      if not (csDesigning in ComponentState) then
        begin
          DebugForm.Width := FWidth;
          SetPosition(FPosition);
        end;
    end;

    procedure TDataAccessDebugBox.SetHeight(A: Integer);
    begin
      FHeight := A;
      if not (csDesigning in ComponentState) then
        begin
          DebugForm.Height := FHeight;
          SetPosition(FPosition);
        end;
    end;

    function TDataAccessDebugBox.ReadFClassName : TComponent;
    begin
      Result := FClassName;
    end;
    procedure TDataAccessDebugBox.WriteFClassName(FComponent : TComponent);
    begin
      FClassName := FComponent;
    end;

    end.

    unit displaydebug;

    interface

    uses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      StdCtrls, Grids, DBGrids, ExtCtrls,db, dbtables, Menus;

    type
TFormMDIDisplayDebug = class(TForm)
Panel2: TPanel;
Panel1: TPanel;
ListBox1: TListBox;
DS: TDataSource;
DSC1: TDataSource;
ScrollBox1: TScrollBox;
Memo1: TMemo;
DBGrid1: TDBGrid;
MainMenu1: TMainMenu;
MNUFile: TMenuItem;
MNUClose: TMenuItem;
MNURefresh: TMenuItem;
AssignSQL1: TMenuItem;
Filter1: TMenuItem;
FilterList1: TMenuItem;
TTable1: TMenuItem;
TQuery1: TMenuItem;
All1: TMenuItem;
procedure FormKeyDown(Sender: TObject; var Key:
  Word; Shift: TShiftState);
procedure FormShow(Sender: TObject);
procedure ListBox1Click(Sender: TObject);
procedure MNURefreshClick(Sender: TObject);
procedure MNUCloseClick(Sender: TObject);
procedure AssignSQL1Click(Sender: TObject);
procedure Filter1Click(Sender: TObject);
procedure TTable1Click(Sender: TObject);
procedure TQuery1Click(Sender: TObject);
procedure All1Click(Sender: TObject);
private
function SelectObjectFromList(intItemIndex
  :Integer) : TDataset;
procedure ReadParameters(AllTableQuery : Integer) ;
{ Private declarations }
public
fquery : tquery;
ftable : ttable;
DModule : TfORM;
ObjList : TComponent;
procedure ReadPara(FComponentName : TComponent);
procedure MemoUpdate(DATASET : TDATASET);
published
{ Public declarations }
end;

    var
      FormMDIDisplayDebug: TFormMDIDisplayDebug;

    implementation

    uses DebugBox;
    {$R *.DFM}

    procedure TFormMDIDisplayDebug.ReadParameters(AllTableQuery : Integer) ;
    var
      i : integer;
    begin
      if objList = nil then exit;
      ListBox1.Items.Clear;
      with objList do
        begin
          for i := 0 to ComponentCount - 1 do
            case AllTableQuery of
              1 : if Components[i] is TDataset then
                    ListBox1.Items.Add(TDataset(components[i]).Name);
              2 : if Components[i] is TTable then
                    ListBox1.Items.Add(TTable(components[i]).Name);
              3 : if Components[i] is TQuery then
                    ListBox1.Items.Add(TQuery(components[i]).Name);
            end;
        end;
      if ListBox1.Items.Count = 0 then DS.Dataset := nil;
    end;

    procedure TFormMDIDisplayDebug.ListBox1Click(Sender: TObject);
begin
if ((ListBox1.Items.Count <> 0) and
  (ListBox1.ItemIndex  = -1)) then
ListBox1.ItemIndex := 0;
DS.DataSet := SelectObjectFromList(ListBox1.ItemIndex);
try MemoUpdate(DS.Dataset); except end;
end;

    procedure TFormMDIDisplayDebug.FormKeyDown(Sender: TObject; var
  Key: Word; Shift: TShiftState);
begin
inherited;
if (Key=VK_ESCAPE) then
if MessageDlg('Close Form, ?', mtInformation,
  [mbYes, mbNo],0) = mrYes then;
close;
end;

    procedure TFormMDIDisplayDebug.MemoUpdate(DATASET : TDATASET);
    begin
      if DATASET = nil then exit;
      Memo1.Lines.Clear;
      if DATASET is Tquery then
        with TQuery(DATASET) do
          if Active then
            begin
              Memo1.Lines.Add(' DataBaseName : ' + DataBaseName);
              Memo1.Lines.Add(' ');
              Memo1.Lines.Add(Text);
              Memo1.Lines.Add('');
              Memo1.Lines.Add('Record Count : ' + IntToStr(RecordCount));
              if Filtered then Memo1.Lines.Add('Filter String : ' + Filter);
              if RequestLive then
                Memo1.Lines.Add('Request Live  : TRUE ')
              else
                Memo1.Lines.Add('Request Live  : FALSE ');
            end
          else
            Memo1.Lines.Add('In active Dataset ')
      else
        with TTable(DATASET) do
          if Active then
            begin
              Memo1.Lines.Add(' DataBaseName : ' + DataBaseName);
              Memo1.Lines.Add(' ');
              Memo1.Lines.Add('Record Count : ' + IntToStr(RecordCount));
              if Filtered then Memo1.Lines.Add('Filter String : ' + Filter);
            end
          else
            Memo1.Lines.Add(' InActive Dataset');
    end;

    procedure TFormMDIDisplayDebug.FormShow(Sender: TObject);
    begin
      Readparameters(1);
      ListBox1Click(Sender);
    end;

    procedure TFormMDIDisplayDebug.ReadPara(FComponentName :
  TComponent);
begin
if FComponentName = nil then exit;
ObjList := FComponentName;
ReadParameters(1);
end;

    procedure TFormMDIDisplayDebug.MNURefreshClick(Sender: TObject);
    begin
      if objList <> nil then ListBox1Click(Sender);
    end;

    procedure TFormMDIDisplayDebug.MNUCloseClick(Sender: TObject);
    begin
      close;
    end;

    procedure TFormMDIDisplayDebug.AssignSQL1Click(Sender: TObject);
var
strDatabaseName, prvDatabaseName, prvSQL,strSQL : string;
begin
if (SelectObjectFromList(ListBox1.ItemIndex) is TQuery) then
  with TQuery(DS.DataSet) do
if MessageDLG(' Do want to assign a New SQL
  Statement for this Query',mtInformation,[mbYes,mbNo],0) = mrYES then
begin
InputQuery('New SQL','Enter
  Databasename',strDatabaseName);
InputQuery('New SQL','Enter
  New SQL Statement',strSQL);
if (strDatabaseName
  <> '') and (strSQL <> '') then
begin
prvSQL := Text;
prvDatabaseName := DatabaseName;
Active := False;
SQL.Clear;
DatabaseName := strDatabaseName;
SQL.Add(strSQL);
Active := True;
end;
end;
end;

    procedure TFormMDIDisplayDebug.Filter1Click(Sender: TObject);
var
strprvfilterstring, nwfilterstring  : string;
boolfiltered   : Boolean;
begin
if DS.Dataset = nil then exit;
with SelectObjectFromList(ListBox1.ItemIndex) do
begin
strprvfilterstring := Filter;
boolfiltered := Filtered;
InputQuery('Enter Filter String',
  '',nwfilterstring);
try
filter := nwfilterstring;
if not boolfiltered then
  Filtered := true;
except
if boolfiltered then Filter
  := strprvfilterstring;
end;
end;
end;

    function TFormMDIDisplayDebug.SelectObjectFromList(intItemIndex :Integer): TDataset;
    var
      i : Integer;
    begin
      Result := nil;
      if intItemIndex = -1 then exit;
      with objList do
        begin
          for i := 0 to ComponentCount -1 do
            if ListBox1.Items[intItemIndex] = Components[i].Name then
              Result := TDataset(Components[i]);
        end;
    end;

    procedure TFormMDIDisplayDebug.TTable1Click(Sender: TObject);
    begin
      ReadParameters(2);
    end;

    procedure TFormMDIDisplayDebug.TQuery1Click(Sender: TObject);
    begin
      ReadParameters(3);
    end;

    procedure TFormMDIDisplayDebug.All1Click(Sender: TObject);
    begin
      ReadParameters(1);
    end;

    end.


Archiving Data in TTables and TQueries

 The Unofficial Newsletter of Delphi Users - by Robert Vivrette

Archiving Data in TTables and TQueries

Matt Hamilton - mhamilton@bunge.com.au

I've used this in my own projects a few times, and I thought it was worth sharing. It is a nice method to archive your database.

Often it is necessary to put in place some sort of backup or archive procedure. If you are unlucky and don't have 3rd-party backup programs, then you might want to build it into your app. I have done this in several apps by copying the necessary data to "CSV" (comma separated value) files.

Here is the idea: You collate all the fields you want to save into a query, then write the entire query off to a CSV file. At some later date you can 'pipe' the data back in either by using a TBatchMove component, or simply reversing the technique shown here.

Anyway, the code:

    procedure TForm1.ArchiveToFile(AFilename: string);
    var
       F: TextFile;
       FieldStrings: TStringList;
       i: Integer;
    begin
       { Open the file to append data to, creating if necessary }
       AssignFile(F, AFilename);
       if FileExists(AFilename) then Append(F) else Rewrite(F);
       { ArchiveQry is the TQuery with all the info to archive }
       with ArchiveQry do
         begin
           Open;
           try
             { We use a TStringList for its nifty "CommaText" property }
             FieldStrings := TStringList.Create;
             try
               First;
               while not Eof do
                 begin
                   FieldStrings.Clear;
                   for i := 0 to FieldCount - 1 do
                      FieldStrings.Add(Fields[i].AsString);
                   WriteLn(F, FieldStrings.CommaText);
                   Next;
                 end;
             finally
               FieldStrings.Free;
             end;
           finally
             Close;
           end;
         end;
       CloseFile(F);
    end;
And there you have it! This procedure copies all the data in ArchiveQry to a file whose name is specified in the parameter AFilename. After you have copied it out, you could prompt the user to delete the real data, or flag it as archived, or whatever.

Cheers!


Highlighting Edit Boxes

The Unofficial Newsletter of Delphi Users - by Robert Vivrette

Highlighting Edit Boxes

by Eamonn Mulvihill - ucs@cableinet.co.uk

Herbert J. Beemster's article Give Your Editbox Some Attention! derived an edit box that display an extra border when it has focus. Great idea, but a real pain in the #!$e deriving a new control every time you wanted to add that functionality.

That set me thinking about an idea i had ages ago - to trap delphi's Cn_FocusChanged message, and draw a border around any control that has just received the focus.

Attached is the control TucsFocus (delphi 3) - basically it waits for a control to send out a Cn_FocusChanged message, and then resizes itself and positions inself *under* the focused control to produce a border effect.

To place the TucsFocus under and control on a form, it is necessary to change it's parent - this caused a problem because when the message handler is active, the parent is looping through it's controls list to notify all it's children, so changing the parent in the message handler resulted in an index out of bounds exception. To handle this i had to post a WM_USER message to the control which would then be processed after all of the parent's children had been notified. It is the WM_USER message handler that does all the work.

I've added two properties: Color (naturally) and BorderSize (the width of the border).

I dare say it could be improved - for instance not using the WM_USER message - but i hope some of you find a use for it.

Eamonn Mulvihill
Consultancy and programing services

    unit ucsFocus;

    {

    TucsFocus by Eamonn Mulvihill of Update Computer Services.

    This control uses delphi's notification message cm_FocusChanged
    to follow the focus around the form.  When a control receives
    focus, it paints a bold border around it, basically by resixing
    itself and placing itself behind the focused control.

    This source is free for any use, but i would appreciate a mention
    in any controls that are derived from it.

    }

    interface

    uses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

    type
TucsFocus = class(TCustomControl)
private
fBorderSize : integer;
protected
procedure CMFocusChanged(var msg:TCMFocusChanged);
  message Cm_FocusChanged;
procedure MSGAfterFocus(var msg:TCMFocusChanged);
  message WM_USER;
procedure Paint; override;
public
constructor Create(AOwner:TComponent); override;
published
property Color;
property BorderSize:integer read fBorderSize write
  fBorderSize;
end;

    procedure Register;

    implementation

    //set property defaults
    constructor TucsFocus.Create(AOwner:TComponent);
    begin;
    inherited create(AOwner);
    width  := 20;
    height := 20;
    color  := clBtnShadow;
    BorderSize := 3;
    end;

    //paint the control
    procedure TucsFocus.Paint;
    begin;
    inherited;
    with canvas do
      begin;
      //draw filled rectangle
      brush.color := color;
      FillRect(ClientRect);
      //a little extra in design mode
      if csDesigning in ComponentState then
        begin;
        pen.color := clBlack;
        rectangle(0,0,width,height);
        font.name := 'Arial';
        font.size := 11;
        font.style := [fsBold];
        TextOut(6,1,'F');
        end;
      end;
    end;

    //Delphi is currently looping throught the parent's controls list.
    //Canging the parent here will cause an exception, so post a USER
    //message, which will be processed after all controls have been
    //processed.
    procedure TucsFocus.CMFocusChanged(var msg:TCMFocusChanged);
    var UserMsg:TMessage;
    begin;
    UserMsg := TMessage(msg);
    UserMsg.msg := WM_USER;
    PostMessage(handle,WM_USER,UserMsg.wParam,UserMsg.lParam);
    end;

    //OK, now we can move the TucsFocus, size it and change the parent
  too!
procedure TucsFocus.MSGAfterFocus(var msg:TCMFocusChanged);
var rect :TRect;
begin;
try
//calculate size and position
rect := msg.Sender.BoundsRect;
rect.left   := rect.left   - BorderSize;
rect.top    := rect.top    -
  BorderSize;
rect.right  := rect.right  + BorderSize;
rect.bottom := rect.bottom + BorderSize;
BoundsRect := rect;
//and change parents
parent := msg.Sender.parent;
SendToBack;
finally
inherited;
end;
end;

    procedure Register;
    begin
      RegisterComponents('U.C.S', [TucsFocus]);
    end;

    end.


Enhanced StatusBar Component

 The Unofficial Newsletter of Delphi Users - by Robert Vivrette

Enhanced StatusBar Component

by Kevin S. Gallagher - gallaghe@teleport.com

I developed this component as a jumping off point to investigate other enhancements to the status bar component in general. In case you haven't worked with StatusBar's much, the sizegrip may appear in certain circumstances where you don't want it. This component corrects that behavior and also adds the interesting effect that you can drop other components (i.e. buttons) onto the status bar. It generates some interesting possibilities.

Please email me if you have comments or ideas about further enhancements!

     unit NoSizeGripBar;
    {*****************************************************************}
    {                                                                 }
    { Enhanced freeware StatusBar component                           }
    { By Kevin S. Gallagher                                           }
    {                                                                 }
    { Accepts other components, i.e. buttons                          }
    { Removes SizeGrip on non-sizable forms                           }
    {                                                                 }
    { abnormalities                                                   }
    { 1. You can not toggle the SizeGrip property                     }
    { 2. If you attempt to change the SizeGrip property in the Object }
    {    Inspector on a non-sizeable form, the SizeGrip may appear.   }
    {    This does not alter runtime behavior, it still works.        }
    {=================================================================}
    { USE TDialogStatusbar AT YOUR OWN RISK.                          }
    { I AM NOT RESPONSIBLE FOR ANY HARM THIS COMPONENT MIGHT CAUSE!!  }
    {                                                                 }
    { Kevin S. Gallagher                                              }
    { E-Mail : Gallaghe@teleport.com                                  }
    {                                                                 }
    {*****************************************************************}
    interface

    uses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      ComCtrls, DsgnIntf;

    type
TAbout = class(TPropertyEditor)
public
procedure Edit; override;
function GetAttributes: TPropertyAttributes;
override;
function GetValue: string; override;
end;

      TDialogStatusbar = class(TStatusBar)
private
FAbout: TAbout;
FSizeGrip: Boolean;
procedure SetUpSizeGrip;
protected
procedure CreateParams(var Params:
TCreateParams); override;
public
constructor Create(AOwner: TComponent);
override;
published
property About: TAbout read FAbout
write FAbout;
end;

    procedure Register;

    implementation

    uses Commctrl;

    procedure TAbout.Edit;
    begin
      Application.MessageBox('TDialogStatusbar component'  + #13 +
      '© 1998 Kevin S. Gallagher - This component is freeware.',
      'About TDialogStatusbar Component', MB_OK + MB_ICONINFORMATION);
    end;

    function TAbout.GetAttributes: TPropertyAttributes;
    begin
      Result:= [paMultiSelect, paDialog, paReadOnly];
    end;

    function TAbout.GetValue: string;
    begin
      Result:= '(about)';
    end;

    constructor TDialogStatusbar.Create(AOwner: TComponent);
    begin
      { Try dropping onto a data form }
      if not(AOwner is TForm) then
        raise EInvalidOperation.Create('Must be owned by a standard form');

      inherited Create(AOwner);

      FSizeGrip := False;

      { This allows you to drop things like labels, editboxes, gauges, button etc
        onto the StatusBar }
      ControlStyle := ControlStyle + [csAcceptsControls];

      SetUpSizeGrip;
    end;

    procedure TDialogStatusbar.SetUpSizeGrip;
    begin
      { Check to see if this is a sizeable form or not }
      with Owner as TForm do
        FSizeGrip :=  not(BorderStyle in [bsToolWindow,
                                          bsDialog,
                                          bsNone,
                                          bsSingle]);
      SizeGrip := FSizeGrip;
    end;

    { Must setup the SizeGrip here }
    procedure TDialogStatusbar.CreateParams(var Params: TCreateParams);
    begin
      inherited CreateParams(Params);
      CreateSubClass(Params, STATUSCLASSNAME);

      with Params do begin
{ This is needed to finalize our
task }
SetUpSizeGrip;
if FSizeGrip then
Style := Style or
SBARS_SIZEGRIP
else
Style := Style or
CCS_TOP;
WindowClass.style := WindowClass.style
and not CS_HREDRAW;
end;
end;

    procedure Register;
    begin
      RegisterComponents('Win32', [TDialogStatusbar]);
      RegisterPropertyEditor(TypeInfo(TAbout), TDialogStatusbar, 'ABOUT', TAbout);
    end;
    end.


Drop File Helper Components

The Unofficial Newsletter of Delphi Users - by Robert Vivrette

Drop File Helper Components

by Grahame Marsh - gsmarsh@aol.com

These simple components were written to provide an easy way for a Delphi form or individual control to receive files dropped on to it. An another component is used to retrieve files dropped onto the application's icon, from say Explorer, triggering the same events as for a form or control.

The components encapsulate a number of Win32 API calls (found in ShellAPI.pas) :

    type
HDROP = Longint;
function DragQueryFile(Drop: HDROP; FileIndex: UINT; FileName: PChar;
  cb: INT): INT; stdcall;
function DragQueryPoint(Drop: HDROP; var Point: TPoint): BOOL;
  stdcall;
procedure DragFinish(Drop: HDROP); stdcall;
procedure DragAcceptFiles(Wnd: HWND; Accept: BOOL); stdcall;

You use the DragAcceptFiles call first to inform windows that the control will accept dropped files. When you are dragging a file over this control the cursor changes to show that the control can accept the drop. DragQueryFile is used to retrieve the filename or names, and the count of files available. DragQueryPoint returns to coordinates of the drop point. And finally, when you are finished retrieving information you call DragFinish.

The component interface looks like this:

    type
TDnDStartEvent = procedure (Sender: TObject; Count, X, Y:
  integer) of object;
TDnDItemEvent = procedure (Sender: TObject; const Item: string)
  of object;

      TCustomDnD = class (TComponent)
private
FParent: THandle;
FActive: boolean;
FOnDnDStart: TDnDStartEvent;
FOnDnDItem: TDnDItemEvent;
FOnDnDFinish: TNotifyEvent;
procedure SetActive (Value : boolean);
public
property Active: boolean read FActive write
  SetActive;
property OnDnDStart: TDnDStartEvent read
  FOnDnDStart write FOnDnDStart;
property OnDnDItem: TDnDItemEvent read FOnDnDItem
  write FOnDnDItem;
property OnDnDFinish: TNotifyEvent read
  FOnDnDFinish write FOnDnDFinish;
end;

This custom interface is never used directly, it simply contains the three events common to all of the functional drag and drop components. When files are dropped the events fire in turn - OnDnDStart, then OnDnDItem for each filename and then OnDnDFinish when all file events have been triggered. The Active property can be used to turn on and off the drop capabilities.

The interface of the usable components are:

    type
      TDnDRun = class (TCustomDnD)
      protected
        procedure Loaded; override;
      public
        procedure Execute;
      published
        property Active;
        property OnDnDStart;
        property OnDnDItem;
        property OnDnDFinish;
      end;

      TDnDForm = class(TCustomDnD)
      private
        FOldDnDefWndProc,
        FNewDefWndProc: pointer;
        procedure NewDefWndProc (var Msg: TMessage);
      protected
        procedure Loaded; override;
      public
        constructor Create (AOwner: TComponent); override;
        destructor Destroy; override;
      published
        property Active;
        property OnDnDStart;
        property OnDnDItem;
        property OnDnDFinish;
      end;

      TDnDControl = class(TDnDForm)
private
FControl: TWinControl;
procedure SetControl (Value: TWinControl);
protected
procedure Loaded; override;
procedure Notification(AComponent: TComponent;
  Operation: TOperation); override;
published
property Control: TWinControl read FControl write
  SetControl;
end;

In each case, the Create and Loaded methods make the necessary API calls so that the control will receive dropped files.

The TDnDRun component is a bit of a cheat in that it only uses ParamCount and ParamStr to return items found on the command line. But it uses the same events interface so I would hope some common code can be used for handling these events.

One final comment is that since the API call to DragAcceptFiles requires a windows handle, then non-windowed visual controls cannot be used to accept dropped files.

The zip file contains the complete source, dcr file and a simple demo. Click here to download it.

Enjoy!


Delphi Users Groups

If you run a Delphi Users Group that is not on this list, please feel free to send me an email with the essentials. Please include basic information about where and when the group meets, and particularly any web links you may have to support the group. I am going to keep the info to a minimum so I can include in each issue (or maybe every other issue). I have provided a sample form to help you provide the right information.

Arizona

    Tucson Delphi Users Group - TDug
California
    Orange County Delphi Users Group
    North Bay Delphi SIG
    Delphi SIG of the Sacramento PC User Group
Canada
    Metro Halifax Delphi Developers Group
    The Toronto Area Delphi Developers Association
    Vancouver Delphi Developers Association
Colorado
    Western Slope Visual Developers Group
    Denver Borland Users Group
Iowa
    Central Iowa Delphi Users Group
Kansas
    Kansas City Delphi Users Group
Massachusetts
    The Delphi Developers Group of Greater Boston
Minnesota
    TCPC Delphi SIG
Michigan
    Royal Oak Delphi Users Group
North Carolina
    Research Triangle Park Delphi Users Group
Ohio
    Delphi SIG of the Greater Cleveland PC Users Group
    Columbus Delphi SIG
    Greater Dayton Delphi Group
Oregon
    Oregon Delphi Users Group
Pennsylvania
    Pittsburgh Area Delphi Users Group
    Borland Technologies User Group
Utah
    Salt Lake City Delphi Users Group


Tucson Delphi Users Group

Group Name: | Tucson Delphi Users Group - TDug
Person(s) in Charge: | Matthew J. Brock, Oscar Speed
Meeting Date/Time: | Third Saturday of each month, 9:00am-10:00am
Meeting Location: | DRA Software Training Center, 3434 E. 22nd St. Suite 100, Tucson, AZ
Dues: | Free
Email Address: | mjb@azstarnet.com
Phone Number: | 520-571-7203
Internet URL: |
Description: | One or more presentations, Q&A, Product Reviews


Orange County Delphi Users Group

Group Name: | Orange County Delphi Users Group
Person(s) in Charge: | Greg Stevenson
Meeting Date/Time: | Fourth Tuesday of each month at 7:00 pm
Meeting Location: | See Web Site
Dues: | See Web Site
Email Address: | See Web Site
Phone Number: | See Web Site
Internet URL: | http://www.ocdelphi.org
Description: |


North Bay Delphi Special Interest Group

Group Name: | North Bay Delphi Special Interest Group
Person(s) in Charge: | Bjarne Winkler
Meeting Date/Time: | Second and Fourth Wednesday of each month from 7:00 pm to 9:00 pm
Meeting Location: |
Dues: |
Email Address: | nts4618086@aol.com
Phone Number: |
Internet URL: |
Description: | Announcements, Q&A, Special topics each meeting.


Delphi SIG of the Sacramento PC User Group

Group Name: | Delphi SIG of the Sacramento PC User Group
Person(s) in Charge: | Robert Muir, Mike Prestwood
Meeting Date/Time: | 2nd Monday of the Month - 6:30pm
Meeting Location: | New Horizons Building, 1215 Howe Avenue, Sacramento, CA
Dues: | None
Email Address: | robertmuir@worldnet.att.net or mike@prestwood.com
Phone Number: |
Internet URL: | www.prestwood.com/forums/delphi/sdug
Description: | Announcements, Q&A, Special Topics each meeting


Metro Halifax Delphi Developers Group

Group Name: | Metro Halifax Delphi Developers Group
Person(s) in Charge: | Dave Hackett
Meeting Date/Time: | First Tuesday of each month from 7:00 pm to 9:00 pm
Meeting Location: | Maritime Life Business Park
Dues: | None
Email Address: | 71650.2646@compuserve.com
Phone Number: |
Internet URL: |
Description: | News, Q&A, Presentations


Toronto Area Delphi Developers Association

Group Name: | Toronto Area Delphi Developers Association (TaDDA!)
Person(s) in Charge: | Henri Fournier (President), Robert Kozak (Membership Director), Ted Nye (Executive Director)
Meeting Date/Time: | First Tuesday of each month
Meeting Location: | North Youk Public Library, Toronto, Ontario, Canada
Dues: | $60/year
Email Address: | membership@TaDDA.com
Phone Number: | 416-366-7150
Internet URL: | http://www.tadda.com
Description: | 3 Hours. Sessions by well known Delphi experts such as Mark Miller, Ray Konopka, Charlie Calvert, etc. and in depth sessions on all aspects of Delphi for New to Advanced users.


Vancouver Delphi Developers Association

Group Name: | Vancouver Delphi Developers Association
Person(s) in Charge: | Michael Li
Meeting Date/Time: | Third Wednesday of each month, 6:30pm
Meeting Location: | Liquor Distribution Branch, 2625 Rupert Street, Vancouver, BC
Dues: | None
Email Address: | mli@infocan.com
Phone Number: | 604-736-5888 x728
Internet URL: | http://www.infocan.com
Description: | Michael Li is usually the main speaker at meetings. Informal setting. Michael's main focus is on Delphi and Borland related topics and discussion, updates on new technology (hardware, software) coming out to the market, updates on books that are useful to particular products (provide evaluation copies for review), information on conferences coming up in Vancouver. May have guest speakers depending on the topic.


Western Slope Visual Developers Group

Group Name: | Western Slope Visual Developers Group
Person(s) in Charge: | Shane Holmes, Software Engineer, ViA Software Services
Meeting Date/Time: | Last Wednesday of each month, 6:30pm
Meeting Location: | ViA Software Services, 743 Horizon Court, Suite 368, Grand Junction, CO 81506
Dues: | None
Email Address: | sholmes@viagj.com
Phone Number: | 970-257-7010, 970-248-9733
Internet URL: | http://www.gj.net/~hap
Description: |


Denver Borland Users Group

Group Name: | Denver Borland Users Group (DeBUG)
Person(s) in Charge: | Ron Kocsis, Chuck Gadd
Meeting Date/Time: | 6:30pm, 2nd Tuesday of the Month
Meeting Location: | Suite #1350 at 5299 E. Prentice Ave, Greenwood Village, CO
Dues: | $30/year
Email Address: | cgadd@cfxc.com
Phone Number: | 303-933-4159
Internet URL: | www.fcxc.com/debug
Description: | Presentation by members or third-party companies.


Central Iowa Delphi Users Group

Group Name: | Central Iowa Delphi Users Group
Person(s) in Charge: | David W. Body
Meeting Date/Time: | Third Thursday of every month at 5:30 pm
Meeting Location: | Offices of Iowa Bankers Association, Liberty Building, 418 6th Ave. Suite 430, Des Moines, Iowa.
Dues: | None
Email Address: |
Phone Number: | 515-984-6243
Internet URL: | http://www.bigcreek.com/delphi
Description: |


Kansas City Delphi User Group

Group Name: | Kansas City Delphi User Group
Person(s) in Charge: | Shawn McDonald, Kerri VanMevern
Meeting Date/Time: | 1st Wednesday of each month, 6:30pm
Meeting Location: | DRT Systems, 4501 College Blvd., Leawood, KS
Dues: | $24/year
Email Address: | mofnet@aol.com
Phone Number: | 913-661-9669 x265
Internet URL: | http://www.kcdelphi.org
Description: | Flexible format includes presentations by members, code reviews, and question and answer


Delphi Developers Group of Greater Boston

Group Name: | Delphi Developers Group of Greater Boston
Person(s) in Charge: | Al Renhart, DisCom Systems
Meeting Date/Time: | Third Monday of each month, 7:00 pm
Meeting Location: | 10 New England Executive Park, Burlington, MA
Dues: |
Email Address: | reinhart@discom.com
Phone Number: | 508-869-6417
Internet URL: |
Description: |


TCPC Delphi SIG

Group Name: | TCPC Delphi SIG
Person(s) in Charge: | Richard Hansen
Meeting Date/Time: | 4th Wednesday of Month, 7pm
Meeting Location: | 2850 Metro Drive, Room 124 - Bloomington, MN
Dues: | None
Email Address: | rickh@artemisalliance.com
Phone Number: | 612-227-7172
Internet URL: | http://www.tcpc.com
Description: | Questions & Answers, Monthlu topic, Focus Groups.


Royal Oak Delphi Users Group

Group Name: | Royal Oak Delphi Users Group
Person(s) in Charge: |
Meeting Date/Time: | First Thursday of each month at 7:00 pm
Meeting Location: | William Beaumont Hospital (Lower Level), Royal Oak, MI. Classrooms in AB-West building.
Dues: | None
Email Address: |
Phone Number: | 810-551-5000
Internet URL: | http://ourworld.compuserve.com/homepages/STNICOL/
Description: | Constructing DLL's, SQL Server 6.5, CGI, Email enabled databases, data collection alternatives, VCL parties, book review night, etc.


Research Triangle Park Delphi Users Group

Group Name: | Research Triangle Park Delphi Users Group
Person(s) in Charge: | Mark Hutchinson
Meeting Date/Time: | Third Wednesday of each month, 5:00 pm
Meeting Location: | New Horizons Computer Learning Center - Willow Oak Bldg, Suite 116, 4625 Creekstone Drive, Durham, NC
Dues: |
Email Address: | aikimark@aol.com
Phone Number: |
Internet URL: | http://www.geocities.com/CapeCanaveral/Lab/1185/rtpdig.html
Description: |


Delphi SIG of the Greater Cleveland PC Users Group

Group Name: | Delphi SIG of the Greater Cleveland PC Users Group
Person(s) in Charge: | Bill Querry
Meeting Date/Time: | Fourth Wednesday of each month, 6:30 pm - 8:30 pm
Meeting Location: | 2747 SOM Center Rd, Willoughby OH 44094
Dues: | Free for Meetings. $25/year for GCPCUG
Email Address: | bq@bigfoot.com
Phone Number: | 440-944-9980
Internet URL: | http://www.gcpcug.org
Description: | Demos of some feature of Delphi or 3rd Party Add-On. General discussion of user's current projects & problems. Talk about latest magazines/book releases.


Columbus Delphi SIG

Group Name: | Columbus Delphi SIG
Person(s) in Charge: | Rick Ross
Meeting Date/Time: | 2nd Wednesday of every month. 7-9pm
Meeting Location: | 1091 W. Broad St., Columbus, OH
Dues: | None
Email Address: | rickross@compuserve.com
Phone Number: | 614-898-2767
Internet URL: |
Description: | Demonstrations, discussion, and training


Greater Dayton Delphi Group

Group Name: | Greater Dayton Delphi Group (GDDG)
Person(s) in Charge: | Keith Wire
Meeting Date/Time: | Second Thursday of each month
Meeting Location: | Dayton, OH
Dues: | $50/Year
Email Address: | kwire@compuserve.com
Phone Number: |
Internet URL: | http://www.aii-usa.com/gddg
Description: | Sharing of Delphi-related information


Oregon Delphi Users Group

Group Name: | Oregon Delphi Users Group
Person(s) in Charge: | Greg Postlewaite
Meeting Date/Time: | 3rd Monday of every month, 7pm
Meeting Location: | Lorenzen Center, Emanuel Hospital, Portland, OR
Dues: |
Email Address: |
Phone Number: |
Internet URL: |
Description: |


Pittsburgh Area Delphi Users Group

Group Name: | Pittsburgh Area Delphi Users Group
Person(s) in Charge: | Kirk A. Farra
Meeting Date/Time: | Second Thursday of the month at 7:00 pm
Meeting Location: | Mastech Inc.
Dues: | None
Email Address: |
Phone Number: | 412-452-6121
Internet URL: | http://www.nauticom.net/www/kfarra
Description: | We cover Delphi and any related products/tools. Members are exposed to many 3rd party components and have a local support network for Q/A. Members get to review many products before they are released and get information on local job opportunities and contracting positions.


Borland Technologies User Group

Group Name: | Borland Technologies User Group
Person(s) in Charge: | Matt Beckius
Meeting Date/Time: | Undetermined (we are just forming now)
Meeting Location: | Philadelphia, PA
Dues: | Undetermined
Email Address: | Undetermined
Phone Number: | 610-409-8229 extension 8
Internet URL: | http://www.sourcetechcorp.com/borland.htm
Description: | Product Reviews, Demonstrations, Discussions


Salt Lake City Delphi Users Group

Group Name: | Salt Lake City Delphi Users Group
Person(s) in Charge: | Robert Love, John Rendell, Mike Mormondo
Meeting Date/Time: | 3rd Thursday of every month
Meeting Location: | Franklin Covey Headquarters
Dues: | None
Email Address: | slcdug@lovedata.com
Phone Number: | 801-296-0809
Internet URL: | http://www.lovedata.com/delphislc
Description: | Each meeting is different but usually it is a presentation of a new idea or product that relates to delphi. There is a Q/A Session in every meeting to help you move along as well.


Form For Users Groups

If your Delphi Users Group is not mentioned in the list, please take a moment to email me the particulars about your group. To make the information as uniform as possible, please cut and paste this form into an email and send it to me at RobertV@compuserve.com. Please only send one if you are in charge of the group… I don't want to have to wade through 30-40 copies for each group… Thanks!

Group Name:
Person(s) In Charge:
Meeting Date/Time:
Meeting Location (include City & State):
Dues:
Email Address:
Phone Number:
Internet URL:
Brief description of meeting format:


 The Delphi Workout
  • Professional Delphi Training for Under £100
  • One of the World's leading Delphi Trainers
  • Great sessions to enhance your Delphi Skills
  • FREE Full 170 page course book
  • FREE Developers CD with over 1200 tools and components
  • FREE £600 off Borland Tools
  • Sessions in London (Westminster Hall) and Manchester (United Football Club)

    • Zack Urlocker (Borland VP Marketing) says: "A must for Developers who want to take their Delphi skills to the next level. Highly recommended"

    To register:

    Phone:      0800 833022
    Fax back:   0118 954 6978
    E-Mail:     workout@multizone.com
    On-Line:    http://www.multizone.com/workout
    Mail:       The Delphi Workout
                Multizone International
                Caversham Business Centre
                23 Prospect St, Caversham, RG4 8JB.
    When:       19th, 20th March 1998 and other dates TBA

    Course Outline:

    8.30-9.00 Registration

    9.00-9.30 Warming up
    In this section we'll discuss some generic tips to working with Delphi 2 including some focus on exciting new methods of working in Delphi 3

    9.00-9.30 - Delphi Overview
    Delphi 2&3, ObjectPascal, Code Insights, Components, BDE. This session will give a very quick overview of some 32-bits Delphi features, such as Code Insights, the VCL Component Palette/Packages, Data Modules, Form Inheritance, ActiveX controls, and the Database-Form Wizard, etc.

    9.30-10.45 The Top 10 Ways to becoming a better Delphi Programmer
    In this section we'll focus on ObjectPascal, exception handling, and performance optimization, positioning most of this on Delphi 2, but highlighting new better ways to do it in Delphi 3 as well

    9.30 -10.00 - ObjectPascal
    ObjectPascal, Exceptions, Try-Except, Try-Finally, Raise, Assert. This session will start with new ObjectPascal features, followed by the benefits of structured exception handling as the preferred way of error detection, error handling and resource management. All Delphi 2 compatible. At the end of the session, we'll also examine a new Delphi 3 feature called assertions, to support preconditions and error detection.

    10.00-10.45 - 32-bits Efficiency
    Profiling, Algorithms & Datastructures, Language Features. This session will identify the steps of performance optimization: finding bottle-necks, checking algorithms & datastructures, and new 32-bits Delphi language features. A number of examples will illustrate what difference it can make in performance to know and apply the tips and techniques from this session.

    10.45-11.00 Coffee

    11.00-12.30 The Top 10 Secrets to building Rapid Applications
    In this section we'll focus on the developer and his building tools (components, packages and Delphi IDE experts/wizards) to help building Rapid Applications.

    11.00-11.45 - Component Building
    Component Wizard, Properties, Methods, Events. This session will teach the basics of component building, as we focus on the Component Wizard, followed by the creation of a component skeleton, the addition of properties, methods, events and event handlers. We'll move on by installing the component in the Component Palette, or in a Delphi 3-specific package

    11.45-12.00 - Delphi 3 Packages
    Design Time, Run Time, Deployment, Versioning. This session will explain what Delphi 3 packages are, how they can benefit our projects (size of executable), how to make our own custom packages with components, and how to deploy them correctly.

    12.00-12.30 - Experts and Wizards
    IDE, Open Tools API, Experts, Wizards. This session will show how to extend the Delphi IDE itself by using the Open Tools API to write Experts (that plug into the IDE) and Wizards, including some User Interface guidelines for writing Wizards.

    12.30-13.30 Lunch

    13.30-14.00 Unleashing the hidden power of Databases within Delphi
    BDE, Tables, Queries, data-aware components. This session will show the database basics, including tables, queries, data-aware components and how to (re-) create your own tables with ObjectPascal source code.

    14.00-14.45 - The Best of Delphi (UK-BUG)
    A Borland User Group representative will highlight how to unearth the most comprehensive guide (the DIL database) where to find free Delphi Code,
    tools, samples and support.

    14.45-17.00 Building Killer Web Applications
    In this section we'll start by seeing how we can use Delphi 2 for data-aware net development, followed by some next exciting techniques and net development support in Delphi 3.

    14.45-15.10 - Table to HTML
    HTML, Tables, Image Map, Table-layout, Index Fields, Frames. This session will shortly introduce the basic concepts of HTML, followed by a Wizard that can be used to convert the contents (records) of a table to a set of static HTML-pages that can be uploaded to the web.

    15.10-15.30 - CGI and WinCGI
    CGI/WinCGI, GET/POST, State, Debugging CGI. This session will extend our HTML knowledge with the Common Gateway Interface protocol, which is a way to interact between the web client and the web server. Delphi 2 compatible.

    15.30-15.45 Afternoon Tea

    15.45-16.15 - Delphi 3 ActiveForms
    New ActiveForm, Converting existing Forms, Deployment. This session will illustrate how to write, use and deploy ActiveForms on the web, including an example where we publish a table on an ActiveForm on the Internet.

    16.15-17.00 - Delphi 3 C/S WebModules
    WebModule, Dispatcher, PageProducer, TableProducers. This session will demonstrate the Delphi 3 Client/Server-only capabilities of the Web Modules to create and support CGI/WinCGI and ISAPI/NSAPI web server applications, including an example where we connect a database to the web, with options to browse, query and update the database contents.

    17.00-17.30 Cooling Down

    17.00-17.30 - The Future of Delphi (Borland)
    A Borland Product Manager will talk to the audience for half an hour on the future of Delphi... and answer questions from the audience.


Product Reviews & Announcements

I have moved all the announcements and reviews of books, and other Delphi related products to this page. If you have a product you would like to see reviewed, or wish to do a review yourself, please feel free to contact me at RobertV@csi.com.

03/25/98 - WinHelp Office Review
Issue #24 - A Second Look at MicroEdge's Visual SlickEdit
Issue #23 - Book Review: Hidden Paths of Delphi 3
Issue #23 - Book Review: Building Delphi 2 Database Applications
Issue #23 - Raize Components
Issue #22 - Programmers Guild Animated Tray Icon
Issue #22 - MicroEdge's Visual SlickEdit
Issue #22 - IniOut Component
Issue #22 - Addict 2.2 Spell Checker for Delphi
Issue #21 - Book Review: Delphi Component Design
Issue #20 - Delphi Books and Periodicals
Issue #19 - SpeedDaemon Code Profiler
Issue #19 - A Look at MagiKit
Issue #18 - Object Express by OopSoft
Issue #18 - Announcement: IniOut Component
Issue #18 - Book Review: Delphi Component Design by Danny Thorpe

More links to come! To see the material in Issues 1 through 17, click here.


Delphi Job Sites

Below are some of the Delphi Job sites currently available. If you know of others, please let me know about them and I will add a link on this page.

    Employment at Borland/Inprise
    http://www.borland.com/about/hr/

    Borland/Inprise Delphi Jobs Newsgroup
    news://forums.inprise.com/borland.public.delphi.jobs

    Delphi Job Hunter
    http://www.inthemiddle.co.uk/jobhunter/delphi/default.htm

    Mike Strock's Delphi Jobs Site
    http://www.oz.net/~mstrock/delphijobs.html

    Greg Postlewait's Delphi Jobs Site
    http://www.teleport.com/~gpost/djobs

    Richard Fellner's Delphi Job Exchange
    http://www.user.xpoint.at/r.fellner/DELPHIJ.HTM

    Richard Maley's Delphi Jobs Service
    http://www.advdelphisys.com/jobs/jobs_all.html

    Becker Technology, Inc.
    http://www.beckertechnology.com/emplopps.htm

Additional Programming-Related Job Sites
    Jobs for Programmers
    http://www.prgjobs.com

    JobServe UK
    http://www.jobserve.com


The Unofficial Newsletter of Delphi Users - News

News Page

June 30, 1998

In under the wire... Two new articles: The first is from Kevin Gallagher on Extending the StatusBar component. Pretty neat stuff. Also today, a great article by Grahame Marsh on helper components for dragging and dropping files to and from your Delphi apps. You can read all about it in Drop File Helper Components. This is one of the more requested capabilities I get from readers, so I am glad Grahame put this together!

Also, I am integrating the Articles page into the Tips & Tricks page. Sometimes it is hard to determine what is an "article" and what is a "tip or trick". Better to put them in one spot I suppose...

June 26, 1998

Added the new Delphi Job Sites link on the UNDU home page. Thanks to everyone for their excellent input on this. Remember, everything that someone submits to me that I use on the site is entered in the random prize drawing at the end of each month. So everyone who submitted a Delphi Jobs site will be in this months drawing! If anyone knows of others that aren't listed, please let me know!

There also was some confusion about how to email me, so I have added an email link button as well.

June 16, 1998

Atanas Stoyanov - astoyanov@nidlink.com has announced the release of a free Memory and Resource leaks debugger called MemProof. You can learn more about this product at his web site: http://www.nidlink.com/~astoyanov/index.htm.

I have received a significant number of emails lately regarding Delphi Job positions. Currently, I am aware of only one Delphi-only Job Site (http://www.inthemiddle.co.uk/jobhunter/delphi/default.htm). If you know of any others, please let me know and I will group them together here for everyone to see.

Also today, Eamonn Mulvihill (I spelled it right this time...) presents an interesting extension to a previous article about highlighting edit boxes that have the focus. His alternate method is called Highlighting Edit Boxes.

And lastly, Matt Hamilton shows a simple technique for archiving data in Tables or Query's out to a Comma-Separated text file. His article is entitled Archiving Data in TTables and TQueries.

June 15, 1998

Don't worry... things will be smoothing out here shortly... I am in the last 2-3 weeks of building our new house (in the lot adjacent to the one we are living in), so it is quite a distraction for me lately. I am planning on getting back to my 2-3 updates a week schedule pretty darn soon...

You have all probably been checking in loyally to see who the randomly selected winner is this month. Well, the winner is... (drum roll...) Alexander Mehlhorn for his article on Dynamically Loading Packages at Runtime. Alexanders prize is a copy of Hidden Paths of Delphi 3, an excellent book by Ray Lischner illustrating the techniques needed to develop experts, wizards, and more using the Open Tools API in Delphi. Remember folks, each month, I randomly select one contributor for that month to receive a prize. During the month of May, there were 6 contributors, so it was just a 1 in 6 chance. Also, most months I will award more than one prize... just depends what I have on hand! Doesn't matter what you contribute. If I use it, you are in the drawing!

Now on to the new stuff...

Jaffar Sulemani brings us an interesting debugging component that allows you to browse through any Table or Query in your application at runtime. Often times we may be inclined to throw a grid on a form just so we can see what is happening while the code is running. Jaffar's solution puts an end to that... Check it out in Sneaking a Peek at Data-Access Components.

Grahame Marsh put together an extension of Jorge Turiel's article on multi-line hints. Grahame presents... The MultiLine Hint Property Editor!

In order to keep the size of the News Page to a minimum, I will be archiving previous months and listing them at the bottom.
News Page for May, 1998
News Page for April, 1998
News Page for March, 1998
News Page for February, 1998


The Unofficial Newsletter of Delphi Users - Past UNDU Issues

Past UNDU Issues

Below are links to all the issues of UNDU that are currently available to read online. If you want to obtain these same issues in a downloadable format, please check the section on Downloadable UNDU Issues.

Issue #24 - December '97
Issue #23 - September '97
Issue #22 - June '97
Issue #21 - May '97
Issue #20 - March '97
Issue #19 - January '97
Issue #18 - November '96
Issue #17 - October '96
Issue #16 - September '96
Issue #15 - August '96
Issue #14 - June '96
Issue #13 - May '96
Issue #12 - February '96
Issue #11 - January '96
Issue #10 - December '95
Issue #9 - November '95
Issue #8 - October '95
Issue #7 - August '95
Issue #6 - July '95
Issue #5 - June '95
Issue #4 - May '95 (b)
Issue #3 - May '95 (a)
Issue #2 - April '95
Issue #1 - March'95


The Unofficial Newsletter of Delphi Users - Downloadable UNDU Issues

Downloadable UNDU Issues

Since issue #1 in March of 1995, all issues of The Unofficial Newsletter of Delphi Users has been published as Windows Help files. Below are links to each of these files so you can download them individually, or all at once. To speed downloading time, I have Zipped them, so you will need PKUNZIP or an equivalent program to decompress them. If you don't have a ZIP compatible program, you can download just the HLP file.

When you unzip them, I suggest that you put all issues in a single directory. Many of the files have links to other issues and if they are all present together, they will behave normally. Most of the later issues in ZIP file format also have a contents file (*.CNT) which is used to by the Windows help system to display a complete list of all issues available.

Effective January, 1998 - I will no longer be arranging UNDU as "issues", but rather as individual articles that will be posted on the UNDU web site every few days. At some time in the future, I may start packaging these articles as downloadable WinHelp files, but I am not promising anything at this point.

Issue # - Month of Release | Zip File | HLP File
Issue #24 - December '97 | DN971201.ZIP | DN971201.HLP
Issue #23 - September '97 | DN970901.ZIP | DN970901.HLP
Issue #22 - June '97 | DN970601.ZIP | DN970601.HLP
Issue #21 - May '97 | DN970501.ZIP | DN970501.HLP
Issue #20 - March '97 | DN970301.ZIP | DN970301.HLP
Issue #19 - January '97 | DN970101.ZIP | DN970101.HLP
Issue #18 - November '96 | DN961101.ZIP | DN961101.HLP
Issue #17 - October '96 | DN961001.ZIP | DN961001.HLP
Issue #16 - September '96 | DN960901.ZIP | DN960901.HLP
Issue #15 - August '96 | DN960801.ZIP | DN960801.HLP
Issue #14 - June '96 | DN960601.ZIP | DN960601.HLP
Issue #13 - May '96 | DN0596.ZIP | DN0596.HLP
Issue #12 - February '96 | DN0223.ZIP | DN0223.HLP
Issue #11 - January '96 | DN0118.ZIP | DN0118.HLP
Issue #10 - December '95 | DN1212.ZIP | DN1212.HLP
Issue #9 - November '95 | DN1109.ZIP | DN1109.HLP
Issue #8 - October '95 | DN1010.ZIP | DN1010.HLP
Issue #7 - August '95 | DN0831.ZIP | DN0831.HLP
Issue #6 - July '95 | DN0725.ZIP | DN0725.HLP
Issue #5 - June '95 | DN0626.ZIP | DN0626.HLP
Issue #4 - May '95 (b) | DN0524.ZIP | DN0524.HLP
Issue #3 - May '95 (a) | DN0501.ZIP | DN0501.HLP
Issue #2 - April '95 | DN0401.ZIP | DN0401.HLP
Issue #1 - March '95 | DN0315.ZIP | DN0315.HLP


Group Name:
Person(s) in Charge:
Meeting Date/Time:
Meeting Location:
Dues:
Email Address:
Phone Number:
Internet URL:
Description: