在没有Win32 API调用的情况下将省略号添加到WinForms程序中的路径(重新访问)

时间:2010-04-14 19:31:48

标签: c# .net-4.0

我正在寻找一种在C#路径中插入省略号的方法,并在stackoverflow上找到答案:C# Path Ellipsis without Win32 API call

使用VS2010和.Net 4.0的RTM版本,我无法获得建议的方法。我搜索了'Net并找到了使用相同方法的示例代码,但它以同样的方式失败了。

您可以在下面的代码中看到我想缩短的字符串。

调用MeasureText方法后,输入字符串(OriginalName)和输出字符串(ellipsisedName)都如下所示:

d:\ ABCD \ EFGH \ IJKL \ MNOP \ QRST \ ... \ test.txt的\ 0F \ GHIJ \ KLMN \使用opqr \ STIV \ WXYZ \ test.txt的

两个问题:

1)生成的字符串被填充(路径按预期截断,但后面跟着看起来像C样式的终止null和原始路径的块)。

2)我的原始字符串已更改与输出字符串相同。

我做错了吗?

namespace WindowsFormsApplication2 {
   public partial class Form1 : Form {
      public Form1()
      {
         InitializeComponent();

         string OriginalPath = @"d:\abcd\efgh\ijkl\mnop\qrst\uvwx\yzAB\CDEF\GHIJ\KLMN\OPQR\STIV\WXYZ\test.txt";
         string ellipsisedPath = OriginalPath;

         Size proposedSize = new Size(label1.Width, label1.Height);

         TextRenderer.MeasureText(ellipsisedPath, label1.Font, proposedSize, TextFormatFlags.ModifyString | TextFormatFlags.PathEllipsis);
      }
   }
}

2 个答案:

答案 0 :(得分:4)

天哪,你发现了一个大麻虫。调用DrawTextEx()的TextRenderer类中使用的P / Invoke是borked。该API函数正在写回字符串,由于cchText参数是LPTSTR而不是LPCTSTR,因此允许这样做。这会破坏两个变量的.NET字符串内容,因为该字符串是实例化的。

该错误并非特定于.NET 4.0,我在.NET 3.5 SP1的ReferenceSource中也看错了,并且可以在VS2008上重复它。麻烦在于内部WindowsGraphics.MeasureText函数。您可以在connect.microsoft.com报告错误。

一种可行的解决方法是更改​​字符串以便复制它并且不会影响原始字符串:

  string ellipsisedPath = OriginalPath + '\0';

但是在这种情况下更好的解决方法是简单地不传递ModifyString选项,它没有用处。哪个更安全,仍有可能通过第一个解决方法销毁垃圾收集堆。对Microsoft的修复同样简单,它应该掩盖ModifyString选项。据记载,它没有效果。

答案 1 :(得分:2)

  

我的原始字符串被更改为与输出字符串相同。

您已经通过指定文档所说的TextFormatFlags.ModifyString

来要求实现此目的
  

修改指定的字符串以匹配显示的文本。除非还指定了EndEllipsis或PathEllipsis,否则此值无效。

这是(在我看来).NET Framework调用操作的一种不寻常的方式,但它明确表示会这样做。 “原始”字符串和“输出”字符串最终都被修改,因为string是引用类型(尽管通常具有不可变值语义) - 当你说

string ellipsisedPath = OriginalPath;

你实际上只是让ellipsisedPath引用与OriginalPath相同的字符串实例。当这个实例被API调用修改时,对它的引用都会看到修改。

至于

  

路径按预期截断,但后面跟着看起来像C样式的终止null和原始路径的块

我的猜测是,这个托管包装器在Win32 API调用周围提供的抽象有点漏洞,因为抽象很容易出现 - 它不会让你屏蔽底层调用与C风格的字符串一起工作的事实。可能你必须自己处理。