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

📄 oledragdroptabctrl.h

📁 一个使用wtl写的完整的多窗口浏览器
💻 H
📖 第 1 页 / 共 2 页
字号:
#pragma once
////////////////////////////////////////////////////////////////////////////
// MTL Version 0.10
// Copyright (C) 2001 MB<mb2@geocities.co.jp>
// All rights unreserved.
//
// This file is a part of Mb Template Library.
// The code and information is *NOT* provided "as-is" without
// warranty of any kind, either expressed or implied.
//
// TabCtrl.h: Last updated: February 12, 2001
/////////////////////////////////////////////////////////////////////////////
#include <vector>
#include "TabCtrl.h"

namespace MTL
{

// for debug
#ifdef _DEBUG
	const bool _Mtl_DragDrop_TabCtrl2_traceOn = false;
	#define DDTCTRACE if (_Mtl_DragDrop_TabCtrl2_traceOn) ATLTRACE
#else
	#define DDTCTRACE
#endif

template <class T>
class COleDragDropTabCtrl :
	public CTabCtrl2Impl<T>,
	public IDropTargetImpl<T>,
	public IDropSourceImpl<T>
{
public:
	DECLARE_WND_CLASS_EX(_T("Mtl_OleDragDrop_TabCtrl"), CS_DBLCLKS, COLOR_BTNFACE)// don't forget CS_DBLCLKS

// Data members
	CRect m_rcInvalidateOnDrawingInsertionEdge;
	bool m_bDragFromItself;
	CSimpleArray<int> m_arrCurDragItems;

// Ctor
	COleDragDropTabCtrl() : m_bDragFromItself(false)
	{
		m_rcInvalidateOnDrawingInsertionEdge.SetRectEmpty();
	}

// Overridables
	bool OnNewTabCtrlItems(int nInsertIndex, CSimpleArray<CTabCtrlItem>& items, IDataObject* pDataObject, DROPEFFECT& dropEffect)
	{
		return false;
	}
	bool OnDropTabCtrlItem(int nIndex, IDataObject* pDataObject, DROPEFFECT& dropEffect)
	{// if return true, delete src items considering ctrl key
		return true;
	}
	void OnDeleteItemDrag(int nIndex)
	{
	}
	HRESULT OnGetTabCtrlDataObject(CSimpleArray<int> arrIndex, IDataObject** ppDataObject)
	{
		ATLASSERT(ppDataObject != NULL);
		*ppDataObject = NULL;
		return E_NOTIMPL;
	}

// Mothods
	enum _hitTestFlag { htInsetLeft, htInsetRight, htItem, htSeparator, htOutside, htWhole };

	int HitTestOnDragging(_hitTestFlag& flag, CPoint point)
	{
		// inside of insets
		bool bLeft = false;
		int nIndex = _HitTestSideInset(point, s_nScrollInset, &bLeft);
		if (nIndex != -1) {
			flag = bLeft ? htInsetLeft : htInsetRight;
			return nIndex;
		}

		// inside of separator
		if ((nIndex = _HitTestSeparator(point, s_nScrollInset)) != -1) {
			flag = htSeparator;
			return nIndex;
		}

		// inside of the item rect
		if ((nIndex = HitTest(point)) != -1) {// hit test for item rect
			flag = htItem;
			return nIndex;
		}

		// out side of items
		flag = htOutside;
		return -1;
	}

// Message map and handlers
	BEGIN_MSG_MAP(COleDragDropTabCtrl<T>)
		MESSAGE_HANDLER(WM_CREATE, OnCreate)
		MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
		MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
		MESSAGE_HANDLER(WM_RBUTTONDOWN, OnRButtonDown)
		CHAIN_MSG_MAP(CTabCtrl2Impl<T>)
	END_MSG_MAP()

	LRESULT OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		DDTCTRACE("COleDragDropTabCtrl::OnLButtonDown\n");
		POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
		
		if (wParam & MK_CONTROL) {
			bHandled = FALSE;
			return 0;
		}

		int nIndex = HitTest(pt);
		if (nIndex != -1) {
			_DoDragDrop(pt, (UINT)wParam, nIndex, true);
		}

		return 0;
	}

	LRESULT OnRButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		DDTCTRACE("COleDragDropTabCtrl::OnRButtonDown\n");
		POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };

		if (wParam & MK_CONTROL) {
			bHandled = FALSE;
			return 0;
		}

		int nIndex = HitTest(pt);
		if (nIndex != -1) {
			_DoDragDrop(pt, (UINT)wParam, nIndex, false);
		}

		return 0;
	}

	LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		bHandled = FALSE;

		ATLASSERT(::IsWindow(m_hWnd));
		bool bReg = RegisterDragDrop();
		ATLASSERT(bReg == true);
		return 0;
	}

	LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
		bHandled = FALSE;
		RevokeDragDrop();
		return 0;
	}

