游戏开发论坛

 找回密码
 立即注册
搜索
查看: 3543|回复: 3

[求助]BitBlt绘制滚动屏幕闪烁问题

[复制链接]

4

主题

6

帖子

14

积分

新手上路

Rank: 1

积分
14
发表于 2009-6-21 13:24:00 | 显示全部楼层 |阅读模式
大家好,我刚开始学习WINDOWS编程,刚接触到BitBlt函数,可是利用该函数绘制了一个滚动屏幕,但是滚动的不流畅,而且闪烁很厉害,我想问下该如何消除BitBlt函数的闪烁情况,如何实现双缓冲。以下是我自己写的代码,写上了注释,这是什么原因?

#include <windows.h>
#include <tchar.h>

#include "resource.h"

float y = 0;                                                                                // 背景图片的Y坐标

/*
函数类型:        windows消息处理函数
函数功能:        处理        WM_PAINT消息:对屏幕进行位图绘制
                                        WM_DESTROY消息:在window退出时,销毁所有使用内存
*/
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
        PAINTSTRUCT ps;                                                                        // 声明绘图PAINTSTRUCT结构
        HDC hdc;                                                                                // 获得当前设备环境
        HDC hdcMem;                                                                                // 声明内存中的设备环境
        HBITMAP hbmp;                                                                        // 声明位图句柄
        BITMAP bmp;                                                                                // 声明位图图像
       
        // 消息处理
        switch(msg) {
        // WM_PAINT消息处理
        case WM_PAINT:
                hdc = BeginPaint(hWnd, &ps);
                hdcMem = CreateCompatibleDC(hdc);
                hbmp = (HBITMAP)LoadImage(NULL, "back.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
                GetObject(hbmp, sizeof(BITMAP), &bmp);
                SelectObject(hdcMem, hbmp);

                BitBlt(hdc, 0, y, bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY);

                EndPaint(hWnd, &ps);
                break;
        // WM_DESTROY消息处理
        case WM_DESTROY:
                PostQuitMessage(0);
                break;
        default:
                return DefWindowProc(hWnd, msg, wParam, lParam);
        }
        return 0;
}

/*
函数类型:        WinMain主函数程序入口
函数功能:        1.窗体的创建
                        2.菜单的加载
                        3.消息的监听
*/
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR lCmdLine, int nCmdShow) {
        // 声明一个窗体
        WNDCLASSEX wcex;
       
        // 设置窗体消息
        wcex.cbSize = sizeof(WNDCLASSEX);
        wcex.style = CS_HREDRAW | CS_VREDRAW;
        wcex.cbClsExtra = 0;
        wcex.cbWndExtra = 0;
        wcex.lpfnWndProc = (WNDPROC)WndProc;
        wcex.hIcon = NULL;
        wcex.hIconSm = NULL;
        wcex.hInstance = hInstance;
        wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
        wcex.lpszClassName = "sunhuiwei";
        wcex.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);
        wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
       
        // 注册窗体
        RegisterClassEx(&wcex);
       
        // 创建窗体句柄
        HWND hWnd = CreateWindowEx(0, "sunhuiwei", "孙惠伟", WS_OVERLAPPEDWINDOW, 200, 200, 1280, 720, HWND_DESKTOP, NULL, hInstance, NULL);

        if(!hWnd) {
                return FALSE;
        }
       
        // 显示和更新窗体
        ShowWindow(hWnd, nCmdShow);
        UpdateWindow(hWnd);
       
        // 声明一个消息
        MSG msg;
       
        // 对消息进行循环监听
        while(GetMessage(&msg, NULL, 0, 0)) {
                TranslateMessage(&msg);
                DispatchMessage(&msg);

                if(y > 600) {
                        y = 0;
                }
                else {
                        y += 2;
                }

                InvalidateRect(hWnd, NULL, true);
                Sleep(75);
        }

        return msg.wParam;
}

0

主题

398

帖子

577

积分

高级会员

Rank: 4

积分
577
发表于 2009-6-22 11:41:00 | 显示全部楼层

Re:[求助]BitBlt绘制滚动屏幕闪烁问题

自己去看GDI绘图的例程,效率低下的原因很明显,不去自己思考就问别人永远不会有提高。双缓冲的实现方法大致就是:创建一个Compatible的Bitmap,然后将你所要绘制的图形绘制到这个Bitmap上(如果有必要在每帧绘制前需要擦除原来的图像),然后把这个Bitmap刷新到最终的窗口DC上,这个刷新过程是不需要擦除DC上原有图像的,否则会闪。
还有你使用的GDI资源都没有释放,这会导致严重问题。一般写代码时最好成对写创建和销毁资源的代码以防止遗忘而造成的内存泄露。

4

主题

6

帖子

14

积分

新手上路

Rank: 1

积分
14
 楼主| 发表于 2009-6-22 21:08:00 | 显示全部楼层

Re:[求助]BitBlt绘制滚动屏幕闪烁问题

谢谢,我在研究下

3

主题

11

帖子

15

积分

新手上路

Rank: 1

积分
15
发表于 2009-6-25 15:41:00 | 显示全部楼层

Re:[求助]BitBlt绘制滚动屏幕闪烁问题

加载图片有缓慢的I/0操作, 你应在外面加载图片。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-12-19 21:31

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表