游戏开发论坛

 找回密码
 立即注册
搜索
查看: 3906|回复: 7

大家帮我看看我的程序错在什么地方

[复制链接]

2

主题

8

帖子

14

积分

新手上路

Rank: 1

积分
14
发表于 2004-2-13 18:16:00 | 显示全部楼层 |阅读模式
这个程序的目的是显示图片,但运行后显示花屏,我怀疑是某些东西没有释放

#include <windows.h>
#include "ddraw.h"

// 变量、声明函数;
LPDIRECTDRAW              pDD7;  //声明DirectDraw对象
LPDIRECTDRAWSURFACE       pPSur; //声明主绘图页
LPDIRECTDRAWSURFACE       pBBuf; //声明后缓冲区
LPDIRECTDRAWSURFACE       pOPla; //声明幕后内存区
DDSCAPS  caps;                   //声明DDSCAPS结构
DDSURFACEDESC             desc;  //声明描述结构
HRESULT result;                   //声明HRESULT类型变量
char Sz1[]="嗨,这是我的第一个DirectX程序";
char Sz2[]="按ESC键退出程序";

// 函数原型:消息处理过程
LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
BOOL InitDDraw(void);                               // 初始化DirectDraw;
void UninitDDraw(void);
BOOL InitWindow(HINSTANCE hInstance, int nCmdShow); // 函数原型:创建主工作窗口;  

BOOL InitWindow(HINSTANCE hInstance, int nCmdShow)
{
    HWND hwnd;     // 窗口句柄;
    WNDCLASS wcex; // 窗口类结构;

    // 设置窗口类结构;
    wcex.style=1;                       // 风格;一般用CW_HREDRAW|CW_VREDRAW:长宽改变则发重绘消息
    wcex.lpfnWndProc=WinProc;           // 窗口处理程序;
    wcex.cbClsExtra=0;                  // 扩充风格;
    wcex.cbWndExtra=0;                  // 扩充程序;
    wcex.hInstance=hInstance;           // 应用程序hInstance句柄;
    wcex.hIcon=LoadIcon(hInstance,IDI_APPLICATION); // 读入默认的图标;
    wcex.hCursor=LoadCursor(NULL,IDC_ARROW);        // 读入默认鼠标形状;
    wcex.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);//窗口背景;
    wcex.lpszMenuName=NULL;               // 窗口目录;
    wcex.lpszClassName= "DirectX--Hello"; // 窗口的类名
   
    // 注册窗口类;
    RegisterClass(&wcex);

// 创建主窗口;
    hwnd=CreateWindowEx(WS_EX_TOPMOST,
                                "DirectX--Hello",
                                "",
                                                WS_OVERLAPPEDWINDOW,   //窗口风格OVERLAPPED风格(和记事本一样的),
                                                //WS_POPUP|WS_VISIBLE, //全屏显示
                        0,
                                                0,
                                                GetSystemMetrics(SM_CXSCREEN),
                        GetSystemMetrics(SM_CYSCREEN),
                                                NULL,       //父窗口句柄,程序没有,所以设为NULL
                                                NULL,       //菜单句柄没有为NULL
                                                hInstance,  //WinMain传递的实例句柄
                                                NULL);
if(!hwnd) return FALSE;
    ShowWindow(hwnd,nCmdShow); // 显示窗口;
    UpdateWindow(hwnd);        // 更新窗口;
    return TRUE;
}


