|
|
//-----------------------------------------------------------------------------
// File: WinMain.CPP
//
// Desc: This sample demonstrates how to bring up a dialog, or any type of
// window, in a DirectDraw full-screen exclusive mode, even on non GDI
// devices.
//
//
// Copyright (c) 1998-1999 Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#define NAME "FSWindow"
#define TITLE "DDraw Full-Screen Dialog Example"
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
//-----------------------------------------------------------------------------
// Include files
//-----------------------------------------------------------------------------
#include "dconfigp.h"
BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); BOOL Init();
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
extern HINSTANCE g_hInst; IDirectDraw7 *g_pDD = NULL; // DirectDraw object
IDirectDrawSurface7 *g_pDDSPrimary = NULL; // DirectDraw primary surface
IDirectDrawSurface7 *g_pDDSBack = NULL; // DirectDraw back surface
BOOL g_fActive = FALSE; // App is running/active
BOOL g_fReady = FALSE; // App is ready for updates
BOOL g_fPaused = FALSE; // App is paused
HWND g_hWndHelp = NULL; HWND g_hWndDlg = NULL; // Sample dialog box handle
//-----------------------------------------------------------------------------
// Name: DebugMsg()
// Desc: This function essentially is a printf for debug output.
//-----------------------------------------------------------------------------
void DebugMsg(LPCTSTR szError,...) { char szBuff[128]; va_list vl;
va_start(vl, szError); #ifdef WIN95
{ char *psz = NULL; char szDfs[1024]={0}; strcpy(szDfs,szError); // make a local copy of format string
while (psz = strstr(szDfs,"%p")) // find each %p
*(psz+1) = 'x'; // replace each %p with %x
vsprintf(szBuff, szDfs, vl); // use the local format string
} #else
{ vsprintf(szBuff, szError, vl); } #endif
OutputDebugString(szBuff); va_end(vl); }
//-----------------------------------------------------------------------------
// Name: ReleaseAllObjects()
// Desc: Release all DDraw objects we use.
//-----------------------------------------------------------------------------
HRESULT ReleaseAllObjects(HWND hWnd) { if (g_pDD != NULL) { g_pDD->SetCooperativeLevel(hWnd, DDSCL_NORMAL); if (g_pDDSBack != NULL) { g_pDDSBack->Release(); g_pDDSBack = NULL; } if (g_pDDSPrimary != NULL) { g_pDDSPrimary->Release(); g_pDDSPrimary = NULL; } } return DD_OK; }
//-----------------------------------------------------------------------------
// Name: InitFail()
// Desc: This function is called if an initialization function fails.
//-----------------------------------------------------------------------------
HRESULT InitFail(HWND hWnd, HRESULT hRet, LPCTSTR szError,...) { char szBuff[128]; va_list vl;
va_start(vl, szError); #ifdef WIN95
{ char *psz = NULL; char szDfs[1024]={0}; strcpy(szDfs,szError); // make a local copy of format string
while (psz = strstr(szDfs,"%p")) // find each %p
*(psz+1) = 'x'; // replace each %p with %x
vsprintf(szBuff, szDfs, vl); // use the local format string
} #else
{ vsprintf(szBuff, szError, vl); } #endif
ReleaseAllObjects(hWnd); MessageBox(hWnd, szBuff, TITLE, MB_OK); DestroyWindow(hWnd); va_end(vl); return hRet; }
//-----------------------------------------------------------------------------
// Name: AppPause()
// Desc: Toggles the pause mode of the app.
//-----------------------------------------------------------------------------
void AppPause(HWND hWnd, BOOL fPause) { if (fPause) { g_fPaused = TRUE; g_pDD->FlipToGDISurface(); RedrawWindow(hWnd, NULL, NULL, RDW_FRAME); } else { RedrawWindow(hWnd, NULL, NULL, RDW_FRAME); g_fPaused = FALSE; } }
//-----------------------------------------------------------------------------
// Name: InitSurfaces()
// Desc: Create all the needed DDraw surfaces and set the coop level.
//-----------------------------------------------------------------------------
static HRESULT InitSurfaces(HWND hWnd) { HRESULT hRet; DDSURFACEDESC2 ddsd; DDSCAPS2 ddscaps;
// Get exclusive mode
hRet = g_pDD->SetCooperativeLevel(hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); if (hRet != DD_OK) return InitFail(hWnd, hRet, "SetCooperativeLevel FAILED");
// Set the video mode to 640x480x16
hRet = g_pDD->SetDisplayMode(1024, 768, 16, 0, 0); if (hRet != DD_OK) return InitFail(hWnd, hRet, "SetDisplayMode FAILED");
// Create the primary surface with 1 back buffer
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 = 1; hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSPrimary, NULL); if (hRet != DD_OK) return InitFail(hWnd, hRet, "CreateSurface (3) FAILED");
ZeroMemory(&ddscaps, sizeof(ddscaps)); ddscaps.dwCaps = DDSCAPS_BACKBUFFER; hRet = g_pDDSPrimary->GetAttachedSurface(&ddscaps, &g_pDDSBack); if (hRet != DD_OK) return InitFail(hWnd, hRet, "GetAttachedSurface FAILED");
// Do help initialization
FSWindow_Init(hWnd, g_pDD, g_pDDSPrimary, g_pDDSBack);
return DD_OK; }
//-----------------------------------------------------------------------------
// Name: ChangeCoopLevel()
// Desc: Called when the user wants to toggle between Full-Screen & Windowed.
//-----------------------------------------------------------------------------
HRESULT ChangeCoopLevel(HWND hWnd) { HRESULT hRet;
// Release all objects that need to be re-created for the new device
if (FAILED(hRet = ReleaseAllObjects(hWnd))) return InitFail(hWnd, hRet, "ReleaseAllObjects FAILED");
// Re-create the surfaces
hRet = InitSurfaces(hWnd); return hRet; }
//-----------------------------------------------------------------------------
// Name: RenderFrame()
// Desc: Blts and moves a bouncing ball, as well as displays helpful text.
//-----------------------------------------------------------------------------
BOOL RenderFrame() { DDBLTFX ddbltfx; HDC hDC; static int x1 = 0, y1 = 0, x2 = 40, y2 = 40; HBRUSH hOldBrush; HPEN hOldPen; static int xDir = +8, yDir = +8;
// Use the blter to do a color fill to clear the back buffer
ZeroMemory(&ddbltfx, sizeof(ddbltfx)); ddbltfx.dwSize = sizeof(ddbltfx); ddbltfx.dwFillColor = 0; g_pDDSBack->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
if (g_pDDSBack->GetDC(&hDC) == DD_OK) { // Paint the bouncing ball
SetBkColor(hDC, RGB(0, 0, 255)); SetTextColor(hDC, RGB(255, 255, 0)); hOldBrush = (HBRUSH) SelectObject(hDC, GetStockObject(LTGRAY_BRUSH)); hOldPen = (HPEN) SelectObject(hDC, GetStockObject(WHITE_PEN)); Ellipse(hDC, x1, y1, x2, y2); SelectObject(hDC, hOldPen); SelectObject(hDC, hOldBrush);
// Move the bouncing ball and make it bounce
x1 += xDir; x2 += xDir; if (x1 < 0) { x1 = 0; x2 = 40; xDir = -xDir; } if (x2 >= 640) { x1 = 640 - 1 - 40; x2 = 640 - 1; xDir = -xDir; } y1 += yDir; y2 += yDir; if (y1 < 0) { y1 = 0; y2 = 40; yDir = -yDir; } if (y2 >= 480) { y1 = 480 - 1 - 40; y2 = 480 - 1; yDir = -yDir; }
// Display the proper text
TextOut(hDC, 0, 0, "Press Escape to quit", 20); TextOut(hDC, 0, 20, "Press F1 to bring up the dialog", 31);
g_pDDSBack->ReleaseDC(hDC); } return TRUE; }
//-----------------------------------------------------------------------------
// Name: UpdateFrame()
// Desc: Call RenderFrame() and the BLT and/or flip the new frame.
//-----------------------------------------------------------------------------
void UpdateFrame() { HRESULT hRet;
// Update the background and flip
//RenderFrame();
while (TRUE) { if (FSWindow_IsActive()) { FSWindow_Update(); break; } else { // Else we are in fullscreen mode, so perform a flip.
hRet = g_pDDSPrimary->Flip(NULL, 0L); } if (hRet == DD_OK) break; if (hRet == DDERR_SURFACELOST) { hRet = g_pDDSPrimary->Restore(); if (hRet != DD_OK) break; } if (hRet != DDERR_WASSTILLDRAWING) break; } }
//-----------------------------------------------------------------------------
// Name: MainWndProc()
// Desc: The Main Window Procedure.
//-----------------------------------------------------------------------------
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_ACTIVATEAPP: // Pause if minimized
g_fActive = !((BOOL)HIWORD(wParam)); return 0L;
case WM_CLOSE: FSWindow_End(); DestroyWindow(hWnd); break;
case WM_DESTROY: // Clean up and close the app
ReleaseAllObjects(hWnd); PostQuitMessage(0); return 0L;
case WM_KEYDOWN: // Handle any non-accelerated key commands
switch (wParam) { case VK_PAUSE: // Allow the app to be paused
AppPause(hWnd, !g_fPaused); break; case VK_ESCAPE: case VK_F12: PostMessage(hWnd, WM_CLOSE, 0, 0); return 0L; case VK_F1: g_hWndHelp = FSWindow_Begin(g_hWndDlg, FALSE); g_hWndDlg = CreateDialog(g_hInst, MAKEINTRESOURCE(IDD_DCONFIG_DIALOG), hWnd, (DLGPROC) DialogProc); ShowWindow(g_hWndDlg, SW_SHOWNORMAL); break; } break;
case WM_SETCURSOR: // Display the cursor if conditions are right
if (g_fActive && g_fReady && !g_fPaused && !FSWindow_IsActive()) { SetCursor(NULL); return TRUE; } break; } return DefWindowProc(hWnd, msg, wParam, lParam); }
//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: Entry point to the program. Initializes everything and calls
// AppIdle() when idle from the message pump.
//-----------------------------------------------------------------------------
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) { WNDCLASS wc; MSG msg; HWND hWnd; HRESULT hRet; HINSTANCE hDDrawDLL; LPDIRECTDRAWENUMERATEEX pDirectDrawEnumerateEx; DWORD dwLastTime; DWORD dwThisTime;
if (!hPrevInstance) { // Register the Window Class
wc.lpszClassName = NAME; wc.lpfnWndProc = MainWndProc; wc.style = CS_VREDRAW | CS_HREDRAW; wc.hInstance = hInstance; wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_DCONFIG_ICON)); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1); wc.lpszMenuName = NULL; wc.cbClsExtra = 0; wc.cbWndExtra = 0; if (!RegisterClass(&wc)) return FALSE; }
g_hInst = g_hInst = hInstance; // Init();
// Create and Show the Main Window
hWnd = CreateWindowEx(0, NAME, TITLE, WS_CLIPCHILDREN | WS_POPUP, CW_USEDEFAULT, CW_USEDEFAULT, 1024, 768, NULL, NULL, hInstance, NULL); if (hWnd == NULL) return FALSE;
// You need to do a GetModuleHandle and GetProcAddress in order to get the
// DirectDrawEnumerateEx function pointer
hDDrawDLL = GetModuleHandle("DDRAW"); if (!hDDrawDLL) return InitFail(hWnd, DD_OK, "GetModuleHandle FAILED");
//Create the main DirectDraw object
hRet = DirectDrawCreateEx(NULL, (VOID**)&g_pDD, IID_IDirectDraw7, NULL); if (hRet != DD_OK) return InitFail(hWnd, hRet, "DirectDrawCreateEx FAILED");
//Initialize all the surfaces we need
hRet = InitSurfaces(hWnd); if (FAILED(hRet)) return FALSE;
g_fReady = TRUE;
g_hWndDlg = CreateDialog(g_hInst, MAKEINTRESOURCE(IDD_DCONFIG_DIALOG), hWnd, (DLGPROC) DialogProc);
ShowWindow(g_hWndDlg, SW_SHOWNORMAL); Sleep(1000);
g_hWndHelp = FSWindow_Begin(g_hWndDlg, FALSE); // Put up the sample dialog right away, to show the sample user what this
// sample is trying to demonstrate.
//-------------------------------------------------------------------------
// The Message Pump
//-------------------------------------------------------------------------
dwLastTime = 0; dwThisTime = timeGetTime(); while (TRUE) { if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { if (!GetMessage(&msg, NULL, 0, 0)) break; // If the dialog is showing, translate messages for it since it's
// a modeless dialog.
if (g_hWndDlg == (HWND )NULL || !IsDialogMessage(g_hWndDlg, &msg)) { // Translate and dispatch the message
TranslateMessage(&msg); DispatchMessage(&msg); } } else if (g_fActive && g_fReady && !g_fPaused) { dwThisTime = timeGetTime(); // 1000/FPS = number of milliseconds to wait
if ((dwThisTime - dwLastTime) >= (1000/30)) { UpdateFrame(); dwLastTime = timeGetTime(); } } else // Make sure we go to sleep if we have nothing else to do
WaitMessage(); } // Release the main DDraw interface
if (g_pDD) g_pDD->Release();
return msg.wParam; }
|