티스토리 뷰
MFC 스레드3
UI스레드
메시지 루프를 가지고 있어서 사용자 입력이나 그 밖의 메시지 형태로 전될되는 이벤트를 처리할 수 있다.
예) 응용프로그램 객체 (프로젝트명App) -DOS 콘솔 응용 프로그램 제외
<응용 프로그램 객체에 해당하는 UI스레드 이외에 새로운 UI스레드를 생성하는 과정>
1. CWinThread 클래스로 부터 새로운 클래스를 파생시킨다.
2. 클래스 선언부와 구현부에 각각 DECLARE_DYNCCREATE, IMPLEMENT_DYNCREATE 매크로를 선언한다. 이 매크로를 선언함으로써 실행 시간 객체 정보와 동적 객체 생성 기능을 지원한다.
3. CWinThread 클래스가 제공하는 가상 함수 중 일부를 재정의 한다. CWinThread::InitInstance() 는 반드시 재정의해야 하며, 나머지 함수는 필요에 따라 재정의 한다.
4. AfxBeginThread() 를 이용하여 새로운 UI스레드를 생성한다.
CWinThread* AfxBeginThread(CRuntimeClass* pThreadClass, int nPriority = THREAD_PRIORITY_NORMAL,
UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL);
- pThreadClass
객체 정보를 담고 있는 CRuntimeClass 구조체 주소를 넣는다. 'RUNTIME_CLASS(클래스 명)' 을 사용한다.
- 나머지 인수는 작업자 스레드와 동일하다. (MFC tmfpem2 - 작업자 스레드 참고)
AfxBeginThread()는 CWinThread 타입 스레드 객체를 동적으로 생성하고(스레드를 만든 후) 이 객체의 주소값을 리턴 한다. 따라서 CWinThread 클래스 멤버 함수를 통해 스레드를 제어할 수 있다.
<UI 스레드 종료 방법 2가지>
1. WM_QUIT 메시지를 받아서 메시지 루프가 종료된다.
2. 스레드 제어 함수 내에서 AfxEndThread() 를 호출한다.
CWinThread를 상속받는 CMyThread 클래스 추가
CFrameWnd 를 상속받는 CMyWnd 클래스 추가
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 |
class CMyWnd : public CFrameWnd
{
...
public:
CString m_str;
afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnPaint();
};
BEGIN_MESSAGE_MAP(CMyWnd, CFrameWnd)
ON_WM_CHAR()
ON_WM_PAINT()
END_MESSAGE_MAP()
void CMyWnd::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
m_str.AppendChar(nChar);
Invalidate();
CFrameWnd::OnChar(nChar, nRepCnt, nFlags);
}
void CMyWnd::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: 여기에 메시지 처리기 코드를 추가합니다.
// 그리기 메시지에 대해서는 CFrameWnd::OnPaint()을(를) 호출하지 마십시오.
CRect rect;
GetClientRect(&rect);
dc.DrawText(m_str, &rect, DT_LEFT);
}
#include "MyWnd.h"
BOOL CMyThread::InitInstance()
{
// TODO: 여기에서 각 스레드에 대한 초기화를 수행합니다.
// 실행시간에 동적으로 CMyWnd 클래스 객체를 생성 CRuntimeClass* pRuntimeClass = RUNTIME_CLASS(CMyWnd);
CObject* pObject = pRuntimeClass->CreateObject();
ASSERT(pObject->IsKindOf(RUNTIME_CLASS(CMyWnd)));
m_pMainWnd = (CWnd*)pObject;
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
return TRUE;
}
BEGIN_MESSAGE_MAP(CMFCApplication6View, CView)
...
ON_WM_LBUTTONDBLCLK()
END_MESSAGE_MAP()
#include "MyThread.h"
void CMFCApplication6View::OnLButtonDblClk(UINT nFlags, CPoint point)
{
// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
AfxBeginThread(RUNTIME_CLASS(CMyThread));
CView::OnLButtonDblClk(nFlags, point);
} |
cs |