single thread 어플리케이션에 취소 버튼 구현
페이지 정보
본문
출처: http://www.fhcf.net/misc/id_ws/database/essays/fboyjoe/cancel/cancel.html
어플리케이션을 개발하다가 간혹 processor-intensive한 루틴을 작성해야할 때가 있다.
단일 쓰레드로 이를 구현했을 때는 하나의 루틴이 프로세서
자원을 다 잡아 먹기 때문에 윈도우즈 메시지를 처리할 수 없는 문제에 부딪힌다.
그래서 이때는 processor 자원을 많이 요구하는 연산 부분은 thread로 구현해서
돌려 놓고 원래의 thread는 윈도우 메시지를 처리하는 방법으로 구현을 한다.
그런데 별도의 쓰레드를 만들지 않고 단일 쓰레드에서 processor 자원 요구량이
많은 모듈과 윈도우즈 메시지를 동시에 처리할 수 있는 기법이 있어 소개한다.
결론을 미리 말하자면, processor-intensive한 연산 안에
message pump를 두어 메시지를 처리하도록 하며 유저가
언제든 취소를 원할 때 연산을 취소할 수 있도록 플래그를 검사하도록 하는 것이다.
플래그는 "취소"버튼을 눌렀을 경우에 셋팅되도록 한다.
핵심 부분을 코드로 살펴보면 다음과 같다.
void StartProcessing()
{
hCancelDialog = CreateDialog (inst, MAKEINTRESOURCE(IDD_DIALOG2),
hwnd, CancelDialog);
ShowWindow (hCancelDialog, TRUE);
// 취소 버튼이 있는 대화 상자 출력
cancelled = 0;
// 취소 버튼이 눌렸는지에 대한 플래그
for ( ...)
{
// 여기부터가 processor-intensive한 연산 부분이다. ....
if(!MessagePump())
{
// 연산 수행중에도 메시지를 처리할 수 있도록 한다.
return;
// WM_QUIT 메시지를 받으면 루틴을 빠져나간다.
}
if(cancelled)
{
// 취소 플래그가 셋팅되면 연산을 중지한다. ....
}
DestroyWindow(hCancelDialog);
EnableWindow(hwnd, TRUE);
....
BOOL MessagePump() // 메시지 펌프
{
MSG msg;
while(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
// 메시지 큐에 메시지가 있는지 체크
if (!GetMessage(&msg, NULL, 0, 0))
{
// 메시지를 가져온다.
PostQuitMessage(0); return FALSE;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return TRUE;
}
어플리케이션을 개발하다가 간혹 processor-intensive한 루틴을 작성해야할 때가 있다.
단일 쓰레드로 이를 구현했을 때는 하나의 루틴이 프로세서
자원을 다 잡아 먹기 때문에 윈도우즈 메시지를 처리할 수 없는 문제에 부딪힌다.
그래서 이때는 processor 자원을 많이 요구하는 연산 부분은 thread로 구현해서
돌려 놓고 원래의 thread는 윈도우 메시지를 처리하는 방법으로 구현을 한다.
그런데 별도의 쓰레드를 만들지 않고 단일 쓰레드에서 processor 자원 요구량이
많은 모듈과 윈도우즈 메시지를 동시에 처리할 수 있는 기법이 있어 소개한다.
결론을 미리 말하자면, processor-intensive한 연산 안에
message pump를 두어 메시지를 처리하도록 하며 유저가
언제든 취소를 원할 때 연산을 취소할 수 있도록 플래그를 검사하도록 하는 것이다.
플래그는 "취소"버튼을 눌렀을 경우에 셋팅되도록 한다.
핵심 부분을 코드로 살펴보면 다음과 같다.
void StartProcessing()
{
hCancelDialog = CreateDialog (inst, MAKEINTRESOURCE(IDD_DIALOG2),
hwnd, CancelDialog);
ShowWindow (hCancelDialog, TRUE);
// 취소 버튼이 있는 대화 상자 출력
cancelled = 0;
// 취소 버튼이 눌렸는지에 대한 플래그
for ( ...)
{
// 여기부터가 processor-intensive한 연산 부분이다. ....
if(!MessagePump())
{
// 연산 수행중에도 메시지를 처리할 수 있도록 한다.
return;
// WM_QUIT 메시지를 받으면 루틴을 빠져나간다.
}
if(cancelled)
{
// 취소 플래그가 셋팅되면 연산을 중지한다. ....
}
DestroyWindow(hCancelDialog);
EnableWindow(hwnd, TRUE);
....
BOOL MessagePump() // 메시지 펌프
{
MSG msg;
while(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
// 메시지 큐에 메시지가 있는지 체크
if (!GetMessage(&msg, NULL, 0, 0))
{
// 메시지를 가져온다.
PostQuitMessage(0); return FALSE;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return TRUE;
}
댓글목록
등록된 댓글이 없습니다.