Docking a dialogue box on the toolbar
by Richard Russell, December 2006
DO NOT USE THE CODE IN THIS ARTICLE, IT HAS BEEN REPORTED THAT IT CAN MAKE YOUR PROGRAM UNSTABLE
A normal dialogue box is free to be moved anywhere on the desktop. This article describes how to 'dock' a dialogue box to a program's toolbar and fix it there so it tracks window movements etc.
The first step is to create the toolbar. This is done conventionally, except that space must be made on the toolbar for where the dialogue box will eventually be placed. This can easily be achieved by including a suitable number of 'separators':
INSTALL @lib$+"WINLIB" nbutts% = 12 DIM button%(nbutts%-1), buttid%(nbutts%-1) button%() = 1,0,0,0,0,0,0,0,0,0,0,2 buttid%() = 100,0,0,0,0,0,0,0,0,0,0,101 htoolbar% = FN_createtoolbar(nbutts%,button%(),buttid%())
Here ten separators (indicated by buttid% values of 0) are included between two conventional buttons. The dialogue box will eventually be placed in this gap.
Step two is to create the dialogue box. Again this is done conventionally, with the exception of an extra statement to make the dialogue box a child window:
INSTALL @lib$+"WINLIB2" dlg% = FN_newdialog("", 0, 0, 48, 16, 8, 1000) dlg%!16 = &568800C4 : REM Make dialogue box a child window PROC_radiobutton(dlg%, "", 501, 5, 2, 13, 13, &20000) PROC_radiobutton(dlg%, "", 502, 20, 2, 13, 13, 0) PROC_radiobutton(dlg%, "", 503, 35, 2, 13, 13, 0)
For the purpose of illustration the dialogue box contains three radiobuttons.
Finally the toolbar is given the WS_CLIPCHILDREN and WS_CLIPSIBLINGS styles and the dialogue box is docked to the toolbar:
PROC_showdialog(dlg%) SYS "GetWindowLong", htoolbar%, -16 TO ws% SYS "SetWindowLong", htoolbar%, -16, ws% OR &6000000 SYS "SetParent", !dlg%, htoolbar% SYS "SetWindowPos", !dlg%, 0, 30, 0, 0, 0, 1
The value in the SetWindowPos call (30 in this case) should be adjusted so that the dialogue box is positioned correctly.
The only complication, as so often, is if you need this to work with different DPI (dots per inch) settings. If the DPI changes the size of the dialogue box will also change, but the size of the toolbar won't. Therefore the dialogue box may no longer fit.
The most straightforward solution, in this case, is probably to design two (or more) different dialogue boxes for the different DPI values you want to support (96 dpi and 120 dpi will cover most eventualities). So if the above code works correctly at 96 dpi then making the following changes should probably be about right for 120 dpi:
dlg% = FN_newdialog("", 0, 0, 36, 12, 8, 1000) dlg%!16 = &568800C4 : REM Make dialogue box a child window PROC_radiobutton(dlg%, "", 501, 3, 2, 10, 10, &20000) PROC_radiobutton(dlg%, "", 502, 15, 2, 10, 10, 0) PROC_radiobutton(dlg%, "", 503, 27, 2, 10, 10, 0)