У меня есть несколько элементов управления представлением списка (TListView), которые используются для отображения данных. Все эти представления списка установлены в режим «Подробности», и всем свойствам «SmallIcons» назначен TImageList.
Я пытаюсь установить ширину этих столбцов на основе их содержимого точно так же, как если бы пользователь дважды щелкнул ползунок разделителя в конце каждого из заголовков столбцов.
Во-первых, я попытался установить ширину столбца на «-1» и «-2» для их автоматического изменения размера: мало того, что это не сработало идеально (некоторые столбцы содержат локальные символы — я использую D6, а это означает, что строки ANSI - слишком малы), но это также сделало отображение столбца чрезвычайно медленным (до 30 секунд для отображения представления списка с 6 столбцами и 150 элементами, когда оно мгновенное с фиксированной шириной).
Я попытался использовать GetTextExtent для каждой ячейки, чтобы получить ожидаемую ширину текста, добавив некоторое поле (от 2 до 10 пикселей) и расширив ширину столбца, если она меньше расчетной ширины текста. К первому столбцу (Items.caption) применяется специальная обработка, учитывающая отображение значка (я добавляю ширину значка плюс поле к ширине текста ячейки).
Это тоже не сработало: во многих случаях (например, отображение даты в формате «гггг/мм/дд чч:нн:сс» приводит к тому, что текст слишком велик, чтобы поместиться в столбце).
Думая, что проблема может быть связана с движком темы окна, я переключился на использование GetThemeTextExtent вместо GetTextExtent, но получил тот же результат.
Единственное, что, кажется, работает, — это добавить произвольно большое поле (20 пикселей) к ширине каждого столбца, но, конечно, это приведет к тому, что столбцы будут больше, чем они должны быть.
Итак, есть ли альтернативная стратегия? Мне не нужно ничего, кроме чего-то, что вычислит правильную ширину один раз: когда список будет впервые заполнен. Код, стоящий за «нажатием разделителя столбцов», работает просто отлично, но я не могу найти, как вызвать его с помощью кода (ну, я думаю, я мог бы отправлять сообщения о двойном щелчке в заголовок напрямую как хак)
Для пояснения, вот что я пробовал в следующем коде:
(в случае вызова выполняется вызов ListView.canvas.Font.Assign(ListView.font)
. Этого нет в этих функциях, потому что достаточно одного присваивания, но код зацикливается на всех столбцах списка без автоматического размера).
Изменить
Моя первая попытка использования Windows Theme API:
function _GetTextWidth1(AText: widestring; IsHeader: boolean = false): Integer;
var
ATheme: HTheme;
rValue: TRect;
iPartID: integer;
AWidetext: WideString;
const
LVP_GROUPHEADER = 6;
begin
// try to get text width using theme API
ZeroMemory(@rValue, SizeOf(rValue));
ATheme := OpenThemeData(ListView.Handle, 'LISTVIEW');
try
if not IsHeader then
iPartID := LVP_LISTITEM
else
iPartID := LVP_GROUPHEADER;
AWidetext := AText;
GetThemeTextExtent( ATheme,
ListView.Canvas.Handle,
iPartID,
LIS_NORMAL,
PWideChar(AWidetext),
-1,
DT_LEFT or DT_SINGLELINE or DT_CALCRECT,
nil,
rValue
);
finally // wrap up
CloseThemeData(ATheme);
end; // try/finally
result := rValue.Right;
end;
следующая попытка использования DrawText/DrawTextW:
function _GetTextWidth2(AText: widestring; IsHeader: boolean = false): Integer;
var
rValue: TRect;
lFlags: Integer;
begin
// try to get text width using DrawText/DrawTextW
rValue := Rect(0, 0, 0, 0);
lFlags := DT_CALCRECT or DT_EXPANDTABS or DT_NOPREFIX or DT_LEFT or DT_EXTERNALLEADING;
DrawText(ListView.canvas.Handle, PChar(AText), Length(AText), rValue, lFlags);
//DrawTextW(ListView.canvas.Handle, PWideChar(AText), Length(AText), rValue, lFlags);
result := rValue.Right;
end;
Третья попытка использования функции Delphi TextWidth
function _GetTextWidth3(AText: widestring; IsHeader: boolean = false): Integer;
begin
// try to get text width using delphi wrapped around GetTextExtentPoint32
result := ListView.canvas.TextWidth(Atext);
end;
Во всех случаях я добавляю поле к полученной ширине: я пробовал значения до 20 пикселей. Я также принимаю во внимание возможность того, что в представлении используются значки (в этом случае я снова добавляю ширину значка плюс поля к первому столбцу).
DrawText
с флагомDT_CALCRECT
, например: как правильно использовать drawtext dt calcrect"> stackoverflow.com/questions/16343147/ - person Jerry Dodge   schedule 20.01.2014