Win32 API TreeControl

elfvyn

Mitglied
Wie kann ich einzelne Baum-Elemente ansprechen?
Ich erstelle meinen Baum wie folgt:

Code:
void RegTreeWindow()
{
	WNDCLASSEX WndClsEx;

	WndClsEx.cbSize	           = sizeof(WNDCLASSEX);
	WndClsEx.style	           = CS_HREDRAW | CS_VREDRAW|CS_PARENTDC;
	WndClsEx.lpfnWndProc	  = TreeWndProc;
	WndClsEx.cbClsExtra	  = 0;
	WndClsEx.cbWndExtra	  = 0;
	WndClsEx.hInstance		  = hInstance;
	WndClsEx.hIcon		  = LoadIcon(NULL, MAKEINTRESOURCE("picticon.ico"));	
	WndClsEx.hCursor		  = LoadCursor(NULL, IDC_ARROW);							        
	WndClsEx.hbrBackground	  = (HBRUSH)(COLOR_BTNFACE + 1);							        
	WndClsEx.lpszMenuName	  = NULL;													                    
	WndClsEx.lpszClassName	  = TreeWindowClassName;									            
	WndClsEx.hIconSm		  = LoadIcon(NULL, MAKEINTRESOURCE("picticon.ico"));	

	RegisterClassEx(&WndClsEx);

}

Code:
HWND CreateTreeWindow(HWND hwnd)
{
	MDICREATESTRUCT mcs;
	
	mcs.szTitle	= "Tree";							  
	mcs.szClass	= TreeWindowClassName;	
	mcs.hOwner	= GetModuleHandle(NULL);
	mcs.x		= 0;								    
	mcs.y		= 0;								    
	mcs.style		= MDIS_ALLCHILDSTYLES;	
	mcs.cx		= 200;								  
	mcs.cy		= 600;								  
	NewWnd = (HWND)SendMessage(hwnd, WM_MDICREATE, 0, (LONG)&mcs);

	return NewWnd;
}

Code:
LRESULT CALLBACK TreeWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch(msg)
	{
		case WM_CREATE:
		{
			AddTreeViewItems(CreateTreeView(hwnd));
		}
		break;

    case WM_MDIACTIVATE:
		{
			HMENU hMenu, hFileMenu;
			UINT EnableFlag;

			hMenu = GetMenu(hWndMainFrame);
			if(hwnd == (HWND)lParam)
			{
				EnableFlag = MF_ENABLED;
			}
			else
			{
				EnableFlag = MF_GRAYED;
			}

			EnableMenuItem(hMenu, 1, MF_BYPOSITION | EnableFlag);
			EnableMenuItem(hMenu, 2, MF_BYPOSITION | EnableFlag);

			hFileMenu = GetSubMenu(hMenu, 0);

			EnableMenuItem(hFileMenu, IDM_FILE_CLOSE, MF_BYCOMMAND | EnableFlag);
			EnableMenuItem(hFileMenu, IDM_WINDOW_CLOSE_ALL, MF_BYCOMMAND | EnableFlag);

			DrawMenuBar(hWndMainFrame);
		}
		break;


		default:

		return DefMDIChildProc(hwnd, msg, wParam, lParam);
	}
	return 0;
}

Über meine Funktion AddTreeViewItems() erstelle ich meine Baumeinträge und er wird auch so dargestellt wie vorgesehen.

Jedes Element gibt mir ja nun seinen handle... aber wie kann ich denn mit WM_LBUTTONDOWN oder so die einelnen Elemente ansprechen?

Ziel ist es von mir durch die Auswahl jedes Eintrages ein neues Fenster zu öffnen!

thx schonmal im vorraus
 
Mit dem Makro
Code:
int TabCtrl_HitTest(
    HWND hwnd, 		
    LPTCHITTESTINFO pinfo		
);
kannst Du feststellen, welches Item angeklickt wurde. Du kannst natürlich auch selber die 'TCM_HITTEST'-Nachricht an Dein TreeCtrl senden.
Die TCHITTESTINFO-Struktur sieht so aus:
Code:
typedef struct tagTCHITTESTINFO { 
    POINT pt; 
    UINT  flags; 
} TCHITTESTINFO, FAR * LPTCHITTESTINFO;
 
