用WindowedMode显示位图图象(转)

用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/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值