在向用户显示之前,我需要对TaskDialog进行一些更改。使用Windows API调用来处理对话框中的每个控件都相当简单。我需要更加确定我找到了哪个按钮。我希望找到一个地方,我可以读取按钮在按下时给出的结果。
换句话说,如果我按下一个会导致返回值的按钮(在Delphi中,它被称为模态结果)为100,我本来期望有一个API调用我可以调用以找出按钮的内容“回报价值”将是。我还没有找到这样的电话。
我不想依赖按钮文字..
这是我到目前为止所拥有的。
function EnumWindowsProcToFindDlgControls(hWindow: HWND; _param:LPARAM): BOOL; stdcall;
var
sClassName:string;
hBMP:THandle;
i:integer;
begin
SetLength(sClassName, MAX_PATH);
GetClassName(hWindow, PChar(sClassName), MAX_PATH);
SetLength(sClassName, StrLen(PChar(sClassName)));
if sClassName='Button' then
begin
// always 0...
i:=GetDlgCtrlID(hWindow);
if (i=100) or (i=102) then
begin
hBmp := LoadImage(HInstance, 'DISA', IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE or LR_LOADTRANSPARENT );
SendMessage(hWindow, BM_SETIMAGE, WPARAM(IMAGE_BITMAP), LPARAM(hBmp));
end;
end;
// keep looking
Result:=true;
end;
procedure TForm2.TaskDialog1DialogConstructed(Sender: TObject);
begin
EnumChildWindows(TaskDialog1.Handle, @EnumWindowsProcToFindDlgControls, 0);
end;
我怀疑用对话框做这样的事情并不完全“可敬”。
这是一个使用Delphi的VCL TTaskDialog组件的Delphi 10 Win32应用程序,它是Windows任务对话框功能的包装器。在显示之前,OnConstructed事件将触发,执行此代码。
感谢您的帮助!
答案 0 :(得分:10)
Win32按钮没有“返回值”,这就是没有API从中检索这样的值的原因。你在想什么是严格的VCL功能。
在Win32 API术语中,按钮可以具有控件ID,例如,在MessageBox()
的情况下,会将IDOK
,IDCANCEL
等标准ID值分配给对话框按钮。单击一个按钮并关闭对话框时,按钮的控件ID将用作函数返回值。
但是任务对话框不使用控件ID,这就是为什么你没有看到任何分配给对话框按钮的原因。
要识别特定的任务对话框按钮,我可以想到两种方法:
检索每个按钮的标题文本(GetWindowText()
),并将其与您感兴趣的标题进行比较。只需知道标准按钮(来自TTaskDialog.CommonButtons
属性)即可使用本地化文本,除非您可以控制应用程序的区域设置,否则不会使其成为定位标准按钮的合适选项。
向对话框发送TDM_ENABLE_BUTTON
消息以暂时禁用具有给定ID的所需按钮,然后枚举对话框的控件,直到找到禁用的子窗口(使用IsWindowEnabled()
),并且然后重新启用控件。然后,您可以根据需要操作找到的窗口。
对于操作按钮的Task Dialog messages和Task Dialog Notifications(例如触发TTaskDialog.OnButtonClicked
事件的TDN_BUTTON_CLICKED
),标准按钮使用IDOK
等ID, IDCANCEL
等自定义按钮(来自TTaskDialog.Buttons
属性)使用其ModalResult
属性作为其ID。
您可以通过TDM_ENABLE_BUTTON
直接发送SendMessage()
标准按钮,也可以通过TTaskDialogBaseButtonItem.Enabled
属性发送自定义按钮。
对于#2,这在我尝试时起作用:
uses
Winapi.CommCtrl;
function FindDisabledDlgControl(hWindow: HWND; _param: LPARAM): BOOL; stdcall;
type
PHWND = ^HWND;
begin
if not IsWindowEnabled(hWindow) then
begin
PHWND(_param)^ := hWindow;
Result := False;
end else
Result := True;
end;
procedure TForm2.TaskDialog1DialogConstructed(Sender: TObject);
var
hButton: HWND;
begin
// common tcbOk button
SendMessage(TaskDialog1.Handle, TDM_ENABLE_BUTTON, IDOK, 0);
hButton := 0;
EnumChildWindows(TaskDialog1.Handle, @FindDisabledDlgControl, LPARAM(@hButton));
SendMessage(TaskDialog1.Handle, TDM_ENABLE_BUTTON, IDOK, 1);
if hButton <> 0 then
begin
// use hButton as needed...
end;
// custom button
TaskDialog1.Buttons[0].Enabled := False;
hButton := 0;
EnumChildWindows(TaskDialog1.Handle, @FindDisabledDlgControl, LPARAM(@hButton));
TaskDialog1.Buttons[0].Enabled := True;
if hButton <> 0 then
begin
// use hButton as needed...
end;
end;