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

📄 tabbedmdi.h

📁 These listed libraries are written in WTL. But it s really hard to mix both MFC & WTL together. Obvi
💻 H
📖 第 1 页 / 共 5 页
字号:
	}
};

template< class TTabCtrl >
class CMDITabOwner :
	public CMDITabOwnerImpl<CMDITabOwner<TTabCtrl>, TTabCtrl>
{
};

/////////////////////////////////////////////////////////////////////////////
//
// CTabbedMDIClient
//
/////////////////////////////////////////////////////////////////////////////

template< class TTabCtrl = CDotNetTabCtrl<CTabViewTabItem>, class TTabOwner = CMDITabOwner<TTabCtrl> >
class CTabbedMDIClient : public ATL::CWindowImpl<CTabbedMDIClient<TTabCtrl, TTabOwner>, ATL::CWindow>
{
public:
	// Expose the type of tab control and tab owner
	typedef typename TTabCtrl TTabCtrl;
	typedef typename TTabOwner TTabOwner;

protected:
	typedef ATL::CWindowImpl<CTabbedMDIClient, ATL::CWindow> baseClass;
	typedef CTabbedMDIClient< TTabCtrl, TTabOwner > thisClass;

// Member variables
protected:
	HWND m_hWndTabOwnerParent;
	TTabOwner m_MdiTabOwner;
	BOOL m_bUseMDIChildIcon;
	bool m_bSubclassed;
	bool m_bDrawFlat;

// Constructors
public:
	CTabbedMDIClient() :
		m_hWndTabOwnerParent(NULL),
		m_bUseMDIChildIcon(FALSE),
		m_bSubclassed(false),
		m_bDrawFlat(false)
	{
		ATLASSERT(UWM_MDICHILDACTIVATIONCHANGE != 0 && "The TabbedMDI Messages didn't get registered properly");
		if(m_bDrawFlat)
		{
			m_MdiTabOwner.ModifyTabStyles(0,CTCS_FLATEDGE);
		}
	}

	virtual ~CTabbedMDIClient()
	{
		if(this->IsWindow() && m_bSubclassed)
		{
			this->UnsubclassWindow(TRUE);
		}
	}

// Methods
public:
	void SetTabOwnerParent(HWND hWndTabOwnerParent)
	{
		m_hWndTabOwnerParent = hWndTabOwnerParent;
	}

	HWND GetTabOwnerParent(void) const
	{
		return m_hWndTabOwnerParent;
	}

	TTabOwner& GetTabOwner(void)
	{
		return m_MdiTabOwner;
	}

	void UseMDIChildIcon(BOOL bUseMDIChildIcon = TRUE)
	{
		m_bUseMDIChildIcon = bUseMDIChildIcon;
	}

	void HideMDITabsWhenMDIChildNotMaximized(BOOL bHideMDITabsWhenMDIChildNotMaximized = TRUE)
	{
		m_MdiTabOwner.HideMDITabsWhenMDIChildNotMaximized(bHideMDITabsWhenMDIChildNotMaximized);
	}

	void SetDrawFlat(bool bDrawFlat = true)
	{
		if(m_bDrawFlat!=bDrawFlat)
		{
			//ATLASSERT((m_hWnd==NULL) && "Please call SetDrawFlat before CreateWindow or SubclassWindow");
			m_bDrawFlat = bDrawFlat;
			if(m_bDrawFlat)
			{
				m_MdiTabOwner.ModifyTabStyles(0,CTCS_FLATEDGE);
			}
			else
			{
				m_MdiTabOwner.ModifyTabStyles(CTCS_FLATEDGE,0);
			}
		}
	}

	bool GetDrawFlat(void) const
	{
		return m_bDrawFlat;
	}

#ifdef __TabbedMDISave_h__

	bool SaveAllModified(bool canPrompt, bool canCancel) const
	{
		if(canPrompt)
		{
			// Prompt using our "Save modified" dialog
			ATL::CComPtr<ITabbedMDIChildModifiedList> modifiedItems;
			this->FindModified(&modifiedItems);
			if(modifiedItems)
			{
				long modifiedCount = 0;
				modifiedItems->get_Count(&modifiedCount);
				if(modifiedCount > 0)
				{
					CSaveModifiedItemsDialog dialog(modifiedItems, canCancel);

					INT_PTR response = dialog.DoModal();
					if(response == IDYES)
					{
						// The dialog will update the list and remove
						// any items that the user unchecked

						this->SaveModified(modifiedItems);
					}
					else if(response == IDCANCEL)
					{
						// Not safe to close
						return false;
					}
				}
			}
		}
		else
		{
			// Save all files, but don't ask permission.

			HWND hWndChild = ::GetTopWindow(m_hWnd);
			while(hWndChild != NULL)
			{
				::SendMessage(hWndChild, UWM_MDICHILDSAVEMODIFIED, 0, 0);
				hWndChild = ::GetNextWindow(hWndChild, GW_HWNDNEXT);
			}
		}

		// Safe to terminate the application if desired
		return true;
	}

