Flash按钮

转载请注明来源:http://www.cnblogs.com/xuesongshu/

  解决闪屏的问题一定要使用双缓冲技术吗?不是。本文将顺便介绍在没有使用双缓冲的如何解决闪屏的问题。本示例同时介绍文安首尾连接不间断滚动的方法。运行效果截图:

  FlashButton.cpp代码:

// FlashButton.cpp : implementation file
//

#include "stdafx.h"
#include "ExMain.h"
#include "FlashButton.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CFlashButton

CFlashButton::CFlashButton()
{
	m_arrStr.Add("花开若相惜,花落莫相离。");
	m_arrStr.Add("弄花香满衣,拂花叶凄凄。");
	m_arrStr.Add("醉言花间意,别情花如依。");
	m_arrStr.Add("纵君解花语,霜雪下花篱。");
	CString str=m_arrStr.GetAt(0);
	m_font.CreateFont(32,0,0,0,FW_BOLD,0,0,0,DEFAULT_CHARSET,0,0,0,0,"华文仿宋");
	m_bmp.LoadBitmap(IDB_BITMAP1);
	bContinue=TRUE;
}

CFlashButton::~CFlashButton()
{
}


BEGIN_MESSAGE_MAP(CFlashButton, CButton)
	//{{AFX_MSG_MAP(CFlashButton)
	ON_WM_PAINT()
	ON_WM_PARENTNOTIFY()
	ON_WM_CLOSE()
	ON_WM_DESTROY()
	ON_WM_LBUTTONUP()
	ON_WM_LBUTTONDOWN()
	ON_WM_GETDLGCODE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CFlashButton message handlers

void CFlashButton::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	
	// TODO: Add your message handler code here
	CBrush br;
	br.CreatePatternBrush(&m_bmp);
	CRect rc;
	GetClientRect(rc);
	dc.FillRect(rc,&br);
	// Do not call CButton::OnPaint() for painting messages
}

void CFlashButton::OnParentNotify(UINT message, LPARAM lParam) 
{
	CWindowDC dc(this);
	CSize sizeRow;
	if (message=WM_USER+1&&lParam==0)
	{
		dc.SelectObject(m_font);
		GetWindowRect(m_rcLoc);
		GetParent()->ScreenToClient(m_rcLoc);
		sizeRow=dc.GetOutputTextExtent(m_arrStr[0]);
		m_nLineHight=sizeRow.cy;
		sizeRow.cy*=4;
		m_yBlock2=max(sizeRow.cy,m_rcLoc.Height());
		// TODO: Add your message handler code here
		AfxBeginThread(DoFlashButtonThread,this);
		
	} 
	else
	{
		CButton::OnParentNotify(message, lParam);
	}
}

UINT DoFlashButtonThread(LPVOID lParam)
{
	CWnd *p=NULL;//父控件窗口
	CBrush br;
	CRect rc;//父窗口控件大小。
	CFlashButton *t=(CFlashButton*)lParam;//本控件
	int yBlock1Begin=0,yBlock2Begin=0,i=0;
	
	p=t->GetParent();
	p->GetClientRect(rc);
	br.CreatePatternBrush(&t->m_bmp);
	yBlock2Begin=t->m_yBlock2;

	while (t->bContinue)
	{
		CWindowDC dc(t);
		//CDC *dcMem->=new CDC;//执行构造函数
		//CDC *dcMem->=(CDC *)calloc(sizeof(CDC),1);//不执行构造函数。
		//设定背景
		CDC dcMem;
		dcMem.CreateCompatibleDC(p->GetDC());
		dcMem.SelectObject(t->m_bmp);
		dcMem.FillRect(rc,&br);

		dcMem.SetBkMode(TRANSPARENT);
		dcMem.SetViewportOrg(t->m_rcLoc.left,t->m_rcLoc.top);
		dcMem.SelectObject(t->m_font);

		//计算绘画位置
		yBlock1Begin--;
		yBlock2Begin--;
		if (yBlock1Begin<-t->m_yBlock2)
		{
			yBlock1Begin=0;
			yBlock2Begin=t->m_yBlock2;
		}
		//绘制文字
		for (i=0;i<4;i++)
		{
			dcMem.TextOut(0,yBlock1Begin+i*t->m_nLineHight,t->m_arrStr[i]);
			dcMem.TextOut(0,yBlock2Begin+i*t->m_nLineHight,t->m_arrStr[i]);
		}
		//设定输出
		dc.BitBlt(0,0,t->m_rcLoc.Width(),t->m_rcLoc.Height(),&dcMem,0,0,SRCCOPY);
		Sleep(100);
	}
	
	return 0;
}

void CFlashButton::OnClose() 
{
	// TODO: Add your message handler code here and/or call default
	bContinue=FALSE;
	CButton::OnClose();
}

void CFlashButton::OnDestroy() 
{
	bContinue=FALSE;
	CButton::OnDestroy();
	
	// TODO: Add your message handler code here
	
}

void CFlashButton::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	
	CButton::OnLButtonUp(nFlags, point);
	Invalidate();
}

void CFlashButton::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	
	CButton::OnLButtonDown(nFlags, point);
	Invalidate();
}

UINT CFlashButton::OnGetDlgCode() 
{
	// TODO: Add your message handler code here and/or call default
	
	int n= CButton::OnGetDlgCode();
	Invalidate();
	return n;
}

  FlashButton.h代码:

#if !defined(AFX_FLASHBUTTON_H__36D25335_C9F2_476B_BCA8_6B63E02DDD19__INCLUDED_)
#define AFX_FLASHBUTTON_H__36D25335_C9F2_476B_BCA8_6B63E02DDD19__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// FlashButton.h : header file
//
#include <afxtempl.h>
/////////////////////////////////////////////////////////////////////////////
// CFlashButton window

class CFlashButton : public CButton
{
// Construction
public:
	CFlashButton();

// Attributes
public:
	CStringArray m_arrStr;
	CFont m_font;//字体
	int m_yBlock2;//第2块绘制起始位置。
	int m_nLineHight;
	CRect m_rcLoc;//相对父控件窗口的位置。
	BOOL bContinue;//线程是否继续执行。
	CBitmap m_bmp;//背景
// Operations
public:
// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CFlashButton)
	//}}AFX_VIRTUAL

// Implementation
public:
	virtual ~CFlashButton();

	// Generated message map functions
protected:
	//{{AFX_MSG(CFlashButton)
	afx_msg void OnPaint();
	afx_msg void OnParentNotify(UINT message, LPARAM lParam);
	afx_msg void OnClose();
	afx_msg void OnDestroy();
	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
	afx_msg UINT OnGetDlgCode();
	//}}AFX_MSG

	DECLARE_MESSAGE_MAP()
};


UINT DoFlashButtonThread(LPVOID lParam);
/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_FLASHBUTTON_H__36D25335_C9F2_476B_BCA8_6B63E02DDD19__INCLUDED_)

  注释算是写得比较详细吧,相信诸位看了注释之后应该能明白。当然,您也可以使用相同的方法去重载一个CStatic类去实现。方法很多啦。

  本示例解决闪屏的方法是首先把要显示的界面在内存里画出来。画完了之后一次输出到显存,成功避免了多次修改显存造成的闪屏的问题。

posted @ 2013-04-19 06:23  岬淢箫声  阅读(1040)  评论(1编辑  收藏  举报