⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tabbedmdi.cpp

📁 These listed libraries are written in WTL. But it s really hard to mix both MFC & WTL together. Obvi
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		UINT nItemFlag = MF_STRING;
		if(i == 0)
		{
			ASSERT(hWndChild == m_hWndCurActive);
			nItemFlag |= MF_CHECKED;
		}
		CWnd::FromHandle(hWndChild)->GetWindowText(strWindowText);
		strMenuText.Format(_T("&%d %s"), i+1, strWindowText);
		menu.AppendMenu(nItemFlag, AFX_IDM_FIRST_MDICHILD + i, strMenuText);
	}
	menu.Detach();
}

void CTabbedMDIFrameWnd::CMDIClientHooker::SetActiveChildByMenuId(UINT_PTR nMenuID)
{
	const int iIndex = (int) (nMenuID - AFX_IDM_FIRST_MDICHILD);
	ASSERT( (0 <= iIndex) && (iIndex < (int) this->m_ZOrder.size()) );
	this->SetActiveChild(m_ZOrder[iIndex]);
}

void CTabbedMDIFrameWnd::CMDIClientHooker::HighlightChild(HWND hWndChild, bool blHighlight)
{
	Pane* pPane = this->lookUpPane(hWndChild);
	if( NULL != pPane)
	{
		TabControlItem* pItem = pPane->get(hWndChild);
		if(pItem && (blHighlight != pItem->IsHighlighted()))
		{
			pItem->SetHighlighted(blHighlight);
			pPane->redrawTabControl();
		}
	}
}

void CTabbedMDIFrameWnd::CMDIClientHooker::SetActiveChild(HWND hWndNewActive)
{
	if(NULL == hWndNewActive)
	{
		hWndNewActive = this->focusedClientView();
	}

	if(hWndNewActive)
	{
		ASSERT(::IsWindow(hWndNewActive));
		if(hWndNewActive != m_hWndCurActive)
		{
			HWND hWndOldActive = m_hWndCurActive;
			m_hWndCurActive = hWndNewActive;

			// Update Z-Order
			std::vector<HWND>::iterator ite = std::find(m_ZOrder.begin(), m_ZOrder.end(), hWndNewActive);
			ASSERT(ite != m_ZOrder.end());
			if(ite != m_ZOrder.begin())
			{
				// Bring it to top
				m_ZOrder.erase(ite);
				m_ZOrder.insert(m_ZOrder.begin(), hWndNewActive);
			}

			if(hWndOldActive)
			{
				ASSERT(::IsWindow(hWndOldActive));
				HighlightChild(hWndOldActive, false);
				::SendMessage(hWndOldActive, WM_MDIACTIVATE, (WPARAM) hWndOldActive, (LPARAM) hWndNewActive);
				::SendMessage(hWndNewActive, WM_MDIACTIVATE, (WPARAM) hWndOldActive, (LPARAM) hWndNewActive);
			}
			else
			{
				::SendMessage(hWndNewActive, WM_MDIACTIVATE, NULL, (LPARAM) hWndNewActive);
			}

			if(hWndNewActive != this->focusedClientView())
			{
				this->setFocusTo(hWndNewActive);
			}
		}
		HighlightChild(hWndNewActive, true);
	}
	else
	{
		m_hWndCurActive = NULL;
	}

	RefreshMenu();
}

void CTabbedMDIFrameWnd::CMDIClientHooker::clientActivate(HWND childWnd, HWND clientViewWnd)
{
	__super::clientActivate(childWnd, clientViewWnd);
	if(clientViewWnd)
	{
		ASSERT_KINDOF(CTabbedMDIChildWnd, CWnd::FromHandlePermanent(clientViewWnd));
		this->SetActiveChild(clientViewWnd);
	}
}

void CTabbedMDIFrameWnd::CMDIClientHooker::clientCloseClick(HWND childWnd, HWND clientViewWnd)
{
	__super::clientCloseClick(childWnd, clientViewWnd);
	if(clientViewWnd)
	{
		ASSERT_KINDOF(CTabbedMDIChildWnd, CWnd::FromHandlePermanent(clientViewWnd));
		::SendMessage(clientViewWnd, WM_CLOSE, 0, 0);
	}
}

