2011-01-10 81 views
2

我想顯示使用ShowMessage,看起來像這樣的表:如何在ShowMessage中顯示錶格?

short   | Description for "short" 
verylongtext  | Description for "verylongtext" 

我如何獲得兩個正確對齊列一樣,在一個簡單的消息對話框?

我試圖使用空格對齊列,但ShowMessage的字體是可變的。然後我嘗試使用製表符對齊它們,但我不知道如何計算每行的適當製表符數。

有沒有可靠的方法來計算標籤計數? PS:我想避免爲此寫一個自定義對話框。

回答

7

您也可以在自定義對話框中使用列表視圖。

List view dialog box http://privat.rejbrand.se/lvdlg.png

嘗試

type StringArray = array of string; 

procedure ShowMemoMessage(AOwner: TForm; const Caption: string; Col1, Col2: StringArray; const DialogType: TMsgDlgType = mtInformation; const DlgWidth: integer = 360; const DlgHeight: integer = 200); 
var 
    dlg: TForm; 
    lv: TListView; 
    btn: TButton; 
    IconType: PChar; 
    icon: HICON; 
    image: TImage; 
    sh: TShape; 
    bvl: TBevel; 
    i: Integer; 
begin 

    if length(Col1) <> length(Col2) then 
    raise Exception.Create('The length of the columns doesn''t match.'); 

    dlg := TForm.Create(AOwner); 
    try 
    dlg.BorderStyle := bsDialog; 
    dlg.Caption := Caption; 
    dlg.Width := DlgWidth; 
    dlg.Height := DlgHeight; 
    dlg.Position := poScreenCenter; 
    btn := TButton.Create(dlg); 
    btn.Parent := dlg; 
    btn.Caption := 'OK'; 
    btn.ModalResult := mrOk; 
    btn.Left := dlg.ClientWidth - btn.Width - 8; 
    btn.Top := dlg.ClientHeight - btn.Height - 8; 
    lv := TListView.Create(dlg); 
    lv.Parent := dlg; 
    lv.Color := dlg.Color; 
    lv.ReadOnly := true; 
    lv.BorderStyle := bsNone; 
    lv.Left := 8; 
    lv.Top := 8; 
    lv.Width := dlg.ClientWidth - 16; 
    lv.Height := dlg.ClientHeight - 16 - 8 - 4 - btn.Height; 
    lv.ViewStyle := vsReport; 
    lv.RowSelect := true; 
    with lv.Columns.Add do 
    begin 
     Caption := 'Name'; 
     Width := 150; 
    end; 
    lv.Columns.Add.Caption := 'Value'; 
    lv.ShowColumnHeaders := false; 

    for i := 0 to high(Col1) do 
     with lv.Items.Add do 
     begin 
     Caption := Col1[i]; 
     SubItems.Add(Col2[i]); 
     end; 

    sh := TShape.Create(dlg); 
    sh.Parent := dlg; 
    sh.Align := alBottom; 
    sh.Shape := stRectangle; 
    sh.Pen.Color := clWhite; 
    sh.Brush.Color := clWhite; 
    sh.Height := btn.Height + 16; 

    bvl := TBevel.Create(dlg); 
    bvl.Parent := dlg; 
    bvl.Align := alBottom; 
    bvl.Height := 2; 
    bvl.Style := bsLowered; 

    case DialogType of 
     mtWarning: 
     begin 
      MessageBeep(MB_ICONWARNING); 
      IconType := IDI_WARNING; 
     end; 
     mtError: 
     begin 
      MessageBeep(MB_ICONERROR); 
      IconType := IDI_ERROR; 
     end; 
     mtInformation: 
     begin 
      MessageBeep(MB_ICONINFORMATION); 
      IconType := IDI_INFORMATION; 
     end; 
     mtConfirmation: 
     begin 
      MessageBeep(MB_ICONQUESTION); 
      IconType := IDI_QUESTION; 
     end; 
     mtCustom: {silence}; 
    end; 

    if DialogType <> mtCustom then 
    begin 
     image := TImage.Create(dlg); 
     image.Parent := dlg; 
     icon := LoadIcon(0, IconType); 
     image.AutoSize := true; 
     image.Picture.Icon.Handle := icon; 
     image.Left := 16; 
     image.Top := 16; 
     lv.Left := image.Width + 32; 
     lv.Top := 16; 
     lv.Height := lv.Height - 8; 
    end; 

    dlg.ShowModal; 
    finally 
    dlg.Free; 
    end; 
