View Single Post
  #1 (permalink)  
Old September 1st, 2003, 12:33 PM
drb2k2 drb2k2 is offline
Authorized User
 
Join Date: Jun 2003
Posts: 15
Thanks: 0
Thanked 0 Times in 0 Posts
Default Can't display a bitmap in a window

Hi all,
I have this piece of code which was butchered from a book. I tried
to make a class that would load a specified bitmap into a window. There are no error messages generated but when its run the window just contains a snap shot of whatever was underneath it (usually .NET). When the window is moved the snapshot moves with it. Needless to say i'm new to windows programming and can't see what the problems are. I expect its something to do with the DC for the bitmap. If anyone could supply some example code I would be very grateful.
Cheers
Drb2k2



int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    HWND hwnd = InitWindow(hInstance, nCmdShow);

    while(1)
    {
        MSG msg;
        if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
        {
            int result = GetMessage(&msg, NULL, 0, 0);
            if(!result) return(msg.wParam);

            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    return 0;
}

and the class files
#include <windows.h>
#include "BitmapLoad.h"

const char *g_strAppName = "Windows Bitmaps"; // name of application
int g_iScreenWidth = 640; // Screen width in pixels
int g_iScreenHeight = 480; // Screen height in pixels

void PaintWindow(HDC hdc, CBitmapLoad Bitmap1)
{
    // set mapping mode as text
    SetMapMode(hdc, MM_TEXT);

    BitBlt(hdc, 0, 0, g_iScreenWidth, g_iScreenHeight, Bitmap1.m_hdcBitmap, 0, 0, SRCCOPY);
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    CBitmapLoad Bitmap1;
    switch(uMsg)
    {
    case WM_CREATE:
        {
        //the window is being created load a bitmap into an off screen DC

        HDC hdcWindow = GetDC(hwnd); // get a DC for this window
        Bitmap1.m_hdcBitmap = CreateCompatibleDC(hdcWindow); // create a compatible in-memory device context
        Bitmap1.LoadBitmap("Trippy.bmp");
        ReleaseDC(hwnd, hdcWindow);
        }
    break;

    case WM_DESTROY:
        {
            if(!Bitmap1.m_hOldBitmap == NULL)
            Bitmap1.Delete();
            //DeleteObject((HGDIOBJ)Bitmap1);
        }
        break;

    case WM_PAINT:
        {
            PAINTSTRUCT ps;

            BeginPaint(hwnd, &ps); // Get the DC we're supposed to use from Windows
            HDC hdc = ps.hdc;

            PaintWindow(hdc, Bitmap1); // Paint the window

            EndPaint(hwnd, &ps);
        }
        return(0);

    case WM_CLOSE:
        {
            PostQuitMessage(0);
            return(0);
        }

    case WM_SIZE:
            g_iScreenWidth = LOWORD(lParam); // new width of client area
            g_iScreenHeight = LOWORD(lParam);
        break;
    }
    return(DefWindowProc(hwnd, uMsg, wParam, lParam));
}

HWND InitWindow(HINSTANCE hinst, int nCmdShow)
{
    HWND hwnd;
    WNDCLASSEX wc;

    // set up and register window class
  memset(&wc, 0, sizeof(wc));
  wc.cbSize = sizeof(wc);
  wc.style = CS_HREDRAW | CS_VREDRAW;
  wc.lpfnWndProc = WindowProc; // change this to NULL and crash!
  wc.cbClsExtra = 0;
  wc.cbWndExtra = 0;
  wc.hInstance = hinst;
  wc.hIcon = NULL;
  wc.hIconSm = NULL;
  wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  wc.hbrBackground = NULL; // don't repaint background. this kills flicker.
  wc.lpszMenuName = NULL;
  wc.lpszClassName = "MyCoolWindow";
  RegisterClassEx(&wc);

  // create a window that's 640 pixels wide, 480 tall.
  hwnd = CreateWindowEx(0, "MyCoolWindow", g_strAppName,
        WS_POPUP | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME,
      10, 10, g_iScreenWidth, g_iScreenHeight, NULL, NULL, hinst, NULL);

  if (!hwnd) {
    ::MessageBox(NULL, "CreateWindow failed!", g_strAppName, MB_ICONSTOP);
    exit(-1);
  }

  ShowWindow(hwnd, nCmdShow);
  return(hwnd);
}

HEADER
#pragma once
#include<windows.h>

class CBitmapLoad
{
public:
    CBitmapLoad(void);
    virtual ~CBitmapLoad(void);
    HDC m_hdcBitmap;
    HBITMAP m_hBitmap;
    HBITMAP m_hOldBitmap;
    int m_iWidth;
    int m_iHeight;
    void LoadBitmap(LPCTSTR lpszFilename);
    void Delete(void);
};

[/code]
and the class file
Code:
#include "bitmapload.h"

CBitmapLoad::CBitmapLoad(void)
: m_iWidth(0)
, m_iHeight(0)
, m_hdcBitmap(NULL)
, m_hBitmap(NULL)
, m_hOldBitmap(NULL)
{
}

CBitmapLoad::~CBitmapLoad(void)
{
}

void CBitmapLoad::LoadBitmap(LPCTSTR lpszFilename)
{
    m_hBitmap = (HBITMAP)LoadImage(NULL, lpszFilename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
    m_hOldBitmap = (HBITMAP)SelectObject(m_hdcBitmap, m_hBitmap);
    BITMAP bmp;
    GetObject(m_hBitmap,sizeof(BITMAP),(LPVOID)&bmp);
    m_iWidth = bmp.bmWidth;
    m_iHeight = bmp.bmHeight;
}

void CBitmapLoad::Delete(void)
{
    m_hBitmap = (HBITMAP)SelectObject(m_hdcBitmap, m_hOldBitmap);
    DeleteDC(m_hdcBitmap);
}
Finally the header for the class
Code:
#pragma once
#include<windows.h>

class CBitmapLoad
{
public:
    CBitmapLoad(void);
    virtual ~CBitmapLoad(void);
    HDC m_hdcBitmap;
    HBITMAP m_hBitmap;
    HBITMAP m_hOldBitmap;
    int m_iWidth;
    int m_iHeight;
    void LoadBitmap(LPCTSTR lpszFilename);
    void Delete(void);
};
Reply With Quote