I want to create a floating (top level) window that shows only Anti-Aliased text (no other window elements). I am trying to draw the text using GDI+ to maintain the alpha channel on the text rendering bitmap, but I'm having limited success.
I am able to create a transparent bitmap, but it looks as if the text drawing function thinks the background is black and not transparent, causing bad aliasing artifacts.
I've attached the full code, what am I missing? :
uses GDIPAPI ,GDIPOBJ;
var
GDIPToken: ULONG;
GDIStartupInput: TGDIPlusStartupInput;
procedure TOSDInfoForm.FormCreate(Sender: TObject);
var
bmp: TBitmap;
blend: TBLENDFUNCTION;
pointSrc, pointForm: TPoint;
bmpsize: TSize;
g: TGPGraphics;
fontFamily: TGPFontFamily;
font: TGPFont;
brush: TGPSolidBrush;
status: TStatus;
begin
BorderStyle := bsNone;
FormStyle := fsStayOnTop;
SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_LAYERED);
GDIStartupInput.SuppressBackgroundThread := False;
GDIStartupInput.SuppressExternalCodecs := False;
GDIStartupInput.GdiplusVersion := 1;
GdiplusStartup(GDIPToken, @GDIStartupInput, nil);
bmp := TBitmap.Create;
try
bmp.PixelFormat := pf32bit;
bmp.Width := Width;
bmp.Height := Height;
g := TGPGraphics.Create(bmp.Canvas.Handle);
try
//g.SetTextRenderingHint(TextRenderingHintClearTypeGridFit);
g.SetTextRenderingHint(TextRenderingHintAntiAliasGridFit);
g.Clear(MakeColor(0, 0, 0, 0)); // Clear with full transparent
fontFamily := TGPFontFamily.Create('Arial');
font := TGPFont.Create(fontFamily, 32, FontStyleRegular, UnitPixel);
brush := TGPSolidBrush.Create(MakeColor(255, 255, 0, 0)); // Red text
g.DrawString('Hello, World!', -1, font, MakePoint(10.0, 10.0), brush);
brush.Free;
font.Free;
fontFamily.Free;
finally
g.Free;
end;
pointSrc := Point(0, 0);
pointForm := Point(Left, Top);
bmpsize.cx := bmp.Width;
bmpsize.cy := bmp.Height;
blend.BlendOp := AC_SRC_OVER;
blend.BlendFlags := 0;
blend.SourceConstantAlpha := 255; // Opaque
blend.AlphaFormat := AC_SRC_ALPHA;
UpdateLayeredWindow(Handle, 0, @pointForm, @bmpsize, bmp.Canvas.Handle, @pointSrc, 0, @blend, ULW_ALPHA);
finally
bmp.Free;
end;
end;
procedure TOSDInfoForm.FormDestroy(Sender: TObject);
begin
GdiplusShutdown(GDIPToken);
end;
EDIT: The code above is functional thanks to Tom's tip, feel free to use it in your own code, take into account it uses GDI+ which requires at least Windows 7 to work without having to manually install GDI+.
You want to use anti-aliased rendering, ergo, change the current
g.SetTextRenderingHint(TextRenderingHintClearTypeGridFit);
to
g.SetTextRenderingHint(TextRenderingHintAntiAliasGridFit);