2008-10-20 78 views
5

我一直使用类似于此你可以重写MessageDlg调用自定义TForm /对话框吗?

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

回答

5

顺便说一句,你想在你的使用条款的对话框之后把它添加单元

你必须在我看来三种选择:。

  1. 添加自己的单位af ter 对话框单位有一个名为MessageDlg的方法,并具有相同的签名来创建您自己的表单。
  2. 或者创建一个全新的方法或一组方法,它们使用您自己的形式创建特定的对话框。
  3. 进行全局搜索&替换为的MessageDlgDarkAxi0mMessageDlg然后你DarkAxi0mDialogs单元添加到您的使用条款。

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

+0

同步编辑的另一个用途是,如果您在文件中有很多文件,只需找到第一个文件,然后在文件末尾选择它并同步编辑。 – skamradt 2008-10-21 01:55:09

2

我建议你将MessageDlg封装在你自己的程序中,这样如果你改变了你的程序,你所有的消息对话框都会被改变,标准。例如:创建Alert(),Error(),Warning()等程序。如果您需要更改错误消息的外观,您只需要在一个地方完成。

有一天,你可能想添加一张图片到你的错误消息,警报......无论如何,谁知道?

2

您可以使用像TextPad这样的工具来搜索/替换跨文件夹和子文件夹的所有字符串实例。所以,我建议你用“MyMessageDlg(”,以便你可以随意自定义它)替换“MessageDlg(”),应该花费5分钟的全部时间。

我认为这会导致你创建替换的问题并离开它命名因为它是目前与VCL冲突

+0

更不用说让维护程序员混淆了! – Blorgbeard 2008-10-21 05:33:46

0

您可以劫持MessageDlg函数并使其指向您自己的MyMessageDlg函数(具有相同的签名),但我认为这将是所有解决方案中最不安全的。
代替干净的代码国际海事组织的恶意破解。

保存的MessageDlg的原始操作码(由编译器产生的ASM)
把硬盘跳到你MyMessageDlg代码
......然后的MessageDlg任何调用将实际执行你的代码...
恢复原代码的MessageDlg
的MessageDlg现在的行为像往常一样

它的工作原理,但应该是保留绝望的处境 ...

0

我制作了一个基于MessageDlg的MessageDlgEx函数,并将其放到我的“库”文件之一中,这样我的所有应用程序都可以使用它。我的功能允许你指定默认的取消按钮,给按钮文本等等,修改/替换内置函数是一个不好的做法。我仍然使用内置功能,但在需要更多功能的情况下可以随时保持此功能。

仅供参考 - 该函数返回按下按钮的数量。第一个按钮是1.按下Close会导致返回值为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;