转载请注明来源:
解决闪屏的问题一定要使用双缓冲技术吗?不是。本文将顺便介绍在没有使用双缓冲的如何解决闪屏的问题。本示例同时介绍文安首尾连接不间断滚动的方法。运行效果截图:
FlashButton.cpp代码:
// FlashButton.cpp : implementation file//#include "stdafx.h"#include "ExMain.h"#include "FlashButton.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/// CFlashButtonCFlashButton::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_MAPEND_MESSAGE_MAP()/// CFlashButton message handlersvoid 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/// CFlashButton windowclass CFlashButton : public CButton{// Constructionpublic: CFlashButton();// Attributespublic: CStringArray m_arrStr; CFont m_font;//字体 int m_yBlock2;//第2块绘制起始位置。 int m_nLineHight; CRect m_rcLoc;//相对父控件窗口的位置。 BOOL bContinue;//线程是否继续执行。 CBitmap m_bmp;//背景// Operationspublic:// Overrides // ClassWizard generated virtual function overrides //{ {AFX_VIRTUAL(CFlashButton) //}}AFX_VIRTUAL// Implementationpublic: virtual ~CFlashButton(); // Generated message map functionsprotected: //{ {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类去实现。方法很多啦。
本示例解决闪屏的方法是首先把要显示的界面在内存里画出来。画完了之后一次输出到显存,成功避免了多次修改显存造成的闪屏的问题。