graber
asked on
Getting and using TextMetrics from dgi32.dll
I am attempting to "TextMetrics" from the gdi32.dll library.
the compiler if flaggin the function GetTextMetrics with
Error 1 Inconsistent accessibility: parameter type 'WindowsControlLibrary1.SW .TEXTMETRI C' is less accessible than method 'WindowsControlLibrary1.SW .GetTextMe trics(Syst em.IntPtr, WindowsControlLibrary1.SW. TEXTMETRIC )' C:\Users\garaber\Documents \Dev Software\BitSWTest\Windows ControlLib rary1\User Control1.c s 41 33 WindowsControlLibrary1
I've seen this example out on the web and it seems to be working for others. Thanks guys
the compiler if flaggin the function GetTextMetrics with
Error 1 Inconsistent accessibility: parameter type 'WindowsControlLibrary1.SW
I've seen this example out on the web and it seems to be working for others. Thanks guys
[DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
public static extern bool GetTextMetrics(IntPtr hdc, TEXTMETRIC lptm);
It sounds like you have a struct defined called TEXTMETRIC that has an accessibility level of private, internal or protected. Its complaining because that would give it a lower accessibility level than the method.
ASKER
TEXTMETRIC is defined just above. The IDE has identified the function GetTextMetrics as the problem. Not sure what I'm doing wrong.
public partial class SW : UserControl
{
struct TEXTMETRIC
{
public int tmHeight;
public int tmAscent;
public int tmDescent;
public int tmInternalLeading;
public int tmExternalLeading;
public int tmAveCharWidth;
public int tmMaxCharWidth;
public int tmWeight;
public int tmOverhang;
public int tmDigitizedAspectX;
public int tmDigitizedAspectY;
public char tmFirstChar;
public char tmLastChar;
public char tmDefaultChar;
public char tmBreakChar;
public char tmItalic;
public char tmUnderlined;
public char tmStruckOut;
public char tmPitchAndFamily;
public char tmCharSet;
}
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
public static extern bool GetTextMetrics(IntPtr hdc, TEXTMETRIC lptm);
C-.jpg
You need to change the line:
struct TEXTMETRIC
To:
public struct TEXTMETRIC
If you don't say otherwise then a nested struct is private. In this case that is causing a problem because it gives the struct a more restrictive visibility that the method for which it is a parameter. If you change the declaration, as above, so that it is public then it should sort the problem.
struct TEXTMETRIC
To:
public struct TEXTMETRIC
If you don't say otherwise then a nested struct is private. In this case that is causing a problem because it gives the struct a more restrictive visibility that the method for which it is a parameter. If you change the declaration, as above, so that it is public then it should sort the problem.
ASKER
I've been writing software for some time now and I still get tag by this stuff. This is embarrassing. Thanks Carl. As it turns out I'm a cheep date :)
ASKER
GetText Metrics is returning false.... Did I miss something?
public partial class Form1 : Form
{
public struct TEXTMETRIC
{
public int tmHeight;
public int tmAscent;
public int tmDescent;
public int tmInternalLeading;
public int tmExternalLeading;
public int tmAveCharWidth;
public int tmMaxCharWidth;
public int tmWeight;
public int tmOverhang;
public int tmDigitizedAspectX;
public int tmDigitizedAspectY;
public char tmFirstChar;
public char tmLastChar;
public char tmDefaultChar;
public char tmBreakChar;
public char tmItalic;
public char tmUnderlined;
public char tmStruckOut;
public char tmPitchAndFamily;
public char tmCharSet;
}
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
public static extern bool GetTextMetrics(IntPtr hDC, TEXTMETRIC lptm);
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);
[DllImport("Gdi32.dll", CharSet = CharSet.Auto)]
public static extern bool DeleteObject(IntPtr hdc);
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
public static extern UInt32 GetLastError();
public Form1()
{
InitializeComponent();
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
Font font = new Font(Font.FontFamily, 10, FontStyle.Regular, GraphicsUnit.Pixel);
TEXTMETRIC tm = new TEXTMETRIC();
IntPtr hDC = e.Graphics.GetHdc();
IntPtr hFont = font.ToHfont();
IntPtr hFontPrev = SelectObject(hDC, hFont);
bool bResults = GetTextMetrics(hDC, tm);
SelectObject(hDC, hFontPrev);
DeleteObject(hFont);
e.Graphics.ReleaseHdc(hDC);
}
ASKER
Am I too assume that this matter is closed. The question as asking for "Getting and using TextMetrics". We're not using it yet.
Gregg
Gregg
Sorry, didn't see that last post. Try the following, as a test, and see if it returns true:
System.Windows.Forms.Label label = new System.Windows.Forms.Label();
Graphics g = Graphics.FromHwnd(label.Handle);
API.TEXTMETRIC metric = new API.TEXTMETRIC();
bool result = API.GetTextMetrics(g.GetHdc(), metric);
ASKER
Thanks carl for responding. I had to alter it a bit to work with the stub. See if this is ok. As it runs right now it is still returning false. Bummer.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace GetTextMetricsTest
{
public partial class Form1 : Form
{
public struct TEXTMETRIC
{
public int tmHeight;
public int tmAscent;
public int tmDescent;
public int tmInternalLeading;
public int tmExternalLeading;
public int tmAveCharWidth;
public int tmMaxCharWidth;
public int tmWeight;
public int tmOverhang;
public int tmDigitizedAspectX;
public int tmDigitizedAspectY;
public char tmFirstChar;
public char tmLastChar;
public char tmDefaultChar;
public char tmBreakChar;
public char tmItalic;
public char tmUnderlined;
public char tmStruckOut;
public char tmPitchAndFamily;
public char tmCharSet;
}
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
public static extern bool GetTextMetrics(IntPtr hDC, TEXTMETRIC lptm);
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);
[DllImport("Gdi32.dll", CharSet = CharSet.Auto)]
public static extern bool DeleteObject(IntPtr hdc);
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
public static extern UInt32 GetLastError();
public Form1()
{
InitializeComponent();
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
System.Windows.Forms.Label label = new System.Windows.Forms.Label();
Graphics g = Graphics.FromHwnd(label.Handle);
TEXTMETRIC tm = new TEXTMETRIC();
bool result = GetTextMetrics(g.GetHdc(), tm);
//Font font = new Font(Font.FontFamily, 10, FontStyle.Regular, GraphicsUnit.Pixel);
//TEXTMETRIC tm = new TEXTMETRIC();
//IntPtr hDC = e.Graphics.GetHdc();
//IntPtr hFont = font.ToHfont();
//IntPtr hFontPrev = SelectObject(hDC, hFont);
//bool bResults = GetTextMetrics(hDC, tm);
//SelectObject(hDC, hFontPrev);
//DeleteObject(hFont);
//e.Graphics.ReleaseHdc(hDC);
}
}
}
ASKER
Carl ... Do you own and operate your own business?...
Ok, that should be working. There must be something in your form, or elsewhere that is causing GetTextMetrics to return false. I would try that block of code by itself in a simple winforms app, but don't put the code in the Paint event.
On a side note, I don't run my own business, but I do do the occasional freelance project.
On a side note, I don't run my own business, but I do do the occasional freelance project.
ASKER
How about a C# console application?
You can do it as a console app, but you will need to add references to the System.Windows.Forms and System.Drawing assemblies, as they won't be included by default.
ASKER
Will do. Thanks again carl.
ASKER
The code as it stands is still returning false.
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Drawing;
namespace ConsoleGetTextMetrics
{
class Program
{
public struct TEXTMETRIC
{
public int tmHeight;
public int tmAscent;
public int tmDescent;
public int tmInternalLeading;
public int tmExternalLeading;
public int tmAveCharWidth;
public int tmMaxCharWidth;
public int tmWeight;
public int tmOverhang;
public int tmDigitizedAspectX;
public int tmDigitizedAspectY;
public char tmFirstChar;
public char tmLastChar;
public char tmDefaultChar;
public char tmBreakChar;
public char tmItalic;
public char tmUnderlined;
public char tmStruckOut;
public char tmPitchAndFamily;
public char tmCharSet;
}
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
public static extern bool GetTextMetrics(IntPtr hDC, TEXTMETRIC lptm);
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);
[DllImport("Gdi32.dll", CharSet = CharSet.Auto)]
public static extern bool DeleteObject(IntPtr hdc);
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
public static extern UInt32 GetLastError();
static void Main(string[] args)
{
System.Windows.Forms.Label label = new System.Windows.Forms.Label();
Graphics g = Graphics.FromHwnd(label.Handle);
TEXTMETRIC tm = new TEXTMETRIC();
bool result = GetTextMetrics(g.GetHdc(), tm);
}
}
}
ASKER
Sorry about the extra DllImports they weren't necessary and should have been removed.
ASKER
I found this out on .Net Framework Developement Center
http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/1bc0166b-8a68-4067-a44b-e11ff7d55720
And it appears to work. I'm using visual studio 2005 on vista OS with a reference for vjslib (com.ms.win32)
http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/1bc0166b-8a68-4067-a44b-e11ff7d55720
And it appears to work. I'm using visual studio 2005 on vista OS with a reference for vjslib (com.ms.win32)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using com.ms.win32;
namespace GetTextMetricsAttempt3
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
int hDC = User32.GetDC((int)this.Handle);
TEXTMETRIC tm = new TEXTMETRIC();
foreach (FontFamily FF in FontFamily.Families)
{
try
{
this.Font = new Font(FF, 10);
}
catch(Exception ex)
{
Console.WriteLine(ex.ToString());
}
Gdi32.GetTextMetrics(hDC, tm);
Console.WriteLine(FF.Name + " " + tm.tmPitchAndFamily.ToString());
}
}
}
}
Oh well, as long as its working for you now. Although I can't see any reason why your other version shouldn't have worked.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.