2008-10-20 58 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;