我在用Directdraw向画面输出文字时出了问题,请大家看一看

时间:2023-01-04 14:14:41
输出文字的代码
if (lpDDSPrimary->GetDC(&hdc) == DD_OK) //拿句柄

     SetBkColor(hdc, RGB(0, 0, 255)); //设置文字背景色,如为透明则把这一句改为:  //SetBkMode(hdc,TRANSPARENT);
        SetTextColor(hdc, RGB(255, 255, 0)); //设置文字颜色
       TextOut(hdc,100,400, text, strlen(text)); //句柄, 左上角X, 左上角Y,
                                          //文字(char *), 文字长度
     lpDDSPrimary->ReleaseDC(hdc); //释放句柄
}

Directdraw初始化代码
BOOL InitDDraw( )
{
     DDSURFACEDESC2 ddsd; // DirectDraw的页面描述
    
 if ( DirectDrawCreateEx (NULL, (void **)&lpDD, IID_IDirectDraw7, NULL) != DD_OK )return FALSE; //创建DirectDraw对象

     //这里使用了 if ( xxx != DD_OK) 的方法进行错误检测,这是最常用的方法 

//Direct的版本最多就只到了7


 if (lpDD->SetCooperativeLevel(hWnd,DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN) != DD_OK ) return FALSE; //设置DirectDraw控制级

if ( lpDD->SetDisplayMode( 1024,768, 32, 0, DDSDM_STANDARDVGAMODE ) != DD_OK ) return FALSE; //设置显示模式

//开始创建主页面,先清空页面描述
memset(&ddsd, 0, sizeof(DDSURFACEDESC2));

//填充页面描述
    ddsd.dwSize = sizeof( ddsd );
ddsd.dwFlags = DDSD_CAPS|DDSD_BACKBUFFERCOUNT; //有后台缓存
     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP|DDSCAPS_COMPLEX;
ddsd.dwBackBufferCount = 1; //一个后台缓存
     
if ( lpDD->CreateSurface( &ddsd, &lpDDSPrimary, NULL ) != DD_OK )return FALSE; //创建主页面
      
   ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER; //这是后台缓存

   if ( DD_OK != lpDDSPrimary->GetAttachedSurface( &ddsd.ddsCaps, &lpDDSBuffer ) )return FALSE; //创建后台缓存

ddsd.dwSize = sizeof( ddsd );
ddsd.dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT; 
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; //这是离屏页面
ddsd.dwHeight=480; //高
ddsd.dwWidth=640; //宽

if ( DD_OK != lpDD->CreateSurface( &ddsd, &lpDDSBack, NULL ) )return FALSE; //创建放背景图的页面
return TRUE;
}

我把输出文字的代码放在消息处理函数WndProc中,当按下DELETE键时输出文字
调试时按下后程序提示
codingtest3.cpp.exe 中的 0x00411f9d 处未处理的异常: 0xC0000005: 读取位置 0x00000000 时发生访问冲突 。
这个是怎么回事?

5 个解决方案

#1


是否哪个对象未初始化.

#2


检查指针是否初始化

#3


没有flip好像是不行的!
在lpDDSPrimary->ReleaseDC(hdc);前面加上一句lpddsprimary->flip(NULL,0,0);看能不能行,不过估计会出现程序死掉的情况,你怎么没建后台表面???

#4


晕死,这样肯定不行塞,如果要按键后显示,必须要有页面刷新,不然就是静态的,一出来就显示.
你最好把文字显示放到buffer页面里面,然后有一个页面刷新的函数,primary页和buffer页在交换的时候显示图片,如果你要通过键盘消息处理后在显示的话,你就要在刷新里面设个标志,if (enable==1),在回调函数函数里面给标志赋值,(enable=1;)
这样才行,给你个源代码:
void Print(char text[255],int x,int y)
{
HDC hdc;
lpDDSBuffer->GetDC(&hdc);
SetBkMode(hdc, TRANSPARENT);
SetTextColor(hdc, RGB(255,255,255));
TextOut(hdc, x, y , text, strlen(text));
lpDDSBuffer->ReleaseDC(hdc);

}
我们自定义一个显示文字的函数,
然后写个刷新函数:
void  refresh()
{

char *text="This is a eary RPG_DEMO^_^!";
if(enable==1)
{
         Print(text,50,10);
}
Flip();
}
然后也要写换页函数,必须换页,才可以达到你按键才显示的效果,不然就是出来就显示是静态的:
void Flip()
{
HRESULT ddrval;
ddrval=lpDDSPrimary->Flip(NULL,DDFLIP_WAIT);
if (ddrval==DDERR_SURFACELOST) 
Restore();
}
还有释放页面函数:
HRESULT Restore(void)
{
    HRESULT ddrval;
ddrval = lpDDSPrimary->Restore();
ddrval = lpDDSBuffer->Restore();
return ddrval;
}
这样在回调函数里面设置一个标志赋值:
LRESULT CALLBACK WinProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
enable=0;
switch(message)
{
case WM_SETCURSOR:
SetCursor(NULL);
return 0;
case WM_KEYDOWN:
switch(wParam)
{
case VK_ESCAPE:
PostQuitMessage(0);
break;
case VK_SPACE:
enable=1;
break;
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;

}
return DefWindowProc(hwnd, message, wParam, lParam);
}
我这里是用空格显示文字,如果你要用delete,就找到delete的键值在case后面改了就可以了

#5


关注

#1


是否哪个对象未初始化.

#2


检查指针是否初始化

#3


没有flip好像是不行的!
在lpDDSPrimary->ReleaseDC(hdc);前面加上一句lpddsprimary->flip(NULL,0,0);看能不能行,不过估计会出现程序死掉的情况,你怎么没建后台表面???

#4


晕死,这样肯定不行塞,如果要按键后显示,必须要有页面刷新,不然就是静态的,一出来就显示.
你最好把文字显示放到buffer页面里面,然后有一个页面刷新的函数,primary页和buffer页在交换的时候显示图片,如果你要通过键盘消息处理后在显示的话,你就要在刷新里面设个标志,if (enable==1),在回调函数函数里面给标志赋值,(enable=1;)
这样才行,给你个源代码:
void Print(char text[255],int x,int y)
{
HDC hdc;
lpDDSBuffer->GetDC(&hdc);
SetBkMode(hdc, TRANSPARENT);
SetTextColor(hdc, RGB(255,255,255));
TextOut(hdc, x, y , text, strlen(text));
lpDDSBuffer->ReleaseDC(hdc);

}
我们自定义一个显示文字的函数,
然后写个刷新函数:
void  refresh()
{

char *text="This is a eary RPG_DEMO^_^!";
if(enable==1)
{
         Print(text,50,10);
}
Flip();
}
然后也要写换页函数,必须换页,才可以达到你按键才显示的效果,不然就是出来就显示是静态的:
void Flip()
{
HRESULT ddrval;
ddrval=lpDDSPrimary->Flip(NULL,DDFLIP_WAIT);
if (ddrval==DDERR_SURFACELOST) 
Restore();
}
还有释放页面函数:
HRESULT Restore(void)
{
    HRESULT ddrval;
ddrval = lpDDSPrimary->Restore();
ddrval = lpDDSBuffer->Restore();
return ddrval;
}
这样在回调函数里面设置一个标志赋值:
LRESULT CALLBACK WinProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
enable=0;
switch(message)
{
case WM_SETCURSOR:
SetCursor(NULL);
return 0;
case WM_KEYDOWN:
switch(wParam)
{
case VK_ESCAPE:
PostQuitMessage(0);
break;
case VK_SPACE:
enable=1;
break;
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;

}
return DefWindowProc(hwnd, message, wParam, lParam);
}
我这里是用空格显示文字,如果你要用delete,就找到delete的键值在case后面改了就可以了

#5


关注