end; 

,然後就這樣稱呼它

procedure TForm1.FormCreate(Sender: TObject); 
var 
    col1, col2: StringArray; 
begin 

    SetLength(col1, 4); 
    col1[0] := 'alpha'; col1[1] := 'beta'; col1[2] := 'gamma'; col1[3] := 'delta'; 

    SetLength(col2, 4); 
    col2[0] := 'yes'; col2[1] := 'no'; col2[2] := 'no'; col2[3] := 'no'; 

    ShowMemoMessage(Self, 'Test', col1, col2); 

end; 

這樣的列都保證保持一致,你不必擔心片停止。

List view dialog box http://privat.rejbrand.se/lvdlg2.png

鼠標懸停:

List view dialog box http://privat.rejbrand.se/lvdlg3.png

6

如果你沒有爲此寫一個自定義對話框,你什麼時候可以?這並不難。只需創建一個表單,在其上放置一個TMemo並只讀備忘錄。您可以設置像Courier New等寬字體,並解決您的問題。您也獲得了滾動條和選擇的優勢,您可以選擇將其設爲非模態。

我甚至會建議在網格(如TStringGrid)中顯示這種類型的數據而不是備忘錄或標籤。

計算如何在消息框中顯示此文本將需要更多的努力,而不僅僅是創建自定義對話框。

+0

等寬看起來嚇人,但定製對話是解決方案都是一樣的 – 2011-01-10 17:15:52

+0

好了,你讓我相信,我會與Adreas的解決方案去。 – 2011-01-11 09:42:37

0

根據所運行代碼(Vista的+或沒有)操作系統版本,UseLatestCommonDialog設置與否,和主題是否啓用與否,無論ShowMessage調用TaskDialogIndirectCreateMessageDialog

CreateMessageDialog的情況下,您可以運行算法獲取短消息的字符差異,然後向最長的消息添加1個選項卡,並將最多8個字符差異的1個選項卡加上一個選項卡,字符串,因爲'CreateMessageDialog'在調用DrawText時不調整製表符,每個默認值爲8個字符。儘管這可能不被認爲是可靠的方法,但在短消息中重複短或長的字符,如果標籤太少或太少,我不會感到驚訝。更可靠的方法是將系統的消息字體(SystemParametersInfoSPI_GETNONCLIENTMETRICS)選擇爲臨時畫布,然後在致電ShowMessage之前進行精確測量。

我不知道如何處理'TaskDialogIndirect'的情況。

所有的一切,我upvoting Golez's answer .. :)

1

剛剛創建的東西,顯示彈出這樣的: Result

只需撥打下面的步驟,並添加一個的TStringList作爲參數。 當然,你可以通過使用TListView,圖標,滾動條等來實現這一點。

把它放在一個單獨的單元中,你總是能夠很容易地顯示這樣的東西。

uses ..., StdCtrls, ExtCtrls; 


procedure ShowTablePopup(SL:TStringList); 
var 
    LButtonOK: TButton; 
    LMemo: TMemo; 
    LPanel: TPanel; 
    LForm: TForm; 
begin 
    LForm := TForm.Create(Application); 
    LMemo := TMemo.Create(LForm); 
    LPanel := TPanel.Create(LForm); 
    LButtonOK := TButton.Create(LForm); 

    LForm.Left := 0; 
    LForm.Top := 0; 
    LForm.Caption := 'Values'; 
    LForm.ClientHeight := 250; 
    LForm.ClientWidth := 400; 

    LMemo.Parent := LForm; 
    LMemo.AlignWithMargins := True; 
    LMemo.Left := 3; 
    LMemo.Top := 3; 
    LMemo.Width := 295; 
    LMemo.Height := 226; 
    LMemo.Align := alClient; 
    LMemo.Font.Name := 'Courier New'; 
    LMemo.Lines.Assign(SL); 

    LPanel.Parent := LForm; 
    LPanel.Caption := ''; 
    LPanel.Left := 0; 
    LPanel.Top := 232; 
    LPanel.Width := 301; 
    LPanel.Height := 37; 
    LPanel.Align := alBottom; 
    LPanel.BevelOuter := bvNone; 

    LButtonOK.Parent := LPanel; 
    LButtonOK.AlignWithMargins := True; 
    LButtonOK.Left := 223; 
    LButtonOK.Top := 3; 
    LButtonOK.Width := 75; 
    LButtonOK.Height := 31; 
    LButtonOK.Align := alRight; 
    LButtonOK.Caption := '&OK'; 
    LButtonOK.ModalResult := mrOk; 
    LButtonOK.Default := True; 

    LForm.ShowModal; 
