ERLEDIGT
JA
JA
ANTWORTEN
26
26
ZUGRIFFE
874
874
EMPFEHLEN
-
07.08.08 17:44 #16
- Registriert seit
- Oct 2007
- Beiträge
- 56
Hallo,
bin ein ganzes Stück weiter.
Die Baumsstruktur ist wird mit den richtigen Daten gefüllt.
Mittels
kann ich den Inhalt des doppelgeklickten Treeeintrags auslesen und dann weiterverarbeiten. Nun wäre es aber vorteilhafter, wenn ich irgendwie die Position bekommen würde.Code :1 2 3 4 5 6
void CDateiDlg::OnDblclkTree1(NMHDR* pNMHDR, LRESULT* pResult) { CString Variable=m_Tree1.GetItemData(m_Tree1.GetSelectedItem()); *pResult = 0; }
In einer Listbox gibt GetCurSel() den Index des ausgewählten Elements zurück. Geht in CTreeCtrl etwas ähnliches? Ich weiss hier ist es schwieriger: Ich müsste wissen, dass in der Wurzel die x.te Verzweigung (entspricht dem Fahrer), in der nächsten Ebene Verzweigung 1 oder 2 (in meinem Falle Trainings- bzw. Rennrunden) und in der dritten Ebene die x.te Runde gewählt wurde.
Dann könnte ich mir die Vergleicherei sparen.
Gruß
OlafGeändert von Olaf Lehmann (07.08.08 um 17:47 Uhr)
-
Hallo Olaf,
du kannst versuchen, dich via GetParentItem() in der Hierachie nach oben zu hangeln, um alle nötigen Infos einzusammeln. Wenn jemand in der 3. Ebene was ausgewählt hat, ist ja nur interessant, zu welcher Runde und zu welchen Fahrer der Eintrag gehört.
Gruß
MCoder"The three chief virtues of a programmer are: Laziness, Impatience and Hubris."
--- Larry Wall
-
07.08.08 22:09 #18
- Registriert seit
- Oct 2007
- Beiträge
- 56
Hallo MCoder,
danke schön!
Hab schon gemerkt, mittels
[CODE]
Var=m_Tree1.GetItemData(m_Tree1.GetParentItem(m_Tree1.GetSelectedItem()));
[CODE]
krieg ich auch die vorhergehenden Bezeichnungen raus. Wie ich ich die Indexe rausbekomme weiss ich noch immer nicht...
Gruß
Olaf
-
Hallo Olaf,
sowas wie einen Index gibt es beim TreeControl nicht; einen fortlaufende Numerierung macht bei einer Baumstruktur auch wenig Sinn. Jeder Knoten wird durch einen eindeutigen HTREEITEM identifiziert. Spezielle Daten pro Knoten können über SetItemData() zugewiesen werden, also etwa auch Zeiger auf Klassenobjekte oder Strukturen, falls komplexere Daten vorgehalten werden soll. Wie ich in deinem Code sehe, hast du ja da schon irgendeinen Text zugewiesen ?
Gruß
MCoder"The three chief virtues of a programmer are: Laziness, Impatience and Hubris."
--- Larry Wall
-
08.08.08 13:43 #20
- Registriert seit
- Oct 2007
- Beiträge
- 56
Hallo MCoder,
SetItemData ist gut. So kann man ja quasi jeden Item unsichtbare Werte zuweisen, die man manchmal besser verwerten kann als die sichtbaren.
Ja die Daten (Fahrernamen/Anzeige ob Training oder Rennen/Rundenzeiten) gelangen schon alle perfekt mittels InsertItem in den Baum...
Es geht nun recht flott voran.
Gruß
Olaf
-
09.08.08 12:37 #21
- Registriert seit
- Oct 2007
- Beiträge
- 56
Hallo!
eine Kleinigkeit gestaltet sich als schwierig.
Ich muss die Rundendaten aus der Baumstruktur in eine Listbox schicken. Soweit so gut. Nun sollte aber in dieser Listbox automatisch dieser (also der letzte Eintrag) ausgewählt werden. Dann könnte ich es nämlich so machen, dass die Daten sofort (ohne dass ich in der Listbox nochmal rumklicken muss) angezeigt werden. Merkwürdigerweise finde ich nirgendwo wie ich den letzten Eintrag einer Listbox markieren kann. Das sollte doch möglich sein...
Gruß
Olaf
P.S.: Es ist vielleicht schwer zu verstehen, wieso die Daten überhaupt erst in diese ListBox müssen. Aber das hängt mit dem bereits seit langem funktionierenden Hauptprogramm zusammen. (Aus auf die Schnelle nicht zu erklärenden Gründen müssen die eigenen Runden des Fahrers der das Replay gespeichert hat auf anderem Wege eingelesen werden.)
-
Versuch's mal so:
GrußCode cpp:1 2 3 4 5
CListBox m_listbox; // ... m_listbox.SetCurSel(m_listbox.GetCount() - 1);
MCoder"The three chief virtues of a programmer are: Laziness, Impatience and Hubris."
--- Larry Wall
-
09.08.08 18:25 #23
- Registriert seit
- Oct 2007
- Beiträge
- 56
Ah, .GetCount ist des Rätsels Lösung, danke. Der letzte Listeintrag wird markiert. Danach lasse ich die Funktion, die sonst immer dann ausgeführt wird, wenn ich einen Doppelklick auf einen Listenfeldeintrag mache, einfach mittels
ausführen.Code :1
OnDblclkList1();
OnDblclkList(1)
macht einige Sachen, u.a. durch Auslösen verschiedener Buttons (BUTTON2, usw...) die ausgewählten Grafiken anzeigen. Alles klappt wie beim Doppelklick aufs Listenfeld, nur eins merkwürdigerweise nicht. Der Eintrag vom Listenfeld (Rundenzeit) wird in ein Text- bzw. Eingabefeld geschickt, weil er dort auch angezeigt werden soll/muss. Dort kommt er aber unerklärlicherweise nicht an. Wenn ich danach nochmal auf den Listenfeldeintrag doppelklicke wird der Eintrag ins Eingabefeld geschickt. Nun verstehe ich nicht was der Unterschied sein kann zwischen dem Auslösen der Funktion mittels Doppelklick und dem Anspringen der Funktion aus einer anderen Funktion heraus, zumal alles andere geht.Code :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 61 62 63 64 65 66
void CDateiDlg::OnDblclkList1() { if(AnzRu<4) { // Rund[AnzRu]=atoi(m_List1.Left(3)); //Alter Code Rund[AnzRu]=m_Liste1.GetCurSel(); //Neu ListBox Index statt 1. 3 Zeichen if(AnzRu==0) m_Anzeige23=m_List1.Mid(3,11); // Rundenzeiten ---> Eingabefelder if(AnzRu==1) m_Anzeige24=m_List1.Mid(3,11); if(AnzRu==2) m_Anzeige25=m_List1.Mid(3,11); if(AnzRu==3) m_Anzeige26=m_List1.Mid(3,11); UpdateData( FALSE ); if(AnzRu==0) { Invalidate(); UpdateWindow(); } //bei erster Rundenwahl Bildschirm löschen AnzRu++; if(AUSEIN2 % 2) { AUSEIN2++; OnButton2(); } if(AUSEIN3 % 2) { AUSEIN3++; OnButton3(); } if(AUSEIN4 % 2) { AUSEIN4++; OnButton4(); } if(AUSEIN8 % 2) { AUSEIN8++; OnButton8(); } if(AUSEIN9 % 2) { AUSEIN9++; OnButton9(); } if(AUSEIN10 % 2) { AUSEIN10++; OnButton10(); } if(AUSEIN11 % 2) { AUSEIN11++; OnButton11(); } if(AUSEIN12 % 2) { AUSEIN12++; OnButton12(); } if(AUSEIN14 % 2) { AUSEIN14++; OnButton14(); } if(AUSEIN16 % 2) { AUSEIN16++, OnButton16(); } if(AUSEIN18 % 2) { AUSEIN18++, OnButton18(); } if(AUSEIN20 % 2) { AUSEIN20++; OnButton20(); } if(AUSEIN21 % 2) { AUSEIN21++; OnButton21(); } if(AUSEIN17 % 2) { AUSEIN17++; OnButton17(); } if(AUSEIN22 % 2) { AUSEIN22++; OnButton22(); } if(AUSEIN23 % 2) { AUSEIN23++; OnButton23(); } if(AUSEIN24 % 2) { AUSEIN24++; OnButton24(); } if(AUSEIN25 % 2) { AUSEIN25++; OnButton25(); } if(AUSEIN26 % 2) { AUSEIN26++; OnButton26(); } if(AUSEIN27 % 2) { AUSEIN27++; OnButton27(); } if(AUSEIN28 % 2) { AUSEIN28++; OnButton28(); } if(AUSEIN29 % 2) { AUSEIN29++, OnButton29(); } if(AUSEIN30 % 2) { AUSEIN30++; OnButton30(); } if(AUSEIN31 % 2) { AUSEIN31++; OnButton31(); } if(AUSEIN32 % 2) { AUSEIN32++; OnButton32(); } if(AUSEIN33 % 2) { AUSEIN33++; OnButton33(); } if(AUSEIN34 % 2) { AUSEIN34++; OnButton34(); } if(AUSEIN35 % 2) { AUSEIN35++; OnButton35(); } if(AUSEIN36 % 2) { AUSEIN36++; OnButton36(); } if(AUSEIN37 % 2) { AUSEIN37++; OnButton37(); } if(AUSEIN38 % 2) { AUSEIN38++; OnButton38(); } if(AUSEIN39 % 2) { AUSEIN39++, OnButton39(); } if(AUSEIN40 % 2) { AUSEIN40++; OnButton40(); } if(AUSEIN41 % 2) { AUSEIN41++; OnButton41(); } if(AUSEIN42 % 2) { AUSEIN42++; OnButton42(); } if(AUSEIN43 % 2) { AUSEIN43++; OnButton43(); } if(AUSEIN44 % 2) { AUSEIN44++; OnButton44(); } CClientDC dc(this); dc.Draw3dRect(948,451,33,60,crColor1,crColor1); //Rechtecke rechts zeichnen dc.Draw3dRect(948,525,33,60,crColor2,crColor2); dc.Draw3dRect(983,451,33,60,crColor3,crColor3); dc.Draw3dRect(983,525,33,60,crColor4,crColor4); } else { AnzRu=0; m_Anzeige23="No lap"; // Rundenzeiten ---> optionsfelderr m_Anzeige24="No lap"; m_Anzeige25="No lap"; m_Anzeige26="No lap"; UpdateData( FALSE ); Rund[0]=0; Rund[1]=0; Rund[2]=0; Rund[3]=0; Invalidate(); } }
Hm, merkwürdig
Gruß
Olaf
-
09.08.08 19:59 #24
- Registriert seit
- Oct 2007
- Beiträge
- 56
Habs gefunden:
Wenn der neue Eintrag nur selektiert und ohne Doppelklick aufgerufen wird reicht es nicht vorher nur
zu schreiben. m_Liste1 ist die Ctrl-Variable.Code :1
m_Liste1.AddString(tim);
Ich mußte auch der Stringvariable der Listbox den neuen String zuweisen.
.Code :1
m_List1=tim;
Beim manuellen Ausführen des Doppelklicks geschieht dies wohl automatisch.
-
28.08.08 12:14 #25
- Registriert seit
- Oct 2007
- Beiträge
- 56
Hallo,
nun hänge ich wieder an zwei kleineren Sachen:
Das Erste: Das Replay beginnt immer in dem Moment indem man selber beitritt. Die Rundenzeiten der anderen Fahrer sind alle aufgeführt, auch die welche vor dem eigenen Beitritt gefahren wurden. Wenn man eine solche Runde auswählen würde können die eigentlichen Telemetrydaten nicht gefunden werden, da sie ja gar nicht aufgezeichnet wurden. Nun kann ich das Programm so basteln, dass beim Doppelklick auf diese Runden nichts passiert. Ich möchte aber gerne, dass die Rundenzeiten verschieden dargestellt werden (z.B. die vorhandenen fett und die fehlenden normal oder die vorhandenen rot und die fehlenden schwarz). Nun hatte ich eine Funktion gefunden mit der man einen Eintrag nachträglich im Aussehen verändern kann. Dazu brauche ich aber eine HTREEITEM Variable. Für die Rundenzeiten habe ich aber, um mir immensen Aufwand zu ersparen, keine HTREEITEMs festgelegt (da es sich um die unterste Ebene handelt ist das nicht unbedingt notwendig). Was ich also brauche ist ein Befehl der festlegt, dass der folgende Eintrag fett oder farbig dargestellt wird. Wenn ich m_Tree.SetTextColor(RGB(so und so)) verwende erscheint der ganze Stammbaum in der geänderten Farbe. Wenn ich hinterher wieder mit dieser Methode auf schwarz umstelle erscheint ALLES schwarz. So gehts also nicht. Hab leider nichts geeignetes gefunden. Gibts da was?
Und das zweite Problem: Man kann auch zoomen. Es gibt eine Bildlaufleiste mit der man dann an die entsprechende Stelle der Runde gehen kann. Das funktioniert auch alles mit SetScrollRange und ziemlich viel Mathematik.
Ich würde gerne die Breite des Verschiebeschalters entsprechend anpassen. Das weiss ich nicht wie das geht. In andern Programmen ist das ja in der Regel so. In meinem Fall müsste dann, wenn z.B. die ganze Runde ausgewählt ist (entspricht Zoomfaktor=1), der Verschiebebalken über die ganze Breite gehen, weil ein Verschieben dann sinnlos wäre, wenn der Zoomfaktor=2 müsste der Verschiebebalken die halbe Breite haben, usw...
Was muss man denn dazu verwenden?
MfG
Olaf
-
Hallo Olaf,
zu deinem ersten Problem:
Das ist kompliziert. Du benötigst einen Handler für die NM_CUSTOMDRAW-Nachricht im Parent und kannst dann darüber in der Darstellung herumfuhrwerken. Ich hab's selber noch nicht gebraucht, kann also zu den Details nichts weiter schreiben.
zu deinem zweiten Problem:
Woher stammt die Scrollbar bzw. welchen Control ist sie zugeordnet? Evt. kannst du da SetScrollInfo() was ausrichten (Page Size).
Gruß
MCoder"The three chief virtues of a programmer are: Laziness, Impatience and Hubris."
--- Larry Wall
-
06.09.08 08:52 #27
- Registriert seit
- Oct 2007
- Beiträge
- 56
Danke MCoder für den Tip: SetScrollInfo()! Damit hab ich die Blidlaufleiste so hingekriegt wie ichs wollte. Sieht ganz professionell aus!
Das andere Problem hab ich einfach anders gelöst. Vor jeder nicht gespeicherten Rundenzeit steht ein Stern. Wenn versucht wird eine solche Runde auszuwählen wird als erstes geprüft ab an der Stelle ein Stern oder ein Leerzeichen steht. Die Einleseprozedur wird dann nur im letzteren Fall gestartet.
Da das Programm in der neuen Ausbaustufe nun gut läuft setz ich mal den Erledigthaken.
Danke für die vielen Tipps!
MfG
Olaf
Ähnliche Themen
-
CTreeCtrl->GetTooltips()->SetDelayTime geht nicht
Von tt5 im Forum C/C++Antworten: 0Letzter Beitrag: 28.11.06, 14:14 -
CTreeCtrl, deselektiertes Item kann nachher nicht mehr selektiert werden
Von tt5 im Forum VisualStudio & MFCAntworten: 2Letzter Beitrag: 07.09.06, 10:45 -
CTreeCtrl in CMDIChildFrame - wird nicht erstellt/angezeigt
Von pibr im Forum VisualStudio & MFCAntworten: 8Letzter Beitrag: 13.09.05, 10:23 -
Bekomme das nicht hin ...
Von belisto im Forum Vektor-ProgrammeAntworten: 1Letzter Beitrag: 23.02.05, 16:49 -
Bekomme XP nicht drauf!!
Von Gullynbg im Forum Microsoft WindowsAntworten: 1Letzter Beitrag: 18.11.02, 09:15





Zitieren
Login






