用WindowedMode顯示點陣圖圖象(轉)

post0發表於2007-08-12
用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/,如需轉載,請註明出處,否則將追究法律責任。

相關文章