|
OnStartDrag и свой компонет
#33872382
Ссылка:
Ссылка на сообщение:
Ссылка с названием темы:
Ссылка на профиль пользователя:
|
Участник
Откуда: Омикрон Персей 8
Сообщения: 7 682
|
|
в одном из своих проектов я реализовывал такое, вот код (ничего не правил)
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115.
// QListCtrl.cpp : implementation file
//
#include "stdafx.h"
#include "qlistctrl.h"
#define QLC_BEGINDRAG (WM_USER + 4000 )
#define QLC_ENDDRAG (WM_USER + 4001 )
// CQListCtrl
IMPLEMENT_DYNAMIC(CQListCtrl, CListCtrl)
CQListCtrl::CQListCtrl()
{
bAllowDrag = FALSE;//-----------------------перемещать запрещено
bDrag = FALSE;
m_drg = NULL;
}
CQListCtrl::~CQListCtrl(){}
BEGIN_MESSAGE_MAP(CQListCtrl, CListCtrl)
//{{AFX_MSG_MAP(CQListCtrl)
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
ON_NOTIFY_REFLECT(LVN_BEGINDRAG, OnBeginDrag)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
// CQListCtrl message handlers
void CQListCtrl::OnBeginDrag(NMHDR* pNMHDR, LRESULT* pResult)
{
//---------------------------начинаем перетаскивать item
//ИНИЦИАЛИЗАЦИЯ*****************************************************
NM_LISTVIEW *pnmListView = (NM_LISTVIEW*) pNMHDR;
CPoint pt, ptAction, ptImage;
HWND hWnd;
//РЕАЛИЗАЦИЯ********************************************************
//--перед перетаскиванием запросим разрешения на это у главной проги
hWnd = this->GetParent()->GetSafeHwnd();
ASSERT(hWnd != NULL);
::SendMessage(hWnd, QLC_BEGINDRAG, 0 , 0 );
if(!bAllowDrag)
return;//---------------------------------------------нельзя
// GetCursorPos(&pt); ScreenToClient(&pt);
ASSERT(!bDrag);//--------------------------уже не перетаскиваем?
bDrag = TRUE;
m_hDrag = pnmListView->iItem;
ptAction = pnmListView->ptAction;
GetItemPosition(m_hDrag, &pt);
GetOrigin(&m_ptOrigin);
ASSERT(m_drg == NULL);
m_drg = CreateDragImage(m_hDrag, &ptImage);//массив картинок для draging'а
m_sizeDelta = ptAction - ptImage; // difference between cursor pos and image pos
m_ptHotSpot = ptAction - pt + m_ptOrigin; // calculate hotspot for the cursor
m_drg->DragShowNolock(TRUE);
m_drg->SetDragCursorImage(0, m_ptHotSpot);
m_drg->BeginDrag(0, CPoint(0,0));
ptAction -= m_sizeDelta;
m_drg->DragEnter(this, ptAction);
m_drg->DragMove(ptAction);
SetCapture();
}
void CQListCtrl::OnMouseMove(UINT nFlags, CPoint point)
{
//ИНИЦИАЛИЗАЦИЯ*****************************************************
int hItem;
LV_ITEM lvitem;
//РЕАЛИЗАЦИЯ********************************************************
ASSERT(m_hWnd != NULL);
long lStyle = GetWindowLong(m_hWnd, GWL_STYLE);
lStyle &= LVS_TYPEMASK; // drag will do different things in list and report mode
if(bDrag)
{
ASSERT(m_drg != NULL);
m_drg->DragMove(point - m_sizeDelta);
if ((hItem = HitTest(point)) != -1)
{
m_hDrop = hItem;
m_drg->DragLeave(this); // unlock the window and hide drag image
if (lStyle == LVS_REPORT || lStyle == LVS_LIST)
{
lvitem.iItem = hItem;
lvitem.iSubItem = 0;
lvitem.mask = LVIF_STATE;
lvitem.stateMask = LVIS_DROPHILITED; // highlight the drop target
SetItem(&lvitem);
}
}
point -= m_sizeDelta;
m_drg->DragEnter(this, point);
}
CListCtrl::OnMouseMove(nFlags, point);
}
void CQListCtrl::OnLButtonUp(UINT nFlags, CPoint point)
{
//РЕАЛИЗАЦИЯ********************************************************
if(bDrag)//-если тащим, проверим указатель на массив изображений
{
bAllowDrag = bDrag = FALSE;
ASSERT(m_drg != NULL);
m_drg->DragLeave(this);
m_drg->EndDrag();
delete m_drg;
m_drg = NULL;
//--возвращаем приложению два item'а для того чтобы решился вопрос о
//----------------------------------перемещении и завершаем dragging
HWND hWnd;
hWnd = this->GetParent()->GetSafeHwnd();
ASSERT(hWnd != NULL);
::SendMessage(hWnd, QLC_ENDDRAG, 0 , 0 );
ReleaseCapture();
}
}
header
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42.
#pragma once
// CQListCtrl
class AFX_EXT_CLASS CQListCtrl : public CListCtrl
{
DECLARE_DYNAMIC(CQListCtrl)
private:
BOOL bDrag;//TRUE----------------идет процесс перемещения
CImageList* m_drg;//--указатель на массив картинок при draging'е
public:
int m_hDrag;//-------------------------перемещаемый item
int m_hDrop;//----------item на который опускается hDrag
BOOL bAllowDrag;//TRUE --------- перетаскивание разрешено
CPoint m_ptHotSpot;
CPoint m_ptOrigin;
CSize m_sizeDelta;
public:
CQListCtrl();
virtual ~CQListCtrl();
#ifndef _DEBUG
void* operator new(size_t nSize)
{
void* p = malloc(nSize);
return p;
}
void operator delete(void *p){free(p);}
#endif
protected:
//{{AFX_CQListCtrl
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnBeginDrag(NMHDR* pNMHDR, LRESULT* pResult);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
--------------------------------------------------------------
|
|
|