BOOL CTabbedMDIFrameWnd::CMDIClientHooker::ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
																	  LRESULT& lResult,
																	  DWORD dwMsgMapID)
{
	BOOL blHandled = FALSE;

	switch(uMsg)
	{
	case WM_MDIRESTORE:
	case WM_MDIMAXIMIZE:
	case WM_MDITILE:
	case WM_MDICASCADE:
	case WM_MDIICONARRANGE:
		// Simply ignore these commands
		blHandled = TRUE;
		lResult = FALSE;
		break;
	case WM_STYLECHANGING:
		if(GWL_EXSTYLE == wParam)
		{
			blHandled = TRUE;
			STYLESTRUCT* pStyle = (STYLESTRUCT*) lParam;
			pStyle->styleNew &= ~WS_EX_CLIENTEDGE;
			lResult = (pStyle->styleNew == pStyle->styleOld)?
				0 : ::DefWindowProc(m_hWnd, uMsg, wParam, lParam);
		}
		break;
	case WM_MDICREATE:
		blHandled = TRUE;
		{
			MDICREATESTRUCT* pMDIStruct = (MDICREATESTRUCT*) lParam;
			HWND hWndNewChild = ::CreateWindowEx(this->GetExStyle(),
				pMDIStruct->szClass,
				pMDIStruct->szTitle,
				pMDIStruct->style &= ~(WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_VISIBLE),
				0, 0, 0, 0,
				m_hWnd,
				NULL,
				(HINSTANCE) ::GetWindowLongPtr(m_hWnd, GWLP_HINSTANCE),
				pMDIStruct);

			//////////////////////////////////////////////////////////////////////////
			// Now change parent of the CMDIChildWnd
			if(hWndNewChild)
			{
				ASSERT_KINDOF(CTabbedMDIChildWnd, CWnd::FromHandlePermanent(hWndNewChild));

				// Update Z-Order
				m_ZOrder.push_back(hWndNewChild);
				this->append(pMDIStruct->szTitle, hWndNewChild);

				if(hWndNewChild == m_hWndCurActive)
				{
					this->HighlightChild(hWndNewChild, true);
				}
			}
			lResult = (LRESULT) hWndNewChild;
		}
		break;
	case WM_MDIDESTROY:
		blHandled = TRUE;
		lResult = 0;
		{
			HWND hWndDestroy = (HWND) wParam;
			if(hWndDestroy == m_hWndCurActive)
			{
				m_hWndCurActive = NULL;
				::SendMessage(hWndDestroy, WM_MDIACTIVATE, wParam, 0);
			}

			// Update Z-Order
			std::vector<HWND>::iterator ite = std::find(m_ZOrder.begin(), m_ZOrder.end(), hWndDestroy);
			ASSERT(ite != m_ZOrder.end());
			m_ZOrder.erase(ite);

			// Detach then destroy
			this->detachClientView(hWndDestroy);
			::DestroyWindow(hWndDestroy);

			// Activate the next window if any
			this->SetActiveChild(NULL);
		}
		break;
	case WM_USER_DESTROY_PANE:
		blHandled = __super::ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult, dwMsgMapID);
		this->SetActiveChild(NULL);
		break;
	//case WM_SIZE:
	//case WM_MOUSEACTIVATE:
	case WM_CREATE:
	case WM_CLOSE:
		// Forward this message to default MDI
		this->DefWindowProc(uMsg, wParam, lParam);
		break;
	case WM_MDIACTIVATE:
		blHandled = TRUE;
		lResult = 0;
		SetActiveChild((HWND) wParam);
		break;
	case WM_MDIGETACTIVE:
		blHandled = TRUE;
		if(m_hWndCurActive)
		{
			ASSERT(::IsWindow(m_hWndCurActive));
			lResult = (LRESULT) m_hWndCurActive;
			if(NULL != lParam)
			{
				// It is not maximized
				*((BOOL*) lParam) = FALSE;
			}
		}
		else
		{
			// Update status
			m_hWndCurActive = NULL;
			lResult = NULL;
		}
		break;
	case WM_MDINEXT:
		blHandled = TRUE;
		lResult = 0;
		ASSERT(NULL == wParam); // Don't support if not NULL
		if(m_ZOrder.size() > 1)
		{
			// The first one must be the active one
			ASSERT(m_hWndCurActive == m_ZOrder[0]);
			if(FALSE == lParam)
			{
				// Send it to back
				m_ZOrder.erase(m_ZOrder.begin());
				m_ZOrder.push_back(m_hWndCurActive);
			}
			else
			{
				// Bring the last one to top
				HWND hWndNewActive = m_ZOrder.back();
				m_ZOrder.pop_back();
				m_ZOrder.insert(m_ZOrder.begin(), hWndNewActive);
			}
			// Then activate the new one
			this->SetActiveChild(m_ZOrder[0]);
		}
		break;
	case WM_MDISETMENU:
		blHandled = TRUE;
		lResult = DefWindowProc(uMsg, wParam, NULL);
		ClearMenu();
		m_hSubMenu = (HMENU) lParam;
		m_iOriginalMenuItemCount = (m_hSubMenu)? GetMenuItemCount(m_hSubMenu) : 0;
		break;
	case WM_MDIREFRESHMENU:
		blHandled = TRUE;
		lResult = DefWindowProc(uMsg, wParam, lParam);
		RefreshMenu();
		break;
	case WM_SETTEXT:
		{
			HWND hWndChild = (HWND) wParam;
			Pane* pPane = NULL;

			if(clientViewPaneMap.Lookup(hWndChild, pPane))
			{
				blHandled = TRUE;
				lResult = TRUE;

				TabControlItem* pItem = pPane->get(hWndChild);
				pItem->SetText((LPCTSTR) lParam);
				pPane->redrawTabControl();
				RefreshMenu();
			}
		}
		break;
	}

	if(FALSE == blHandled)
	{
		blHandled = __super::ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult, dwMsgMapID);
	}

	return blHandled;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -