Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Сложно ли напичкать ListView 32-битными картинками? / 10 сообщений из 10, страница 1 из 1
30.04.2010, 03:40
    #36606508
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложно ли напичкать ListView 32-битными картинками?
Сразу скажу, что с аналогичной задачей для Treeview я справился и остался доволен.
Из этого екзампла:
http://btmtz.mvps.org/treeview/
VBDirectoryTV: Make the TreeView into a DirListBox
http://btmtz.mvps.org/treeview/vbdirectorytv.zip
Как то я его уже использовал не думая. Но тогда не осознал.
Вчера сидел плевался, но сегодня осознал и сделал, т.е.
1)Заменил GetSystemImagelist(SHGFI_SMALLICON) на пользовательский
Код: plaintext
1.
2.
3.
    m_himl = ImageList_Create( 16 ,  16 , ILC_MASK Or ILC_COLOR32,  1 ,  1 )
    ImageList_AddMasked m_himl, LoadResPicture("testroot", vbResBitmap), vbBlack
    ImageList_AddMasked m_himl, LoadResPicture("test1", vbResBitmap), vbBlack
    ImageList_AddMasked m_himl, LoadResPicture("test2", vbResBitmap), vbBlack
2)На базе ф-ции
Код: plaintext
1.
2.
3.
4.
Public Function InsertFolder(objTV As TreeView, _
                                            nodParent As Node, _
                                            hitemParent As Long, _
                                            hitemPrevChild As Long, _
                                            sFolder As String) As Long

нарисовал свою
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
Public Function InsertItem(objTV As TreeView, _
                                            nodParent As ComctlLib.Node, _
                                            hitemParent As Long, _
                                            hitemPrevChild As Long, _
                                            hasChildren As Boolean, _
                                            imgNormal As Long, _
                                            imgSelected As Long, _
                                            hitemText As String) As Long
  Dim ulAttrs As Long
  Dim tvi As TVITEM
  Dim nod As ComctlLib.Node
  
  With tvi
    ' Indicate what TVITEM members will contain data
    .mask = TVIF_CHILDREN Or TVIF_IMAGE Or TVIF_SELECTEDIMAGE
    ' If the item has subitems
    .cChildren = Abs(hasChildren)
    .iImage = imgNormal 'GetFileIconIndex(sFolder, SHGFI_SMALLICON)
    .iSelectedImage = imgSelected 'GetFileIconIndex(sFolder, SHGFI_SMALLICON Or SHGFI_OPENICON)
  End With
#If (USEDISPINFO =  0 ) Then
  ' Explicitly set the item's text, overriding the LPSTR_TEXTCALLBACK
  tvi.mask = tvi.mask Or TVIF_TEXT
  tvi.pszText = StrPtr(String$(MAX_PATH,  0 ))
  Call lstrcpyA(ByVal tvi.pszText, ByVal hitemText)
  tvi.cchTextMax = MAX_PATH
  ' Add the Node to the TreeView, without a button, icons, or text (we did everything
  ' above first so that there's the least amount of code between inserting the Node
  ' and setting its attributes below). This must happen, since the TreeView needs a
  ' place-holder for all items in the tree.
  If (nodParent Is Nothing) Then
    Set nod = objTV.Nodes.Add
  Else
    Set nod = objTV.Nodes.Add(nodParent, tvwChild)
  End If
#Else
  ' Set the Node's Text.
  If (nodParent Is Nothing) Then
    Set nod = objTV.Nodes.Add(, , , hitemText)
  Else
    Set nod = objTV.Nodes.Add(nodParent, tvwChild, , hitemText)
  End If
#End If   ' (USEDISPINFO = 0)
  ' Since we may be setting the item's Text, making Node.Text
  ' empty, we'll store the item's Text in the Node's Tag
  nod.Tag = hitemText
  nod.Key = hitemText
  ' ====================================================
  ' Get the new Node's hItem
  If (hitemParent =  0 ) Then
    tvi.hItem = TreeView_GetRoot(objTV.hwnd)
  ElseIf (hitemPrevChild =  0 ) Then
    tvi.hItem = TreeView_GetChild(objTV.hwnd, hitemParent)
  Else
    tvi.hItem = TreeView_GetNextSibling(objTV.hwnd, hitemPrevChild)
  End If
  ' And set the item's button, icons (and text), done deal...
  Call TreeView_SetItem(objTV.hwnd, tvi)
  ' Return the folder's hItem
  InsertItem = tvi.hItem
End Function
убрав всю муть про рекурсивное сканирование folders'
Т.е. получив возможность добавлять Nodes с картинками заданного содержания как мне надо через API
3)сильно упростил сабклассинг (он там явно навернутый, для общего случая много лишнего)
оставив лишь суть:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
   Public Function NewTreeViewWindowProc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    'для событий TreeView1
    ' ============================================================
    ' Prevent the TreeView from removing our system imagelist assignment, which
    ' it wil do when it sees no VB ImageList associated with it.
    ' (the TreeView can't be subclassed when we're assigning imagelists...)
    If (Msg = TVM_SETIMAGELIST) Then
        Exit Function
    End If
    NewTreeViewWindowProc = CallWindowProc( _
        OldTreeViewWindowProc, hwnd, Msg, wParam, _
        lParam)
End Function

В итоге получилось красиво и просто:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
    'привязываем ImageList к Treeview1
    Call TreeView_SetImageList(TreeView1.hwnd, m_TViml, TVSIL_NORMAL)
    'загрузка событий Treeview1
    OldTreeViewWindowProc = SetWindowLong(TreeView1.hwnd, GWL_WNDPROC, _
        AddressOf NewTreeViewWindowProc)
    'Call SubClass(TreeView1.hwnd, AddressOf TVWndProc)'-используем более простой вариант
    'конструируем дерево
    RemoveRootFolder TreeView1
    hitemRoot = InsertItem(TreeView1, Nothing,  0 ,  0 , True,  0 ,  0 , "TestRoot")
    TreeView1.Nodes("TestRoot").Expanded = True
    TreeView1.Nodes("TestRoot").Selected = True
    hitemTemp = InsertItem(TreeView1, TreeView1.Nodes("TestRoot"), hitemRoot,  0 , False,  1 ,  1 , "Test1")
    hitemTemp = InsertItem(TreeView1, TreeView1.Nodes("TestRoot"), hitemRoot, hitemTemp, False,  2 ,  2 , "Test2")
End Sub

Вопрос собственно в чем...
Насколько тяжело добавить всю эту 32-битность в ListView?
Всякие там итемсы, сабитемсы(про header-ы не спрашиваю, там просто). Потому как с тривью провозился целый день, не считая попыток кот. делал раньше(хоть за бесполезную пока возню с прозрачным тулбаром отыгрался...).
В принципе на том же сайте кажется пример с ListView тоже есть. Автор только почему-то наивно полагает что ListView и Treeview используются исключительно для отображения файловой системы, посему сильно накручивает коды.
...
Рейтинг: 0 / 0
30.04.2010, 12:51
    #36607239
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложно ли напичкать ListView 32-битными картинками?
Дмитрий77Насколько тяжело добавить всю эту 32-битность в ListView?Странный вопрос. Сам же это сделал в п. 1).
...
Рейтинг: 0 / 0
30.04.2010, 13:08
    #36607295
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложно ли напичкать ListView 32-битными картинками?
Antonariy,
вопрос далеко не странный.
пункт 1 просто создает API-ImageList
но для Treeview недостаточно просто его привязать и использовать без API:
грубо говоря я не могу писать
Set thisnode = TreeView1.Nodes.Add(, , "RootText", "RootText", pictureNormal, pictureSelected)
Это во первых, поэтому понадобился нехилый пункт 2

более того мой новоявленный API-лист будет стерт VB-окружением поэтому надо отрабатывать
If (Msg = TVM_SETIMAGELIST) Then
Exit Function
(пункт 3)

Или вы хотите сказать что в случае ListView мы радостно установим API-ImageList через SendMessage и сможем оперировать Items-ами и SubItems-ми (c 32-х битными картинками из API-Image-листа) чисто по правилам VB (т.е. без API) и это прокатит?
...
Рейтинг: 0 / 0
30.04.2010, 14:00
    #36607476
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложно ли напичкать ListView 32-битными картинками?
Все равно вопросы странные :)
Вы уже все знаете, что нужно делать, решите теперь, делать или нет.
Разве что п 2) стоит переделать. Добавлять айтем нужно через объектную модель без картинки, а картинку устанавливать после через апи.
...
Рейтинг: 0 / 0
30.04.2010, 14:56
    #36607635
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложно ли напичкать ListView 32-битными картинками?
Хорошо, вопросы по сути тогда:

AntonariyРазве что п 2) стоит переделать. Добавлять айтем нужно через объектную модель без картинки, а картинку устанавливать после через апи.

Вы имеете ввиду переделать для Treeview?
Я не нашел как это сделать по типу SendMessage(<...hwndNode, TVND_SETIMAGE, imgNum...>)
Как тогда получить hwndNode(Node) и как установить картинку?
По идее для Treeview итак неплохо, ибо ф-ция уже написана и осознана, и ей можно всегда пользоваться.
Но если можно примерчик кода (в 2-3 строчки имею ввиду).

