Page 1 of 1

Auto-close window

Posted: 25 May 2012, 10:55
by mesajflaviu
As avea nevoie de un message-box cu auto-inchidere ... am gasit intr-un mic articol o idee interesanta care foloseste metoda MessageBox a clasei CWnd :

Code: Select all

void CMsgBox::MessageBox(CString sMsg, CString sCaption, UINT nSleep, 
						 UINT nFlags, bool bAutoClose)
{
	// Save the caption, for finding this 
	// message box window later
	m_Caption = sCaption;
	
	// If auto close selected then, start the timer.
	if(bAutoClose)
		SetTimer(100, nSleep, NULL);
	
	// Show the message box
	CWnd::MessageBox(sMsg, sCaption, nFlags);
}
iar la expirarea timpului, se trimite un mesaj WM_CLOSE acestei ferestre :

Code: Select all

void CMsgBox::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	
	BOOL bRetVal = false;
	
	// Find the message box window
	CWnd* pWnd = FindWindow(NULL, m_Caption);
	if(pWnd != NULL)
	{
		// Send close command to the message box window
		::PostMessage(pWnd->m_hWnd, WM_CLOSE, 0, 0);
	}

	// Kill the timer
	KillTimer(100);

	CWnd::OnTimer(nIDEvent);
}
acuma, de vreme ce pot customiza acest message-box (MB_YESNO de exemplu), as vrea ca dupa expirarea timpului sa simulez o apasare pe un anumit buton ('Yes' sau 'No') :

Code: Select all

void CMsgBox::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	
	BOOL bRetVal = false;
	
	// Find the message box window
	CWnd* pWnd = FindWindow(NULL, m_Caption);
	if(pWnd != NULL)
	{
		// Send close command to the message box window
//		::PostMessage(pWnd->m_hWnd, WM_CLOSE, 0, 0);
		CWnd* pOK = pWnd->GetDlgItem(IDOK);
		HWND hWndOK = pOK->m_hWnd; // <-- Access violation
		PostMessage(WM_COMMAND, MAKEWPARAM(IDOK, BN_CLICKED), (LPARAM)hWndOK);
	}

	// Kill the timer
	KillTimer(100);

	CWnd::OnTimer(nIDEvent);
}
dar la linia

Code: Select all

HWND hWndOK = pOK->m_hWnd; <-- Access violation
am 'Access violation', semn ca pOK e null ... intrebarea mea este : pot avea acces la butoanele acestei ferestre ? Pentru exemplificare atasez si proiectul demo ... Multumesc anticipat !

Re: Auto-close window

Posted: 25 May 2012, 19:35
by Marius Bancila
Pay daca ai creat box-ul cu butoanele YES si NO atunci verifica IDYES si IDNO, in nici un caz IDOK, pt. ca acest buton nu exista. Cand iei acolo un pointer la buton verifica ca e valid si porma foloseste-l.

Re: Auto-close window

Posted: 25 May 2012, 21:23
by mesajflaviu
Am incercat IDOK, IDYES, IDNO, etc., acel pointer (l-am notat acum cu pButton) e invalid :

Code: Select all

		CWnd* pButton = pWnd->GetDlgItem(IDYES);
		if(pButton)
		{
			HWND hButtonWnd = pButton->m_hWnd;
			PostMessage(WM_COMMAND, MAKEWPARAM(IDYES, BN_CLICKED), (LPARAM)hButtonWnd);
		}

Re: Auto-close window

Posted: 28 May 2012, 22:17
by Ovidiu Cucu
Vezi aici o solutie mai buna, care foloseste un hook Cum facem AfxMessageBox cu auto-close?

Re: Auto-close window

Posted: 30 May 2012, 10:15
by mesajflaviu
Rezolvare model. Multumesc !