API и FreeBasic. (дочерние окна-TreeView)
При упорядочивании какой-либо информации часто требуется создать древовидную структуру. Примеры древовидной структуры можно встретить практически везде. Самый наверно простой пример - это проводник Windows (колонка слева), в которой в порядке иерархии размещены папки. Создать подобную колонку нетрудно с помощью контрола TreeView.
Для создания контрола TreeView нужно:
- Создать дочернее окно на базе имеющегося контрола SysTreeView32
- Создать структурную переменную TVINSERTSTRUCT
- Заполнить поля структуры для каждого добавляемого пункта контрола
- Отправить контролу сообщение TVM_INSERTITEM и в параметре LPARAM передать указатель на заполненную структуру TVINSERTSTRUCT (в нашем случае мы используем макрос TreeView_InsertItem)
Необязательно , но практически всегда к контролу подключают список изображений с иконками или изображениями. В нашем примере ниже так и сделано.
Структура TVINSERTSTRUCT выглядит так:
Type TVINSERTSTRUCTA hParent As HTREEITEM hInsertAfter As HTREEITEM Union itemex As TVITEMEX item As TVITEM End Union End Type
- hParent - идентификатор родительского пункта, если есть или TVI_ROOT
- hInsertAfter - идентификатор пункта, после которого будет выполнена вставка
- itemex - информация о вставляемом пункте (расширенная структура TVITEM)
- item - информация о вставляемом пункте (структура TVITEM)
Вложенная структура TVITEM выглядит так:
Type TVITEM mask As UINT hItem As HTREEITEM state As UINT stateMask As UINT pszText As LPSTR cchTextMax As Integer iImage As Integer iSelectedImage As Integer cChildren As Integer lParam As LPARAM End Type
- mask - маска использования нужных полей структуры
- TVIF_TEXT - поле pszText
- TVIF_IMAGE - поле iImage
- TVIF_SELECTEDIMAGE - поле iSelectedImage
- TVIF_PARAM - поле lParam
- TVIF_CHILDREN - поле cChildren
- TVIF_HANDLE - поле hItem
- TVIF_STATE - поле state
- hItem - определяет элемент, к которому относится эта структура
- state - текущее состояние элемента
- stateMask - маска состояния элемента
- pszText - указатель на буфер строки для пункта
- cchTextMax - размер строкового буфера
- iImage - индекс в списке изображений невыбранного пункта
- iSelectedImage - индекс в списке изображений выбранного пункта
- cChildren - флаг дочерних элементов
- lParam - дополнительное 32-битное значение, связанное с элементом
Собственно из вышеописанного должно быть понятно, что для использования в контроле строк , необходимо указать маску TVIF_TEXT. Так же обязательно при использовании строк указать буфер с нужной строкой и размер этого буфера. Если понадобится использовать изображения\иконки , то нужно определить дополнительно маски TVIF_IMAGE , TVIF_SELECTEDIMAGE. А в полях структуры iImage и iSelectedImage передать индексы списка изображений , который перед этим нужно создать и заполнить (про списки изображений рассказывалось в этой статье). И конечно в любом случае нужно определить место каждого пункта в иерархии. Для этого нужно правильно определить пункты структуры TVINSERTSTRUCT hInsertAfter и hParent
Обработка сообщений контрола ведется как и у всех контролов в процедуре родительского окна. При получении сообщения WM_NOTIFY как и в случае с LISTVIEW в параметре LPARAM оказывается указатель на структуру NMHDR . Далее проверяется код извещения и вынимаются нужные данные из структур либо заполняются и отправляются соответствующие сообщения. Кол-во извещений, сообщений довольно значительно и для разных задач. Некоторые из них (остальные можете посмотреть ЗДЕСЬ.):
Извещения:
- TVN_SELCHANGED - Уведомляет родительское окно TreeView, что выбор изменился от одного пункта к другому.
- TVN_BEGINDRAG - Начало операции переноса "drag and drop" для левой кнопки мыши
- TVN_BEGINLABELEDIT - Начало операции редактирования названия элемента
- TVN_BEGINRDRAG - Начало операции переноса "drag and drop" для правой кнопки мыши
- TVN_DELETEITEM - Удаление определенного элемента дерева
- TVN_ENDLABELEDIT - Завершение операции редактирования названия элемента
- TVN_GETDISPINFO - Контрол запрашивает информацию, необходимую для отображения элемента
- TVN_KEYDOWN - Была нажата клавиша
Сообщения:
- TVM_GETTEXTCOLOR - Получение цвета текста котрола
- TVM_CREATEDRAGIMAGE - Создание изображения, необходимого для выполнения операции перемещения "drag and drop"
- TVM_GETTOOLTIPS - Получение хендла tooltip, определенного для treeview
- TVM_DELETEITEM - Удаление элемента из дерева
- TVM_EDITLABEL - Начать процесс редактирования имени элемента
- TVM_GETCOUNT - Получение количества элементов в дереве
- TVM_GETEDITCONTROL - Получение хендла редактора, который используется для редактирования названия элемента
- TVM_SETTOOLTIPS - Установка tooltip для treeview
- TVM_GETIMAGELIST - Получение хендла списка изображения
- TVM_GETINDENT - Определение размера сдвига вложенных элементов(в пикселах)
- TVM_GETISEARCHSTRING - Получение инкрементальной строки поиска
- TVM_GETITEM - Получение всех или некоторых атрибутов элемента дерева
- TVM_GETITEMRECT - Определение границ, занимаемых элементом в окне просмотра.
- TVM_GETVISIBLECOUNT - Определение количества видимых элементов в контроле
- TVM_HITTEST - Определение элемента, расположенного в данной позиции
- TVM_INSERTITEM - Вставка элемента
- TVM_SETTEXTCOLOR - Установка цвета текста для контрола
- TVM_SELECTITEM - Выделение заданного элемента
- TVM_SETIMAGELIST - Подключение списка изображений к контролу
- TVM_SETINDENT - Установка размера сдвига вложенных элементов(в пикселах)
- TVM_SETITEM - Установка всех или некоторых атрибутов заданного элемента дерева
- TVM_SORTCHILDREN - Сортировка вложенных элементов для заданного элемента дерева
И конечно пример:
#INCLUDE "windows.bi" #INCLUDE "win/commctrl.bi" #INCLUDE "win/shellapi.bi" Dim msg As MSG Dim As WNDCLASSEX wc Dim As String NameClass="MyClass" Dim As HINSTANCE Hinst=GetModuleHandle(0) Dim Shared As ZString*15 szArray(6) = {_ "First_Root",_ "One",_ "Two",_ "Three",_ "Four",_ "Five",_ "Second_Root" _ } Function wndproc(hwnd As HWND, msg As Uinteger,_ wparam As WPARAM, lparam As LPARAM) As Integer Static As HWND hTree Select Case msg Case WM_CREATE ' создаем контрол hTree = CreateWindowEx( 0, "SysTreeView32", 0,_ WS_CHILD+WS_VISIBLE+TVS_HASBUTTONS+_ TVS_LINESATROOT+WS_BORDER+TVS_HASLINES,_ 10, 10, 200, 200, hwnd, Cast(HMENU,1), 0, 0) ' узнаем путь к системной папке Dim szPath As String*512 GetSystemDirectory(Cast(LPSTR,@szPath),Len(szPath)) ' извлекаем иконки из DLL файла Dim As HICON icon1,icon2 icon1 = ExtractIcon(0,szPath & "\Shell32.DLL",3) icon2 = ExtractIcon(0,szPath & "\Shell32.DLL",45) ' создаем список изображений Dim As HIMAGELIST ImageList = ImageList_Create(_ 16,16,ILC_COLOR32 Or ILC_MASK,1,1) ' делаем цвет фона иконок в списке прозрачным ImageList_SetBkColor(ImageList,_ TreeView_GetBkColor(hTree) Xor &hff000000) ' добавляем иконки в список изображений Dim As Integer iNoSelect = ImageList_AddIcon(ImageList,icon1) Dim As Integer iSelect = ImageList_AddIcon(ImageList,icon2) ' подключаем список изображений к контролу TreeView SendMessage(hTree,TVM_SETIMAGELIST,TVSIL_NORMAL,Cast(LPARAM,ImageList)) '------------------заполняем контрол пунктами----------------- Dim tvis As TVINSERTSTRUCT Dim htr(11) As HTREEITEM ' Создаем корневые пункты For i As Integer = 0 To 1 tvis.Item.Mask = TVIF_TEXT+TVIF_IMAGE+TVIF_SELECTEDIMAGE tvis.item.pszText = Strptr(szArray(i*6)) tvis.item.cchTextMax = Len(szArray(i*6)) tvis.hParent = Cast(HTREEITEM,TVI_ROOT) htr(i) = TreeView_InsertItem(hTree, @tvis ) 'Создаем подпункты For j As Integer = 1 To 5 tvis.Item.Mask = TVIF_TEXT+TVIF_IMAGE+TVIF_SELECTEDIMAGE tvis.item.pszText = Strptr(szArray(j)) tvis.item.cchTextMax = Len(szArray(j)) tvis.item.iImage = iNoSelect tvis.item.iSelectedImage = iSelect tvis.hInsertAfter = Cast(HTREEITEM,j) tvis.hParent = Cast(HTREEITEM,htr(i)) htr(j+i*5+1) = TreeView_InsertItem(hTree, @tvis ) Next Next Case WM_NOTIFY ' получаем текст из пункта TreeView Dim As NMHDR Ptr nmhdr = Cast(NMHDR Ptr,lParam) If nmhdr->code = TVN_SELCHANGED Then Dim As NMTREEVIEW Ptr NMTW = Cast(NMTREEVIEW Ptr,LPARAM) Dim TV_ITEM As TVITEM Dim As String*256 szBuf TV_ITEM.pszText = Cast(LPSTR,@szBuf) TV_ITEM.cchTextMax = 20 TV_ITEM.mask = TVIF_TEXT TV_ITEM.hItem = NMTW->itemNew.hItem SendMessage(hTree,TVM_GETITEM,0,Cast(LPARAM,@TV_ITEM)) MessageBox(0,szBuf,"",0) Endif Case WM_DESTROY PostQuitMessage(0) End Select Return DefWindowProc(hwnd,msg,wparam,lparam) End Function With wc .cbSize=SizeOf(WNDCLASSEX) .style=CS_HREDRAW Or CS_VREDRAW .lpfnWndProc=@wndproc .hInstance=Hinst .hIcon=LoadIcon(0,IDI_WINLOGO) .hCursor=LoadCursor(0,IDC_ARROW) .hbrBackground=Cast(HBRUSH,COLOR_WINDOWFRAME) .lpszClassName=StrPtr(NameClass) .hIconSm=.hIcon End With If RegisterClassEx(@wc)=0 Then Print "Register error, press any key" Sleep End Endif CreateWindowEx(0,NameClass,"TreeView",_ WS_VISIBLE Or WS_OVERLAPPEDWINDOW,100,100,235,255,0,0,Hinst,0) While GetMessage(@msg,0,0,0) TranslateMessage(@msg) DispatchMessage(@msg) Wend
содержание | назад | вперед