Форум: "WinAPI";
Текущий архив: 2006.01.22;
Скачать: [xml.tar.bz2];
ВнизLBS_SORT - реализация Найти похожие ветки
← →
n0name (2005-11-09 08:21) [0]Мне необходимо сделать сортировку в 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;
← →
YuRock © (2005-11-09 08:35) [1]Вопрос: зачем тебе LBS_OWNERDRAWVARIABLE??
← →
n0name (2005-11-09 10:05) [2]Для реализации собственной сортировки.
← →
YuRock © (2005-11-09 10:23) [3]
> Для реализации собственной сортировки.
Для этого и преднозначено WM_COMPAREITEM, если я еще не сплю.
← →
Игорь Шевченко © (2005-11-09 10:25) [4]OwnerDraw к сортировке вроде не имеет никакого отношения ?
← →
YuRock © (2005-11-09 10:32) [5]
> OwnerDraw к сортировке вроде не имеет никакого отношения ?
Да вообще фиг его знает... Если сортировать слева-направо - без него не обойтись...
← →
n0name (2005-11-09 13:34) [6]>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
← →
Игорь Шевченко © (2005-11-09 15:00) [7]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 not the 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 17:50) [8]Численно по возростанию. А не 1, 11, 12, 2, 3, 4.
>Кстати, насколько я понимаю, с точность до наоборот:
Если вы создаёте owner-draw ListBox с LBS_SORT стилем И не используете LBS_HASSTINGS стиль, то система отсылает сообщение WM_COMPAREITEM.
PS: Проще прочитать всё страницу MSDN"а, но изз-а громоздкости оной, проще поверить мне на слово %)
← →
Игорь Шевченко © (2005-11-09 18:14) [9]n0name (09.11.05 17:50) [8]
А дурацкий совет - если убрать с обычного ListBox стиль LBS_HASSTRING, сообщение будет посылаться ?
← →
n0name (2005-11-09 19:43) [10]Нет.
Я уже раза 3 всё перепроверял, так неохота было делать собственноручную прорисовку :)
← →
Игорь Шевченко © (2005-11-09 22:03) [11]
> Не подкинете исходника как отрисовывать элемент. Основная
> проблема - откуда получать текст.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-12 10:22) [12]Такой вариант почему-то не проходит.
Я так и делал.
Ну да лано буду копаться в компонентах.
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2006.01.22;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.051 c