VC 关闭已经打开的MessageBox的方法

这两天一直在跟这东东较劲,今天终于有了点结果。
其实思路很简单:第一步找到Message的窗口句柄,第二步关掉它。
找句柄有若干的方法,这两天重点研究的是FindWindowEx() 和 GetLastActivePopup()。各有利弊。后述。

关窗口也有若干方法。可以发送WM_CLOSE/调用CloseWindow(), 发送WM_DESTROY/DestroyWindow(),PoseMessage(hWnd, WM_COMMAND, MAKEWPARAM(IDCANCEL,BN_CLICKED) , (LPARAM)::GetDlgItem( hWnd ,IDCANCEL ) )(发送点击button事件。根据Messagebox类型改变ID),以及EndDialog()实现。
CloseWindow()最不好用。因为它实际上只是将Messageox最小化了,并没有真正销毁。
DestroyWindo()虽然销毁了Messagebox,却没有重新激活其父窗口。在多窗口的时候会造成界面的混乱。
模拟点击Button比较万能,因为可以实现不同的逻辑效果,只是有点麻烦。
EndDialog最好用,能够安全地干掉Messagebox,并且模拟返回值(第二个参数)。

下面是查找句柄的两个例程:
一、使用GetLastActivePopup()。
前提条件:需要知道父窗口。
优点:简单明了。
缺陷:当焦点不在MessageBox上时无法将其关闭。

void DestroyMsg(HWND parent)
{
    if (parent)
    {
        HWND hWnd = GetLastActivePopup( parent ) ; //查找激活的MessageBox
        if (hWnd)
        {
            EndDialog( hWnd, 0 ) ;
        }
    }
}

二、使用FindWindowEx()。
前提条件:MessageBox的标题和内容
优点:可以找到任意MessageBox。
缺点:代码长,消耗资源大。

static BOOL CALLBACK EnumCommonProc( HWND hwnd,  LPARAM lParam )
{
	stMsgFeature* pstMsg = (stMsgFeature*)lParam ;
	char szQuestionMsg[255] = { 0 } ;
    GetWindowText( hwnd , szQuestionMsg , 255 ) ;
    
    if ( ( strcmp( pstMsg->pszContent , szQuestionMsg ) == 0 ) )

    {
        // found , and exit enum
		pstMsg->bFound = true ;
        return false ;
    }
    
    return true ;
}

bool IsMsgWnd ( HWND hWnd , char* pszContent )
{
	stMsgFeature stMsg ;
	stMsg.pszContent = pszContent ;
	stMsg.bFound = false ;
    EnumChildWindows( hWnd,
        EnumCommonProc,
		LPARAM(&stMsg)) ;
    
	return stMsg.bFound ;
}

void DestroyWnd(const char* pszCaption , const char* pszContent )
{
	HWND hJigCaption = FindWindowEx(
        NULL ,          // parent
        NULL ,          // child after
        NULL ,          // class
        pszCaption ) ;  // caption
        
    while ( hJigCaption )
    {
		if ( IsMsgWnd( hJigCaption , pszContent ) )
        {
            break ;
        }
        
        // find next window
        hJigCaption = FindWindowEx(
            NULL ,          // parent
            hJigCaption ,   // child after
            NULL ,          // class
            pszCaption ) ;  // caption
    }

	if (hJigCaption)
	{
		::EndDialog( hJigCaption , 0 ) ;
	}
}

你好,新朋友。留言前请先填写昵称邮箱