游戏开发论坛

 找回密码
 立即注册
搜索
查看: 2488|回复: 6

【求助】为何DDraw程序运行到创建显示表面时就会内存出

[复制链接]

5

主题

19

帖子

19

积分

新手上路

Rank: 1

积分
19
发表于 2006-3-9 11:24:00 | 显示全部楼层 |阅读模式
希望各位大大别路过,多留点意见,谢谢了!!
[em17][em17][em17][em17][em17][em17][em17][em17][em17]

问题:
    1. 当我的代码运行到创建显示表面时,就会出现内存报错,不知道是哪里设置不对...
    2. 我在设置协作级别中分别试了全屏和窗口模式,然后分步运行时发现,设为全屏时似乎
        并未调用SetCooperativeLevel函数,而如果将参数设为窗口模式(DDSCL_NORMAL)
        该函数就会被执行,不知道这是否正常现象?
所用工具:
    VC++6.0      D9.0_SDK
代码:
#include <ddraw.h>
#include <windows.h>
#include <iostream.h>

#pragma comment(lib,"ddraw.lib")
#pragma comment(lib,"dxguid.lib")

int CCreate(HWND, LPDIRECTDRAW7);                                                                                // 创建
int CRelease(LPDIRECTDRAW7);                                                                                        // 释放
int CShow(LPDIRECTDRAWSURFACE7, LPDIRECTDRAW7);                                                        // 显示

int main(void)
{
        // 创建窗体句柄
        HWND hWnd = NULL;
        // 创建 DirectDraw7 接口指针
        LPDIRECTDRAW7 lpDD7 = NULL;
        // 创建 DirectDraw7 显示表面接口指针
        LPDIRECTDRAWSURFACE7 lpDD7Primary = NULL;

        CCreate(hWnd, lpDD7);                                        // 创建窗口
        CShow(lpDD7Primary, lpDD7);                                // 显示窗口
        CRelease(lpDD7);                                                // 释放窗口
        return 0;
}

// 创建
int CCreate(HWND hWnd, LPDIRECTDRAW7 lpDD7)
{

        // 对 DirectDraw7 接口的调用
        if ( DD_OK == DirectDrawCreateEx(NULL, (void **)&lpDD7, IID_IDirectDraw7, NULL) )
        {
                cout << "Create" << endl;
        //        return E_FAIL;
        }

        // 设置协作级别
        if ( DD_OK == lpDD7->SetCooperativeLevel(hWnd, DDSCL_FULLSCREEN |
                                                                                                   DDSCL_ALLOWMODEX |
                                                                                                   DDSCL_EXCLUSIVE  |
                                                                                                   DDSCL_ALLOWREBOOT) )
        {
                cout << "Do" << endl;
        //        return E_FAIL;
        }

        // 设置显示模式
        if ( DD_OK == lpDD7->SetDisplayMode(1024, 768, 8, 0, 0) )
        {
                cout << "Show" << endl;
        //        return E_FAIL;
        }

        return S_OK;
}

// 显示
int CShow(LPDIRECTDRAWSURFACE7 lpDD7Primary,
                  LPDIRECTDRAW7 lpDD7)
{
        // 声明并填充描述DirectDraw表面的结构体
        DDSURFACEDESC2 ddsd;

        // ※填充前记得要把结构体初始化为0(使用系统宏ZeroMemory或者函数memset)※
        memset(&ddsd, 0, sizeof(ddsd));
        // 填充
        ddsd.dwSize                        = sizeof(ddsd);
        ddsd.dwFlags                = DDSD_CAPS;
        ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
       
        if ( DD_OK == lpDD7->CreateSurface(&ddsd, &lpDD7Primary, NULL) )
        {
                cout << "CreateShow" << endl;
        }

        return 0;
}

// 销毁
int CRelease(LPDIRECTDRAW7 lpDD7)
{
        if ( lpDD7 )
        {
                lpDD7->Release();
                lpDD7 = NULL;
        }

        return 0;
}