end; 

如何使用它例如:

var 
    SL:TStringList; 
begin 
    SL := TStringList.Create; 
    try 
    SL.Add('short   | Description for "short"'); 
    SL.Add('verylongtext  | Description for "verylongtext"'); 
    ShowTablePopup(SL); 
    finally 
    SL.Free; 
    end; 
end; 
0

只是爲了保持完整性,我給怎麼可能構建一個自定義對話框一個簡單的例子:

procedure ShowMemoMessage(AOwner: TForm; const Caption, Text: string; const DialogType: TMsgDlgType = mtInformation; const DlgWidth: integer = 360; const DlgHeight: integer = 200); 
var 
    dlg: TForm; 
    re: TRichEdit; 
    btn: TButton; 
    IconType: PChar; 
    icon: HICON; 
    image: TImage; 
    sh: TShape; 
    bvl: TBevel; 
begin 
    dlg := TForm.Create(AOwner); 
    try 
    dlg.BorderStyle := bsDialog; 
    dlg.Caption := Caption; 
    dlg.Width := DlgWidth; 
    dlg.Height := DlgHeight; 
    dlg.Position := poScreenCenter; 
    btn := TButton.Create(dlg); 
    btn.Parent := dlg; 
    btn.Caption := 'OK'; 
    btn.ModalResult := mrOk; 
    btn.Left := dlg.ClientWidth - btn.Width - 8; 
    btn.Top := dlg.ClientHeight - btn.Height - 8; 
    re := TRichEdit.Create(dlg); 
    re.Parent := dlg; 
    re.Color := dlg.Color; 
    re.ReadOnly := true; 
    re.BorderStyle := bsNone; 
    re.Left := 8; 
    re.Top := 8; 
    re.Width := dlg.ClientWidth - 16; 
    re.Height := dlg.ClientHeight - 16 - 8 - 4 - btn.Height; 
    re.Lines.Text := Text; 

    sh := TShape.Create(dlg); 
    sh.Parent := dlg; 
    sh.Align := alBottom; 
    sh.Shape := stRectangle; 
    sh.Pen.Color := clWhite; 
    sh.Brush.Color := clWhite; 
    sh.Height := btn.Height + 16; 

    bvl := TBevel.Create(dlg); 
    bvl.Parent := dlg; 
    bvl.Align := alBottom; 
    bvl.Height := 2; 
    bvl.Style := bsLowered; 

    case DialogType of 
     mtWarning: 
     begin 
      MessageBeep(MB_ICONWARNING); 
      IconType := IDI_WARNING; 
     end; 
     mtError: 
     begin 
      MessageBeep(MB_ICONERROR); 
      IconType := IDI_ERROR; 
     end; 
     mtInformation: 
     begin 
      MessageBeep(MB_ICONINFORMATION); 
      IconType := IDI_INFORMATION; 
     end; 
     mtConfirmation: 
     begin 
      MessageBeep(MB_ICONQUESTION); 
      IconType := IDI_QUESTION; 
     end; 
     mtCustom: {silence}; 
    end; 

    if DialogType <> mtCustom then 
    begin 
     image := TImage.Create(dlg); 
     image.Parent := dlg; 
     icon := LoadIcon(0, IconType); 
     image.AutoSize := true; 
     image.Picture.Icon.Handle := icon; 
     image.Left := 16; 
     image.Top := 16; 
     re.Left := image.Width + 32; 
     re.Top := 16; 
     re.Height := re.Height - 8; 
    end; 

    dlg.ShowModal; 
    finally 
    dlg.Free; 
    end; 
end; 

用法示例:

ShowMemoMessage(Self, 'Test', 'This is a long text.'#13#10#13#10'Alpha:'#9#9'Yes'#13#10'Beta:'#9#9'No'); 

Rich Edit dialog box http://privat.rejbrand.se/redlg.png

它看起來不完美,但它是一個開始。也許。