Posted by: Zeeshan Amjad | August 27, 2009

Creating Torn Paper Effect using MFC


We just studied that how to create torn paper effect in WPF using C#. Now we are going to do the same thing with VC++ using MFC. But this time there are two main differences between this technique and the WPF one.

The first one is that here we are not going to set window style none and make it transparent. What does it mean? It means the output of this program shows the title bar along with maximize, minimize button.

The other difference it the technique we are using here. In WPF program we create a random polygon and display it in window and set the main window transparent. However here we are using a region and create main window inside that region.

Here is a simple code to do this.

  1: #include "TornPaper.h"
  2: 
  3: App objApp;
  4: 
  5: BOOL App::InitInstance()
  6: {
  7: 	m_pMainWnd = new MainWnd();	
  8: 	m_pMainWnd->ShowWindow(m_nCmdShow);
  9: 	m_pMainWnd->UpdateWindow();
 10: 
 11: 	return TRUE;
 12: }
 13: 
 14: IMPLEMENT_DYNCREATE(MainWnd, CFrameWnd)
 15: 
 16: BEGIN_MESSAGE_MAP(MainWnd, CFrameWnd)
 17: 	ON_WM_CREATE()
 18: 	ON_WM_SIZE()
 19: 	ON_WM_ERASEBKGND()
 20: 	ON_WM_PAINT()
 21: END_MESSAGE_MAP()
 22: 
 23: MainWnd::MainWnd()
 24: {
 25: 	CRect rect(100, 100, 500, 400);
 26: 	Create(NULL, _T("Torn Paper Effect"), WS_OVERLAPPEDWINDOW, rect);
 27: }
 28: 
 29: int MainWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
 30: {
 31: 	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
 32: 		return -1;
 33: 
 34: 	return 0;
 35: }
 36: 
 37: void MainWnd::OnSize(UINT nType, int cx, int cy)
 38: {
 39: 	CFrameWnd::OnSize(nType, cx, cy);
 40: 
 41: 	m_rgn.DeleteObject();
 42: 
 43: 	CRect rect;
 44: 	GetWindowRect(&rect);
 45: 	rect -= rect.TopLeft();
 46: 
 47: 	srand((unsigned)time(0));
 48: 
 49: 	int iWidth = rect.Width();
 50: 	int iHeight = rect.Height();
 51: 
 52: 	int iHorizantaRegions = 96;
 53: 	int iVerticalRegions = 48;
 54: 
 55: 	int iHRegionWidth = iWidth / iHorizantaRegions;
 56: 	int iVRegionWidth = iHeight / iVerticalRegions;
 57: 
 58: 	const int iTotalPoints = (iHorizantaRegions * 2) 
 59: 							+ (iVerticalRegions * 2) 
 60: 							+ 1;
 61: 
 62: 	int iDistance = 12;
 63: 
 64: 	vector<CPoint> pt(iTotalPoints);
 65: 	int iPoint = 0;
 66: 	
 67: 	pt[iPoint].x = rect.left;
 68: 	pt[iPoint].y = rect.top;
 69: 	++iPoint;
 70: 
 71: 	// top horizontal
 72: 	for (int i = 1; i < iHorizantaRegions; ++i)
 73: 	{
 74: 		pt[iPoint].x = pt[iPoint - 1].x + iHRegionWidth;
 75: 		pt[iPoint].y = rect.top + rand() % iDistance;
 76: 		++iPoint;
 77: 	}
 78: 
 79: 	pt[iPoint].x = rect.right;
 80: 	pt[iPoint].y = rect.top;
 81: 	++iPoint;
 82: 
 83: 	// right vertical
 84: 	for (int i = 1; i < iVerticalRegions; ++i)
 85: 	{
 86: 		pt[iPoint].x = rect.right - rand() % iDistance;
 87: 		pt[iPoint].y = pt[iPoint - 1].y + iVRegionWidth;
 88: 		++iPoint;
 89: 	}
 90: 
 91: 	pt[iPoint].x = rect.right;
 92: 	pt[iPoint].y = rect.bottom;
 93: 	++iPoint;
 94: 
 95: 	// bottom horizontal
 96: 	for (int i = 1; i < iHorizantaRegions; ++i)
 97: 	{
 98: 		pt[iPoint].x = pt[iPoint - 1].x - iHRegionWidth;
 99: 		pt[iPoint].y = rect.bottom - rand() % iDistance;
100: 		++iPoint;
101: 	}
102: 
103: 	pt[iPoint].x = rect.left;
104: 	pt[iPoint].y = rect.bottom;
105: 	++iPoint;
106: 
107: 	// left vertical
108: 	for (int i = 1; i < iVerticalRegions; ++i)
109: 	{
110: 		pt[iPoint].x = rect.left + rand() % iDistance;
111: 		pt[iPoint].y = pt[iPoint - 1].y - iVRegionWidth;
112: 		++iPoint;
113: 	}
114: 
115: 	pt[iPoint].x = rect.left;
116: 	pt[iPoint].y = rect.top;
117: 	++iPoint;
118: 
119: 	m_rgn.CreatePolygonRgn(&pt[0], iTotalPoints, WINDING);
120: 
121: 	SetWindowRgn(m_rgn, TRUE);
122: }
123: 
124: BOOL MainWnd::OnEraseBkgnd(CDC* pDC)
125: {
126:       // Set brush to desired background color
127:       CBrush backBrush(RGB(128, 128, 255));
128: 
129:       // Save old brush
130:       CBrush* pOldBrush = pDC->SelectObject(&backBrush);
131: 
132:       CRect rect;
133:       pDC->GetClipBox(&rect);     // Erase the area needed
134: 
135:       pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(),
136:           PATCOPY);
137: 
138:       pDC->SelectObject(pOldBrush);
139:       return TRUE;
140: }
141: 
142: void MainWnd::OnPaint()
143: {
144: 	CPaintDC dc(this);
145: }
146: 

Here is the output of this program.

TornPaper_MFC

Note that the caption window is also visible in the output of this program.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

%d bloggers like this: