update for HEAD-2003091401
[reactos.git] / subsys / system / explorer / Seashell / SeaShellExt / UIImageDropTarget.cpp
1 //*******************************************************************************
2 // COPYRIGHT NOTES
3 // ---------------
4 // You may use this source code, compile or redistribute it as part of your application 
5 // for free. You cannot redistribute it as a part of a software development 
6 // library without the agreement of the author. If the sources are 
7 // distributed along with the application, you should leave the original 
8 // copyright notes in the source code without any changes.
9 // This code can be used WITHOUT ANY WARRANTIES at your own risk.
10 // 
11 // For the latest updates to this code, check this site:
12 // http://www.masmex.com 
13 // after Sept 2000
14 // 
15 // Copyright(C) 2000 Philip Oldaker <email: philip@masmex.com>
16 //*******************************************************************************
17
18 // IM_OleImageDropTarget.cpp : implementation file
19 //
20
21 #include "stdafx.h"
22 #include "UIDragImage.h"
23 #include "UIImageDropTarget.h"
24
25 #ifdef _DEBUG
26 #define new DEBUG_NEW
27 #undef THIS_FILE
28 static char THIS_FILE[] = __FILE__;
29 #endif
30
31 /////////////////////////////////////////////////////////////////////////////
32 // CUI_ImageDropTarget
33
34 CUI_ImageDropTarget::CUI_ImageDropTarget() : m_pImage(NULL),m_pWnd(NULL)
35 {       
36         m_nCFFormat = ::RegisterClipboardFormat(_T("APP_CF_DD_LISTCTRL_IMAGE"));
37         m_nImage = -1;
38 }
39
40 CUI_ImageDropTarget::~CUI_ImageDropTarget()
41 {
42 }
43
44
45 /////////////////////////////////////////////////
46 //
47 // For OLE drag and drop 
48 //
49 /////////////////////////////////////////////////
50 void CUI_ImageDropTarget::OnDragLeave( CWnd* pWnd)
51 {
52     if (m_pImage == NULL) 
53                 return;
54
55         // Erase the old drag image and delete the temporary widget.
56         CClientDC dc(GetImageWin(pWnd));
57     m_pImage->DrawDragImage (&dc,m_ptOldImage,m_ptItem);
58     delete m_pImage;
59     m_pImage = NULL;
60
61         COleDropTarget::OnDragLeave(pWnd);
62 }
63
64 DROPEFFECT CUI_ImageDropTarget::OnDragEnter( CWnd* pWnd, COleDataObject* pDataObject, DWORD dwKeyState, CPoint point )
65 {
66         DROPEFFECT dwEffect = COleDropTarget::OnDragEnter(pWnd,pDataObject,dwKeyState,point);
67     HGLOBAL hData = pDataObject->GetGlobalData(GetClipboardFormat());
68         if (hData == NULL)
69                 return dwEffect;
70     //
71     // Create a temporary image for drag imaging.
72     //
73     int *pData = (int*)::GlobalLock(hData);
74     int nType = *pData++;
75         int nSelected = *pData++;
76     DD_ImageData *pImageData = (DD_ImageData*)pData;
77         CPoint pt = pImageData->m_ptDrag;
78         int i;
79     switch (nType) 
80         {
81     case LVS_ICON: 
82         case LVS_SMALLICON:
83         case LVS_LIST:
84         case LVS_REPORT:
85         m_pImage = new CDragDropImage(nSelected,nType);
86                 for(i=0;i < nSelected;i++)
87                 {
88                         m_pImage->AddItem(&pImageData->m_rcItem,&pImageData->m_rcIcon);
89                         pImageData++;
90                 }
91         break;
92     default:
93                 ASSERT(0);
94                 // Just in case
95             ::GlobalUnlock(hData);
96         return DROPEFFECT_NONE;
97     }
98         // total item
99     CRect rcItem;
100         pData = (int*)pImageData;
101         rcItem.left = *pData++;
102         rcItem.right = *pData++;
103         rcItem.top = *pData++;
104         rcItem.bottom = *pData;
105     ::GlobalUnlock(hData);
106
107     //
108     // Begin dragging.
109     //
110         CClientDC dc(GetImageWin(pWnd));
111         pWnd->ClientToScreen(&point);
112         m_pWnd->ScreenToClient(&point);
113     dc.DPtoLP(&point);
114         m_ptItem = pt;
115
116     CPoint ptDrag (point.x, point.y);
117     m_ptOldImage.x = m_ptOldImage.y = -32000;
118     m_ptPrevPos = point;
119
120         return dwEffect;
121 }
122
123 DROPEFFECT CUI_ImageDropTarget::OnDragOver( CWnd* pWnd, COleDataObject* pDataObject, DWORD dwKeyState, CPoint point )
124 {
125         DROPEFFECT dwEffect = COleDropTarget::OnDragOver(pWnd,pDataObject,dwKeyState,point);
126         if (!pDataObject->IsDataAvailable(GetClipboardFormat()))
127                 return dwEffect;
128     // Erase the old drag image and draw a new one if the cursor has moved.
129         CClientDC dc(GetImageWin(pWnd));
130         pWnd->ClientToScreen(&point);
131         m_pWnd->ScreenToClient(&point);
132     dc.DPtoLP(&point);
133     if (m_pImage && point != m_ptPrevPos) 
134         {
135                 // erase the old image
136         m_pImage->DrawDragImage(&dc,m_ptOldImage,m_ptItem);
137 //        CPoint ptDrag (point.x - m_sizeDelta.cx, point.y - m_sizeDelta.cy);
138         CPoint ptDrag (point.x, point.y);
139                 // draw the new image
140         m_pImage->DrawDragImage (&dc, ptDrag, m_ptItem);
141                 // save coords
142         m_ptOldImage = ptDrag;
143         m_ptPrevPos = point;
144     }
145         return dwEffect;
146 }
147
148 BOOL CUI_ImageDropTarget::OnDrop( CWnd* pWnd, COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point )
149 {
150         BOOL bRet = COleDropTarget::OnDrop(pWnd,pDataObject,dropEffect,point);
151         if (!pDataObject->IsDataAvailable(GetClipboardFormat()))
152                 return bRet;
153     //
154     // Erase the old drag image and delete the temporary widget.
155     //
156     CClientDC dc(GetImageWin(pWnd));
157     if (m_pImage != NULL) 
158         {
159         m_pImage->DrawDragImage (&dc,m_ptOldImage,m_ptItem);
160         delete m_pImage;
161         m_pImage = NULL;
162     }
163         return bRet;
164 }
165
166 void CUI_ImageDropTarget::EraseOldImage()
167 {
168         if (m_pImage == NULL)
169                 return;
170         CClientDC dc(GetImageWin(NULL));
171     m_pImage->DrawDragImage(&dc,m_ptOldImage,m_ptItem);
172     m_ptOldImage.x = m_ptOldImage.y = -32000;
173 }