Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add MAKELONG and related macros #1018

Merged
merged 1 commit into from
Aug 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/Microsoft.Windows.CsWin32/Generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -943,6 +943,16 @@ internal void RequestMacro(MethodDeclarationSyntax macro)
this.TryGenerateType(identifierString.Substring(GlobalNamespacePrefix.Length));
}
}

// Generate macro dependencies, if any.
foreach (IdentifierNameSyntax identifier in macro.DescendantNodes().OfType<IdentifierNameSyntax>())
{
string identifierString = identifier.ToString();
if (Win32SdkMacros.ContainsKey(identifierString))
{
this.TryGenerateMacro(identifierString, out _);
}
}
});
}

Expand Down
32 changes: 32 additions & 0 deletions src/Microsoft.Windows.CsWin32/templates/PInvokeClassMacros.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,36 @@ internal class PInvokeClassMacros
/// Learn more in <see href="https://docs.microsoft.com/windows/win32/api/winerror/nf-winerror-hresult_from_win32">the documentation for this API</see>.
/// </remarks>
internal static global::Windows.Win32.Foundation.HRESULT HRESULT_FROM_WIN32(global::Windows.Win32.Foundation.WIN32_ERROR error) => new(unchecked(error <= 0 ? (int)error : (int)(((uint)error & 0x0000FFFF) | 0x80070000)));

/// <summary>
/// Joins two 16-bit integers into a 32-bit integer.
/// </summary>
/// <param name="a">The low word.</param>
/// <param name="b">The high word.</param>
/// <returns>A 32-bit unsigned integer.</returns>
internal static uint MAKELONG(ushort a, ushort b) => (uint)(a | b << 16);

/// <summary>
/// Constructs a <see cref="global::Windows.Win32.Foundation.WPARAM"/> from two 16-bit values.
/// </summary>
/// <param name="l">The low word.</param>
/// <param name="h">The high word.</param>
/// <returns>The WPARAM value.</returns>
internal static global::Windows.Win32.Foundation.WPARAM MAKEWPARAM(ushort l, ushort h) => MAKELONG(l, h);

/// <summary>
/// Constructs a <see cref="global::Windows.Win32.Foundation.LPARAM"/> from two 16-bit values.
/// </summary>
/// <param name="l">The low word.</param>
/// <param name="h">The high word.</param>
/// <returns>The LPARAM value.</returns>
internal static global::Windows.Win32.Foundation.LPARAM MAKELPARAM(ushort l, ushort h) => unchecked((nint)MAKELONG(l, h));

/// <summary>
/// Constructs a <see cref="global::Windows.Win32.Foundation.LRESULT"/> from two 16-bit values.
/// </summary>
/// <param name="l">The low word.</param>
/// <param name="h">The high word.</param>
/// <returns>The LRESULT value.</returns>
internal static global::Windows.Win32.Foundation.LRESULT MAKELRESULT(ushort l, ushort h) => unchecked((global::Windows.Win32.Foundation.LRESULT)(nint)MAKELONG(l, h));
}
68 changes: 68 additions & 0 deletions test/GenerationSandbox.Tests/MacroTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using Windows.Win32.Foundation;
using static Windows.Win32.PInvoke;

public class MacroTests
{
[Fact]
public void HRESULT_FROM_WIN32Test()
{
Assert.Equal(HRESULT.S_OK, HRESULT_FROM_WIN32(WIN32_ERROR.NO_ERROR));
}

[Fact]
public void MAKELONGTest()
{
Assert.Equal(0x00000000u, MAKELONG(0x0000, 0x0000));
Assert.Equal(0x00010000u, MAKELONG(0x0000, 0x0001));
Assert.Equal(0x00000001u, MAKELONG(0x0001, 0x0000));
Assert.Equal(0x00010002u, MAKELONG(0x0002, 0x0001));
Assert.Equal(0xFFFF0000u, MAKELONG(0x0000, 0xFFFF));
Assert.Equal(0x0000FFFFu, MAKELONG(0xFFFF, 0x0000));
Assert.Equal(0xFFFFFFFFu, MAKELONG(0xFFFF, 0xFFFF));
}

[Fact]
public void MAKEWPARAMTest()
{
Assert.Equal(0x00000000u, MAKEWPARAM(0x0000, 0x0000));
Assert.Equal(0x00010000u, MAKEWPARAM(0x0000, 0x0001));
Assert.Equal(0x00000001u, MAKEWPARAM(0x0001, 0x0000));
Assert.Equal(0x00010002u, MAKEWPARAM(0x0002, 0x0001));
Assert.Equal(0xFFFF0000u, MAKEWPARAM(0x0000, 0xFFFF));
Assert.Equal(0x0000FFFFu, MAKEWPARAM(0xFFFF, 0x0000));
Assert.Equal(0xFFFFFFFFu, MAKEWPARAM(0xFFFF, 0xFFFF));
}

[Fact]
public void MAKELPARAMTest()
{
unchecked
{
Assert.Equal((LPARAM)(nint)0x00000000, MAKELPARAM(0x0000, 0x0000));
Assert.Equal((LPARAM)(nint)0x00010000, MAKELPARAM(0x0000, 0x0001));
Assert.Equal((LPARAM)(nint)0x00000001, MAKELPARAM(0x0001, 0x0000));
Assert.Equal((LPARAM)(nint)0x00010002, MAKELPARAM(0x0002, 0x0001));
Assert.Equal((LPARAM)(nint)0xFFFF0000, MAKELPARAM(0x0000, 0xFFFF));
Assert.Equal((LPARAM)(nint)0x0000FFFF, MAKELPARAM(0xFFFF, 0x0000));
Assert.Equal((LPARAM)(nint)0xFFFFFFFF, MAKELPARAM(0xFFFF, 0xFFFF));
}
}

[Fact]
public void MAKELRESULTTest()
{
unchecked
{
Assert.Equal((LRESULT)(nint)0x00000000, MAKELRESULT(0x0000, 0x0000));
Assert.Equal((LRESULT)(nint)0x00010000, MAKELRESULT(0x0000, 0x0001));
Assert.Equal((LRESULT)(nint)0x00000001, MAKELRESULT(0x0001, 0x0000));
Assert.Equal((LRESULT)(nint)0x00010002, MAKELRESULT(0x0002, 0x0001));
Assert.Equal((LRESULT)(nint)0xFFFF0000, MAKELRESULT(0x0000, 0xFFFF));
Assert.Equal((LRESULT)(nint)0x0000FFFF, MAKELRESULT(0xFFFF, 0x0000));
Assert.Equal((LRESULT)(nint)0xFFFFFFFF, MAKELRESULT(0xFFFF, 0xFFFF));
}
}
}
5 changes: 5 additions & 0 deletions test/GenerationSandbox.Tests/NativeMethods.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ GetTickCount
GetWindowText
GetWindowTextLength
HDC_UserSize
HRESULT_FROM_WIN32
IDirectorySearch
IEnumDebugPropertyInfo
IPersistFile
Expand All @@ -21,6 +22,9 @@ IShellWindows
KEY_EVENT_RECORD
LoadLibrary
MainAVIHeader
MAKELPARAM
MAKELRESULT
MAKEWPARAM
MAX_PATH
NTSTATUS
PathParseIconLocation
Expand All @@ -30,6 +34,7 @@ PZZWSTR
RECT
RegLoadAppKey
RM_PROCESS_INFO
S_OK
SHDESCRIPTIONID
ShellLink
ShellWindowFindWindowOptions
Expand Down
23 changes: 0 additions & 23 deletions test/Microsoft.Windows.CsWin32.Tests/GeneratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -389,29 +389,6 @@ public void ObsoleteAttributePropagated()
Assert.Contains(field!.Value.Field.AttributeLists, al => IsAttributePresent(al, "Obsolete"));
}

[Theory, PairwiseData]
public void MacroAPIsGenerateWithAppropriateVisibility(bool publicVisibility)
{
this.generator = this.CreateGenerator(DefaultTestGeneratorOptions with { Public = publicVisibility });
Assert.True(this.generator.TryGenerate("HRESULT_FROM_WIN32", CancellationToken.None));
this.CollectGeneratedCode(this.generator);
this.AssertNoDiagnostics();
var method = Assert.Single(this.FindGeneratedMethod("HRESULT_FROM_WIN32"));

Assert.True(method.Modifiers.Any(publicVisibility ? SyntaxKind.PublicKeyword : SyntaxKind.InternalKeyword));
}

[Theory]
[MemberData(nameof(AvailableMacros))]
public void MacroAPIsGenerate(string macro)
{
this.generator = this.CreateGenerator();
Assert.True(this.generator.TryGenerate(macro, CancellationToken.None));
this.CollectGeneratedCode(this.generator);
this.AssertNoDiagnostics();
Assert.Single(this.FindGeneratedMethod(macro));
}

[Theory]
[InlineData("BOOL")]
[InlineData("BOOLEAN")]
Expand Down
33 changes: 33 additions & 0 deletions test/Microsoft.Windows.CsWin32.Tests/MacrosTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

public class MacrosTests : GeneratorTestBase
{
public MacrosTests(ITestOutputHelper logger)
: base(logger)
{
}

[Theory, PairwiseData]
public void MacroAPIsGenerateWithAppropriateVisibility(bool publicVisibility)
{
this.generator = this.CreateGenerator(DefaultTestGeneratorOptions with { Public = publicVisibility });
Assert.True(this.generator.TryGenerate("MAKELONG", CancellationToken.None));
this.CollectGeneratedCode(this.generator);
this.AssertNoDiagnostics();
var method = Assert.Single(this.FindGeneratedMethod("MAKELONG"));

Assert.True(method.Modifiers.Any(publicVisibility ? SyntaxKind.PublicKeyword : SyntaxKind.InternalKeyword));
}

[Theory]
[MemberData(nameof(AvailableMacros))]
public void MacroAPIsGenerate(string macro)
{
this.generator = this.CreateGenerator();
Assert.True(this.generator.TryGenerate(macro, CancellationToken.None));
this.CollectGeneratedCode(this.generator);
this.AssertNoDiagnostics();
Assert.Single(this.FindGeneratedMethod(macro));
}
}