duilib中实现弹出模态框时要注意的地方

        在duilib中,可以调用CWindowWnd::ShowModal()来实现模态框的显示,该接口的代码如下所示:

UINT CWindowWnd::ShowModal()
{
	ASSERT( ::IsWindow(m_hWnd) );
	UINT nRet = 0;
	HWND hWndParent = GetWindowOwner( m_hWnd );
	::ShowWindow( m_hWnd, SW_SHOWNORMAL );
	::EnableWindow( hWndParent, FALSE );
	MSG msg = { 0 };
	while( ::IsWindow(m_hWnd) && ::GetMessage(&msg, NULL, 0, 0) ) 
	{
		if( WM_CLOSE == msg.message && msg.hwnd == m_hWnd ) 
		{
			nRet = msg.wParam;
			::EnableWindow( hWndParent, TRUE );
			::SetFocus( hWndParent );
		}

		if( !CPaintManagerUI::TranslateMessage(&msg) ) 
		{
			::TranslateMessage( &msg );
			::DispatchMessage( &msg );
		}

		if( WM_QUIT == msg.message ) 
		{
			break;
		}
	}
	::EnableWindow( hWndParent, TRUE );
	::SetFocus( hWndParent );
	if( WM_QUIT == msg.message ) 
	{
		::PostQuitMessage( msg.wParam );
	}

	return nRet;
}
由代码可以看出,先将父窗口Disable掉,然后接管UI主线程的消息循环,在模态框关闭后,再将消息循环放归UI主线程。但在使用时要要稍微注意一下,下面就简单的说明一下。

        先给出几段有问题的代码,先假设CDemoDlg是待显示的模态框窗口,由DUI派生而来,如下所示:

class CDemoDlg : public CWindowImplBase
{
public:
	CDemoDlg( STRINGorID strUI, unsigned int dwTransparent = 255, bool bDeleteSelf = true );
	virtual ~CDemoDlg();
......
}

        代码段1如下所示:(下面的代码均是放置在某一个函数中,即在某一函数中弹出模态框)

		CDemoDlg demoDlg( IDR_XML_DEMO_DLG );
		demoDlg.Create( hParentWnd, _T("CDemoDlg"), UI_WNDSTYLE_BOX, UI_WNDSTYLE_EX_FRAME );
		demoDlg.CenterWindow();
		demoDlg.ShowModal();
代码中可以看出,CDemoDlg在创建时将使用默认值bool bDeleteSelf = true,所以在WindowImplBase::OnFinalMessage函数中窗口对象会自动被delete掉,看上去好像是没问题。实际上,demoDlg是局部对象,使用的是栈上的内存,但是delete删除的是堆上的内存,这肯定是有问题的,会引起异常。所以这种方法是有问题。

        代码段2如下所示:

		CDemoDlg* pDlg = new CDemoDlg ( IDR_XML_DEMO_DLG, 255, false );
		pDlg->Create( hParentWnd, _T("CDemoDlg"), UI_WNDSTYLE_BOX, UI_WNDSTYLE_EX_FRAME );
		pDlg->CenterWindow();
		pDlg->ShowModal();
代码1中的自动销毁有问题,那我们就将bDeleteSelf设置为false,不让自动被销毁。但还是有问题,new出来的对象没有释放,会有内存泄漏,其实在ShowModal执行完后把new来的对象delete就好了。

        那么如果不用new的方式,用代码1中的方式如何实现呢?也简单,构造对象时将bDeleteSelf设置为false,不让其自动被销毁,由于是局部变量,函数退出时会被销毁掉,即如下的代码:

		CDemoDlg demoDlg( IDR_XML_DEMO_DLG,255, false );
		demoDlg.Create( hParentWnd, _T("CDemoDlg"), UI_WNDSTYLE_BOX, UI_WNDSTYLE_EX_FRAME );
		demoDlg.CenterWindow();
		demoDlg.ShowModal();

你可能感兴趣的:(Directui相关)