Добавьте Эллипсис к Пути в Программе WinForms без (пересмотренного) вызова API Win32

Я искал способ вставить замещающий знак в путь C# и нашел ответ здесь на stackoverflow: Эллипсис Пути C# без вызова API Win32

Используя версии RTM VS2010 и.Net 4.0, я не мог заставить предложенный метод работать. Я искал 'Сеть и нашел пример кода, который использует тот же метод, но это перестало работать таким же образом.

Вы видите строку, которую я пытаюсь укоротить в своем коде ниже.

После вызова метода MeasureText и входная строка (OriginalName) и выходная строка (ellipsisedName) похожи на это:

d:\abcd\efgh\ijkl\mnop\qrst\...\test.txt\0F\GHIJ\KLMN\OPQR\STIV\WXYZ\test.txt

Две проблемы:

1) Получившая строка является narfed (путь является усеченным как ожидалось, но сопровождается тем, что похоже на пустой указатель завершения C-стиля и блок первоначального тракта).

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);
      }
   }
}

5
задан Community 23 May 2017 в 11:53
поделиться

2 ответа

Святая милая, вы нашли огромную ошибку. P / Invoke, используемый внутри класса TextRenderer, который вызывает DrawTextEx (), не работает. Эта функция API выполняет обратную запись в строку, что ей разрешено, поскольку аргумент cchText является LPTSTR, а не LPCTSTR. Это уничтожит содержимое строки .NET для обеих переменных, поскольку строка интернирована.

Ошибка не специфична для .NET 4.0, я считаю ее неправильной и в ReferenceSource для .NET 3.5 SP1, и могу воспроизвести ее на VS2008. Проблема во внутренней функции WindowsGraphics.MeasureText. Вы можете сообщить об ошибке на сайте connect.microsoft.com.

Возможный обходной путь - изменить строку так, чтобы она копировалась и не могла повлиять на оригинал:

  string ellipsisedPath = OriginalPath + '\0';

Но лучший обходной путь в этом случае - просто не передавать параметр ModifyString, это бесполезно. Что тоже безопаснее, все еще есть возможность уничтожить кучу собранного мусора с помощью первого обходного пути. Исправление для Microsoft так же просто, оно должно просто замаскировать параметр ModifyString. Документально подтверждено, что это не имеет никакого эффекта.

4
ответ дан 14 December 2019 в 13:30
поделиться

Моя исходная строка изменена, чтобы быть идентичной выходной строке.

Вы попросили, чтобы это произошло, указав TextFormatFlags.ModifyString , что в документации сказано

Изменяет указанную строку , чтобы она соответствовала отображаемому тексту. Это значение не действует, если также не указаны EndEllipsis или PathEllipsis.

Это (на мой взгляд) необычный способ работы вызова .NET Framework, но в нем ясно сказано, что он будет это делать.И "исходная" строка, и "выходная" строка в конечном итоге изменяются, потому что строка является ссылочным типом (хотя обычно с семантикой неизменяемого значения) - когда вы говорите

string ellipsisedPath = OriginalPath;

, вы фактически просто делаете ellipsisedPath относится к тому же экземпляру строки, что и OriginalPath . Когда этот экземпляр будет изменен вызовом API, обе ссылки на него увидят изменение.

Что касается

, путь усекается, как и ожидалось, но за ним следует то, что выглядит как завершающий ноль в стиле C, и фрагмент исходного пути

, я предполагаю, что абстракция, которую предоставляет эта управляемая оболочка вокруг вызов Win32 API несколько нечеткий, поскольку абстракции склонны к существованию - это не защищает вас от того факта, что основной вызов работает со строками в стиле C. Возможно, вам придется разобраться с собой.

2
ответ дан 14 December 2019 в 13:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: