Menu

Problems Loading Bitmaps in GDI

2004-01-20
2012-09-26
  • Nobody/Anonymous

    Hi, Im using dev c++ v.4.9.8.5

    the code below is designed to read data from a file consisting of the filenames of bmp images and a grid that determines how and where those bmps are displayed on the screen. (Like tiles in a game)

    The Init(HWND hwnd) function first gets the number of bitmaps from the file, then loads the filenames of those bitmaps into a global array of null terminated strings. It then loads two grids, one named g_Area with numbers that correspond to positions in the filename array (to tell the program what bitmap to display) and another,named g_Passable, that tells whether or not that tile can be walked on (for when I add sprites). Finally, Init() loads the bitmaps into another grid of HBITMAPs.

    In an Earlier version, I did not have the program load the bmp filenames from the file, I loaded the grid only and used a switch statement to manually load the bitmaps with constant values. This worked fine.

    However, I want this program to be as flexible as possible, and be able to change the tiles and grid layouts just by changing the text file, not recompiling. In the current version I have now, I have verified that it is loading the filenames correctly into the array, and the program compiles, but when i run it I receive "Illegal Operation" errors.
    So, can you only load bitmaps using the LoadImage() function with constants as filenames? or is something else wrong? Heres the code:

    Walkman.h:

    #include <fstream>

    using namespace std;

    #define WIN_WIDTH 640
    #define WIN_HEIGHT 480
    #define TILE_WIDTH 40
    #define TILE_HEIGHT 40
    #define AREA_ONE_FILE "Area1.grd"
    #define FPS 30

    bool isFullscreen;
    bool wantsFullscreen;

    //array of bitmap filenames

    PSTR list[32];

    //grids
    HBITMAP g_bmpTiles[WIN_HEIGHT / TILE_HEIGHT][WIN_WIDTH / TILE_WIDTH];
    int g_Area[WIN_HEIGHT / TILE_HEIGHT][WIN_WIDTH / TILE_WIDTH];
    bool g_Passable[WIN_HEIGHT / TILE_HEIGHT][WIN_WIDTH / TILE_WIDTH];

    //function headers
    HBITMAP LoadABitmap(LPSTR szFileName);
    void Init(HWND hwnd);
    void DeInit();
    void DrawTile(HWND hwnd, int x, int y);
    bool EnterFullScreenMode(int scrWidth, int scrHeight);

    //end of walkman.h

    walkman.cpp:

    #include <windows.h>
    #include "Walkman.h"

    using namespace std;

    /*  Declare Windows procedure  */
    LRESULT CALLBACK WinProc (HWND, UINT, WPARAM, LPARAM);

    /*  Make the class name into a global variable  */
    char szClassName[ ] = "Walkman";
    HDC hdc;

    DWORD PrevTime;
    DWORD CurrentTime;

    int WINAPI WinMain (HINSTANCE hThisInstance,
                        HINSTANCE hPrevInstance,
                        LPSTR CmdLine,
                        int ishow)

    {
        PrevTime = GetTickCount();
        int x, y;
        DWORD winStyle;
      
        isFullscreen = false;
        wantsFullscreen = false;
       
        HWND hwnd;               /* This is the handle for our window */
        MSG msg;            /* Here messages to the application are saved */
        WNDCLASSEX wndClass;        /* Data structure for the windowclass */

        /* The Window structure */
        wndClass.hInstance = hThisInstance;
        wndClass.lpszClassName = szClassName;
        wndClass.lpfnWndProc = WinProc;      /* This function is called by windows */
        wndClass.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;                 /* Catch double-clicks */
        wndClass.cbSize = sizeof (WNDCLASSEX);

        /* Use default icon and mouse-pointer */
        wndClass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
        wndClass.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
        wndClass.hCursor = LoadCursor (NULL, IDC_ARROW);
        wndClass.lpszMenuName = NULL;                 /* No menu */
        wndClass.cbClsExtra = 0;                      /* No extra bytes after the window class */
        wndClass.cbWndExtra = 0;                      /* structure or the window instance */
        /* Use Windows's default color as the background of the window */
        wndClass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);

        /* Register the window class, and if it fails quit the program */
        if (!RegisterClassEx (&wndClass))
            return 0;
        if(MessageBox(NULL, "Go Fullscreen?", "Options", MB_YESNO) == IDYES)
           wantsFullscreen = true;
        else
           wantsFullscreen = false;
        if(wantsFullscreen)
        {   
            if(!EnterFullScreenMode(WIN_WIDTH,WIN_HEIGHT))
                {
                  MessageBox(NULL,"Failed to enter fullscreen mode.","ERROR!", MB_OK);
                  return 0;
                }
            winStyle = WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
            ShowCursor(0);
        }
        else
            winStyle = WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
          
        /* The class is registered, let's create the program*/
        hwnd = CreateWindowEx (
               0,                   /* Extended possibilites for variation */
               szClassName,         /* Classname */
               "Walkman",       /* Title Text */
               winStyle, /* default window */
               0,       /* Windows decides the position */
               0,       /* where the window ends up on the screen */
               WIN_WIDTH,                 /* The programs width */
               WIN_HEIGHT,                 /* and height in pixels */
               HWND_DESKTOP,        /* The window is a child-window to desktop */
               NULL,                /* No menu */
               hThisInstance,       /* Program Instance handler */
               NULL                 /* No Window Creation data */
               );
        Init(hwnd);
              
         /* Make the window visible on the screen */
        ShowWindow (hwnd, ishow);
        UpdateWindow (hwnd);

        while(1)
        {
            if(PeekMessage(&msg, hwnd, 0, 0, PM_REMOVE))
            {
                    if (msg.message == WM_QUIT)
                       break;
                    TranslateMessage(&msg);
                    DispatchMessage(&msg);
            }
            else
            {
                    CurrentTime = GetTickCount();
                             
                    if( (CurrentTime - PrevTime) / 1000.0 >= (1.0 / FPS))
                    {
                       for(y = 0; y < WIN_HEIGHT / TILE_HEIGHT; y++)
                       {
                         for(x = 0; x < WIN_WIDTH / TILE_WIDTH; x++)
                         {
                            DrawTile(hwnd, x, y);
                         }
                       }
                     PrevTime = CurrentTime;
                    }
                   
                   
           }
        }
        DeInit();
       
        return msg.wParam;
    }

    /*  This function is called by the Windows function DispatchMessage()  */

    LRESULT CALLBACK WinProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        WINDOWPLACEMENT winSet;
        winSet.length = sizeof(WINDOWPLACEMENT);
        PAINTSTRUCT PaintStrct;
       
        switch (message)                  /* handle the messages */
        {
          
            case WM_PAINT:
                hdc = BeginPaint(hwnd, &PaintStrct);
              
                EndPaint(hwnd, &PaintStrct);
                break;
           
            case WM_KEYDOWN:                 //if the escape key is pressed, app closes...
               
                switch(wParam)
                    {
                        case VK_ESCAPE:
                          if(isFullscreen) ChangeDisplaySettings(NULL,0);
                          isFullscreen = false;
                          PostQuitMessage(0);
                          break;
                    }
                break;
               
            case WM_ACTIVATEAPP:                        //if the application is deactivated,
               
                switch(wParam)                          //window is minimized and screen resolution is
                {                                       //restored...
                   case 0:
                     if(isFullscreen)
                     {
                        ChangeDisplaySettings(NULL,0);
                        isFullscreen = false;
                        GetWindowPlacement(hwnd,&winSet);
                        winSet.showCmd = SW_MINIMIZE;
                        SetWindowPlacement(hwnd,&winSet);
                     }
                     break;
                  
                   case 1:
                     if(!isFullscreen && wantsFullscreen)
                        EnterFullScreenMode(WIN_WIDTH,WIN_HEIGHT);
                     break;
                } break;
                       
            case WM_CLOSE:
            case WM_DESTROY:
                PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
                break;
               
            default:                      /* for messages that we don't deal with */
                return DefWindowProc (hwnd, message, wParam, lParam);
        }

        return 0;
    }

    void Init(HWND hwnd)
    {   
        int x, y, numTiles;
        ifstream fin(AREA_ONE_FILE);
        fin >> numTiles;
        PSTR file;
       
        for(x = 0; x < numTiles; x++)
        {
           file = "";
           fin >> file;
           *list[x] = *file;
        }
          
       
        for(y = 0; y < WIN_HEIGHT / TILE_HEIGHT; y++)
        {
           
            for(x = 0; x < WIN_WIDTH / TILE_WIDTH; x++)
            {
             
                fin >> g_Area[y][x];
            }
        }
       
        for(y = 0; y < WIN_HEIGHT / TILE_HEIGHT; y++)
        {
           
            for(x = 0; x < WIN_WIDTH / TILE_WIDTH; x++)
            {
             
                fin >> g_Passable[y][x];
            }
        }

        // Read in the titles, depending on our g_BoardArray
        for(y = 0; y < WIN_HEIGHT / TILE_HEIGHT; y++)
        {
           
            for(x = 0; x < WIN_WIDTH / TILE_WIDTH; x++)
            {
               
                //Do a switch on the value of the current index
                // Since we are using a 1D array, we use the equation:
                // x + y * BOARD_WIDTH  - This allows us to treat it like a 2D array
                file = "";
                *file = *list[g_Area[y][x]];
                g_bmpTiles[y][x] = LoadABitmap(file);
               
            }
        }
       
        fin.close();
                                               
    }

    void DeInit()
    {
            // Go through and free all of our tiles
        for(int y = 0; y < WIN_HEIGHT / TILE_HEIGHT; y++)
        {
            for(int x = 0; x < WIN_WIDTH / TILE_WIDTH; x++)
            {
                // Free the tile stored in this index
                DeleteObject(g_bmpTiles[y][x]);
            }
        }

        // Post the QUIT message to the window (0 = WM_QUIT)                                                           
        PostQuitMessage(0);               
    }

    HBITMAP LoadABitmap(LPSTR szFileName)
    {
        // Load the bitmap and return the handle to the bitmap we just loaded
        return (HBITMAP)LoadImage(NULL, szFileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
    }

    bool EnterFullScreenMode(int scrWidth, int scrHeight)
    {
        DEVMODE devMode;
        memset(&devMode,0,sizeof(DEVMODE));
        devMode.dmSize = sizeof(DEVMODE);
        EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&devMode);
        devMode.dmPelsWidth = scrWidth;
        devMode.dmPelsHeight = scrHeight;   
      
        if(ChangeDisplaySettings(&devMode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
        {
            return 0;
        }
        else
        {
            isFullscreen = true;
            return 1;      
        }
    }

    void DrawTile(HWND hwnd, int x, int y)
    {
        HDC hdc = GetDC(hwnd);
        HDC ImageDC = CreateCompatibleDC(hdc);
        HBITMAP oldBitmap;
        oldBitmap = (HBITMAP) SelectObject(ImageDC, g_bmpTiles[y][x]);
        BitBlt(hdc,
               x * TILE_WIDTH,
               y * TILE_HEIGHT,
               TILE_WIDTH,
               TILE_HEIGHT,
               ImageDC,
               0,
               0,
               SRCCOPY);
        SelectObject(ImageDC, oldBitmap);
        DeleteDC(ImageDC);
        ReleaseDC(hwnd,hdc);
    }

     
    • Anonymous

      Anonymous - 2004-01-21

      Ok guys this is the original poster (I registered.)

      Just wanted to let you know that I fixed my problem by changing all my C-style NULL terminated strings into objects of the string class, and used a vector object instead of a C-style array to store my list of filenames.

       

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.