2005. május 22., vasárnap
How to modify dialog boxes
Problem/Question/Abstract:
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:
{ ... }
BtnHandle := CreateWindow('BUTTON', '&Ban', WS_CHILD or WS_CLIPSIBLINGS or
WS_VISIBLE or WS_TABSTOP or BS_PUSHBUTTON, Rightmost - 72,
Lowest - 21, 72, 21, DlgH, BanBtn_ID, HInstance, nil);
{Set the new button's font}
TempFont := TFont.Create;
try
PostMessage(BtnHandle, WM_SETFONT, Longint(TempFont.Handle), MAKELPARAM(1, 0));
finally
TempFont.Free;
end;
{Subclass the dialog to process the new button}
Integer(@GlobalWas) := SetWindowLong(DlgH, GWL_WNDPROC, Longint(@BanBtnWndProc));
{ ... }
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.
function BanBtnWndProc(HWindow: HWND; Msg: UINT; wParam: WPARAM;
lParam: LPARAM): LRESULT; stdcall;
{This wndproc subclasses the font dialog and responds to the added Ban button}
var
buff: array[0..MAX_PATH] of Char;
sel: Integer;
begin
if (Msg = WM_COMMAND) and (Lo(wParam) = BanBtn_ID) then
begin
sel := SendMessage(GlobalCBH, CB_GETCURSEL, 0, 0);
if Sel >= 0 then
SendMessage(GlobalCBH, WM_GETTEXT, MAX_PATH, Integer(@buff))
else
Buff[0] := #0;
if StrLen(Buff) > 0 then
MainForm.BanFont(StrPas(Buff))
else
MessageBeep(MB_ICONSTOP);
Result := 0;
end
else
Result := GlobalWas(HWindow, Msg, wParam, lParam);
end;
You can accomplish your modification of the file common dialogs using a similar technique.
Feliratkozás:
Megjegyzések küldése (Atom)
Nincsenek megjegyzések:
Megjegyzés küldése