	HRESULT FindModified(ITabbedMDIChildModifiedList** modifiedItemsOut) const
	{
		WTL::CWaitCursor	waitCursor;

		if(modifiedItemsOut == NULL)
		{
			return E_POINTER;
		}
		*modifiedItemsOut = NULL;

		long modifiedCount = 0;

		HRESULT hr = S_OK;

		// Build up a list of all the modified documents
		ATL::CComPtr<ITabbedMDIChildModifiedList> modifiedItems;
		::CreateTabbedMDIChildModifiedList(&modifiedItems);

		if(modifiedItems)
		{
			HWND hWndChild = ::GetTopWindow(m_hWnd);
			while(hWndChild != NULL)
			{
				_CSTRING_NS::CString windowText;
				int cchWindowText = ::GetWindowTextLength(hWndChild);
				LPTSTR pszText = windowText.GetBuffer(cchWindowText+1);
				cchWindowText = ::GetWindowText(hWndChild, pszText, cchWindowText+1);
				windowText.ReleaseBuffer(cchWindowText);

				CComBSTR defaultName(windowText);

				ATL::CComPtr<ITabbedMDIChildModifiedItem> modifiedItem;
				::CreateTabbedMDIChildModifiedItem(hWndChild,
					defaultName, defaultName, defaultName, 0, NULL, &modifiedItem);

				BOOL bIsModified = (BOOL)::SendMessage(hWndChild, UWM_MDICHILDISMODIFIED, 0, (LPARAM)modifiedItem.p);
				if(bIsModified)
				{
					++modifiedCount;

					modifiedItems->Insert(-1, modifiedItem);
				}

				hWndChild = ::GetNextWindow(hWndChild, GW_HWNDNEXT);
			}

			if(modifiedCount > 0)
			{
				modifiedItems.CopyTo(modifiedItemsOut);
			}
		}

		return hr;
	}

	HRESULT SaveModified(ITabbedMDIChildModifiedList* modifiedItems) const
	{
		if(modifiedItems == NULL)
		{
			return E_INVALIDARG;
		}

		WTL::CWaitCursor waitCursor;

		HRESULT hr = S_OK;

		long count = 0;
		modifiedItems->get_Count(&count);
		for(long i=0; i<count; ++i)
		{
			ATL::CComPtr<ITabbedMDIChildModifiedItem> modifiedItem;
			modifiedItems->get_Item(i, &modifiedItem);
			if(modifiedItem)
			{
				HWND hWnd = NULL;
				modifiedItem->get_Window(&hWnd);
				if(hWnd && ::IsWindow(hWnd))
				{
					::SendMessage(hWnd, UWM_MDICHILDSAVEMODIFIED, 0, (LPARAM)modifiedItem.p);
				}

				// Important!  If an item has sub-items, the "top-level"
				//  item is responsible for ensuring that modifications
				//  are saved.
			}
		}

		return hr;
	}
	
#endif // __TabbedMDISave_h__

	void CloseAll(bool bPreferNoPrompt = false) const
	{
		HWND hWndChild = ::GetTopWindow(m_hWnd);
		while(hWndChild != NULL)
		{
			HWND hWndClose = hWndChild;
			hWndChild = ::GetNextWindow(hWndChild, GW_HWNDNEXT);

			if(bPreferNoPrompt)
			{
				::SendMessage(hWndClose, UWM_MDICHILDCLOSEWITHNOPROMPT, 0, 0L);
			}

			if(::IsWindow(hWndClose))
			{
				// The window doesn't support UWM_MDICHILDCLOSEWITHNOPROMPT
				// or the caller didn't want to close with no prompt,
				// so we'll send a close message it should understand.
				::SendMessage(hWndClose, WM_SYSCOMMAND, SC_CLOSE, 0L);
			}
		}
	}

	BOOL SubclassWindow(HWND hWnd)
	{
		BOOL bSuccess = baseClass::SubclassWindow(hWnd);

		m_bSubclassed = true;

		this->InitTabs();

		m_MdiTabOwner.CalcTabAreaHeight();

		return bSuccess;
	}

