从样式 Dialog / ShowMessage 边框中排除 VCL 样式

Exclude VCL Styles from styling Dialog / ShowMessage borders

有什么方法可以将 VCL 样式从系统对话框边框的样式中排除。

具体是通过调用 MessageDlg 或 ShowMessage 显示的对话框。

我在 "The Road To Delphi" 上阅读了一些文章(顺便说一句,这是一个很棒的网站)但找不到答案。

这是我想要实现的目标:

现在(带样式边框的 Carbon 样式):

目标(具有标准 windows 边框的 Carbon 样式):

我仍然想要带样式的控件,但没有带样式的边框。

从父表单 StyleElements 中删除 seBorder 没有成功。

谢谢!

要设置无边框样式的表单,您必须从表单的 StyleElements 属性.

中删除 seBorder
  StyleElements := [seFont, seClient];

但是您必须为每个表单设置 属性。如果我理解正确的话,你想显示带有 Windows 边框的消息对话框。在那种情况下,为调用 ShowMessage 的表单设置 StyleElements 属性 将对对话框没有影响,因为这是全新的表单。

您需要做的是以某种方式将 StyleElements 属性 设置为 Delphi 创建的您无法访问的对话框。为此,您必须创建自己的表单 StyleHook 并替换为所有表单注册的 TFormStyleHook

只需在您的项目中添加以下单元,所有表单都将具有 Windows 边框,无需为每个表单显式设置。

unit WinBorder;

interface

uses
  Winapi.Windows,
  Winapi.Messages,
  Vcl.Themes,
  Vcl.Controls,
  Vcl.Forms;

type
  TWinBorderFormStyleHook = class(TFormStyleHook)
  protected
    procedure WndProc(var Message: TMessage); override;
  public
    constructor Create(AControl: TWinControl); override;
  end;

implementation

constructor TWinBorderFormStyleHook.Create(AControl: TWinControl);
begin
  inherited;
  OverridePaintNC := false;
end;

procedure TWinBorderFormStyleHook.WndProc(var Message: TMessage);
begin
  inherited;
  if Message.Msg = CM_VISIBLECHANGED then
    begin
      if (Control is TCustomForm) and (seBorder in TCustomForm(Control).StyleElements) then
        TCustomForm(Control).StyleElements := [seFont, seClient];
    end;
end;

initialization

  TCustomStyleEngine.UnRegisterStyleHook(TCustomForm, TFormStyleHook);
  TCustomStyleEngine.UnRegisterStyleHook(TForm, TFormStyleHook);
  TCustomStyleEngine.RegisterStyleHook(TCustomForm, TWinBorderFormStyleHook);
  TCustomStyleEngine.RegisterStyleHook(TForm, TWinBorderFormStyleHook);

finalization

  TCustomStyleEngine.UnRegisterStyleHook(TCustomForm, TWinBorderFormStyleHook);
  TCustomStyleEngine.UnRegisterStyleHook(TForm, TWinBorderFormStyleHook);
  TCustomStyleEngine.RegisterStyleHook(TCustomForm, TFormStyleHook);
  TCustomStyleEngine.RegisterStyleHook(TForm, TFormStyleHook);

end.

MessageDlg()ShowMessage() 是 Delphi VCL 函数。他们动态创建 Delphi TForm 并显示它,因此您没有机会对其进行自定义。但是,您可以使用 CreateMessageDialog() 代替创建相同的 TForm,然后根据需要修改其样式元素,然后显示它。例如:

function DoMessageDlgPosHelp(MessageDialog: TForm; X, Y: Integer): Integer;
begin
  with MessageDialog do
    try
      if X >= 0 then Left := X;
      if Y >= 0 then Top := Y;
      if (Y < 0) and (X < 0) then Position := poScreenCenter;
      Result := ShowModal;
    finally
      Free;
    end;
end;

procedure ShowStyledMessage(const Msg: string; const StyleElements: TStyleElements);
var
  Form: TForm;
begin
  Form := CreateMessageDialog(Msg, mtCustom, [mbOK]);
  Form.StyleElements := StyleElements;
  DoMessageDlgPosHelp(Form, -1, -1);
end;

这样称呼它:

ShowStyledMessage('Some text', [seFont, seClient]);

对话框如下所示: