With The Case Of  Release The Power OF  Visual C++ !   HomeProducts | PurchaseSupport | Downloads  
Download Evaluation
Pricing & Purchase?
E-XD++Visual C++/ MFC Products
Features Tour 
Electronic Form Solution
Visualization & HMI Solution
Power system HMI Solution
CAD Drawing and Printing Solution

Bar code labeling Solution
Workflow Solution

Coal industry HMI Solution
Instrumentation Gauge Solution

Report Printing Solution
Graphical modeling Solution
GIS mapping solution

Visio graphics solution
Industrial control SCADA &HMI Solution
BPM business process Solution

Industrial monitoring Solution
Flowchart and diagramming Solution
Organization Diagram Solution

Graphic editor Source Code
UML drawing editor Source Code
Map Diagramming Solution

Architectural Graphic Drawing Solution
Request Evaluation
ActiveX COM Products
Technical Support
  General Q & A
Discussion Board
Contact Us


Get Ready to Unleash the Power of UCanCode .NET

UCanCode Software focuses on general application software development. We provide complete solution for developers. No matter you want to develop a simple database workflow application, or an large flow/diagram based system, our product will provide a complete solution for you. Our product had been used by hundreds of top companies around the world!

"100% source code provided! Free you from not daring to use components because of unable to master the key technology of components!"

Visual C++ Example: Multiple CRectTracker Drawing

Thierry Maurel 
February 5, 2000 

Environment: VC++ 6 SP2, Visual C++ 2003, Visual C++ 2005, NT4 SP3, Win95/98

The class I present performs the classic dragging and resizing of multiple objects, like vector editors or CAD programs.
It does the same operations that the CRectTracker, with an array of rectangles instead of a single rectangle.
Those rectangles could be implemented with a CArray<CRect*, CRect*>, but the code in the project's view would be complex and not portable. So my solution is the CMRTObject (for CMultiRectTrackerObject), a base class for the edited objects, with just a rectangle information and two functions Get/Set. In a normal project, those objects are often based on CObject, but with multiple inheritance, this add-in is easy to be implemented. Another good news is that the CMultiRectTracker class gets the possibility to directly change the position/size of selected objects, so the CView code for the manipulation is light, as listed below.

// This is a demo object. As long as it contains 
// CMRTObject in its base classes, the multitrack works.
// Implement your own Draw fct, with your datas, etc..
// If derived from CObject, the serialize capacities can 
// be added.
class CDemoObject : public CMRTObject, public CObject
 CDemoObject (COLORREF rgb)
 : CMRTObject(), m_color(rgb) {;}
 CDemoObject (LPCRECT lpSrcRect, COLORREF rgb)
 : CMRTObject(lpSrcRect), m_color(rgb) {;}

 ~CDemoObject () {;}

 void Draw (CDC* pDC) {
 pDC->FillSolidRect (GetRect(), m_color);

 COLORREF m_color;

Listed below is a possible implementation for your CxxView::OnLButtonDown(). It performs multiple selection with a local CRectTracker, and updates the CMultiRectTracker object contained by the view. If there is no rubber band, it selects the object clicked, and if the HitTest is different than -1 (CRectTracker::hitNothing), it starts the CMultiRectTracker::Track() function, wich contains the similar internal loop than CRectTracker. All objects moved or sized are directly updated in the Track() fct, the only work the CxxView needs to do is a call to Invalidate(). The CTRL key is scanned, and selected objects are removed if the user don't hit CTRL.

void CDemoView::OnLButtonDown(UINT nFlags, CPoint point)
 CDemoDoc* pDoc = GetDocument();

 // the multitrack if an object is already 
 // selected or a handle. If not, start the 
 // local tracker. 
 if (multiTrack.HitTest(point) < 0) {

  // Reset the multitrack only if there 
  // is no CTRL key. 
  if (!(nFlags & MK_CONTROL))

  CRect rcObject;
  CDemoObject* pObject;

  // local tracker... 
  CRectTracker tracker;
  if (tracker.TrackRubberBand(this, point, TRUE)) {

   // see if rubber band intersects with the objects 
   CRect rectT;
   POSITION pos = pDoc->m_objects.GetHeadPosition ();
   while (pos != NULL) {
    pObject = (CDemoObject*)(pDoc->m_objects.GetNext(pos));
    rcObject = pObject->GetRect();
    rectT.IntersectRect(tracker.m_rect, rcObject);
    if (rectT == rcObject) {
     multiTrack.Add(pObject); // add it to the multitrack, 
     // and continue the loop 
  } else {
   // No rubber band, see if the point selects an object. 
   POSITION pos = pDoc->m_objects.GetHeadPosition ();
   while (pos != NULL) {
    pObject = (CDemoObject*)(pDoc->m_objects.GetNext(pos));
    rcObject = pObject->GetRect();
    if (rcObject.PtInRect(point)) {
		 // add just one object to the multitrack 
 } else {
  // Click on the multitrack, forward actions to it. 
  if (multiTrack.Track(this, point, FALSE))
 // Update drawing. 
 CView::OnLButtonDown(nFlags, point);

In order to be classic, the cursor needs to be updated, function of its position on the objects, so a call to SetCursor() is needed before the CView-base class OnSetCursor() call, like the CRectTracker usage.

BOOL CDemoView::OnSetCursor(CWnd* pWnd, UINT nHitTest,
 UINT message)
 // forward to multitracker 
 if (pWnd == this && multiTrack.SetCursor(this, nHitTest))
 return TRUE;
 return CView::OnSetCursor(pWnd, nHitTest, message);


Download demo project - 34 Kb
Download source - 5 Kb



Copyright ?1998-2009 UCanCode.Net Software , all rights reserved.
Other product and company names herein may be the trademarks of their respective owners.

Please direct your questions or comments to