HTREEITEM bekommen dessen "Check" sich geändert hat

EriFo

Erfahrenes Mitglied
Moinsn,

ich hab in meinem Programm ein CTreeCtrl bei dem jedes Item einen Checkbox hat.
Nun hab ich aber das Problem, dass ich nicht mitbekomme, wenn der Benutzer ein Häckchen setzt (oder löscht).
Man ist halt aufgeschmissen, wenn's keine extra Behandlungsrotine gibt. :)
Kommt man irgendwie an das HTREEITEM ran bei dem sich das "Check" ändert ?

(Zur Erklärung: Ich möchte, dass, sobald man das Häckchen eines Items ändert auch das Eltern Teil einen bekommt )

M.f.G. Erik
 
Knifflig, jedenfalls ein bischen. Ist das eine von dir von CTreeCtrl abgeleitete Klasse oder ein generisches Treecontrol?
 
Zuletzt bearbeitet:
Das Teil heist "Strukturansicht" und die zugewiesene Variable ist vom Typ "CTreeCtrl".
 
Okay. In dem Fall musst du Folgendes machen:

1. Dein Dialog bekommt einen Handler für den Klick auf den Tree. Das Ereignis heisst NM_CLICK (für deinen Tree) und erzeugt wird vom Classwizard wahrscheinlich ein Handler namens OnClickTree() (Falls dein Tree "Tree" heisst). Dieser Handler wird aufgerufen, sobald der Tree geklickt wird - klar! ;)

2. In deinen Handler tust du folgenden Code, der prüft, ob ge- oder entcheckt wurde und entsprechend für Vorfahren des Items verfährt.

Code:
void CMeinDialog::OnClickTree(NMHDR* pNMHDR, LRESULT* pResult) 
{
  NMTREEVIEW* pNMTreeView = (NMTREEVIEW*)pNMHDR;

  unsigned int uFlags;

  POINT pt;
  GetCursorPos( &pt );
  m_Tree.ScreenToClient( &pt );
 
  HTREEITEM hItem = m_Tree.HitTest( pt, &uFlags );

  if ( uFlags & 64 )
  {
    // der Check hat sich geändert! Check ändern
    m_Tree.SetCheck( hItem, !m_Tree.GetCheck( hItem ) ); 
    
    // Check für alle Vorfahren ändern entsprechend diesem Item
    CheckAllParentNodes( m_Tree, hItem, m_Tree.GetCheck( hItem ) ); 

    *pResult = 1;
    return;
  }
  
  *pResult = 0;
}

3. Du schreibst eine Routine (namens CheckAllParentNodes), die entsprechend alle Vorfahren des Knotens checkt, wenn der Knoten gecheckt wurde. Nicht vergessen: Alle Kindknoten des Knoten entchecken , wenn der Knoten entcheckt wurde! Die Routine kann CTreeCtrl::SetCheck() verwenden. Die Routine kannst du auch rekursiv machen. Sie wird auf jeden Fall noch für einige Stunden Arbeit machen - das kann ich dir versprechen. Solltest du damit nicht klar kommen, kannst du ja nochmal nachfragen.

Ich hoffe, dass du damit schon wieder einen Schritt weiter kommst!
 
Fantastisch - mit der Nachricht hatte ich auch schon ein bischen rumgebastelt aber is nix gescheites dabei rausgekommen. :)

Das mit der Rekursion ist kein Problem - hab schon ein paar davon zum Löschen von Unmarkierten ect.
Damit hätte ich jetzt erstmal kein lebenswichtiges Problem mehr ^_^ aber
vielleicht könntest du mir zum Verständniss erklären, wozu du dir den Zeiger auf die NMTREEVIEW-Struktur
geben lässt - ich seh' jetz nicht wo das zum Tragen kommt.
Zumal sie laut MSDN sogar die Client-Mauskoordinaten beinhaltet (welche du dir auch extra geben lässt).
Und wie kommst du auf das "& 64" ?!
Ich nehm mal an, das die Zahl abhängig ist von dem, was sich verändert hat, nur wie kommt man da ran ?

Wie auch immer - ich danke dir.
Hatte schon mit dem Gedanken gespielt, mir ne Funktion zu schreiben,
welche alles durchgeht und schaut ob "ungecheckte" items "ge(s)checkte"
Kinder haben. (währ aber bei weitem nicht so elegant ^_^)

M.f.G. Erik
 
Zuletzt bearbeitet:
vielleicht könntest du mir zum Verständniss erklären, wozu du dir den Zeiger auf die NMTREEVIEW-Struktur
geben lässt - ich seh' jetz nicht wo das zum Tragen kommt.
Zumal sie laut MSDN sogar die Client-Mauskoordinaten beinhaltet (welche du dir auch extra geben lässt).
Die Zeile mit der Struktur wird vom Wizard automatisch erzeugt. Ich lasse sie meist drin und vergesse sie. ;)
Wenn es stimmt, dass man darin die Mauskoordinaten bekommt, muss ich das bei Gelegenheit mal ausprobieren. Vielen Dank für den Tipp!

Und wie kommst du auf das "& 64" ?!
Ich nehm mal an, das die Zahl abhängig ist von dem, was sich verändert hat, nur wie kommt man da ran ?
Es sollte eigentlich TVHT_ONITEMSTATEICON sein (definiert als 0x0040). Das ist eines der Flags, die man von CTreeCtrl::HitTest() geliefert bekommt. Warum nicht es da steht, weiss ich auch nicht. Die Routine ist in dieser Form einem Projekt entnommen, das ich nicht vollständig umgesetzt habe und weswegen ein Teil des Codes nicht von mir ist. Vielleicht hat der Kollege da nicht in der MSDN Lib nachgesehen, sondern ausprobiert, welche Flags HitTest() unter verschiedenen Umständen liefert. Auch eine Lösung. ;)

Hatte schon mit dem Gedanken gespielt, mir ne Funktion zu schreiben,
welche alles durchgeht und schaut ob "ungecheckte" items "ge(s)checkte"
Kinder haben. (währ aber bei weitem nicht so elegant ^_^)
Aber vielleicht effizienter als eine rekursive Lösung. Das musst du selbst entscheiden.
 
achso

Mein Wizard scheint da fauler zu sein °-_- , der lässt die Zeile einfach weg.
Bei OnKeydownTree z.B. ist dann auch wieder eine dabei, was mich ein bischen gewundert hatte - naja egal.

Danke nochmal,

M.f.G. Erik
 

Neue Beiträge

Zurück