Delphi 是否可以覆盖对自定义TForm/Dialog的MessageDlg调用?

Delphi 是否可以覆盖对自定义TForm/Dialog的MessageDlg调用?,delphi,Delphi,我一直在使用类似的代码 MessageDlg('', mtWarning, [mbOK], 0); 在我的整个项目中,(感谢GExperts消息对话框工具:),我想知道是否有人知道一种方法可以覆盖调用并显示我自己的自定义表单 我能想到的唯一方法就是用类似的东西创造一种新的形式 function MessageDlg(const Msg: string; DlgType: TMsgDlgType; Buttons: TMsgDlgButtons; HelpCtx: Longint): Int

我一直在使用类似的代码

MessageDlg('', mtWarning, [mbOK], 0);
在我的整个项目中,(感谢GExperts消息对话框工具:),我想知道是否有人知道一种方法可以覆盖调用并显示我自己的自定义表单

我能想到的唯一方法就是用类似的东西创造一种新的形式

function MessageDlg(const Msg: string; DlgType: TMsgDlgType;
  Buttons: TMsgDlgButtons; HelpCtx: Longint): Integer;
begin
  //show my own code here
end;
并将其放在对话框单元之前的每个“我的使用”列表中,但是否有保证方法确保其使用我的代码而不是对话框单元代码。
我不喜欢将对话单元复制到本地目录并对其进行更改


或者这需要做很多工作,我应该使用自己的函数调用并用自己的函数替换所有MessageDlg吗。(这不会很有趣,我可能太多使用MessageDlg了)

我建议您将MessageDlg封装在自己的过程中,这样,如果您更改过程,所有消息对话框都将更改,并且您保持标准

示例:创建一些过程,例如,Alert()、Error()、Warning()等。如果您需要更改错误消息的外观,则只需在一个位置执行

有一天你可能想在错误消息、警报中添加一张图片。。。不管怎样,谁知道呢?

您可以使用类似的工具在文件夹和子文件夹中搜索/替换字符串的所有实例。因此,我建议您将“MessageDlg”()替换为“MyMessageDlg”(),以便您可以随意定制它。这需要全部5分钟的时间


我认为创建替换项并将其命名为VCL可能会导致问题。

顺便说一句,您希望将其添加到uses子句中的对话框单元之后

