![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
LBS_SORT - реализация
n0name © (2005-11-09 08:21:00)Мне необходимо сделать сортировку в ListBox'е.
Для этого я указал стили LBS_OWNERDRAWVARIABLE и LBS_SORT.
Чтоб сортировать, как я понял, я должен обработать WM_COMPAREITEM, в этом нет проблем, однако я не могу правильно сделать отрисовку Item'а в ListBoxe.
На сообщение WM_MEASUREITEM я заполняю все необходимые поля. Не подкинете исходника как отрисовывать элемент. Основная проблема - откуда получать текст. В МСДНе используется WM_GETTEXT, но у меня почему-то не получается.
Вот код:
function ListBoxOnDraw(lParam, wParam: Integer): boolean;
var
DWI: PDrawItemStruct;
Text: PChar;
TextMetr: TEXTMETRICA;
begin
result:=true;
DWI:=PDrawItemStruct(lParam);
If DWI^.itemID=DWORD(-1) then
exit;
Text:=ListBoxGetText(hMain, IDC_SUBNET, DWI^.itemID);
GetTextMetricsA(DWI^.hDC, TextMetr);
TextOut(DWI^.hDC, 6, (DWI^.rcItem.Bottom+DWI^.rcItem.Top-TextMetr.tmHeight) div 2, Text, length(Text));
FreeMemory(Text);
if DWI^.itemAction=ODS_SELECTED then
DrawFocusRect(DWI^.hDC, DWI^.rcItem);
end;
function ListBoxOnMeasure(lParam, wParam: Integer): boolean;
var
hDC: THandle;
TextMetr: TEXTMETRICA;
begin
hDC:=GetDC(GetDlgItem(hMain, IDC_SUBNET));
GetTextMetricsA(hDC, TextMetr);
with PMeasureItemStruct(lParam)^ do
begin
itemWidth:=100;
itemHeight:=TextMetr.tmHeight;
end;
result:=true;
end;
n0name (2005-11-12 10:22:00) [1]Такой вариант почему-то не проходит.
Я так и делал.
Ну да лано буду копаться в компонентах.
Игорь Шевченко (2005-11-09 22:03:00) [2]
> Не подкинете исходника как отрисовывать элемент. Основная
> проблема - откуда получать текст.
function TListBoxStrings.Get(Index: Integer): string;
var
Len: Integer;
begin
if ListBox.Style in [lbVirtual, lbVirtualOwnerDraw] then
Result := ListBox.DoGetData(Index)
else
begin
Len := SendMessage(ListBox.Handle, LB_GETTEXTLEN, Index, 0);
if Len = LB_ERR then Error(SListIndexError, Index);
SetLength(Result, Len);
if Len <> 0 then
begin
Len := SendMessage(ListBox.Handle, LB_GETTEXT, Index, Longint(PChar(Result)));
SetLength(Result, Len); // LB_GETTEXTLEN isn't guaranteed to be accurate
end;
end;
end;
И в прорисовке, соотвественно,
TextOut(Rect.Left+1, Rect.Top+1, ListBox1.Items[Index]);
n0name (2005-11-09 19:43:00) [3]Нет.
Я уже раза 3 всё перепроверял, так неохота было делать собственноручную прорисовку :)
Игорь Шевченко (2005-11-09 18:14:00) [4]n0name (09.11.05 17:50) [8]
А дурацкий совет - если убрать с обычного ListBox стиль LBS_HASSTRING, сообщение будет посылаться ?
n0name (2005-11-09 17:50:00) [5]Численно по возростанию. А не 1, 11, 12, 2, 3, 4.
>Кстати, насколько я понимаю, с точность до наоборот:
Если вы создаёте owner-draw ListBox с LBS_SORT стилем Ине используете LBS_HASSTINGS стиль, то система отсылает сообщение WM_COMPAREITEM.
PS: Проще прочитать всё страницу MSDN'а, но изз-а громоздкости оной, проще поверить мне на слово %)
Игорь Шевченко (2005-11-09 15:00:00) [6]n0name (09.11.05 13:34) [6]
> The LBS_SORT style causes the list box to sort strings alphabetically
Этого недостаточно ? Как надо сортировать ?
Кстати, насколько я понимаю, с точность до наоборот:
"f you create an owner-drawn list box with the LBS_SORT style but notthe LBS_HASSTRINGS style, the system sends the WM_COMPAREITEM message one or more times to the owner of the list box to place the new item properly in the list box. "
n0name (2005-11-09 13:34:00) [7]>OwnerDraw к сортировке вроде не имеет никакого отношения ?
Если бы :(
An owner-drawn list box that has the LBS_SORT style and does not have the LBS_HASSTRINGS style sends a WM_COMPAREITEM message to its parent window when the list box receives an LB_ADDSTRING, LB_FINDSTRING, LB_FINDSTRINGEXACT, or LB_SELECTSTRING message.
WM_COMPAREITEM посылается окну-прародителю только при собственной отрисовке ListBox'a.
The LBS_SORT style causes the list box to sort strings alphabetically that are added to the list box with an LB_ADDSTRING message in either of these cases:
* If the list box is an owner-drawn list box with the LBS_HASSTRINGS style
* If the list box is not an owner-drawn list box
YuRock (2005-11-09 10:32:00) [8]
> OwnerDraw к сортировке вроде не имеет никакого отношения ?
Да вообще фиг его знает... Если сортировать слева-направо - без него не обойтись...
Игорь Шевченко (2005-11-09 10:25:00) [9]OwnerDraw к сортировке вроде не имеет никакого отношения ?
YuRock (2005-11-09 10:23:00) [10]
> Для реализации собственной сортировки.
Для этого и преднозначено WM_COMPAREITEM, если я еще не сплю.
n0name (2005-11-09 10:05:00) [11]Для реализации собственной сортировки.
YuRock (2005-11-09 08:35:00) [12]Вопрос: зачем тебе LBS_OWNERDRAWVARIABLE??