Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > ОС и железо
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 23.11.2014, 17:54
Аватар для Stalker2-42
Stalker2-42 Stalker2-42 вне форума
Новичок
 
Регистрация: 28.09.2013
Сообщения: 94
Версия Delphi: 2010
Репутация: 10
По умолчанию Сортировка в ListView WinApi

Здравствуйте.
Как организовать сортировку по клику по колонкам?
Искал в инете, но толкового ни чего не неашел(быть может, искал плохо).
Встречается либо код на С, либо VCL(Аналогичное у меня есть).
Никак не соображу.
Подскажите пожалуйста.
Ответить с цитированием
  #2  
Старый 23.11.2014, 18:20
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

LVM_SORTITEMS
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #3  
Старый 23.11.2014, 18:32
Аватар для Stalker2-42
Stalker2-42 Stalker2-42 вне форума
Новичок
 
Регистрация: 28.09.2013
Сообщения: 94
Версия Delphi: 2010
Репутация: 10
По умолчанию

Я так понимаю SendMessage(LV, LVM_SORTITEMS, 0, 0) ?
Ответить с цитированием
  #4  
Старый 23.11.2014, 18:37
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

LVM_SORTITEMS
Цитата:
wParam = (WPARAM) (LPARAM) lParamSort;
lParam = (LPARAM) (PFNLVCOMPARE) pfnCompare;

Parameters

lParamSort

Application-defined value that is passed to the comparison function.

pfnCompare

Pointer to the application-defined comparison function. The comparison function is called during the sort operation each time the relative order of two list items needs to be compared.

Return Values

Returns TRUE if successful or FALSE otherwise.

Remarks

The comparison function has the following form:

int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2,
LPARAM lParamSort);

The lParam1 parameter is the 32-bit value associated with the first item being compared; and the lParam2 parameter is the value associated with the second item. These are the values that were specified in the lParam member of the items' LV_ITEM structure when they were inserted into the list. The lParamSort parameter is the same value passed to the LVM_SORTITEMS message.
The comparison function must return a negative value if the first item should precede the second, a positive value if the first item should follow the second, or zero if the two items are equivalent.
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #5  
Старый 23.11.2014, 19:14
Аватар для Stalker2-42
Stalker2-42 Stalker2-42 вне форума
Новичок
 
Регистрация: 28.09.2013
Сообщения: 94
Версия Delphi: 2010
Репутация: 10
По умолчанию

Попытался переделать

Код:
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  
Старый 24.11.2014, 00:53
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Взято из действующей программы
Код:
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 в.д.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра
Комбинированный вид Комбинированный вид

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 09:40.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter