» ListView: обычный список

K.A.V.
www.oszone.net
22.02.2010
Автор: K.A.V.
Последнее обновление: 17.05.2014

Примечание. Для работы с данным элементом необходимо добавить в код:
!include "nsDialogs.nsh"
!include "CommCtrl.nsh"

Т.к. данный тип элемента не поддерживается NIS Edit -  нам необходимо вручную прописать тип элемента в настройки с секцией элемента
Для этого создаём любой элемент, доступный в NIS Edit, для наглядности лучше создать элемент "ListBox", подгоните размеры элемента и читайте дальше :)
Затем переходим в режим редактирования (F12), ищем порядковый номер нашего созданного элемента и меняем значение параметра Type на ListView
[Field 1]
Type=ListView

Для создания взаимодействующего элемента:
NOTIFY=ONSELCHANGE


Необходимые стили

Начнем работу с данным элементом с того, что присвоим ему необходимый стиль для нашей работы, назначив параметру Flags значение REPORT_VIEW

Т.к. этот урок предназначен для элемента без колонок, добавляем команду добавления стиля, запрещающего отображаться в стиле колонок (после инициализации):
${NSD_AddStyle} $HWND "${LVS_NOCOLUMNHEADER}"
где $HWND - HWND элемента

Если вы хотите, чтобы при выделении мышкой пункта в списке выделялась вся строка целиком, а не только текст, то после инициализации необходимо присвоить ещё один стиль данному элементу командой:
SendMessage $HWND ${LVM_SETEXTENDEDLISTVIEWSTYLE} "${LVS_EX_FULLROWSELECT}" "${LVS_EX_FULLROWSELECT}"
где $HWND - HWND элемента

Также, после добавления элементов вам необходимо прописать ещё одну команду:
SendMessage $HWND ${LVM_SETCOLUMNWIDTH} "0" "${LVSCW_AUTOSIZE_USEHEADER}"
где $HWND - HWND элемента


Не забывайте

После добавления/удаления/редактирования пункта для растягивания границы отображения текста во весь элемент или же для того, чтобы при выделении мышкой пункта в списке выделялась вся строка целиком, мы должны корректировать область видимости информации в элементе:
SendMessage $HWND ${LVM_SETCOLUMNWIDTH} "0" "${LVSCW_AUTOSIZE_USEHEADER}"
где $HWND - HWND элемента


Удаление всех строк в элементе

Для удаления всех в строк в элементе мы будем использовать следующую команду (после инициализации или в режиме реального времени):
SendMessage $HWND ${LVM_DELETEALLITEMS} 0 0
где $HWND - HWND элемента


Добавление строк

Можно сделать 2 способами:
1. Вручную добавить все строки, указав значение параметра ListItems, разделяя пункты вертикальной чертой
ListItems=Строка 1|Строка 2|Строка 3|Строка 4|Строка 5
2. Добавить все строки непосредственно в NSIS скрипте. Данный метод может использоваться после инициализации или в режиме реального времени
Чтобы наши добавляемые пункты добавлялись в конец списка, нам сначала необходимо узнать количество уже существующих пунктов в элементе, делается это командой:
SendMessage $HWND ${LVM_GETITEMCOUNT} "" "" $1
где $HWND - HWND элемента
результат в $1 - количество существующих строк, отчет идет с 0

Затем мы добавляем наш пункт в последнюю позицию:
${NSD_LV_InsertItem} $HWND "$1" "Моя строка"
где $HWND - HWND элемента
где $1 - позиция, начиная с 0, в которую мы вставляем строку, т.к. до этого мы получили количество строк сообщением "LVM_GETITEMCOUNT", мы используем переменную $1 и вставляем нашу строку последней в список
Обратите внимание, что мы можем вставить строку в любую позицию, даже самой первой в уже существующем списке


Как узнать позицию и текст строки, которая выделена?

Примечание. Для использования флага вы должны сделать элемент взаимодействующим.
Данная возможность будет работать только при некоторых условиях:
Если вы пропишите соответствующую команду на событие при выделении строки пользователем. Вам необходимо выделить отдельную переменную для хранения информации о позиции выбранного пункта при работе кастомной странички.
SendMessage $HWND ${LVM_GETHOTITEM} "" "" $R9
где $HWND - HWND элемента
результат в R9 - позиция выбранного элемента, начиная с 0

Затем, вы уже можете в любом месте функции получать текст выделенной строки данной командой:
${NSD_LV_GetItemText} $HWND $R9 "0" $1
где $HWND - HWND элемента
где R9 - позиция выбранного элемента, начиная с 0
результат в $1 - текст выделенной строки


Изменение имени строки

Для изменения содержимого строки мы будем использовать данную команду:
${NSD_LV_SetItemText} $HWND "3" "0" "Новое имя строки"
где $HWND - HWND элемента
где 3 - позиция строки, начиная с 0, содержимое которой мы изменяем


Удаление строки

Для удаления строки используйте следующую команду:
SendMessage $HWND ${LVM_DELETEITEM} "3" ""
где $HWND - HWND элемента
где 3 - позиция строки, начиная с 0, которую вы удаляете


Отключаем перерисовку элемента при активном добавлении строк

Если вы будете в режиме реального времени заполнять элемент большим количеством строкам, то можете столкнуться с таким эффектом у элемента, как искаженное отображение или вовсе исчезновение элемента, пока ваши строки добавляются.
Этого можно избежать, достаточно дать элементу команду не перерисовывать своё содержимое, пока вы добавляете элементы.
Перед командой добавления строк пропишите команду: 
SendMessage $HWND ${WM_SETREDRAW} "0" ""
где $HWND - HWND элемента
где 0 - запрет элементу перерисовывать своё содержимое

После добавления элементов необходимо выполнить эту же команду, но передать другое значение:
SendMessage $HWND ${WM_SETREDRAW} "1" ""
где $HWND - HWND элемента
где 1 - разрешение элементу перерисовывать своё содержимое


Как "проскроллить" (перемотать) список на определённую позицию?

Опять же, всё легко!
Достаточно выполнить следующую команду:
SendMessage $HWND ${LVM_ENSUREVISIBLE} $0 1
где $HWND - HWND элемента
где $0 - позиция, начиная с 0, на которую мы перематываем элемент
Соответственно, чтобы при активном добавлении строк вам показывалась самая последняя, необходимо после команды добавления строки добавить данную команду с последней позицией добавленной строки



Пример кода

Содержимое INI файла странички Показать »
; Ini file generated by the HM NIS Edit IO designer.
[Settings]
NumFields=6

[Field 1]
Type=ListView
Text=ListView
Left=0
Right=134
Top=0
Bottom=74
ListItems=Строка 1|Строка 2|Строка 3|Строка 4|Строка 5
NOTIFY=ONSELCHANGE
Flags=REPORT_VIEW

[Field 2]
Type=Button
Text=Какой пункт выделен?
Left=138
Right=262
Top=0
Bottom=12
NOTIFY=ONCLICK

[Field 3]
Type=Button
Text=Удалить все строки
Left=138
Right=262
Top=16
Bottom=28
NOTIFY=ONCLICK

[Field 4]
Type=Button
Text=Заполнить строки
Left=138
Right=262
Top=32
Bottom=44
NOTIFY=ONCLICK

[Field 5]
Type=Button
Text=Удалить выделенную
Left=138
Right=262
Top=62
Bottom=74
NOTIFY=ONCLICK

[Field 6]
Type=Text
Left=1
Right=262
Top=78
Bottom=88


NSIS код Показать »
Function MyDialog

  InitPluginsDir
  File /oname=$PLUGINSDIR\Project.ini "Project.ini"

        InstallOptionsEx::initDialog /NOUNLOAD "$PLUGINSDIR\Project.ini"

  Var /global HWND
  Var /global HWND_Text
  ReadINIStr $HWND "$PLUGINSDIR\Project.ini" "Field 1" "HWND"
  ReadINIStr $HWND_Text "$PLUGINSDIR\Project.ini" "Field 6" "HWND"

 ${NSD_AddStyle} $HWND "${LVS_NOCOLUMNHEADER}"
 SendMessage $HWND ${LVM_SETEXTENDEDLISTVIEWSTYLE} "${LVS_EX_FULLROWSELECT}" "${LVS_EX_FULLROWSELECT}"
 SendMessage $HWND ${LVM_SETCOLUMNWIDTH} "0" "${LVSCW_AUTOSIZE_USEHEADER}"

        InstallOptionsEx::show
FunctionEnd


Function MyDialog_Leave
  ReadINIStr $0 "$PLUGINSDIR\Project.ini" "Settings" "State"

  StrCmp $0 0 Button_NEXT_Clicked
  StrCmp $0 1 ListView_SelChange
  StrCmp $0 2 Button_1
  StrCmp $0 3 Button_2
  StrCmp $0 4 Button_3
  StrCmp $0 5 Button_4

  abort ; прекращаем проверку, т.к. взаимодействующих элементов в нашей странички больше нет

ListView_SelChange:
 SendMessage $HWND ${LVM_GETHOTITEM} "" "" $R9
StrCmp $R9 "" +2 +3
StrCmp $R9 "-1" 0 +2
abort

 ${NSD_LV_GetItemText} $HWND $R9 "0" $2
 SendMessage $HWND_Text ${WM_SETTEXT} "" "STR:Выбран пункт с ID: $R9, $2"
abort

Button_1:
 ${NSD_LV_GetItemText} $HWND $R9 "0" $2
 MessageBox MB_OK|MB_ICONINFORMATION "Выбран пункт: $2"
abort

Button_2:
 SendMessage $HWND ${LVM_DELETEALLITEMS} 0 0
 SendMessage $HWND_Text ${WM_SETTEXT} "" "STR:Все строки удалены!"
abort

Button_3:
 SendMessage $HWND ${LVM_DELETEALLITEMS} 0 0
SendMessage $HWND ${LVM_GETITEMCOUNT} "" "" $2
${NSD_LV_InsertItem} $HWND "$2" "Строка №1"
SendMessage $HWND ${LVM_GETITEMCOUNT} "" "" $2
${NSD_LV_InsertItem} $HWND "$2" "Строка №2"
SendMessage $HWND ${LVM_GETITEMCOUNT} "" "" $2
${NSD_LV_InsertItem} $HWND "$2" "Строка №3"
SendMessage $HWND ${LVM_GETITEMCOUNT} "" "" $2
${NSD_LV_InsertItem} $HWND "$2" "Строка №4"
 SendMessage $HWND_Text ${WM_SETTEXT} "" "STR:Строки добавлены!"
abort

Button_4:
 SendMessage $HWND ${LVM_DELETEITEM} "$R9" ""
 SendMessage $HWND_Text ${WM_SETTEXT} "" "STR:Строка удалена!"
abort

Button_NEXT_Clicked:
FunctionEnd