精华内容
下载资源
问答
  • 百度了一下,使用【双缓冲解决闪屏,其实关于闪屏的问题,3年前我也收藏过相关的文章,现在连我自己都忘记了。 参考资料:https://bbs.csdn.net/topics/350077253 @码侬 //创建内存DC HDC hdcMem = ...

    最近刚刚学习了使用 gdi+ 在窗口上绘制 png 图片, 但还是遇到一个老问题, 就是闪屏的情况。

    百度了一下,使用【双缓冲】解决闪屏,其实关于闪屏的问题,3年前我也收藏过相关的文章,现在连我自己都忘记了。

     

    参考资料: https://bbs.csdn.net/topics/350077253 @码侬

    //创建内存DC
         HDC hdcMem = CreateCompatibleDC(hdc);
         //创建一个bmp内存空间
         HBITMAP hBmp = CreateCompatibleBitmap(hdc,SCREEN_WIDTH,SCREEN_HEIGHT);
         //将bmp内存空间分配给内存DC
         HGDIOBJ hOldSel = SelectObject(hdcMem,hBmp);
        
         //这是使用者需要绘制的画面,全部往内存DC绘制
          // 绘制代码.......................
    
         如:
          Rectangle(hdcMem,0,0,SCREEN_WIDTH,SCREEN_HEIGHT);
         
        
         //将内存DC的内容复制到屏幕显示DC中,完成显示
         BitBlt(hdc,0,0,SCREEN_WIDTH,SCREEN_HEIGHT,hdcMem,0,0,SRCCOPY);
         //清除资源
         SelectObject(hdcMem,hOldSel);    
         DeleteDC(hdcMem);    
    
    另外,重载OnEraseBkgnd(CDC* pDC),在该函数中不要绘制背景,中直接返回TRUE。
    
    也就是:
    
    switch(message)
        {
            case WM_ERASEBKGND:
            {
    
                // 重载OnEraseBkgnd(CDC* pDC),在该函数中不要绘制背景,中直接返回TRUE。
    
                return TRUE;
            }

     

    还有一篇类似的资料: https://blog.csdn.net/lanyzh0909/article/details/5913836

     

    另外有两篇:基于GDI+实现双缓冲技术  https://blog.csdn.net/woaisia/article/details/46788965      https://blog.csdn.net/htt9931/article/details/28641039

    下面这个,我没测试:

            CPaintDC dc(this);                              // device context for painting
            Graphics gr(dc.m_hDC);                          // Graphics to paint
    
    
            Rect rGdi;
            gr.GetVisibleClipBounds(&rGdi);                 // The same as the clip rect
            
            //创建缓冲区
            Bitmap clBmp(rGdi.Width, rGdi.Height);          // Mem bitmap
            Graphics* grPtr = Graphics::FromImage(&clBmp);  // As memDC
            
            //利用grPtr在clBmp缓冲区绘图
            grPtr->DrawImage(m_PngMeter,clock_Rect);
            grPtr->TranslateTransform(Pcenter.X,Pcenter.Y);
            grPtr->RotateTransform(i);
            grPtr->TranslateTransform(-Pcenter.X,-Pcenter.Y);
            grPtr->DrawImage(m_PngArrow,picRect);
            grPtr->ResetTransform();
     
            //将clBmp缓冲区绘制到窗口
            gr.DrawImage(&clBmp, rGdi); 
    
    
    delete grPtr; //注:使用完缓冲区后,一定要及时释放内才能,尤其是在OnPaint中,否则程序很快占满物理内存,崩溃!

     

    转载于:https://www.cnblogs.com/personnel/p/9339526.html

    展开全文
  • c++控制台程序双缓冲解决闪屏

    千次阅读 2017-12-10 11:16:58
    #include #include using namespace std; #define MAP_HEGHT 20 #define MAP_WIGHT 30 void map(int CountX, int CountY); int main() { HANDLE hOutput; COORD coord = { 0, 0 };...hOutput = GetStdHand
    #include<iostream>
    #include<Windows.h>
    using namespace std;
    #define MAP_HEGHT  20
    #define MAP_WIGHT  30
    void map(int CountX, int CountY);
    int main()
    {
    HANDLE hOutput;
    COORD coord = { 0, 0 };
    hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
    int BeginTime = GetTickCount();
    while (true)
    {
    if (GetTickCount() - 1000 / 6 >= BeginTime)
    {
    SetConsoleCursorPosition(hOutput, coord);
    map(MAP_HEGHT, MAP_WIGHT);
    BeginTime = GetTickCount();
    }
    }
    cin.get();
    }
    void map(int CountX, int CountY)
    {
    for (int x = 0; x < CountX; x++)
    {
    for (int y = 0; y < CountY; y++)
    {
    cout << "□";
    }
    cout << endl;
    }
    }
    展开全文
  • 不多说,直接上Win32 VC++代码 ///FrameCPP.h /// #pragma once #include "resource.h" #include #include #include ...#pragma comment(lib, "comctl32.lib") #pragma comment(lib, "gdiplus.lib

    不多说,直接上Win32 VC++代码

    ///FrameCPP.h
    ///
    
    #pragma once
    
    #include "resource.h"
    #include <ShlObj.h>
    #include <CommCtrl.h>
    #include <vector>
    
    #include <comdef.h>
    #include <gdiplus.h>
    #pragma comment(lib, "comctl32.lib")  
    #pragma comment(lib, "gdiplus.lib")
    
    std::vector<WCHAR*> filenames;
    std::vector<Gdiplus::Image*> images;
    Gdiplus::Image* bgimg;
    int index;

    /// FramesCPP.cpp : 定义应用程序的入口点。
    ///
    
    #include "stdafx.h"
    #include "FramesCPP.h"
    
    #define MAX_LOADSTRING 100
    
    // 全局变量: 
    HINSTANCE hInst;                                // 当前实例
    WCHAR szTitle[MAX_LOADSTRING];                  // 标题栏文本
    WCHAR szWindowClass[MAX_LOADSTRING];            // 主窗口类名
    
    // 此代码模块中包含的函数的前向声明: 
    ATOM                MyRegisterClass(HINSTANCE hInstance);
    BOOL                InitInstance(HINSTANCE, int);
    LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
    INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);
    
    int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                         _In_opt_ HINSTANCE hPrevInstance,
                         _In_ LPWSTR    lpCmdLine,
                         _In_ int       nCmdShow)
    {
        UNREFERENCED_PARAMETER(hPrevInstance);
        UNREFERENCED_PARAMETER(lpCmdLine);
    
        // TODO: 在此放置代码。
    
        // 初始化全局字符串
        LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
        LoadStringW(hInstance, IDC_FRAMESCPP, szWindowClass, MAX_LOADSTRING);
        MyRegisterClass(hInstance);
    
        // 执行应用程序初始化: 
        if (!InitInstance (hInstance, nCmdShow))
        {
            return FALSE;
        }
    
        HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_FRAMESCPP));
    
        MSG msg;
    	Gdiplus::GdiplusStartupInput gsi;
    	Gdiplus::GdiplusStartupOutput gso;
    	ULONG_PTR token;
    	GdiplusStartup(&token,&gsi,&gso);
    	bgimg = Gdiplus::Image::FromFile(L".\\bg.jpg");
        // 主消息循环: 
        while (GetMessage(&msg, nullptr, 0, 0))
        {
            if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
    
        return (int) msg.wParam;
    }
    
    
    
    //
    //  函数: MyRegisterClass()
    //
    //  目的: 注册窗口类。
    //
    ATOM MyRegisterClass(HINSTANCE hInstance)
    {
        WNDCLASSEXW wcex;
    
        wcex.cbSize = sizeof(WNDCLASSEX);
    
        wcex.style          = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc    = WndProc;
        wcex.cbClsExtra     = 0;
        wcex.cbWndExtra     = 0;
        wcex.hInstance      = hInstance;
        wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_FRAMESCPP));
        wcex.hCursor        = LoadCursor(nullptr, IDC_ARROW);
        wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
        wcex.lpszMenuName   = MAKEINTRESOURCEW(IDC_FRAMESCPP);
        wcex.lpszClassName  = szWindowClass;
        wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
    
        return RegisterClassExW(&wcex);
    }
    
    //
    //   函数: InitInstance(HINSTANCE, int)
    //
    //   目的: 保存实例句柄并创建主窗口
    //
    //   注释: 
    //
    //        在此函数中,我们在全局变量中保存实例句柄并
    //        创建和显示主程序窗口。
    //
    BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
    {
       hInst = hInstance; // 将实例句柄存储在全局变量中
    
       HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
          CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
    
       if (!hWnd)
       {
          return FALSE;
       }
    
       ShowWindow(hWnd, nCmdShow);
       UpdateWindow(hWnd);
    
       return TRUE;
    }
    
    //
    //  函数: WndProc(HWND, UINT, WPARAM, LPARAM)
    //
    //  目的:    处理主窗口的消息。
    //
    //  WM_COMMAND  - 处理应用程序菜单
    //  WM_PAINT    - 绘制主窗口
    //  WM_DESTROY  - 发送退出消息并返回
    //
    //
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)
        {
        case WM_COMMAND:
            {	
                int wmId = LOWORD(wParam);
                // 分析菜单选择: 
                switch (wmId)
                {
                case IDM_ABOUT:
                    DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                    break;
    			case IDM_OPEN:
    			{
    				LPITEMIDLIST pil = NULL;
    				INITCOMMONCONTROLSEX InitCtrls = { 0 };
    				TCHAR szBuf[4096] = { 0 };
    				BROWSEINFO bi = { 0 };
    				bi.hwndOwner = NULL;
    				bi.iImage = 0;
    				bi.lParam = NULL;
    				bi.lpfn = NULL;
    				bi.lpszTitle = _T("请选择文件路径");
    				bi.pszDisplayName = szBuf;
    				bi.ulFlags = BIF_BROWSEINCLUDEFILES;
    
    				InitCommonControlsEx(&InitCtrls);//在调用函数SHBrowseForFolder之前需要调用该函数初始化相关环境  
    				pil = SHBrowseForFolder(&bi);
    				for (int i = 0; i < filenames.size();i++)
    				{
    					delete filenames[i];
    					delete images[i];
    				}
    				filenames.clear();
    				images.clear();
    				KillTimer(hWnd, 1);
    				if (NULL != pil)//若函数执行成功,并且用户选择问件路径并点击确定  
    				{
    					SHGetPathFromIDList(pil, szBuf);//获取用户选择的文件路径  
    					WIN32_FIND_DATAW fd;
    					memset(&fd, 0, sizeof(fd));
    					TCHAR strall[MAX_PATH];
    					_tcscpy_s(strall, szBuf);
    					_tcscat_s(strall, _T("\\*.*"));
    					HANDLE findhandle = FindFirstFile(strall, &fd);
    					while (TRUE)
    					{
    						BOOL r = FindNextFile(findhandle, &fd);
    						TCHAR* filename = new TCHAR[260];
    						_tcscpy_s(filename,260, fd.cFileName);
    						TCHAR* filepath = new TCHAR[260];
    						_stprintf_s(filepath, 260, L"%s\\%s", szBuf, filename);
    						if (!r)
    							break;
    						if (_tcscmp(filename, L"..") != 0) {
    							filenames.push_back(filepath);
    							images.push_back(Gdiplus::Image::FromFile(filepath));
    						}
    					}
    					FindClose(findhandle);
    					SetTimer(hWnd, 1, 20, NULL);
    					//wprintf_s(_T("%s"), szBuf);
    				}
    				break;
    			}
                case IDM_EXIT:
                    DestroyWindow(hWnd);
                    break;
                default:
                    return DefWindowProc(hWnd, message, wParam, lParam);
                }
            }
            break;
    	case WM_ERASEBKGND:
    	{
    		//PAINTSTRUCT ps;
    		//HDC hdc = BeginPaint(hWnd, &ps);
    		 TODO: 在此处添加使用 hdc 的任何绘图代码...
    
    		if (filenames.size() > 0) {
    			Gdiplus::Graphics* g = Gdiplus::Graphics::FromHDC(GetDC(hWnd));
    			Gdiplus::Image *tempimg = new Gdiplus::Bitmap(bgimg->GetWidth(), bgimg->GetHeight());
    			Gdiplus::Graphics* g1 = Gdiplus::Graphics::FromImage(tempimg);
    			//g->Clear(Gdiplus::Color::White);
    			g1->DrawImage(bgimg, 0, 0);
    			g1->DrawImage(images[index], 0, 0);
    			g1->Flush();
    			g1->Save();
    			g->DrawImage(tempimg, 0, 0);
    			tempimg->~Image();
    			g1->~Graphics();
    			g->~Graphics();
    		}
    		//EndPaint(hWnd, &ps);
    		break; 
    	}
    	case WM_TIMER:
    		{
    			index += 1;
    			if (index >= filenames.size())
    				index = 0;
    
    			RECT clientrect;
    			GetClientRect(hWnd, &clientrect);
    			InvalidateRect(hWnd, &clientrect, TRUE);
    			break;
    		}
        case WM_PAINT:
            {
                PAINTSTRUCT ps;
                HDC hdc = BeginPaint(hWnd, &ps);
                //TODO: 在此处添加使用 hdc 的任何绘图代码...
                EndPaint(hWnd, &ps);
            }
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
        return 0;
    }
    
    // “关于”框的消息处理程序。
    INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
        UNREFERENCED_PARAMETER(lParam);
        switch (message)
        {
        case WM_INITDIALOG:
            return (INT_PTR)TRUE;
    
        case WM_COMMAND:
            if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
            {
                EndDialog(hDlg, LOWORD(wParam));
                return (INT_PTR)TRUE;
            }
            break;
        }
        return (INT_PTR)FALSE;
    }
    


    展开全文
  • MFC双缓冲 防止闪屏

    千次阅读 2012-04-15 13:39:37
    今天帮别人看改个闪屏的问题。 弄了挺久的。。写在把解决的方法写出来。 void CWanggeView::OnDraw(CDC* pDC) { CWanggeDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for ...

    好久没有写mfc的东西了。今天帮别人看改个闪屏的问题。

    弄了挺久的。。写在把解决的方法写出来。


    void CWanggeView::OnDraw(CDC* pDC)
    {
    	CWanggeDoc* pDoc = GetDocument();
    	ASSERT_VALID(pDoc);
    	// TODO: add draw code for native data here
    	CRect rect;
    	GetClientRect(&rect);
    	//建立与屏幕设备描述表(前端缓冲区)兼容的内存设备描述表句柄(后备缓冲区)
    	MemDC.CreateCompatibleDC(NULL);
    	//这时还不能绘图,因为没有位图的设备描述表是不能绘图的
    	//下面建立一个与屏幕设备描述表(或者内存设备描述表)兼容的位图
    	MemBitmap.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());
    	//将位图选入到内存设备描述表
    	//只有选入了位图的设备描述表才有地方绘图,画到指定的位图上
    	CBitmap *pOldBit=MemDC.SelectObject(&MemBitmap);
    
    
    	//
    	//绘图什么的就写在这里。。。
    	//
    	//将后备缓冲区中的图形拷贝到前端缓冲区
    	pDC->BitBlt(0,0,rect.Width(),rect.Height(),&MemDC,0,0,SRCCOPY);
    	//绘图完成后的清理
    	MemBitmap.DeleteObject();
    	MemDC.DeleteDC();
    
    
    }


    展开全文
  • 双缓冲解决切换图片闪屏实例双缓冲解决切换图片闪屏实例
  • //在原来的基础上加上这些代码,剩下的按照原来的做,就可以解决闪屏问题 @Override public void update(Graphics src) { if(iBuffer==null) { iBuffer=createImage(this.getSize().width,this.get
  • 这个问题很影响人机交互的效果,最后通过一个大佬了解到了“双缓冲”技术,在大佬给的示例中我稍微修改了一下,现在分享给大家: 1、首先我重写了panel控件,项目(右键)–>添加新项–>自定义控件 2、添加...
  • 最近在工作需要使用C#绘制图形,看了一下绘制的函数觉得很简单就开始着手工作了,但是在实际应用的时候发现鼠标进行绘制的时候会闪屏,原因是图元重绘的时间不一致,百度一下有很多更详细的,于是参照网上的解决办法...
  • 关于双缓冲在OnPaint中解决闪屏

    千次阅读 2012-07-24 17:39:55
    但是由于刷屏一直会造成严重的闪屏,所以参照网上的方法,利用双缓冲技术进行函数重载绘制,但是一直仍旧闪屏,最后找到问题的根源,更改之后的效果确实良好,防止了屏幕出现闪屏,但是我的编码过程中也与网上的方法...
  • openGL ES双缓冲描画导致闪屏

    千次阅读 2018-08-13 11:48:50
    其实双缓冲,就是用来解决闪屏问题的。但存在这么一种情况,使得采用双缓冲描画会导致闪屏问题:一个进程(由于某些限制只能申请一个On- screen Surface)中,需要在两个不同的位置,同时显示不同的内容。 这种情况...
  • 用GDI绘制四叶草,每秒中换一种随机颜色。重绘时候利用后台缓冲技术解决图像闪屏现象。纯WIN32API,没有利用MFC。
  • 双缓冲解决重绘和闪屏问题
  • GDI+双缓冲解决图片移动的闪屏问题

    千次阅读 2008-04-12 13:39:00
    GDI+双缓冲解决图片移动的闪屏问题
  • 我在一个frame里面放入了3个panel,其中一个panel重写了paint方法并且加入双缓冲,repaint该panel,但是还是闪屏,请前辈提供思路. 如果愿意看下我的代码的话,(http://pan.baidu.com/s/1bnCcO4R),我第一次写...
  • 双缓冲作图基本思路 使用bi tbl t函数,其原理是可以支持图形块的快速复制;所以,我们可以先在内存中作图,然后使用Bi t B l t函数将内存中的图片复制到前台,同时禁止背景刷新,这样就消除了闪烁。 ...
  • 1、双缓冲机制: 至于什么是双缓冲机制,我这里简单介绍一下,大家可以上网查看别人的资料都很详细了:这种机制的原理就是第一次显示缓存A的内容,下次显示缓存B的内容,在下次又显示缓存A的内容,即两个缓存中的...
  • 网上很多文章都是在重复下面这个代码块,对于这个代码段没啥好说的,关键在于一个细节:在你重写update的时候是否把super.update()去掉了,我们重写update方法就是为了全面接管,所以去掉super.update(),问题解决!...
  •  双缓冲是一个解决闪屏很有效的方法,即在内存中创建一块与客户区大小相同的表面,在其上绘制好要画的所有图,然后通过一次位块转移操作,翻转到实际的客户区表面,最后一起显示出来。这样做的好处是可以减少了对主...
  • 双缓冲就是除了在屏幕上有图形进行显示以外,在内存中也有图形在绘制。
  • 本文主要介绍:在利用MFC画图或图像显示时,有时候需要调用OnDraw()函数刷新屏幕,而屏幕往往会发生闪烁,本文主要介绍利用双缓冲解决闪屏问题。 关于闪屏方面的介绍分析见博文: ... 博文中关于双缓冲实现部分不够...

空空如也

空空如也

1 2 3 4 5 6
收藏数 115
精华内容 46
关键字:

双缓冲解决闪屏