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

📄 tabbedmdi.h

📁 一款最完整的工业组态软源代码
💻 H
📖 第 1 页 / 共 5 页
字号:
public:
	// Either call the normal "CreateMDIClient"

	HWND CreateMDIClient(HMENU hWindowMenu = NULL, UINT nID = ATL_IDW_CLIENT, UINT nFirstChildID = ATL_IDM_FIRST_MDICHILD)
	{
		HWND hWndClient = baseClass::CreateMDIClient(hWindowMenu, nID, nFirstChildID);

		this->SubclassMDIClient();

		return hWndClient;
	}

	// Or, after creating the client, call SubclassMDIClient
	BOOL SubclassMDIClient()
	{
		ATLASSERT(m_hWndMDIClient && ::IsWindow(m_hWndMDIClient));

		return m_tabbedClient.SubclassWindow(m_hWndMDIClient);
	}

	void SetTabOwnerParent(HWND hWndTabOwnerParent)
	{
		m_tabbedClient.SetTabOwnerParent(hWndTabOwnerParent);
	}

	HWND GetTabOwnerParent() const
	{
		return m_tabbedClient.GetTabOwnerParent();
	}

// Message Handling
public:
	typedef CTabbedMDIFrameWindowImpl< T, TBase, TWinTraits >	thisClass;
	typedef CMDIFrameWindowImpl<T, TBase, TWinTraits >	baseClass;
	BEGIN_MSG_MAP(thisClass)
		CHAIN_MSG_MAP(baseClass)
	END_MSG_MAP()
};

template <class T, class TBase = CMDIWindow, class TWinTraits = CMDIChildWinTraits>
class ATL_NO_VTABLE CTabbedMDIChildWindowImpl : public CMDIChildWindowImpl<T, TBase, TWinTraits>
{
// Member variables
protected:
	bool m_bMaximized;

// Constructors
public:
	CTabbedMDIChildWindowImpl() :
		m_bMaximized(false)
	{
		ATLASSERT(UWM_MDICHILDACTIVATIONCHANGE != 0 && "The TabbedMDI Messages didn't get registered properly");
	}

// Overrides ofCMDIChildWindowImpl
public:

	// NOTE: CreateEx also calls this (through T*)
	HWND Create(HWND hWndParent, _U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
			DWORD dwStyle = 0U, DWORD dwExStyle = 0U,
			UINT nMenuID = 0U, LPVOID lpCreateParam = NULL)
	{
		// NOTE: hWndParent is going to become m_hWndMDIClient
		//  in CMDIChildWindowImpl::Create
		ATLASSERT(::IsWindow(hWndParent));

		BOOL bMaximizeNewChild = (WS_MAXIMIZE == (T::GetWndStyle(dwStyle) & WS_MAXIMIZE));
		if(bMaximizeNewChild == FALSE)
		{
			// If WS_MAXIMIZE wasn't requested, check if the currently
			//  active MDI child (if there is one) is maximized.  If so,
			//  maximize the new child window to match.
			::SendMessage(hWndParent, WM_MDIGETACTIVE, 0, (LPARAM)&bMaximizeNewChild);
		}

		if(bMaximizeNewChild == TRUE)
		{
			::SendMessage(hWndParent, WM_SETREDRAW, FALSE, 0);

			// We'll ShowWindow(SW_SHOWMAXIMIZED) instead of using
			//  WS_MAXIMIZE (which would cause visual anomolies in some cases)
			dwStyle = (T::GetWndStyle(dwStyle) & ~WS_MAXIMIZE);
		}


		HWND hWnd = baseClass::Create(hWndParent, rect, szWindowName, dwStyle, dwExStyle, nMenuID, lpCreateParam);

		if(bMaximizeNewChild == TRUE)
		{
			::ShowWindow(hWnd, SW_SHOWMAXIMIZED);

			::SendMessage(hWndParent, WM_SETREDRAW, TRUE, 0);
			::RedrawWindow(hWndParent, NULL, NULL,
				//A little more forceful if necessary: RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN);
				RDW_INVALIDATE | RDW_ALLCHILDREN);
		}

		if(hWnd != NULL && ::IsWindow(m_hWnd) && !::IsChild(hWnd, ::GetFocus()))
			::SetFocus(hWnd);

		return hWnd;
	}

// Methods
public:
	void SetTitle(LPCTSTR sNewTitle, BOOL bUpdateTabText = TRUE)
	{
		this->SetWindowText(sNewTitle);

		if(bUpdateTabText)
		{
			::SendMessage(m_hWndMDIClient, UWM_MDICHILDTABTEXTCHANGE, (WPARAM)m_hWnd, (LPARAM)sNewTitle);
		}
	}

	void SetTabText(LPCTSTR sNewTabText)
	{
		::SendMessage(m_hWndMDIClient, UWM_MDICHILDTABTEXTCHANGE, (WPARAM)m_hWnd, (LPARAM)sNewTabText);
	}

	void SetTabToolTip(LPCTSTR sNewToolTip)
	{
		::SendMessage(m_hWndMDIClient, UWM_MDICHILDTABTOOLTIPCHANGE, (WPARAM)m_hWnd, (LPARAM)sNewToolTip);
	}

// Message Handling
public:

