Click here to Skip to main content
15,886,787 members
Articles / Desktop Programming / ATL

2D Water Effect in WTL

Rate me:
Please Sign up or sign in to vote.
4.66/5 (22 votes)
28 Apr 2011CPOL4 min read 144.2K   3.7K   55  
A WTL control class to add water effect to an image, like what's done in the TortoiseSVN About dialog
// WaterEffectImplBase.h : the WaterEffectImplBase & WaterEffectCtl classes
// Written by Tan, Zhi(tomgee) 4/28/2011
/////////////////////////////////////////////////////////////////////////////

#pragma once

#include "WaterEffect.h"
#include "Renderer.h"

#include <atlcrack.h>
#include <atlimage.h>
#include <atltrace.h>


// for usage as a base class
template<class Derived>
class WaterEffectImplBase : public CMessageMap
{
private:
	CRenderer m_renderer;
	CWaterEffect m_waterEffect;
	CRect m_rectDraw;
private:
	enum
	{
		DRAW	 = 1,
		BLOB	 = 2
	};
public:
	BEGIN_MSG_MAP_EX(WaterEffectImplBase)
		MSG_WM_TIMER(OnTimer)
		MSG_WM_MOUSEMOVE(OnMouseMove)
	END_MSG_MAP()

public:
	void init(_U_STRINGorID  nIDResource, const CPoint& topleft = CPoint(0,0))
	{		
		CImage m_image;
		m_image.LoadFromResource(_Module.m_hInst, nIDResource.m_lpstr);

		init(m_image, topleft);
	}

	void init(const CImage& image, const CPoint& topleft = CPoint(0,0))
	{		
		CClientDC dc(static_cast<Derived*>(this)->m_hWnd);

		m_renderer.init(image, dc);
		m_waterEffect.Init(m_renderer);  

		m_rectDraw.SetRect(topleft, CPoint(topleft.x + image.GetWidth(), topleft.y + image.GetHeight()));

		CWindow hwnd = static_cast<Derived*>(this)->m_hWnd;
		SetTimer(hwnd, DRAW, 40, NULL);
		SetTimer(hwnd, BLOB, 1500, NULL);    	
	}

private:
	void OnTimer(UINT_PTR id)
	{
		if (id == DRAW)
		{
			m_waterEffect.Commit();

			CClientDC dc(static_cast<Derived*>(this)->m_hWnd);
			m_renderer.Draw(m_rectDraw.TopLeft(), dc);

		}
		if (id == BLOB)
		{
			m_waterEffect.BlobOnce(
					random(m_rectDraw.left,m_rectDraw.right), 
					random(m_rectDraw.top, m_rectDraw.bottom), 
					5, 
					800, 
					m_waterEffect.m_iHpage
				);
		}
	}

	void OnMouseMove(UINT nFlags, CPoint point)
	{
		if(m_rectDraw.PtInRect(point) == TRUE)
		{
			// dibs are drawn upside down...
			point.y -= m_rectDraw.top;

			// position relative to m_rectDraw.TopLeft()
			point.x -= m_rectDraw.left;
			point.y  = m_rectDraw.Height() - point.y;

			if (nFlags & MK_LBUTTON)
				m_waterEffect.BlobOnce(point, 10, 1600);
			else
				m_waterEffect.BlobOnce(point, 5, 50);
		}
	}    
};


// for usage as a member control 
class WaterEffectCtl :  public CWindowImpl<WaterEffectCtl, CWindow>, 
						public WaterEffectImplBase<WaterEffectCtl>
{
public:
	BEGIN_MSG_MAP(WaterEffectCtl)    
        CHAIN_MSG_MAP(WaterEffectImplBase<WaterEffectCtl>)
	END_MSG_MAP()
public:
	void init(HWND hWnd, _U_STRINGorID nIDResource, const CPoint& topleft = CPoint(0,0))
	{
		Attach(hWnd);

		// call base class method
		WaterEffectImplBase<WaterEffectCtl>::init(nIDResource, topleft); 	
	}   

	void init(HWND hWnd, const CImage& image, const CPoint& topleft = CPoint(0,0))
	{
		Attach(hWnd);

		// call base class method
		WaterEffectImplBase<WaterEffectCtl>::init(image, topleft); 
	}

private:
	BOOL Attach(HWND hWnd)
	{
		//subclass
		ATLASSERT(m_hWnd==NULL);
		ATLASSERT(::IsWindow(hWnd));
		BOOL bRet = CWindowImpl<WaterEffectCtl, CWindow>::SubclassWindow(hWnd);
		
		return bRet;
	}
};

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Team Leader
China China
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions