1,058 views
首页 > WTL, 技术心得, 日常琐碎 > WTL 创建 MDI 子窗口, 但不激活它

WTL 创建 MDI 子窗口, 但不激活它

2010年1月10日

终于解决 MDI 程序的子窗口, 在新创建时窗口时, 不激活这个新的子窗口. 技术细节是, 在 WTL 的 “atlframe.h” 文件的 CMDIChildWindowImpl 类的成员函数 Create 内:

// ...
class ATL_NO_VTABLE CMDIChildWindowImpl : public CFrameWindowImplBase<TBase, TWinTraits >
{
// ...
	HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
			DWORD dwStyle = 0, DWORD dwExStyle = 0,
			UINT nMenuID = 0, LPVOID lpCreateParam = NULL)
	{
		// ... 

		// If the currently active MDI child is maximized, we want to create this one maximized too
		ATL::CWindow wndParent = hWndParent;
		BOOL bMaximized = FALSE;
		wndParent.SendMessage(WM_MDIGETACTIVE, 0, (LPARAM)&bMaximized);
		if(bMaximized)
			wndParent.SetRedraw(FALSE);

		HWND hWnd = CFrameWindowImplBase<TBase, TWinTraits >::Create(hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, (UINT)0U, atom, lpCreateParam);

		if(bMaximized)
		{
			// Maximize and redraw everything
			if(hWnd != NULL)
				MDIMaximize(hWnd);
			wndParent.SetRedraw(TRUE);
			wndParent.RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN);
			::SetFocus(GetMDIFrame());   // focus will be set back to this window
		}
		else if(hWnd != NULL && ::IsWindowVisible(m_hWnd) && !::IsChild(hWnd, ::GetFocus()))
		{
			::SetFocus(hWnd);
		}

		return hWnd;
	}

上列代码片段的 24 行 MDIMaximize(hWnd); 以及 31 行 ::SetFocus(hWnd); 将激活当前创建的窗口.
为了与当前的 CMDIChildWindowImpl 类和平相处, 又能达到我自己的目的, 我在创建我自己的窗口时, 将我自己的窗口创建成不可见风格, 同时将我的最大化的子窗口恢复成 restore 状态, 当调用完 create 函数完成创建后, 又恢复成原样, 并将新创建的窗口设置成可见的, 像以下代码片段:

		ATL::CWindow wndParent = hWndParent;	// MDI Client Window
		BOOL bMaximized = FALSE;
		HWND hWndActive = (HWND) wndParent.SendMessage(WM_MDIGETACTIVE, 0, (LPARAM)&bMaximized);
		if(bMaximized) {
			wndParent.SetRedraw(FALSE);
			wndParent.SendMessage(WM_MDIRESTORE, (WPARAM)hWndActive, 0);
		}
		dwStyle = GetWndStyle(dwStyle);
		dwStyle &= ~(WS_VISIBLE);

		HWND hWnd = (CMDIChildWindowImpl::) Create(hWndParent, rect, lpcstrWindowName, dwStyle, dwExStyle, NULL, lpCreateParam);

		if (bMaximized || CMainOption::s_bTabMode) {
			wndParent.SendMessage(WM_MDIMAXIMIZE, (WPARAM)(hWndActive?hWndActive:hWnd), 0);
		}
		if(bMaximized) {
			wndParent.SetRedraw(TRUE);
		}

		if(FALSE == IsWindowVisible())
		{
			DWORD dwSWPflags = SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|SWP_NOZORDER;
			dwSWPflags |= SWP_SHOWWINDOW;
			::SetWindowPos(m_hWnd, 0, 0,0,0,0, dwSWPflags);
		}

WTL, 技术心得, 日常琐碎 , ,

  1. 目前还没有任何评论.
  1. 目前还没有任何 trackbacks 和 pingbacks.