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 [imageview.zip] (4,301 bytes) - [image viewer.cpp] - (11,819 bytes)

    //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
    ///////////////////////////////////////////////////////////

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.