//Program: Image Viewer
//Author: Dave Javaheri
//Date: 9/08/2000
//DEFINES//////////////////////////////////////////////////////////////
#define INITGUID
#define WIN32_LEAN_AND_MEAN
#define SCREEN_WIDTH 640 //screen resolution
#define SCREEN_HEIGHT 480
#define SCREEN_BPP 16 //screen bitdepth (8,16,24 etc.)
#define DDRAW_INIT_STRUCT(ddstruct) {memset(&ddstruct,0,sizeof(ddstruct));ddstruct.dwSize=sizeof(ddstruct);}
#define SafeRelease(x) if (x) { x->Release(); x=NULL;}
//INCLUDES/////////////////////////////////////////////////////////////
#include <windows.h> // include important windows stuff
#include <windowsx.h>
#include <stdio.h>
#include <ddraw.h>
#include <mmsystem.h>
//ERROR STRINGS////////////////////////////////////////////////////////
const char *ErrStr=NULL;
const char Err_Reg_Class[] = "Error Registering Window Class";
const char Err_Create_Win[] = "Error Creating Window";
const char Err_DirectDrawCreate[] = "DirectDrawCreate FAILED";
const char Err_Coop[] = "SetCooperativeLevel FAILED";
const char Err_CreateSurf[] = "CreateSurface FAILED";
const char Err_GetBack[] = "Error Retrieving Back Buffer";
const char Err_DispMode[] = "Error Setting Display Mode";
const char Err_LoadImage[] = "Error Loading Image";
//WINDOW CLASS INFORMATION/////////////////////////////////////////////
static char szClass[] = "Image Loader";
static char szCaption[] = "Image Loader";
//GLOBALS//////////////////////////////////////////////////////////////
LPDIRECTDRAW7 lpDD = NULL; //ddraw object
LPDIRECTDRAWSURFACE7 lpDDSPrimary = NULL; //primary surface
LPDIRECTDRAWSURFACE7 lpDDSBack = NULL; //backbuffer
LPDIRECTDRAWSURFACE7 bitmap_surface = NULL; //holds bitmap
HWND hWnd = NULL; //main window handle
int x1 = 0; //starting size of rect
int y1 = 0;
int x2 = 200;
int y2 = 200;
RECT rct;
char buffer[126];
char *g_filename = "bitmap24.bmp"; //the file name of the bmp
//PROTOTYPES///////////////////////////////////////////////////////////
void Game_Shutdown();
static BOOL Init(HINSTANCE hInstance, int nCmdShow);
int Game_Main();
LPDIRECTDRAWSURFACE7 LoadSurface(LPCTSTR file_name,RECT *dims=NULL);
int Draw_Text(char*,int,int,COLORREF, LPDIRECTDRAWSURFACE7);
int DDraw_Fill_Surface(LPDIRECTDRAWSURFACE7 lpdds,int color);
//------ Windows Message Handler ------//
LRESULT CALLBACK
WindowProc(HWND hWnd, unsigned uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_DESTROY:
Game_Shutdown();
PostQuitMessage(0);
break;
case WM_KEYDOWN:
switch (wParam)
{
case VK_ESCAPE: // exit the program on escape
DestroyWindow(hWnd);
break;
case VK_RIGHT: //move rect to the right
x1 += 1;
x2 += 1;
break;
case VK_LEFT: //move rect to the left
x1 -= 1;
x2 -= 1;
break;
case VK_UP: //move rect up
y1 -= 1;
y2 -= 1;
break;
case VK_DOWN: //move rect down
y1 += 1;
y2 += 1;
break;
case 'E': //increase height
y1 -= 1;
break;
case 'D': //decrease height
y2 -= 1;
break;
case 'S': //increase width
x1 -= 1;
break;
case 'F': //decrease width
x2 -= 1;
break;
// Process other non-character keystrokes.
default:
break;
}
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0L;
}
///////////////////////////////////////////////////////////////////////
//------ Application Loop ------//
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg; // message from queue
BOOL notDone=TRUE; // flag for thread completion
WNDCLASS wc;
// Set up and register window class
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC) WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = sizeof(DWORD);
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = szClass;
if (!RegisterClass(&wc))
{
ErrStr=Err_Reg_Class;
return FALSE;
}
// Get dimensions of display
int ScreenWidth = GetSystemMetrics(SM_CXSCREEN);
int ScreenHeight = GetSystemMetrics(SM_CYSCREEN);
// Create a window and display
hWnd = CreateWindow(szClass, //class
szCaption, //caption
WS_VISIBLE|WS_POPUP, //style
0, //left
0, //top
ScreenWidth, //width
ScreenHeight, //height
NULL, //parent window
NULL, //menu
hInstance, //instance
NULL); //parms
if (!hWnd)
{
ErrStr=Err_Create_Win;
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
//initialize the application, exit on failure
if (!Init(hInstance, nCmdShow))
{
Game_Shutdown();
return FALSE;
}
while (notDone)
{
// is there a message to process?
if (PeekMessage( &msg, NULL, 0, 0, PM_REMOVE))
{
// yes, is it a quit message?
if (msg.message==WM_QUIT)
notDone=FALSE;
// dispatch the message
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
//User does not want to quit so run game main
Game_Main();
}
}
//exit returning final message
return (msg.wParam);
}
//------ Function to Initialize DirectDraw and the Application ------//
static BOOL Init(HINSTANCE hInstance, int nCmdShow)
{
HRESULT ddrval;
//Create the main DirectDraw object
ddrval=DirectDrawCreateEx(NULL,(VOID **)&lpDD,IID_IDirectDraw7,NULL);
if (ddrval != DD_OK)
{
ErrStr=Err_DirectDrawCreate;
return FALSE;
}
//Set our cooperative level
ddrval=lpDD->SetCooperativeLevel(hWnd,DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
if (ddrval != DD_OK)
{
ErrStr=Err_Coop;
return FALSE;
}
//Set the display mode
ddrval=lpDD->SetDisplayMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,0,0);
if (ddrval !=DD_OK)
{
ErrStr=Err_DispMode;
return FALSE;
}
//Create the primary surface with 1 back buffer
DDSURFACEDESC2 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 = 1;
ddrval = lpDD->CreateSurface( &ddsd, &lpDDSPrimary, NULL );
if (ddrval!=DD_OK)
{
ErrStr=Err_CreateSurf;
return FALSE;
}
//Fetch back buffer interface
DDSCAPS2 ddscaps;
ZeroMemory(&ddscaps,sizeof(ddscaps));
ddscaps.dwCaps=DDSCAPS_BACKBUFFER;
ddrval=lpDDSPrimary->GetAttachedSurface(&ddscaps,&lpDDSBack);
if (ddrval!=DD_OK)
{
ErrStr=Err_GetBack;
return FALSE;
}
//Clear out the back buffer
DDraw_Fill_Surface(lpDDSBack, 0);
bitmap_surface=LoadSurface(g_filename);
if(!bitmap_surface)
{
ErrStr=Err_LoadImage;
return FALSE;
}
//return success to caller
return TRUE;
}
///////////////////////////////////////////////////////////////////////
int Game_Main()
{
//clip the sprite if necessary
rct.left = x1;
rct.top = y1;
rct.right = x2;
rct.bottom = y2;
//test for clipping
if(x1<0)
{
rct.left+=x1;
x2-=x1;
x1=0;
}
if(y1<0)
{
rct.top +=y1;
y2-=y1;
y1 =0;
}
if(x2>640)
{
rct.right += x2;
x1-=1;
x2=640;
}
if(y2>480)
{
rct.bottom += y2;
y1-=1;
y2=480;
}
//blt bitmap to back buffer
lpDDSBack->BltFast(x1,y1,bitmap_surface,&rct,DDBLTFAST_WAIT);
sprintf(buffer,"X1 = [%d] Y1 = [%d] X2 = [%d] Y2 = [%d] E,S,D,F"
" resize image, arrow keys move Rect ", x1, y1, x2, y2);
Draw_Text(buffer,8,0,RGB(0,255,0),lpDDSBack);
//flip the surfaces
lpDDSPrimary->Flip(NULL, DDFLIP_WAIT);
//Clear out the back buffer
DDraw_Fill_Surface(lpDDSBack, 0);
//return success
return(1);
} //end Game_Main
///////////////////////////////////////////////////////////////////////
//Cleanup Function to Release Objects//////////////////////////////////
void Game_Shutdown()
{
//release the surface
SafeRelease(bitmap_surface);
//release DirectDraw interfaces
SafeRelease(lpDDSPrimary);
SafeRelease(lpDD);
//display error if one thrown
if (ErrStr)
{
MessageBox(NULL, ErrStr, szCaption, MB_OK);
ErrStr=NULL;
}
}
LPDIRECTDRAWSURFACE7 LoadSurface(LPCTSTR file_name,RECT *dims)
{
HDC hdc;
HBITMAP bit;
LPDIRECTDRAWSURFACE7 surf;
//load the interface bitmap
bit=(HBITMAP) LoadImage(NULL,file_name,IMAGE_BITMAP,0,0,
LR_DEFAULTSIZE|LR_LOADFROMFILE);
if(!bit)
// failed to load, return failure to caller
return NULL;
//get bitmap dimensions
BITMAP bitmap;
GetObject( bit, sizeof(BITMAP), &bitmap );
int surf_width=bitmap.bmWidth;
int surf_height=bitmap.bmHeight;
//create surface
HRESULT ddrval;
DDSURFACEDESC2 ddsd;
ZeroMemory(&ddsd,sizeof(ddsd));
ddsd.dwSize = sizeof(DDSURFACEDESC2);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwWidth = surf_width;
ddsd.dwHeight = surf_height;
//attempt to create surface
ddrval=lpDD->CreateSurface(&ddsd,&surf,NULL);
//created ok?
if(ddrval!=DD_OK)
{
//no, release the bitmap and return failure to caller
DeleteObject(bit);
return NULL;
}
else
{
//yes, get a DC for the surface
surf->GetDC(&hdc);
//generate a compatible DC
HDC bit_dc=CreateCompatibleDC(hdc);
//blit the interface to the surface
SelectObject(bit_dc,bit);
BitBlt(hdc,0,0,surf_width,surf_height,bit_dc,0,0,SRCCOPY);
//release the DCs
surf->ReleaseDC(hdc);
DeleteDC(bit_dc);
//save the dimensions if rectangle pointer provided
if(dims)
{
dims->left=0;
dims->top=0;
dims->right=surf_width;
dims->bottom=surf_height;
}
}
//clear bitmap
DeleteObject(bit);
//return pointer to caller
return surf;
}
//------ Function to clear a surface ----------------------//
int DDraw_Fill_Surface(LPDIRECTDRAWSURFACE7 lpdds,int color)
{
DDBLTFX ddbltfx; // this contains the DDBLTFX structure
//clear out the structure and set the size field
DDRAW_INIT_STRUCT(ddbltfx);
//set the dwfillcolor field to the desired color
ddbltfx.dwFillColor = color;
//ready to blt to surface
lpdds->Blt(NULL, //ptr to dest rectangle
NULL, //ptr to source surface, NA
NULL, //ptr to source rectangle, NA
DDBLT_COLORFILL | DDBLT_WAIT, //fill and wait
&ddbltfx); //ptr to DDBLTFX structure
//return success
return(1);
} //end DDraw_Fill_Surface
///////////////////////////////////////////////////////////
int Draw_Text(char*text,int x,int y,COLORREF color,LPDIRECTDRAWSURFACE7 lpdds)
{
//this function draws the sent text on the sent surface
//using color index as the color in the palette
HDC xdc; //the working dc
//get the dc from surface
if(FAILED(lpdds->GetDC(&xdc)))
return(0);
//set the colors for the text up
SetTextColor(xdc,color);
//set background mode to transparent so black isn't copied
SetBkMode(xdc, TRANSPARENT);
//draw the text a
TextOut(xdc,x,y,text,strlen(text));
//release the dc
lpdds->ReleaseDC(xdc);
//return success
return(1);
} //end Draw_Text_GDI
///////////////////////////////////////////////////////////
|