The weekly comp.lang.pascal.delphi.misc MiniFAQ

COMP.LANG.PASCAL.DELPHI.MISC FAQ

Welcome Delphi newbies!  This FAQ has been put together by Delphi experts who
frequent this group, and is posted weekly by a Delphi non-expert(me!), in the
hopes of making this group a nicer place to be for all concerned by answering
the most frequently-asked questions even before you've asked them!

So now you don't have to admit that you don't know the answers to these
questions; just read on, and learn the answers in the "privacy of your own home"
(or wherever you happen to be)!  Meanwhile, our resident Delphi experts are busy
answering all manner of new and exciting questions!

To save costs for those readers with pay-per-megabyte charges, this FAQ is
posted in abbreviated form three weeks out of four.  The entire FAQ can be
found at the following location:
http://www.bancoems.com/CompLangPascalDelphiMisc-MiniFAQ.htm

The full FAQ ends with a list of links to useful sites.  There, you'll find
advice, components to download and use in your own programs, tutorials, tips
and tricks, and many other useful things for Delphi programmers. The Delphi
community is LARGE...make the most of it!

--
Esther Michaels
Please respond to newsgroup; I don't check my mail account

================================================================================
VERSION HISTORY
2001-Apr-04: Initial version (kindly contributed by Bruce Roberts).
2001-Apr-25: Formatted to 80 characters per line, added preamble, made html
             version.
2001-Apr-26: Added reference to FindCmdLineSwitch and CmdLine in Q10.
2001-Oct-30: Updated Links section.
2001-Nov-11: Added Q12 (with thanks to John Stockton).
2001-Nov-22: Added Q13 (with thanks to Daniel Rutten).
2002-Jan-13: Added Q14 and Q15 (with thanks to Bruce Roberts), and updated
             introduction to fit with abbreviated-posting policy.
================================================================================
   CONTENTS
1. How do I start another program from my program?
2. How to stop a second instance of my program from executing? (Also: HPrevInst
doesn't seem to work, why?)
3. I'm getting strange decimal values when I manipulate real numbers (i.e.
single, real48, double, extended), what gives?
4. Is there a limit on the number of characters allowed in a tMemo?
5. Why do I get an "abstract error" when I try to use a tStrings variable?
6. How do I access a component/property/field of Form1 from Form2?
7. How do I change the background, font, general appearance of an entry in a
tListView, tTreeView, tListBox, tCombobox list, tStringGrid, etc.?
8. How do I change the formatting of a line/word/character in a tMemo?
9. Why does the de{*word*81} show my For loop variable counting down, not up?
10. How do I get the path of my executable? And, how do I retrieve the command
line parameters?
11. When my program is in a loop it doesn't respond to user input or update its
display. Can I change this?
12. How do I access the compilation date in my program?
13. How do I access the VersionInfo tab's data at runtime?
14. Does Delphi have an equivalent to the VB Split function?
15. I create a label/edit/some other control at run-time but it doesn't
appear on
the form. Why?
USEFUL LINKS
================================================================================
1. How do I start another program from my program?
  The most common methods of doing this employ either ShellExecute or
  CreateProcess, both of which are documented in the WindowsSDK help file.
  ShellExecute is quite versatile and has the advantage of being simple and able
  to open or print any file for which there is a file association registered on
  the system. CreateProcess is a little more complex but provides much better
  control over the process. Information returned by CreateProcess can be used
  to pause a program until the called program has completed (using
  WaitForSingleObject). See http://www.bancoems.com/mini_faq_examples.htm for
  an example of each method.
  Return to contents
-------
2. How to stop a second instance of my program from executing? (Also: HPrevInst
doesn't seem to work, why?)
  There are several methods of handling this. The most common recommendation is
  to use a mutex (see the Windows SDK help). See
  http://www.bancoems.com/mini_faq_examples.htm for an example. (HPrevInst only
  works in Delphi 1.)
  Return to contents
