Section 1 - Introduction
1.1. What is the purpose of this FAQ?
1.2. How can I get the latest version of this FAQ?
1.3. Is this FAQ copyrighted?
Section 2 - Delphi Resources
2.1. What are some good books about Delphi?
2.2. Does anyone publish a Delphi magazine or journal?
2.3. Where can I get Delphi files via WWW and FTP?
2.4. What other FAQs or FAQ-like documents exist for Delphi?
Section 3 - General Questions
3.1. What is Delphi?
3.2. What versions of Delphi are there?
3.3. How much disk space, memory, etc., do I need to run Delphi?
3.4. How tough is it to learn Delphi?
3.5. What's the difference between Delphi and Delphi Client/Server?
3.6. Can you write multi-user database applications in regular Delphi?
3.7. What is the history of Delphi?
3.8. Where can I get a copy of Delphi?
3.9. What if I don't have a CD-ROM drive?
3.10. How can I contact Borland?
3.11. What technical support do I get with Delphi?
3.12. What known bugs exist in Delphi?
3.13. I just bought Delphi. Where are the language and library reference 
    manuals?
3.14. Are there commercial applications developed in Delphi?
3.15. What patches to Delphi exist?
Section 4 - Compatibility
4.1. What operating systems does Delphi support?
4.2. What source management tools are compatible with Delphi?
4.3. Can I use DLLs developed in C or C++ from Delphi?
4.4. Can I make calls to Delphi code from C or C++?
4.5. What Dephi-specific third-party packages are available?
4.6. What non-Delphi-specific third-party packages are specifically known 
    to work (or not work) with Delphi?
Section 5 - Database Questions
5.1. How do I get access to a database from Delphi?
5.2. Does Delphi support the 
5.3. What data-aware controls come with Delphi?
5.4. Can I use the ODBC drivers that I got with 
5.5. What about data-aware VBXes?
5.6. How do I write a "change password" function for a Paradox table?
5.7. Why do I get errors when I call the Add method for a TFieldDefs?
5.8. What is the procedure for connecting Delphi to an MS Access database?
5.9. How can I manipulate data programatically?
5.10. Is it possible to add referential integrity to a Paradox table at 
    run-time?
Section 6 - Programming Questions
6.1. What target formats can I create using Delphi?
6.2. I built a small test project. What are all these files?
6.3. How can I yield the CPU to other tasks, like "DoEvents" in VB?
6.4. Why do I get compile errors acessing the Sender object in events?
6.5. Are there any tools to help me migrate my applications to Delphi?
6.6. What's the Delphi equivalent to Visual Basic control arrays?
6.7. How do I close a modal form? For that matter, what's the best way to 
    close any form?
6.8. Do I have to know a lot about the Windows API to use Delphi?
6.9. Do I have to understand object-oriented programming to use Delphi?
6.10. How does Delphi's exception handling work?
6.11. Does Delphi use Pascal or C style strings?
6.12. How does Delphi handle Windows callbacks?
6.13. How does Run-Time Type Information (RTTI) work?
6.14. I'm creating a toolbar, but I have icons, not bitmaps. Help!
6.15. When I use the Glyph property, how do I know which color is 
    transparent?
6.16. How can I make my Delphi application respond to Windows messages?
6.17. How can I allocate blocks of memory larger than 64k?
6.18. Is it possible to write a Windows screen saver in Delphi?
6.19. I'm trying to call 
6.20. How can I add pages to a TTabbedNotebook at run-time?
6.21. I'm painting complex graphics. How can I speed up redrawing?
6.22. How can I hide MDI child windows?
6.23. How do I write a global error handler?
6.24. Why do I get exception messages even though I'm in protected code?
6.25. I've added code to my OnKeyPress event that traps Enter keys, but it 
    keeps beeping at me and/or activating the default button. How do I 
    make it stop?
6.26. I want to modify a component's properties at run-time, but it isn't 
    convenient to store a pointer to the component. Is there an easy way 
    to get access to it?
6.27. How do I create help for new components so that the Delphi help file 
    is not corrupted?
6.28. What's the best way to handle large data elements (bigger than 64k) in 
    16-bit Delphi?
6.29. Can I make a form come up centered?
6.30. How do I extract an icon from an .EXE file?
6.31. How can I 
6.32. What should I give to Windows API functions that want a hWnd?
6.33. How do I use the palPalEntry in TLogPallette?
6.34. What is required to make a label with an accelerator key set focus to 
    a different control?
