Manipulating Draw Mode Settings and Using GDI+ to Save

Click here for a larger image.
Environment: Tested on Windows 2000
A simple demonstration of draw mode settings as well as a demonstration using GDI+ to save to a file.
This is my first column. I'll show you how to set the drawing mode with SetROP2. Parameters R2_NOTXORPEN Pixel are the inverse of the R2_XORPEN color (final pixel = NOT(pen XOR screen pixel)).
LRESULT CMiniProjectView::WindowProc
(UINT message, WPARAM wParam, LPARAM lParam)
{
CDC *pDC = NULL;
CMiniProjectDoc *pDoc = NULL;
CMainFrame *pMainFrame = (CMainFrame *)AfxGetMainWnd();
CPen *pOldPen = NULL;
CDrawObj *pDwObj = NULL;
CRect rcClient, rcRT, rcSave;
CPoint ptClientUL, ptClientLR;
static POINTS ptsBegin;
static POINTS ptsEnd;
static POINTS ptsPrevEnd;
static BOOL bPrevLine = FALSE;
INT_PTR nNewFH = 0;
switch (message)
{
case WM_SAVE_TO_FILE:
SaveToFile((BOOL)wParam);
break;
case WM_RECT_TRACK:
pDoc = GetDocument();
ASSERT(pDoc);
GetClientRect(&rcClient);
m_bSelArea = (BOOL)wParam;
if((INT)lParam == 1)
rcRT.CopyRect(DEF_RECT1);
else
rcRT.CopyRect(DEF_RECT2);
rcRT.SetRect(0, 0, rcRT.Width() * MULTI,
rcRT.Height() * MULTI);
rcRT.OffsetRect((rcClient.Width()
-rcRT.Width()) >> 1, (rcClient.Height()
-rcRT.Height()) >> 1);
pDoc->m_rtSelArea.m_rect.CopyRect(rcRT);
InvalidateRect(&rcClient, TRUE);
break;
case WM_LBUTTONDOWN:
ptsBegin = MAKEPOINTS(lParam);
pDoc = GetDocument();
ASSERT(pDoc);
if(m_bSelArea)
{
pDoc->m_rtSelArea.GetTrueRect(&rcSave);
if(pDoc->m_rtSelArea.HitTest
(CPoint(ptsBegin.x, ptsBegin.y)) !=
CRectTracker::hitNothing)
{
pDoc->m_rtSelArea.Track(this, CPoint
(ptsBegin.x, ptsBegin.y));
Invalidate(TRUE);
return 0;
}
}
SetCapture();
GetClientRect(&rcClient);
ptClientUL.x = rcClient.left;
ptClientUL.y = rcClient.top;
ptClientLR.x = rcClient.right + 1;
ptClientLR.y = rcClient.bottom + 1;
ClientToScreen(&ptClientUL);
ClientToScreen(&ptClientLR);
SetRect(&rcClient, ptClientUL.x, ptClientUL.y,
ptClientLR.x, ptClientLR.y);
ClipCursor(&rcClient);
if(pMainFrame->m_eActiveStyle == eFreehandStyle)
{
ASSERT(pDoc->m_parrObj);
pDoc->m_parrObj->Add(new CDrawObj
(CRect(ptsBegin.x, ptsBegin.y,
ptsEnd.x, ptsEnd.y),
pMainFrame->m_eActiveStyle));
}
return 0;
case WM_MOUSEMOVE:
pDoc = GetDocument();
if (wParam & MK_LBUTTON)
{
pDC = GetDC();
pDC->SetROP2(R2_NOTXORPEN);
CPen pen(PS_SOLID, PEN_WIDTH, RGB(0, 0, 0));
pOldPen = pDC->SelectObject(&pen);
switch(pMainFrame->m_eActiveStyle)
{
case eLineStyle:
if (bPrevLine)
{
pDC->MoveTo(ptsBegin.x, ptsBegin.y);
pDC->LineTo(ptsPrevEnd.x, ptsPrevEnd.y);
}
ptsEnd = MAKEPOINTS(lParam);
pDC->MoveTo(ptsBegin.x, ptsBegin.y);
pDC->LineTo(ptsEnd.x, ptsEnd.y);
bPrevLine = TRUE;
ptsPrevEnd = ptsEnd;
break;
case eSquareStyle:
if (bPrevLine)
pDC->Rectangle(ptsBegin.x, ptsBegin.y,
ptsPrevEnd.x, ptsPrevEnd.y);
ptsEnd = MAKEPOINTS(lParam);
pDC->Rectangle(ptsBegin.x, ptsBegin.y,
ptsEnd.x, ptsEnd.y);
bPrevLine = TRUE;
ptsPrevEnd = ptsEnd;
break;
case eFreehandStyle:
ptsEnd = MAKEPOINTS(lParam);
pDC->MoveTo(ptsBegin.x, ptsBegin.y);
pDC->LineTo(ptsEnd.x, ptsEnd.y);
bPrevLine = TRUE;
ptsPrevEnd = ptsEnd;
ptsBegin = ptsEnd;
//save point
nNewFH = pDoc->m_parrObj->GetCount() - 1;
if(nNewFH >= 0)
{
pDwObj = (CDrawObj *)pDoc->m_parrObj->GetAt(nNewFH);
if(pDwObj == NULL)
{TRACE0("Get NULL of Freehand object\n");
break;
}
if(pDwObj->m_eStyle == eFreehandStyle)
pDwObj->m_parrPoint->Add(new CPoint
(ptsEnd.x, ptsEnd.y));
}
break;
case eCircleStyle:
if (bPrevLine)
pDC->Ellipse(ptsBegin.x, ptsBegin.y,
ptsPrevEnd.x, ptsPrevEnd.y);
ptsEnd = MAKEPOINTS(lParam);
if((ptsEnd.x - ptsBegin.x > 0) &&
(ptsEnd.x - ptsBegin.x < MIN_SIZE))
break;
else if((ptsEnd.x - ptsBegin.x < 0) &&
(ptsBegin.x - ptsEnd.x < MIN_SIZE))
break;
else
{
pDC->Ellipse(ptsBegin.x, ptsBegin.y,
ptsEnd.x, ptsEnd.y);
bPrevLine = TRUE;
ptsPrevEnd = ptsEnd;
}
break;
default:
break;
} //end style
pDC->SelectObject(pOldPen);
pDC->ReleaseOutputDC();
}
break;
case WM_LBUTTONUP:
pDoc = GetDocument();
bPrevLine = FALSE;
ClipCursor(NULL);
ReleaseCapture();
ASSERT(pDoc->m_parrObj);
if(pMainFrame->m_eActiveStyle != eFreehandStyle)
{
pDoc->m_parrObj->Add(new CDrawObj( CRect
(ptsBegin.x, ptsBegin.y,
ptsEnd.x, ptsEnd.y),
pMainFrame->m_eActiveStyle));
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return CView::WindowProc(message, wParam, lParam);
}
For saving to a file, I showed you how to use GDI+. Before using GDI+, you must initialize GDI+ with GdiplusStartup(...) and override GetEncoderClsid(...) to get the encode class identified for the target image type.
int CMiniProjectView::GetEncoderClsid
(const WCHAR* format, CLSID* pClsid)
{
UINT num = 0; // number of image encoders
UINT size = 0; // size of the image encoder array
// in bytes
ImageCodecInfo* pImageCodecInfo = NULL;
GetImageEncodersSize(&num, &size);
if(size == 0)
return -1;
pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
if(pImageCodecInfo == NULL)
return -1;
GetImageEncoders(num, size, pImageCodecInfo);
for(UINT j = 0; j < num; ++j)
{
if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
{
*pClsid = pImageCodecInfo[j].Clsid;
free(pImageCodecInfo);
return j; // Success
}
}
free(pImageCodecInfo);
return -1;
}
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
Bitmap *pBitmap = Bitmap::FromHBITMAP(
(HBITMAP)bmp.GetSafeHandle(),
(HPALETTE)pPalette->GetSafeHandle());
//get encoder CLSID
CLSID Clsid;
if(fileDlg.GetFileExt().MakeUpper() == _T("BMP"))
GetEncoderClsid(L"image/bmp", &Clsid);
else if(fileDlg.GetFileExt().MakeUpper() == _T("GIF"))
GetEncoderClsid(L"image/gif", &Clsid);
else if(fileDlg.GetFileExt().MakeUpper() == _T("JPG"))
GetEncoderClsid(L"image/jpeg", &Clsid);
//save to file with current color
BSTR bstrFileName = fileDlg.GetPathName().AllocSysString();
pBitmap->Save(bstrFileName, &Clsid, NULL);
//clear and shutdown GDI+
SysFreeString(bstrFileName);
GdiplusShutdown(gdiplusToken);
You must initialize an array of EncoderParameters if you want to set parameters for encoding.
long nCompress = 0;
EncoderParameters encoderParameters[2];
encoderParameters[0].Count = 2;
encoderParameters[0].Parameter[0].Guid = EncoderQuality;
encoderParameters[0].Parameter[0].NumberOfValues = 1;
encoderParameters[0].Parameter[0].Type =
EncoderParameterValueTypeLong;
encoderParameters[0].Parameter[0].Value = &nCompress;
int nDep = 1;
encoderParameters[1].Parameter[0].Guid = EncoderColorDepth;
encoderParameters[1].Parameter[0].NumberOfValues = 1;
encoderParameters[1].Parameter[0].Type =
EncoderParameterValueTypeLong;
encoderParameters[1].Parameter[0].Value = &nDep;
//save to file with current color
BSTR bstrFileName = fileDlg.GetPathName().AllocSysString();
pBitmap->Save(bstrFileName, &Clsid, encoderParameters);
Downloads
Download demo project - 44 KbDownload source - 202 Kb

Comments
You necessitate some tomato basil and mozzarella. Into indoor power, these slippers are as emerge considering and manueverable as sneakers.
Posted by Soaceddew on 04/25/2013 12:59amHas just released respective new color Democratic Inneva Woven shoes, Nike recently with another way to regurgitate shoes with diverse styling to all [url=http://markwarren.org.uk/goodbuy.cfm]nike free uk[/url] eyes. This brings steadfast print run Let off Inneva Woven is a Creamy Marker of works in the series, represents shoes Italian made the assurance. Latest Free Inneva Woven swart and blue are available in two color schemes, to hand-knit Woven vamp in summing-up to infiltrated Italy's [url=http://northernroofing.co.uk/roofins.cfm]nike free run 3[/url] finest crafts, during the interval gives athletes terminate to the foot of ease, the most consequential thing is the end of Free 5 configuration, barefoot know it will bring cannot be ignored. Nike Empty Inneva Woven SP Pale-complexioned Characterization Compact on March 16 at outlets on all sides the [url=http://northernroofing.co.uk/roofins.cfm]nike free run[/url] trade name on the shelves, and on trade in minimal sort, interested friends should recompense terminate ralame to Nike announced the news.
ReplyMust have VC++ 7.0 to run and complie
Posted by Legacy on 12/30/2002 12:00amOriginally posted by: Anonymous
...
Reply
Complier Err, Why not use MFC4.2 lib, it is enough
Posted by Legacy on 10/28/2002 12:00amOriginally posted by: Too many compile error
Pls note to the readers it is compiled in Visual .Net
ReplyYou know there is no GetCount() in CPrtArray class, so how u conpile these codes.
At last pls limk staticly to facilate the readers, thank u.