Auto-close window

Intrebari legate de programarea cu biblioteci precum MFC, ATL, WTL si GDI+.
Post Reply
mesajflaviu
Membru++
Membru++
Posts: 687
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Auto-close window

Post by mesajflaviu » 25 May 2012, 10:55

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 !
Attachments
AutoMsgBoxDemo.zip
(74.08 KiB) Downloaded 309 times



User avatar
Marius Bancila
Fondator
Fondator
Posts: 2344
Joined: 11 Jul 2007, 11:45
Judet: Timiş
Location: Timisoara
Contact:

Re: Auto-close window

Post by Marius Bancila » 25 May 2012, 19:35

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.
Marius Bancila
Fondator Codexpert, Microsoft MVP VC++
Site personal | Blog

mesajflaviu
Membru++
Membru++
Posts: 687
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Re: Auto-close window

Post by mesajflaviu » 25 May 2012, 21:23

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);
		}

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3778
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Auto-close window

Post by Ovidiu Cucu » 28 May 2012, 22:17

Vezi aici o solutie mai buna, care foloseste un hook Cum facem AfxMessageBox cu auto-close?

mesajflaviu
Membru++
Membru++
Posts: 687
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Re: Auto-close window

Post by mesajflaviu » 30 May 2012, 10:15

Rezolvare model. Multumesc !

Post Reply