1. What should I give to Windows API functions that want a hWnd?

Each form has a property called Handle, which contains the form's hWnd. Many controls also have hWnd properties. However, don't try to pass Canvas.Handle to an API function expecting a hWnd, because TCanvas's Handle property is a hDC, not a hWnd.

2. Why do I get exception messages even though I am in protected code?

By default, the internal debugger will halt any time there is an exception, even if the exception is trapped by code. This can often be useful for debugging purposes. If it offends you, turn it off. You control it from the Options/Environment menu.

3. How do I write a global error handler?

Use the Application.OnException event. Look in the help under "application events" for details of how to create and attach an event handler to the application variable.

4. I am trying to call from Delphi and it GPFs. Whats up?

Based on the number of postings to comp.lang.pascal, it would seem that by far the largest number of problems calling Windows API functions or non-Delphi DLLs are caused by passing Pascal-style strings to functions that expect null-terminated (PChar) strings. This is the first thing you should check if you get a GPF or other strange results when calling an external function. See section 6.11 for more information on which type of strings go where.

5. When I use the Glyph property, how do I know which color is transparent?

Delphi always assumes that the color of the bottom left-hand corner pixel is the background color and should be displayed as transparent. Yes, it took me a while to figure this out. It's not documented anywhere, but if you have the VCL source, you can look at the code in BUTTONS.PAS.

6. How does Delphi handle Windows callbacks?

Just like C: You can get a far pointer to your callback procedure (you have to remember to declare it with the "far" qualifier, unless you have {F$+} in effect to force all calls to be far), pass the pointer to the Windows callback function, and there it is.

7. How does Delphis exception handling work?

The basic structure goes something like this:

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.

8. Do I have to understand object-oriented programming to use Delphi?

Well, yes, to a point. Delphi's user interface design tools produce object-oriented code. However, if you're familiar with either Visual Basic or Powerbuilder, you probably have enough understanding of OOP to get by. You can do a great deal in Delphi without having to create your own objects, which is the point at which it becomes important to really understand something about them.

9. Do I have to know a lot about the Windows API to use Delphi?

There seems to be a feeling that you need to know more about Windows to use Delphi than you do to use Visual Basic. This isn't really true; you can get by in both environments with a very minimal understanding of Windows internals. However, in both environments, you have to know at least a little about the Windows API in order to really make the most of what you have. The difference is that Delphi gives you a lot more power to do all these interesting things, so you feel more limited if you don't know how.

10. How do I close a modal form? For that matter, what is the best way to close any form?

Generally speaking, you call the form's Close method. This runs the OnClose event, which may decide it doesn't want to close, for example if there is unsaved data in the form. Close doesn't free the memory associated with the form, unless of course you put a call to Release in the form's OnClose event.

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.

Download Interview PDF