본문 바로가기
개발/mfc

mfc AfxMessageBox 응답 받기, Title바꾸기, 시간 제한

by 즐기며 2024. 5. 24.

mfc AfxMessageBox 응답 받기, vs2010

 

목차

1. 응답 받기

2. AfxMessageBox  title 바꾸기

3. 시간 제한 1 - Timer

4. 시간 제한 2 - FindWindow

5. 시간 제한 3 - FindWindowEx

================================

 

1. 응답 받기,

 

1). 그냥 아래처럼 쓰면 됩니다.

if( IDYES == AfxMessageBox(_T("Are you OK ?"), MB_YESNO) ) {
	AfxMessageBox(_T("Good ?")
} else {
	AfxMessageBox(_T("Why ?")
}

 

 

2). MB_YESNO 대신 들어 갈거 뭐 디파인 찾어 보시면 됩니다.

// MessageBox() Flags
#define MB_OK                       0x00000000L
#define MB_OKCANCEL                 0x00000001L
#define MB_ABORTRETRYIGNORE         0x00000002L
#define MB_YESNOCANCEL              0x00000003L
#define MB_YESNO                    0x00000004L
#define MB_RETRYCANCEL              0x00000005L

#if(WINVER >= 0x0500)
	#define MB_CANCELTRYCONTINUE        0x00000006L
#endif /* WINVER >= 0x0500 */
버튼스타일 의미
MB_ABORTRETRYIGNORE [취소],[재시도],[무시]
MB_OK  [확인]
MB_OKCANCEL [확인],[취소]
MB_RETRYCANCEL  [재시도],[취소]
MB_YESNO [예],[아니오]
MB_YESNOCANCEL [예],[아니오],[취소]
   
아이콘스타일  의미
MB_ICONEXCLAMATION [느낌표]
MB_ICONINFORMATION  [느낌표]
MB_ICONQUESTION [물음표]
MB_ICONSTOP [X]
   
디폴트버튼 의미
MB_DEFBUTTON1 첫번째버튼
MB_DEFBUTTON2 두번째버튼
MB_DEFBUTTON3 세번째버튼
   
모달리티 의미
MB_APPLMODAL 메시지박스를 종료시켜야  프로그램을 계속진행할수있음
MB_SYSTEMMODAL  메시지박스를 종료시켜야  시스템을 사용할수있음

 

3).  IDYES 대신 들어 갈거..

// Dialog Box Command IDs
#define IDOK                1
#define IDCANCEL            2
#define IDABORT             3
#define IDRETRY             4
#define IDIGNORE            5
#define IDYES               6
#define IDNO                7
#if(WINVER >= 0x0400)
	#define IDCLOSE         8
	#define IDHELP          9
#endif /* WINVER >= 0x0400 */
반환값  의미
IDABORT [취소(Abort)]가 눌러졌음
IDCANCEL  [취소(Cancel)]이 눌러졌음
IDIGNORE [무시]가 눌러졌음
IDNO [아니오]가 눌러졌음
IDOK [확인]이 눌러졌음
IDRETRY [재시도]가 눌러졌음
IDYES [예]가 눌러졌음

 

 

2. AfxMessageBox  title 바꾸기

Dialog에서 임시로 변경해서 사용이 가능합니다.

LPCTSTR pAppNameTemp = AfxGetApp()->m_pszAppName;	// 기존 app Name 을 저장	
AfxGetApp()->m_pszAppName = L"MyTemporaryTitle";	// 새로운 이름 할당
AfxMessageBox(_T("Test!!!"));				// 창 띄우기
AfxGetApp()->m_pszAppName = pAppNameTemp;		// 저장했던 app Name 복구

주소를 백업한 이후에 임시로 변경한 이후에 다시 복원시키는 방법입니다.

 

 

3. 시간 제한 1 - Timer

AfxMessageBox 함수 자체에는 시간 제한 기능이 없지만,  여러 가지로 구현 할 수 있읍니다.
 
