| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 5090 人关注过本帖
标题:请教客户区画面抖动问题
只看楼主 加入收藏
菜鸟AB
Rank: 1
等 级:新手上路
帖 子:16
专家分:0
注 册:2015-5-13
结帖率:100%
收藏
已结贴  问题点数:20 回复次数:16 
请教客户区画面抖动问题
取名字大侠,我又来麻烦您了,同时恭祝荣升斑竹。
我要做一个象棋棋盘在客户区显示。
象棋棋盘位图在RC中
创建标准窗口,用WNDCLASSEX注册窗口类。
在WM_CREATE中建立DC,LoadBitmap位图句柄,
句柄选入DC,然后WM_PAINT中BitBlt位图DC,
这样的代码安排,鼠标在边框放大或缩小时,位图
会闪烁很严重。
百度双缓冲,拷贝些原代码,经过测试,均闪烁。
老罗书中演示了一个双缓冲,是时间钟程序,但他的
窗口很小,并且是不可放大或缩小,用的是
invoke    InvalidateRect,hWnd,NULL,FALSH,
我的窗口是要能放大与缩小的,不适用老罗的代码。
请问怎样能使象棋棋盘位图在客户区中放大或缩小窗口
时不闪烁。
搜索更多相关主题的帖子: 百度 取名字 象棋 
2015-07-07 15:16
菜鸟AB
Rank: 1
等 级:新手上路
帖 子:16
专家分:0
注 册:2015-5-13
收藏
得分:0 
有段百度的文章,摘录片段
我们的绘图过程大多放在OnDraw或者OnPaint函数中,OnDraw在进行屏幕显示时是由OnPaint进行调用的。当窗口由于任何原因需要重绘时,总是先用背景色将显示区清除,然后才调用OnPaint,而背景色往往与绘图内容反差很大,这样在短时间内背景色与显示图形的交替出现,使得显示窗口看起来在闪。
有的人会说,闪烁是因为绘图的速度太慢或者显示的图形太复杂造成的,其实这样说并不对,绘图的显示速度对闪烁的影响不是根本性的。
在图形图象处理编程过程中,双缓冲是一种基本的技术。我们知道,如果窗体在响应WM_PAINT消息的时候要进行复杂的图形处理,那么窗体在重绘时由于过频的刷新而引起闪烁现象。解决这一问题的有效方法就是双缓冲技术。
因为窗体在刷新时,总要有一个擦除原来图象的过程OnEraseBkgnd,它利用背景色填充窗体绘图区,然后在调用新的绘图代码进行重绘,这样一擦一写造成了图象颜色的反差。当WM_PAINT的响应很频繁的时候,这种反差也就越发明显。于是我们就看到了闪烁现象。
个人总结:这里的双缓冲,是局限特定环境的,需要窗口不可放大缩小,由InvalidateRect引发刷新
我需要窗口可自由放大缩小。但这时候刷新为被动刷新,系统会永远先用背景色将显示区清除,
背景色与显示图形的交替出现,形成闪烁。
求解决之道
2015-07-07 19:42
取名字
Rank: 8Rank: 8
等 级:贵宾
威 望:21
帖 子:236
专家分:924
注 册:2015-4-27
收藏
得分:20 
楼主能不能放上原码看一下。
2015-07-08 14:59
菜鸟AB
Rank: 1
等 级:新手上路
帖 子:16
专家分:0
注 册:2015-5-13
收藏
得分:0 
好,等我
2015-07-08 15:22
菜鸟AB
Rank: 1
等 级:新手上路
帖 子:16
专家分:0
注 册:2015-5-13
收藏
得分:0 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        .386
        .model flat,stdcall
        option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include        windows.inc
include        gdi32.inc
includelib    gdi32.lib
include        user32.inc
includelib    user32.lib
include        kernel32.inc
includelib    kernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
wt_wt        equ    300
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        .data?
hInstance    dd        ?
hWinMain    dd        ?
hDc        dd        ?
hwt        dd        ?
        .const
szClassName    db    'MyClass',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        .code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 窗口过程
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcWinMain    proc    uses ebx edi esi,hWnd,uMsg,wParam,lParam
        local    @stPs:PAINTSTRUCT
        local    @stRect:RECT
        local    @hDc
        mov    eax,uMsg
;********************************************************************
        .if    eax ==    WM_PAINT
            invoke    BeginPaint,hWnd,addr @stPs
            mov    @hDc,eax
            invoke    BitBlt,@hDc,0,0,448,496,hDc,0,0,SRCCOPY            
            invoke    EndPaint,hWnd,addr @stPs
;********************************************************************
        .elseif    eax ==    WM_CREATE
            invoke    GetDC,hWinMain
            push    eax
            invoke    CreateCompatibleDC,eax
            mov    hDc,eax
            pop    eax
            invoke    ReleaseDC,hWinMain,eax
            invoke    LoadBitmap,hInstance,wt_wt
            mov    hwt,eax
            invoke    SelectObject,hDc,hwt
        .elseif    eax ==    WM_CLOSE
            invoke    DestroyWindow,hWinMain
            invoke    PostQuitMessage,NULL
            invoke    DeleteDC,hDc
            invoke    DeleteObject,hwt
