Drawing Simple Lines and Shapes (C++ 5.0 and later)

Take the following steps to add code that lets you draw a line, rectangle and ellipse on the bitmap.

1.

Start with the project that you created in Loading and Displaying an Image.

2.

Edit TUTORDLG.H and insert the following lines in the definition of CTutorDlg after DECLARE_MESSAGE_MAP():

   int  m_nDrawObject; // The object we are drawing
   float m_fStartX; // Starting X position
   float m_fStartY; // Starting Y position
   float m_fEndX; // Ending X position
   float m_fEndY; // Ending Y position
   ILEADRasterFXD *m_pltRasFXD;
   BOOL m_bDrawing;

3.

Add #import and #include statements to your program so you can access the LEAD COM constants and classes:

 

a.

In the Project Workspace, click the FileView tab.

 

b.

Double-click the tutor files folder to open it.

 

c.

Double-click the Header Files folder to open it.

 

e.

Double-click the StdAfx.h file to edit it.

 

d.

Add the following lines to the end of the file (keep in mind, you may have to change the path to where the dll's reside):

#import "c:\\winnt\\system32\\ltrfd14n.dll" no_namespace, named_guids

4.

Add the following code to the OnInitDialog

CoCreateInstance(CLSID_LEADRasterFXD, NULL, CLSCTX_ALL,IID_ILEADRasterFXD, (void**)&m_pltRasFXD);
m_pltRasFXD->PutDstLeft(0);
m_pltRasFXD->PutDstTop(0);
m_pltRasFXD->PutSrcLeft(0);
m_pltRasFXD->PutSrcTop(0);
m_pltRasFXD->PutScaleMode (3);
m_pltRasFXD->PutClientSizeX (5);
m_pltRasFXD->PutClientSizeY (5);

5.

Process the WM_DESTROY dialog message as follows:

 

Click on the Class View Tab

 

a.

Right-clock the CTutorDlg class

 

b.

Choose "Add Windows Message Handler"

 

c.

Select WM_DESTROY for the "New Window Messages/events"

 

d.

Click the "Add and Edit" button

 

e.

Enter new code as follows:

void CTutorDlg::OnDestroy() 
{
   if (!m_pltRasFXD)
      m_pltRasFXD->Release();
   CDialog::OnDestroy();
}

6.

Edit the OnLoadlead() function to add the following code to the end:

 m_nDrawObject = 0;
   m_bDrawing = FALSE;
   m_pltRasFXD->PutDstRight((long) m_LEADRasterView1.GetRaster().GetBitmapWidth());
   m_pltRasFXD->PutDstBottom((long) m_LEADRasterView1.GetRaster().GetBitmapHeight());
   m_pltRasFXD->PutSrcRight((long) m_LEADRasterView1.GetRaster ().GetBitmapWidth());
   m_pltRasFXD->PutSrcBottom ((long) m_LEADRasterView1.GetRaster().GetBitmapHeight());

7.

Code the LEADRasterView control's MouseDown event as follows. (This code selects a different drawing object each time the event occurs.)

 

a.

Press Ctrl-W to go to the MFC Class Wizard.

 

b.

Click the Message Maps tab.

 

c.

In the Class Name box, select CTutorDlg.

 

d.

In the Object IDs list box, select IDC_LEADRASTERVIEW1.

 

e.

In the Messages list box, select MouseDown.

 

f.

Click the Add function button. Choose OK for the default function name

 

g.

Click the Edit Code button, and edit the function so it appears as follows:

void CTutorDlg::OnMouseDownLeadrasterview1(short Button, short Shift, float x, float y) 
{
   m_bDrawing = TRUE;
   // Save the starting position.
   m_fStartX = x;
   m_fStartY = y;
   m_fEndX   = x;
   m_fEndY   = y;
   // Cycle through the types of drawing objects.
   switch (m_nDrawObject)
   {
   case 0:
      m_nDrawObject = 1;   // Line
      break;
   case 1:
      m_nDrawObject = 2;   // Rectangle
      break;
   case 2:
      m_nDrawObject = 0;   // Ellipse
      break;
   }
}

8.

Add the LEADRasterView control's MouseMove event as described in the previous step. This code uses DRAWMODE_INVERT for the DrawMode, which means that pixel colors are inverted. Thus, the drawing methods can erase the previous object and draw a new one. Code the LEADRasterView control's MouseMove event as follows.

void CTutorDlg::OnMouseMoveLeadrasterview1(short Button, short Shift, float x, float y) 
{
   float OldEndX, OldEndY;
   float OldDrawX, OldDrawY, OldWidth, OldHeight;
   float DrawX, DrawY, NewWidth, NewHeight;
   if (m_bDrawing == TRUE)
   {
      // Set the drawing styles.
      m_pltRasFXD->PutDrawPenStyle(DRAWPENSTYLE_SOLID);
      m_pltRasFXD->PutDrawMode(DRAWMODE_INVERT);
      m_pltRasFXD->PutDrawFillStyle(DRAWFILLSTYLE_TRANSPARENT);
      m_pltRasFXD->PutDrawPersistence(FALSE); // On the window, not the bitmap
      // Save the previous ending mouse position.
      OldEndX = m_fEndX;
      OldEndY = m_fEndY;
      // Get the current mouse position.
      m_fEndX = x;
      m_fEndY = y;
      // Calculate the origin of the current object.
      if (m_fEndX > m_fStartX)
         DrawX = m_fStartX;
      else
         DrawX = m_fEndX;
      if (m_fEndY > m_fStartY)
         DrawY = m_fStartY;
      else
         DrawY = m_fEndY;
      // Calculate the origin of the previous object.
      if (OldEndX > m_fStartX)
         OldDrawX = m_fStartX;
      else
         OldDrawX = OldEndX;
      if (OldEndY > m_fStartY)
         OldDrawY = m_fStartY;
      else
         OldDrawY = OldEndY;
      // Calculate the height and width of the current object.
      NewHeight = (float)abs((int)m_fStartY - (int)m_fEndY);
      NewWidth = (float)abs((int)m_fStartX - (int)m_fEndX);
      // Calculate the height and width of the previous object.
      OldHeight = (float)abs((int)m_fStartY - (int)OldEndY);
      OldWidth = (float)abs((int)m_fStartX - (int)OldEndX);
      // Erase the old object and draw the new one.
      switch (m_nDrawObject)
      {
      case 0:   // Ellipse
         m_pltRasFXD->DrawEllipse(NULL, m_LEADRasterView1. GetClientDC(), (float)OldDrawX, (float)OldDrawY, (float)OldWidth, (float)OldHeight);
         m_pltRasFXD->DrawEllipse(NULL, m_LEADRasterView1. GetClientDC(), (float)DrawX, (float)DrawY, (float)NewWidth, (float)NewHeight);
         break;
      case 1:   // Line
         m_pltRasFXD->DrawLine( NULL, m_LEADRasterView1. GetClientDC(), m_fStartX, m_fStartY, OldEndX, OldEndY);
         m_pltRasFXD->DrawLine( NULL, m_LEADRasterView1. GetClientDC(), m_fStartX, m_fStartY, m_fEndX, m_fEndY);
         break;
      case 2:   // Rectangle
         m_pltRasFXD->DrawRectangle( NULL, m_LEADRasterView1. GetClientDC(), OldDrawX, OldDrawY, OldWidth, OldHeight);
         m_pltRasFXD->DrawRectangle( NULL, m_LEADRasterView1. GetClientDC(), DrawX, DrawY, NewWidth, NewHeight);
         break;
      }
   }
}

8.

Add the LEADRasterView control's MouseUp event as described in the previous step.This code sets the drawing style and draws the object on the bitmap. Code the LEADRasterView control's MouseUp event as follows.

void CTutorDlg::OnMouseUpLeadrasterview1(short Button, short Shift, float x, float y) 
{
  float DrawX, DrawY, NewWidth, NewHeight;
  m_bDrawing = FALSE;
  // Set the drawing style.
  m_pltRasFXD->PutDrawPenStyle(DRAWPENSTYLE_SOLID);
  m_pltRasFXD->PutDrawPenWidth(2);
  m_pltRasFXD->PutDrawPenColor(RGB(255, 0, 0));    // Red
  m_pltRasFXD->PutDrawMode(DRAWMODE_COPY_PEN);
  m_pltRasFXD->PutDrawFillColor(RGB(0, 255, 0));   // Green
  m_pltRasFXD->PutDrawFillStyle(DRAWFILLSTYLE_HORIZONTAL_LINE);
  m_pltRasFXD->PutDrawPersistence(TRUE);           // On the bitmap
  // Get the current mouse position
  m_fEndX = x;
  m_fEndY = y;
  // Determine the origin of the object.
  if (m_fEndX > m_fStartX)
   DrawX = m_fStartX;
  else
   DrawX = m_fEndX;
  if (m_fEndY > m_fStartY)
   DrawY = m_fStartY;
  else
   DrawY = m_fEndY;
  // Determine the height and width of the object.
  NewHeight = (float)abs((int)m_fStartY - (int)m_fEndY);
  NewWidth = (float)abs((int)m_fStartX - (int)m_fEndX);
  // Draw the object
  switch (m_nDrawObject)  
  {
   case 0:   // Ellipse
     m_pltRasFXD->DrawEllipse((ILEADRaster *)m_LEADRasterView1.GetRaster().m_lpDispatch, NULL, DrawX, DrawY, NewWidth, NewHeight);
     break;
   case 1:   // Line
     m_pltRasFXD->DrawLine((ILEADRaster *)m_LEADRasterView1.GetRaster().m_lpDispatch, NULL, m_fStartX, m_fStartY, m_fEndX, m_fEndY);
     break;
   case 2:   // Rectangle
     m_pltRasFXD->DrawRectangle((ILEADRaster *)m_LEADRasterView1.GetRaster().m_lpDispatch, NULL , DrawX, DrawY, NewWidth, NewHeight);
     break;
  }

  m_LEADRasterView1.ForceRepaint();
}

9.

Run your program to test it.