ImageList in list control
-
Heiho
Ich hab da mal ne frage, und zwar hab ich hier schon meine List Control klasse wo ich alle moeglichen funktionen gekapselt habe
was ich jetzt suche ist die moeglichkeit die selben icons anzeigen zu lassen wie in windows
also ich lese einen ordner aus und lasse alle gefundenen dateien anzeigen
diese sollen alle nu auch die selben icons bekommen wie im explorerwie kann ich das bewerkstelligen?
-
Dies ist abhängig von der Extension. Die Funktion SHGetFileInfo mit SHGFI_ICON liefert Dir das Icon. Einfach mit Add an eine ImamgeList anhängen und das wars.
Aber Achtung bitte darauf achten, dass die Icons auch wieder freigegeben werden müssen!
SHGFI_SYSICONINDEX kann man evtl. auch verwenden!
-
irgendwas mach ich falsch- ich hab keine ahnung wie ich ueberhaupt irgendein icon anzeigen lassen kann
. . . LVITEM item; item.mask = LVIF_COLUMNS|LVIF_TEXT|LVIF_IMAGE; item.iSubItem = 0; item.cColumns = 0; item.iItem = uiPos; item.pszText = str; SHFILEINFO shfi; HIMAGELIST hSysImgList; hSysImgList = (HIMAGELIST)SHGetFileInfo(_T("C:\\FilterLog.log"), 0, &shfi, sizeof(SHFILEINFO), SHGFI_SYSICONINDEX); item.iImage = shfi.iIcon; . . .
//ist zusammen gegooglet
ich bekomm zwar in shfi.iIcon den richtigen icon index, aber das aendert nichts
so ist die list erstellt:
m_Handle = ::CreateWindow(WC_LISTVIEW, _T(""), WS_CHILD|WS_VISIBLE|WS_BORDER|LVS_REPORT|LVS_EDITLABELS, ...); ::SendMessage(m_Handle, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_GRIDLINES|LVS_EX_FULLROWSELECT|LVS_SMALLICON);
-
habs hinbekommen
LVITEM item; item.mask = LVIF_COLUMNS|LVIF_TEXT|LVIF_IMAGE; item.iSubItem = 0; item.cColumns = 0; item.iItem = uiPos; item.pszText = str; SHFILEINFO shfi; HIMAGELIST hSysImgList; hSysImgList = ImageList_Create(16, 16, ILC_MASK, 1, 0); //file for testing SHGetFileInfo(_T("C:\\FilterLog.log"), 0, &shfi, sizeof(SHFILEINFO), SHGFI_ICON); int erg = ImageList_AddIcon(hSysImgList, shfi.hIcon); ::SendMessage(m_Handle, LVM_SETIMAGELIST, LVSIL_SMALL, reinterpret_cast<LPARAM>(static_cast<HIMAGELIST>(hSysImgList))); item.iImage = 0;
-
hmm
doch nicht so recht, ich hab sobald ich es teste alle items mit den selben icon /=
-
Du musst natürlich die Icons sammeln. Dann bekommst Du für jedes Icon das Du in die Imagelist einsetzt eine ID. Diese ID musst Du bei dem List Item wieder angeben. Wenn Du immer Imagelist Index 0 angibst bekomst Du immer nur das erste Icon!
-
auf den trichter des sammelns bin ich auch schon gekommen, ich habe
HIMAGELIST hSysImgList;
jetzt in der klasse damit die immer gueltig ist
dann beim adden eines elements mach ich immer
SHFILEINFO shfi; hSysImgList = ImageList_Create(16, 16, ILC_MASK, 200, 200); _tstring path = strPath; path += strName; SHGetFileInfo(path.c_str(), 0, &shfi, sizeof(SHFILEINFO), SHGFI_ICON); ImageList_AddIcon(hSysImgList, shfi.hIcon); ::SendMessage(m_Handle, LVM_SETIMAGELIST, LVSIL_SMALL, reinterpret_cast<LPARAM>(static_cast<HIMAGELIST>(hSysImgList))); item.iImage = shfi.iIcon; // hier probier ich rum
ich dacht shfi.iIcon waere die ID - aber ich bekomm nu nie icons angezeigt
was mach ich falsch - google hilft mir kein stueck - such schon stundenlang
-
ImageList_AddIcon returninert einen Index!
Diese gibt den Index des Bildes an. So schwer ist das mit den Imagelists doch wirklich nicht. Wie hast Du den vorher ImageLists verwendet?
-
vorher ? noch nie - ist das erste mal das ich damit in beruehrung komm #gg
habs geschafft - das eine mit den add icon war noch der stolperstein
was habe ich nu:
Klasse
HIMAGELIST hSysImgList;
Konstruktor
hSysImgList = ImageList_Create(16, 16, ILC_MASK, 200, 200);
Nach dem Create
::SendMessage(m_Handle, LVM_SETIMAGELIST, LVSIL_SMALL, reinterpret_cast<LPARAM>(static_cast<HIMAGELIST>(hSysImgList)));
beim adden
SHFILEINFO shfi; _tstring path = strPath+strName; SHGetFileInfo(path.c_str(), 0, &shfi, sizeof(SHFILEINFO), SHGFI_ICON); int id = ImageList_AddIcon(hSysImgList, shfi.hIcon); item.iImage = id;
eine kleine frage noch
bei
"hSysImgList = ImageList_Create(16, 16, ILC_MASK, 200, 200);"
hab ich beides als 200 angegeben - gibt es da ein richtwert - wieviel sinnvoll/notwndig ist ?vielen dank {=
-
1. Du solltest Dir ein internen mao aufbauen, sodaß Du extensions nur einmal lädst. Dann wird die Imagelist nicht endlos groß
2. Wie groß Du die Imagelist machst hängt davon ab was Du reinpacken willst. Sind die Werte zu klein muss zu oft reallokiert werden. Sind die Werte zu groß verschwendest Du immens Speicher.
-
ist mir gestern auch noch in den sinn gekommen das ich irgendwie duplicates loeschenlassen sollte - muss ich erstmal schauen wie das funktioniert, da ich wie gesagt das erste mal damit in beruehung komm
im speicher landen nur die small icons
was ich mich grad aber frag, ich habe ja den wert fest eingegeben - du sagtest "muss zu oft reallokiert werden"
macht die imagelist das dynamisch ?
-
Du musst nichts doppeltes löschen, Du musst nur nachsehen ob Du das Icon schon hast für die entsprechende Dateiendung!
Ja Imagelist vergrößert sich selbst den Speicherbereich. Lies doch die Doku, die entsprechenden zwei letzten Parameter geben das doch an.
nInitial
Number of images that the image list initially contains.
nGrow
Number of images by which the image list can grow when the system needs to resize the list to make room for new images. This parameter represents the number of new images the resized image list can contain.
-
Martin Richter schrieb:
Du musst nichts doppeltes löschen, Du musst nur nachsehen ob Du das Icon schon hast für die entsprechende Dateiendung!
da bin ich bisher am rumprobieren, ich pack das nicht
mein problem ist - wie finde ich ein icon in der imagelist
also ich hole das icon der datei
int GetIconID(_tstring strFile){ SHFILEINFO shfi; SHGetFileInfo(strFile.c_str(), 0, &shfi, sizeof(SHFILEINFO), SHGFI_ICON); return ImageList_AddIcon(hSysImgList, shfi.hIcon); }
dann adde ich das und returniere den index
aber ich brauch noch sowas (pseudocode)
int GetIconID(_tstring strFile){ SHFILEINFO shfi; SHGetFileInfo(strFile.c_str(), 0, &shfi, sizeof(SHFILEINFO), SHGFI_ICON); //---------------- Begin Pseudo int pos = ImageList_FindIcon(shfi.hIcon); if(pos >= 0) return pos; else return ImageList_AddIcon(hSysImgList, shfi.hIcon); }
dazuedit:
das hab ich eben gebastelt:int CListsControl::GetIconID(_tstring strFile){ SHFILEINFO shfi; SHGetFileInfo(strFile.c_str(), 0, &shfi, sizeof(SHFILEINFO), SHGFI_ICON); //return ImageList_AddIcon(hSysImgList, shfi.hIcon); for(int i=0; i<ImageList_GetImageCount(hSysImgList); ++i){ HICON icon = ImageList_GetIcon(hSysImgList, i, ILD_MASK); if(icon == shfi.hIcon) return i; } return ImageList_AddIcon(hSysImgList, shfi.hIcon); }
ist das richtig ? ich kann ganz schlecht ueberprüfen obs funktioniert
-
funktioniert anscheinend doch nicht /=
das problem ist das ich die HICONs nicht vergleichen kann
und wenn ich es probeweise adde und dann vergleiche aendert das auch nichtsalso lautet die frage - woher weiss ich ob ich das icon image bereits abgespeichert habe oder nicht
muss ich nebenher eine map laufen lassen wo ich ext-string + id separat abspeicher?
-
Habe ich das nicht geschrieben?
Doch!Du solltest genau das tun! Eine map führen in der Du Extension und den vergebenen Index abspeicherst. PathFindExtension hilft Dir dabei. Achte darauf das die map Groß- und Kleinschreibung nicht unterscheidet.
1. HICONS lassen sich nicht vergleichen, weil eben immer neue angelegt werden!
2. Und wo entsorgst Du bitte das Icon, dass Du durch SHGetFileInfo bekommen hast? Bitte Doku lesen!
3. Auf SHGFI_SYSICONINDEX habe ich Dich auch schon hingewiesen!
-
Martin Richter schrieb:
Du solltest genau das tun! Eine map führen in der Du Extension und den vergebenen Index abspeicherst.
das hab ich soeben erfolgreich implementiert
Martin Richter schrieb:
2. Und wo entsorgst Du bitte das Icon, dass Du durch SHGetFileInfo bekommen hast? Bitte Doku lesen!
stimmt, das hatte ich bisher vergessen, find das nur merkwuerdig da ich das icon nur in der SHFILEINFO struktur habe..
SHFILEINFO shfi; SHGetFileInfo(strFile.c_str(), 0, &shfi, sizeof(SHFILEINFO), SHGFI_ICON); . . DestroyIcon(shfi.hIcon);
Martin Richter schrieb:
3. Auf SHGFI_SYSICONINDEX habe ich Dich auch schon hingewiesen!
damit hab ich bisher gar nichts hinbekommen - wuesste nicht wie ich das anwende, habs ja mitlerweile ohne damit funktionstuechtig implementiert
-
Selbst wenn das hIcon nur in der Struktur ist, muss es ja jemand freigeben. Es wurde ja für Dich erzeugt!
-
klingt logisch #gg
wie gesagt, ich hab DestroyIcon bereits gemacht