본문 바로가기
프로그래밍/MFC (C++)

MFC ] 통계자료, 스레드 Thread 를 사용하여 로드하기

by eteo 2022. 7. 9.

 

깃허브 주소 :

https://github.com/joeteo/CarAccidentList.git

 

GitHub - joeteo/CarAccidentList

Contribute to joeteo/CarAccidentList development by creating an account on GitHub.

github.com

 

 

 

무거운 프로세스나 무한루프로 동작해야할 작업이 있다면 쓰레드를 생성해서 백그라운드로 작업을 넘기면 된다.

 

이전에 만든 교통사고 통계조사 프로그램에서 시간이 오래 걸릴 수 있는 파일 불러오기 부분을 스레드를 사용한 버전으로 수정하였다.

 

UINT Load(LPVOID LpData)
{
	CCarAccidentListDlg* target = (CCarAccidentListDlg*)(LpData);
	target->DC.loadListFromFile();
	//LPARAM temp = (LPARAM)(target);
	SendMessage(target->m_hWnd, MYMSG, NULL, NULL);
	return 0;
}

void CCarAccidentListDlg::OnBnClickedButtonload()
{
	AfxBeginThread(Load, (LPVOID)this);		
}

afx_msg LRESULT CCarAccidentListDlg::OnMymsg(WPARAM wParam, LPARAM lParam)
{

	CString str;
	m_list.DeleteAllItems();

	for (int i = 0; i < (int)DC.getList().size(); i++)
	{
		str.Format(_T("%d"), i + 1);
		m_list.InsertItem(i, str);
		m_list.SetItem(i, 1, LVIF_TEXT, DC.getList().at(i)->GetSiDo(), NULL, NULL, NULL, NULL);
		m_list.SetItem(i, 2, LVIF_TEXT, DC.getList().at(i)->GetSiGunGoo(), NULL, NULL, NULL, NULL);


		for (int j = 0; j < LOCATION_NUMBER; j++)
		{
			str.Format(_T("%d"), DC.getList().at(i)->GetAccidentCount(j));
			m_list.SetItem(i, j + 3, LVIF_TEXT, str, NULL, NULL, NULL, NULL);
		}
	}
	
    UpdateData(false);	
    
	return 0;
}

 

 

먼저 UINT Load(LPVOID LpData) 라는 전역함수를 만든다.

 

기존에 불러오기 버튼을 누르면 실행되는 이벤트 처리 함수에선 AfxBeginThread 로 해당 함수를 호출하며 this 포인터를 넘겨준다.

 

쓰레드가 실행되고 전달받은 포인터를 사용하여 파일 불러오기를 한다.

 

쓰레드 내에서는 UpdateData(false); 를 사용할 수 없으므로 쓰레드 종료시점에 메시지전달 SendMessage 을 사용하여 UI에 데이터를 그리는 부분을 작성한다.

 

메시지 생성하기

 

 

위와 같은 방법으로 MYMSG라는 메시지를 만들고 그 안에 리스트 컨트롤을 업데이트 하는 부분을 집어넣었다.

 

다이얼로그 헤더 상단에는 다음과 같이 define 해준다.

 

#define MYMSG WM_USER+1

 

참고로

0 ~ 0x400 까지는 시스템 메시지용으로 예약 되어 있으며 WM_로 시작되는 대부분의 메시지는 이 영역에 예약되어 있다.

0x401 - 0x7FFF 까지는 프로그래머가 필요에 의해 사용할 수 있는 구역이다.

WM_USER가 0x400 이니까 위 처럼 WM_USER+1 로 define 하여 사용할 수 있다.

 

 

LPVOID 는 void*와 같다. minwindef.h 에 typedef 로 선언되어있다.

WPARAM 은 WORD 파라미터의 약자

LPARAM 은 LONG 파라미터의 약자로

 

일반적으로 데이터를 넘길때는 WPARAM 을 포인터를 넘길때는 LPARAM 을 사용한다고 한다. 위에서는 사용하지 않고 NULL을 넘겼다.