Bekomme CTreeCtrl nicht auf

Olaf Lehmann

Mitglied
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.)
 

MCoder

Erfahrenes Mitglied
Versuch's mal so:
C++:
CListBox m_listbox;

// ...

m_listbox.SetCurSel(m_listbox.GetCount() - 1);
Gruß
MCoder
 

Olaf Lehmann

Mitglied
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
Code:
OnDblclkList1();
ausführen.
OnDblclkList(1)
Code:
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(); }

}
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.

Hm, merkwürdig

Gruß
Olaf
 

Olaf Lehmann

Mitglied
Habs gefunden:
Wenn der neue Eintrag nur selektiert und ohne Doppelklick aufgerufen wird reicht es nicht vorher nur
Code:
m_Liste1.AddString(tim);
zu schreiben. m_Liste1 ist die Ctrl-Variable.
Ich mußte auch der Stringvariable der Listbox den neuen String zuweisen.
Code:
 m_List1=tim;
.
Beim manuellen Ausführen des Doppelklicks geschieht dies wohl automatisch.
 

Olaf Lehmann

Mitglied
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
 

MCoder

Erfahrenes Mitglied
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
 

Olaf Lehmann

Mitglied
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