Baum Zeichnen?

Ron-calli

Grünschnabel
Moin Moin,

ich habe folgende Struktur:

Code:
typedef struct baum			
{
	char szName[100];	// speichert den Namen.
	baum *pnaechster[n]; //Zeigt auf einen der Kinder
        baum *pvorgaenger;	    // Zeiger auf den Vorgänger.
}baum;

class clTreeStruct 
{
public://Methoden
	clTreeStruct(void);
	~clTreeStruct(void);
	void AddItem(char *name);
	char *GetBack(void);
	baum *anker;
	baum *pWorker;
};

Also ein Baum, wo jeder Knoten n-Viele Kinder hat. Jetzt möchte ich das Ding zeichnen, komm aber in meinen Gedanken nicht weiter. Eine verkettete Liste zu Zeichen hat bereits geklappt, dort muss nan nur gucken ob es einen Nachfolger gibt, wenn ja, diesen Ausgeben und so weiter, nur bei so einem Baum?

Hier nochmal wie ich die Liste ausgegeben hab:
Code:
void CPhytreeView::OnPaint()
{
    CPaintDC dc(this); // device context for painting
	CRect Recto;//Die Area wo das drin ist
    CPen PenBlack;//Farbe!?
	PenBlack.CreatePen(PS_SOLID, 1, BLACK_PEN);
	dc.SelectObject(&PenBlack);
	GetClientRect(&Recto[0]);
	//Bereich fürn Baum
	int y = 10;
	Recto.top = y;
	Recto.left = 10;
	Recto.bottom = 400;//Graphisch Clippen
	Recto.right = 400;
	if(objTree.anker != NULL)
	{
	char *pErster = objTree.anker->szName;//ersten Zeichnen lassen.
	DrawText(dc,pErster,strlen(pErster),&Recto,DT_LEFT);
	//Rest zeichnen lassen.
	objTree.pWorker = objTree.anker;
	while(objTree.pWorker->pnaechster[0] != NULL)
	{
		Recto.top = y+20;
		objTree.pWorker = objTree.pWorker->pnaechster[0];
		char *pName = objTree.pWorker->szName;
		DrawText(dc,pName,strlen(pName),&Recto,DT_LEFT);
		y +=20;
	}
	}
}


Viele Grüße
 
Moin moin,

in dem Fall wirst du um einen Rekursiven Aufruf nicht drum rum kommen.
-Schreib dir ne Funktion, die einen Knoten übergeben bekommt
-Den zeichnest du dann
-in einer Schleife über alle Kinder rufst du die Funktion selbst dann auf und übergibst ihr das jeweilige Kind.

Gestartet wird mit dem Root...

Gruss Michael
 
Hi


Ich hb das auch mal gemacht, aber ohne Klassen und Knoten...
Allerdings rekursiv, kannst es dir ja mal angucken:
Code:
#define STRICT

#include <windows.h>


LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
				   PSTR szCmdLine, int nCmdShow)
{
	HWND hWnd;
	MSG msg;
	WNDCLASS wc;

	const char szApp[]={"Anwendung"};

	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wc.hInstance = hInstance;
	wc.lpfnWndProc = WndProc;
	wc.lpszClassName = szApp;
	wc.lpszMenuName = NULL;
	wc.style = CS_VREDRAW | CS_HREDRAW;

	RegisterClass(&wc);

	hWnd = CreateWindow(szApp, szApp, WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, CW_USEDEFAULT,
		CW_USEDEFAULT, CW_USEDEFAULT,
		NULL, NULL, hInstance, NULL);

	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);

	while(GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return (int)msg.wParam;
}

int anz=0;

void zeichnen(HDC hDC, int x, int y, int richtung, float weite, float div)
{
	int i=0;

	anz++;

	if(weite > 0.5)
	switch(richtung)
	{
	case 1:
		for(i=0; i < weite; i++)
			SetPixel(hDC, x, y-i, RGB(0,0,0));
		zeichnen(hDC, x, y-i, 3, weite/div, div);
		zeichnen(hDC, x, y-i, 4, weite/div, div);
		break;
	case 2:
		for(i=0; i < weite; i++)
			SetPixel(hDC, x, y+i, RGB(0,0,0));
		zeichnen(hDC, x, y+i, 3, weite/div, div);
		zeichnen(hDC, x, y+i, 4, weite/div, div);
		break;
	case 3:
		for(i=0; i < weite; i++)
			SetPixel(hDC, x-i, y, RGB(0,0,0));
		zeichnen(hDC, x-i, y, 1, weite/div, div);
		zeichnen(hDC, x-i, y, 2, weite/div, div);
		break;
	case 4:
		for(i=0; i < weite; i++)
			SetPixel(hDC, x+i, y, RGB(0,0,0));
		zeichnen(hDC, x+i, y, 1, weite/div, div);
		zeichnen(hDC, x+i, y, 2, weite/div, div);
		break;
	}
}



LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	static RECT rect;
	
	switch(message)
	{
	case WM_CREATE:
		{
			return 0;
		}
	case WM_SIZE:
		{
			rect.right = LOWORD(lParam);
			rect.bottom = HIWORD(lParam);

			return 0;
		}
	case WM_CHAR:
		{
			return 0;
		}
	case WM_PAINT:
		{
			HDC hDC;
			PAINTSTRUCT ps;
			hDC = BeginPaint(hWnd, &ps);
			{
				zeichnen(hDC, 400, 500, 1, 300, 1.35);
			}
			EndPaint(hWnd, &ps);
			ReleaseDC(hWnd, hDC);
			
			return 0;
		}
	case WM_DESTROY:
		{
			PostQuitMessage(0);
			return 0;
		}
	}

	return DefWindowProc(hWnd, message, wParam, lParam);
}

mfg
umbrasaxum
 
So langsam wird´s was :) Naja...

Ich rufe über die OnPaint die Methode mit dem rekursiven Aufruf auf. Jedoch wird immer nur das erste Element gezeichnet. Normal müsste es überschrieben werden.

Code:
void CTaxonView::OnPaint()
{
	if(objTree.anker != NULL)
	{
		objTree.pWorker=objTree.anker;
		Zeichne(*objTree.pWorker);
	}
	else
	{
	CPaintDC dc(this);
	}
}

Code:
void CTaxonView::Zeichne(baum objBaum)
{
	CPaintDC dc(this); // device context for painting
	CRect Recto;
        CPen PenBlack;
	PenBlack.CreatePen(PS_SOLID, 1, BLACK_PEN);
	dc.SelectObject(&PenBlack);
	GetClientRect(&Recto[0]);
	//Bereich fürn Baum
	Recto.top = 10;
	Recto.left = 10;
	Recto.bottom = 400;//Graphisch Clippen
	Recto.right = 400;
	char *pWort = objBaum.szName;//ersten Zeichnen lassen.
	DrawText(dc,pWort ,strlen(pWort ),&Recto,DT_LEFT);//Immer nur den 1.ten?
        MessageBox(pErster,MB_OK);//GIBT JEDEN AUS
	//Rekursiv alles aufrufen.
	for(int i=0;i<200;i++)
	{
		if(objBaum.pnaechster[i]!=NULL)
		{
			Zeichne(*objBaum.pnaechster[i]);
		}
	return;
	}
}

Also in der MessageBox wird jedes Element ausgegeben. Nur beim Zeichnen bleibt es immer das 1. :( Wisst ihr wieso?

Grüße!
 
Zurück