See what's going on with flipcode!

This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.


  Image Viewer
  Submitted by

This program is a simple image viewer. It blts a bitmap to a surface then only displays whatever is in the user defined RECT. E,S,D,F resize the RECT and the arrow keys move it around the screen. I use this program for looking at templated bitmaps to get the exact coordinates of each cell.

Dave Javaheri

Currently browsing [] (4,301 bytes) - [image viewer.cpp] - (11,819 bytes)

//Program: Image Viewer
//Author:  Dave Javaheri
//Date:    9/08/2000

#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 = 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; = y1; rct.right = x2; rct.bottom = y2; //test for clipping if(x1<0) { rct.left+=x1; x2-=x1; x1=0; } if(y1<0) { +=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 ///////////////////////////////////////////////////////////

The zip file viewer built into the Developer Toolbox made use of the zlib library, as well as the zlibdll source additions.


Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
Please read our Terms, Conditions, and Privacy information.