为什么下面的程序无法进行锁定(IDirectDrawSurface7::Lock())?另外InitDDraw()中初始化全部成功了.
// mydx9.cpp : 定义应用程序的入口点。
//#include "stdafx.h"
#include "mydx9.h"
#include "ddraw.h"#define MAX_LOADSTRING 100
//该处宏定义的意义比较复杂,为了方便以后使用
#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code)&0x8000)?1:0)
#define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code)&0x8000)?0:1)// 全局变量:
HINSTANCE hInst; // 当前实例
HWND main_window_handle = NULL; //主窗口句柄
TCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名
LPDIRECTDRAW7 lpdd; //DDRAW指针
LPDIRECTDRAWSURFACE7 lpdds0; //主界面指针
LPDIRECTDRAWSURFACE7 lpdds1; //附属界面指针
DDSURFACEDESC2 ddsd; //表面结构描述
DDSCAPS2 ddscaps; //缓冲页面指针// 此代码模块中包含的函数的前向声明:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
BOOL InitDDraw(); //初始化DDRAW
BOOL FreeDDraw(); //释放DDRAW
void MainLoop();
BOOL bActive = TRUE;
int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
  // TODO: 在此放置代码。
MSG msg;
HACCEL hAccelTable; // 初始化全局字符串
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_MYDX9, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance); // 执行应用程序初始化:
if (!InitInstance (hInstance, nCmdShow)) 
{
return FALSE;
} InitDDraw(); hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_MYDX9); // 主消息循环:
while (TRUE) 
{
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if (msg.message == WM_QUIT)
{
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
MainLoop();
} return (int) msg.wParam;
}//
//  函数:MyRegisterClass()
//
//  目的:注册窗口类。
//
//  注释:
//
//    仅当希望在已添加到 Windows 95 的
//    “RegisterClassEx”函数之前此代码与 Win32 系统兼容时,
//    才需要此函数及其用法。调用此函数
//    十分重要,这样应用程序就可以获得关联的
//   “格式正确的”小图标。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX);  wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_MYDX9);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL); return RegisterClassEx(&wcex);
}//
//   函数:InitInstance(HANDLE, int)
//
//   目的:保存实例句柄并创建主窗口
//
//   注释:
//
//        在此函数中,我们在全局变量中保存实例句柄并
//        创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;   hInst = hInstance; // 将实例句柄存储在全局变量中   hWnd = CreateWindow(szWindowClass, szTitle, WS_POPUP|WS_VISIBLE,//WS_OVERLAPPEDWINDOW,
     0, 0, 800, 600, NULL, NULL, hInstance, NULL);   if (!hWnd)
   {
      return FALSE;
   }   //将主窗口句柄储存到全局变量中以方便其他地方的调用
   main_window_handle = hWnd;   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);   return TRUE;
}//
//  函数:WndProc(HWND, unsigned, WORD, LONG)
//
//  目的:处理主窗口的消息。
//
//  WM_COMMAND - 处理应用程序菜单
//  WM_PAINT - 绘制主窗口
//  WM_DESTROY - 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc; switch (message) 
{
case WM_COMMAND:
wmId    = LOWORD(wParam); 
wmEvent = HIWORD(wParam); 
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: 在此添加任意绘图代码...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}// “关于”框的消息处理程序。
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE; case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}BOOL InitDDraw()
{ if ( FAILED(DirectDrawCreateEx(NULL,(void**)&lpdd,IID_IDirectDraw7,NULL) ) )
{
MessageBox(NULL,"Fail to creat DirectDraw ERROR 001(DirectX 8.1 required!)","ERROR",MB_OK);
exit(0);
}
if ( FAILED(lpdd->SetCooperativeLevel(main_window_handle,DDSCL_FULLSCREEN|DDSCL_ALLOWMODEX|DDSCL_EXCLUSIVE|DDSCL_ALLOWREBOOT)))
{
MessageBox(NULL,"Fail to creat DirectDraw ERROR 002(DirectX 8.1 required!)","ERROR",MB_OK);
exit(0);
}
if (FAILED(lpdd->SetDisplayMode(800,600,16,0,0)))
{
MessageBox(NULL,"Fail to creat DirectDraw ERROR 003(DirectX 8.1 required!)","ERROR",MB_OK);
exit(0);
} ZeroMemory(&ddsd,sizeof(ddsd));
//ZeroMemory(&ddscaps,sizeof(ddscaps)); ddsd.dwSize=sizeof(ddsd);
ddsd.dwFlags=DDSD_CAPS ;//| DDSD_BACKBUFFERCOUNT;
//ddsd.dwBackBufferCount = 1;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE ;//| DDSCAPS_FLIP | DDSCAPS_COMPLEX; if (lpdd->CreateSurface(&ddsd,&lpdds0,NULL) != DD_OK )
{
MessageBox(NULL,"Fail to creat surface","ERROR",MB_OK);
exit(0);
} return TRUE;
}BOOL FreeDDraw()
{
if (lpdd)
{
lpdd->Release();
lpdd = NULL;
}
return TRUE;
}BOOL InitWindow()
{
return TRUE;
}void MainLoop()
{
if (KEY_DOWN(VK_ESCAPE))
{
SendMessage(main_window_handle,WM_CLOSE,0,0);
} ZeroMemory(&ddsd,sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd); if (FAILED(lpdds0->Lock(NULL,&ddsd,DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL)))
{
MessageBox(main_window_handle,"FAILED TO LOCK!","ERROR",MB_OK);
SendMessage(main_window_handle,WM_CLOSE,0,0);
}

//lpdds0->Lock(NULL,&ddsd,DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);
int mempitch = (int)ddsd.lPitch;
UCHAR *video_buffer = (UCHAR*) ddsd.lpSurface; UCHAR color = 30045; //video_buffer[2000] = color;}

解决方案 »

  1.   

    没人知道吗?
    顺便提一下,问题在MainLoop函数中!锁定的时候出错!
      

  2.   

    你的程序中为什么没有Unlock(NULL)呢???
      

  3.   

    今天上午我自己解决了
    每个lock必须紧紧跟随一个unlock,因为多数情况下,lock与unlock操作必须在无限次的主游戏循环中,这样如果一个循环中不释放上次循环中lock的区域(通常这个区域是这个屏幕!),那么在下次进行锁定的时候,lock方法会无法锁定一个已经被锁定的区域。不过还是要谢谢耐心读我程序的人!