Ihrgendwie bekomme ich das nicht so hin wie ich möchte....
Ich bräuchte mal bitte ein direktes code-Beispiel. Ich hab übrigens den eigentlichen Baum ja vergessen:
Code:
HWND CreateTreeView (HWND hWndParent)
{
	HWND hwndTree;     
	RECT rcl;           
	HMENU ID_TREEVIEW=NULL;
	int BITMAP_WIDTH=10;
	int BITMAP_HEIGHT=10;
	int NUM_BITMAPS=1;
	GetClientRect(hWndParent, &rcl);	
	hwndTree = CreateWindowEx(	0L,
	WC_TREEVIEW,
	"",
	WS_VISIBLE | WS_CHILD | WS_BORDER | TVS_HASLINES | TVS_HASBUTTONS | 
	TVS_LINESATROOT | TVS_SHOWSELALWAYS | TVS_CHECKBOXES,
	0,
	0,
	rcl.right - rcl.left,
	rcl.bottom - rcl.top,
	hWndParent,
	(HMENU) ID_TREEVIEW,
	hInstance,
	NULL );

	return (hwndTree);
}

Wo muss ich denn genau eingreifen.... Also der Baum schickt doch seine Messages an sein ParentWindow (TreeWindow bei mir). Und in dessen Nsachrichtenroutine muss ich diese doch dann abfangen oder?
thx
 
Hab jetzt mal in die TreeWindow Nachrichtenroutine folgendes eingebaut:
Code:
case WM_NOTIFY:
      {
        switch(((LPNMHDR)lParam)->code)
        {
          case NM_CLICK:
          {

          }
          break;

          case NM_DBLCLK:
          {

          }
          break;
        }
      }
Damit reagiere ich schonmal auf die Mouse. Wie komm ich jetzt ran was denn nu geklickt wurde? Kann ich das denn so überhaupt machen?
 
So ungefähr könnte das gehen (ist aber nicht getestet):
Code:
case WM_NOTIFY:
     {
     	switch(((LPNMHDR)lParam)->code)
     	{
     		case NM_CLICK:
     		{
     			POINT point;
     			TVHITTESTINFO info;
     			HTREEITEM itemCicked;
     			
     			//Mausposition holen
     			DWORD mousepos = GetMessagePos();
     			//Koordinaten extrahieren (Bildschirmkoordinaten)
     			point.x = ((int)(short)LOWORD(mousepos));
     			point.y = ((int)(short)HIWORD(mousepos));
     			//In Fensterkoordinaten umwandeln
     			ScreenToClient(&point);
     			//Item herausfinden
     			itemCicked = TreeView_HitTest(hwndTree, &info);
     			//und jetzt kannst Du das Item verwenden
     		}
     		break;
     
     		case NM_DBLCLK:
     		{
     
     		}
     		break;
     	}
 }
P.S.: Sorry, im letzten Post habe ich aus Versehen das falsche Makro angegeben (TabCtrl_HitTest statt TreeCtrl_HitTest). Die Nachricht heißt TVM_HITTEST und nicht TCM_HITTEST
 
So ich hab das jetzt alles soweit angepasst, glaube aber das ich in der Initialisierung des Baumes noch einen Denkfehler habe..
Hab das ausprobiert was oben steht und sogar noch eine weitere Variante gefunden die mir das TreeItem beim draufklicken zurückgeben soll

Code:
 itemClicked=(HTREEITEM)SendMessage(hWndTree,TVM_GETNEXTITEM,TVGN_CARET,(LPARAM)itemClicked);

Problem ist nur... ich bekomme immer 0 zurück.

Also fehlt scheinbar was..... Also genau gesehen habe ich ja nur den Hanlde auf den Tree und sonst nichts auf das ich mich beziehen kann oder wo der Baum hinterlegt ist.. Bei MFC hätte ich ja nun auchnoch die Resource und sowas wie IDC_TREE1 oder so.
Das habe ich ja nunmal nicht da ich ohne MFC arbeite.

Aber wo liegt nun das problem..?hilfe
 
Joa ich habs.... bin schon C-Blind geworden.. war ein Variablen Problem...Hat doch so geklappt!.
danke für alle Hilfe
 
Zurück