delphidelphi-2007

How to detect Windows 10 vs. Windows 11 in order to use Dwmapi.DwmSetWindowAttribute


I have the following window corner rounding code, that only works in Win11. Now I need to detect if Win10 is used in order to make the rounding of corners differently.

How can I check if this code did made the corners rounded, and/or if Windows v11 or newer is in use?

unit delphi_rounded_corners;

interface

uses
  Windows;

type
  TRoundedWindowCornerType = (RoundedCornerDefault, RoundedCornerOff, RoundedCornerOn, RoundedCornerSmall);

////////////////////////////////////////////////////////////////////////////
//
// Originally written by Ian Barker
//            https://github.com/checkdigits
//            https://about.me/IanBarker
//            ian.barker@gmail.com
//
// Based on an example in an answer during the RAD Studio 11 Launch Q & A
//
//
// Free software - use for any purpose including commercial use.
//
////////////////////////////////////////////////////////////////////////////
//
// Set or prevent Windows 11 from rounding the corners or your application
//
// Usage:
//         SetRoundedCorners(Self.Handle, RoundedCornerSmall);
//
////////////////////////////////////////////////////////////////////////////
///
procedure SetRoundedCorners(const TheHandle: HWND; const CornerType: TRoundedWindowCornerType);

implementation

uses
  Dwmapi;

const

  //
  // More information:
  //      https://docs.microsoft.com/en-us/windows/apps/desktop/modernize/apply-rounded-corners
  //      https://docs.microsoft.com/en-us/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute
  //      https://docs.microsoft.com/en-us/windows/win32/api/dwmapi/nf-dwmapi-dwmsetwindowattribute
  //

  DWMWCP_DEFAULT    = 0; // Let the system decide whether or not to round window corners
  DWMWCP_DONOTROUND = 1; // Never round window corners
  DWMWCP_ROUND      = 2; // Round the corners if appropriate
  DWMWCP_ROUNDSMALL = 3; // Round the corners if appropriate, with a small radius

  DWMWA_WINDOW_CORNER_PREFERENCE = 33; // [set] WINDOW_CORNER_PREFERENCE, Controls the policy that rounds top-level window corners

procedure SetRoundedCorners(const TheHandle: HWND; const CornerType: TRoundedWindowCornerType);
var
  DWM_WINDOW_CORNER_PREFERENCE: DWORD;
begin
  case CornerType of
    RoundedCornerOff:     DWM_WINDOW_CORNER_PREFERENCE := DWMWCP_DONOTROUND;
    RoundedCornerOn:      DWM_WINDOW_CORNER_PREFERENCE := DWMWCP_ROUND;
    RoundedCornerSmall:   DWM_WINDOW_CORNER_PREFERENCE := DWMWCP_ROUNDSMALL;
  else
    DWM_WINDOW_CORNER_PREFERENCE := DWMWCP_DEFAULT;
  end;

  // or simpler, since TRoundedWindowCornerType and
  // the DWM_WINDOW_CORNER_PREFERENCE enum have the
  // same numeric values:
  //
  // DWM_WINDOW_CORNER_PREFERENCE := Ord(CornerType);

  Dwmapi.DwmSetWindowAttribute(TheHandle, DWMWA_WINDOW_CORNER_PREFERENCE, @DWM_WINDOW_CORNER_PREFERENCE, sizeof(DWM_WINDOW_CORNER_PREFERENCE));
end;

end.

Solution

  • How can I check if this code did [make] the corners rounded, and/or if Windows v11 or newer is in use?

    Indeed, it is often better to check if a particular feature is available (or was successfully used) than to hardcode tests for specific Windows versions.

    And this is easy in this case. Of course, the first thing you did when you found the code above, was to read the documentation for the DwmSetWindowAttribute function:

    Return value

    Type: HRESULT

    If the function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.

    Therefore, you only need to check the result. If it's S_OK, your corners are now rounded. Otherwise, it was not possible to round the corners, most likely because the OS doesn't support rounded corners:

    For example (using the DwmApi unit shipped in more recent versions of Delphi):

    procedure TForm1.FormClick(Sender: TObject);
    begin
      var pref: DWORD := DWMWCP_ROUND;
      if not Succeeded(DwmSetWindowAttribute(Handle, DWMWA_WINDOW_CORNER_PREFERENCE, @pref, Sizeof(pref))) then
        ShowMessage('Failed to round the window''s corners.');
    end;