BOOL wmCommandHook(MSG *pMsg)
{
if (pMsg->message == WM_COMMAND) {
// conflicting apps looking for the same event
acedRemoveFilterWinMsg(wmCommandHook);
}
}
//dropTarget.h
#ifndef __DRAWDROPTARGET_H__
#define __DRAWDROPTARGET_H__
class CDummyDropTarget : public COleDropTarget
{
DROPEFFECT OnDragOver(CWnd* pWnd, COleDataObject* pDataObject,
DWORD dwKeyState, CPoint point)
{ return DROPEFFECT_MOVE;}; // just to display move icon
};
class CMyOverrideDropTarget : public COleDropTarget
{
public:
CMyOverrideDropTarget();
~CMyOverrideDropTarget();
virtual DROPEFFECT OnDragEnter(CWnd* pWnd, COleDataObject* pDataObject,
DWORD dwKeyState, CPoint point);
virtual DROPEFFECT OnDragOver(CWnd* pWnd, COleDataObject* pDataObject,
DWORD dwKeyState, CPoint point);
virtual BOOL OnDrop(CWnd* pWnd, COleDataObject* pDataObject,
DROPEFFECT dropEffect, CPoint point);
virtual void OnDragLeave(CWnd* pWnd);
virtual DROPEFFECT OnDropEx(CWnd* pWnd, COleDataObject* pDataObject,
DROPEFFECT dropDefault, DROPEFFECT dropList, CPoint point);
int m_nOldMouseX; // QiZhi modified to change INT_PTR to int
int m_nOldMouseY; // QiZhi modified to change INT_PTR to int
private:
CPoint m_lastDragPt;
DROPEFFECT m_prevDropEffect;
CSize m_trackerSize;
int m_rad;
};
class CMyFileDropTarget : public COleDropTarget
{
virtual BOOL OnDrop(CWnd* pWnd, COleDataObject* pDataObject,
DROPEFFECT dropEffect, CPoint point);
virtual DROPEFFECT OnDropEx(CWnd* pWnd, COleDataObject* pDataObject,
DROPEFFECT dropDefault, DROPEFFECT dropList, CPoint point);
virtual DROPEFFECT OnDragEnter(CWnd* pWnd, COleDataObject* pDataObject,
DWORD dwKeyState, CPoint point);
virtual DROPEFFECT OnDragOver(CWnd* pWnd, COleDataObject* pDataObject,
DWORD dwKeyState, CPoint point);
virtual void OnDragLeave(CWnd* pWnd);
};
#endif // __DRAWDROPTARGET_H__
//dropTarget.cpp
#include "rxmfcapi.h"
#include "dbents.h"
#include "dbsymtb.h"
#include "dropTarget.h"
#include "TentObj\GeneralDictionary.h"
#include "StressColor.h"
Adesk::Boolean
append(AcDbDatabase*pDb, AcDbEntity* pEntity, int vport)
{
AcDbBlockTable *pBlockTable;
Acad::ErrorStatus es = pDb->getSymbolTable(pBlockTable,
AcDb::kForRead);
if (es != Acad::eOk) {
ads_alert(_T("Failed to get block table!"));
return Adesk::kFalse;
}
AcDbBlockTableRecord *pBlockRec;
es = pBlockTable->getAt(vport == 1 ? ACDB_PAPER_SPACE : ACDB_MODEL_SPACE ,
pBlockRec, AcDb::kForWrite);
if (es != Acad::eOk) {
ads_alert(_T("Failed to get block table record!"));
pBlockTable->close();
return Adesk::kFalse;
}
es = pBlockRec->appendAcDbEntity(pEntity);
if (es != Acad::eOk) {
ads_alert(_T("Failed to append entity!"));
pBlockTable->close();
pBlockRec->close();
delete pEntity;
return Adesk::kFalse;
}
pBlockRec->close();
pBlockTable->close();
return Adesk::kTrue;
}
BOOL PasteFromData(COleDataObject* pDataObject, CRect& resRect, int& objType)
{
STGMEDIUM medium;
if (!SUCCEEDED(pDataObject->GetData(CF_TEXT, &medium)))
return FALSE;
CRect rect;
int type, left, top, right, bottom;
TCHAR * pstr = (TCHAR*) GlobalLock (medium.hGlobal);
if (_stscanf(pstr, _T("%d %d %d %d %d"), &type, &left, &top, &right, &bottom) != 5)
TRACE("Getting incorrect ObjType & CRect information
");
GlobalUnlock(medium.hGlobal);
rect.SetRect(left, top, right, bottom);
rect.NormalizeRect();
resRect = rect;
objType = type;
ReleaseStgMedium(&medium);
return TRUE;
}
CMyOverrideDropTarget::CMyOverrideDropTarget()
{
m_rad = 0;
m_nOldMouseX = 0;
m_nOldMouseY = 0;
}
CMyOverrideDropTarget::~CMyOverrideDropTarget()
{
}
DROPEFFECT
CMyOverrideDropTarget::OnDragEnter(CWnd* pWnd, COleDataObject* pDataObject,
DWORD dwKeyState, CPoint point)
{
if (! pDataObject->IsDataAvailable(CF_TEXT))
return DROPEFFECT_NONE;
// set the tracker size.
CRect rSize;
int objType;
if (!::PasteFromData(pDataObject, rSize, objType) || rSize.IsRectEmpty() == TRUE)
m_rad = 10;
else
m_rad = min(rSize.Width(), rSize.Height());
return OnDragOver(pWnd, pDataObject, dwKeyState, point);
}
DROPEFFECT
CMyOverrideDropTarget::OnDragOver(CWnd* pWnd, COleDataObject* pDataObject,
DWORD dwKeyState, CPoint point)
{
// find the tracker size
CSize trackerSize;
int rectSize;
acedDwgPoint ptIn, ptIn2;
if (NULL==pDataObject)
return DROPEFFECT_NONE;;
CPoint lowerLeft, lowerRight;
ptIn[0]= ptIn[1] = ptIn[2]=0;
ptIn2[0]= (2*m_rad);
ptIn2[1]= ptIn2[2]=0;
int windnum = acedGetWinNum(point.x, point.y);
if (windnum == 0)
{
if (m_prevDropEffect != DROPEFFECT_NONE)
{ // erase the prev tracker
pWnd->GetDC()->DrawFocusRect(CRect(m_lastDragPt, m_trackerSize));
}
return DROPEFFECT_NONE;
}
acedCoordFromWorldToPixel(windnum, ptIn, lowerLeft);
acedCoordFromWorldToPixel(windnum, ptIn2, lowerRight);
rectSize = lowerRight.x - lowerLeft.x;
TRACE("rectSize is %d
", rectSize);
trackerSize = CSize(rectSize,rectSize);
CPoint trackerCenterPt (point.x - trackerSize.cx/2,
point.y - trackerSize.cx/2);
// check if it's the same point
if (point == m_lastDragPt)
return DROPEFFECT_COPY;
CDC *pDC = pWnd->GetDC();
ASSERT(pDC);
if (m_prevDropEffect != DROPEFFECT_NONE)
{ // erase the prev tracker
pDC->DrawFocusRect(CRect(m_lastDragPt, m_trackerSize));
// draw new tracker
pDC->DrawFocusRect(CRect(trackerCenterPt, trackerSize));
m_lastDragPt = trackerCenterPt;
m_trackerSize = trackerSize;
}
return DROPEFFECT_COPY;
}
void
CMyOverrideDropTarget::OnDragLeave(CWnd* pWnd)
{
if (m_prevDropEffect != DROPEFFECT_NONE)
{
CDC* pDC = pWnd->GetDC();
ASSERT(pDC);
// erase previous focus rect
pDC->DrawFocusRect(CRect(m_lastDragPt, m_trackerSize));
m_prevDropEffect = DROPEFFECT_NONE;
}
}
DROPEFFECT CMyOverrideDropTarget::OnDropEx(CWnd* pWnd, COleDataObject* pDataObject,
DROPEFFECT dropDefault, DROPEFFECT dropList, CPoint point)
{
return -1; // calls OnDrop();
}
BOOL
CMyOverrideDropTarget::OnDrop(CWnd* pWnd, COleDataObject* pDataObject,
DROPEFFECT dropEffect, CPoint point)
{
BOOL fRet=TRUE;
GeneralDict *pDict;
int PosX, PosY;
CPoint ptGlobPos;
if(!get_general_dictionary(pDict, AcDb::kForRead, workingDb()))
return FALSE;
if (NULL == pDataObject)
return FALSE;
OnDragLeave(pWnd);
CRect rSize;
int objType;
fRet = ::PasteFromData(pDataObject, rSize, objType);
if (rSize.IsRectEmpty() == TRUE)
return FALSE;
acedGetAcadFrame()->GetActiveWindow();
if (!GetCursorPos(&ptGlobPos)) //Get coordinates of the mouse (complete screen)
return FALSE;
PosX = ptGlobPos.x;
PosY = ptGlobPos.y;
if ( gpStressColor == NULL )
{
gpStressColor = new CStressColor;
gpStressColor->clrBackColor = acedGetRGB((int)pDict->getStressColor(objType));
gpStressColor->Create(IDD_STRESS_COLOR,acedGetAcadFrame());
gpStressColor->ShowWindow(SW_SHOW);
}
gpStressColor->SetWindowPos(NULL, PosX, PosY, 0,0,SWP_NOSIZE);
pDict->close();
// Set Focus to AutoCAD because AutoCAD doesn't update its
// display if it's not in focus.
acedGetAcadFrame()->SetActiveWindow();
return TRUE;
}
// get all files in hDrop and ads_print them
void processDrop(HDROP hDrop)
{
TCHAR fileName[MAX_PATH];
// Get the number of files dropped on us.
int nFiles = ::DragQueryFile( hDrop, 0xFFFFFFFF, NULL, 0 );
acutPrintf(_T("Files dropped:
"));
// get filename(s) and insert them print them
for (int i=0; i < nFiles; i++) {
if (::DragQueryFile(hDrop, i, fileName, MAX_PATH) !=0)
acutPrintf(_T("%s
"),fileName);
}
acutPrintf(_T("
"));
acedPostCommandPrompt();
}
void InitFormatEtc(FORMATETC& formatEtc, ULONG tymed, CLIPFORMAT cfFormat)
{
memset(&formatEtc, 0, sizeof(FORMATETC));
formatEtc.tymed = tymed;
formatEtc.cfFormat = cfFormat;
formatEtc.dwAspect = DVASPECT_CONTENT;
formatEtc.lindex = -1;
}
BOOL processDrop(COleDataObject* pDataObject)
{
// Check for File Manager/Explorer File Drop
//
BOOL bFile = pDataObject->IsDataAvailable(CF_HDROP);
if (bFile) {
STGMEDIUM stgMedium;
FORMATETC formatEtc;
::InitFormatEtc(formatEtc, TYMED_HGLOBAL, CF_HDROP);
pDataObject->GetData(CF_HDROP, &stgMedium, &formatEtc);
if (stgMedium.hGlobal != NULL) {
HDROP hDrop = (HDROP)::GlobalLock(stgMedium.hGlobal);
if (hDrop != (HDROP)0) {
processDrop(hDrop);
::GlobalUnlock(stgMedium.hGlobal);
}
::ReleaseStgMedium(&stgMedium);
}
return TRUE;
}
return FALSE;
}
// Special Note:
// This Popup Menu mechanism is totaly unsafe.
// It's possible that two different apps will define
// the same command id. In order to prevent this,
// I will provide an API to do popup menu.
// Something like AcApTrackPopupMenu(CWnd*, CPoint, UIContext*);
// UIContext is the same callback class used in ARX context menu.
//
#define ID_PRINTFILE 0xDFFF
#define ID_CANCELDROPX 0xDFFE
BOOL wmCommandHook(MSG *pMsg)
{
BOOL bRes = FALSE; // continue
// Remove letter x or X
if (pMsg->message == WM_COMMAND) {
// This filter hook is short live to prevent
// conflicting apps looking for the same event
acedRemoveFilterWinMsg(wmCommandHook);
}
return bRes;
}
BOOL
CMyFileDropTarget::OnDrop(CWnd* pWnd, COleDataObject* pDataObject,
DROPEFFECT dropEffect, CPoint point)
{
processDrop(pDataObject);
return TRUE; // take care of drop, doesn't let anyone handle it.
// Return False, if you want other apps to also
// get the drop event
}
DROPEFFECT
CMyFileDropTarget::OnDropEx(CWnd* pWnd, COleDataObject* pDataObject,
DROPEFFECT dropDefault, DROPEFFECT dropList, CPoint point)
{
CMenu dropMenu;
dropMenu.CreatePopupMenu();
dropMenu.AppendMenu(MF_ENABLED, ID_PRINTFILE, _T("List Files"));
dropMenu.AppendMenu(MF_SEPARATOR);
dropMenu.AppendMenu(MF_ENABLED, ID_CANCELDROPX, _T("Cancel"));
pWnd->ClientToScreen(&point);
UINT cmdID = dropMenu.TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_NONOTIFY | TPM_RETURNCMD, point.x, point.y, pWnd);
switch(cmdID)
{
case ID_PRINTFILE:
{
processDrop(pDataObject);
break;
}
case ID_CANCELDROPX:
// no op
break;
}
return DROPEFFECT_MOVE; // return other than NONE in order to prevent it
// from calling ::onDrop();
}
DROPEFFECT
CMyFileDropTarget::OnDragEnter(CWnd* pWnd, COleDataObject* pDataObject,
DWORD dwKeyState, CPoint point)
{
// need to override this method to prevent calling AutoCAD's view
// OnDragEnter() which can cause infinite recursive calls.
return DROPEFFECT_MOVE;
}
DROPEFFECT
CMyFileDropTarget::OnDragOver(CWnd* pWnd, COleDataObject* pDataObject,
DWORD dwKeyState, CPoint point)
{
// need to override this method to prevent calling AutoCAD's view
// onDragOver() which can cause infinite recursive calls.
return DROPEFFECT_MOVE;
}
void
CMyFileDropTarget::OnDragLeave(CWnd* pWnd)
{
}