18

主题

573

帖子

573

积分

高级会员

Rank: 4

积分
573
发表于 2006-3-9 14:21:00 | 显示全部楼层

Re:【求助】为何DDraw程序运行到创建显示表面时就会内存

将函数中的指针换成二级指针或者指向指针的引用,如下:
int CCreate(HWND, LPDIRECTDRAW7 *); // 创建
int CRelease(LPDIRECTDRAW7 *); // 释放
int CShow(LPDIRECTDRAWSURFACE7 *, LPDIRECTDRAW7 *); // 显示
当然你的函数实现中也要该成这样的

在调用的时候:
CCreate(hWnd, &lpDD7); // 创建窗口
CShow(&lpDD7Primary, &lpDD7); // 显示窗口
CRelease(&lpDD7); // 释放窗口

试一下吧!

5

主题

19

帖子

19

积分

新手上路

Rank: 1

积分
19
 楼主| 发表于 2006-3-9 21:27:00 | 显示全部楼层

Re:【求助】为何DDraw程序运行到创建显示表面时就会内存


原来如此!好象确实是这样的!
谢谢了!
那个...还有,我的问题2不知道是不是属于正常啊?

18

主题

573

帖子

573

积分

高级会员

Rank: 4

积分
573
发表于 2006-3-9 22:52:00 | 显示全部楼层

Re:【求助】为何DDraw程序运行到创建显示表面时就会内存

对于第二个问题,我的理解是:
如果你给SetCooperativeLevel函数传一个NULL的HWND,默认会采用桌面的HWND(使用MessageBox函数时就是这样的情况,可参考MSDN),桌面也是一个窗体,所以也有HWND,本来桌面就是全屏幕的,你再设置它为全屏幕就会出问题了,我本来就是全屏幕,你干吗还要设置我为全屏幕,是这个理吧!当你设置为DDSCL_NORMAL时,默认的就是采用桌面作为你的绘制窗体的,后面这段话我记得在《Windows编程大师技巧》中看到过,大概就是这么个意思(时间太长了,记得不是很清楚),当然,这是我个人的理解,请大家指正!
所以我的建议是建立一个窗体,传入这个窗体的HWND给SetCooperativeLevel就可以了。

38

主题

275

帖子

281

积分

中级会员

Rank: 3Rank: 3

积分
281
QQ
发表于 2006-3-10 14:36:00 | 显示全部楼层

Re:【求助】为何DDraw程序运行到创建显示表面时就会内存

~~晕~~第一次看到写 DirectDraw程序建立控制台程序的~小弟真是见识浅薄了~~这样的话~那不就跟在DOS下做游戏一样了?~~
  我试了试~还真行~~在传 hWnd时  我用了GetForegroundWindow,好象就可以了~~SetCoopertiveLevel调用成功,返回DD_OK~~

5

主题

19

帖子

19

积分

新手上路

Rank: 1

积分
19
 楼主| 发表于 2006-3-10 23:15:00 | 显示全部楼层

Re:【求助】为何DDraw程序运行到创建显示表面时就会内存

今天刚刚弄明白,的确是因为所传的窗体句柄为空导致的!

并且对于我的第一个问题,似乎只要把代码封装成类就可以解决了,后来想了一想,可能与
函数内的行参作为值传递时会出现问题类似...

5楼的大大所说的,其实我只是想搞一个比较简单的环境验证一下这些函数,呵呵,做的不好
还请大大们别笑我~多提点意见!

谢谢了!

5

主题

19

帖子

19

积分

新手上路

Rank: 1

积分
19
 楼主| 发表于 2006-3-10 23:19:00 | 显示全部楼层

Re:【求助】为何DDraw程序运行到创建显示表面时就会内存

PS:
这段时间在研究的书正是4楼大大所说的《WINDOWS游戏编程大师技巧》
果然是很经典的书啊~并且计划有可能的话还要继续学习《3D游戏编程大师技巧》
呵呵~
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-1-23 21:13

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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