这两天极郁闷 需要写个打印程序,需一个字符一个字符的打,所以要量每个字符的宽度后再打下一个字符,比如I与Q就不一样大,我是在printPage里用Graphics.DrawString(string,font,x,y)的X,Y定好位一个个打的. 在网上看了好多人说用MeasureString方法来量,可是量出来的比实际要大1.2 - 1.3倍之间,但不准有些字符会挨在一起有些又不会,所以字符老打的不紧挨在一起,又听说API函数GetTextExtentPoint能量的准确! 故问一下高手们怎么用此API来量?最好能给一个简单的C#源码,小弟谢过!
Document 将文档单位(1/300 英寸)指定为度量单位。
Inch 将英寸指定为度量单位。
Millimeter 将毫米指定为度量单位。
Pixel 将设备像素指定为度量单位。
Point 将打印机点(1/72 英寸)指定为度量单位。
World 将世界坐标系单位指定为度量单位。
using System.Drawing;[DllImport("gdi32.dll")]
static extern bool GetTextExtentPoint(IntPtr hdc, string lpString,
int cbString, ref Size lpSize);IntPtr HDC = CreateGraphics().GetHdc();
Size MeasureSize = new Size(0, 0);
String str = "string";
int length = str.Length;
GetTextExtentPoint(HDC, str, length, ref MeasureSize);
{
Graphics g = pevent.Graphics;
IntPtr HDC = g.GetHdc();
}自己试试,我没试过.
http://www.pinvoke.net/default.aspx/gdi32/GetTextExtentPoint.html
不过调用API是很慢的. 程序可能会慢.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 WindowsApplication1
{
public partial class Form1 : Form
{
private IntPtr hdc; public Form1()
{
InitializeComponent();
} [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class LOGFONT
{
public int lfHeight = 0;
public int lfWidth = 0;
public int lfEscapement = 0;
public int lfOrientation = 0;
public int lfWeight = 0;
public byte lfItalic = 0;
public byte lfUnderline = 0;
public byte lfStrikeOut = 0;
public byte lfCharSet = 0;
public byte lfOutPrecision = 0;
public byte lfClipPrecision = 0;
public byte lfQuality = 0;
public byte lfPitchAndFamily = 0;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string lfFaceName = string.Empty;
} [DllImport("gdi32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr CreateFontIndirect(
[In, MarshalAs(UnmanagedType.LPStruct)]
LOGFONT lplf // characteristics
); [DllImport("gdi32.dll")]
public static extern bool DeleteObject(
IntPtr handle
); [DllImport("gdi32.dll")]
static extern bool GetTextExtentPoint(IntPtr hdc, string lpString,
int cbString, ref Size lpSize); protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
} [DllImport("gdi32.dll", EntryPoint = "SelectObject", SetLastError = true)]
private static extern IntPtr SelectObjectCE(IntPtr hdc, IntPtr hgdiobj); private void button1_Click(object sender, EventArgs e)
{
LOGFONT lf = new LOGFONT();
//Font f = Font.FromLogFont(lf); Graphics g = CreateGraphics();
this.Font.ToLogFont(lf, g);
hdc = g.GetHdc();
IntPtr handle = CreateFontIndirect(lf);
SelectObjectCE(hdc, handle);
Size MeasureSize = new Size(0, 0);
String str = "s";
int length = str.Length;
GetTextExtentPoint(hdc, str, length, ref MeasureSize); MessageBox.Show(MeasureSize.Width.ToString());
g.ReleaseHdc(hdc);
MessageBox.Show(g.MeasureString(str, this.Font).Width.ToString());
}
}
}