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. |