Treeview SelectItem
-
heiho
kann mir jemand verraten wie ich ein bestimmtes item in einer treeview selectieren kann ohne das eins manuell selectiert wurde ?
"TVM_SELECTITEM"die item struktur ist unbekannt
braeuchte auch ne idee wie ich die items benennen kann, meine erste idee war "RootItem X - SubItem X" usw
danke
-
ich arbeite bisher so das ich items nacheinander in nem vector schieb und dann kann ich anhand der position selectieren und machen/tun
|-0 |-1 |-2 |-3 |-4 |-5 |-6 |-7 |-8 |-9usw
ne bessere loesung will mir nicht einfallen - das bloede ist allerdings das der vector recht gross werden kann
-
Ich verstehe jetzt nicht ganz was Du meinst.
TVM_SELECTITEM ruft man einfach auf und übergibt die gewünschten Flgas un das entsprechende Item.
Warum hast Du diesen Array?
Verwende doch das lparam Feld in TVITEM. Damit stellt man den Bezug zwischen Daten und Tree-Item her!
-
ich versteh nicht, "TVITEM" ist doch immer unbekannt, ich hab das hinzufuegen von items usw alles in funktionen gekapselt
eine funktion um items hinzu zu fuegen usw
ich hab spaeter dann nirgends informationen zu den items"TVM_SELECTITEM ruft man einfach auf und übergibt die gewünschten Flgas un das entsprechende Item."
ich kann kein item uebergeben wenn ich zu der laufzeit kein item zu auswahl habebin grad am ueberlegen wie ich text eines items aendern kann
-
Wieso hast Du kein Item. Du bekommst doch mit dem Einfügen ein HTREEITEM!
Nun verstehe ich gar nichts mehr. Wen Du Daten in den Baum einfügst. Woher weisst Du denn weclhes Item sich auf welche Daten bezieht?
Das macht man doch eben über den lparam des TVITEM's.
Ich verstehe gerade nichts mehr! Versuche noch mal Dein problem in anderen Worten zu schildern...
-
jo ich versuchs mal #gg
also, ich hab hier alles in einzelnen funktionen, und das sollte schon so bleiben
ich habe diese funktion in meiner TreeView klasse:
BOOL AddItem(std::wstring ItemName, std::wstring ParentItem);sodass ich immer nur so machen brauch
m_TreeView.AddItem(_T("First"), TVI_ROOT); m_TreeView.AddItem(_T("Second"), TVI_ROOT); m_TreeView.AddItem(_T("FirstSub"), _T("First"));das "Problem" ist, es ist immer unbekannt was hinzugefuegt wird, und wieviel - und das HTREEITEM wird auch nicht uebergeben, ich hab m_TreeView als eigene klasse und das soll es intern verwalten
dh ich brauch eine dynamische liste von "HTREEITEM"
und das problem ist, ich muss irgendwie vergleichen koennen damit ich das parent richtig setzen kann
aber aus HTREEITEM bekomm ich kein string zum vergleich /=
-
ich glaub ich hab was, ich speichere einfach einen std::vector string liste wo nur die namen enthalten sind, dann kann ich damit vergleichen bis ich die positionen hab {=
class CTreeview{ private: std::vector<HTREEITEM>m_Items; std::vector<DString>m_ItemsText; public: AddElement(std::wstring Name, std::wstringParent) }: BOOL CTreeview::AddElement(std::wstringName, std::wstringParent){ TV_ITEM item; item.mask = TVIF_TEXT; item.pszText = (LPTSTR)Name.c_str(); TV_INSERTSTRUCT inserter; inserter.item = item; if(!m_Items.empty()){ for(UINT i=0; i<m_ItemsText.size(); ++i){ if(m_ItemsText[i] == Parent){ inserter.hParent = m_Items[i]; break; } else inserter.hParent = TVI_ROOT; } } else inserter.hParent = TVI_ROOT; inserter.hInsertAfter = TVI_SORT; m_Items.push_back(((HTREEITEM)::SendMessage(m_Handle, TVM_INSERTITEM, NULL, (LPARAM)(LPTVINSERTSTRUCT)&inserter))); m_ItemsText.push_back(Name); return TRUE; }//returniert bisher nur true, muss noch ueberlegen wie ich das loes
-
1. Bau doch nur eine Liste mit einem entsprechenden paar HTREEITEM, DString. Dann musst Du nicht zwei vectoren verwalten.
2. Warum hast Du überhaupt diesen vector?Ich arbeite immer nur mit der GUI. D.h. wenn jetzt was zu suchen ist durchlaufe ich den TreeView. Die daten sind doch redundant.
-
> 1. Bau doch nur eine Liste mit einem entsprechenden paar HTREEITEM, DString. Dann musst Du nicht zwei vectoren verwalten.
und wie soll ich dann an die namen kommen ?> 2. Warum hast Du überhaupt diesen vector?
a. ich kann alle items durchlaufen und ggf. vergleichen
b. ich hab direkten zugriff auf die namen der items> Ich arbeite immer nur mit der GUI. D.h. wenn jetzt was zu suchen ist durchlaufe ich den TreeView. Die daten sind doch redundant.
die gesammte liste durchlaufen ? mit allen subitems und items ?zb. ich sage "SelectItem(std::wstring StringName)"
das selektiert dann das item mit diesen angegebenen namen
wenn ich die GUI liste durchlaufen will muss ich ja zuerst erstes item holen, dann irgendwie den namen auslesen, dann vergleichen und wenn nichts ist das naechste item,
so brauch ich nur meinen zweiten vector nach dem namen durchsuchen, und hab dann die position wo ich dann in der ersten vectorliste sagen kann welche selektiert werden kannich hab bisher diese funktionen erfolgreich implementiert:
private: std::vector<HTREEITEM>m_Items; std::vector<DString>m_ItemsText; UINT GetItemNumber(std::wstring Name); std::wstring GetItemText(HTREEITEM Item); public: BOOL AddElement(std::wstring Name, std::wstring Parent = _T("")); BOOL SelectItem(std::wstring Name); void Deselect(); void Clear(); void Expand(std::wstring Name = _T("")); UINT GetSelectedItemNumber(); BOOL DeleteItem(std::wstring Item); BOOL DeleteSelectedItem(); std::wstring GetSelectedItemText(); std::wstring GetParentItem(std::wstring Child); std::vector<DString> GetChildItems(std::wstring Parent); std::vector<DString> GetRootItems(); BOOL SetSelectedItemText(std::wstring Text); BOOL SetItemText(std::wstring OldName, std::wstring NewName);also komplette steuerung der items nur anhand der namen {o; und darum gings mir (wenn ein string default auf _T("") steht bedeutet das root)
-
Ich habe mich auch mal intensiver mit dem TreeView beschäftigt und diese Frage bezüglich der Position usw. auch gefragt. Ich weis nicht ob ich deins direkt Verstanden habe. Aber ich finde die Lösung (so wie ich sie Verstanden habe) mit den Namen nicht so gut. Das ist doch nicht eindeutig! Oder? Was ist wenn du 2 mal den selben Namen hast?
Da ich bei meinem TreeView genau wusste wie viele SubItems ein Parent haben konnte hab ich mir ne struct alastruct TreeViewPos { int Parent; int FirstChild; int SecondChild; int ThirdChild; int FourthChild; };Naja war auch nicht die beste Lösung aber damals hat es gefunzt

> 1. Bau doch nur eine Liste mit einem entsprechenden paar HTREEITEM, DString. Dann musst Du nicht zwei vectoren verwalten.
und wie soll ich dann an die namen kommen ?Wenn du ein HTREEITEM hast kannst du doch ganz einfach den Namen herausbekommen

MfG schirrmie
-
Mr Evil schrieb:
> 1. Bau doch nur eine Liste mit einem entsprechenden paar HTREEITEM, DString. Dann musst Du nicht zwei vectoren verwalten.
und wie soll ich dann an die namen kommen ?Ich verstehe die Frage nicht. Ob Du nun 2 Arrays hast oder einen Array mit einer struct oder einem pair, Du kommst genau gleich an den Namen!
Nr Evil schrieb:
> 2. Warum hast Du überhaupt diesen vector?
a. ich kann alle items durchlaufen und ggf. vergleichen
b. ich hab direkten zugriff auf die namen der itemsUnd warum brauchst Du das? Entweder hat der Tree die Kontrolle oder nicht. Alles andere ist überflüssiger Verwaltungsaufwand.
Ich Speichere meine Daten im Baum unter einem Text. Einen entsprechenden Zeiger auf weitere Daten oder eine ID kommen in das lparam Feld des Tree-Items.Wenn ich einen Konten in meinem Baum Suche, dann traversiere ich den Baum.
Nr Evil schrieb:
zb. ich sage "SelectItem(std::wstring StringName)"
das selektiert dann das item mit diesen angegebenen namen
wenn ich die GUI liste durchlaufen will muss ich ja zuerst erstes item holen, dann irgendwie den namen auslesen, dann vergleichen und wenn nichts ist das naechste item,
so brauch ich nur meinen zweiten vector nach dem namen durchsuchen, und hab dann die position wo ich dann in der ersten vectorliste sagen kann welche selektiert werden kannDafür hast Du doppelte Datenhaltung. Wenn Du jetzt mit einem Drag&Drop anfängst, oder mit Sortieren der Unterknoten oder sonstigen netten Spielereien kannst Du Dir den vector schenken.
Als Grundsatz habe ich mir angewöhnt:
1. Daten gibt es nur an einer Stelle.
2. Alles was die Daten representiert hat einen Verweis auf diese Daten.
3. Eine 1:1 Verknüpfung von GUI (sprich Darstellung) zur Datenhaltung ist möglichst zu vermeiden, da dies nur Probleme mit Sortieren Drag&Drop etc bringt.Just my 2 cents!
-
und wie soll ich aus nem HTREEITEM den namen bekommen ?
ich hab google abgestoebert, auch die MSDN rauf und runter - nirgends find ich informationen wie ich den namen eines items aus TREEITEM auslesen kann - das ist ja die ganze zeit schon die problematik
-
Na wenns weiter nix ist

Mit nem HTREEITEM kannst du an sich alles machen wie mit nem HITEM.void TreeView::GetItem(HTREEITEM htitem, TVITEM *tvi) { char Buffer[2001] = ""; //Hole den Namen des TreeviewItem's tvi->mask = TVIF_HANDLE | TVIF_TEXT; tvi->hItem = htitem; tvi->pszText = Buffer; tvi->cchTextMax = 2000; TreeView_GetItem(Hwnd, tvi); } char * TreeView::GetItemText(HTREEITEM htitem) { TVITEM Tvi; char Buffer[5000] = ""; GetItem(htitem, &Tvi); Tvi.mask = TVIF_TEXT; Tvi.pszText = Buffer; TreeView_GetItem(Hwnd, &Tvi); return Buffer; }MfG schirrmie
-
vor ein paar minuten hatte ichs endlich hinbekommen
std::wstring CTreeview::GetItemText(HTREEITEM Item){
TVITEM item;
item.hItem = Item;
item.mask = TVIF_TEXT;
std::wstring str;
item.pszText = (LPTSTR)str.c_str();
item.cchTextMax = (int)str.capacity();
::SendMessage(m_Handle, TVM_GETITEM, NULL, (LPARAM)&item);
return str.c_str();
}ps. mit macros arbeite ich nicht, makros doof und boese #gg
bin grad dabei meine methoden neu zu implementieren - also alles neu aufzubauen ohne die listen - nicht so einfach den gesammten baum zu durchsuchen - und wie ich doppelte namen handel weiss ich noch nicht {wenn ich sag add item und den string das parent angeb, das ich weiss zu welchem item es added werden soll}
-
Ist das mit den Makros auf mein Code bezogen? Da sind keine Makros drinne.
Ja das mein ich ja mit den Namen das ist ne schlechte Implementierung weil du nix eindeutiges hast. Mach es wie einer meiner Vorredner gesagt hat und nimm das LPARAM vom ITEM da kannst ja soviele Informationen reinpacken wie du willst.MfG schirrmie
-
Doch TreeView_GetItem ist ein Makro!
Allerdings kann ich diese Meinung nicht teilen. Diese Art Makros helfen immens beim korrekten Umgang mit den entsprechenden Fensterklassen!
-
Achso stimmt ja daran hab ich garnicht gedacht. Naja ob da nun nen SendMessage oder nen Makro steht ist mir Relativ. Ich find die Makros nur übersichtlicher beim lesen. Beim Überfliegen erkennt man halt sofort was gemacht wird was bei SendMessage meist nicht sooo schnell der Fall ist aber naja das ist geschmackssache.
MfG schirrmie
-
Martin Richter schrieb:
Allerdings kann ich diese Meinung nicht teilen. Diese Art Makros helfen immens beim korrekten Umgang mit den entsprechenden Fensterklassen!
das ist bei mir ein vorurteil wo ich keine lust habe das abzulegen - hast schon recht aber egal #gg
das mit den namen - mein ziel ist ja das man das tree nur mit namen handeln kann, das man spaeter beim benutzen die id oder soetwas nicht kennen braucht
wie ich "AddItem(std::wstring Name, std::wstring Parent)" implementiere sobald ein name mehrmals auftaucht weiss ich noch nicht, denk da schon den ganzen tag drueber nach
-
Mr Evil schrieb:
ps. mit macros arbeite ich nicht, makros doof und boese #gg
Kann ich unterstützen, ABER wenn Du schon keine Makros nutzt (wie das in C++ ja üblich ist), dann nimm doch auch C++ Casts und keine C - Casts
.
-
ja ich weiss, bloede angewohnheit - komme wie so viele aus der c schiene und bin da vorbelastet
bei den casts
reinterpret_cast<>()
dynamic_cast<>()
static_cast<>()und welche es noch gibt {?} blick ich zZt nicht ganz durch welches wann am besten zu gebrauchen ist
-
Ich denke ohne eine Entsprechende Id oder so wirst du nicht weit kommen oder du legst fest das ein Name nur einmal vorkommen darf aber ka was du vor hast und es so gehen kann?
Versteh aber nicht ganz dein Problem mit den Namen. Wenn ein User in nem TreeView später was selektiert oder so da brauchst du doch keine Namen oder so dann hast doch das Item also ich versteh dein Problem nicht wirklich. Was hast du denn mit dem TreeView vor das es Nur über Namen ansprechbar sein soll? Also ich hab bis jetzt immer mit der Maus draufgeklickt oder mit der Tastatur navigiert und nich Probleme gehabt
MfG schirrmie