Problem painting the BITMAP
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 14 of 14

Thread: Problem painting the BITMAP

  1. #1
    Join Date
    Nov 2009
    Posts
    32

    Problem painting the BITMAP

    Code:
    #include <windows.h>
    #include "resource.h"
    
    const char g_szClassName[] = "myWindowClass";
    
    HBITMAP g_hbmBall = NULL;
    HBITMAP g_hbmBrick = NULL;
    
    LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    	switch(msg)
    	{
    		case WM_CREATE:
    			g_hbmBall = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_BALL));
    			if(g_hbmBall == NULL)
    				MessageBox(hwnd, "Could not load IDB_BALL!", "Error", MB_OK | MB_ICONEXCLAMATION);
    			g_hbmBrick = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_BRICK));
    			if(g_hbmBrick == NULL)
    				MessageBox(hwnd, "Could not load IDB_BRICK!", "Error", MB_OK | MB_ICONEXCLAMATION);
    		break;
    		case WM_CLOSE:
    			DestroyWindow(hwnd);
    		break;
    		case WM_PAINT:
    		{
    			// Just a note, never use a MessageBox from inside WM_PAINT
    			// The box will cause more WM_PAINT messages and you'll probably end up
    			// stuck in a loop
    
    			BITMAP bm;
    			BITMAP bm2;
    			PAINTSTRUCT ps;
    			PAINTSTRUCT ps2;
    
    			HDC hdc = BeginPaint(hwnd, &ps);
    			HDC hdc2 = BeginPaint(hwnd, &ps2);
    
    			HDC hdcMem = CreateCompatibleDC(hdc);
    			HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, g_hbmBall);
    			HDC hdcMem2 = CreateCompatibleDC(hdc);
    			HBITMAP hbmOld2 = (HBITMAP)SelectObject(hdcMem2, g_hbmBrick);
    
    			GetObject(g_hbmBall, sizeof(bm), &bm);
    			GetObject(g_hbmBrick, sizeof(bm2), &bm2);
    
    			BitBlt(hdc, 10, 10, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
    			BitBlt(hdc, 50, 50, bm2.bmWidth, bm.bmHeight, hdcMem2, 0, 0, SRCCOPY);
    
    
    			SelectObject(hdcMem, hbmOld);
    			DeleteDC(hdcMem);
    
    			EndPaint(hwnd, &ps);
    		}
    		break;
    		case WM_DESTROY:
    			DeleteObject(g_hbmBall);
    			PostQuitMessage(0);
    		break;
    		default:
    			return DefWindowProc(hwnd, msg, wParam, lParam);
    	}
    	return 0;
    }
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    	LPSTR lpCmdLine, int nCmdShow)
    {
    	WNDCLASSEX wc;
    	HWND hwnd;
    	MSG Msg;
    
    	wc.cbSize		 = sizeof(WNDCLASSEX);
    	wc.style		 = 0;
    	wc.lpfnWndProc	 = WndProc;
    	wc.cbClsExtra	 = 0;
    	wc.cbWndExtra	 = 0;
    	wc.hInstance	 = hInstance;
    	wc.hIcon		 = LoadIcon(NULL, IDI_APPLICATION);
    	wc.hCursor		 = LoadCursor(NULL, IDC_ARROW);
    	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    	wc.lpszMenuName  = NULL;
    	wc.lpszClassName = g_szClassName;
    	wc.hIconSm		 = LoadIcon(NULL, IDI_APPLICATION);
    
    	if(!RegisterClassEx(&wc))
    	{
    		MessageBox(NULL, "Window Registration Failed!", "Error!",
    			MB_ICONEXCLAMATION | MB_OK);
    		return 0;
    	}
    
    	hwnd = CreateWindowEx(
    		WS_EX_CLIENTEDGE,
    		g_szClassName,
    		"A Bitmap Program",
    		WS_OVERLAPPEDWINDOW,
    		CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
    		NULL, NULL, hInstance, NULL);
    
    	if(hwnd == NULL)
    	{
    		MessageBox(NULL, "Window Creation Failed!", "Error!",
    			MB_ICONEXCLAMATION | MB_OK);
    		return 0;
    	}
    
    	ShowWindow(hwnd, nCmdShow);
    	UpdateWindow(hwnd);
    
    	while(GetMessage(&Msg, NULL, 0, 0) > 0)
    	{
    		TranslateMessage(&Msg);
    		DispatchMessage(&Msg);
    	}
    	return Msg.wParam;
    }
    so basically when i run this program i get the error that says it cannot load IDB_BRICK. i dont understand how i can get it to load that bitmap image.

    heres my resource file too

    Code:
    //{{NO_DEPENDENCIES}}
    // Microsoft Developer Studio generated include file.
    // Used by bmp_one.rc
    //
    #define IDB_BALL                        101
    #define IDB_BRICK                       102
    
    // Next default values for new objects
    // 
    #ifdef APSTUDIO_INVOKED
    #ifndef APSTUDIO_READONLY_SYMBOLS
    #define _APS_NEXT_RESOURCE_VALUE        102
    #define _APS_NEXT_COMMAND_VALUE         40001
    #define _APS_NEXT_CONTROL_VALUE         1000
    #define _APS_NEXT_SYMED_VALUE           101
    #endif
    #endif
    incidentally i'm trying to create a breakout clone and am wondering if i am going about this the right way.

  2. #2
    VictorN's Avatar
    VictorN is online now Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Wallisellen (ZH), Switzerland
    Posts
    17,267

    Re: Problem painting the BITMAP

    Well, the error message seems correct. Your "resource" file (at least, what you have shown as a resource file) does not contain any resource at all. Neither bitmaps now anything else.
    Victor Nijegorodov

  3. #3
    Join Date
    Apr 2009
    Posts
    598

    Re: Problem painting the BITMAP

    Have you included the resource file in your project ? (It is not enough to have #include "resource.h")
    HDC hdc = BeginPaint(hwnd, &ps);
    HDC hdc2 = BeginPaint(hwnd, &ps2);
    [...]EndPaint(hwnd, &ps);
    Two BeginPaint() ! I have never seen so many before at once ! Not sure this will work.
    Only one EndPaint() !

  4. #4
    Join Date
    Nov 2009
    Posts
    32

    Re: Problem painting the BITMAP

    well what i don't understand is that the file paints the image of the ball that is displayed but not the image of the brick. i was wondering the same thing, where do i declare what the bmp file is, or where it is located in the project. this is directly from the forgers win32 api tutorial and i have no idea how he gets the ball to display, without declaring the bmp as a resource anywhere in the program. i have looked over the code several times and just cant understand how to do it.

    also, if i dont declare begin paint multiple times how can i paint multiple objects to the screen? just using 1 begin paint?

  5. #5
    Join Date
    Apr 2009
    Posts
    598

    Re: Problem painting the BITMAP

    BeginPaint() is used to retrieve a handle to a display context (hdc).
    If you need another handle, usually, you call CreateComptaibleDC(), instead of calling again BeginPaint(). I don't know if calling several times BeginPaint() is working or not. It is just that I have never thought of doing that, and never seen a program doing that (although I am programming Windows applications for ten years).
    Otherwise, your code looks correct. I have done almost the same thing. If IDB_BRICK cannot be loaded, it might be a problem with the creation of the bitmap in the resource file. Maybe you could try to load it before loading the ball. Maybe you can try to store a third bitmap in the resource file, one that would be like the ball, and try to load it after having loaded the ball.
    Also, release hdcMem2 with SelectObject(hdcMem2, hbmOld2); DeleteDC(hdcMem2);;
    Last edited by olivthill2; November 23rd, 2010 at 04:55 AM.

  6. #6
    Join Date
    Nov 2009
    Posts
    32

    Re: Problem painting the BITMAP

    i cant figure out how to make a brick break program, i have put days of work into this and i dont understand how this is to be easy....Does anyone have, or know of, a tutorial where i can get a better understanding of how to make a game like this?

  7. #7
    Join Date
    Apr 2009
    Posts
    598

    Re: Problem painting the BITMAP

    Unfortunately this is not easy, you are right.
    I once suggested drawing a rectangle, because, myself, I have spent several days debugging the display of images from resources. In the end, I got the correct result, but maybe you don't have much time.
    If you want to keep on working with images, then, show us your code (I guess you have updated it since last time), show us your resource file. Like I said before, I think the problem is with the resource file. But you don't seem to listen to my advice :-(. Have you tried to remove the second BeginPaint()? Have you tried to load the brick before the ball? Have you tried to load the ball twice? What have you tried to do? Are there other problems than this loading of the brick? Can you draw a rectangle instead of loading the bitmap, so that you can go ahead and later you will try again loading the image? Good luck to you!

  8. #8
    Join Date
    Nov 2009
    Posts
    32

    Re: Problem painting the BITMAP

    ok so COMPLETE code remodification.....

    here is the new code

    Code:
    #include <windows.h>
    #include <string>
    using namespace std;
    
    const char g_szClassName[] = "myWindowClass";
    const int ID_TIMER = 1;
    const int BALL_MOVE_DELTA = 4; //ball speed
    
    typedef struct _BALLINFO 
    {
    	int width;
    	int height;
    	int x;
    	int y;
    
    	int dx;
    	int dy;
    }BALLINFO;
    
    BALLINFO g_ballInfo;
    
    typedef struct _PADDLEINFO 
    {
    	int width;
    	int height;
    	int x;
    	int y;
    
    	int dx;
    	int dy;
    }PADDLEINFO;
    
    PADDLEINFO g_leftPaddleInfo;
    
    string message = "A sample message.";
    
    void DrawBall(HDC hdc, RECT* prc)
    {
    
    	HBRUSH blueBrush=CreateSolidBrush(RGB(0,0,255));
    	HGDIOBJ old=SelectObject(hdc,blueBrush);
    
    	Ellipse(hdc, g_ballInfo.x, g_ballInfo.y, g_ballInfo.x+g_ballInfo.width, g_ballInfo.y+g_ballInfo.height);
    	
    	DeleteObject(blueBrush);
    	SelectObject(hdc,old);
    }
    
    void DrawLeftPaddle(HDC hdc, RECT* prc)
    {
    	HBRUSH redBrush=CreateSolidBrush(RGB(255,0,0));
    	HGDIOBJ old=SelectObject(hdc,redBrush);
    
    	Rectangle(hdc, g_leftPaddleInfo.x, g_leftPaddleInfo.y, g_leftPaddleInfo.x + g_leftPaddleInfo.width, g_leftPaddleInfo.y+g_leftPaddleInfo.height);
    
    	DeleteObject(redBrush);
    	SelectObject(hdc,old);
    }
    
    void UpdateBall(RECT* prc)
    {
    
    	// collision detection
    
    	g_ballInfo.x += g_ballInfo.dx;
    	g_ballInfo.y += g_ballInfo.dy;
    
    	if(g_ballInfo.x < 0)
    	{
    		g_ballInfo.x = 0;
    		g_ballInfo.dx = BALL_MOVE_DELTA;
    	}
    	else if(g_ballInfo.x + g_ballInfo.width > prc->right)
    	{
    		g_ballInfo.x = prc->right - g_ballInfo.width;
    		g_ballInfo.dx = -BALL_MOVE_DELTA;
    	}
    
    	if(g_ballInfo.y < 0)
    	{
    		g_ballInfo.y = 0;
    		g_ballInfo.dy = BALL_MOVE_DELTA;
    	}
    	else if(g_ballInfo.y + g_ballInfo.height > prc->bottom)
    	{
    		g_ballInfo.y = prc->bottom - g_ballInfo.height;
    		g_ballInfo.dy = -BALL_MOVE_DELTA;
    	}
    }
    
    LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    	switch(msg)
    	{
    		case WM_CREATE:
    		{
    			UINT ret;				//unsigned int to hold result of timer creation
    	
    			g_leftPaddleInfo.width = 60;
    			g_leftPaddleInfo.height = 10;
    		
    			g_leftPaddleInfo.x = 20;  // this is where the paddle starts
    			g_leftPaddleInfo.y = 340; // also here
    
    			g_ballInfo.width = 10;
    			g_ballInfo.height = 10;
    
    			g_ballInfo.dx = BALL_MOVE_DELTA;
    			g_ballInfo.dy = BALL_MOVE_DELTA;
    
    			ret = SetTimer(hwnd, ID_TIMER, 20, NULL);	// 20 milliseconds
    			if(ret == 0)								
    				MessageBox(hwnd, "Could not SetTimer()!", "Error", MB_OK | MB_ICONEXCLAMATION);
    		
    		}
    		break;
    		case WM_CLOSE:
    			DestroyWindow(hwnd);
    		break;
    		case WM_PAINT:
    		{
    			RECT rcClient;				//struct to hold rectangle coordinates	
    			PAINTSTRUCT ps;				//struct representing client area of window 
    			HDC hdc = BeginPaint(hwnd, &ps);
    
    			GetClientRect(hwnd, &rcClient);  //get coordinates of client area of window
    			 
    			DrawBall(hdc, &rcClient);
    		
    			EndPaint(hwnd, &ps);
    		}
    		break;
    		case WM_TIMER:
    		{
    			/*if (GetAsyncKeyState(VK_UP) < 0)
    			{
    				g_leftPaddleInfo.y-=6;
    			}
    			if(GetAsyncKeyState(VK_DOWN) < 0)
    			{
    				g_leftPaddleInfo.y+=6;
    			}
    			*/
    			if (GetAsyncKeyState(VK_RIGHT) < 0)
    			{
    				g_leftPaddleInfo.x+=6;
    			}
    			if(GetAsyncKeyState(VK_LEFT) < 0)
    			{
    				g_leftPaddleInfo.x-=6;
    			}
    
    			if(g_leftPaddleInfo.x < 0)
    	{
    		g_leftPaddleInfo.x = 0;
    		//g_ballInfo.dx = BALL_MOVE_DELTA;
    	}
    	else if(g_leftPaddleInfo.x + g_leftPaddleInfo.width > 385)
    	{
    		g_leftPaddleInfo.x =320;  // prc->right - g_leftPaddleInfo.width;
    		//g_ballInfo.dx = -BALL_MOVE_DELTA;
    	}
    
    
    
    			RECT rcClient;					//struct to hold rectangle coordinates
    			HDC hdc = GetDC(hwnd);			//grab a handle to the window (Device Context)
    
    			GetClientRect(hwnd, &rcClient);  //get coordinates of client area of window 
    											 // and store them in rcClient	
    			UpdateBall(&rcClient);			 //calculate next ball position
    
    			FillRect(hdc, &rcClient, (HBRUSH)GetStockObject(WHITE_BRUSH));
    			TextOut(hdc, 20, 20, message.c_str(), message.length());
    
    			DrawBall(hdc, &rcClient);		 //clear screan and draw ball in new position
    			DrawLeftPaddle(hdc, &rcClient);	
    			
    			ReleaseDC(hwnd, hdc);			//release the handle to the window (Device Context)
    		}
    		break;
    		
    
    
    		case WM_KEYDOWN:
    			/*	if(wParam == VK_DOWN)  // try this way instead - See the problem?
    					y+=6;
    				if(wParam == VK_UP)
    					y-=6;
    			*/
    		break;
    		case WM_KEYUP:
    				
    		break;
    		case WM_DESTROY:
    			KillTimer(hwnd, ID_TIMER);
    			PostQuitMessage(0);
    		break;
    		default:
    			return DefWindowProc(hwnd, msg, wParam, lParam);
    	}
    	return 0;
    }
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    	LPSTR lpCmdLine, int nCmdShow)
    {
    	WNDCLASSEX wc;
    	HWND hwnd;
    	MSG Msg;
    
    	wc.cbSize		 = sizeof(WNDCLASSEX);
    	wc.style		 = 0;
    	wc.lpfnWndProc	 = WndProc;
    	wc.cbClsExtra	 = 0;
    	wc.cbWndExtra	 = 0;
    	wc.hInstance	 = hInstance;
    	wc.hIcon		 = LoadIcon(NULL, IDI_APPLICATION);
    	wc.hCursor		 = LoadCursor(NULL, IDC_ARROW);
    	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    	wc.lpszMenuName  = NULL;
    	wc.lpszClassName = g_szClassName;
    	wc.hIconSm		 = LoadIcon(NULL, IDI_APPLICATION);
    
    	if(!RegisterClassEx(&wc))
    	{
    		MessageBox(NULL, "Window Registration Failed!", "Error!",
    			MB_ICONEXCLAMATION | MB_OK);
    		return 0;
    	}
    
    	hwnd = CreateWindowEx(
    		WS_EX_CLIENTEDGE,
    		g_szClassName,
    		"An Animation Program",
    		WS_OVERLAPPEDWINDOW,
    		CW_USEDEFAULT, CW_USEDEFAULT, 400, 400,
    		NULL, NULL, hInstance, NULL);
    
    	if(hwnd == NULL)
    	{
    		MessageBox(NULL, "Window Creation Failed!", "Error!",
    			MB_ICONEXCLAMATION | MB_OK);
    		return 0;
    	}
    
    	ShowWindow(hwnd, nCmdShow);
    	UpdateWindow(hwnd);
    
    	while(GetMessage(&Msg, NULL, 0, 0) > 0)
    	{
    		TranslateMessage(&Msg);
    		DispatchMessage(&Msg);
    	}
    	return Msg.wParam;
    }
    and up until this point i have been very happy with myself. my problem now is getting collision detection working for the paddle on the bottom. i just dont know how to get that done. any tips?

    ive fiddled around with different x and y positions like if(x of ball = x of paddle and y of ball = y of paddle)(ball move delta) but that doesnt work and if i set x of ball to x of paddle, the ball stays on a straight line horizontally and vice versa if i set y of ball to y of paddle.

    the message is a place holder for a possible score keeping system later on.
    Last edited by Newkid34; November 26th, 2010 at 09:39 PM.

  9. #9
    Join Date
    Nov 2009
    Posts
    32

    Re: Problem painting the BITMAP

    Code:
    #include <windows.h>
    #include <string>
    using namespace std;
    
    const char g_szClassName[] = "myWindowClass";
    const int ID_TIMER = 1;
    const int BALL_MOVE_DELTA = 4; //ball speed
    
    typedef struct _BALLINFO 
    {
    	int width;
    	int height;
    	int x;
    	int y;
    
    	int dx;
    	int dy;
    }BALLINFO;
    
    BALLINFO g_ballInfo;
    
    typedef struct _PADDLEINFO 
    {
    	int width;
    	int height;
    	int x;
    	int y;
    
    	int dx;
    	int dy;
    }PADDLEINFO;
    
    PADDLEINFO g_leftPaddleInfo;
    
    string message = "A sample message.";
    
    void DrawBall(HDC hdc, RECT* prc)
    {
    
    	HBRUSH blueBrush=CreateSolidBrush(RGB(0,0,255));
    	HGDIOBJ old=SelectObject(hdc,blueBrush);
    
    	Ellipse(hdc, g_ballInfo.x, g_ballInfo.y, g_ballInfo.x+g_ballInfo.width, g_ballInfo.y+g_ballInfo.height);
    	
    	DeleteObject(blueBrush);
    	SelectObject(hdc,old);
    }
    
    void DrawLeftPaddle(HDC hdc, RECT* prc)
    {
    	HBRUSH redBrush=CreateSolidBrush(RGB(255,0,0));
    	HGDIOBJ old=SelectObject(hdc,redBrush);
    
    	Rectangle(hdc, g_leftPaddleInfo.x, g_leftPaddleInfo.y, g_leftPaddleInfo.x + g_leftPaddleInfo.width, g_leftPaddleInfo.y+g_leftPaddleInfo.height);
    
    	DeleteObject(redBrush);
    	SelectObject(hdc,old);
    }
    void DrawBlock(HDC hdc, RECT* prc)
    {
    	HBRUSH redBrush=CreateSolidBrush(RGB(255,0,0));
    	HGDIOBJ old=SelectObject(hdc,redBrush);
    
    	Rectangle(hdc, 50,50,110,60);
    	Rectangle(hdc, 110,50,170,60);
    	Rectangle(hdc, 170,50,230,60);
    	Rectangle(hdc, 230,50,290,60);
    	Rectangle(hdc, 50,60,110,70);
    	Rectangle(hdc, 110,60,170,70);
    	Rectangle(hdc, 170,60,230,70);
    	Rectangle(hdc, 230,60,290,70);
    	Rectangle(hdc, 50,70,110,80);
    	Rectangle(hdc, 110,70,170,80);
    	Rectangle(hdc, 170,70,230,80);
    	Rectangle(hdc, 230,70,290,80);
    
    	DeleteObject(redBrush);
    	SelectObject(hdc,old);
    }
    
    /* void DrawRectLoop(HDC hdc, RECT*prc)
    {
    	HBRUSH redBrush=CreateSolidBrush(RGB(255,0,0));
    	HGDIOBJ old=SelectObject(hdc,redBrush);
    
    	Rectangle(hdc, 50,50,110,60);
    
    	DeleteObject(redBrush);
    	SelectObject(hdc,old);
    }
    
    
    
    */
    void UpdateBall(RECT* prc)
    {
    
    	// collision detection
    
    	g_ballInfo.x += g_ballInfo.dx;
    	g_ballInfo.y += g_ballInfo.dy;
    
    	if(g_ballInfo.x < 0)
    	{
    		g_ballInfo.x = 0;
    		g_ballInfo.dx = BALL_MOVE_DELTA;
    	}
    	else if(g_ballInfo.x + g_ballInfo.width > prc->right)
    	{
    		g_ballInfo.x = prc->right - g_ballInfo.width;
    		g_ballInfo.dx = -BALL_MOVE_DELTA;
    	}
    	if(g_ballInfo.y < 0)
    	{
    		g_ballInfo.y = 0;
    		g_ballInfo.dy = BALL_MOVE_DELTA;
    	}
    	else if(g_ballInfo.y + g_ballInfo.height > prc->bottom)
    	{
    		g_ballInfo.y = prc->bottom - g_ballInfo.height;
    		g_ballInfo.dy = -BALL_MOVE_DELTA;
    	}
    	//if((g_ballInfo.x = g_leftPaddleInfo.x) & (g_ballInfo.y = g_leftPaddleInfo.y))
    	{
    		//g_ballInfo.y = 0;
    		//g_ballInfo.dx = -BALL_MOVE_DELTA;
    		//g_ballInfo.dy = -BALL_MOVE_DELTA;
    	}
    }
    
    LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    	switch(msg)
    	{
    		case WM_CREATE:
    		{
    			UINT ret;				//unsigned int to hold result of timer creation
    	
    			g_leftPaddleInfo.width = 60;
    			g_leftPaddleInfo.height = 10;
    		
    			g_leftPaddleInfo.x = 20;  // this is where the paddle starts
    			g_leftPaddleInfo.y = 340; // also here
    
    			g_ballInfo.width = 10;
    			g_ballInfo.height = 10;
    
    			g_ballInfo.dx = BALL_MOVE_DELTA;
    			g_ballInfo.dy = BALL_MOVE_DELTA;
    
    			ret = SetTimer(hwnd, ID_TIMER, 20, NULL);	// 20 milliseconds
    			if(ret == 0)								
    				MessageBox(hwnd, "Could not SetTimer()!", "Error", MB_OK | MB_ICONEXCLAMATION);
    		
    		}
    		break;
    		case WM_CLOSE:
    			DestroyWindow(hwnd);
    		break;
    		case WM_PAINT:
    		{
    			RECT rcClient;				//struct to hold rectangle coordinates	
    			PAINTSTRUCT ps;				//struct representing client area of window 
    			HDC hdc = BeginPaint(hwnd, &ps);
    
    			GetClientRect(hwnd, &rcClient);  //get coordinates of client area of window
    			 
    			DrawBall(hdc, &rcClient);
    		
    			EndPaint(hwnd, &ps);
    		}
    		break;
    		case WM_TIMER:
    		{
    			/*if (GetAsyncKeyState(VK_UP) < 0)
    			{
    				g_leftPaddleInfo.y-=6;
    			}
    			if(GetAsyncKeyState(VK_DOWN) < 0)
    			{
    				g_leftPaddleInfo.y+=6;
    			}
    			*/
    			if (GetAsyncKeyState(VK_RIGHT) < 0)
    			{
    				g_leftPaddleInfo.x+=6;
    			}
    			if(GetAsyncKeyState(VK_LEFT) < 0)
    			{
    				g_leftPaddleInfo.x-=6;
    			}
    
    			if(g_leftPaddleInfo.x < 0)
    	{
    		g_leftPaddleInfo.x = 0;
    		//g_ballInfo.dx = BALL_MOVE_DELTA;
    	}
    	else if(g_leftPaddleInfo.x + g_leftPaddleInfo.width > 385)
    	{
    		g_leftPaddleInfo.x =320;  // prc->right - g_leftPaddleInfo.width;
    		//g_ballInfo.dx = -BALL_MOVE_DELTA;
    	}
    
    
    
    			RECT rcClient;					//struct to hold rectangle coordinates
    			HDC hdc = GetDC(hwnd);			//grab a handle to the window (Device Context)
    
    			GetClientRect(hwnd, &rcClient);  //get coordinates of client area of window 
    											 // and store them in rcClient	
    			UpdateBall(&rcClient);			 //calculate next ball position
    
    			FillRect(hdc, &rcClient, (HBRUSH)GetStockObject(WHITE_BRUSH));
    			TextOut(hdc, 20, 20, message.c_str(), message.length());
    
    			DrawBall(hdc, &rcClient);		 //clear screan and draw ball in new position
    			DrawLeftPaddle(hdc, &rcClient);	
    			DrawBlock(hdc,&rcClient);
    			
    			ReleaseDC(hwnd, hdc);			//release the handle to the window (Device Context)
    		}
    		break;
    		
    
    
    		case WM_KEYDOWN:
    			/*	if(wParam == VK_DOWN)  // try this way instead - See the problem?
    					y+=6;
    				if(wParam == VK_UP)
    					y-=6;
    			*/
    		break;
    		case WM_KEYUP:
    				
    		break;
    		case WM_DESTROY:
    			KillTimer(hwnd, ID_TIMER);
    			PostQuitMessage(0);
    		break;
    		default:
    			return DefWindowProc(hwnd, msg, wParam, lParam);
    	}
    	return 0;
    }
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    	LPSTR lpCmdLine, int nCmdShow)
    {
    	WNDCLASSEX wc;
    	HWND hwnd;
    	MSG Msg;
    
    	wc.cbSize		 = sizeof(WNDCLASSEX);
    	wc.style		 = 0;
    	wc.lpfnWndProc	 = WndProc;
    	wc.cbClsExtra	 = 0;
    	wc.cbWndExtra	 = 0;
    	wc.hInstance	 = hInstance;
    	wc.hIcon		 = LoadIcon(NULL, IDI_APPLICATION);
    	wc.hCursor		 = LoadCursor(NULL, IDC_ARROW);
    	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    	wc.lpszMenuName  = NULL;
    	wc.lpszClassName = g_szClassName;
    	wc.hIconSm		 = LoadIcon(NULL, IDI_APPLICATION);
    
    	if(!RegisterClassEx(&wc))
    	{
    		MessageBox(NULL, "Window Registration Failed!", "Error!",
    			MB_ICONEXCLAMATION | MB_OK);
    		return 0;
    	}
    
    	hwnd = CreateWindowEx(
    		WS_EX_CLIENTEDGE,
    		g_szClassName,
    		"An Animation Program",
    		WS_OVERLAPPEDWINDOW,
    		CW_USEDEFAULT, CW_USEDEFAULT, 400, 400,
    		NULL, NULL, hInstance, NULL);
    
    	if(hwnd == NULL)
    	{
    		MessageBox(NULL, "Window Creation Failed!", "Error!",
    			MB_ICONEXCLAMATION | MB_OK);
    		return 0;
    	}
    
    	ShowWindow(hwnd, nCmdShow);
    	UpdateWindow(hwnd);
    
    	while(GetMessage(&Msg, NULL, 0, 0) > 0)
    	{
    		TranslateMessage(&Msg);
    		DispatchMessage(&Msg);
    	}
    	return Msg.wParam;
    }
    This is the newest code i have. collision detection is still a problem but i have fixed the paddle and drawn the blocks to the window. i cant get the collision detection to work for the paddle or the blocks =/.

  10. #10
    Join Date
    Apr 2009
    Posts
    598

    Re: Problem painting the BITMAP

    Code:
    //if((g_ballInfo.x = g_leftPaddleInfo.x) & (g_ballInfo.y = g_leftPaddleInfo.y))
    Beware of the difference between = and ==, and between & and && (and also | and ||). Here, I think you meant == and &&.

  11. #11
    Join Date
    Nov 2009
    Posts
    32

    Re: Problem painting the BITMAP

    ohhh your right about that, Thanks. will try and repost

  12. #12
    Join Date
    Nov 2009
    Posts
    32

    Re: Problem painting the BITMAP

    Code:
    #include <windows.h>
    #include <string>
    using namespace std;
    
    const char g_szClassName[] = "myWindowClass";
    const int ID_TIMER = 1;
    const int BALL_MOVE_DELTA = 4; //ball speed
    
    typedef struct _BALLINFO 
    {
    	int width;
    	int height;
    	int x;
    	int y;
    
    	int dx;
    	int dy;
    }BALLINFO;
    
    BALLINFO g_ballInfo;
    
    typedef struct _PADDLEINFO 
    {
    	int width;
    	int height;
    	int x;
    	int y;
    
    	int dx;
    	int dy;
    }PADDLEINFO;
    
    PADDLEINFO g_leftPaddleInfo;
    
    string message = "A sample message.";
    
    void DrawBall(HDC hdc, RECT* prc)
    {
    
    	HBRUSH blueBrush=CreateSolidBrush(RGB(0,0,255));
    	HGDIOBJ old=SelectObject(hdc,blueBrush);
    
    	Ellipse(hdc, g_ballInfo.x, g_ballInfo.y, g_ballInfo.x+g_ballInfo.width, g_ballInfo.y+g_ballInfo.height);
    	
    	DeleteObject(blueBrush);
    	SelectObject(hdc,old);
    }
    
    void DrawLeftPaddle(HDC hdc, RECT* prc)
    {
    	HBRUSH redBrush=CreateSolidBrush(RGB(255,0,0));
    	HGDIOBJ old=SelectObject(hdc,redBrush);
    
    	Rectangle(hdc, g_leftPaddleInfo.x, g_leftPaddleInfo.y, g_leftPaddleInfo.x + g_leftPaddleInfo.width, g_leftPaddleInfo.y+g_leftPaddleInfo.height);
    
    	DeleteObject(redBrush);
    	SelectObject(hdc,old);
    }
    void DrawBlock(HDC hdc, RECT* prc)
    {
    	HBRUSH redBrush=CreateSolidBrush(RGB(255,0,0));
    	HGDIOBJ old=SelectObject(hdc,redBrush);
    
    	Rectangle(hdc, 50,50,110,60);
    	Rectangle(hdc, 110,50,170,60);
    	Rectangle(hdc, 170,50,230,60);
    	Rectangle(hdc, 230,50,290,60);
    	Rectangle(hdc, 50,60,110,70);
    	Rectangle(hdc, 110,60,170,70);
    	Rectangle(hdc, 170,60,230,70);
    	Rectangle(hdc, 230,60,290,70);
    	Rectangle(hdc, 50,70,110,80);
    	Rectangle(hdc, 110,70,170,80);
    	Rectangle(hdc, 170,70,230,80);
    	Rectangle(hdc, 230,70,290,80);
    
    	DeleteObject(redBrush);
    	SelectObject(hdc,old);
    }
    
    /* void DrawRectLoop(HDC hdc, RECT*prc)
    {
    	HBRUSH redBrush=CreateSolidBrush(RGB(255,0,0));
    	HGDIOBJ old=SelectObject(hdc,redBrush);
    
    	Rectangle(hdc, 50,50,110,60);
    
    	DeleteObject(redBrush);
    	SelectObject(hdc,old);
    }
    
    
    
    */
    void UpdateBall(RECT* prc)
    {
    
    	// collision detection
    
    	g_ballInfo.x += g_ballInfo.dx;
    	g_ballInfo.y += g_ballInfo.dy;
    
    	if(g_ballInfo.x < 0)
    	{
    		g_ballInfo.x = 0;
    		g_ballInfo.dx = BALL_MOVE_DELTA;
    	}
    	else if(g_ballInfo.x + g_ballInfo.width > prc->right)
    	{
    		g_ballInfo.x = prc->right - g_ballInfo.width;
    		g_ballInfo.dx = -BALL_MOVE_DELTA;
    	}
    	if(g_ballInfo.y < 0)
    	{
    		g_ballInfo.y = 0;
    		g_ballInfo.dy = BALL_MOVE_DELTA;
    	}
    	else if(g_ballInfo.y + g_ballInfo.height > prc->bottom)
    	{
    		g_ballInfo.y = prc->bottom - g_ballInfo.height;
    		g_ballInfo.dy = -BALL_MOVE_DELTA;
    	}
    	if(g_ballInfo.x > g_leftPaddleInfo.x && g_ballInfo.x < g_leftPaddleInfo.x + g_leftPaddleInfo.width && g_ballInfo.y == g_leftPaddleInfo.y)
    	{
    		//g_ballInfo.x = 0;
    		g_ballInfo.dx = BALL_MOVE_DELTA;
    		g_ballInfo.dy = -BALL_MOVE_DELTA;
    	}
    }
    
    LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    	switch(msg)
    	{
    		case WM_CREATE:
    		{
    			UINT ret;				//unsigned int to hold result of timer creation
    	
    			g_leftPaddleInfo.width = 60;
    			g_leftPaddleInfo.height = 10;
    		
    			g_leftPaddleInfo.x = 20;  // this is where the paddle starts
    			g_leftPaddleInfo.y = 340; // also here
    
    			g_ballInfo.width = 10;
    			g_ballInfo.height = 10;
    
    			g_ballInfo.dx = BALL_MOVE_DELTA;
    			g_ballInfo.dy = BALL_MOVE_DELTA;
    
    			ret = SetTimer(hwnd, ID_TIMER, 20, NULL);	// 20 milliseconds
    			if(ret == 0)								
    				MessageBox(hwnd, "Could not SetTimer()!", "Error", MB_OK | MB_ICONEXCLAMATION);
    		
    		}
    		break;
    		case WM_CLOSE:
    			DestroyWindow(hwnd);
    		break;
    		case WM_PAINT:
    		{
    			RECT rcClient;				//struct to hold rectangle coordinates	
    			PAINTSTRUCT ps;				//struct representing client area of window 
    			HDC hdc = BeginPaint(hwnd, &ps);
    
    			GetClientRect(hwnd, &rcClient);  //get coordinates of client area of window
    			 
    			DrawBall(hdc, &rcClient);
    		
    			EndPaint(hwnd, &ps);
    		}
    		break;
    		case WM_TIMER:
    		{
    			/*if (GetAsyncKeyState(VK_UP) < 0)
    			{
    				g_leftPaddleInfo.y-=6;
    			}
    			if(GetAsyncKeyState(VK_DOWN) < 0)
    			{
    				g_leftPaddleInfo.y+=6;
    			}
    			*/
    			if (GetAsyncKeyState(VK_RIGHT) < 0)
    			{
    				g_leftPaddleInfo.x+=6;
    			}
    			if(GetAsyncKeyState(VK_LEFT) < 0)
    			{
    				g_leftPaddleInfo.x-=6;
    			}
    
    			if(g_leftPaddleInfo.x < 0)
    	{
    		g_leftPaddleInfo.x = 0;
    		//g_ballInfo.dx = BALL_MOVE_DELTA;
    	}
    	else if(g_leftPaddleInfo.x + g_leftPaddleInfo.width > 385)
    	{
    		g_leftPaddleInfo.x =320;  // prc->right - g_leftPaddleInfo.width;
    		//g_ballInfo.dx = -BALL_MOVE_DELTA;
    	}
    
    
    
    			RECT rcClient;					//struct to hold rectangle coordinates
    			HDC hdc = GetDC(hwnd);			//grab a handle to the window (Device Context)
    
    			GetClientRect(hwnd, &rcClient);  //get coordinates of client area of window 
    											 // and store them in rcClient	
    			UpdateBall(&rcClient);			 //calculate next ball position
    
    			FillRect(hdc, &rcClient, (HBRUSH)GetStockObject(WHITE_BRUSH));
    			TextOut(hdc, 20, 20, message.c_str(), message.length());
    
    			DrawBall(hdc, &rcClient);		 //clear screan and draw ball in new position
    			DrawLeftPaddle(hdc, &rcClient);	
    			DrawBlock(hdc,&rcClient);
    			
    			ReleaseDC(hwnd, hdc);			//release the handle to the window (Device Context)
    		}
    		break;
    		
    
    
    		case WM_KEYDOWN:
    			/*	if(wParam == VK_DOWN)  // try this way instead - See the problem?
    					y+=6;
    				if(wParam == VK_UP)
    					y-=6;
    			*/
    		break;
    		case WM_KEYUP:
    				
    		break;
    		case WM_DESTROY:
    			KillTimer(hwnd, ID_TIMER);
    			PostQuitMessage(0);
    		break;
    		default:
    			return DefWindowProc(hwnd, msg, wParam, lParam);
    	}
    	return 0;
    }
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    	LPSTR lpCmdLine, int nCmdShow)
    {
    	WNDCLASSEX wc;
    	HWND hwnd;
    	MSG Msg;
    
    	wc.cbSize		 = sizeof(WNDCLASSEX);
    	wc.style		 = 0;
    	wc.lpfnWndProc	 = WndProc;
    	wc.cbClsExtra	 = 0;
    	wc.cbWndExtra	 = 0;
    	wc.hInstance	 = hInstance;
    	wc.hIcon		 = LoadIcon(NULL, IDI_APPLICATION);
    	wc.hCursor		 = LoadCursor(NULL, IDC_ARROW);
    	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    	wc.lpszMenuName  = NULL;
    	wc.lpszClassName = g_szClassName;
    	wc.hIconSm		 = LoadIcon(NULL, IDI_APPLICATION);
    
    	if(!RegisterClassEx(&wc))
    	{
    		MessageBox(NULL, "Window Registration Failed!", "Error!",
    			MB_ICONEXCLAMATION | MB_OK);
    		return 0;
    	}
    
    	hwnd = CreateWindowEx(
    		WS_EX_CLIENTEDGE,
    		g_szClassName,
    		"An Animation Program",
    		WS_OVERLAPPEDWINDOW,
    		CW_USEDEFAULT, CW_USEDEFAULT, 400, 400,
    		NULL, NULL, hInstance, NULL);
    
    	if(hwnd == NULL)
    	{
    		MessageBox(NULL, "Window Creation Failed!", "Error!",
    			MB_ICONEXCLAMATION | MB_OK);
    		return 0;
    	}
    
    	ShowWindow(hwnd, nCmdShow);
    	UpdateWindow(hwnd);
    
    	while(GetMessage(&Msg, NULL, 0, 0) > 0)
    	{
    		TranslateMessage(&Msg);
    		DispatchMessage(&Msg);
    	}
    	return Msg.wParam;
    }
    HAHA! ive got the collision detection working for the paddle, Thanks Oliv, but now for the bricks. I drew each brick individually so I don't know if there is any easy way to get the collision detection off of a brick. anyone have any tips.

  13. #13
    Join Date
    Nov 2009
    Posts
    32

    Re: Problem painting the BITMAP

    can someone give me some insight as to how to create an array of bricks instead of drawing each individually? I realize individually it makes it significantly harder to do a brick collision detection.

    Thanks.

  14. #14
    Join Date
    Nov 2009
    Posts
    32

    Re: Problem painting the BITMAP

    as the original problem is solved im going to open a new thread for the current problem. it seems no one is answering this and i think the misleading title may be the cause

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Azure Activities Information Page

Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center