我想知道的是"宋体"是如何关联上simsun.ttc
就是说我用FontDialog得到"宋体"这个名称后,然后我该如何去获得simsun.ttc这个系统文件名
有现成的函数或者方法吗?

解决方案 »

  1.   

    注册表 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts
      

  2.   


    查过了,没有找到 宋体名和simsun.ttc文件名的对应
      

  3.   

    MSDN上2007年已经有人问过这个问题,如果你的英文还可以的话,可以看下地址:
    http://social.msdn.microsoft.com/Forums/en-US/windowsxps/thread/843d0e98-ac8e-4021-94f9-5e3130d058b9解决方案在:http://www.codeproject.com/Articles/4190/XFont-Get-font-name-and-file-information就是第一篇帖子最后一个人所说:It's not perfect, but it works.Good Luck!
      

  4.   

    刚好我也需要这个功能,就一次回复到位吧。
    以下C#代码可读取指定.ttf文件里的字体名,思路反过来:遍历<windir\>Fonts目录下的所有文件,即可找到通过“字体选择器”返回的字体名的字体文件。
    虽然办法笨了点,但确实也没啥好办法,凑合着能用。
    It's not perfect, but it works.
    ----------------------------------------------
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    using System.IO;namespace FontNameGetter
    {    [StructLayout(LayoutKind.Sequential, Pack = 0x1)]    struct TT_OFFSET_TABLE
        {        public ushort uMajorVersion;
            public ushort uMinorVersion;
            public ushort uNumOfTables;
            public ushort uSearchRange;
            public ushort uEntrySelector;
            public ushort uRangeShift;
        }
        [StructLayout(LayoutKind.Sequential, Pack = 0x1)]    struct TT_TABLE_DIRECTORY
        {        public char szTag1; public char szTag2;
            public char szTag3;
            public char szTag4;
            public uint uCheckSum; //Check sum        public uint uOffset; //Offset from beginning of file        public uint uLength; //length of the table in bytes    }    [StructLayout(LayoutKind.Sequential, Pack = 0x1)]    struct TT_NAME_TABLE_HEADER
        {        public ushort uFSelector;
            public ushort uNRCount;
            public ushort uStorageOffset;
        }    [StructLayout(LayoutKind.Sequential, Pack = 0x1)]    struct TT_NAME_RECORD
        {        public ushort uPlatformID;
            public ushort uEncodingID;
            public ushort uLanguageID;
            public ushort uNameID;
            public ushort uStringLength;
            public ushort uStringOffset;
        }    partial class Form1 : Form
        {        public Form1()
            {            InitializeComponent();
            }        private TT_OFFSET_TABLE ttOffsetTable;
            private TT_TABLE_DIRECTORY tblDir;
            private TT_NAME_TABLE_HEADER ttNTHeader;
            private TT_NAME_RECORD ttNMRecord;
            private void button1_Click(object sender, EventArgs e)
            {            FileStream fs = new FileStream("f:\\simsun.ttc", FileMode.Open, FileAccess.Read);
                BinaryReader r = new BinaryReader(fs);
                byte[] buff = r.ReadBytes(Marshal.SizeOf(ttOffsetTable));
                buff = BigEndian(buff);
                IntPtr ptr = Marshal.AllocHGlobal(buff.Length);
                Marshal.Copy(buff, 0x0, ptr, buff.Length);
                TT_OFFSET_TABLE ttResult = (TT_OFFSET_TABLE)Marshal.PtrToStructure(ptr, typeof(TT_OFFSET_TABLE));
                Marshal.FreeHGlobal(ptr);
                //Must be maj =1 minor = 0            if (ttResult.uMajorVersion != 1 || ttResult.uMinorVersion != 0)                return;
                bool bFound = false;
                TT_TABLE_DIRECTORY tbName = new TT_TABLE_DIRECTORY();
                for (int i = 0; i < ttResult.uNumOfTables; i++)
                {                byte[] bNameTable = r.ReadBytes(Marshal.SizeOf(tblDir));
                    IntPtr ptrName = Marshal.AllocHGlobal(bNameTable.Length);
                    Marshal.Copy(bNameTable, 0x0, ptrName, bNameTable.Length);
                    tbName = (TT_TABLE_DIRECTORY)Marshal.PtrToStructure(ptrName, typeof(TT_TABLE_DIRECTORY));
                    Marshal.FreeHGlobal(ptrName);
                    string szName = tbName.szTag1.ToString() + tbName.szTag2.ToString() + tbName.szTag3.ToString() + tbName.szTag4.ToString();
                    if (szName != null)
                    {                    if (szName.ToString() == "name")
                        {                        bFound = true;
                            byte[] btLength = BitConverter.GetBytes(tbName.uLength);
                            byte[] btOffset = BitConverter.GetBytes(tbName.uOffset);
                            Array.Reverse(btLength);
                            Array.Reverse(btOffset);
                            tbName.uLength = BitConverter.ToUInt32(btLength, 0);
                            tbName.uOffset = BitConverter.ToUInt32(btOffset, 0);
                            break;
                        }                }            }            if (bFound)
                {                fs.Position = tbName.uOffset;
                    byte[] btNTHeader = r.ReadBytes(Marshal.SizeOf(ttNTHeader));
                    btNTHeader = BigEndian(btNTHeader);
                    IntPtr ptrNTHeader = Marshal.AllocHGlobal(btNTHeader.Length);
                    Marshal.Copy(btNTHeader, 0x0, ptrNTHeader, btNTHeader.Length);
                    TT_NAME_TABLE_HEADER ttNTResult = (TT_NAME_TABLE_HEADER)Marshal.PtrToStructure(ptrNTHeader, typeof(TT_NAME_TABLE_HEADER));
                    Marshal.FreeHGlobal(ptrNTHeader);
                    bFound = false;
                    for (int i = 0; i < ttNTResult.uNRCount; i++)
                    {                    byte[] btNMRecord = r.ReadBytes(Marshal.SizeOf(ttNMRecord));
                        btNMRecord = BigEndian(btNMRecord);
                        IntPtr ptrNMRecord = Marshal.AllocHGlobal(btNMRecord.Length);
                        Marshal.Copy(btNMRecord, 0x0, ptrNMRecord, btNMRecord.Length);
                        TT_NAME_RECORD ttNMResult = (TT_NAME_RECORD)Marshal.PtrToStructure(ptrNMRecord, typeof(TT_NAME_RECORD));
                        Marshal.FreeHGlobal(ptrNMRecord);
                        if (ttNMResult.uNameID == 1)
                        {                        long fPos = fs.Position;
                            fs.Position = tbName.uOffset + ttNMResult.uStringOffset + ttNTResult.uStorageOffset;
                            char[] szResult = r.ReadChars(ttNMResult.uStringLength);
                            if (szResult.Length != 0)
                            {                            int y = 0;//szResult now contains the font name.
                                //szResult即是文件中的字体名,遍历Fonts目录下的所有文件,目标就实现了                        }                    }                }            }        }        private byte[] BigEndian(byte[] bLittle)
            {            byte[] bBig = new byte[bLittle.Length];
                for (int y = 0; y < (bLittle.Length - 1); y += 2)
                {                byte b1, b2;
                    b1 = bLittle[y];
                    b2 = bLittle[y + 1];
                    bBig[y] = b2;
                    bBig[y + 1] = b1;
                }            return bBig;
            }
        }
    }
    -----------------------------------------------
    别说不会用这个例子啊,仔细看下代码就知道啦。
      

  5.   

    经测试,上面老外的方法不好用,不好意思。
    自己写了个简单的,经测可用:    class FontNameFile
        {
            public static string getFontFileName(string fontname)
            {
                string folderFullName = System.Environment.GetEnvironmentVariable("windir") + "\\fonts";
                DirectoryInfo TheFolder = new DirectoryInfo(folderFullName);
                foreach (FileInfo NextFile in TheFolder.GetFiles())
                {
                    if (NextFile.Exists)
                    {
                        if (fontname == getFontName(NextFile.FullName)) return NextFile.FullName;
                    }
                }
                return ("");
            }        private static string getFontName(string fontfilename)
            {
                PrivateFontCollection pfc = new PrivateFontCollection();
                try
                {
                    pfc.AddFontFile(fontfilename);
                }
                catch (Exception ex)
                {
                    return "";
                }
                return(pfc.Families[0].Name);
            }
        }
      

  6.   

    PrivateFontCollection的AddFontFile方法还是不支持很多ttf字体!