Dialog 기반 프로그램에서 OnIdle (WM_IDLE) 구현하기 (WM_KICKIDLE사용)
기본적으로 Dialog로 작성된 프로그램은 일반 응용 프로그램의 메시지 루프 처리에 차이로 인해서 WM_IDLE 사용에 문제가 발생한다.
CWnd::RunModalLoop는 CWinThread::PumpMessages(win32의 모달 대화상자 작동형태를 흉내낸 것)를 호출하게 된다. 이는 모달 대화상자가 실제로는 MFC에의해 모달리스 처럼 다뤄지지만 나타나는 형태는 모달로서 작동하게 된다.
이로 인해 일반 WM_IDLE을 사용할 수 없고 WM_ENTERIDLE를 사용하게 된다. 그러나 이는 약간 속임수로 우리가 원하는 IDLE에서 처리를 할 수 없다.
WM_ENTERIDLE은 대화상자가 동작했을 때 작동되며, 대화상자가 종료되면 작동이 중단된다. 그래서 대화상자에 의해서 선택된 내용이 적용되고 싶으나 다음 대화상자를 작동할 때까지 아무 작업도 하지 않은다.
우리가 원하는 IDLE에서 수행하는 메커니즘을 제공하는 것이 WM_KICKIDLE 메시지이다. 이 메시지 핸들러를 작성하고 OnIdle 핸들러를 호출하는 것은 어리석은 짓이며 제대로 작동하지 않을 것이다.
이런 것은 앞에서 WM_ENTERIDLE 메시지를 WindowProc에서 다음과 같이 메시지 큐에 메시지가 없으면 강제적으로 OnKickIdle 핸들러를 호출하게 했으나 메시지 맵 오류가 발생하게 된다.
if(HIWORD(GetQueueStatus(QS_ALLEVENTS)) == 0) {
PostMessage(WM_ENTERIDLE, wParam + 1, 0);
}
그럼 WM_KICKIDLE를 추가해보자.
Step 1) 필요한 헤더 파일을 추가하자.
#include <afxpriv.h> // for WM_KICKIDLE declaration
afxpriv.h에 WM_KICKIDLE 메시지에 대한 처리가 들어 있다. 반드시 추가해줘야 한다.
Step 2) 클래스에 메시지 핸들러를 정의 한다.
class CTestDlg : public CDialog
{
...
afx_msg LRESULT OnKickIdle(WPARAM wParam, LPARAM lParam); // 핸들러 추가
}
Step 3) 메시지 맵에 WM_KICKIDLE를 추가한다.
BEGIN_MESSAGE_MAP(CTestDlg , CDialog)
...
ON_MESSAGE(WM_KICKIDLE, OnKickIdle)
END_MESSAGE_MAP()
Step 4) 메시지 핸들러를 정의 한다. 그리고 그 안에 내가 갱신하고 싶은 내용을 넣는다.
LRESULT CTestDlg ::OnKickIdle(WPARAM wParam, LPARAM lParam)
{
switch(lParam) {
case 2:
// IDLE에서 처리할 내용
break;
case 4:
// IDLE에서 처리할 내용
break;
}
return (lParam <= 10);
}
여기서 lParam <= 10은 카운터 범위가 0 - 9까지를 말한다. 즉 lParam이 증가가 0 - 9까지 되며 계속 순환하는 형태로 되어 있다. 즉 return이 TRUE이면 계속 증가되고 FALSE이면 다시 0에서 증가하게 된다.
0
1
2 ==> case 2 호출
3
4 ==> case 4 호출
5
6
7
8
9
0 ==> 순환
1
2
if문을 사용해서 짝수만 호출하거나 원하는 순번에 호출할 수 있게 하면된다.
이는 CWinApp의 OnIdle을 호출하는 것이 아니고 CTestDlg의 OnKickIdle을 호출한다.
그렇기에 갱신되는 모든 처리는 CTestDlg에서 이뤄지게 된다.
참조
[1] http://www.codeguru.com/forum/archive/index.php/t-260189.html
'3.구현 > VC++' 카테고리의 다른 글
Win32 쓰레드에서 동기화 방법 (0) | 2007.02.16 |
---|---|
HRESULT 일반적인 값들 (0) | 2007.01.30 |
[수정중]윈도우에서 GetWindowRect, GetCllientRect를 통해 크기 얻기 (2) | 2006.11.23 |
자동으로 빌드 넘버 올려주는 매크로 (0) | 2006.11.22 |
ActiveX 사용한 CListView 사용자 컨트롤 (0) | 2006.11.16 |