一个严重打击菜鸟的有关问题,小弟我只是想blt一张位图而已

一个严重打击初学者的问题,我只是想blt一张位图而已!
如题,本人初学directdraw,想载入一张位图到一个离屏表面,然后直接blt到主表面

具体问题就出在每次执行离屏表面blt到主表面的时候总是报错,blt失败!

但是如果我把离屏表面换成后备缓冲,先将位图载入到后备缓冲然后再blt到主表面却总能成功!

但是就这么一个问题愣是一天没有实现。快疯了

以下是完整的程序源码。使用directx8(程序编译成功!没有任何报错)

#define WIN32_LEAN_AND_MEAN
#define INITGUID // make sure directX guids are included

#include <windows.h>
#include <windowsx.h>

#include <ddraw.h>

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

#define WINDOW_CLASS_NAME "WINCLASS"

// default screen size
#define SCREEN_WIDTH 640 // size of screen
#define SCREEN_HEIGHT 480
#define SCREEN_BPP 32 // bits per pixel

// initializes a direct draw struct
#define DDRAW_INIT_STRUCT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct)); ddstruct.dwSize=sizeof(ddstruct); }

#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)

HWND main_window_handle = NULL; 
int virtual_code = 0;
unsigned int key_state = 1000;

LPDIRECTDRAW7 lpdd = NULL; // directdraw 对象
LPDIRECTDRAWSURFACE7 lpddsprimary = NULL; // directdraw 主表面
LPDIRECTDRAWSURFACE7 lpddsback = NULL; // directdraw 后备缓冲或者离屏表面
LPDIRECTDRAWCLIPPER lpddclipper = NULL; // directdraw 剪裁器
DDSURFACEDESC2 ddsd; // 一个用来描述directdraw表面的结构

RECT source_rect = {0,0,SCREEN_WIDTH,SCREEN_HEIGHT};
RECT dest_rect = {0,0,SCREEN_WIDTH,SCREEN_HEIGHT};

/////////////////////////////////////////////////////////////////

void CreateSurface(LPDIRECTDRAWSURFACE7 *lpSource, int xs, int ys)
{

  DDRAW_INIT_STRUCT(ddsd);
  ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
  ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
  ddsd.dwWidth = xs;
  ddsd.dwHeight = ys;
  if(lpdd->CreateSurface(&ddsd, lpSource, NULL) != DD_OK)
{
//MessageBox(NULL, "创建表面失败","错误信息!",MB_OK | MB_ICONEXCLAMATION);
}
}

/////////////////////////////////////////////////////////////////

void DrawHBitmap(IDirectDrawSurface7 *lpSurface, HBITMAP hBitmap, int x, int y, int width, int height)
{
  HDC hdcImage;
  HDC hdc;
  BITMAP bm;

  if (lpSurface == NULL || hBitmap == NULL)
  return;
  lpSurface->Restore();

  hdcImage = CreateCompatibleDC(NULL);
  SelectObject(hdcImage, hBitmap);

  GetObject(hBitmap, sizeof(bm), &bm);
  width = width == 0 ? bm.bmWidth : width;
  height = height == 0 ? bm.bmHeight : height;

  if(lpSurface->GetDC(&hdc) != DD_OK)
{
MessageBox(NULL, "设备获取失败","错误信息!",MB_OK | MB_ICONEXCLAMATION);
}
  BitBlt(hdc, x, y, width, height, hdcImage, 0, 0, SRCCOPY);
  lpSurface->ReleaseDC(hdc);
  DeleteDC(hdcImage);
}

/////////////////////////////////////////////////////////////////

void CreateBitmapSurface(LPDIRECTDRAWSURFACE7 lpSurface, char *fname, int xs, int ys)
{
  HBITMAP hBitmap;

  CreateSurface(&lpSurface,xs, ys);
  hBitmap = (HBITMAP)LoadImage(NULL, fname, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
  DrawHBitmap(lpSurface, hBitmap, 0, 0, xs, ys);
  DeleteObject(hBitmap);
}

/////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////

int Game_Init(void *parms = NULL, int num_parms = 0)
{


// create IDirectDraw interface 7.0 object and test for error
if (FAILED(DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL)))