Author: Tomas Rutkauskas
To define additional controls for a dialog box, I use a custom template as
demonstrated by the TOpenPictureDialog source code. My component is a TOpenDialog
descendant which needs space for extra controls on the bottom of the dialog. This
works fine, except for the dimensions of the dialog.
Answer:
I've found the idea of using a dialog template to be a real pain - you basically
have to throw away the Delphi TOpenDialog and do everything through the API
functions. Instead, I modify the dialog in the OnShow event. At the time this event
occurs, the component's Handle is valid.
I can change the size of the dialog window, or change its caption, using simple
messages. I can enumerate its controls by simply stepping through with
FindWindowEx. And I can add new controls using CreateWindow(). E.g. in a recent
project I added a button to the Font dialog that lets the user take action
regarding the selected font. I had calculated the position of the Rightmost
control, and the Lowest control, and used those to place the button. It's also
necessary to set the font for the new button, and to subclass the dialog, thus:
1 { ... }
2 BtnHandle := CreateWindow('BUTTON', '&Ban', WS_CHILD or WS_CLIPSIBLINGS or
3 WS_VISIBLE or WS_TABSTOP or BS_PUSHBUTTON, Rightmost - 72,
4 Lowest - 21, 72, 21, DlgH, BanBtn_ID, HInstance, nil);
5 {Set the new button's font}
6 TempFont := TFont.Create;
7 try
8 PostMessage(BtnHandle, WM_SETFONT, Longint(TempFont.Handle), MAKELPARAM(1, 0));
9 finally
10 TempFont.Free;
11 end;
12 {Subclass the dialog to process the new button}
13 Integer(@GlobalWas) := SetWindowLong(DlgH, GWL_WNDPROC, Longint(@BanBtnWndProc));
14 { ... }
The replacement dialog proc is pretty simple - if any control but our new button is
pressed, it passes the processing to the old dlgproc. If it IS our button, it
checks to make sure there IS a selection in the font name combobox (whose window
handle was obtained during the enumeration of the box's controls) and, if so, calls
a routine in the main form.
15
16 function BanBtnWndProc(HWindow: HWND; Msg: UINT; wParam: WPARAM;
17 lParam: LPARAM): LRESULT; stdcall;
18 {This wndproc subclasses the font dialog and responds to the added Ban button}
19 var
20 buff: array[0..MAX_PATH] of Char;
21 sel: Integer;
22 begin
23 if (Msg = WM_COMMAND) and (Lo(wParam) = BanBtn_ID) then
24 begin
25 sel := SendMessage(GlobalCBH, CB_GETCURSEL, 0, 0);
26 if Sel >= 0 then
27 SendMessage(GlobalCBH, WM_GETTEXT, MAX_PATH, Integer(@buff))
28 else
29 Buff[0] := #0;
30 if StrLen(Buff) > 0 then
31 MainForm.BanFont(StrPas(Buff))
32 else
33 MessageBeep(MB_ICONSTOP);
34 Result := 0;
35 end
36 else
37 Result := GlobalWas(HWindow, Msg, wParam, lParam);
38 end;
You can accomplish your modification of the file common dialogs using a similar technique.
|