LRESULT CALLBACK WinProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
    switch(message)       // 接受消息循环的函数,采用switch处理各种消息
    {
    case WM_KEYDOWN:    // 如果击键;
        switch(wParam)
        {
        case VK_ESCAPE: // Esc键;
UninitDDraw();
            PostMessage(hWnd,WM_CLOSE,0,0);
            break;
        }
        break;
    case WM_DESTROY:    // 退出消息循环;
        UninitDDraw();
        PostQuitMessage(0);
        break;
    }
    // 调用缺省消息处理过程;
    return DefWindowProc(hWnd,message,wParam,lParam);
}
//************************************************************
//函数:WinMain( )
//功能:Windows程序入口函数。创建主窗口,处理消息循环
//************************************************************
int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
if ( !InitWindow( hInstance, nCmdShow ) ) return FALSE; //创建主窗口
//如果创建不成功则返回FALSE并同时退出程序
// 初始化DirectDraw环境,并实现DirectDraw功能;
    if (!InitDDraw())
    {
        MessageBox(GetActiveWindow(),"初始化DirectDraw时出错!",
                   "Error",MB_OK);
        UninitDDraw();
        DestroyWindow(GetActiveWindow());
        return FALSE;
    }
MSG msg;
//进入消息循环:
for(;;)
{
        if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
                if ( msg.message==WM_QUIT) break;
                TranslateMessage(&msg);
                DispatchMessage(&msg);
        }
}
return msg.wParam;
}

// 本程序的最核心内容,即DirectDraw的基本功能与用法;
BOOL InitDDraw(void)
{
   
    HDC hdc,hdc1;
        HBITMAP bitmap;
RECT rect = { 0, 0, 640, 480 };
    // 创建DirectDraw对象;
    result=DirectDrawCreate(NULL,&pDD7,NULL);
    if (result!=DD_OK)
MessageBox(GetActiveWindow(),"创建DirectDraw对象失败!","Mouse",MB_OK);


        // 设置为全屏模式;
result=pDD7->SetCooperativeLevel(GetActiveWindow(),   //设置 DirectDraw 的控制级
    DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN);
    if (result!=DD_OK)
MessageBox(GetActiveWindow(),"设置全屏模式失败!","Mouse",MB_OK);

    // 设置显示模式;
result=pDD7->SetDisplayMode(800,600,16);
    if (result!=DD_OK)
MessageBox(GetActiveWindow(),"设置显示模式失败!","Mouse",MB_OK);

    // 设置主页面信息;
    memset(&desc,0,sizeof(desc));     
//        ZeroMemory(&desc,sizeof(desc));
        desc.dwSize = sizeof(desc);           
        desc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
        desc.dwBackBufferCount = 1;        
desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
    // 创建一个表面,类似开辟一块屏幕大小的显示内存;
    result=pDD7->CreateSurface(&desc,&pPSur,NULL);
    if (result!=DD_OK)
   MessageBox(GetActiveWindow(),"建立主绘图页失败!","Mouse",MB_OK);

caps.dwCaps = DDSCAPS_BACKBUFFER;  
        result = pPSur->GetAttachedSurface(&caps,&pBBuf);         //连结后缓冲区
        if(result !=DD_OK)
                 MessageBox(GetActiveWindow(),"连结后缓冲区失败!","Mouse",MB_OK);

memset(&desc,0,sizeof(desc));        
        desc.dwSize = sizeof(desc);
        desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
        desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN ;
        desc.dwWidth = 640;
        desc.dwHeight = 480;
        result = pDD7->CreateSurface(&desc, &pOPla, NULL);
        //建立幕后内存区
        if(result !=DD_OK)
          MessageBox(GetActiveWindow(),"建立幕后内存区失败!","Mouse",MB_OK);
//-----------------------------------------------------------
hdc = ::CreateCompatibleDC(NULL);
bitmap = (HBITMAP):oadImage(NULL,"bground.bmp",IMAGE_BITMAP,640,480,LR_LOADFROMFILE); //载入图档
::SelectObject(hdc,bitmap);       //设定hdc中的位图为bitmap
        pOPla->GetDC( &hdc1 );            //取得幕后内存区的DC
        ::BitBlt( hdc1 , 0 , 0 , 800 , 600 , hdc , 0 , 0 , SRCCOPY ); //将位图复制到幕后内存区中
        pOPla->ReleaseDC( hdc1 );         //释放DC
DeleteDC(hdc);
//-----------------------------------------------
pBBuf->BltFast( 100 , 200 , pOPla, &rect, DDBLTFAST_WAIT );
        pPSur->Flip( NULL , DDFLIP_WAIT );
pOPla->Release();
//==========================================
return TRUE;
}