	typedef CTabbedMDIChildWindowImpl< T, TBase, TWinTraits >	thisClass;
	typedef CMDIChildWindowImpl<T, TBase, TWinTraits >	baseClass;
	BEGIN_MSG_MAP(thisClass)
		MESSAGE_HANDLER(WM_MDIACTIVATE, OnMDIActivate)
		MESSAGE_HANDLER(WM_SETTEXT, OnSetText)
		MESSAGE_HANDLER(WM_SIZE, OnSize)
		MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
		MESSAGE_HANDLER(WM_MOUSEACTIVATE, OnMouseActivate)
		MESSAGE_HANDLER(UWM_MDICHILDSHOWTABCONTEXTMENU, OnShowTabContextMenu)
		MESSAGE_HANDLER(UWM_MDICHILDSAVEMODIFIED, OnSaveModified)
		MESSAGE_HANDLER(UWM_MDICHILDCLOSEWITHNOPROMPT, OnCloseWithNoPrompt)
		CHAIN_MSG_MAP(baseClass)
	END_MSG_MAP()

	LRESULT OnMDIActivate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
	{
		//HWND hWndDeactivating = (HWND)wParam;
		HWND hWndActivating = (HWND)lParam;

		if(m_hWnd == hWndActivating)
		{
			::SendMessage(m_hWndMDIClient, UWM_MDICHILDACTIVATIONCHANGE, (WPARAM)m_hWnd, 0);
		}

		bHandled = FALSE;
		return 0;
	}

	LRESULT OnSetText(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
		//::SendMessage(m_hWndMDIClient, UWM_MDICHILDTABTEXTCHANGE, (WPARAM)m_hWnd, lParam);

		bHandled = FALSE;
		return 0;
	}

	LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		if(wParam == SIZE_MAXIMIZED && m_bMaximized == false)
		{
			m_bMaximized = true;
			::SendMessage(m_hWndMDIClient, UWM_MDICHILDMAXIMIZED, (WPARAM)m_hWnd, lParam);
		}
		else if(wParam != SIZE_MAXIMIZED && m_bMaximized == true)
		{
			m_bMaximized = false;
			::SendMessage(m_hWndMDIClient, UWM_MDICHILDUNMAXIMIZED, (WPARAM)m_hWnd, lParam);
		}

		bHandled = FALSE;
		return 0;
	}

	LRESULT OnMouseActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
	{
		LRESULT lRes = this->DefWindowProc(uMsg, wParam, lParam);
		if(lRes == MA_NOACTIVATE || lRes == MA_NOACTIVATEANDEAT)
			return lRes;   // frame does not want to activate

		// activate window if necessary
		HWND hWndActive = this->MDIGetActive();
		if(m_hWnd != hWndActive)
		{
			this->MDIActivate(m_hWnd);
		}

		return lRes;
	}

	LRESULT OnSetFocus(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
		// NOTE: ::IsWindowVisible(m_hWndClient) will be false if
		//  the frame is maximized.  So just use "IsWindow" instead.
		if(m_hWndClient != NULL && ::IsWindow(m_hWndClient))
		{
			::SetFocus(m_hWndClient);
		}

		bHandled = FALSE;
		return 1;
	}

	LRESULT OnShowTabContextMenu(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
	{
		bHandled = TRUE;

		// NOTE: Your deriving class doesn't have to do the context menu
		//  this way (show the system menu, use TPM_RETURNCMD, etc.)
		//  It can do whatever it wants.  This is just the "fall through"
		//  implementation if you don't want to specialize.

		// NOTE: The sender of the message has already handled the case
		//  when launching the context menu from the keyboard
		//  (translating -1,-1 into a usable position)

		// We use essentially the same code as CMDICommandBarCtrl::OnNcLButtonDown
		//  (for when it handles the menu for the maximized child when clicking
		//  on the document icon to the left of the menus).
		// NOTE: On Windows 2000 and 98 and later, we'll get bitmaps in the menu.
		//  Also note that when running on NT 4 or Win 95, CMDICommandBarCtrl::OnNcLButtonDown
		//  will fail to show the system menu at all because it doesn't like
		//  the real definition of TPM_VERPOSANIMATION.  To avoid that
		//  problem, we won't even try to use TPM_VERPOSANIMATION.
		CMenuHandle menu = this->GetSystemMenu(FALSE);

		UINT command = (UINT)menu.TrackPopupMenu(TPM_LEFTBUTTON | TPM_VERTICAL | TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD, 
			GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), m_hWnd);

		// See MSDN about "GetSystemMenu".  Returns codes greater than
		//  0xF000 (which happens to be SC_SIZE) are sent with WM_SYSCOMMAND
		if(command >= SC_SIZE)
		{
			::PostMessage(m_hWnd, WM_SYSCOMMAND, command, 0L);
		}
		else if(command != 0)
		{
			// Non SC_* commands don't work with WM_SYSCOMMAND.  We could handle
			// the situation here by using WM_COMMAND, but there's other places
			// where the "window menu" is dealt with that wouldn't have the same handling
			// (like CMDICommandBarCtrl::OnNcLButtonDown).  To help prevent
			// errors, do an assert to warn.  Instead of depending on this base
			// implementation, you should override handling UWM_MDICHILDSHOWTABCONTEXTMENU
			// in a derived class, and do your own context menu there.
			// See the "TabDemo" sample for an example.
			ATLASSERT(0 && 
				"You've tried to put a non SC_* command in the window menu.  "
				"Please override the default context menu handling, and use a custom menu.");
		}

		return 0;
	}

	LRESULT OnSaveModified(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
		// A derived class should handle this message.
		// Return non-zero if you want to "cancel"
		bHandled = FALSE;
		return 0;
	}

	LRESULT OnCloseWithNoPrompt(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		// When getting a real WM_CLOSE, you usually want to
		// prompt to save if there's been modifications, and
		// return TRUE to cancel.  However, this is here for
		// the cases when we need to close the window with no
		// prompt and no chance to cancel
		// (such as when we've already given the user the
		// chance to save the file, but they said no).
		return this->DefWindowProc(WM_CLOSE, 0, 0L);
	}
};


