Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> ListView сортировка 
:(
    Опции темы
neosapient
Дата 23.1.2008, 19:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 672
Регистрация: 16.8.2006

Репутация: 3
Всего: 4



Вопрос: как отсортировать поля в ListView.
В приложении мой пример, не могу понять что не работает?

Помогите найти ошибку. 
Диагноз такой, когда человек щелкает по шапке столбца, то начинает вызываться моя функция сравнения ListSort(...)
Последний параметр воспринимаю бес проблем. А вот в два других ничего не передается. Почему? немогу понять...
Код

// точка входа

#include <windows.h>
#include "resource.h"
// подключаем нестандартные контролы
#include <commctrl.h>
#pragma comment(lib,"comctl32.lib")
#include <stdio.h>

HINSTANCE hInst;
LRESULT CALLBACK Proc (HWND, UINT, WPARAM, LPARAM);
void massageprocess ();
BOOL InitListViewColumns(HWND hWndListView);
int CALLBACK ListSort(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);

WINAPI WinMain // точка входа в Windows программу
(HINSTANCE hInstance, HINSTANCE hPrevInstance,
 LPSTR lpCmdLine, int nCmdShow)
{
    HWND hDlg;
    // сохраняем индентификатор приложения
    hInst=hInstance;
    // инициализация дополнительных компонентов
    InitCommonControls (); 
    // создаем диалог
    hDlg=CreateDialog(hInst,MAKEINTRESOURCE(IDD_DIALOG1),0,(DLGPROC)Proc);
    // показать диалог
    ShowWindow(hDlg, SW_SHOW);
    // обрабатываем очередь сообщений
    massageprocess ();
    return 0;
}

// оконная процедура для обработки сообщений
LRESULT CALLBACK Proc
(HWND hDlg,UINT msg,WPARAM wParam,LPARAM lParam)
{
    NMLISTVIEW *lpNm;
    LPNMHDR pnmh;
    switch(msg)
    {
    case WM_INITDIALOG :  
        InitListViewColumns(GetDlgItem(hDlg,IDC_LIST1));
        break;
    case WM_COMMAND:  
        switch (LOWORD(wParam))
        {
        case IDCANCEL:
            EndDialog(hDlg, LOWORD(wParam));
            PostQuitMessage(0);
            return TRUE;
        case IDOK:
            break;         
        }
        break;
    case WM_NOTIFY:
        pnmh = (LPNMHDR)lParam;
        switch (pnmh->code)
        {
        case LVN_COLUMNCLICK:
            lpNm = (NMLISTVIEW *)lParam;
            ListView_SortItems(lpNm->hdr.hwndFrom, (PFNLVCOMPARE)ListSort, (LPARAM)(lpNm));

            break;
        }
        break;         
    case WM_KEYDOWN:  
        switch (wParam) 
            { 
                case VK_ESCAPE:
                    PostQuitMessage(0);
                    break;
            }
        break;

    case WM_DESTROY: //сообщение уничтожения окна 
        PostQuitMessage(0);
        break;
    }
return 0;
}

void massageprocess()
{MSG msg;
// получаем в цикле следующее сообщение из очереди
// сообщений
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

BOOL InitListViewColumns(HWND hWndListView) 
{ 
    char szText[256];     // temporary buffer 
    LVCOLUMN lvc; 
    int i; 
    char localbuf[80];
    char *mas[]={"first","second"};
    char *mas1[]={"3","1","5","2","4"};
    char *mas2[]={"third","first","fifth","second","fourth"};

    lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT |LVCF_SUBITEM; 
    for (i = 0; i < 2; i++) 

    { 
        lvc.iSubItem = i;
        lvc.pszText = mas[i];    
        lvc.cx = 90;     // width of column in pixels
        lvc.fmt = LVCFMT_CENTER;  // left-aligned column
        if (ListView_InsertColumn(hWndListView, i,&lvc) == -1) 
            return FALSE; 
    } 

    LVITEM lvI;
    lvI.mask = LVIF_TEXT | LVIF_STATE ; 
    lvI.state = 0; 
    lvI.stateMask = 0; 

    // Initialize LVITEM members that are different for each item. 
    for (int index = 0; index < 5; index++)
    {
        lvI.iItem = index;
        lvI.iSubItem = 0;
        lvI.pszText =  mas1[index];
        lvI.cchTextMax = strlen(mas1[index]);
        ListView_InsertItem(hWndListView, &lvI);

        lvI.iItem = index;
        lvI.iSubItem = 1;
        lvI.pszText =  mas2[index];
        lvI.cchTextMax = strlen(localbuf);
        ListView_SetItem(hWndListView, &lvI);
        //ListView_InsertItem(hWndListView, &lvI);
    }
    return TRUE; 
} 


int CALLBACK ListSort(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
    NMLISTVIEW *lpNm = NULL;
    HWND hList = NULL;
    TCHAR pszBuff0[256]={0};
    TCHAR pszBuff1[256]={0};
    int iSubItem=0;

    lpNm = (NMLISTVIEW*)lParamSort;
    hList = lpNm->hdr.hwndFrom;
    iSubItem = lpNm->iSubItem;
    ListView_GetItemText(hList,lParam1,iSubItem,pszBuff0,256);
    ListView_GetItemText(hList,lParam2,iSubItem,pszBuff1,256);
    return strcmp(pszBuff0, pszBuff1);
}


Присоединённый файл ( Кол-во скачиваний: 7 )
Присоединённый файл  ListViewSortTest.rar 4,35 Kb
PM MAIL   Вверх
Earnest
Дата 23.1.2008, 19:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



 smile 
Цитата

The comparison function has the following form: 

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

The lParam1 parameter is the 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' LVITEM structure when they were inserted into the list. The lParamSort parameter is the same value passed to the LVM_SORTITEMS message. 

Что положил в итемы, то и передается... А ты, насколько я вижу, ничего туда не положил...


--------------------
...
PM   Вверх
neosapient
Дата 24.1.2008, 12:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 672
Регистрация: 16.8.2006

Репутация: 3
Всего: 4



Я ни на английском, ни на русском не могу понять алгоритма мох действий по продготовке и проведению поиска.
У меня в голове лежит следующий стериотип.

Я вызываю макрос 
Код

BOOL ListView_SortItemsEx(
    HWND hwnd,
    PFNLVCOMPARE pfnCompare,
    LPARAM lParamSort
);


В первый параметр передаю хендл ListView
Во второй параметр указатель на функцию сравнения двух элементов.
В третий параметр - четырехбайтное значение, которое будет передано моей функции, в моем случае это указатель на структуру.
Управление берет на себя винда. Она по какому то алгоритму (думаю qsort) начинает попарное сравнение, всех элементов.
Далее сортировка. Выбираются два элемента, и передаются в функцию сравнения (вместе с третим, в котором управляющие параметры передаем себе)

Код

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


Я не понимаю на каком шаге и где, мною что то кладется?

Хотелось бы рабочий пример или этот подправить.
PM MAIL   Вверх
Earnest
Дата 24.1.2008, 12:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



lParam1 и 2 это lParam из элемента лист-вью (из структуры LVITEM), который ты туда помещаешь (можешь поместить) в момент наполнения лист-вью. Пример сейчас не найду, но помню, что была тема про сортировку в лист вью, поищи.


--------------------
...
PM   Вверх
neosapient
Дата 24.1.2008, 14:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 672
Регистрация: 16.8.2006

Репутация: 3
Всего: 4



Вроде разобрался.
Помещаю на момент заполнения ListView в переменную LVITEM::lParam свои значения (уменя отличные от нуля - соответствующие пересчету) и добавляю флаг LVITEM::mask |= LVIF_PARAM.

затем в функции сравнения получаю входные LVITEM::lParam 


Начало сортировать )
Вот только второй столбец исчез когда я сменил стиль на LVITEM::mask |= LVIF_PARAM.

Как исправить это недоразумение? )

