Skip to content

Commit

Permalink
Various WinForms helper classes.
Browse files Browse the repository at this point in the history
  • Loading branch information
jamiehighfield committed May 19, 2022
1 parent 00a50b5 commit 72a38ac
Show file tree
Hide file tree
Showing 4 changed files with 209 additions and 0 deletions.
48 changes: 48 additions & 0 deletions src/BetterControls/Helpers/AccessibilityHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using System;
using System.Runtime.InteropServices;

namespace BetterControls.Helpers
{
internal static class AccessibilityHelper
{
/// <summary>
/// Determines whether or not a <see cref="string"/> contains a mnemonic.
/// </summary>
/// <param name="text">The <see cref="string"/> to determine whether or not contains a mnemonic.</param>
/// <returns><A <see cref="bool"/> value indicating whether or not a <see cref="string"/> contains a mnemonic.</returns>
internal static bool ContainsMnemonic(string text)
{
if (text is null)
{
throw new ArgumentNullException(nameof(text));
}

int textLength = text.Length;
int firstAmpersand = text.IndexOf('&', 0);
if (firstAmpersand >= 0 && firstAmpersand <= textLength - 2)
{
return text.IndexOf('&', firstAmpersand + 1) == -1;
}

return false;
}

/// <summary>
/// Shows keyboard accelerators for the specified handle.
/// </summary>
/// <param name="handle">The handle to show keyboard accelerators for.</param>
internal static void ShowKeyboardAccelerators(HandleRef handle)
{
UnsafeNativeMethods.SendMessage(handle, NativeMethods.WM_UPDATEUISTATE, (IntPtr)(NativeMethods.UIS_CLEAR | (NativeMethods.UISF_HIDEACCEL << 16)), IntPtr.Zero);
}

/// <summary>
/// Hides keyboard accelerators for the specified handle.
/// </summary>
/// <param name="handle">The handle to hide keyboard accelerators for.</param>
internal static void HideKeyboardAccelerators(HandleRef handle)
{
UnsafeNativeMethods.SendMessage(handle, NativeMethods.WM_UPDATEUISTATE, (IntPtr)(NativeMethods.UIS_SET | (NativeMethods.UISF_HIDEACCEL << 16)), IntPtr.Zero);
}
}
}
91 changes: 91 additions & 0 deletions src/BetterControls/Helpers/IconUtilities.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace BetterControls
{
/// <summary>
/// Helper class for icon utilities.
/// </summary>
internal static class IconUtilities
{
private static Bitmap _shieldImage;

/// <summary>
/// Adds the system shield icon to a <see cref="Button"/>.
/// </summary>
/// <param name="button">The button to add the system shield icon to.</param>
internal static void AddShield(this Button button)
{
button.FlatStyle = FlatStyle.System;

UnsafeNativeMethods.SendMessage(new HandleRef(button, button.Handle), NativeMethods.BCM_SETSHIELD, 0, 1);
}

/// <summary>
/// Gets the system shield icon as an instance of <see cref="Bitmap"/>.
/// </summary>
/// <returns>The system shield icon as an instance of <see cref="Bitmap"/>.</returns>
public static Bitmap GetShieldImage()
{
if (_shieldImage != null)
{
return _shieldImage;
}

const int buttonWidth = 50;
const int buttonHeight = 50;
const int buttonMargin = 4;

Button button = new Button()
{
Text = " ",
Size = new Size(buttonWidth, buttonHeight)
};

// Set the shield icon on the button, and it'll be extracted from there.
button.AddShield();

// Create a ne bitmap that the button is drawn to.
Bitmap buttonBitmap = new Bitmap(buttonWidth, buttonHeight);

button.Refresh();
button.DrawToBitmap(buttonBitmap, new Rectangle(new Point(0, 0), new Size(buttonWidth, buttonHeight)));

int min_x = buttonWidth, max_x = 0, min_y = buttonHeight, max_y = 0;

for (int y = buttonMargin; y < buttonHeight - buttonMargin; y++)
{
Color targetColor = buttonBitmap.GetPixel(buttonMargin, y);

for (int x = buttonMargin; x < buttonWidth - buttonMargin; x++)
{
if (buttonBitmap.GetPixel(x, y).Equals(targetColor))
{
buttonBitmap.SetPixel(x, y, Color.Transparent);
}
else
{
if (min_y > y) min_y = y;
if (min_x > x) min_x = x;
if (max_y < y) max_y = y;
if (max_x < x) max_x = x;
}
}
}

// Clip out the shield part.
int shield_wid = max_x - min_x + 1;
int shield_hgt = max_y - min_y + 1;

_shieldImage = new Bitmap(shield_wid, shield_hgt);

using (Graphics shield_gr = Graphics.FromImage(_shieldImage))
{
shield_gr.DrawImage(buttonBitmap, 0, 0, new Rectangle(min_x, min_y, shield_wid, shield_hgt), GraphicsUnit.Pixel);
}

return _shieldImage;
}
}
}
48 changes: 48 additions & 0 deletions src/BetterControls/Helpers/StringUtilities.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using System;
using System.Globalization;

namespace BetterControls
{
/// <summary>
/// Helper class containing string utilities.
/// </summary>
internal class StringUtilities
{
/// <summary>
/// Gets the mnemonic, if any, from the specified string.
/// </summary>
/// <param name="text">The string from which to get the mnemonic, if any.</param>
/// <param name="upperCase">A <see cref="bool"/> value indicating whether or not to convert the mnemonic to upper case.</param>
/// <returns>The string mnemonic as a <see cref="char"/> value.</returns>
internal static char GetMnemonic(string text, bool upperCase)
{
if (text is null)
{
throw new ArgumentNullException(nameof(text));
}

for (int i = 0; i < text.Length - 1; i++)
{
if (text[i] == '&')
{
if (text[i + 1] == '&')
{
i++;

continue;
}
if (upperCase)
{
return char.ToUpper(text[i + 1], CultureInfo.CurrentCulture);
}
else
{
return char.ToLower(text[i + 1], CultureInfo.CurrentCulture);
}
}
}

return default;
}
}
}
22 changes: 22 additions & 0 deletions src/BetterControls/Helpers/WindowsFormsUtilities.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System.Drawing;

namespace BetterControls
{
/// <summary>
/// Utility helpers for Windows Forms.
/// </summary>
public static class WindowsFormsUtilities
{
/// <summary>
/// Gets the absolute pointer position.
/// </summary>
/// <returns>The absolute pointer position.</returns>
public static Point GetPointerPosition()
{
NativeMethods.POINT pt = new NativeMethods.POINT();
UnsafeNativeMethods.GetCursorPos(pt);

return new Point(pt.x, pt.y);
}
}
}

0 comments on commit 72a38ac

Please sign in to comment.