Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 16.11.2013, 21:37   #1
slipp
Пользователь
 
Регистрация: 07.11.2013
Сообщений: 21
Счастье virtuallistview

Код:
//создаем list view
#include <windows.h>
#include "resource.h"
#include <CommCtrl.h>

#pragma comment(lib, "comctl32")

BOOL CALLBACK DlgProc(HWND,UINT,WPARAM,LPARAM);

//void DlgOnCommand(HWND,int,HWND,UINT);
//BOOL DlgOnInitDialog(HWND,HWND,LPARAM);
HINSTANCE hInstance;
int WINAPI WinMain(HINSTANCE hlnst,HINSTANCE,LPSTR,int)
{
  hInstance=hlnst;
  InitCommonControls();
  DialogBox(hlnst,MAKEINTRESOURCE(IDD_DIALOG),NULL,DlgProc);
  return 0;
}

BOOL CALLBACK DlgProc(HWND hwnd,UINT msg, WPARAM wParam,LPARAM lParam)
{
  switch(msg)
  {
  case WM_INITDIALOG:
    {
      char szName[]="имя файла";
      char szSize[]="размер файла";

      char szFileName[80];
      char szFileSize[10]="9999.99";

     // DWORD dwFileSize;
      int nItemIndex=0;

      HWND hWndList= CreateWindowEx(0, WC_LISTVIEW, NULL, WS_CHILD|WS_BORDER|WS_VISIBLE|LVS_REPORT
        ,20,15, 270, 250, hwnd, NULL, hInstance,NULL);

      //-----------------------------------------------------------------------
      //заголовок
      LV_COLUMN lvc;
      ZeroMemory(&lvc,sizeof(lvc));

      lvc.mask=LVCF_FMT|LVCF_SUBITEM|LVCF_TEXT|LVCF_WIDTH;
      lvc.fmt=LVCFMT_LEFT;//выравнивание
      
      lvc.cx=150;
      lvc.pszText=(LPSTR)szName;
      ListView_InsertColumn(hWndList,0,&lvc);

      lvc.cx=120;
      lvc.pszText=(LPSTR)szSize;
      ListView_InsertColumn(hWndList,1,&lvc);

      //-----------------------------------------------------------------------
      //список
      LV_ITEM lvi;
      ZeroMemory(&lvi,sizeof(lvi));
      
      lvi.mask=LVIF_TEXT;
      //lvc.pszText=szFileName;
      
      strcpy (szFileName,"filename");
      for(int i=0;i!=20;i++)
      { 
        lvi.iItem=nItemIndex;
        
        ListView_InsertItem(hWndList,&lvi);
        ListView_SetItemText(hWndList,nItemIndex,0,(LPSTR)szFileName);
        ListView_SetItemText(hWndList,nItemIndex,1,(LPSTR)szFileSize);
        nItemIndex++;
      }
      return TRUE;
    }

  case WM_COMMAND:
    switch(LOWORD(wParam))
    {
    case IDOK:
    case IDCANCEL:
      EndDialog(hwnd,0);
      break;
    }
  default:
    return FALSE;
  }
}
как виртуализировать этот список.
используя LVS_OWNERDATA.

может кто подкинет примерчик...
slipp вне форума Ответить с цитированием
Старый 16.11.2013, 22:29   #2
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Сначала через WM_SETITEMCOUNT сообщаем сколько строчек будет, а потом обрабатываем LVN_GETDISPINFO.
waleri вне форума Ответить с цитированием
Старый 18.11.2013, 19:02   #3
slipp
Пользователь
 
Регистрация: 07.11.2013
Сообщений: 21
Счастье

it is terminated

complete
complete
complete

Цитата:
Сообщение от waleri Посмотреть сообщение
Сначала через WM_SETITEMCOUNT сообщаем сколько строчек будет, а потом обрабатываем LVN_GETDISPINFO.
с этим разобрался

следующий непонятный вопрос:

как заставить виртуальный список сортироватся при клике по заголовку колонки...
Изображения
Тип файла: jpg VLV.jpg (63.3 Кб, 63 просмотров)

Последний раз редактировалось Stilet; 23.11.2013 в 23:56.
slipp вне форума Ответить с цитированием
Старый 19.11.2013, 16:46   #4
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Никак - самому, ручками.
Отслеживаем LVN_COLUMNCLICK, дальше сортируем сами.
waleri вне форума Ответить с цитированием
Старый 19.11.2013, 17:24   #5
slipp
Пользователь
 