6.35. How can I calculate the height and width of text to be displayed in a 
    particular font?
Section 7 - Questions about distributing Delphi apps
7.1. Is there anything in Delphi similar to the VB "setup wizard?"
7.2. What files am I allowed to redistribute with my applications?
7.3. If I want to send out a Delphi-compiled EXE file, what other files do 
    I need to send with it?
7.4. I want to distribute a database application, but I don't want to force 
    all my users to create BDE aliases. What do I do?
    This is not really a FAQ in the pure sense of the term, because some 
    of the questions answered here are not really very frequently asked at 
    all.
    
    James R. Ward jward@neosoft.com 
    says: "Also, I have purchased 'Instant Delphi' which is somewhat 
    introductory, but pretty good.  (I'm not returning it!)"
    Paul Johnson pauljo@netcom.com 
    says: "I bought a copy of Mr. Duntemann's book two days ago at my 
    local book sellers, so it is definitely out.  It appears to be a very 
    good book.  I also bought Delphi for Dummies, but I found it too cute 
    for my tastes (which is a shame, because Neil Rubenking is an 
    excellent writer and teacher).  The best book I have found is Instant 
    Delphi by Dave Jewel (if memory serves).  The examples are good and 
    provide enough detail and background information to get you (me) going 
    in the right direction.  I highly recommend it  (comes with a disk, 
    too)."
    
    Delphi Developer, 12 issues/$99, Pinnacle Publishing (206) 251-1900
    Delphi Informant, 12 issues/$49, Delphi Informant (916) 686-6610
    Inside Delphi, 12 issues/$79, Cobb Group (502) 493-3200
    The Delphi Magazine, 6 issues/???, The Delphi Magazine +44 1181 460 
    0650
    
    Nick Hodges' Home 
    Page
    The Delphi Bug 
    List
    Turbo Pascal Programmers 
    Page
    Delphi Tech Support Home 
    Page
    Wild Thing 
    Cool Delphi Stuff
    Coriolis Group 
    Delphi EXplorer
    CITY ZOO 
    Inc. Home Page
    The Delphi Connection WWW 
    Site
    Jeroen Prins' Home 
    Page
    
    Raymond Kennington marwk@levels.unisa.edu.au 
    has produced a FAQ which contains several fairly lengthy source code 
    examples.
Robert Vivrette e-publishes the "Unofficial Newsletter of Delphi Users," which is available on Wild Thing's Delphi home page and on CompuServe.
    Okay, now for everyone else. In order to make full use of the Delphi 
    environment, you have to know Pascal, you have to have some grasp of 
    object orientation, and you have to understand event-driven 
    programming. Once you're over those three hurdles, you've pretty much 
    got it. See section 5 for more information.
    On the other hand, most people don't need to make "full" use of the 
    environment. If you just want to pull a simple application together 
    that doesn't do anything too fancy, Delphi shouldn't be any harder to 
    learn than VB--it's just that there's a whole lot more you *can* do in 
    Delphi, which will make you feel more lost than you really are.
    
       - SQL-Links 2.5, which includes native client drivers for Oracle, 
    Sybase, Informix, and InterBase, and includes full royalty-free 
    redistribution rights to those drivers, and which costs $995 if bought 
    separately;
       - The Local InterBase Deployment Kit, $495 (*);
       - ReportSmith/SQL, $300 (**);
       - "Team development support" -- interoperation with PVCS 
    (obviously, this is no use to you if you don't own PVCS), not 
    available separately;
       - The visual query builder, which creates SQL statements for you, 
    also not available separately;
       - The VCL source code, which is available separately for $100.
    (*) Local InterBase is a single-user SQL database engine. The version 
    included in Delphi Desktop is intended to be used by developers who 
    want to write SQL applications that can be seamlessly migrated to 
    client/server environments, but without buying their own (expensive) 
    server platform. However, Delphi Desktop does not include 
    redistribution rights. If you want to distribute a single-user 
    application that uses Local InterBase, you have to pay extra for the 
    deployment kit.
    (**) The version of ReportSmith bundled with Delphi Desktop 
    specifically detects and excludes any server-based ODBC drivers from 
    its list of acceptable connections. Yes, you heard that right. Even 
    though you've got third-party ODBC drivers, and even though you can 
    talk to these drivers just fine from the Delphi environment, 
    ReportSmith still won't work. If you want to do this without buying 
    Delphi Client/Server, you can buy ReportSmith/SQL separately for $300. 
    As an alternative, if you happen to already own a copy of Visual 
    Basic, you can use the Crystal Reports VBX just fine from within 
    Delphi.
    
    Steven Lamotte slamotte@jenex.mb.ca says: "I 
    think the benefits of the native SQL drivers relate mostly to speed. 
    It may be true that ODBC allows you to do most everything a server 
    permits, but your SQL commands still have to be processed by ODBC. I 
    once wrote a program to compare Sybase SQL Server access with C++ 
    using ODBC and using OpenClient (the native SQL interface for SQL 
    Server) and the results were that the native interface version 
    performed several times better than ODBC."
    
    The development of Delphi started sometime in 1993. Various beta-test 
    and prerelease copies have been circulated, including several hundred 
    "early experience" copies which were given away at the trade show 
    Software Development '95. Delphi was officially announced in the U.S. 
    on Feb. 14, 1995, and the first release-level copies were shipped on 
    Feb. 28.
    
    Of course, if you buy through a reseller, you will probably pay less. 
    According to Borland, "Delphi is available through the following US 
    resellers: CompUSA, Best Buy, Elek-Tek, Computer City, Babbages, 
    Software Etc., Fry's, Electronics Boutique, Corporate Software, ASAP 
    Software Express, Egghead Software, Softmart, Software Spectrum, CDW, 
    PC Connection, Programmer's Paradise, Programmer's Warehouse, 
    ProVantage Shop, and Micro Warehouse."
    Note that you do NOT have to go through Borland directly to get the 
    upgrade price. When you buy a copy of Delphi at the discounted retail 
    price (US street prices are $179-$189), the box contains a coupon for 
    the $50 discount if you mail in a serial number for Turbo or Borland 
    Pascal. You have to send in a photocopy of your install disk, or the 
    original first page of your manual.
    Borland also maintains list prices in several other currencies through 
    their various international offices. In addition, distributors sell 
    Borland products across the globe. I do not currently have any 
    verified information about non-U.S. pricing for Delphi; check with the 
    closest Borland office or with your distributor or reseller.
    
    Australia: (61) 2 911 1000 
    Belgium/Luxembourg: (32) 2 4610 448 
    Brazil: (55) 11 851 5326 
    Canada: (416) 229 6000 
    Chile: (56) 2 233 7113 
    Denmark, Norway: (45) 22 62 89 00 
    Eastern Europe, Mediterranean, Russia, Middle East: (33) 1 41 23 11 00 
    France: (33) 1 41 23 11 00 
    Germany, Austria, Switzerland: (49) 61 03 9790 
    Asian Headquarters/Hong Kong: (852) 540 4380 
    Italy: (39) 2 26 91 51 
    Japan: (81) 3 5350 9370 
    Korea: (82) 2 551 2795 
    Latin America Headquarters: (408) 431 1074 
    Malaysia: (60) 3 230 2618 
    Netherlands: (31) 020 540 5400 
    Singapore: (65) 339 8122 
    Spain: (34) 1 650 7250 
    Sweden, Finland: (46) 8 799 20 00 
    Taiwan: (886) 2 718 66 27 
    United Kingdom: (44) 1734 320 022 
    USA: (408) 431 1000 
    
    In order to get what borland calls "consultative" tech support (I.E. 
    someone with whom you can discuss reasons why a program is not 
    working), you have to pay $2/minute. You can call (900) 555-1015 and 
    have the charges put on your phone bill, or else (800) 330-3372 and 
    use a credit card. I have called twice, and they couldn't answer my 
    question either time; however, they didn't charge me for the calls.
    
    Chuck Jazdzewski cjazdzewski@wpo.borland.com 
    gives us the details:
    The development environment is a Delphi project. This includes all the 
    menus, dialogs, editor interface (display and keystroke interpreter), 
    debugger interface (breakpoint managment, evaluator dialogs, etc), 
    form designer, object inspector, etc.  In other words, just about 
    anything you see while using Delphi was written using Delphi.  The 
    back-ends are written using other languages since the code already 
    existed.  The compiler/linker, for example, is written in assembler 
    (essentially the same compiler technology that shipped in Turbo Pascal 
    4.0).  The debug kernel DLL (PASDBK16) and the editor kernel (text 
    buffer manipulation) (DELPHIED and DELPHIKB) are written in C from a 
    shared code base with the BC++ team.
    
    According to the README.TXT file included with delpatch.exe, the patch 
    file address the following problems:
     1.  Improved compatibility with Windows 95 M8 beta for MDI (e.g. new 
    child) and OLE2 (e.g. insert object).
     2.  IDE debugger compatibility fix for NT.
     3.  Fixed MDI design mode problem when minimizing MDI Child window.
     4.  Significant updates to OLE2 API unit (see \DELPHI\DOC\OLE2.INT).
     5.  Fixed unit version problem in DLIB.EXE.
     6.  Fixed problem in Browser when you double-click a reference to a 
    .PAS file that is not already open in the editor.
     7.  Fixed Options|Rebuild Library problem when the current project 
    has an active Dataset.
     8.  Fixed Alt+Tab problem in Grid control.
     9.  Fixed DBGrid to allow cancel of SetKey mode.
    10.  TForm.DefineProperty now calls its inherited method.
    11.  Support for owner draw in TOutline.
    12.  DBImage.CutToClipboard now correctly updates the clipboard.
    13.  In TDataSource.OnDataChange, fixed invalid pointer in the Field 
    Parameter.
    14.  Fixed various demo problems.
    
    Applications built in Delphi are Windows 3.1, 16-bit applications. 
    However, Borland has stated that existing Delphi applications will 
    compile unmodified in 32-bit Delphi.
    Francis Whiteley whiteley@croughton.win-uk.net 
    points out that the readme.txt file for Delphi says: "Delphi has been 
    tested under Windows 3.1, Windows for Workgroups 3.11, Windows NT 3.5, 
    OS/2 Warp, and the latest pre-release version of Windows 95. Note that 
    we do not recommend large-scale deployment of database applications 
    running under Windows 95 until Microsoft certifies a release for 
    commercial use." 
    
    If your have a source manager that simply cannot deal with binary 
    files, Rick Thompson rat@ab00.larc.nasa.gov points 
    out: "According to the docs (User Guide, pp. 94-95) you can save forms 
    as ASCII text for editing or version control purposes.  ASCII forms 
    can also be loaded and resaved in binary *.DFM format."
    Duncan Murdoch dmurdoch@mast.QueensU.CA 
    adds: "The CONVERT.EXE program does this conversion from the command 
    line.  I don't know if it's documented anywhere."
    According to Chuck Lownie chuck@mks.com, "MKS Source Integrity 
    (MKS SI is 2nd in PC/PCLAN source management market next to PVCS with 
    over 35,000 developers using SI) also offers integration into Delphi.  
    Our integration into Delphi is currently being shipped along with MKS 
    Source Integrity, however, in a future maintenance release of Delphi, 
    our integration will also be shipped in the Delphi box, similar to 
    PVCS."
    
    As is the case in all Windows programming languages that I know of, 
    DLLs are difficult to debug and will crash your system if they aren't 
    quite right. Save your source code frequently.
    
    Rocket: Database engine compatible with FoxPro, Clipper, and HyPer-Six 
    (whatever that is). Their ad says: "Plus, we've included a set of 
    Delphi CLASS-WRAPPERS for complete plug-n-play integration." The 
    control was originally developed for VB. SuccessWare, (909) 699-9657.
    DrawKit: Drawing and design application builder kit. Handles .wmf, 
    .bmp and .drw files. Includes floating toolbox component. 25+ 
    compoments. Mobius Ltd., +44 131 467 3267. (This is a UK number. You 
    can also use e-mail to 73563.533@compuserve.com.)
    Business Builder: Contains "specialized table subclasses" with 
    built-in functions for common items like customers, vendors, sales & 
    purchase orders, etc. 30+ components. Mobius Ltd., +44 131 467 3267. 
    (This is a UK number. You can also use e-mail to 
    73563.533@compuserve.com.)
    VisualPROS for Delphi: Progress meter, background-bitmap tool for 
    controls and forms, improved balloon help, INI files and Registry 
    component, Visual Prompt, Visual LED, enhanced bitmap button, and 
    improved menu control. Shoreline Software, (800) 261-9198 or (203) 
    870-5707. 
    Async Professional for Windows: Comm port control, including Zmodem, 
    Kermit, CIS B+, Ymodem and Xmodem; ANSI emulation; modem database. 
    TurboPower Software, (800) 333-4160 or (719) 260-9136.
    Orpheus: Currently in beta test, but you can buy it as an "early 
    experience" product. Data entry fields, array editors, virtual 
    listbox, 16Mb-capacity text editor, unlimited-size viewer for text or 
    binary data, improved tabbed notebook control, timer pool, rotated 
    font label, calendar, meter, spinner, four-way spinner.  TurboPower 
    Software, (800) 333-4160 or (719) 260-9136. 
    TOLEAutomationClient: The component lets you control OLE Automation 
    servers using Delphi syntax that's analogous to the way it's done in 
    Visual Basic.  Besides taking care of initialising the Windows OLE 
    libraries, etc., it lets you activate a server and then access its 
    exposed properties and call its exposed methods, passing arguments 
    either by value or by reference. Fax: +64 9 832 0088; E-mail: 
    sraike@iconz.co.nz
    
    Hey, you! I know you've used some VBXes (or whatever) with Delphi. 
    Please e-mail graham (at) mhn.org with your findings so that this list can 
    become more complete.
    minimum of 
    If you've been trying for hours to get this to work, and no matter 
    what you do you just don't see anything happening, try setting the 
    "active" property on the Table or Query to "True." This will open the 
    database. I have seen many people get caught out by this the first 
    time they try it.
    
    Both versions contain the same data-aware components:
    TDBGrid (a data grid)
    TDBEdit (an edit control)
    TDBNavigator (a navigator with buttons to move around in a table)
    TDBLabel (a label control)
    TDBMemo (a multiline edit control useful for text blobs)
    TDBImage (a component that displays graphic fields)
    TDBRadioButton and TDBCheckBox (self-explanatory)
    TDBListBox, TDBComboBox, TDBLookupListBox, TDBLookupComboBox
    
    procedure Add(const Name: string; DataType: TFieldType; Size: Word; 
    Required: Boolean);
    
    Here is the step-by-step process that I took to connect my Delphi app. 
    to an Access database:
    1) Open up the Windows Control Panel.
    2) Open up the ODBC "Data Sources" icon.
    3) ADD a new Data Source of Type ACCESS DATA.
    4) Provide a unique "Data Source Name" (it doesn't really matter what 
    you call it - description is optional).
    5) Choose the Database File by clicking the "Select Database" button.
    6) Close the "Data Source" window.
    7) Open up the "Database Engine Configuration" to get to the "BDE 
    Configuration Utility" screen.
    8) Click on the "NEW ODBC Driver" button.
    9) Provide a "SQL Link Driver" - once again, it doesn't really matter 
    what you call it.
    10) Select a Default ADBC Driver of type ACCESS DATA.
    11) Under "Default Data Source Name" choose the name of the ADBC 
    driver that you provided from the Control Panel.
    12) Create a new alias by clicking on the "Alis" page tab.
    13) Click on the "New Alias" button.
    14) Give the alias a name.
    15) Select an Alias Type of ODBC_[WHATEVER YOU CALLED IT IN STEP 11].
    16) Save your settings with File/Save.
    17) You can now close the BDE Config. Utility.
    18) IN YOUR PROJECT --- (I am sure that there are many ways to 
    approach the next steps, but here's what I did)
    18.a) Add a Tdatabase component
    18.a.1) Set the AliasName to the new alias that you just defined.
    18.a.2) Provide a dummy DatabaseName.
    18.a.3) Set the LoginPrompt to FALSE (if you don't want permission 
    checking).
    18.b) Add a TQuery component.
    18.b.1) Set the DatabaseName to the dummy name you provided in a.2)
    18.c) Add a TDataSource component.
    18.c.1) Set the DataSet to the name of the TQuery comp.
    And you are done!  You now have a SQL-ready, data-aware form that you 
    can plop SQL into and data-aware components on to!
    
    Duncan Murdoch dmurdoch@mast.QueensU.CA 
    clarifies: "The command line compiler can create DOS and DOS-DPMI 
    programs, with the same /CD and /CP options that BPC used.  The main 
    problem is that Delphi doesn't ship with libraries for these; you'd 
    have to write those yourself, and it would be a lot of work."
    
    DPR - Delphi Project File. This is actually a Pascal source file; it 
    just happens to be the main program for the application.
    ~DP - A backup file of the DPR file before the last save operation.
    PAS - In Delphi, PAS files are always the source code to either a unit 
    or a form. The main program of an application is in the DPR file.
    ~PA - A backup of a .PAS file.
    DFM - These files are always paired with PAS files. The DFM file is 
    the binary data used to set up initial data for components (IE, the 
    properties you set in design mode rather than in code). You can't edit 
    a DFM file with a text editor, but if you open it in Delphi, you will 
    see a textual version of the contents.
    ~DF - A backup of a .DFM file.
    DCU - A compiled unit, similar in concept to an OBJ file.
    DSM - Symbol information file, used by the internal debugger. This 
    file is recreated each time you do a build. If you delete it, Delphi 
    will complain until you rebuild.
    OPT - Project Options; i.e. compiler and linker settings, which form 
    is the main form, what icon to use for the application, etc. 
    Generally, the stuff you edit under Options/Project.
    RES - A Windows resource file; generated automatically by Delphi and 
    required by the compilation process. You don't need to worry about 
    this file, but don't delete it either.
    EXE - All of the above linked together into runnable format.
    
    Steve Teixeira steixeir@borland.com explains:
    You should not use Yield() unless your application is *guaranteed* not
    to receive any messages (ie, your application contains no windows).
    Instead, the way to do this in Delphi is to call 
    Application.ProcessMessages. ProcessMessage encapsulates a 
    PeekMessage() loop, which is the correct "API-way" to do this.
    
       EarthTrek
       7 Mountain Rd.
       Burlington, MA  01803
       (617) 273-0308
    
    Reason 1. You want to share event handlers between different controls 
    on a form.
    This is really easy. All you have to do is select the same event 
    handler procedure in each of the controls' events. This is better than 
    control arrays because you can even have the same event handler 
    function across different kinds of control; for example, a toolbar 
    button and a menu item can call the same function directly in each of 
    their Click events.
    Reason 2. You want to be able to dynamically allocate and deallocate 
    controls at run-time.
    This is also pretty easy in Delphi. Suppose you have a button on a 
    form, and each time it is clicked, you want to create another, 
    different button. The following sample code shows how to do this:
    procedure TForm1.Button1Click(Sender: TObject);
    var
      NewButton: TButton;
    begin
      NewButton := TButton.Create(Self);
      NewButton.Parent := Self;
    end;
    It is important to note that once this event finishes, the NewButton 
    variable goes out of scope and we no longer have a pointer to the 
    newly-created control. You can't deallocate a control within its own 
    event handlers, so if at some point you want to remove one or more 
    dynamically-created controls, you have to search for them in the 
    Form.Controls array and/or maintain your own list of pointers to the 
    controls you create. Assuming that there are no control event handlers 
    running, it is safe to deallocate a control by just calling its Free 
    method.
    Reason 3. You really want to access controls by number.
