[DllImport("gdi32.dll", EntryPoint = "GetCharABCWidths", SetLastError = true, CharSet = CharSet.Auto)]
static extern unsafe bool GetCharABCWidths(IntPtr hdc, uint uFirstChar,
uint uLastChar, ABC* lpabc);
[DllImport("gdi32.dll", EntryPoint = "GetCharABCWidthsW", SetLastError = true, CharSet = CharSet.Unicode)]
static extern unsafe bool GetCharABCWidthsW(IntPtr hdc, uint uFirstChar,
uint uLastChar, ABC* lpabc);
//CharSet = CharSet.Ansi is the default for C#. SetLastError = true adds some overhead and is default set false.
[DllImport("gdi32.dll", EntryPoint = "GetCharABCWidthsA", SetLastError = true)]
static extern unsafe bool GetCharABCWidthsA(IntPtr hdc, uint uFirstChar,
uint uLastChar, ABC* lpabc);
[StructLayout(LayoutKind.Sequential)]
public struct ABC
{
public int abcA;
public uint abcB;
public int abcC;
public override string ToString()
{
return string.Format("A={0}, B={1}, C={2}", abcA, abcB, abcC);
}
}
None.
Please add some!
The following method can be used to get the width of a single character. Change to W for unicode
/// <summary>
/// Gets the width of an ANSI true type font character
/// </summary>
/// <param name="g">A graphics object</param>
/// <param name="f">A font, note that all Fonts encapsulated
/// in a Font object are True Type.</param>
/// <param name="c">A character</param>
public static ABC GetCharABCWidthsA_(Graphics g, Font f, char c)
{
IntPtr hDC = g.GetHdc();
W32.ABC[] abc_array = new ABC[1];
IntPtr abcptr = Marshal.UnsafeAddrOfPinnedArrayElement(abc_array, 0);
IntPtr hFont = f.ToHfont();
try
{
IntPtr hFontPreviouse = SelectObject(hDC, hFont);
bool result = GetCharABCWidthsA(hDC, (uint) c, (uint) c, abcptr);
SelectObject(hDC, hFontPreviouse);
if (!result)
{
Console.WriteLine("Did not find ABC: " + f.ToString());
//Only works if "setLastError" is true on DllImport
Int32 err = Marshal.GetLastWin32Error();
throw new Win32Exception(err);
}
}
finally
{
DeleteObject(hFont);
g.ReleaseHdc(hDC);
}
return abc_array[0];
}
/// <summary>
/// The SelectObject function selects an object into the specified device
/// context (DC). The new object replaces the previous object of the same
/// type.
/// </summary>
/// <param name="hdc">Handle to the DC.</param>
/// <param name="hgdiobj">Handle to the object to be selected.</param>
/// <returns>If IntPtr.Zero it's an error</returns>
[DllImport("gdi32.dll", ExactSpelling = true, PreserveSig = true, SetLastError = true)]
public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);
/// <summary>
/// deletes a logical pen, brush, font, bitmap, region, or palette,
/// freeing all system resources associated with the object.
/// </summary>
[DllImport("GDI32.dll")]
public static extern bool DeleteObject(IntPtr objectHandle);
Do you know one? Please contribute it!