Это сообщение отредактировал(а) neosapient - 24.1.2008, 14:41

Присоединённый файл ( Кол-во скачиваний: 6 )
Присоединённый файл  ListViewSortTest2.rar 4,41 Kb
PM MAIL   Вверх
neosapient
Дата 24.1.2008, 15:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 672
Регистрация: 16.8.2006

Репутация: 3
Всего: 4



Вроде разобрался
Рабочий вариант

Код

// точка входа

#include <windows.h>
#include "resource.h"
// подключаем нестандартные контролы
#include <commctrl.h>
#pragma comment(lib,"comctl32.lib")
#include <stdio.h>

HINSTANCE hInst;
LRESULT CALLBACK Proc (HWND, UINT, WPARAM, LPARAM);
void massageprocess ();
BOOL InitListViewColumns(HWND hWndListView);
int CALLBACK ListSort(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);

WINAPI WinMain // точка входа в Windows программу
(HINSTANCE hInstance, HINSTANCE hPrevInstance,
 LPSTR lpCmdLine, int nCmdShow)
{
    HWND hDlg;
    // сохраняем индентификатор приложения
    hInst=hInstance;
    // инициализация дополнительных компонентов
    InitCommonControls (); 
    // создаем диалог
    hDlg=CreateDialog(hInst,MAKEINTRESOURCE(IDD_DIALOG1),0,(DLGPROC)Proc);
    // показать диалог
    ShowWindow(hDlg, SW_SHOW);
    // обрабатываем очередь сообщений
    massageprocess ();
    return 0;
}

