Re: comp.lang.pascal.delphi.misc miniFAQ (full version)

From: Joe (joen_at_spamintelcom.si)
Date: 04/05/04

  • Next message: John O'Keefe: "NYC - Delphi Developer Position"
    Date: Mon, 5 Apr 2004 20:11:01 +0200
    
    

    My name should be mentioned for the inspiration of your faq publishing
    name.
    btw: you have "grown" taller since the last lesson. keep up the good work!

    "Evil MiniFAQ Boss" <miniFAQ@mfw.dds.nl> wrote in message
    news:406b75c4$0$568$e4fe514c@news.xs4all.nl...
    > FAQ FOR NEWSGROUPS: COMP.LANG.PASCAL.DELPHI.MISC,
    ALT.COMP.LANG.BORLAND-DELPHI
    >
    > Version: 2003-10-07
    > First maintainer: Esther Michaels
    > Current maintainer: Maarten Wiltink (Evil miniFAQ Boss)
    > Posting schedule: Short version every Sunday, full version every first of
    > the month
    >
    > Copyright 2003 the current maintainer, all rights reserved except the
    right
    > to re-distribute the current document. Even better: give out the URL.
    >
    > --------------------------------------------------------------------------
    ------
    >
    > Latest version:
    > http://www.bancoems.com/CompLangPascalDelphiMisc-MiniFAQ.htm
    > Plain text version:
    > http://www.bancoems.com/CompLangPascalDelphiMisc-MiniFAQ.txt
    > Examples page:
    > http://www.bancoems.com/mini_faq_examples.htm
    >
    > --------------------------------------------------------------------------
    ------
    >
    > 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. Floating-point work - i.e. with single, real, real48, double,
    extended -
    > gives long decimals or wrong numbers. Why?
    > 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 debugger 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?
    > 16. How do I use streams?
    > 17. How do I declare an event handler for an object that I create at
    runtime?
    > 18. When using the TRegistry component under Windows NT, Windows 2000, or
    > Windows XP, a user with less than Administrator rights is unable to
    > access information stored in the HKEY_LOCAL_MACHINE hive. How can I
    > work around this?
    > 19. When drawing text on a canvas, how do I determine the resulting text
    size?
    > 20. How can I loop through the components/labels/edit-boxes on my form?
    (Also:
    > Tag is unused, what is it good for?)
    >
    > 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 example code showing
    > how to call each of these procedures.
    >
    > --------------------------------------------------------------------------
    ------
    >
    > 2. How to stop a second instance of my program from executing? (Also:
    > HPrevInst doesn't seem to work, why?)
    >
    > HPrevInst only works in Delphi 1. There are several methods of handling
    > this in Delphi 2 and above. The most common recommendation is to use a
    > mutex (see the Windows SDK help). See
    > http://www.bancoems.com/mini_faq_examples.htm for example code.
    >
    > --------------------------------------------------------------------------
    ------
    >
    > 3. Floating-point work - i.e. with single, real, real48, double,
    extended -
    > gives long decimals or wrong numbers. Why?
    >
    > Because computers are finite, all floating point formats are
    approximations.
    > Values that have no exact representation are simply replaced by the value
    > closest to it. It's like replacing "1/3" by "0.3333", and the computer has
    > no thoughts about what that number means. Multiplying it by 3 again gives
    > 0.9999, not 1. Also, Trunc(0.9999) will return 0, not 1.
    >
    > Comparing floating point numbers should not be done by testing for exact
    > equality, but for a difference being smaller than the inaccuracy in the
    > computed numbers. Errors start larger for shorter types and grow further
    > as more calculations are performed with inexact numbers.
    >
    > 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.
    >
    > --------------------------------------------------------------------------
    ------
    >
    > 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.)
    >
    > --------------------------------------------------------------------------
    ------
    >
    > 5. Why do I get an "abstract error" when I try to use a tStrings variable?
    >
    > You should never create a tStrings object. Instead create one of its
    > descendants like tStringList.
    >
    > --------------------------------------------------------------------------
    ------
    >
    > 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';
    >
    > --------------------------------------------------------------------------
    ------
    >
    > 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. See
    > http://www.bancoems.com/mini_faq_examples.htm for example code.
    >
    > --------------------------------------------------------------------------
    ------
    >
    > 8. How do I change the formatting of a line/word/character in a tMemo?
    >
    > You can't. Use a tRichEdit instead.
    >
    > --------------------------------------------------------------------------
    ------
    >
    > 9. Why does the debugger 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 debugger value and consider
    > the For loop variable "unavailable due to optimization".
    >
    > --------------------------------------------------------------------------
    ------
    >
    > 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 FindCmdLineSwitch and
    > CmdLine in the help.
    >
    > --------------------------------------------------------------------------
    ------
    >
    > 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!
    >
    > --------------------------------------------------------------------------
    ------
    >
    > 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 executable 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-17'; 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.
    >
    > --------------------------------------------------------------------------
    ------
    >
    > 13. How do I access the VersionInfo tab's data at runtime?
    >
    > See http://www.bancoems.com/mini_faq_examples.htm for example code and a
    > component that does this.
    >
    >
    > --------------------------------------------------------------------------
    ------
    >
    > 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, Delimiter: string; Results: tStrings);
    > begin
    > Results.CommaText:='"' + StringReplace(aString, Delimiter, '","',
    [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.)
    >
    > --------------------------------------------------------------------------
    ------
    >
    > 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.
    >
    > --------------------------------------------------------------------------
    ------
    >
    > 16. How do I use streams?
    >
    > Alan Lloyd has written an excellent introduction to streams in the form of
    > a help file, available from http://www.bancoems.com/mini_faq_examples.htm.
    >
    > --------------------------------------------------------------------------
    ------
    >
    > 17. How do I declare an event handler for an object that I create at
    runtime?
    >
    > Declare the event handler with the appropriate type signature (e.g. an
    > OnClick handler will be of type TNotifyEvent), then once you have created
    > the object simply assign the handler to the OnClick property of the
    object,
    > like this: MyRuntimeButton.OnClick := MyRuntimeButtonClickHandler; See
    > the examples file at http://www.bancoems.com/mini_faq_examples.htm for an
    > example.
    >
    > --------------------------------------------------------------------------
    ------
    >
    > 18. When using the TRegistry component under Windows NT, Windows 2000, or
    > Windows XP, a user with less than Administrator rights is unable to access
    > information stored in the HKEY_LOCAL_MACHINE hive. How can I work around
    this?
    >
    > The problem is caused by the fact that TRegistry (and the derived
    TRegIniFile)
    > always opens a key with KEY_ALL_ACCESS privileges, even if only KEY_READ
    would
    > be needed.
    >
    > In Delphi 5+, you can specify the access you require using the Access
    property.
    >
    > You can also avoid this by going back to using the WinAPI registry
    functions
    > (RegOpenKey et. al.), or in Delphi versions that don't already have it,
    add an
    > Access property to a new class derived from TRegistry. Alternatiely, the
    new
    > class could just always open keys read-only.
    >
    > --------------------------------------------------------------------------
    ------
    >
    > 19. When drawing text on a canvas, how do I determine the resulting text
    size?
    >
    > Create a bitmap and allocate a font to its canvas. To get the height of
    > the font elements, call the WinAPI function GetTextMetrics using the
    > bitmap's handle. Use TCanvas.TextWidth to get character widths. Some
    > printing terms are used in GetTextMetrics:
    >
    > * Ascent is the pixel height of characters, including any diacritics,
    > above the base height.
    > * Descent is the pixel amount below the baseline, in letters like "y" and
    "g".
    > * Internal leading (pronounced "ledding") is how much higher diacritics go
    > than capitals.
    > * External leading is the minimum empty space between two lines above
    > each other: between descent for the top line and capitals or diacritics
    > for the bottom line.
    >
    > So the vertical margins in a TEdit are TEdit.Height - (Ascent + Descent),
    > but this dimension is neither constant nor the same as External Leading.
    >
    > All values from GetTextMetrics will be in pixels. A call to GetDeviceCaps
    > can tell you how many pixels there are in an inch on your output device.
    >
    > --------------------------------------------------------------------------

    ---
    >
    > 20. How can I loop through the components/labels/edit-boxes on my form?
    > (Also: Tag is unused, what is it good for?)
    >
    > Loop through the Components array property of the form. To process only
    > one kind of component, test the class of each using the "is" operator.
    > To indicate special processing for any particular component, you can set
    > its Tag property in the Object Inspector.
    >
    > If you use Tag to signify that a component should be treated specially
    > in your loop, use zero to mean that it should be ignored, to prevent
    > surprises later when you may add components to the form. Tag is declared
    > as LongInt and its default value is zero. If a 4-byte LongInt is not
    > enough for your purposes, you can store an object reference or a pointer
    > to a record in in, but then be careful that you know what you are doing.
    >
    > See http://www.bancoems.com/mini_faq_examples.htm for example code.
    >
    > --------------------------------------------------------------------------
    ------
    >
    > Links
    >
    > These links may prove useful. Inclusion here should not necessarily be
    taken
    > as an endorsement.
    >
    > Newsgroups 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
    > Borland Delphi Newsgroups
    >
    http://newsgroups.borland.com/cgi-bin/dnewsweb?cmd=listall&group=borland.public.delphi.&utag=
    (but first read the posting guidelines, at
    http://www.borland.com/newsgroups/guide.html)
    > Google - Newsgroups archives
    >
    http://groups.google.com/groups?hl=en&lr=&safe=off&group=comp.lang.pascal.delphi.misc
    > 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.delphicenter.com/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
    > Martin Harvey's tutorial on multi-threading
    > http://www.pergolesi.demon.co.uk/prog/threads/ToC.html
    > Henry Bartlett's page on Delphi-related newsgroups
    > http://www.hotkey.net.au/~hambar/habit/newsgroups.htm
    >
    > --------------------------------------------------------------------------
    ------
    >
    > VERSION HISTORY
    >
    > 2003-Oct-07: Updated copyright notice (with thanks to John Stockton).
    > 2003-Sep-21: HTML tidied. Added copyright notice. Removed dead link from
    Q12.
    > Rephrased Q20.
    > 2003-Jul-29: Example date in Q12 changed to an unambiguous value.
    Reordered
    > and slightly changed Q18. Rephrased Q19 and added note about units.
    > 2003-Jun-27: Rephrased Q3, again. Added Q18 (with thanks to Dan Donoghue),
    > Q19 (with thanks to Alan Lloyd), and Q20 (with thanks to Henry
    > Bartlett). Added a link to Henry Bartlett's Delphi newsgroups page.
    > Reordered document. Removed introduction.
    > 2002-Nov-16: Rephrased Q3.
    > 2002-Jul-27: Reformatted into HTML.
    > 2002-May-10: Minor corrections, added links to Borland Delphi newsgroups
    > and posting guidelines.
    > 2002-Apr-21: Added Q17.
    > 2002-Apr-11: Minor corrections, added link to Martin Harvey's
    multi-threading
    > tutorial.
    > 2002-Apr-06: Added Q16 (with thanks to Alan Lloyd for the referenced file)
    > 2002-Jan-13: Added Q14 and Q15 (with thanks to Bruce Roberts), and updated
    > introduction to fit with abbreviated-posting policy.
    > 2001-Nov-22: Added Q13 (with thanks to Daniel Rutten).
    > 2001-Nov-11: Added Q12 (with thanks to John Stockton).
    > 2001-Oct-30: Updated Links section.
    > 2001-Apr-26: Added reference to FindCmdLineSwitch and CmdLine in Q10.
    > 2001-Apr-25: Formatted to 80 characters per line, added preamble, made
    > html version.
    > 2001-Apr-04: Initial version (kindly contributed by Bruce Roberts).
    >
    > --------------------------------------------------------------------------
    ------
    >
    > END
    

  • Next message: John O'Keefe: "NYC - Delphi Developer Position"