-----
3. I'm getting strange decimal values when I manipulate real numbers (i.e.
single, real48, double, extended), what gives?
  When working with floating point numbers one must remember that the binary
  format they use is not capable of representing all possible decimal values. If
  you must have precision use the Currency type (4 decimals) or use an integer
  type and scale the results. When it's just a question of displaying a result,
  use one of the formatting functions that allow you to specify the number of
  decimal places to display - Format and FormatFloat. See
  http://www.efg2.com/Lab/Library/Delphi/MathInfo for more info on this and
  other math related questions.
  Return to contents
-----
4. Is there a limit on the number of characters allowed in a tMemo?
  Yes. The limit depends on the operating system and can be as low as 32KB. If
  you need to have more than 32KB in a memo, use a tRichEdit instead. Set the
  rich edit's PlainText property to True and its MaxLength property to an
  appropriately large value, e.g.
    RichEdit1.MaxLength := MaxInt - 2;
  allows the RichEdit1 to work with ~2GB. (Setting MaxLength to 0 as suggested
  for tCustomEdit in the help doesn't work for rich edits.)
  Return to contents
-----
5. Why do I get an "abstract error" when I try to use a tStrings variable?
  You should never create a tStrings variable. Instead create one of its
  descendants like tStringList. return to contents
-----
6. How do I access a component/property/field of Form1 from Form2?
  Add the Form1 unit to the Uses clause in the implementation section of Form2.
  (By default there is no uses clause so you may have to add one - do so just
  after the '{$R *.DFM}' line.) You can then reference items belonging to Form1
  by prefixing them with "Form1.", e.g.,
    Form1.Label1.Caption := 'Hi there, I was set from Form2';
  Return to contents
-----
7. How do I change the background, font, general appearance of an entry in a
tListView, tTreeView, tListBox, tCombobox list, tStringGrid, etc.?
  You have to use the owner draw event (typically OnDraw <something>) to draw
  the items. This means that you have to draw each item when the control asks
  you to do so. An example can be found at
  http://www.bancoems.com/mini_faq_examples.htm
  Return to contents
-----
8. How do I change the formatting of a line/word/character in a tMemo?
  You can't. Use a tRichEdit instead.
  Return to contents
-----
9. Why does the de{*word*81} show my For loop variable counting down, not up?
  The Delphi optimizer may generate loop code that decrements an internal
  counter instead of your variable. This behavior is guaranteed not to alter
  the correctness of your program. Ignore the de{*word*81} value and consider the
  For loop variable "unavailable due to optimization".
  Return to contents
-----
10. How do I get the path of my executable? And, how do I retrieve the command
line parameters?
  Application.ExeName will return the full name of your executable. You can get
  the path portion using ExtractFilePath. ParamStr(0) will return the same
  value as Application.ExeName. To retrieve other command line arguments use the
  ParamCount and ParamStr functions.  See also FindCmdLineSwitchand CmdLine in
  the help.
  Return to contents
-----
11. When my program is in a loop it doesn't respond to user input or update its
display. Can I change this?
  Yes. In your loop you need to add a call to the Application.ProcessMessages
  method. This will allow your application to process Windows messages,
  including those generated by user actions. There are two significant caveats.
  First, since Windows messages often translate into calls to event handlers
  your program may begin to do things at inappropriate times. Make sure that the
  user can't initiate actions that will interfere with the loop while the loop
  is active. In particular, note the following sentence, taken from Delphi 3's
  help file on TApplication.Terminated: "For applications using
  calculation-intensive loops, call Application.ProcessMessages periodically,
  and also check Application.Terminated to determine whether or not to abort the
  calculation so that the application can terminate." The second caveat is that
  calling Application.ProcessMessages can be relatively expensive and may slow
  the program. In a fast (tight) loop you may not want to call the method on
  each iteration.  If you only want to update the display and not handle user
  input you can use the Update method (Delphi 3 and up) of the control covering
  the part of the display you want to update. Remember that this will also slow
  down the loop!
  Return to contents
-----
12. How do I access the compilation date in my program?
  There are a number of ways to achieve this, depending on the architecture of
  your program.  If the program consists of a single EXE whose creation date is
  guaranteed never to change after compilation, then the following code will
  be sufficient:
    DateToStr(FileDateToDateTime(FileAge(Application.ExeName)))
  This returns a string containing the date of the EXE file, formatted using the
  host computer's current date format setting.
  However, these circumstances don't hold for most programs. In these cases one
  solution is to create a file, perhaps called Today.pas, which holds a single
  constant:
    const COMPILE_DATE = '2001-11-10';
  This file should be updated daily, perhaps at boot time. In units of your
  program which need to refer to the compilation date, you add the file to the
  "uses" clause, and then simply refer to the constant as you would any other.
  For example, an About box might contain a TEdit whose job is to display the
  compilation date:
    Edit1.Text := COMPILE_DATE;
  This will then show the compilation date in your About box.
  Return to contents
-----
13. How do I access the VersionInfo tab's data at runtime?
  See
  http://www.bancoems.com/mini_faq_examples.htm
  for example code showing how to access each field of the VersionInfo tab.
  Return to contents
-----
14. Does Delphi have an equivalent to the VB Split function?
  There is no direct equivalent. However one can use the CommaText property
  of a tStrings to achieve the same result.
  Example:
    procedure Split(const aString, Delimeter: string; Results: tStrings);
    begin
      Results.CommaText := '"' + StringReplace(aString,Delimeter, '","',
         [rfReplaceAll]) + '"';
    end;

  (Note: the Results parameter is declared as tStrings. If you are using a
  variable as the actual parameter, (as opposed to a VCL control's
  property, e.g. tMemo.Lines, tListBox.Items, and tComboBox.Items),
  see question 5.)
  Return to contents
-----
15. I create a label/edit/some other control at run-time but it doesn't
appear on the form. Why?
  The most common cause of this problem is failure to assign, or correctly
  assign, the Parent property. When one creates a control at run-time the
  Owner (passed as a parameter to the constructor) should in almost all
  circumstances be the form. Once the control has been constructed one must
  then assign it a Parent. In most circumstances the Parent should also be
  the form. However, if one wants the control to be on a Panel or in a
  GroupBox then the Panel/GroupBox control should be made the Parent.
  Return to contents
-----
   Links: These links may prove useful. Inclusion here should not necessarily be
taken as an endor{*word*224}t.

News Group Etiquette
  http://www.uwasa.fi/~ts/http/tsfaq.html
Borland Delphi Community - TI, FAQ, links, articles
  http://community.borland.com/delphi/0,1419,1,00.html
Google - NG archives

http://groups.google.com/groups?hl=en&lr=&safe=off&group=comp.lang.pa...
  http://groups.google.com/
The Delphi Bug List - bugs and gotchas
  http://www.jrsoftware.org/buglist/bugsall.htm
Undu - Delphi articles, tips, techniques, links
  http://www.undu.com
Deborah Pate's Pages - Word, Excel, etc. automation
  http://www.djpate.freeserve.co.uk/Automation.htm
Kyle Cordes BDE Alternatives Guide
  http://www.kylecordes.com/bag/index.html
Delphi Printing Info and Links
  http://www.efg2.com/Lab/OtherProjects/PrinterProjects.htm
BDE Support Page
  http://www.bdesupport.com
Microsoft MSDN - Win API documentation
  http://msdn.microsoft.com
Project JEDI - open source code library
  http://www.delphi-jedi.org
Delphi Super Page (DSP) - components, links
  http://delphi.icm.edu.pl/
  http://community.borland.com/homepages/dsp
Torry's Delphi Pages - components, links
  http://www.torry.net
ICS (Internet Component Suite) - internet components
  http://overbyte.alexid.fr/frame_index.html
Indy (Internet Direct, was Winshoes) - internet components
  http://www.nevrona.com/Indy
The Tutorial Times - links to tutorials
  http://www.tutorialtimes.com
Timo Salmi's Pascal programming material (a little dated but good general Pascal
knowledge)
  http://www.uwasa.fi/~ts/http/http2.html#programming

================================================================================
END