用WindowedMode显示位图图象(转)[@more@]
前面所所讲过的例子里,整个画面全部被 DirectX 独占,这种模式叫 "Full Screen Mode(全屏模式)",需要高速描绘的游戏程序,很多都使用全屏模式。
这回我们让 DirectX 程序与其他 Windows 程序同屏显示。
这个模式其实就是标准 Windows 程序的运行方式,所以称作 "Windowed Mode(窗口模式)" 。在窗口模式下,参照同时运行的其它程序来切换窗口、移动、调整大小等因素都必须考虑。
以窗口模式初始化 DirectX 的代码。
"320,240" 是窗口的初始大小,这里让它跟要显示的图象大小一样:
if (FAILED(hr = g_pDisplay->CreateWindowedDisplay(hWnd,320,240)))
{ ERMSG("Failed initializing DirectDraw.");
return hr;
}
窗口模式的 CALLBACK 函数。
用它来处理窗口的移动、调整大小等事件:
//★ MainWndProc()
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{ switch (msg)
{ case WM_KEYDOWN:
PostMessage(hWnd,WM_CLOSE,0,0);
return 0L;
case WM_PAINT:
if (g_pDisplay)
{ // Display the new position of the sprite
if (DisplayFrame() == DDERR_SURFACELOST)
{ PostMessage(hWnd,WM_CLOSE,0,0);
}
}
break;
case WM_MOVE:
if (g_pDisplay) g_pDisplay->UpdateBounds();
return 0L;
case WM_SIZE:
// Check to see if we are losing our window...
if (SIZE_MAXHIDE==wParam||SIZE_MINIMIZED==wParam) g_bActive= FALSE;
else g_bActive= TRUE;
if (g_pDisplay) g_pDisplay->UpdateBounds();
break;
case WM_DESTROY:
// Cleanup and close the app
FreeDirectDraw();
PostQuitMessage(0);
return 0L;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
本章的例子编译成功后,试试用鼠标拖曳来改变窗口大小。图象的大小、 Aspect Ratio(纵横比) 会适应窗口的大小而改变。
如果把 "WM_SIZE:" 下面这行注释起来跳过编译,再改变窗口大小的时候图象的大小就不会随着改变了:
// if (g_pDisplay) g_pDisplay->UpdateBounds();
其它的跟以前的程序一样。
窗口模式也能使用 Common 文件夹下那4个文件,跟上一节一样,我们也把它复制到工程文件夹。
下面说明工程的创建方法。
1. 新建一个 Win32 Application 空白工程,命名为 "Winmode"。
2. 向工程中新建一个 C++ Source File ,命名为 "winmode" ,向其中键入篇末附带的源程序。
3. 把下面4个文件复制到工程文件夹(我是 G:DirectX 8Winmode):
E:MssdksamplesMultimediaCommonincludeddutil.h
E:MssdksamplesMultimediaCommonincludedxutil.h
E:MssdksamplesMultimediaCommonsrcddutil.cpp
E:MssdksamplesMultimediaCommonsrcdxutil.cpp
然后选择菜单 [Project|工程]-[Add To Project|添加到工程]-[Files...|文件...] ,向工程中添加这4个文件。
4. 准备合适的图象文件(我是在 G:DirectX 8 下放了张 "旷野中的小屋.bmp")。
我用的图象大小是 320*240 ,实际上随便多大都可以。下面是读取图象的代码,请改成你自己准备的路径和文件名:
if (FAILED(hr = g_pDisplay->CreateSurfaceFromBitmap
(&g_pBmpSurface,"G:DirectX 8旷野中的小屋.bmp",0,0)))
5. 选择菜单 [Project|工程]-[Settings...|设定...] 打开[Project Settings|工程设定] 面板,点击 [Link|链接] 标签,向 [Object/library modules|对象、库模块] 栏内添加下面4个库文件:
dxguid.lib
ddraw.lib
dxerr8.lib
winmm.lib
6. 编译并执行!
源程序:
/************************************************************************/
/*★ 用 Windowed Mode(窗口模式) 显示位图图象 2001-01-10 前田 稔 ★*/
/************************************************************************/
#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;
BOOL g_bActive = FALSE;
// Function-prototypes
LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
HRESULT WinInit(HINSTANCE hInst, int nCmdShow, HWND* phWnd);
HRESULT InitDirectDraw(HWND hWnd);
VOID FreeDirectDraw();
HRESULT DisplayFrame();
//★ Windows Main
int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pCmdLine, int nCmdShow)
{ MSG msg;
HWND hWnd;
if (FAILED(WinInit(hInst, nCmdShow, &hWnd))) return FALSE;
if (FAILED(InitDirectDraw(hWnd)))
{ if (g_pDisplay)
g_pDisplay->GetDirectDraw()->SetCooperativeLevel(NULL, DDSCL_NORMAL);
ERMSG("DirectDraw init failed. The sample will now exit.");
return FALSE;
}
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. The sample will now exit.");
return FALSE;
}
}
else WaitMessage();
}
}
}
//★ WinInit()
HRESULT WinInit(HINSTANCE hInst, int nCmdShow, HWND* phWnd)
{ WNDCLASS wc;
HWND hWnd;
// Register the Window Class
wc.lpszClassName = TEXT("BMP View");
wc.lpfnWndProc = MainWndProc;
wc.style = CS_VREDRAW | CS_HREDRAW;
wc.hInstance = hInst;
wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
if (RegisterClass(&wc) == 0) return E_FAIL;
// Create and show the main window
hWnd = CreateWindowEx(0, TEXT("BMP View"), TEXT("WindowedMode"),
WS_POPUP, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInst, NULL);
if (hWnd==NULL) return E_FAIL;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
*phWnd = hWnd;
return S_OK;
}
//★ InitDirectDraw()
HRESULT InitDirectDraw(HWND hWnd)
{ HRESULT hr;
g_pDisplay = new CDisplay();
if (FAILED(hr = g_pDisplay->CreateWindowedDisplay(hWnd,320,240)))
{ ERMSG("Failed initializing DirectDraw.");
return hr;
}
// Create a surface, and draw a bitmap resource on it.
if (FAILED(hr = g_pDisplay->CreateSurfaceFromBitmap
(&g_pBmpSurface,"G:DirectX 8旷野中的小屋.bmp",0,0)))
return hr;
return S_OK;
}
//★ FreeDirectDraw()
VOID FreeDirectDraw()
{ SAFE_DELETE(g_pBmpSurface);
SAFE_DELETE(g_pDisplay);
}
//★ MainWndProc()
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{ switch (msg)
{ case WM_KEYDOWN:
PostMessage(hWnd,WM_CLOSE,0,0);
return 0L;
case WM_PAINT:
if (g_pDisplay)
{ // Display the new position of the sprite
if (DisplayFrame() == DDERR_SURFACELOST)
{ PostMessage(hWnd,WM_CLOSE,0,0);
}
}
break;
case WM_MOVE:
if (g_pDisplay) g_pDisplay->UpdateBounds();
return 0L;
case WM_SIZE:
// Check to see if we are losing our window...
if (SIZE_MAXHIDE==wParam||SIZE_MINIMIZED==wParam) g_bActi
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/8225414/viewspace-952196/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/8225414/viewspace-952196/