7
votes

Is there any way to exclude VCL Styles from styling a system dialogs' border.

Sepecifically a dialog that is shown by calling MessageDlg or ShowMessage.

I read some articles on "The Road To Delphi" (which is an excellent site btw) but couldn't find the answer.

Here is what i want to achieve:

Now (Carbon Style with styled borders):

now

Goal (Carbon Style with standard windows borders):

enter image description here

I still want to have styled controls but no styled border.

Removing seBorder from the parent forms StyleElements doesn't do the trick.

enter image description here

Thanks!

2
I think you should rephrase your statement that you already tried setting the parent forms style. The way it is written has already misled two people. Also, what dialogs exactly are you interested in, because a great number of dialogs do not even support styling without 3rd party units.Tom Brunberg
I rephrased the first sentencesChrisB
Thanks for the edit, but please also edit what you have tried. 'Setting' is the wrong word and misleading when you removed 'seBorder' from StyleElements. I suggest: Removing seBorder` from the parent forms StyleElements doesn't do the trick.`Tom Brunberg
It'll be interesting to hear the answer, but the goal screenshot looks a bit weird and ugly to me. Mixing a custom style with a random system style (who knows what users installed) doesn't sound like a good plan to me. In fact I've had so many user complaints because of skins that I now tend to shy away from them. The default windows styles might be boring, but they're well tested.Wouter van Nifterick

2 Answers

4
votes

MessageDlg() and ShowMessage() are Delphi VCL functions. They dynamically create a Delphi TForm and display that, so you do not have a chance to customise it. However, you can use CreateMessageDialog() instead to create the same TForm, then modify its style elements as needed, and then show it. For instance:

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;

Call it like this:

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

And the dialog looks like this:

screenshot

4
votes

To have styled form without borders you have to remove seBorder from form's StyleElements property.

  StyleElements := [seFont, seClient];

From form designer

But you have to set that property for each and every form. If I understood you correctly you want to show message dialog with Windows border. In that case setting StyleElements property for form that invokes ShowMessage will have no effect on dialog box, because that is completely new form.

What you have to do is to somehow set StyleElements property for dialog form that Delphi creates out of your reach. To do that you have to create your own form StyleHook and replace TFormStyleHook registered for all forms.

Just add following unit in your project and all forms will have Windows border, without the need to set it explicitly for every form.

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.