这两天极郁闷    需要写个打印程序,需一个字符一个字符的打,所以要量每个字符的宽度后再打下一个字符,比如I与Q就不一样大,我是在printPage里用Graphics.DrawString(string,font,x,y)的X,Y定好位一个个打的.    在网上看了好多人说用MeasureString方法来量,可是量出来的比实际要大1.2 - 1.3倍之间,但不准有些字符会挨在一起有些又不会,所以字符老打的不紧挨在一起,又听说API函数GetTextExtentPoint能量的准确!    故问一下高手们怎么用此API来量?最好能给一个简单的C#源码,小弟谢过!

解决方案 »

  1.   

    Font.Unit 用于获Font 的度量单位.它是一个 GraphicsUnit,表示此 Font 的度量单位。 Display 指定显示设备的度量单位。通常,视频显示使用的单位是像素;打印机使用的单位是 1/100 英寸。  
     Document 将文档单位(1/300 英寸)指定为度量单位。  
     Inch 将英寸指定为度量单位。  
     Millimeter 将毫米指定为度量单位。  
     Pixel 将设备像素指定为度量单位。  
     Point 将打印机点(1/72 英寸)指定为度量单位。  
     World 将世界坐标系单位指定为度量单位。  
      

  2.   

    using System.Runtime.InteropServices;
    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);
      

  3.   

    Font 可以取当前使用的字体,protected override void OnPaint(PaintEventArgs pevent)
    {
        Graphics g = pevent.Graphics;
        IntPtr HDC = g.GetHdc();
    }自己试试,我没试过.
      

  4.   

    to 在网上看了好多人说用MeasureString方法来量,可是量出来的比实际要大1.2 - 1.3倍之间,但不准有些字符会挨在一起有些又不会,所以字符老打的不紧挨在一起,又听说API函数GetTextExtentPoint能量的准确!按说MeasureString就可以了如果调用Api,参看
    http://www.pinvoke.net/default.aspx/gdi32/GetTextExtentPoint.html
      

  5.   

    其次,你可以用Graphics.MeasureCharacterRanges这个方法,或许更准确。
      

  6.   

    反正没事, 测试了一下, 以下是结果:
    不过调用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());
            }
        }
    }