3

This question looks very simple, with VCL this is works fine (Image is TImage on VCL):

procedure TFormMain.btnDrawBackgroundClick(Sender: TObject);
var
  theme: HTHEME;
begin
  theme := OpenThemeData(0, 'TASKDIALOG');
  if theme <> 0 then
  try
    DrawThemeBackground(theme,
                        Image.Canvas.Handle,
                        TDLG_SECONDARYPANEL,
                        0,
                        Image.ClientRect,
                        nil);
  finally
    CloseThemeData(theme);
  end;
end;

Question: what I should change to get the same effect with FMX (on Windows)

Alex Egorov
  • 907
  • 7
  • 26

1 Answers1

4

Based on this answer you simply can't do that.

The problem is that with Firemonkey, you only have a single device context for the form and not one for each component. When a component needs to be redrawn, it gets passed the forms canvas but with clipping and co-ordinates mapped to the components location.

But there is always some workaround and you can try something like this.

procedure TFormMain.btnDrawBackgroundClick(Sender: TObject);
var
  lTheme : HTHEME;
  lStream : TMemoryStream;
  lBitmap : Vcl.Graphics.TBitmap;
begin
  lTheme := OpenThemeData(0, 'TASKDIALOG');
  if lTheme <> 0 then
  try
    lBitmap := Vcl.Graphics.TBitmap.Create;
    try
      lBitmap.Width := Round(Image.Width);
      lBitmap.Height := Round(Image.Height);
      DrawThemeBackground(lTheme, lBitmap.Canvas.Handle, TDLG_SECONDARYPANEL, 0, 
                          Rect(0, 0, lBitmap.Width, lBitmap.Height), nil);
      lStream := TMemoryStream.Create;
      try
        lBitmap.SaveToStream(lStream);
        Image.Bitmap.LoadFromStream(lStream);
      finally
        lStream.Free;
      end;
    finally
      lBitmap.Free;
    end;
  finally
    CloseThemeData(lTheme);
  end;
end;
Triber
  • 1,525
  • 2
  • 21
  • 38
  • 1
    And this is help's me to resolve this question: http://stackoverflow.com/questions/42928717/colors-of-the-tdialogservice-messagedialog – Alex Egorov Mar 22 '17 at 12:18
  • Why is this answer using VCL's `TBitmap` when the question is about FireMonkey instead? VCL and FMX are not meant to be mixed together. FMX's `TBitmap` does not have a `HDC` that you can draw on with the Win32 API. However, FMX's `TImage` does have an `OnPaint` event, and you can grab the Form's `HDC` to draw on. Or draw on a Win32 `HBITMAP` first and then type-cast a FMX `Canvas` to the appropriate descendant to access its underlying GDI+/Direct2D object and then draw the `HBITMAP` onto that as needed. – Remy Lebeau Mar 22 '17 at 16:18
  • 1
    Remy, thank you for your comment, but with FMX on Windows we have several problems which can't be worked without VCL (for example using TIcon for extracting MAINICON resource) – Alex Egorov Mar 23 '17 at 04:51