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);
};