/////////////////////////////////////////////////////////////////////////////
//
// CMDITabOwner
//
/////////////////////////////////////////////////////////////////////////////

template< class T, class TTabCtrl >
class CMDITabOwnerImpl :
	public CWindowImpl<T>,
	public CCustomTabOwnerImpl<T, TTabCtrl>
{
public:
	// Expose the type of tab control
	typedef typename TTabCtrl TTabCtrl;

protected:
	typedef CMDITabOwnerImpl< T, TTabCtrl > thisClass;
	typedef CWindowImpl<T> baseClass;
	typedef CCustomTabOwnerImpl<T, TTabCtrl> customTabOwnerClass;

// Member variables
protected:
	HWND m_hWndMDIClient;
	DWORD m_nTabStyles;
	bool m_bKeepTabsHidden;

// Constructors
public:
	CMDITabOwnerImpl() :
		m_hWndMDIClient(NULL),
		m_nTabStyles(CTCS_TOOLTIPS | CTCS_BOLDSELECTEDTAB | CTCS_SCROLL | CTCS_CLOSEBUTTON | CTCS_DRAGREARRANGE),
		m_bKeepTabsHidden(false)
	{
		ATLASSERT(UWM_MDICHILDACTIVATIONCHANGE != 0 && "The TabbedMDI Messages didn't get registered properly");
	}

// Methods
public:
	void SetMDIClient(HWND hWndMDIClient)
	{
		m_hWndMDIClient = hWndMDIClient;
	}

	void SetTabStyles(DWORD nTabStyles)
	{
		m_nTabStyles = nTabStyles;
	}

	DWORD GetTabStyles(void) const
	{
		return m_nTabStyles;
	}

	void ModifyTabStyles(DWORD dwRemove, DWORD dwAdd)
	{
		DWORD dwNewStyle = (m_nTabStyles & ~dwRemove) | dwAdd;
		if(m_nTabStyles != dwNewStyle)
		{
			m_nTabStyles = dwNewStyle;
		}
	}

	void KeepTabsHidden(bool bKeepTabsHidden = true)
	{
		if(m_bKeepTabsHidden != bKeepTabsHidden)
		{
			m_bKeepTabsHidden = bKeepTabsHidden;
			this->CalcTabAreaHeight();

			if(m_bKeepTabsHidden)
			{
				this->OnRemoveLastTab();
			}
			else if(this->GetTabCtrl().GetItemCount() > 0)
			{
				this->OnAddFirstTab();
			}
		}
	}

// Message Handling
public:
	DECLARE_WND_CLASS_EX(_T("MdiTabOwner"), 0, COLOR_APPWORKSPACE)

	BEGIN_MSG_MAP(thisClass)
		MESSAGE_HANDLER(WM_CREATE, OnCreate)
		MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
		MESSAGE_HANDLER(WM_SIZE, OnSize)
		MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
		MESSAGE_HANDLER(WM_CONTEXTMENU, OnContextMenu)
		NOTIFY_CODE_HANDLER(NM_CLICK, OnClick)
		NOTIFY_CODE_HANDLER(CTCN_ACCEPTITEMDRAG, OnAcceptItemDrag)
		NOTIFY_CODE_HANDLER(CTCN_CANCELITEMDRAG, OnCancelItemDrag)
		NOTIFY_CODE_HANDLER(CTCN_DELETEITEM, OnDeleteItem)
		NOTIFY_CODE_HANDLER(CTCN_SELCHANGING, OnSelChanging)
		NOTIFY_CODE_HANDLER(CTCN_SELCHANGE, OnSelChange)
		NOTIFY_CODE_HANDLER(CTCN_CLOSE, OnTabClose)

		// NOTE: CCustomTabCtrl derived classes no longer
		//  need notifications reflected.
		// REFLECT_NOTIFICATIONS()
	END_MSG_MAP()

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

		CreateTabWindow(m_hWnd, rcDefault, m_nTabStyles);

		return 0;

⌨️ 快捷键说明

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