	HWND UnsubclassWindow(BOOL bForce = FALSE)
	{
		m_bSubclassed = false;

		return baseClass::UnsubclassWindow(bForce);
	}

protected:
	void InitTabs()
	{
		if( !m_MdiTabOwner.IsWindow() )
		{
			if(m_hWndTabOwnerParent == NULL)
			{
				// If the tab owner's parent is not specified,
				// have the tabs as a sibling
				m_hWndTabOwnerParent = this->GetParent();
			}

			m_MdiTabOwner.Create(
				m_hWndTabOwnerParent, 
				rcDefault, NULL,
				WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN // start out not visible
				);

			m_MdiTabOwner.SetMDIClient(m_hWnd);
		}
	}

// Message Handling
public:
	DECLARE_WND_SUPERCLASS(_T("TabbedMDIClient"), _T("MDIClient"))

	BEGIN_MSG_MAP(CTabbedMDIClient)
		MESSAGE_HANDLER(WM_CREATE, OnCreate)
		MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
		MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange)
		MESSAGE_HANDLER(WM_WINDOWPOSCHANGING, OnWindowPosChanging)
		MESSAGE_HANDLER(WM_NCPAINT, OnNcPaint)
		//MESSAGE_HANDLER(WM_MDICREATE, OnMDICreate)
		MESSAGE_HANDLER(WM_MDIDESTROY, OnMDIDestroy)
		MESSAGE_HANDLER(UWM_MDICHILDACTIVATIONCHANGE, OnChildActivationChange)
		MESSAGE_HANDLER(UWM_MDICHILDTABTEXTCHANGE, OnChildTabTextChange)
		MESSAGE_HANDLER(UWM_MDICHILDTABTOOLTIPCHANGE, OnChildTabToolTipChange)
		MESSAGE_HANDLER(UWM_MDICHILDMAXIMIZED, OnChildMaximized)
		MESSAGE_HANDLER(UWM_MDICHILDUNMAXIMIZED, OnChildUnMaximized)
	END_MSG_MAP()

	LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		// "base::OnCreate()"
		LRESULT lRet = this->DefWindowProc(uMsg, wParam, lParam);
		bHandled = TRUE;
		if(lRet == -1)
		{
			return -1;
		}

		this->InitTabs();

		m_MdiTabOwner.CalcTabAreaHeight();

		return lRet;
	}

	LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
		// Say that we didn't handle it so that anyone else
		//  interested gets to handle the message
		bHandled = FALSE;
		return 0;
	}

	LRESULT OnSettingChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		// Be sure tab gets message before we recalculate the tab area height
		//  so that it can adjust its font metrics first.
		// NOTE: This causes the tab to get the WM_SETTINGCHANGE message twice,
		//  but that's OK.
		m_MdiTabOwner.GetTabCtrl().SendMessage(uMsg, wParam, lParam);

		m_MdiTabOwner.CalcTabAreaHeight();

		bHandled = FALSE;
		return 0;
	}

	LRESULT OnWindowPosChanging(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		LPWINDOWPOS pWinPos = reinterpret_cast<LPWINDOWPOS>(lParam);
		if(pWinPos)
		{
			if( m_MdiTabOwner.IsWindow() )
			{
				//ATLTRACE(_T("Resizing MDI tab and MDI client\n"));
				int nTabAreaHeight = (m_MdiTabOwner.IsWindowVisible()) ? m_MdiTabOwner.GetTabAreaHeight() : 0;

				TTabCtrl& TabCtrl = m_MdiTabOwner.GetTabCtrl();
				DWORD dwStyle = TabCtrl.GetStyle();
				if(CTCS_BOTTOM == (dwStyle & CTCS_BOTTOM))
				{
					m_MdiTabOwner.SetWindowPos(
						NULL,
						pWinPos->x, pWinPos->y + (pWinPos->cy - nTabAreaHeight),
						pWinPos->cx, nTabAreaHeight,
						(pWinPos->flags & SWP_NOMOVE) | (pWinPos->flags & SWP_NOSIZE) | SWP_NOZORDER | SWP_NOACTIVATE);

					if((pWinPos->flags & SWP_NOSIZE) == 0)
					{
						pWinPos->cy -= nTabAreaHeight;
					}
				}
				else
				{
					m_MdiTabOwner.SetWindowPos(
						NULL,
						pWinPos->x, pWinPos->y,
						pWinPos->cx, nTabAreaHeight,
						(pWinPos->flags & SWP_NOMOVE) | (pWinPos->flags & SWP_NOSIZE) | SWP_NOZORDER | SWP_NOACTIVATE);

					if((pWinPos->flags & SWP_NOMOVE) == 0)
					{
						pWinPos->y += nTabAreaHeight;

⌨️ 快捷键说明

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