Construct DirectX application framework with MFC

zhaozj2021-02-08  261

Author: Guangxi Vocational and Technical College Computing Center (530 227) Tanwen Hong

Abstract: Pack DirectXSDK in the MFC class to create a DirectX application framework. Keywords: MFC class library, DirectXSDK

First, the MFC class library and DirectXSDK

Microsoft DirectX SDK is a software development tool developed based on Windows platform games. Its main feature is mainly included in five components: DirectDraw, DirectSound, DirectPlay, Direct3D, and DirectInput, each component has different features:

. DirectDraw uses direct write technology to speed up the animation speed of the game; DiRecsound controls the synthesis and playback of the game sound; DirectPlay enables the game with multiplayer game features;. Direct3D allows programmers to make more convenient development of 3D games:. DirectInput allows the game to support more input devices (now only support the joystick, mouse, and keyboard).

It can be said that DirectXSDK provides a function and base function that writes a game, so most of the Windows games use DitRectxsdk.

The MFC (Microsoft Foundation Class) class is a powerful Windows application development class available in Microsoft Visual C . Use these classes to avoid and cumbersome Windows APL deal, and we can also use C1assWizard to MFC class in Visualc Perform a Windows message mapping, so if you can develop DirectXSDK applications with an MFC class library, at least the following benefits:

1. You can map Windows messages with VC C1AssWizard; 2. Added the readability of the program and can be used by the classview of the ClassView of VC ; 3. Increasing the reusability of program code, can develop a more powerful application on the original basis, if we can develop a VC engineering guide that generates the basic framework of the DirectXSDK application, it will develop DirectX SDK later. Applications provide and greatly. Below, we will use Visua1 C 5.0 first to write a basic framework of a DirectXSDK application.

Second, write the basic framework of DirectXSDK applications

Let's establish a basic framework for the RECTXSDK program by following these steps:

1. Generate a dialog-based project file with Visual C MFC AppWizard (EXE), named DirectX, cancel the check box of About Box when the wizard is second step, then press the Finish button. 2. Delete DirectXDLG generated in the DirectX engineering directory. CPP and DirectXDLG. H Two files and delete the above two files in the FileView of Visual C , press CTRL Ten W to launch CDIRECTXDLG classes, and then delete IDD_directx_ dialog in ResourceView. 3. Establish two file DirectXWnd.cpp and DirectXWnd. H (These two files are in the appendices of this article, please note that there is not to delete the content between "// {" and "//}", otherwise the window message will be mapped using ClassWizard) and add them to In the project. At this time, an engine will add a CWND CDirectXWnd class, which is the base class of our DirRectx application. CDIRECTXWND class Create a window and generates a DirectDraw object LPDD associated with the window, and generates a display plane (lpfrontbuffer) and a display buffer plane (LPBackBuffer), which uses several virtual functions, if necessary, when necessary These functions can be overwritten. 4. Open DirectX. CPP, change the #include "directxdlg.h" to #include "directxwnd.h" and then modify the cDirectxapp :: initInstance () function as follows, in which the black body is to increase: BOOL CDIRECTXAPP :: lnitlnstnnce () {#ifdef _Afxdll enable3dControls (); // call thisime will #else enable3dControlsStatic (); // call this when linking to mfc staticly #endif

CDirectXWnd * pWnd = new CDirectXWnd (); pWnd-> Create ( "DirectXWnd Test"); m_pMainWnd = pWnd; pWnd-> UpdateWindow (); pWnd-> SetFocus (); if (pWnd-> InitializeGame (640,480,8) = = False) {PWND-> DestroyWindow (); return false;} msg msg; while (1) {if (PeekMessage (& MSG, NULL, 0, 0, PM_NOREMOVE)) {if (! GetMessage (& MSG, NULL, 0, 0) Return Msg.wParam; TranslateMessage (& MSG); DISPATCHMESSAGE (& MSG);} else {if (pwnd-> blsactive) {PWND-> UpdateFrame ();}}} Return False;} Compiling the program and runs, When you see a black screen window, press ESC or F12 to exit the program. At this point, our basic framework has been established, although this framework is relatively simple, but we can develop a more powerful application framework on this basis. To facilitate the use of this frame, we can write a Custom AppWizard for the framework, of course, you can copy it, just copy the files in the project to another. Third, test framework

Now, we write a test program by following steps: Test this framework:

1. Copy the project frame created to a new directory and open it. Create a CWND-based class CTestWnd with C1AssView, then replace all the "CWnd" strings in ctestwnd.h and ctestwnd.cpp files to "cDirectxWnd" and add the following strings in the ctestwnd.h file: #include "DirectXWnd ". 2. Open the DirectX.cpp file, add #include "testwnd.h" on the file header and replace all the "cDirectXWnd" strings in the file into "ctestwnd" and save it. 3. Add a virtual function updateFrame () for the CTestWnd class, which overwrite the updateframe of its base class cDirectWnd:

Void ctestwnd :: updateFrame () {static int x = 0, dx = 5; static int y = 0, DY = 5; HDC HDC; DDBLTFX DDBLTFX; HRESULT DDRVAL; UPDATEWINDOW (); ddbltfx.dwsize = sizeof (ddbltfx); ddbltfx.dwFillColor = 0; ddrval = lpBackBuffer-> Blt (NULL, // dest rect NULL, // src surface NULL, // src rect DDBLT_COLORFILL | DDBLT_WAIT, & ddbltfx); if (ddrval = DD_OK!) {Msg ( "Fill FAILED DDRVAL = 0x% 081X ", DDRVAL); return;}}} (lpBackBuffer-> getDC (& HDC) == DD_OK) {if (x <0) DX = 5; if (x> 590) DX = -5; if (Y <0) DY = 5; if (Y> 430) DY = -5; x = DX; Y = DY; Ellipse (HDC, X, Y, X 50, Y 50); lpBackBuffer-> ReleaseDC ( HDC);} while; ddrval = lpfrontbuffer-> flip (null, 0); if (ddrval == dd_ok) {breaf;}; if (ddrval == DDERR_SURFACELOST) {if (! CDIRECTXWND :: RESTORESURFCES ()) {Brea K;}} if (DDRVAL! = DDERR_WASSTILLDRAWING) {Break;}}} no hearts Press: Light is not successful in the test, may have to add two lines in ctestwnd.h: public: void updateFrame (); otherwise Compiling may be wrong.

4, compile and run the program, a white ball will appear on the screen.

appendix:

Document: DirectxWnd.h

#if! defined (DirectxWnd_H) #define directxwnd_h //directxwnd.h:Header file #include #pragma comment (lib, "ddraw.lib") // Add DDRAW.LIB library Class CDIRECTXWND: PUBLIC CWnd {// Construction public: CDirectXWnd (); // Attributes public: BOOL blsActive; // whether the application is activated protected: LPDIRECTDRAW lpDD; // DirectDraw object pointer LPDIRECTDRAWSURFACE lpFrontBuffer; // DirectDraw primary buffer LPDIRECTDRAWSURFACE lpBackBuffer; // DirectDraw background buffer int nbuffercount; // backup buffer number // Operations protected: Void MSG (lpstr fmt, ...); public: bool create (lpcstr lpszappname); // Create Form // Overrides Virtual Bool InitializeGame (UINT GModex, UINT GModeY, UINT GBPP); virtual BOOL CleanSurface (); virtual void UpdateFrame (); virtual BOOL RestoreSurfaces (void); // {{AFX_VIRTUAL (CDirectXWnd) //}} AFX_VIRTUAL // implementation public: virtual ~ CDIRECTXWND (); // generated message map functions protected: // {{AFX_MSG (CDIRECTXWND) AFX_MSG VOID ONKEYDOWN (uint nchar, uint nrepcnt , Uint nflags; afx_msg void onactivateApp (bool bactage, htask htask; //}} AFX_MSG declare_MESSAGE_MAP ()}; {{AFX_INSERT_LOCATION}} #ENDIF / /! DEFINE (DirectXWnd_H)

File: DirectXWnd.CPP //DirectXWnd.cpp:implementation file #include "stdafx.h" #include "DirectX.h" #include "DirectXWnd.h" #ifdef _DUBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE [] = __FILE__; #endif CDirectXWnd :: CDirectXWnd () {lpDD = NULL; lpFrontBuffer = NULL; lpBackBuffer = NULL; nBufferCount = 0; blsActive = TRUE;} CDirectXWnd :: ~ CDirectXWnd () {if (lpDD) {CleanSurface (); lpDD -> Release (); lpDD = NULL;}} BOOL CDirectXWnd :: Create (LPCSTR lpszAppName) {CString className = AfxRegisterWndClass (CS_DBLCLKS, :: LoadCursor (NULL, IDC_ARROW), NULL, AfxGetApp () -> LoadIcon (IDR_MAINFRAME)) ; return (CWnd :: CreateEx (WS_EX_APPWINDOW, className, lpszAppName, WS_VISIBLE | WS_SYSMENU | WS_POPUP, 0,0, GetSystemMetrics (SM_CXSCREEN), GetSystemMetrics (SM_CYSCREEN), NULL, NULL));} BOOL CDirectXWnd :: InitializeGame (UINT GModeX, UINT GMODEY, UINT GBPP) {HRESULT DDRVAL; DDRVAL = DirectDrawCreate (NULL, & LPDD, NULL); if (DDRVAL! = DD_ OK) {Msg ( "DirectDrawCreate failed err =% d", ddrval); return FALSE;}! Ddrval = lpDD-> SetCooperativeLevel (m_hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); if (ddrval = DD_OK) {Msg ( "SetCooperativeLevel failed err = % D ", DDRVAL); RETURN FALSE;} DDRVAL = LPDD-> SetDisplayMode (Gmodex, Gmodey, GBPP); if (DDRVAL! = DD_OK) {msg (" setDisplayMode failed err =% D ", DDRVAL); RETURN FALSE } // Check Capabilites DDCAPS DDCAPS; DDCAPS.DWSIZE = SIZEOF (DDCAPS); DDRVAL = LPDD-> GetCaps (& DDCAPS, NULL); if (DDRVAL! =

DD_OK) {Msg ( "GetCaps failed err =% d", ddrval); return FALSE;} if (ddcaps.dwCaps & DDCAPS_NOHARDWARE) {Msg ( "No hardware support at all");} // default to double buffered on 1mb, triple Buffered if (nbuffercount == 0) {if (ddcaps.dwvidMTotal <= 1024L * 1024L * (GBPP / 8) || GMODEX> 640) {nbuffercount = 2;} else {nbuffercount = 3;}} DDSurfaceDesc DDSD;: :: ZeroMemory (& ddsd, sizeof (ddsd)); ddsd.dwSize = sizeof (ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; ddsd.dwBackBufferCount = nBufferCount-1; ddrval = lpDD -> CreateSurface (& DDSD, & LPFRONTBUFFER, NULL); if (DDRVAL! = DD_OK) {msg ("CreateSurface Failed Err =% D", DDRVAL); Return False;} else msg ("Show memory allowed buffer number = % D (maximum 3) ", nbuffercount); DDSCAPS DDSCAPS; DDSCAPS.DWCAPS = DDSCAPS_BACKBUFFER; DDRVAL = LpFrontBuffer-> GetAttachedSurface (& ddscaps, & lpBackBuffer); if (ddrval = DD_OK!) {Msg ( "GetAttachedsurface failed err =% d", ddrval); return FALSE;} return TRUE;} void CDirectXWnd :: Msg (LPSTR fmt, ...) {Char BUFF [256]; VA_List Va; LSTRCPY (BUFF, "DirectXWnd:"); VA_START (VA, FMT); WVSPrintf (& Buff [LSTRLEN (BUFF)], FMT, VA); VA_END (VA) LSTRCAT (BUFF, "/ R / N"); AFXMessageBox (BUF);} Virtual Function Bool CDIRECTXWND :: RESTORESURFCES () {HRESULT DDRVAL; DDRVAL = LPFRONTBUFFER-> Restore ();

if (ddrval = DD_OK!) return FALSE; return TRUE;} BOOL CDirectXWnd :: CleanSurface () {if (lpBackBuffer) {lpBackBuffer-> Release (); lpBackBuffer = NULL;} if (lpFrontBuffer) {lpFrontBuffer-> Release () ; lpFrontBuffer = NULL;} return TRUE;} void CDirectXWnd :: UpdateFrame () {} BEGIN_MESSAGE_MAP (CDirectXWnd, CWnd) // {{AFX_MSG_MAP (CDirectXWnd, Cwnd) ON_WM_KEYDOWN () ON_WM_ACTIVATEAPP () //}} AFX_MSG_MAP END_MESSAGE_MAP () / // CDirectXWnd message handlers void CDirectXWnd :: OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags) {switch (nChar) {case VK_ESCAPE: case VK_F12: PostMessage (WM_CLOSE); break;} CWnd :: OnKeyDown (nChar, nRepCnt, nFlags ); void cdirectxWnd :: OnActivateApp (Bool Bactive, htask htask) {CWnd :: OnActivateApp (BACTIVE, HTASK); BLSACTIVE = BACTIVE; RETURN;} Please download: 1, DirectX.zip, Engineering Frame source file; 2, ctestwnd .zip, test program source file. Do not compile directly when using these two source programs, because all files needed to be compiled, and should be done according to this article, when you need to enter the code, replace the file to the corresponding file in the download package. Also, do not switch from Alt Tab at runtime, otherwise it will be locked, and non-reset is not. If you want to be locked, please study the DirectDraw technology to modify this procedure. ---- No heart

This article is taken from the "Computer Programming Skills and Maintenance" magazine 1999, 3rd finishing: unintentional willow (all code has entered test pass) 1999/11/02

转载请注明原文地址:https://www.9cbs.com/read-1343.html

New Post(0)