我认为你有三个选择:

  • 在Dialogs单元之后添加您自己的单元,该单元有一个名为MessageDlg的方法,并且具有创建您自己表单的相同签名
  • 或者创建一个全新的方法或一组方法,使用您自己的表单创建特定的对话框
  • 用Darkaxi0MessageDLG对MessageDlg进行全局搜索和替换,然后将Darkaxi0MessageDLG对话框单元添加到uses子句中

  • 第一个是有问题的,因为你可能会错过一个单元,仍然会得到旧的MessageDlg。第二个需要更多的使用,但从长远来看提供了更好的灵活性。第三个可能是最简单的,缺点最少。确保在进行替换之前备份,然后使用diff工具(如)检查您的更改。

    您可以劫持MessageDlg函数,并将其指向您自己的MyMessageDlg函数(具有相同的签名),但我认为这是所有解决方案中最不安全的。
    一个糟糕的黑客程序代替了干净的代码。

    保存MessageDlg(编译器生成的asm)的原始操作码
    硬跳转到MyMessageDlg代码
    …然后对MessageDlg的任何调用都将实际执行您的代码…
    将原始代码还原为MessageDlg
    MessageDlg现在的行为与往常一样


    它可以工作,但应该是为绝望的情况保留的。

    我基于MessageDlg创建了一个MessageDlgEx函数,并将其放入我的一个“库”中“我的功能”允许您指定默认和取消按钮、给出按钮文本等。修改/替换内置功能是一种不好的做法。我仍然使用内置功能,但在需要更多功能的情况下保留此功能

    仅供参考——该函数返回按下的按钮数。第一个按钮为1。按下“关闭”会导致返回值为0。按钮没有图示符

    我已经用了5年了&它对我很有用

    function MessageDlgEx(Caption, Msg: string; AType: TMsgDlgType;
                          AButtons: array of string;
                          DefBtn, CanBtn: Integer; iWidth:integer=450;bCourier:boolean=false): Word;
    const
      icMin=50;
      icButtonHeight=25;
      icInterspace=10;
      icButtonResultStart=100;
      icFirstButtonReturnValue=1;
    var
      I, iButtonWidth, iAllButtonsWidth,
      iIconWidth,iIconHeight:Integer;
      LabelText:String;
      Frm: TForm;
      Lbl: TLabel;
      Btn: TBitBtn;
      Glyph: TImage;
      FIcon: TIcon;
      Rect:TRect;
      Caption_ca:Array[0..2000] of Char;
    begin
      { Create the form.}
      Frm := TForm.Create(Application);
      Frm.BorderStyle := bsDialog;
      Frm.BorderIcons := [biSystemMenu];
      Frm.FormStyle := fsStayOnTop;
      Frm.Height := 185;
      Frm.Width := iWidth;
      Frm.Position := poScreenCenter;
      Frm.Caption := Caption;
      Frm.Font.Name:='MS Sans Serif';
      Frm.Font.Style:=[];
      Frm.Scaled:=false;
    
      if ResIDs[AType] <> nil then
        begin
          Glyph := TImage.Create(Frm);
          Glyph.Name := 'Image';
          Glyph.Parent := Frm;
    
          FIcon := TIcon.Create;
          try
            FIcon.Handle := LoadIcon(HInstance, ResIDs[AType]);
            iIconWidth:=FIcon.Width;
            iIconHeight:=FIcon.Height;
            Glyph.Picture.Graphic := FIcon;
            Glyph.BoundsRect := Bounds(icInterspace, icInterspace, FIcon.Width, FIcon.Height);
          finally
            FIcon.Free;
          end;
        end
        else
        begin
          iIconWidth:=0;
          iIconHeight:=0;
        end;
    
      { Loop through buttons to determine the longest caption. }
      iButtonWidth := 0;
      for I := 0 to High(AButtons) do
        iButtonWidth := Max(iButtonWidth, frm.Canvas.TextWidth(AButtons[I]));
    
      { Add padding for the button's caption}
      iButtonWidth := iButtonWidth + 18;
    
      {assert a minimum button width}
      If iButtonWidth<icMin Then
        iButtonWidth:=icMin;
    
      { Determine space required for all buttons}
      iAllButtonsWidth := iButtonWidth * (High(AButtons) + 1);
    
      { Each button has padding on each side}
      iAllButtonsWidth := iAllButtonsWidth +icInterspace*High(AButtons);
    
      { The form has to be at least as wide as the buttons with space on each side}
      if iAllButtonsWidth+icInterspace*2 > Frm.Width then
        Frm.Width := iAllButtonsWidth+icInterspace*2;
    
      if Length(Msg)>sizeof(Caption_ca) then
        SetLength(Msg,sizeof(Caption_ca));
    
      { Create the message control}
      Lbl := TLabel.Create(Frm);
      Lbl.AutoSize := False;
      Lbl.Left := icInterspace*2+iIconWidth;
      Lbl.Top := icInterspace;
      Lbl.Height := 200;
      Lbl.Width := Frm.ClientWidth - icInterspace*3-iIconWidth;
      Lbl.WordWrap := True;
      Lbl.Caption := Msg;
      Lbl.Parent := Frm;
    
      if bCourier then
        lbl.Font.Name:='Courier New';
    
      Rect := Lbl.ClientRect;
      LabelText:=Lbl.Caption;
      StrPCopy(Caption_ca, LabelText);
    
      Lbl.Height:=DrawText(Lbl.Canvas.Handle,
                           Caption_ca,
                           Length(LabelText),
                           Rect,
                           DT_CalcRect or DT_ExpandTabs or DT_WordBreak Or DT_Left);
    
    
      If Lbl.Height<iIconHeight Then
        Lbl.Height:=iIconHeight;
    
      { Adjust the form's height accomodating the message, padding and the buttons}
      Frm.ClientHeight := Lbl.Height + 3*icInterspace + icButtonHeight;
    
      { Create the pusbuttons}
      for I := 0 to High(AButtons) do
        begin
          Btn := TBitBtn.Create(Frm);
          Btn.Height := icButtonHeight;
          Btn.Width := iButtonWidth;
          Btn.Left:=((Frm.Width-iAllButtonsWidth) Div 2)+I*(iButtonWidth+icInterspace);
          Btn.Top := Frm.ClientHeight - Btn.height-icInterspace;
          Btn.Caption := AButtons[I];
          Btn.ModalResult := I + icButtonResultStart + icFirstButtonReturnValue;
          Btn.Parent := Frm;
    
          If I=DefBtn-1 Then
            Begin
              Frm.ActiveControl:=Btn;
              Btn.Default:=True;
            End
            Else
            Btn.Default:=False;
    
          If I=CanBtn-1 Then
            Btn.Cancel:=True
            Else
            Btn.Cancel:=False;
        end;
    
      Application.BringToFront;
    
      Result := Frm.ShowModal;
    
      {trap and convert user Close into mrNone}
      If Result=mrCancel Then
        Result:=mrNone
        Else
        If Result>icButtonResultStart Then
          Result:=Result - icButtonResultStart
          Else
          Exception.Create('Unknown MessageDlgEx result');
    
      Frm.Free;
    end;
    
    函数消息DLGEX(标题,消息:字符串;AType:TMsgDlgType;
    邻接子:字符串数组;
    defftn,CanBtn:Integer;iWidth:Integer=450;bCourier:boolean=false):字;
    常数
    icMin=50;
    icButtonHeight=25;
    icInterspace=10;
    icButtonResultStart=100;
    icFirstButtonReturnValue=1;
    变量
    一、 iButtonWidth,iAlButtonWidth,
    iIconWidth,iIconHeight:整数;
    标签文本:字符串;
    Frm:TForm;
    Lbl:TLabel;
    Btn:TBitBtn;
    铭文:提摩日;
    菲康:提康;
    Rect:TRect;
    描述:字符的数组[0..2000];
    开始
    {创建表单。}
    Frm:=TForm.Create(应用程序);
    Frm.BorderStyle:=bsDialog;
    Frm.BorderIcons:=[双系统菜单];
    Frm.FormStyle:=fsStayOnTop;
    起始高度:=185;
    Frm.宽度:=i宽度;
    Frm.位置:=位置中心;
    Frm.标题:=标题;
    Frm.Font.Name:=“MS无衬线”;
    Frm.Font.Style:=[];
    Frm.缩放:=假;
    如果ResIDs[AType]nil,则
    开始
    Glyph:=TImage.Create(Frm);
    Glyph.Name:=“图像”;
    Glyph.Parent:=Frm;
    FIcon:=TIcon.Create;
    尝试
    FIcon.Handle:=LoadIcon(HInstance,ResIDs[AType]);
    iIconWidth:=FIcon.Width;
    iIconHeight:=FIcon.Height;
    Glyph.Picture.Graphic:=FIcon;
    Glyph.BoundsRect:=边界(icInterspace、icInterspace、FIcon.Width、FIcon.Height);
    最后
    自由的;
    结束;
    结束
    其他的
    开始
    iIconWidth:=0;
    iIconHeight:=0;
    结束;
    {循环浏览按钮以确定最长的标题。}
    iButtonWidth:=0;
    对于I:=0到高(邻接)do
    iButtonWidth:=Max(iButtonWidth,frm.Canvas.TextWidth(AButtons[I]);
    {为按钮标题添加填充}
    iButtonWidth:=iButtonWidth+18;
    {断言最小按钮宽度}
    如果iButtonWidth Frm.宽度,则
    起始宽度:=iAllButtonsWidth+icInterspace*2;
    如果长度(Msg)>sizeof(标题\u ca),则
    设置长度(Msg,sizeof(Caption_ca));
    {创建消息控件}
    Lbl:=TLabel.Create(Frm);
    Lbl.AutoSize:=False;
    Lbl.Left:=icInterspace*2+IICONWITH;
    Lbl.Top:=icInterspace;
    磅高:=200;
    Lbl.Width:=Frm.ClientWidth-iInterspace*3-iIconWidth;
    Lbl.WordWrap:=真;
    Lbl.标题:=味精;
    Lbl.父项:=Frm;
    如果是游客的话