|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
||||
|
||||
Сортировка в ListView WinApi
Здравствуйте.
Как организовать сортировку по клику по колонкам? Искал в инете, но толкового ни чего не неашел(быть может, искал плохо). Встречается либо код на С, либо 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; Je venus de nulle part 55.026263 с.ш., 73.397636 в.д. |