// оконная процедура для обработки сообщений
LRESULT CALLBACK Proc
(HWND hDlg,UINT msg,WPARAM wParam,LPARAM lParam)
{
    NMLISTVIEW *lpNm;
    LPNMHDR pnmh;
    switch(msg)
    {
    case WM_INITDIALOG :  
        InitListViewColumns(GetDlgItem(hDlg,IDC_LIST1));
        break;
    case WM_COMMAND:  
        switch (LOWORD(wParam))
        {
        case IDCANCEL:
            EndDialog(hDlg, LOWORD(wParam));
            PostQuitMessage(0);
            return TRUE;
        case IDOK:
            break;         
        }
        break;
    case WM_NOTIFY:
        pnmh = (LPNMHDR)lParam;
        switch (pnmh->code)
        {
        case LVN_COLUMNCLICK:
            lpNm = (NMLISTVIEW *)lParam;
            ListView_SortItems(lpNm->hdr.hwndFrom, (PFNLVCOMPARE)ListSort, (LPARAM)(lpNm));

            break;
        }
        break;         
    case WM_KEYDOWN:  
        switch (wParam) 
            { 
                case VK_ESCAPE:
                    PostQuitMessage(0);
                    break;
            }
        break;

    case WM_DESTROY: //сообщение уничтожения окна 
        PostQuitMessage(0);
        break;
    }
return 0;
}

void massageprocess()
{MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

BOOL InitListViewColumns(HWND hWndListView) 
{ 
    char szText[256];     // temporary buffer 
    LVCOLUMN lvc; 
    int i; 
    char localbuf[80];
    char *mas[]={"first","second"};
    char *mas1[]={"3","1","5","2","4"};
    char *mas2[]={"third","first","fifth","second","fourth"};
    DWORD style;

    style = ListView_GetExtendedListViewStyle(hWndListView);
    style |= LVS_REPORT|LVS_EX_FULLROWSELECT ;
    ListView_SetExtendedListViewStyle (hWndListView,style);

    lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT |LVCF_SUBITEM; 
    for (i = 0; i < 2; i++) 

    { 
        lvc.iSubItem = i;
        lvc.pszText = mas[i];    
        lvc.cx = 90;     // width of column in pixels
        lvc.fmt = LVCFMT_CENTER;  // left-aligned column
        if (ListView_InsertColumn(hWndListView, i,&lvc) == -1) 
            return FALSE; 
    } 

    LVITEM lvI;
    lvI.mask = LVIF_TEXT | LVIF_STATE; 
    lvI.state = 0; 
    lvI.stateMask = 0; 

    // Initialize LVITEM members that are different for each item. 
    for (int index = 0; index < 5; index++)
    {

        //---- ссылка для сортировки
        lvI.lParam = atoi(mas1[index]);
        lvI.mask |= LVIF_PARAM; 

        //---- заполнение 0 столбца (создание элемента)
        lvI.iItem = index;
        lvI.iSubItem = 0;
        lvI.pszText =  mas1[index];
        lvI.cchTextMax = strlen(mas1[index]);
        ListView_InsertItem(hWndListView, &lvI);

        //---- убираем ссылку для сортировки (в остальных полях не нужна)
        lvI.mask = lvI.mask&(~LVIF_PARAM); 

        //---- заполнение 1 столбца
        lvI.iItem = index;
        lvI.iSubItem = 1;
        lvI.pszText =  mas2[index];
        lvI.cchTextMax = strlen(mas2[index]);
        ListView_SetItem(hWndListView, &lvI);
    }
    return TRUE; 
} 


int CALLBACK ListSort(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
    NMLISTVIEW *lpNm = NULL;
    HWND hList = NULL;
    TCHAR pszBuff0[256]={0};
    TCHAR pszBuff1[256]={0};
    int iSubItem=0;

    return lParam1>lParam2;
}


Для ListView есть ещё макросы ListView_SortItemsEx и ListView_SortGroups 
Чем эти сортиовки отличаются?

Это сообщение отредактировал(а) neosapient - 24.1.2008, 15:37

Присоединённый файл ( Кол-во скачиваний: 19 )
Присоединённый файл  ListViewSortTest3.rar 4,45 Kb
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0490 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.