好像System.Text下有一个函数可以求单个字符的宽度.

解决方案 »

  1.   

    /// <summary>
    /// 拆分字符串
    /// </summary>
    /// <param name="pString">要拆分的字符串</param>
    /// <param name="pLen">拆分长度</param>
    /// <returns></returns>
    private ArrayList SplitString(string pString,int pSplitLen)
    {
    ArrayList mAList=new ArrayList(); 
    string mBtyeStr="";//要拆分字符串的每个字符
    string mSplitStr="";//拆分的每一个字符串
    byte[] mBytes;
    int iSplitStrLen=0;//拆分的每一个字符串当前长度
    for(int i=0;i<pString.Length;i++)
    {
    mBtyeStr=pString.Substring(i,1); 
    mBytes=System.Text.Encoding.GetEncoding("gb2312").GetBytes(mBtyeStr);
    iSplitStrLen+=mBytes.Length; 
    if(iSplitStrLen<=pSplitLen*2)
    {
    mSplitStr+=mBtyeStr;
    }
    else
    {
    mAList.Add(mSplitStr); 
    iSplitStrLen=0;
    i--;
    mSplitStr="";
    }
    }
    mAList.Add(mSplitStr);
    return mAList; 
    }
    ---------------------------------------------------------------------
    这是我写的解决相同问题的代码,就是循环来进行匹配最接近的宽度,好像没有其他太好的办法。
      

  2.   

    楼上的老大似乎误解我的意思了,呵呵。我需要的是把String.Length和pixel做一个最近的匹配。不过,你的思路和我想得差不多,谢谢了!!!
      

  3.   

    终于找到了从前bcb写的代码:
    tmp = GetCurrentDir()+"\\"+file->ReadString("ComponentInstallInformation","Com"+IntToStr(i+1),"");
    prompt->Caption = MinimizeName(tmp,Canvas,prompt->Width);
    用的就是这个MinimizeName函数,哈哈!在bcb的source下面,找到了他的delphi实现代码,贴在下面!function MinimizeName(const Filename: TFileName; Canvas: TCanvas;
      MaxLen: Integer): TFileName;
    var
      Drive: TFileName;
      Dir: TFileName;
      Name: TFileName;
    begin
      Result := FileName;
      Dir := ExtractFilePath(Result);
      Name := ExtractFileName(Result);  if (Length(Dir) >= 2) and (Dir[2] = ':') then
      begin
        Drive := Copy(Dir, 1, 2);
        Delete(Dir, 1, 2);
      end
      else
        Drive := '';
      while ((Dir <> '') or (Drive <> '')) and (Canvas.TextWidth(Result) > MaxLen) do
      begin
        if Dir = '\...\' then
        begin
          Drive := '';
          Dir := '...\';
        end
        else if Dir = '' then
          Drive := ''
        else
          CutFirstDirectory(Dir);
        Result := Drive + Dir + Name;
      end;
    end;其实,我想就是循环作判断。当然,对于汉字与非汉字的处理,要小心一点就是了。我用C#修改一下,等会贴上来,准备结帐!谢谢大家了!
      

  4.   

    代码如下://测试用的文字是:中华人民1共和国万岁!!!我爱北23京4天安门!!!
    //字体:宋体,小三
    int MagicNumber = 5;
    protected override void OnPaint(PaintEventArgs e){
    Graphics g = e.Graphics;

    g.DrawString(MeasureString(g,Text,Font,this.ClientSize.Width-MagicNumber),Font,SystemBrushes.WindowText,0,0); base.OnPaint (e);
    }private string MeasureString(Graphics g,string text,Font font,int maxwidth){
    SizeF sf = g.MeasureString(text,font);
    if(sf.Width<maxwidth)return text; int len = text.Length;
    string s = "";
    StringBuilder sb = new StringBuilder(64); for(int i=len-1;i>=0;i--){
    sb.Remove(0,sb.Length);
    sb.Append(text.Substring(0,i));
    sb.Append("...");
    s = sb.ToString();
    sf = g.MeasureString(s,font);
    if(sf.Width<=maxwidth)break;
    }
    return s;
    }private void Form1_Resize(object sender, System.EventArgs e){
    Invalidate();
    }
    谢谢大家!结帐了!!!