В общем рисовать как оказалось на неклиентской части формы вообще не проблема. Но я делаю форму Acrylic (Полупрозрачную с размытым фоном), и вот тут появляются проблемы. Если рисовать обычным способом, как на Canvas, то цвет получается тоже полупрозрачный. Путём экспериментов выяснил, что относительно нормально рисуется таким методом:
uses Winapi.Windows;
BitBlt( GetWindowDC( WindowHandleToPlatform( Form.Handle ).Wnd ), 0, 0, BitMap.Width, BitMap.Height, BitMap.Canvas.Handle, 0, 0, cmMergePaint );
В обычном случае последний аргумент должен быть cmSrcCopy, но с ним тоже получается полупрозрачная картинка. Помогает только cmMergePaint, НО! таким способом рисуется картинка с инвертированными цветами. То есть перед таким рисованием нужно её самому инвертировать.
Следующий шаг – это рисовать png картинку, так как редко надо рисовать просто непрозрачную прямоугольную картинку. С 32-битным TBitMap у меня пока что-то не получилось, а вот TPngImage вполне хорошо рисуется.
uses FMX.Platform.Win, Winapi.Windows, Vcl.Graphics, Vcl.Imaging.pngimage;
function TForm1.WinHandle: HWND;
begin
Result := WindowHandleToPlatform( Self.Handle ).Wnd;
end;
procedure TForm1.FormPaint(Sender: TObject; Canvas: TCanvas; const ARect: TRectF);
var
ACanvas: Vcl.Graphics.TCanvas;
png: TPngImage;
begin
ACanvas := Vcl.Graphics.TCanvas.Create;
ACanvas.Handle := GetWindowDC(Self.WinHandle);
png := TPngImage.Create;
png.LoadFromFile('C:\Image.png');
try
PatBlt( ACanvas.Handle, 0, 0, png.Width, png.Height, cmBlackness );
png.Draw( ACanvas, Rect( 0, 0, png.Width, png.Height ) );
finally
ReleaseDC(Self.WinHandle, ACanvas.Handle);
ACanvas.Handle := 0;
ACanvas.DisposeOf;
png.DisposeOf;
end;
end;
Но и тут есть подводные камни. Метод TPngImage.Draw, если заглянуть в его код становится понятно, что рисует он поверх того, что уже нарисовано и картина накладывается одна на другую быстро теряя прозрачность полупрозрачных пикселей. Поэтому перед её рисованием нужно стереть, что было до этого, с чем отлично справляется функция Winapi.Windows.PatBlt. Но таким образом появляется мерцание.
А так же я ещё не нашёл, как отловить в FireMonkey отловить у формы событие WM_NCPAINT. Пока что навесил рисование на событие формы OnPaint, но оно не стабильно работает в данном случае и бывает, когда картинка стирается и не рисуется, пока не наступит надобность перерисовать клиентскую часть формы.