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.