void UninitDDraw(void)//卸载DirectDraw;
{

   
        if(pPSur!=NULL)
        {
            pPSur->Release();
            pPSur=NULL;
        }
        if(pOPla!=NULL)
        {
            pOPla->Release();
            pOPla=NULL;
        }
if(pDD7!=NULL)
    {
        pDD7->Release();
        pDD7=NULL;
    }
}


      

30

主题

298

帖子

299

积分

中级会员

Rank: 3Rank: 3

积分
299
QQ
发表于 2004-2-13 19:47:00 | 显示全部楼层

Re:大家帮我看看我的程序错在什么地方

能不能详细描述一下花屏特征。

你可以试一下在使用后台缓冲之前先用某种颜色填充一下,或者一次BLT整屏大小的位图。你说的花屏可能是使用没有清零的显存造成的。

2

主题

8

帖子

14

积分

新手上路

Rank: 1

积分
14
 楼主| 发表于 2004-2-14 00:08:00 | 显示全部楼层

Re:大家帮我看看我的程序错在什么地方

第一次运行的时候可以显示图片,但我换了图片后,重新编译、连接,运行时看到的还是原来那张图片,重起机子后再次运行出现花屏。


我估计是没有释放某些东西,但是不知道少了什么

30

主题

298

帖子

299

积分

中级会员

Rank: 3Rank: 3

积分
299
QQ
发表于 2004-2-14 00:20:00 | 显示全部楼层

Re:大家帮我看看我的程序错在什么地方

你说的花屏是屏幕上的图像在闪烁,还是出现杂乱的色块

30

主题

298

帖子

299

积分

中级会员

Rank: 3Rank: 3

积分
299
QQ
发表于 2004-2-14 01:07:00 | 显示全部楼层

Re:大家帮我看看我的程序错在什么地方

出现色块的话,可能是显卡上的显存颗粒损坏或是显卡金手指接触不良这一类的原因。

仔细看了一下你的代码:
rect是这样定义的:RECT rect = { 0, 0, 640, 480 };

而这一行:pBBuf->BltFast( 100 , 200 , pOPla, &rect, DDBLTFAST_WAIT );
应该是不会执行成功的。

因为:
BltFast方法是不能对要BLT的图像做裁剪的。

所以:
因为BltFast方法没有成功,所以后台缓冲里还是以前的程序使用过后的遗留的废数据,因而造成花屏。

PS:你说第一次运行可以显示图片,这点我很奇怪。

2

主题

8

帖子

14

积分

新手上路

Rank: 1

积分
14
 楼主| 发表于 2004-2-16 17:27:00 | 显示全部楼层

Re:大家帮我看看我的程序错在什么地方

非常感谢你的回复,我马上去试一下

2

主题

8

帖子

14

积分

新手上路

Rank: 1

积分
14
 楼主| 发表于 2004-2-16 17:29:00 | 显示全部楼层

Re:大家帮我看看我的程序错在什么地方

忘了讲了,是出现色块

2

主题

8

帖子

14

积分

新手上路

Rank: 1

积分
14
 楼主| 发表于 2004-2-16 22:48:00 | 显示全部楼层

Re:大家帮我看看我的程序错在什么地方

我加了一段:

pOPla->GetSurfaceDesc(&desc);
int width,height;
width = desc.dwWidth;  height = desc.dwHeight;
RECT rcArea;
rcArea.left=0; rcArea.top=0; rcArea.right=width; rcArea.bottom=height;

pBBuf->BltFast(0,0,pOPla,&rcArea,DDBLTFAST_WAIT);

现在终于可以显示图片了,这是我第一次成功的程序,再次感谢!

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-2-25 06:24

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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