メインコンテンツへスキップ
見出し画像

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

    1. Background of the Issue

    2. Direct HDC Management Solution

    3. Key Implementation Points

    4. Why This Solution Works

    5. 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.

     
     
    病気のことや障害枠の事やシステムエンジニアの事を書いていきます。 よろしくお願いします。統合失調症(寛解)

    あなたへのおすすめ