norains的专栏

只专注于WINCE开发

用户操作
[即时聊天] [发私信] [加为好友]
norainsID:norains
142878次访问,排名598,好友0人,关注者53人。
代码其实是一种乐趣
norains的文章
原创 189 篇
翻译 0 篇
转载 10 篇
评论 274 篇
norains的公告
联系方式请看置顶文章
最近评论
dfdf:讨厌MFC!我觉得MFC就是太乱了!看似无用的代码不要不行,MD微软啥都给我们做完了,原理性的东西我们却永远没法搞懂了!
ironox:有个地方 我觉得很别扭,不知道怎么办好

比如说 CReg reg(HKEY_CURRENT_USER,TEXT("ControlPanel\Volume"));
ControlPanel\Volume 有可能不存在呀,这个该怎么处理哦?对象虽然创建了,出错了也没提示
szterry:呵呵,果然工作狂技术狂,同感,一样的感觉……不过我才刚毕业一年……搞IT就是玩……
jinlking:这个botton的实现只是在主窗口画了一块区域,对于事件的处理还要放在主窗口的窗口处理函数之中,在对应的消息处理上调用CheckTap来判断是否是此“按钮”,问一下,这种方法与把按钮封装在子窗口中有什么区别,二者使用那个更好?
KUODY:博主真是好人
文章分类
收藏
    相册
    动漫
    文章图片
    程序交流
    xumercury的BLOG
    狗友们的博客
    清蒸石斑鱼
    美女如刀锋
    茁茁的BLOG
    魅力老姐的窝
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 轻松消除贴图闪烁收藏

    新一篇: MultiByteToWideChar和WideCharToMultiByte用法详解 | 旧一篇: windows防火墙不能自动运行的问题解决一例

    //========================================================================
    //TITLE:
    //    轻松消除贴图闪烁
    //AUTHOR:
    //    norains
    //DATE:
    //    Thursday  25-December -2006
    //Environment:
    //  EVC4.0 + Standard SDK
    //========================================================================
        有没有在程序中尝试过贴图?我们都有这么一个经验,如果直接往屏幕贴图,一张图我们觉得显示正常流畅;两张图,如果图片不大,并且速度也够快的话,我们也觉得没问题;但如果,有一张很大的位图,并且我们需要在位图上面输出文本,甚至在这张位图上面还要再贴另外的位图----可能是两张,也可能是十张,甚至是百张----那展现在我们面前的将是什么呢?我们将看到,屏幕上位图缓慢地一张一张出现,造成一种让人烦躁的闪烁效果.
        那有没有办法实现上面所需的功能,并且又不显得闪烁呢?方法当然有,并且也极为简单.一句话,就是把所有的数据往内存里写,然后再把内存的数据显示到屏幕上.
        好了,那现在让我们开始吧!
       
        首先,让我们获取一个屏幕的DC.这个DC嘛,就是显示给我们看的屏幕的设备.
        HDC hdc = GetDC(m_hWnd);
       
        如果代码是用来响应WM_PAINT,那么这个DC句柄的获得应该使用另外一个函数:
        HDC hdc = BeginPaint(m_hWnd,&ps);
       
        嗯,接下来我们要做的就是,创建一个和设备DC相符合的内存DC.换句话说,就是开辟一块内存空间,并且这空间的大小足以用来表示设备DC的数据.
        HDC hdcMem = CreateCompatibleDC(hdc);
       
        内存分配完毕之后,我们需要告诉程序这内存是用来干什么的,也就是说,这内存的格式是什么.这和变量声明比较像,不过却更为复杂.
      最初,我们需要创建一个符合目前设备DC的位图格式:
      HBITMAP hBitmap = CreateCompatibleBitmap(hdc,IMG_MAINWND_WIDTH,IMG_MAINWND_HEIGHT);
      
      最后就是把创建的这个位图和内存DC关联.
      HGDIOBJ hOldSel = SelectObject(hdcMem,hBitmap);
      
      好了,供贴图的内存已经准备好了,现在我们想干嘛就可以干嘛了.嗯,那我们还是赶快尝试一把吧.好,就先从位图绘制开始吧.
      由于位图的绘制比较复杂,并且其数据必须要和内存关联,然后才能读取位图的数据.所以我们第一步还是需要先建立一个适合设备DC的位图DC:
      HDC hdcBmp = CreateCompatibleDC(hdc);
      
      读取位图数据:
      HANDLE hBmp= LoadImage(m_hInst,MAKEINTRESOURCE(IDB_MAINWND),IMAGE_BITMAP,0,0,0);
      
      将位图数据和位图DC关联起来:
      HGDIOBJ hOldBmpSel = SelectObject(hdcBmp,hBmp);
      
      将位图数据复制到内存DC中:
      BitBlt(hdcMem,0,0,IMG_MAINWND_WIDTH,IMG_MAINWND_HEIGHT,hdcBmp,0,0,SRCCOPY);
      
      好了,现在位图已经绘制到内存去了,看起来也不是很复杂嘛!
      
      如果我们想在内存中输出文本,该怎么做呢?呵呵,这比绘制位图要简单多了:
      DrawText(hdcMem,TEXT("输出文本"),-1,&rc,DT_LEFT);
      
      嗯,就是这样,仅仅一条语句.如果还想让输出的文本背景透明,并且也想改变字体的颜色,在绘图前我们之需要添加以下语句即可:
      COLORREF oldColor;
      SetBkMode(hdcMem,TRANSPARENT);
      oldColor = SetTextColor(hdcMem,RGB(40,96,170));
      
      当然,绘制完毕之后,把原来的颜色还原是一个好习惯:
      SetTextColor(hdcMem,oldColor);
      
      做到现在,是不是已经迫不及待地想将成果显示到屏幕上了呢?好,那就让我们看看成果吧: 
      BitBlt(hdc,rc.left,rc.top,(rc.right - rc.left),(rc.bottom - rc.top),hdcMem,rc.left,rc.top,SRCCOPY);
      
      怎么样?是不是显示得非常流畅,完全没有闪烁的现象?
      
      做到这里,是不是非常高兴,就想着拿这段代码去应用了?等等,先别急,我们还需要清除一下我们狂欢后留下的垃圾,否则,系统这家伙就要生气,说不定就会来个蓝屏当机哦!
      SelectObject(hdcBmp,hOldBmpSel);
      SelectObject(hdcMem,hOldSel);
      DeleteObject(hBitmap);
      DeleteDC(hdcMem);
      ReleaseDC(m_hWnd,hdc); //如果是响应WM_PAINT消息,这里应改成:EndPaint(m_hWnd,&ps);
      
      如果我们想做得更完美一些,甚至可以不用响应WM_ERASEBKGND消息.因为WM_ERASEBKGND会占用一帧来绘制.所以我们需要做的是,只要检测到WM_ERASEBKGND消息,直接返回.
      
      附录1.
      无闪烁的完整代码(其中的一些未知变量,窗口句柄需根据实际情况更改):
      HDC hdc = GetDC(m_hWnd);
      //Create a DC that matches the device
      HBITMAP hBitmap = CreateCompatibleBitmap(hdc,IMG_MAINWND_WIDTH,IMG_MAINWND_HEIGHT);
      HDC hdcMem = CreateCompatibleDC(hdc);
      //Select the bitmap into to the compatible device context
      HGDIOBJ hOldSel = SelectObject(hdcMem,hBitmap);
      
      //Create a DC that matches the device
      HDC hdcBmp = CreateCompatibleDC(hdc);
      //Load the bitmap
      HANDLE hBmp= LoadImage(m_hInst,MAKEINTRESOURCE(IDB_MAINWND),IMAGE_BITMAP,0,0,0);
      //Select the bitmap into to the compatible device context
      HGDIOBJ hOldBmpSel = SelectObject(hdcBmp,hBmp);
      //Copy the bitmap image to the memory DC
      BitBlt(hdcMem,0,0,IMG_MAINWND_WIDTH,IMG_MAINWND_HEIGHT,hdcBmp,0,0,SRCCOPY);
     
      COLORREF oldColor;
      SetBkMode(hdcMem,TRANSPARENT);
      oldColor = SetTextColor(hdcMem,RGB(40,96,170));
      DrawText(hdcMem,lpcszText,-1,&m_rcInfoArea,DT_LEFT);
      SetTextColor(hdcMem,oldColor);
      
      BitBlt(hdc,m_rcInfoArea.left,m_rcInfoArea.top,(m_rcInfoArea.right - m_rcInfoArea.left),(m_rcInfoArea.bottom - m_rcInfoArea.top),hdcMem,m_rcInfoArea.left,m_rcInfoArea.top,SRCCOPY);
      //Restore original bitmap selection and destroy the memory DC
      SelectObject(hdcBmp,hOldBmpSel);
      SelectObject(hdcMem,hOldSel);
      DeleteObject(hBitmap);
      DeleteDC(hdcMem);
      ReleaseDC(m_hWnd,hdc);
      
      
      附录2
      会闪烁的代码
       InvalidateRect(m_hWnd,&m_rcInfoArea,TRUE);
       
       HDC hdc = GetDC(m_hWnd);
       //Create a DC that matches the device
       HDC hdcBmp = CreateCompatibleDC(hdc);
       //Load the bitmap
       HANDLE hBmp= LoadImage(m_hInst,MAKEINTRESOURCE(IDB_MAINWND),IMAGE_BITMAP,0,0,0);
       //Select the bitmap into to the compatible device context
       HGDIOBJ hOldSel = SelectObject(hdcBmp,hBmp);
       //Get the bitmap dimensions from the bitmap
       BITMAP bmp;
       GetObject(hBmp,sizeof(BITMAP),&bmp);
       //Copy the bitmap image from the memory DC to the screen DC
       BitBlt(hdc,m_rcInfoArea.left,m_rcInfoArea.top,(m_rcInfoArea.right - m_rcInfoArea.left),(m_rcInfoArea.bottom - m_rcInfoArea.top),hdcBmp,m_rcInfoArea.left,m_rcInfoArea.top,SRCCOPY);
       //Restore original bitmap selection and destroy the memory DC
       SelectObject(hdcBmp,hOldSel); 
      
       COLORREF oldColor;
       SetBkMode(hdc,TRANSPARENT);
       oldColor = SetTextColor(hdc,RGB(40,96,170));
       DrawText(hdc,lpcszText,-1,&m_rcInfoArea,DT_LEFT);
       SetTextColor(hdc,oldColor);
       
       DeleteDC(hdcBmp);
       ReleaseDC(m_hWnd,hdc);

    发表于 @ 2006年12月25日 22:43:00|评论(loading...)|编辑

    新一篇: MultiByteToWideChar和WideCharToMultiByte用法详解 | 旧一篇: windows防火墙不能自动运行的问题解决一例

    评论:没有评论。

    发表评论  


    登录
    Csdn Blog version 3.1a
    Copyright © norains