Или намекаете на то, какой метод использовать в п.2 для ListView(Добавлять без картинки, а картинку после через апи)? Потому как эта идея мне больше нравится. Treeview как бы простенькие и статические у меня(то что уже накатал более чем...), а содержание ListView меняется динамически. Но честно с ListView еще не разбирался.
...
Рейтинг: 0 / 0
30.04.2010, 15:18
    #36607696
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложно ли напичкать ListView 32-битными картинками?
Да, именно для листвью, для тривью это сделать сложнее как раз из-за hNode. У листвью индексы.
...
Рейтинг: 0 / 0
05.05.2010, 13:44
    #36612899
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложно ли напичкать ListView 32-битными картинками?
А все же я чего-то недопонимаю. 32-bit это иконка + AlphaChanel (прозрачность?). Т.е. bmp + MaskColor я могу использовать без проблем через ресурсы + API-ImageList, но это 24bit. Т.е. если я тибрю красивую иконку из виндов, то я не могу ее использовать в лоб. Я должен переделать ее в bmp 24bit, при этом требуется некот. дорисовка "теней" цветами, и все равно получается "чуть хуже". Что упустил? Или bmp-24bit это максимум, что я могу выжать из VB? Потому как работа предстоит тупая и кропотливая, и делать ее дважды при недопонимании чего-то неохота.
...
Рейтинг: 0 / 0
05.05.2010, 15:21
    #36613172
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложно ли напичкать ListView 32-битными картинками?
Не, ну по идее API-imagelist поддерживает 32-битнось, вопроса тогда 2:
1) Где держать этот зоопарк? потому что тогда надо
vb-редактор ресурсов иконки 32-бит не понимает
можно их вставлять через VC++6 редактор в res-файл, но vb-редактор их игнорирует... и т.п. и не факт что старый vc++ их не портит при вставке, редактировать точно не умеет
можно еще пытаться править ресурсы иконок после компиляции...
2) Как доставать зверей из этого зоопарка, чтоб шкурка не почернела (да и чтоб вообще их увидеть)

Потому как 24-bit bmp для 16х16 без альфа-канала погоды особо не делают, а гемороя все равно много.
...
Рейтинг: 0 / 0
05.05.2010, 16:06
    #36613310
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложно ли напичкать ListView 32-битными картинками?
Эге, дело сдвинулось с мертвой точки.
Вот так фурычит c нормальными иконками:
Код: plaintext
1.
2.
3.
4.
5.
Dim lngIcon As Long
lngIcon = LoadImage( 0 , "test.ico", IMAGE_ICON,  16 ,  16 , LR_LOADFROMFILE) 'App.hInstance
  m_hIml = ImageList_Create( 16 ,  16 , ILC_MASK Or ILC_COLOR32,  3 ,  0 )
  ImageList_ReplaceIcon m_hIml, - 1 , lngIcon
  ImageList_ReplaceIcon m_hIml, - 1 , lngIcon
  ImageList_ReplaceIcon m_hIml, - 1 , lngIcon
где "test.ico"-норм. иконка с прозрачным фоном и альфа-каналом.
Правда не в VB(черный ободок) а в exe с манифестом, но это устраивает.
Осталось выяснить, как строить зоопарк, и как получать lngIcon
...
Рейтинг: 0 / 0
05.05.2010, 17:05
    #36613450
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложно ли напичкать ListView 32-битными картинками?
Ну...получается но ето работы конечно...и что паршиво надо делать всякий раз
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
Dim lngIcon As Long
lngIcon = LoadImage(App.hInstance, MAKEINTRESOURCE( 1111 ), IMAGE_ICON,  16 ,  16 , LR_DEFAULTCOLOR)  'App.hInstance
  m_hIml = ImageList_Create( 16 ,  16 , ILC_MASK Or ILC_COLOR32,  3 ,  0 )
  ImageList_ReplaceIcon m_hIml, - 1 , lngIcon
  ImageList_ReplaceIcon m_hIml, - 1 , lngIcon
  ImageList_ReplaceIcon m_hIml, - 1 , lngIcon
...
Public Function MAKEINTRESOURCE(ByVal lID As Long) As String
    MAKEINTRESOURCE = "#" & CStr(MAKELONG(lID,  0 ))
End Function

Public Function LOWORD(ByVal dwValue As Long) As Long
    Call CopyMemory(LOWORD, dwValue,  2 )
End Function

Public Function MAKELONG(ByVal wLow As Long, ByVal wHi As Long) As Long
    If (wHi And &H8000&) Then
        MAKELONG = (((wHi And &H7FFF&) *  65536 ) Or (wLow And &HFFFF&)) Or &H80000000
    Else
        MAKELONG = LOWORD(wLow) Or (&H10000 * LOWORD(wHi))
    End If
End Function

Т.е.иконки предварительно надо ложить 256-цветов (рыба)
Но оно при этом в vb-ide не показывается, только в exe будет работать

А после компиляции exe-шника менять их на альфа-32бит аналоги тупо вручную через ICOFx напр.
Тогда будет работать.
При этом надо б иметь хоть какой дублирующий код для IDE чтоб хотяб видеть чего будет.
...
Рейтинг: 0 / 0
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Сложно ли напичкать ListView 32-битными картинками? / 10 сообщений из 10, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]