// Overrides
	bool OnScroll(UINT nScrollCode, UINT nPos, bool bDoScroll = true)
	{
		DDTCTRACE("COleDragDropTabCtrl::OnScroll\n");
		
		bool bResult = false;
		if (!m_wndUpDown.IsWindowVisible())
			return bResult;

		if (LOBYTE(nScrollCode) == SB_LINEUP) {
			if (bDoScroll)
				bResult = ScrollItem(false);
			else
				bResult = CanScrollItem(false);

		}
		else if (LOBYTE(nScrollCode) == SB_LINEDOWN) {
			if (bDoScroll)
				bResult = ScrollItem(true);
			else
				bResult = CanScrollItem(true);
		}

		return bResult;
	}
	DROPEFFECT OnDragOver(IDataObject* pDataObject, DWORD dwKeyState, CPoint point, DROPEFFECT dropOkEffect)
	{
		_hitTestFlag flag;
		int nIndex = HitTestOnDragging(flag, point);
		_DrawInsertionEdge(flag, nIndex);

		if (flag == htItem && _IsSameIndexDropped(nIndex))
			return DROPEFFECT_NONE;

		if (flag == htItem && m_bDragFromItself && m_arrCurDragItems.GetSize() > 1)
			return DROPEFFECT_NONE;

		if (!m_bDragFromItself)
			return _MtlStandardDropEffect(dwKeyState) | _MtlFollowDropEffect(dropOkEffect) | DROPEFFECT_COPY;
	
		return _MtlStandardDropEffect(dwKeyState);
	}
	DROPEFFECT OnDrop(IDataObject* pDataObject,	DROPEFFECT dropEffect,
		DROPEFFECT dropEffectList, CPoint point)
	{
		_ClearInsertionEdge();

		T* pT = static_cast<T*>(this);
		CSimpleArray<CTabCtrlItem> arrItems;

		_hitTestFlag flag;
		int nIndex = HitTestOnDragging(flag, point);

		if (flag == htInsetLeft) {
			if (m_bDragFromItself && (dropEffect & DROPEFFECT_MOVE)) {// just move items
				MoveItems(nIndex, m_arrCurDragItems);
			}
			else {
				pT->OnNewTabCtrlItems(nIndex, arrItems, pDataObject, dropEffect);
				for (int i = 0; i < arrItems.GetSize(); ++i)
					InsertItem(nIndex, arrItems[i]);
			}
		}
		else if (flag == htInsetRight) {
			if (m_bDragFromItself && (dropEffect & DROPEFFECT_MOVE)) {// just move items
				MoveItems(nIndex + 1, m_arrCurDragItems);
			}
			else {
				pT->OnNewTabCtrlItems(nIndex + 1, arrItems, pDataObject, dropEffect);
				for (int i = 0; i < arrItems.GetSize(); ++i)
					InsertItem(nIndex + 1, arrItems[i]);
			}
		}
		else if (flag == htItem && !_IsSameIndexDropped(nIndex)) {
			DROPEFFECT dropEffectPrev = dropEffect;
			bool bDelSrc = pT->OnDropTabCtrlItem(nIndex, pDataObject, dropEffect);

			if (bDelSrc && m_bDragFromItself && (dropEffectPrev & DROPEFFECT_MOVE)) {// just move items
				// do nothing
				for (int i = 0; i < m_arrCurDragItems.GetSize(); ++i)
					pT->OnDeleteItemDrag(m_arrCurDragItems[i]);
				DeleteItems(m_arrCurDragItems);
			}
		}
		else if (flag == htSeparator) {
			if (m_bDragFromItself && (dropEffect & DROPEFFECT_MOVE)) {// just move items
				MoveItems(nIndex + 1, m_arrCurDragItems);
			}
			else {
				pT->OnNewTabCtrlItems(nIndex + 1, arrItems, pDataObject, dropEffect);
				for (int i = 0; i < arrItems.GetSize(); ++i)
					InsertItem(nIndex + 1, arrItems[i]);
			}
		}
		else if (flag == htOutside) {
			if (m_bDragFromItself && (dropEffect & DROPEFFECT_MOVE)) {// just move items to tail
				MoveItems(GetItemCount(), m_arrCurDragItems);
			}
			else {
				pT->OnNewTabCtrlItems(GetItemCount(), arrItems, pDataObject, dropEffect);
				for (int i = 0; i < arrItems.GetSize(); ++i)
					AddItem(arrItems[i]);
			}
		}

		return dropEffect;
	}

	void OnDragLeave()

⌨️ 快捷键说明

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