
GDI Behavior in Windows11 24H2 and Delphi 11.3 High DPI Support
Disclaimer:
I am Japanese, so my English may not be perfect. If there are any mistakes, I apologize in advance.
Table of Contents
Background of the Issue
Direct HDC Management Solution
Key Implementation Points
Why This Solution Works
Summary
When developing high DPI-aware applications in Delphi 11.3, you may encounter unexpected issues with image rendering when using TImageCollection and TVirtualImage. Particularly in Windows 11 24H2 and later versions, subtle changes in GDI (Graphics Device Interface) behavior have made traditional implementation methods less reliable for proper image display.
Background of the Issue Traditionally, when handling images with TImageCollection and TVirtualImage, images were drawn directly from the components. However, since the release of Windows 11 24H2, compatibility issues have emerged in GDI drawing processes in high DPI environments. Specifically, there have been reports of images either not displaying at all or rendering incorrectly.
Solution: Direct HDC Management for Drawing The key to resolving this issue lies in directly managing the HDC (Device Context) of the destination TBitmap and using the Windows API AlphaBlend function for image drawing. Here's an implementation example:
delphi
procedure TFormPrintAddressImp.DrawVirtualImage(VirtualImageList: TVirtualImageList;
const Index: Integer; DestBitmap: TBitmap);
var
SrcBmp: TBitmap;
SrcDC, DestDC: HDC;
BlendFunc: BLENDFUNCTION;
DestRect: TRect;
begin
// Create temporary source image
SrcBmp := TBitmap.Create;
try
SrcBmp.PixelFormat := pf32bit;
SrcBmp.Width := VirtualImageList.Width;
SrcBmp.Height := VirtualImageList.Height;
// Get image from VirtualImageList (image at Index)
VirtualImageList.GetBitmap(Index, SrcBmp);
// Set destination bitmap's PixelFormat to 32bit
DestBitmap.PixelFormat := pf32bit;
// If DestBitmap size is not set, make it same as VirtualImageList
if (DestBitmap.Width = 0) or (DestBitmap.Height = 0) then
begin
DestBitmap.Width := VirtualImageList.Width;
DestBitmap.Height := VirtualImageList.Height;
end;
// Create destination region
DestRect := Rect(0, 0, DestBitmap.Width, DestBitmap.Height);
// Get destination HDC
DestDC := DestBitmap.Canvas.Handle;
// Fill background with white
FillRect(DestDC, DestRect, GetStockObject(WHITE_BRUSH));
// Create compatible memory DC for source
SrcDC := CreateCompatibleDC(DestDC);
try
SelectObject(SrcDC, SrcBmp.Handle);
// Configure BLENDFUNCTION (fully opaque with alpha channel)
BlendFunc.BlendOp := AC_SRC_OVER;
BlendFunc.BlendFlags := 0;
BlendFunc.SourceConstantAlpha := 255;
BlendFunc.AlphaFormat := AC_SRC_ALPHA;
// Draw source image to DestBitmap using AlphaBlend (scale to fit DestRect)
if not Windows.AlphaBlend(DestDC,
0, 0, DestBitmap.Width, DestBitmap.Height,
SrcDC,
0, 0, SrcBmp.Width, SrcBmp.Height,
BlendFunc) then
begin
RaiseLastOSError;
end;
finally
DeleteDC(SrcDC);
end;
finally
SrcBmp.Free;
end;
end;Key Implementation Points
32-bit Pixel Format Usage: Setting the PixelFormat to pf32bit for both source and destination bitmaps ensures proper handling of images with alpha channels.
Direct HDC Manipulation: Obtaining the device context (HDC) through DestBitmap.Canvas.Handle and creating a memory DC using CreateCompatibleDC bypasses issues that occurred with traditional VCL component-based drawing.
AlphaBlend Function Usage: Using the Windows API AlphaBlend enables proper alpha blending (transparency processing). Appropriate configuration of BlendFunc parameters ensures expected behavior for image transparency and blending.
Why Does This Solution Work? Windows 11 24H2 introduced changes to internal processing and DPI scaling for GDI-based drawing, which caused standard VCL drawing methods to fail in some cases. The implementation above circumvents these issues by directly controlling the drawing target through low-level HDC operations and API calls, ensuring proper image rendering.
Summary
Traditional VCL drawing methods may be insufficient for handling high DPI environments and Windows 11 24H2 changes.
Direct HDC manipulation and Windows API AlphaBlend usage enable proper rendering of TImageCollection and TVirtualImage images.
This approach represents an important solution for high DPI-aware application development in Delphi 11.3 and later versions.
Consider implementing this method in your projects to achieve stable image rendering in modern Windows environments.