2011-01-10 46 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

它看起来不完美,但它是一个开始。也许。