2008-10-20 9 views
5

Byłem przy użyciu kodu podobnego do tegoCzy można zastąpić wywołania MessageDlg do niestandardowego TForm/Dialog?

MessageDlg('', mtWarning, [mbOK], 0); 

całym moim projekcie, (dzięki narzędziu GExperts dialogowym komunikatu :)) i zastanawiałem się, czy ktoś zna sposób nie nadpisać rozmowę i pokazać własną rękę niestandardowy formularz.

Jedynym sposobem mogę myśleć to zrobić jej zrobić nową formę z czymś jak

function MessageDlg(const Msg: string; DlgType: TMsgDlgType; 
    Buttons: TMsgDlgButtons; HelpCtx: Longint): Integer; 
begin 
    //show my own code here 
end; 

i umieścić każdy z moich zastosowań list przed jednostką Dialogi ale tam jest gwarantowany sposób, aby upewnić się, że używa mojego kodu, a nie kodu jednostki Dialogs.
Nie podoba mi się pomysł kopiowania jednostki dialogów do lokalnego katalogu i wprowadzania w nim zmian.

Czy to wszystko za dużo pracy i powinienem po prostu użyć mojego własnego wywołania funkcji i zastąpić całą wiadomość MessageDlg moją własną. (co nie byłoby zabawne, ive prawdopodobnie użył MessageDlg zbyt dużo)

Odpowiedz

5

BTW, chcesz dodać go po Dialogi urządzenie w klauzuli uses

masz trzy możliwości moim zdaniem..

  1. Dodaj własną jednostkę af Jednostka Dialogs, która ma metodę o nazwie MessageDlg i ma tę samą sygnaturę, aby utworzyć własny formularz.
  2. Lub utwórz całkowicie nową metodę lub zestaw metod, który tworzy określone okna dialogowe przy użyciu własnego formularza.
  3. Czy globalne wyszukiwanie & Wymienić na MessageDlg z DarkAxi0mMessageDlg a następnie dodaj swoją jednostkę DarkAxi0mDialogs do klauzuli zastosowań.

Pierwsza z nich jest problematyczna, ponieważ można pominąć jednostkę i nadal uzyskać stary komunikat MessageDlg. Drugi ma dużo więcej zastosowań, ale zapewnia większą elastyczność w dłuższej perspektywie. Trzeci jest prawdopodobnie najłatwiejszy i najmniej wadny. Upewnij się, że wykonałeś kopię zapasową przed wykonaniem zamiany, a następnie użyj narzędzia różnicowego (np. Beyond Compare), aby sprawdzić zmiany.

+0

Również inne użycie do edycji synchronizacji, jeśli masz dużo ich w pliku, po prostu znajdź pierwszy, wybierz go do końca pliku i zsynchronizuj edycję. – skamradt

+0

Wyszukiwarka grep GExperts wykonuje dobrą robotę pomagając znaleźć wszystkie referencje. – skamradt

2

Polecam obudować MessageDlg wewnątrz własnych procedur, w ten sposób, jeśli zmienisz swoje procedury wszystkie okna dialogowe wiadomości zostaną zmienione i zachowasz standard.

Przykład: Utwórz niektóre procedury, takie jak Alert(), Error(), Warning() itp. Jeśli kiedykolwiek będziesz musiał zmienić komunikat o błędzie, musisz to zrobić tylko w jednym miejscu.

Któregoś dnia możesz chcieć dodać zdjęcie do swoich komunikatów o błędach, alertów ... cokolwiek, kto wie?

2

Można użyć narzędzia takiego jak TextPad do wyszukiwania/zamiany wszystkich wystąpień ciągu znaków w folderach i podfolderach. Sugerowałbym, abyś zastąpił "MessageDlg (" z "MyMessageDlg ("), aby móc go dostosować do woli. Powinno to potrwać 5 minut.

Myślę, że spowodowałoby to problemy z utworzeniem zamiennika i pozostawienie nazwany jak to jest obecnie w konflikcie z VCL

+0

Nie wspominając o mylących dla programistów konserwacji! – Blorgbeard

0

Możesz przejąć funkcję MessageDlg i wskazać na swoją własną funkcję MyMessageDlg (z tą samą sygnaturą), ale myślę, że byłoby to najmniej bezpieczne ze wszystkich rozwiązań.
Złe hacki zamiast czystego kodu IMO.

zachować oryginalne rozkazy z MessageDlg (ASM generowane przez kompilator)
Włóż dysk skok do kodu MyMessageDlg
... Wtedy każde wezwanie do MessageDlg rzeczywiście wykonać swój kod ...
Przywracanie oryginalny kod do MessageDlg
MessageDlg teraz zachowuje się jak zwykle

To działa, ale powinno być zarezerwowane dla rozpaczliwych sytuacjach ...

0

Utworzono funkcję MessageDlgEx na podstawie MessageDlg i upuszczono ją do jednego z moich plików "biblioteki", aby wszystkie moje aplikacje mogły z niego korzystać. moja funkcja pozwala ci określić domyślne przyciski anulowania &, teksty przycisków itp. niewłaściwą praktyką byłoby modyfikowanie/zamiana wbudowanej funkcji. nadal korzystam z wbudowanej funkcji, ale trzymaj tę funkcję pod ręką w sytuacjach, gdy potrzebuję trochę więcej.

FYI - funkcja zwraca numer naciśniętego przycisku. pierwszy przycisk to 1. naciśnięcie przycisku Zamknij powoduje powrót do wartości 0. przyciski nie mają znaków.

Używam tego przez około 5 lat & to mi dobrze służyło.

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; 
Powiązane problemy