주의할점 : 프로젝트 생성시
New - Project - Win32 Application 으로 생성해야합니다.
Win32 Consol Application으로 할 경우 링크애러(아래 글 참조)를 맞이할 수 있습니다;
프로젝트 생성후 새파일을 하고 아래 소스를 넣고 cpp로 파일을 저장합니다.
소스 :
cpp 소스입니다 ㅋ
#include <windows.h>
#include <math.h>
const double pi = 3.14159265358979;
void drawLineAngle(HDC hdc, int posX, int posY, double firstAngle, double firstLineLength);
// draw line with hdc, start position, Line Direct(Angle) and Line Length
void drawLine(HDC hdc, int posX, int posY, int tgtX, int tgtY);
// draw line with hdc, start position and object position
int drawTree(int depth, HDC hdc, void (*dLA)(HDC, int, int, double, double), void (*dL)(HDC, int, int, int, int), int posX, int posY, double firstAngle, double firstLineLength, int isRoot, int diffAngle, double lenRate);
//depth, HDC, dLA func, dL func, posX, posY, firstAngle, firstLength, isRoot, diffAngle, lenRate
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
LPSTR lpszClass="First";
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance
,LPSTR lpszCmdParam,int nCmdShow)
{
HWND hWnd;
MSG Message;
WNDCLASS WndClass;
g_hInst=hInstance;
WndClass.cbClsExtra=0;
WndClass.cbWndExtra=0;
WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
WndClass.hInstance=hInstance;
WndClass.lpfnWndProc=(WNDPROC)WndProc;
WndClass.lpszClassName=lpszClass;
WndClass.lpszMenuName=NULL;
WndClass.style=CS_HREDRAW | CS_VREDRAW;
RegisterClass(&WndClass);
hWnd=CreateWindow(lpszClass,lpszClass,WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
NULL,(HMENU)NULL,hInstance,NULL);
ShowWindow(hWnd,nCmdShow);
while(GetMessage(&Message,0,0,0)) {
TranslateMessage(&Message);
DispatchMessage(&Message);
}
return Message.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
switch(iMessage) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_LBUTTONDOWN :
{
HDC hdc = GetDC(hWnd);
drawTree(30, hdc, drawLineAngle, drawLine, 350, 400, 90 , 90, 1, 25, 0.8);
//depth, HDC, dLA func, dL func, posX, posY, firstAngle, firstLength, isRoot, diffAngle, lenRate
ReleaseDC(hWnd, hdc);
break;
}
case WM_CREATE :
break;
}
return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}
void drawLineAngle(HDC hdc, int posX, int posY, double firstAngle, double firstLineLength)
{
int lenX, lenY;
double radian;
radian = (firstAngle - 90) / 180 * pi;
lenX = int(double(firstLineLength) * sin(radian));
lenY = int(double(firstLineLength) * cos(radian));
MoveToEx(hdc, posX, posY, NULL);
LineTo(hdc, posX + lenX, posY + lenY);
}
void drawLine(HDC hdc, int posX, int posY, int tgtX, int tgtY)
{
MoveToEx(hdc, posX, posY, NULL);
LineTo(hdc, tgtX, tgtY);
}
int drawTree(int depth, HDC hdc, void (*dLA)(HDC, int, int, double, double), void (*dL)(HDC, int, int, int, int), int posX, int posY, double firstAngle, double firstLineLength, int isRoot, int diffAngle, double lenRate)
{
if( !depth || firstLineLength < 3)
return 0;
int lenX, lenY, tgtX, tgtY;
double radian = (firstAngle - 90) / 180 * pi;
lenX = int(double(firstLineLength) * sin(radian));
lenY = int(double(firstLineLength) * cos(radian));
tgtX = posX - lenX;
tgtY = posY - lenY;
if(isRoot) {
MoveToEx(hdc, posX, posY, NULL);
dL(hdc, posX, posY, tgtX , tgtY);
}
else {
// tgtX = posX;
// tgtY = posY;
}
MoveToEx(hdc, tgtX, tgtY, NULL);
dLA(hdc, tgtX, tgtY, firstAngle + 180 + diffAngle , double(firstLineLength) * lenRate);
dLA(hdc, tgtX, tgtY, firstAngle + 180 - diffAngle , double(firstLineLength) * lenRate);
drawTree(depth-1, hdc, dLA, dL, tgtX, tgtY, int( firstAngle + diffAngle ) % 360, double(firstLineLength) * lenRate, 0, diffAngle, lenRate);
drawTree(depth-1, hdc, dLA, dL, tgtX, tgtY, int( firstAngle - diffAngle + 360 ) % 360, double(firstLineLength) * lenRate, 0, diffAngle, lenRate);
return 0;
}