![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
|
|
#1
|
||||
|
||||
|
Здравствуйте.
Как организовать сортировку по клику по колонкам? Искал в инете, но толкового ни чего не неашел(быть может, искал плохо). Встречается либо код на С, либо VCL(Аналогичное у меня есть). Никак не соображу. Подскажите пожалуйста. |
|
#2
|
||||
|
||||
|
LVM_SORTITEMS
|
|
#3
|
||||
|
||||
|
Я так понимаю SendMessage(LV, LVM_SORTITEMS, 0, 0) ?
|
|
#4
|
||||
|
||||
|
LVM_SORTITEMS
Цитата:
|
|
#5
|
||||
|
||||
|
Попытался переделать
Код:
if(nmhdr->code == LVN_COLUMNCLICK)
{
NM_LISTVIEW *pnm;
pnm = (NM_LISTVIEW *) lParam; // заполняем структуру NM_LISTVIEW
// сортируем
ListView_SortItems(pnm->hdr.hwndFrom, // идентификатор окна List View
CompareListViewProc, // указатель на функцию сравнения
(LPARAM) (pnm->iSubItem)); // если в функцию сравнения нужно передать какое либо значение, этот параметр для этого. я тут передаю просто номер столбца
break;
int CALLBACK CompareListViewProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
CHAR Buff1[1024]={0};
CHAR Buff2[1024]={0};
LPSTR lpStr1, lpStr2;
INT iNum1=0, iNum2=0;
INT iResult, iIndex=0;
LVFINDINFO ItemInfo;
ItemInfo.flags=LVFI_PARAM;
// копируешь в буфера сравниваемые строки
ItemInfo.lParam=lParam1;
iIndex=ListView_FindItem(hWndListView, -1, &ItemInfo);
ListView_GetItemText(hWndListView, iIndex, (int)lParamSort, Buff1, sizeof(Buff1));
lpStr1=Buff1;
ItemInfo.lParam=lParam2;
iIndex=ListView_FindItem(hWndListView, -1, &ItemInfo);
ListView_GetItemText(hWndListView, iIndex, (int)lParamSort, Buff2, sizeof(Buff2));
lpStr2=Buff2;
if(lpStr1 && lpStr2)
{
switch(lParamSort)
{
// тут по номеру столбца, делается сравнение
case 0:
case 4:
iResult=strcmpi(lpStr1, lpStr2);
break;
case 1:
case 2:
case 3:
iNum1 = atoi(lpStr2);
iNum2 = atoi(lpStr1);
iResult = iNum2 - iNum1;
break;
default:
iResult=0;
break;
}
}
// возврат результата сравнения
return(iResult);
}Вот что получилось(в моем Listview 7 колонок): Код:
LVN_COLUMNCLICK : ListView_SortItems(LV, @CompareFunc, PNMLISTVIEW(lParam).iSubItem);
function CompareFunc(LPARAM1, LPARAM2, lParamSort: Cardinal): Integer; stdcall;
var
Buff1, Buff2 : array[0..1024] of Char;
lpStr1, lpStr2 : string;
iNum1, iNum2, iResult, iIndex : Integer;
ItemInfo : LV_FINDINFO;
begin
ItemInfo.flags := LVFI_PARAM;
// копируешь в буфера сравниваемые строки
ItemInfo.lParam := lParam1;
iIndex := ListView_FindItem(LV, -1, &ItemInfo);
ListView_GetItemText(LV, iIndex, lParamSort, Buff1, sizeof(Buff1));
lpStr1 := Buff1;
ItemInfo.lParam := lParam2;
iIndex := ListView_FindItem(lParamSort, -1, &ItemInfo);
ListView_GetItemText(lParamSort, iIndex, lParamSort, Buff2, sizeof(Buff2));
lpStr2 := Buff2;
// if(lpStr1 and lpStr2) then
case (lParamSort) of
// тут по номеру столбца, делается сравнение
// 0:
0..7:
iResult := lstrcmp(PChar(lpStr1), PChar(lpStr2));
// break;
// case 1:
// case 2:
{ 3:
iNum1 = atoi(lpStr2);
iNum2 = atoi(lpStr1);
iResult = iNum2 - iNum1;
break;
default: }
// break;
// возврат результата сравнения
end; // iResult:=0;
Result := (iResult);
end;Поправте пожалуйста, а то чертовщина какято тварится(вроде строки бегают, но не так как надо). |
|
#6
|
||||
|
||||
|
Взято из действующей программы
Код:
function CompareFunc(lParam1, lParam2, SortType : Longint) : Integer; stdcall;
var
lvi : LV_ITEM;
Size1,
Size2 : Integer;
Column : Word;
St1, St2 : String;
begin
Column := LOWORD(SortType);
lvi.mask := LVIF_TEXT;
if Column = 0 then
begin
Result := AnsiCompareText(LV_GetItemText(hLV, lParam1, 0), LV_GetItemText(hLV, lParam2, 0));
end
else if Column = LVSize + 1 then
begin
try
Size1 := StrToInt(Copy(LV_GetItemText(hLV, lParam1, Column), 1, Pos(' ', LV_GetItemText(hLV, lParam1, Column)) - 1));
Size2 := StrToInt(Copy(LV_GetItemText(hLV, lParam2, Column), 1, Pos(' ', LV_GetItemText(hLV, lParam2, Column)) - 1));
Result := Size1 - Size2;
except
Result := 0;
end;
end
else
begin
St1 := LV_GetItemText(hLV, lParam1, Column);
St2 := LV_GetItemText(hLV, lParam2, Column);
Result := AnsiCompareText(St1, St2);
if (St1 = '') or (St2 = '') then
Result := 0;
end;
if isSorted then
Result := Result
else
Result := -Result;
end;
procedure DrawColumnImage(hHeader : HWND; Column : Integer; bmp : Integer);
var
Item : THDITEM;
begin
FillChar(Item, SizeOf(ThdItem), 0);
Item.Mask := HDI_FORMAT;
if (not Header_GetItem(hHeader, Column, Item)) then
Exit;
if (Bmp = 0) then
begin
Item.mask := HDI_FORMAT;
Item.fmt := Item.fmt and not (HDF_BITMAP or HDF_BITMAP_ON_RIGHT);
end
else
begin
Item.mask := Item.Mask or HDI_BITMAP;
Item.fmt := Item.fmt or HDF_BITMAP or HDF_BITMAP_ON_RIGHT;
Item.hbm := Bmp;
end;
Header_SetItem(hHeader, Column, Item);
end;
procedure SortItems(hList : HWND; Column, bmArUp, bmArDn : Integer);
var
hHeader : HWND;
Item : THDITEM;
I : Integer;
St : String;
bm : Integer;
begin
hLV := hList;
St := '';
for I := 0 to LV_Count(hList) - 1 do
St := St + LV_GetItemText(hList, I, Column);
if (St = '') then
begin
hHeader := ListView_GetHeader(hList);
if (hHeader = 0) then
Exit;
DrawColumnImage(hHeader, 0, 0);
Exit;
end;
hHeader := ListView_GetHeader(hList);
if (hHeader = 0) then
Exit;
if Column = SortColumn then
isSorted := not isSorted
else
begin
SortColumn := Column;
isSorted := True;
end;
if (Column <> -1) then
begin
FillChar(Item, SizeOf(THDITEM), 0);
Item.mask := Item.mask or HDI_LPARAM;
if (not Header_GetItem(hHeader, Column, Item)) then
Exit;
Item.lParam := not Item.lParam;
Header_SetItem(hHeader, Column, Item);
end;
for I := 0 to LV_Count(hList) - 1 do
begin
if I <> Column then
bm := 0
else
begin
if isSorted then
bm := bmArUp
else
bm := bmArDn;
end;
DrawColumnImage(hHeader, I, bm);
end;
if (Column <> -1) then
ListView_SortItems(hList, @CompareFunc, MAKELONG(Column, ord(isSorted)));
end; |