一个双缓冲原理的解释:Flash按钮
2016-08-16 11:35
176 查看
转载请注明来源:http://blog.csdn.net/caoshiying/article/details/52218665
解决闪屏的问题一定要使用双缓冲技术吗?不是。本文将顺便介绍在没有使用双缓冲的如何解决闪屏的问题。本示例同时介绍文安首尾连接不间断滚动的方法。首先上一个运行效果截图:
FlashButton.h代码:
本示例解决闪屏的方法是首先把要显示的界面在内存里画出来。画完了之后一次输出到显存,成功避免了多次修改显存造成的闪屏的问题。
解决闪屏的问题一定要使用双缓冲技术吗?不是。本文将顺便介绍在没有使用双缓冲的如何解决闪屏的问题。本示例同时介绍文安首尾连接不间断滚动的方法。首先上一个运行效果截图:
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_)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; }注释算是写得比较详细吧,相信诸位看了注释之后应该能明白。当然,您也可以使用相同的方法去重载一个CStatic类去实现。方法很多啦。
本示例解决闪屏的方法是首先把要显示的界面在内存里画出来。画完了之后一次输出到显存,成功避免了多次修改显存造成的闪屏的问题。
相关文章推荐
- sdl2.0的按钮控件实现原理小程序
- 在U-boot下实现自动识别启动Flash的原理(针对S3C24x0)
- ssh的配置与原理解释
- TCP/IP具体解释--TCP/IP可靠的原理 滑动窗体 拥塞窗体
- 什么情况下document.write会覆盖页面及覆盖原理解释
- 分页式内核模式驱动--解释#ifdef ALLOC_PRAGMA代码段的原理
- Flash 与课件制作:缓冲公式
- DSound的所有音频特技使用和参数解释详细笔记(音频特效)[静态缓冲]
- css按钮自适应实现原理及代码
- 解释Windows7“上帝模式”的原理
- Canny边缘检測算法原理及其VC实现具体解释(一)
- 从两个角度解释电容退耦原理
- Random Forest 原理解释机器参数说明
- 小白都能看明白的VLAN原理解释
- onvif 开发框架生成,解决在线/本地生成https,ssl/tsl错误,以及原理解释
- Spring的IOC原理[通俗解释一下]
- 解释下原型继承的原理。
- Spring 原理的基本解释
- faster-rcnn原理及相应概念解释
- Apache.Tomcat 调用Servlet原理之Class类的反射机制,用orc类解释