I ran across this when I decided to write a board game similar to Reversi as a Delphi learning project. I had 100 TShape controls on a form, in a 10x10 grid. So, I painted all the shapes in the form designer and allowed it to give them names like "ShapeNN", but then I also declared an array of pointers to controls: "Board: array[1..10, 1..10] of TShape;" and populated it in the form's Create event. When I did this initially, I just used a hundred lines of code, but it has subsequently been pointed out that since these are the only TShape controls on the form, I could just as easily have iterated through the form's Controls array. Anyway, once it was set up I could access controls in a two-dimensional array, like this: "Board[3,5].Brush.Color := clRed;" -- which is more than I could have done with VB.
    If you want to close a form without giving it a chance to argue, call 
    the form's Release method. This is similar to Free, but it allows 
    event handlers (e.g. OnDestroy) to finish running before the memory 
    goes away.
    Modal forms "end their modal state" when you set the form's 
    ModalResult property to anything greater than zero. If you put a 
    button on a modal form and set the button's ModalResult property to 
    some value, then when the user clicks on that button the form will 
    close with the result you specified. You can find out what the result 
    was by calling ShowModal as a function; i.e. result := Form.ShowModal.
    
       p := new(big_thing);
       try
         blah(p);
         foo(p);
       finally
         dispose(p);
       end;
    The first line allocates a big block of memory. Then, in the "try" 
    block, we execute several statements, each of which might produce an 
    error--or, in other words, "raise an event."  If an error does occur, 
    the rest of the "try" block will be skipped, "finally" blocks will be 
    executed. If there are no errors, then the "finally" block will be 
    entered when the last statement in the "try" block completes. So, 
    either way, the big block of memory gets freed. These "try/finally" 
    blocks will trap anything up to and including a Windows GPF.
    In addition, you can construct "except" blocks which can provide local 
    error handling either for all errors or for particular types of error; 
    and you can also create your own global error handler to trap 
    exceptions that aren't otherwise handled by try blocks. See Chapter 7 
    in the Delphi User's Guide for more details.
    
    If you have text in a Pascal string and you want to pass it to a 
    function that expects a PChar, the following code is a "quick and 
    dirty" way of doing it, assuming that s is of type string and that the 
    string has room for one more character:
    s[length(s)+1] := #0;     { Appends a null to the end of the string }
    C_Style_Function(@s[1]);  { @s[1] is a PChar to the beginning of s }
    
    The "is" operator is used to compare an instance of an object to a 
    class of objects, to see if a typecast using "as" will work. If you 
    have a variable MySport of type TSport, and it currently contains an 
    instance of a TBasketball, then the following statements are true:
       (MySport is TSport)
       (MySport is TBasketball)
       not (MySport is TFootball)
    The combination of these two operators might lead to code such as the 
    following:
       function player_goodness(var MySport: TSport): integer;
       begin
         if (MySport is TBasketball) then
           player_goodness := (MySport as TBasketball).rebound_shots
         else if (MySport is TFootball) then
           player_goodness := (MySport as TFootball).total_yardage;  
       end;
    It has been pointed out that this would be better implemented as a 
    method which TSport defines and TBasketball and TFootball override, 
    but then it wouldn't illustrate how RTTI works, would it? :-)
    
    1. Display the icon somehow. Doesn't matter how you do it.
    2. Press Alt-PrintScreen to copy the current window to the clipboard.
    3. Load Paintbrush and do an Edit/Paste.
    4. Highlight the icon using the square selection tool and do an 
    Edit/Copy.
    5. Go to Options/Image Attributes and set the working area to 32x32 
    pixels.
    6. Do an Edit/Paste again.
    7. Save the result as a BMP file.
    
    Declaring a method in a TForm will allow you to handle 
    WM_WININICHANGED messages:
        procedure WMWinIniChange(var Message: TMessage); 
          message WM_WININICHANGE;
    The body of the implementation could look like:
    procedure TForm1.WMWinIniChange(var Message: TMessage);
    begin
      inherited;
      
      {.. react to someone mucking with control panel ..}
    end;
    The call to "inherited" is important.  Note also that message handlers 
    are special when calling their inherited since you
    don't refer to the name of the inherited.  This is because the 
    inherited is referring to the inherited message handler for
    this message number, which might not have a visible name or or even 
    the same name as you have given it, or in some cases,
    might not even exist (in which case you are really calling 
    DefaultHandler).
    
    Chuck Jazdzewski cjazdzewski@wpo.borland.com 
    elaborates:
    Also you might want to use the MemAlloc from Graphics which will 
    allocate the memory from the normal pascal sub-allocater if it is less 
    than 64k.  This routine will always the memory the way
    that is most efficient.
    Once you have allocated a larger-than-64k block of memory, you will 
    probably need to access elements within it. The problem is, pointer 
    arithmetic won't work too well when it crosses a 64k boundary. Thomas 
    AW Brown T.Brown@ite.ac.uk 
    discusses one way to solve this problem:
    The OffsetPointer procedure was lifted directly from the VCL source 
    code (in the CLASSES.PAS file). My knowledge of assembler is rather 
    limited, so suffice to say that you can drop it into a Unit and just 
    use it PROVIDED THAT YOU ALSO DECLARE the __AHSHIFT PROCEDURE PRIOR. 
    Here is a unit you could use, and include in a project and forget...
    {This works in Windows 3.1, 3.11, WorkGroups 3.11 and Windows95 
    preview}
    Unit OfsetPtr;
    interface
    function OffsetPointer(P: Pointer; Ofs: Longint): Pointer;
      
    implementation
      
    procedure __AHSHIFT; far; external 'KERNEL' index 113;
      
    function OffsetPointer(P: Pointer; Ofs: Longint): Pointer; assembler;
    asm
      MOV     AX,Ofs.Word[0]
      MOV     DX,Ofs.Word[2]
      ADD     AX,P.Word[0]
      ADC     DX,0
      MOV     CX,OFFSET __AHSHIFT
      SHL     DX,CL
      ADD     DX,P.Word[2]
    end;
    end.
    
    Someone posted a message requesting information on how to use Delphi 
    for a screen saver. 
    a) In the project file (*.dpr) add '{$D SCRNSAVE < saver name> } 
    after the uses clause.
    b) On the main form, turn off the border and icon controls. In the 
    activate method set the form left and top to 0, and set the 
    Windowstate to wsMaximize.
    c) In the form create method, set the application.OnMessage to a 
    method that controls the deactivation of the screen saver. Set the 
    application.OnIdle method to whatever display method for the saver.
    d) In the form create method the command line should be tested for /c 
    and /s. These are the command line parameters windows uses to define 
    whether the screensaver should run or configure. (/c is for 
    configuration)
    e) Compile the program, and rename the .exe to .scr. Move it to the 
    windows directory, and it should show up in the control panel.
    
    procedure whatever_whenever;
    var
      NewPage: TTabPage;
      NewPageNumber: word;
      NewButton: TButton;
    begin
      {Create the new TTabPage object}
      NewPage := TTabPage.Create(Application);
      {The page must be a child of the notebook}
      TabbedNotebook1.InsertControl(NewPage);
      {Add text to the notebook's Pages property; this will cause
      the new page to be added as the last tab on the notebook}
      NewPageNumber := TabbedNotebook1.Pages.Add(`New Page');
      TabbedNotebook1.PagesObjects[NewPageNumber] := NewPage;
      {The page needs controls on it; here's how to add one}
      NewButton := TButton.Create(Self);
      (TabbedNotebook1.Pages.Objects[NewPageNumber] as TWinControl)
       .InsertControl(NewButton);
      NewButton.Top := 10;
      NewButton.Height := 30;
      NewButton.Width := 100;
      NewButton.Caption := `OK';
    end;
    
    Use a TBitmap component as a memory DC.  You can then copy from 
    Bitmap.Canvas to your form's Canvas.
    
    You can't hide MDI children.  Windows does weird things when you try 
    to hide MDI children, so VCL doesn't permit it.
    
    "It is necessary in HelpInst to load the current .KWF file which one 
    wants to add the new help file to before running the add option."
    
    The API has a function ExtractIcon that does the job nicely.
    Like:
      { Extract the icon }
      TheIcon := ExtractIcon(HInstance,IconFile,IconNr);
      if TheIcon <  2 then
        TheIcon := LoadIcon(0,idi_Question);
    The rest of the code is available at Anders Ohlsson's home page in my 
    application launcher...
    
    > Can someone explain the palpalentry? I don't understand what the
    > array[0..0] does and how to use it. I would think for this record
    > that you would want a way to make the array of variable length but
    > I have no idea what array[0..0] does.
    Yes, you can use this for indicating the number of colours your 
    palette is
    to contain. You should use should allocate memory for the palette 
    dynamically,
    this way you can decide how much memory you want to put aside for the
    palette, i.e.
    VAR LogPal  : PLogPalette;
        Palette : HPalette;
        PalSize : LongInt;
    BEGIN
      ...
      PalSize:=2*SizeOf(Word)+n_Colors*SizeOf(TPaletteEntry));
       { 2 * SizeOf(Word) to get space for palVersion and palNumEntries }
       { n_Colors is (of course) the number of colors in the palette    }
      GetMem(LogPal,PalSize);
      LogPal^.palVersion:=$0300;
      LogPal^.palNumEntries:=n_Colors;
      LogPal^.palPalEntry[0]:= {Some colour};
      LogPal^.palPalEntry[1]:= {Some other colour};
      etc.
     ...
      FreeMem(LogPal,PalSize);
     ...
    END;
    This has to be compiled with $R- (no range checking), otherwise you 
    will
    get an error when you try using palPalEntry with an index higher than
    0.
    
Place A label on your Form and make a Accelerator with the & in the caption. Set the FocusControl property of the label to the edit control. That's all there is to it.
    This works for me in Delphi:
          canvas.font := my_font; {or assign separately to the fields of 
    'canvas.font'}
          width := canvas.textwidth(my_text);
          height := canvas.textheight(my_text);
    You need a canvas to use 'textwidth' and 'textheight', but it can be
    any old canvas (e.g. one that belongs to a handy bitmap).
    
    If the application uses database functions, you also have to include 
    the Borland Database Engine. You can just distribute the two 
    pre-packaged disks on the Delphi CD (they don't get installed to your 
    hard drive). And if the application uses ReportSmith, you have to 
    distribute the ReportSmith run-time. These are big; the BDE is two 
    disks and ReportSmith is five.