Click here to Skip to main content
15,881,715 members
Articles / Desktop Programming / MFC

A Drag-Drop Manager for CObjects

Rate me:
Please Sign up or sign in to vote.
4.58/5 (8 votes)
16 Jan 2000 159.6K   3.9K   78  
A drag-drop/clipboard manager class for MFC objects derived from CObject
//util.cpp - Source file for general utility functions
#include "stdafx.h"
#include "util.h"
#include <math.h>

namespace util1
{

/////////////////////////////////////////////////////////////
//Build/erase a "focus rectangle"
//The caller passes the DC pointer, the rectangle,
//and a "show/erase" flag.
//A "focus" rectangle is always 1 pixel line width,
//grey, with a dotted pen.
//Note also that the rectangle is drawn just a tad
//larger than the passed rectangle, so that it will
//always show.
/////////////////////////////////////////////////////////////
BOOL FocusRect(CDC*     pDC,
               CRect    rect,
               BOOL     bShow,
               COLORREF rgbFocus,
               int      nPenStyle,
               int      nPenWidth,
               BOOL     bDrawEdge)
{
    if (pDC == NULL || rect.IsRectNull())
        return FALSE;

	CPen* pOldPen = NULL;
	CPen  FocusPen;
	int	  nDrawMode = pDC->GetROP2();

	if (bShow)
	{
		if (!FocusPen.CreatePen	(nPenStyle,nPenWidth,rgbFocus))
			return	FALSE;
	}

	//Set the drawing mode to "erase" the rectangle
	else
    {
        pDC->SetROP2(R2_NOT);
    }

   //Make sure top and bottom, left and right are a bit different
   if (abs(rect.top-rect.bottom) <= 5)
   {
      rect.top    += 5;
      rect.bottom -= 5;
   }

   else if (abs(rect.left-rect.right) <= 5)
   {
      rect.left -= 5;
      rect.right+= 5;
   }


	//Draw the lines;
	//remember that a line on the right or
	//bottom side of the rectangle is not
	//"in" the rectangle
	pOldPen = pDC->SelectObject(&FocusPen);

	int nOrigBk = pDC->SetBkMode(TRANSPARENT);

	if (bDrawEdge)
	{
		pDC->DrawEdge(&rect,EDGE_RAISED,BF_RECT);
	}

	else
	{
		pDC->MoveTo(rect.TopLeft());
		pDC->LineTo(rect.BottomRight().x-1,rect.TopLeft().y);
		pDC->LineTo(rect.BottomRight().x-1,rect.BottomRight().y+1);
		pDC->LineTo(rect.TopLeft().x,rect.BottomRight().y+1);
		pDC->LineTo(rect.TopLeft());
	}

	pDC->SetBkMode(nOrigBk);

	//Put the initial pen back in place if drawing,
	//or reset the draw mode if erasing
	if (bShow)
		pDC->SelectObject(pOldPen);
	else
		pDC->SetROP2(nDrawMode);

    FocusPen.DeleteObject();

	return	TRUE;
}

///////////////////////////////////////////////////////////////////////
void GetDelta(CPoint  pt1,
              CPoint  pt2,
              CPoint& ptDelta)
{
    ptDelta.x = pt2.x - pt1.x;
    ptDelta.y = pt2.y - pt1.y;
}

///////////////////////////////////////////////////////////////////////
void ApplyDelta(CPoint& ptTgt,
                CPoint  ptDelta)
{
    ptTgt.x += ptDelta.x;
    ptTgt.y += ptDelta.y;
}

///////////////////////////////////////////////////////////////////////
CString CSFrom(int n)
{
    CString cs;
    cs.Format("%d",n);
    return cs;
}

//////////////////////////////////////////
int DistanceBetween(CPoint pt1,CPoint pt2)
{
	int	nDistance = 0;

	int	nY = abs(abs(pt2.y) - abs(pt1.y));
	int	nX = abs(abs(pt2.x) - abs(pt1.x));

	nDistance = (nY * nY) + (nX * nX);
	nDistance = util1::RndUp(sqrt((double)nDistance));

	return	nDistance;
}

////////////////////////////////////////////////////
int Rnded(double d)
{
	return ((fabs(d-(double)((int)d))>=0.5)?
	       (int)(d+((d>0)?1:-1)):(int)d);
}

////////////////////////////////////////////////////
int RndUp(double d)
{
   double e = (double)((int)d);

   double f = fabs(d-e);

	return (f > 0.000001 ? //Account for x - x != exactly 0
	       (int)(d+((d>0)?1:-1)) : (int)d);
}

////////////////////////////////////////////
//Figure the area of a rectangle in device units
////////////////////////////////////////////
int	AreaOf(CRect rect)
{
	int nWidth = rect.BottomRight().x - rect.TopLeft().x;
	int nHeight= rect.BottomRight().y - rect.TopLeft().y;

	int nArea = abs(nWidth * nHeight);

	return	nArea;
}

///////////////////////////////////////////////////
//This function fixes up narrow rectangles so the
//user can still select on them
///////////////////////////////////////////////////
void FixUpRect(CRect* pRect)
{
    if (pRect == NULL)
        return;

   if (abs(pRect->top - pRect->bottom) <= 5)
   {
      pRect->top    += 5;
      pRect->bottom -= 5;
   }

   else if (abs(pRect->left - pRect->right) <= 5)
   {
      pRect->left -= 5;
      pRect->right+= 5;
   }
}


/////////////////////////////////////////////////////////////////////////////
//This function dolls up a moving object rect a bit...
/////////////////////////////////////////////////////////////////////////////
void AdjustMoveRect(CRect&  rect,
                    CPoint  point,
                    CPoint& ptTL,
                    CPoint& ptBR) 
{
	rect.NormalizeRect();

	int nW = rect.Width() /2;
	int nH = rect.Height()/2;

	ptTL.x = point.x-nW;
	ptTL.y = point.y+nH;
	ptBR.x = point.x+nW;
	ptBR.y = point.y-nH;
}


}   //end namespace util1





By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions