显示背景图象,再在上面使用透明色显示文本文字。
Display 与储存背景图象和文本文字的 Surface(表面|描绘用内存区) 。
g_bActive 是 DirectDraw 初始化成功的标志:
CDisplay*
g_pDisplay
= NULL;
CSurface*
g_pBmpSurface = NULL;
CSurface*
g_pTextSurface= NULL;
BOOL
g_bActive
= FALSE;
创建背景图象 Surface 的代码。
输入的图象大小是 320*240 ,象下面这种写法,会把它扩展到 640*480 来储存:
if (FAILED(hr= g_pDisplay-CreateSurfaceFromBitmap(&g_pBmpSurface,
"G:\\DirectX 8\\旷野中的小屋.bmp",640,480)))
return hr;
文本文字 Surface 及 ColorKey(颜色键值) 的设定。
所谓 ColorKey ,就是"透明色",把指定的颜色变成透明的,使背景图象能够透过。通常把黑色(0)设为透明色。
等这篇的例子编译成功以后,把下面这段代码中含有 SetColorKey() 的语句注释起来跳过编译,再对比一下前后的执行效果,"透明色"的意思就会一目了然。
if (FAILED(hr= g_pDisplay-CreateSurfaceFromText(&g_pTextSurface,
NULL,"旷野中的小屋",RGB(0,0,0),RGB(0,255,0))))
return hr;
// Set the color key for the logo sprite to black
if (FAILED( hr = g_pTextSurface-SetColorKey(0)))
return hr;
创建窗口的代码试着给它尽量简化:
WNDCLASSEX wc = { sizeof(WNDCLASSEX),CS_CLASSDC,WndProc,0L,0L,
GetModuleHandle(NULL),NULL,NULL,NULL,NULL,NAME,NULL
};
if (RegisterClassEx(&wc)==0)
return FALSE;
HWND hWnd = CreateWindow( NAME,NAME,WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
GetDesktopWindow(),NULL,wc.hInstance,NULL);
if (hWnd==NULL)
return FALSE;
下面说明工程的创建方法。
这回仍然要用到 Common 文件夹下保存着的那4个文件,这4个文件实在太麻烦把工程往别处挪一挪就要出错,做个工程不容易,文件夹一移动就出错了。这回我们把那4个文件直接复制过来,复制到工程文件夹!
这样就没事了,想挪哪里挪哪里,没事。创建工程也简单了。不过就是硬盘上多了那4个文件的几份拷贝。
其实只是在编译的时候才用得上那4个文件,编译完成以后删了没问题。
1.
新建一个 Win32 Application 空白工程,命名为 "Colkey"。
2.
向工程中新建一个 C++ Source File ,命名为 "colkey" ,向其中键入篇末附带的源程序。
3.
把下面4个文件复制到工程文件夹(我是 G:\DirectX 8\Colkey\):
E:\Mssdk\samples\Multimedia\Common\include\ddutil.h
E:\Mssdk\samples\Multimedia\Common\include\dxutil.h
E:\Mssdk\samples\Multimedia\Common\src\ddutil.cpp
E:\Mssdk\samples\Multimedia\Common\src\dxutil.cpp
然后选择菜单 [Project|工程]-[Add To Project|添加到工程]-[Files...|文件...] ,向工程中添加这4个文件。
4.
准备合适的背景图象文件(我是在 G:\DirectX 8\ 下放了张 "旷野中的小屋.bmp")。
5.
选择菜单 [Project|工程]-[Settings...|设定...] 打开[Project Settings|工程设定] 面板,点击 [Link|链接] 标签,向 [Object/library modules|对象、库模块] 栏内添加下面4个库文件:
dxguid.lib
ddraw.lib
dxerr8.lib
winmm.lib
6.
编译并执行!
源程序:
/*****************************************************************/
/*★ 使用背景图象与透明色的文字的描绘
2001-01-15
前田 稔 ★*/
/*****************************************************************/
#define
NAME
"Color Key"
#define
STRICT
#include
#include
#include
#include
"ddutil.h"
// Defines, constants, and global variables
#define SAFE_DELETE(p)
{ if (p) { delete (p);
(p)=NULL; } }
#define SAFE_RELEASE(p) { if (p) { (p)-Release(); (p)=NULL; } }
#define ERMSG(x)
MessageBox(hWnd, x, "DirectDraw Samplee", MB_OK);
CDisplay*
g_pDisplay
= NULL;
CSurface*
g_pBmpSurface = NULL;
CSurface*
g_pTextSurface= NULL;
BOOL
g_bActive
= FALSE;
// Function-prototypes
LRESULT
CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HRESULT
InitDraw(HWND hWnd);
VOID
FreeDraw();
HRESULT
DisplayFrame();
//★ Windows Main
int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pCmdLine, int nCmdShow)
{
MSG
msg;
WNDCLASSEX wc = { sizeof(WNDCLASSEX),CS_CLASSDC,WndProc,0L,0L,
GetModuleHandle(NULL),NULL,NULL,NULL,NULL,NAME,NULL
};
if (RegisterClassEx(&wc)==0)
return FALSE;
HWND hWnd = CreateWindow( NAME,NAME,WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
GetDesktopWindow(),NULL,wc.hInstance,NULL);
if (hWnd==NULL)
return FALSE;
if (FAILED(InitDraw(hWnd)))
{
if (g_pDisplay)
g_pDisplay-GetDirectDraw()-SetCooperativeLevel(NULL, DDSCL_NORMAL);
ERMSG("DirectDraw init failed");
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
while(TRUE)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
if (0==GetMessage(&msg, NULL, 0, 0))
return (int)msg.wParam;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
if (g_bActive)
{
if (FAILED(DisplayFrame()))
{
SAFE_DELETE(g_pDisplay);
ERMSG("Displaying the next frame failed");
return FALSE;
}
}
else
WaitMessage();
}
}
}
//★ WndProc()
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_KEYDOWN:
PostMessage(hWnd, WM_CLOSE, 0, 0);
return 0L;
case WM_SIZE:
if (SIZE_MAXHIDE==wParam || SIZE_MINIMIZED==wParam)
g_bActive = FALSE;
else
g_bActive = TRUE;
break;
case WM_SETCURSOR:
//隐藏光标
SetCursor(NULL);
return TRUE;
case WM_SYSCOMMAND:
switch(wParam)
{
case SC_MOVE:
case SC_SIZE:
case SC_MAXIMIZE:
case SC_MONITORPOWER:
return TRUE;
}
break;
case WM_DESTROY:
FreeDraw();
PostQuitMessage(0);
return 0L;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
//★ InitDraw()
HRESULT InitDraw(HWND hWnd)
{
HRESULT
hr;
g_pDisplay = new CDisplay();
if (FAILED(hr= g_pDisplay-CreateFullScreenDisplay(hWnd,640,480,16)))
{
ERMSG("This display card does not support 640x480x16.");
return hr;
}
// Create a surface, and draw a bitmap resource on it.
if (FAILED(hr= g_pDisplay-CreateSurfaceFromBitmap(&g_pBmpSurface,
"G:\\DirectX 8\\旷野中的小屋.bmp",640,480)))
return hr;
if (FAILED(hr= g_pDisplay-CreateSurfaceFromText(&g_pTextSurface,
NULL,"旷野中的小屋",RGB(0,0,0),RGB(0,255,0))))
return hr;
// Set the color key for the logo sprite to black
if (FAILED( hr = g_pTextSurface-SetColorKey(0)))
return hr;
return S_OK;
}
//★ DisplayFrame()
HRESULT DisplayFrame()
{
HRESULT hr;
g_pDisplay-Clear(0);
// Blt all the sprites onto the back buffer using color keying
g_pDisplay-Blt(0,0,g_pBmpSurface,NULL);
g_pDisplay-Blt(230,200,g_pTextSurface,NULL);
if (FAILED(hr= g_pDisplay-Present())) return hr;
return S_OK;
}
//★ FreeDraw()
VOID FreeDraw()
{
SAFE_DELETE(g_pBmpSurface);
SAFE_DELETE(g_pDisplay);
}