SetTimer 함수를 사용하여 메시지 박스 표시 후 일정 시간이 지나면 자동으로 종료되도록 구현할 수 있습니다. 
SetTimer로 타이머를 설정한 후 AfxMessageBox를 호출하고, OnTimer 메시지 핸들러에서 GetClassName 함수를 이용해 마지막 활성 팝업 창의 클래스 이름을 확인하여 AfxMessageBox 창을 식별하고 PostMessage나 SendMessage를 이용하여 종료시키는 방식으로 구현합니다. 
 
구현 방법: 
 
1) 타이머 설정: SetTimer 함수를 사용하여 일정한 간격으로 OnTimer 메시지가 발생하도록 설정합니다. 
    SetTimer(101, 1000, NULL); // 1초마다 타이머 발생

 

2) 메시지 박스 호출: SetTimer 이후 AfxMessageBox를 호출하여 메시지 박스를 띄웁니다. 

    if(AfxMessageBox("박스다..") == IDOK) {
        // OK 버튼을 누른 경우 처리
    }

 

3) OnTimer 함수 구현: OnTimer 함수에서 다음을 수행합니다. 

 
  • GetLastActivePopup 함수로 마지막 활성 팝업 창 핸들을 가져옵니다. 
     
  • GetClassName 함수를 사용하여 해당 팝업 창의 클래스 이름을 가져옵니다. AfxMessageBox로 생성된 메시지 박스의 클래스 이름은 #32770입니다. 
     
  • 클래스 이름이 #32770이면, PostMessage나 SendMessage 함수를 호출하여 해당 창에 WM_CLOSE 메시지를 보내거나 DestroyWindow 함수로 직접 창을 파괴합니다. 
     
코드 예시 (간략화):
// OnTimer 메시지 처리 함수
void CYourView::OnTimer(UINT_PTR nIDEvent)
{
    if (nIDEvent == 101) {
        HWND wndDlg = ::GetLastActivePopup(m_hWnd);
        if (wndDlg && wndDlg != m_hWnd) {
            char buffer[256] = {0};
            ::GetClassName(wndDlg, buffer, 256);

            if (strcmp(buffer, "#32770") == 0) { // AfxMessageBox의 클래스 이름
                // 타이머를 멈추고 메시지 박스를 닫습니다.
                KillTimer(101); // 타이머 중지
                ::SendMessage(wndDlg, WM_CLOSE, 0, 0); // 메시지 박스 닫기
            }
        }
    }
    CView::OnTimer(nIDEvent);
}
 

 

 

4. 시간 제한 2 - FindWindow - 동작 하는거 확인 하였읍니다.

위 2에서 이름을 별도로 지정 한 경우,

HWND wndDlg = ::FindWindow(NULL, L"MyTemporaryTitle");
if( wndDlg !=0 ) {		// 있으면, 죽인다.
    ::EndDialog(wndDlg, IDNO);    // IDNO  IDOK
    //::SendMessage(wndDlg, WM_CLOSE, 0, 0); // 메시지 박스 닫기
}
 
5. 시간 제한 3 - FindWindowEx

FindWindowEx 함수는 특정 윈도우에 포함된 자식 윈도우를 탐색할 때 사용하는 함수로서, 
FindWindow 함수의 기능이 확장된 함수입니다

HWND wndDlg = NULL;
int n=0;
while (wndDlg = ::FindWindowEx(m_hWnd, wndDlg, NULL, L"MyTemporaryTitle")) {
	// wndDlg NULL이 아니라면 자식 윈도우를 찾았다는 뜻이다.
	n++; if(n>1000) break;  // 무한 방지
}

if( wndDlg !=0 ) {		// 있으면, 죽인다.
	::EndDialog(wndDlg, IDNO);    // IDNO  IDOK
	//::SendMessage(wndDlg, WM_CLOSE, 0, 0); // 메시지 박스 닫기
}

 

 

이상 입니다.