Feedback Search Top Backward Forward

Questions and Answers

Written by Larry Salomon Jr.


Gotcha Notes!

It appears that if you have the following:


do {

   ulSzDestDrive= ... ;

   if (ulSzSourceDrive!=ulSzDestDrive) promptUser(...);
} while (ulSzSourceDrive!=ulSzDestDrive);
If the user removes the diskette when prompted, the next call to DosDevIOCtl() will return ERROR_NOT_DOS_DISK even though the diskette is formatted. The way around this is to close the drive and reopen using DosOpen().

Questions and Answers

James P Robertson ( writes:

I was just wondering if there was an easy way to have a "tool bar". A menu of buttons underneath the standard system menu. I looked into value set controls, but I don't think that is what I am looking for. It seems as though quite a few applications have this tool bar.

Good question, with a complex answer. There are actually two approaches to this problem:

  1. You can create the tool bar on top of your client. This has the advantage of simplicity, but you must insure that the client never overlaps the tool bar in the z-order.
  2. You can create the tool bar as another frame control. This has the advantage of being cleaner, but it is more difficult to do correctly.

To implement the first solution, you need to do a trick that was used by many wallpaper programs before better techniques were developed. Intercept the WM_PAINT message in your client window procedure as always, but just before exiting the window procedure, call WinSetWindowPos() to change the z-order to HWND_BOTTOM.

The second solution requires a bit more coding and lot more patience and involves a couple of steps.

  1. Subclass the frame and intercept the WM_QUERYFRAMECTLCOUNT and WM_FORMATFRAME.
  2. For the former message, call the old frame window procedure, add 1 to the result, and return this value. This message is sent to query the number of frame controls (system menu, titlebar, etc.). The "+1" is for the tool bar.
  3. For the latter message, call the old frame window procedure, loop through the array of SWP structures passed in mpParm1 and adjust the value of the client window accordingly. Use WinQueryWindowUShort() on the hwnd field of the SWP structure and look for FID_CLIENT.
  4. Insert your SWP values as the last item in the array.
That should do it, but be patient. The second method isn't exactly well-documented anywhere and there are snags which I have undoubtedly forgotten.