📄 oledragdroptabctrl.h
字号:
#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 + -