加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 当迭代表单上的控件时,如何识别特定按钮?

发布时间:2020-12-15 04:17:53 所属栏目:大数据 来源:网络整理
导读:在向用户显示之前,我需要对TaskDialog进行一些更改.使用 Windows API调用来处理对话框中的每个控件都相当简单.我需要更加确定我找到了哪个按钮.我原本希望找到一个可以读取按钮按下时给出的结果的地方. 换句话说,如果我按下一个会导致返回值的按钮(在Delphi
在向用户显示之前,我需要对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,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事件触发,执行此代码.

谢谢您的帮助!

解决方法

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(如TDN_BUTTON_CLICKED,触发TTaskDialog.OnButtonClicked事件),标准按钮使用IDOK,IDCANCEL等ID,而自定义按钮(来自TTaskDialog.Buttons属性)使用其ModalResult属性作为其ID .

您可以通过SendMessage()直接发送TDM_ENABLE_BUTTON用于标准按钮,也可以通过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,0);
  hButton := 0;
  EnumChildWindows(TaskDialog1.Handle,@FindDisabledDlgControl,LPARAM(@hButton));
  SendMessage(TaskDialog1.Handle,1);
  if hButton <> 0 then
  begin
    // use hButton as needed...
  end;

  // custom button
  TaskDialog1.Buttons[0].Enabled := False;
  hButton := 0;
  EnumChildWindows(TaskDialog1.Handle,LPARAM(@hButton));
  TaskDialog1.Buttons[0].Enabled := True;
  if hButton <> 0 then
  begin
    // use hButton as needed...
  end;
end;

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读