;********************************************************************
        .else
            invoke    DefWindowProc,hWnd,uMsg,wParam,lParam
            ret
        .endif
;********************************************************************
        xor    eax,eax
        ret

_ProcWinMain    endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_WinMain    proc
        local    @stWndClass:WNDCLASSEX
        local    @stMsg:MSG
        invoke    GetModuleHandle,NULL
        mov    hInstance,eax
        invoke    RtlZeroMemory,addr @stWndClass,sizeof @stWndClass
;********************************************************************
; 注册窗口类
;********************************************************************
        invoke    LoadCursor,0,IDC_ARROW
        mov    @stWndClass.hCursor,eax
        push    hInstance
        pop    @stWndClass.hInstance
        mov    @stWndClass.cbSize,sizeof WNDCLASSEX
        mov    @stWndClass.style,CS_HREDRAW or CS_VREDRAW
        mov    @stWndClass.lpfnWndProc,offset _ProcWinMain
        mov    @stWndClass.hbrBackground,COLOR_WINDOW + 1
        mov    @stWndClass.lpszClassName,offset szClassName
        invoke    RegisterClassEx,addr @stWndClass        
;********************************************************************
; 建立并显示窗口
;********************************************************************
        invoke    CreateWindowEx,WS_EX_CLIENTEDGE,offset szClassName,NULL,\
            WS_OVERLAPPEDWINDOW,\
            100,100,500,600,\
            NULL,NULL,hInstance,NULL
        mov    hWinMain,eax
        invoke    ShowWindow,hWinMain,SW_SHOWNORMAL
        invoke    UpdateWindow,hWinMain
;********************************************************************
; 消息循环
;********************************************************************
        .while    TRUE
            invoke    GetMessage,addr @stMsg,NULL,0,0
            .break    .if eax    == 0
            invoke    TranslateMessage,addr @stMsg
            invoke    DispatchMessage,addr @stMsg
        .endw
        ret

_WinMain    endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
        call    _WinMain
        invoke    ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        end    start
2015-07-08 15:41
菜鸟AB
Rank: 1
等 级:新手上路
帖 子:16
专家分:0
注 册:2015-5-13
收藏
得分:0 
RC文件就2句

#define wt_wt 300
wt_wt BITMAP "xq.bmp"

这个位图是象棋棋盘,448*496
2015-07-08 15:43
取名字
Rank: 8Rank: 8
等 级:贵宾
威 望:21
帖 子:236
专家分:924
注 册:2015-4-27
收藏
得分:0 
大侠不敢当,或许有些方面我不如你,我们一起探讨,一起学习,一起进步。

编译并运行了一下楼主的程序,在我的机子上测试:
在标题栏上通过双击改变窗口大小、拖动边框改变窗口大小,闪烁并不明显,可以认为这是一种正常现象。
我感觉闪烁还是和机器的处理速度有关,机器的处理速度够快,屏幕的刷新频率自然也快,快到我们人眼分辨不出来了,自然就看不到闪烁了。
就像我们调计算机的刷新频率一样,如果我们把刷新频率调低,就可以看到屏幕的闪烁很严重,把刷新频率调高,就看不出来屏幕在闪烁。

利用缓冲技术,可以将窗口改变后前景图片和背景图片计算好,然后再拷贝过去,这样或许可以解决闪烁的问题,但如果机器处理速度不快的话,在计算前景图片和背景图片时所耗时间过多,会导致客户区无反映。
2015-07-08 16:57
取名字
Rank: 8Rank: 8
等 级:贵宾
威 望:21
帖 子:236
专家分:924
注 册:2015-4-27
收藏
得分:0 
如果在窗口大小改变时,不作其他改变,可以把这句去掉“mov    @stWndClass.style,CS_HREDRAW or CS_VREDRAW”,取消在窗口大小变化时重绘窗口,就看不到闪烁了。
2015-07-08 17:15
菜鸟AB
Rank: 1
等 级:新手上路
帖 子:16
专家分:0
注 册:2015-5-13
收藏
得分:0 
版主,我现在希望在客户区贴张500*500左右位图,然后拖动边框改变窗口大小,
不希望位图出现闪烁,怎么解决。
能不能辛苦写下代码,我运行运行
不胜感激,困扰我一个月了
2015-07-08 17:15
菜鸟AB
Rank: 1
等 级:新手上路
帖 子:16
专家分:0
注 册:2015-5-13
收藏
得分:0 
mov    @stWndClass.style,CS_HREDRAW or CS_VREDRAW
这句我仔细看看
2015-07-08 17:16
快速回复:请教客户区画面抖动问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.017419 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved