Win32_API - GDI로 선그리기3(연속해서 여러 선 그리기)

컴퓨터/Win32-API

728x90
반응형

서론

 

 

Win32_API - GDI로 선그리기2 (마우스 동작을 이용해봅시다.)

서론 지난 글에서 MoveToEx와 LineTo 2개의 함수를 이용해서 선을 그려봤습니다. 본문에서는 이 두 함수와 마우스 동작에 따른 처리를 하면서 마우스 동작에 따른 처리방법을 알아보고, 다양한 형태

blog-of-gon.tistory.com

지난 글에서 간단하게 마우스 클릭으로 직선을 그려보았습니다. 하지만 추가적으로 선을 그리지 못하고 하나의 선만을 그릴 수 있었습니다. 

이유는 다시 WM_PAINT 메세지를 처리할 때 마지막의 직선만을 그리기 때문입니다.

이 문제를 해결하기 위해서는 여러방법이 있습니다. 본문에서는 여러 선들의 좌표들을 기억해서 다시 그리는 방법으로 해결을 해보도록 합시다.

 

여러 선들의 좌표를 기억해야 한다 - C 링크드리스트 이용

여러 선들을 좌표를 계속해서 기억하고 추가하여야합니다. 순수 C언어만을 이용한다고 가정했을 때 배열로는 이 과정을 극복하기가 쉽지 않습니다.

따라서 동적메모리 할당을 이용한 링크드 리스트를 구현하여 연속적으로 좌표를 기억할 수 있는 리스트를 만들어 봅시다.

링크들 리스트를 구현하기 위해서 아래 글을 참조하면 도움이 될 것입니다.

 

 

C언어 - Single linked list(단일 연결 리스트) 구현해보기

시작하기 전에 자료구조인 List의 개념이 익숙하지 않거나 모르신다면 개념을 익히고 보는 것을 추천드립니다. 자료구조 - List(리스트)와 종류 List 개념 이해하기 자료구조 중 하나인 List는 배열

blog-of-gon.tistory.com

//C언어 리스트 구현 
typedef struct _Node
{
    POINT st,end;
    struct _Node* next_node;
}NODE, Node;

Node* CreateNode(POINT st, POINT end) {
    Node* newNode = (Node*)malloc(sizeof(Node)); // 노드 동적 할당
    newNode->next_node = NULL;	                      // 다음 노드는 아직 존재하지 않음으로 NULL 로 초기화
    newNode->st = st;
    newNode->end = end;
    return newNode;	// 생성된 포인터 타입의 노드를 반환 
}

void AppendNode(Node** List, POINT st , POINT end) {
    if ((*List) == NULL) {
        *List = CreateNode(st,end);
    }
    else {
        Node* Node_tail = (*List);
        while (Node_tail->next_node != NULL) {
            Node_tail = Node_tail->next_node;
        }
        Node_tail->next_node = CreateNode(st,end);
    }
}

 

전역 변수로 링크드 리스트 선언 하기

계속해서 그려지는 좌표를 기억하기 위한 전역 변수를 하나 선언해 줍니다.

Node* List;

클릭이 끝날때마다 포인트 기억하기

WM_LBUTTONUP 메시지에서 마우스 버튼이 떨어지는 것을 감지할 때마다 전역 변수 List에 값을 계속 추가해 주도록 합시다.

    case WM_LBUTTONUP:
        end_pos.x = GET_X_LPARAM(lParam);
        end_pos.y = GET_Y_LPARAM(lParam);

        AppendNode(&List, start_pos, end_pos);
        count++;
        status = 0;
        break;

WM_PAINT 처리하기

    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            hdc = BeginPaint(hWnd, &ps);

            if (status == 1) {
                MoveToEx(hdc, start_pos.x, start_pos.y, NULL);
                LineTo(hdc, end_pos.x, end_pos.y);
            }
            //예제 4를 위한 소스코드
                NODE* temp = List;

                for (int i = 0; i < count; i++)
                {
                    MoveToEx(hdc, temp->st.x, temp->st.y, NULL);
                    LineTo(hdc, temp->end.x, temp->end.y);
                    temp = temp->next_node;
                }

            EndPaint(hWnd, &ps);
        }
        break;

 

위의 소스코드처럼 List에 저장된 좌표를 하나씩 꺼내와 반복문을 통해 저장된 직선을 계속 그려주면 됩니다.

728x90
반응형

Commnet

G91개발일지

Gon91(지구일)

91년생 공학엔지니어의 개발일지

TODAY :

YESTER DAY :

TOTAL :