这个例子来自于wm5.0 sdk的的sample:DDex1
对于DirectDraw功用就不多说了,这里详细讲解一下例子
首先当然是生成DirectDraw对象指针了,第一个参数是指定显示设备对象的宏,双屏设备使用,一般都设为NULL,指定为当前激活的屏幕,第二个参数是输出参数,就是我们要的,g_pDD是LPDIRECTDRAW对象指针。第三个参数是预留参数,作功能拓展用的,暂时置NULL
hRet = DirectDrawCreate(NULL, &g_pDD, NULL);
接下来取得对象后我们调用SetCooperativeLevel,这是一个高优先级占用的函数,第一个参数是一个当前应用程序的顶层窗口,不能指定一个子窗口的句柄。第二个参数是两个宏设定:
DDSCL_FULLSCREEN是独占访问,GDI的操作将无效,DDSCL_NORMAL是标准操作,但是一些主要的功能不能实现,代码显示的是使用全屏独占访问方式
hRet = g_pDD->SetCooperativeLevel(hWnd, DDSCL_FULLSCREEN);
然后要获取一次设备功能参数,第一个是硬件设备参数结构休,第二个是虚设备参数结构体,只能设一个为NULL,表示不接收
g_pDD->GetCaps(&ddCaps, &ddHelCaps);
if (!(ddCaps.ddsCaps.dwCaps & DDSCAPS_BACKBUFFER))
{
return InitFail(hWnd, E_FAIL, szNoBackBufferMsg);
}
if (!(ddCaps.ddsCaps.dwCaps & DDSCAPS_FLIP))
{
return InitFail(hWnd, E_FAIL, szNoFlipSurfacesMsg);
}
最后建立主绘面CreateSurface,这个函数第一个参数是主绘面的信息数据地址指针LPDDSURFACEDESC,第二个参数是主绘面的指针的指针对象,用来标识这个主绘面,第三个是预留参数,为NULL,创建成功后,调用EnumAttachedSurfaces,取得副绘面的指针
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |
DDSCAPS_FLIP;
ddsd.dwBackBufferCount = 1;
hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSPrimary, NULL);
if (hRet != DD_OK)
{
return InitFail(hWnd, hRet, szCreateSurfaceFailMsg);
}
// Get a pointer to the back buffer
hRet = g_pDDSPrimary->EnumAttachedSurfaces(&g_pDDSBack, EnumFunction);
至此主面和副面就创建完成了,接下来就是对面的操作了:
首先是Flip函数,Flip函数的目的是把在副绘面上的内容弹到主绘面,从而显示出来,第一个参数是绘面指针,如果是NULL就会循环取出在绘面链中的所有副绘面,否则指定的那个绘面弹入,第二个参数是flip标志
//这是一个ontimer事件的响应,是一个rate是500毫秒的触发
case WM_TIMER:
// Update and flip surfaces
if (g_bActive && TIMER_ID == wParam)
{
UpdateFrame(hWnd);
while (TRUE)
{
hRet = g_pDDSPrimary->Flip(NULL, 0);
if (hRet == DD_OK)
break;
if (hRet == DDERR_SURFACELOST)
{
hRet = g_pDDSPrimary->Restore();
if (hRet != DD_OK)
break;
}
if (hRet != DDERR_WASSTILLDRAWING)
break;
}
}
break;
//具体的操作函数
UpdateFrame(HWND hWnd)
{
static BYTE phase = 0;
HDC hdc;
RECT rc;
SIZE size;
int nMsg;
DDBLTFX ddbltfx;
// Use the blter to do a color fill to clear the back buffer
memset(&ddbltfx, 0, sizeof(ddbltfx));
ddbltfx.dwSize = sizeof(ddbltfx);
ddbltfx.dwFillColor = 0;
g_pDDSBack->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAITNOTBUSY, &ddbltfx);
if (g_pDDSBack->GetDC(&hdc) == DD_OK)
{
//文字背景
SetBkColor(hdc, RGB(155, 0, 255));
//文字色彩
SetTextColor(hdc, RGB(255, 255, 0));
GetClientRect(hWnd, &rc);
if (phase)
{
nMsg = lstrlen(szMsg);
GetTextExtentPoint(hdc, szMsg, nMsg, &size);
ExtTextOut(hdc,
(rc.right - size.cx) / 2,
(rc.bottom - size.cy) / 2,
0, // fuOptions
NULL, // lprc
szMsg,
nMsg,
NULL); // lpDx
nMsg = lstrlen(szFrontMsg);
GetTextExtentPoint(hdc, szFrontMsg, nMsg, &size);
ExtTextOut(hdc,
(rc.right - size.cx) / 2, // Center horz. for tv reasons
0,
0, // fuOptions
NULL, // lprc
szFrontMsg,
nMsg,
NULL); // lpDx
phase = 0;
}
else
{
nMsg = lstrlen(szBackMsg);
GetTextExtentPoint(hdc, szBackMsg, nMsg, &size);
ExtTextOut(hdc,
(rc.right - size.cx) / 2, // Center horz. for tv reasons
0,
0, // fuOptions
NULL, // lprc
szBackMsg,
nMsg,
NULL); // lpDx
phase = 1;
}
g_pDDSBack->ReleaseDC(hdc);
}
}