Регистрация: 07.11.2013
Сообщений: 21
Счастье sort

вот так определил LVN_COLUMNCLICK
в каждом case: определен метод для сортировки контейнера в котором находятся все записи...

что делаю не так??
Код:
case LVN_COLUMNCLICK:
      {
        NMLVDISPINFO* plvdi = (NMLVDISPINFO*)lParam;
          
          switch (plvdi->item.iSubItem)
          {
          case 0:
            //"имя файла"
            sort(directory.begin(), directory.end(), boost::bind(less<string>(), boost::bind(&data::_name, _1), boost::bind(&data::_name, _2)));//убывание
            break;
          case 1:
            //"путь к файлу"
            sort(directory.begin(), directory.end(), boost::bind(less<string>(), boost::bind(&data::_path, _1), boost::bind(&data::_path, _2)));//убывание
            break;
          case 2:
            //"размер файла"
            sort(directory.begin(), directory.end(), boost::bind(less<uintmax_t>(), boost::bind(&data::_fsize, _1), boost::bind(&data::_fsize, _2)));//убывание
            break;
          case 3:
            //"когда создан"
            sort(directory.begin(),directory.end(),compareTimeLess);
            break;
          default:
            break;
          }
      }
все колонки сортируются уже при старте диалога. по нажатию ничего не происходит...

Последний раз редактировалось slipp; 19.11.2013 в 17:32.
slipp вне форума Ответить с цитированием
Старый 19.11.2013, 17:42   #6
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

case LVN_COLUMNCLICK это конечно хорошо, а вот каков здесь switch?
LVN_COLUMNCLICK - это не сообщение окна.
waleri вне форума Ответить с цитированием
Старый 19.11.2013, 17:49   #7
slipp
Пользователь
 
Регистрация: 07.11.2013
Сообщений: 21
По умолчанию

очевидно так?
Код:
case LVN_COLUMNCLICK:
          {
            NM_LISTVIEW* plvdi = (NM_LISTVIEW*)lParam;
            switch (plvdi->iSubItem)
            {
            case 0:
              {
                //"имя файла"
                sort(directory.begin(), directory.end(), boost::bind(less<string>(), boost::bind(&data::_name, _1), boost::bind(&data::_name, _2)));//убывание
                break;
              }
            case 1:
              {
                //"путь к файлу"
                sort(directory.begin(), directory.end(), boost::bind(less<string>(), boost::bind(&data::_path, _1), boost::bind(&data::_path, _2)));//убывание
                break;
              }
            case 2:
              {
                //"размер файла"
                sort(directory.begin(), directory.end(), boost::bind(less<uintmax_t>(), boost::bind(&data::_fsize, _1), boost::bind(&data::_fsize, _2)));//убывание
                break;
              }
            case 3:
              {
                //"когда создан"
                sort(directory.begin(),directory.end(),compareTimeLess);
                break;
              }
              /*
              default:
              break;
              */
            }
          }
данные виртуального списка хранятся в контейнере (данные добавляются в конец контейнера). можно ли по мере добавления данных отрисовывать не весь список, а только добавленную в конец контейнера информацию.

Последний раз редактировалось Stilet; 23.11.2013 в 23:57.
slipp вне форума Ответить с цитированием
Старый 22.11.2013, 07:38   #8
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Список все равно рисует только то, что умещается на экране.
У LVM_SETITEMCOUNT есть флаги, которые определяют как и что перерисовывать.

Если речь идет о том, чтоб показывать новые елементы, смотрите LVM_ENSUREVISIBLE (правда с виртуальным списком я никогда не пробовал).
waleri вне форума Ответить с цитированием
Старый 23.11.2013, 06:44   #9
slipp
Пользователь
 
Регистрация: 07.11.2013
Сообщений: 21
Счастье

при добавлении большого количества элементов в список происходят частые мерцания... пробовал ListView_SetItemCountEx с флагом LVSICF_NOINVALIDATEALL но тогда не работает сортировка по нажатии заголовка колонки... как поправить?
slipp вне форума Ответить с цитированием
Старый 23.11.2013, 23:50   #10
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Есть WM_SETREDRAW, но правильнее всего вызывать WM_SETITEMCOUNT только один раз, в конце, когда все данные собраны.
waleri вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц