954,498 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?

Bouncing Ball (Dev C++ GUI code)

0
By vegaseat on Nov 22nd, 2004 1:08 am

What "Hello World" is to the console, the "Bouncing Ball" is to the Graphical User Interface. Nothing fancy, the ball is created via a call to the API function ellipse() and then bounced within the confines of the windows form. For the DEV C++ crowd: Let me know if you find these snippets somewhat helpful in your learning process in the comments section at the end.

// BCX Bounce by Kevin Diggins adopted from Charles Petzold 
// BCX generated C code modified for the free Dev-C++ system
// from   http://www.bloodshed.net/
// or     http://sourceforge.net/projects/dev-cpp/
// (actually Dev-C++ is the IDE for the GNU GCC/G++ compiler)
// a Dev-C++ tested Windows Application by  vegaseat  21nov2004

#include <windows.h>

#define Show(Window) RedrawWindow(Window,0,0,0);ShowWindow(Window,SW_SHOW);

#define AppName "BouncingBall1"
#define Caption "Bouncing Ball ..."

char BCX_STR [1024*1024];

static int     BCX_GetDiaUnit;
static int     BCX_cxBaseUnit;
static int     BCX_cyBaseUnit;
static int     BCX_ScaleX;
static int     BCX_ScaleY;
static HANDLE  Form1;

double  MIN (double,double);
double  MAX (double,double);

int     WINAPI WinMain (HINSTANCE, HINSTANCE, LPSTR, int);
void    FormLoad (HANDLE);
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);


double MAX (double a, double b)
{
  if (a > b)
  {
    return a;
  }
  return b;
}


double MIN (double a, double b)
{
  if (a < b)
  {
    return a;
  }
  return b;
}


// standard main for Windows GUI
int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR CmdLine, int CmdShow)
{
  static  WNDCLASS  Wc;
  memset(&Wc,0,sizeof(Wc));
  static  MSG  Msg;
  memset(&Msg,0,sizeof(Msg));

  Wc.style=CS_HREDRAW | CS_VREDRAW;
  Wc.lpfnWndProc=WndProc;
  Wc.cbClsExtra=0;
  Wc.cbWndExtra=0;
  Wc.hInstance=hInst;
  Wc.hIcon=LoadIcon(NULL,IDI_WINLOGO);
  Wc.hCursor=LoadCursor(NULL,IDC_ARROW);
  Wc.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
  Wc.lpszMenuName=NULL;
  Wc.lpszClassName=AppName;
  RegisterClass(&Wc);
  FormLoad(hInst);
  // 50ms here, lower value gives higher speed
  SetTimer((HWND)Form1,1,50,NULL);
  // ye olde event message loop
  while(GetMessage(&Msg,NULL,0,0))
  {
    if (!IsWindow((HWND)Form1)||!IsDialogMessage((HWND)Form1,&Msg))
    {
      TranslateMessage(&Msg);
      DispatchMessage(&Msg);
    }
  }
  return Msg.wParam;
}


// create the form and show it (somewhat older style)
void FormLoad (HANDLE hInst)
{
  // get the scale factors
  BCX_GetDiaUnit = GetDialogBaseUnits();
  BCX_cxBaseUnit = LOWORD(BCX_GetDiaUnit);
  BCX_cyBaseUnit = HIWORD(BCX_GetDiaUnit);
  BCX_ScaleX = BCX_cxBaseUnit/4;
  BCX_ScaleY = BCX_cyBaseUnit/8;
  // now the form
  Form1=CreateWindow(AppName,Caption,
    DS_MODALFRAME|WS_POPUP|WS_CAPTION|WS_SYSMENU,
    10*BCX_ScaleX,20*BCX_ScaleY,250*BCX_ScaleX,175*BCX_ScaleY,NULL,
    (HMENU)NULL,(HINSTANCE)hInst,NULL);
  Show((HWND)Form1);
}


// event message handler
LRESULT CALLBACK WndProc (HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
  static  HANDLE  hBitmap;
  static  HBRUSH  hBrush;
  static  HDC  hdc;
  static  HDC  hdcMem;
  static int cxClient;
  static int cyClient;
  static int xCenter;
  static int yCenter;
  static int cxTotal;
  static int cyTotal;
  static int cxRadius;
  static int cyRadius;
  static int cxMove;
  static int cyMove;
  static int xPixel;
  static int yPixel;
  static int nScale;
  
  while(1)
  {
    if (Msg == WM_CREATE)
    {
      hdc = GetDC(hWnd);
      xPixel = GetDeviceCaps(hdc,ASPECTX);
      yPixel = GetDeviceCaps(hdc,ASPECTY);
      ReleaseDC(hWnd,hdc);
      return 0;
      break;
    }
    // draw the ball
    if (Msg == WM_SIZE)
    {
      xCenter = (cxClient=LOWORD(lParam))/2;
      yCenter = (cyClient=HIWORD(lParam))/2;
      nScale = (int)MIN(cxClient*xPixel,cyClient*yPixel)/16;
      cxRadius = nScale/xPixel;
      cyRadius = nScale/yPixel;
      cxMove = (int)MAX(1,cxRadius/4);
      cyMove = (int)MAX(1,cyRadius/4);
      cxTotal = 2*(cxRadius+cxMove);
      cyTotal = 2*(cyRadius+cyMove);
      if (hBitmap)
      {
        DeleteObject(hBitmap);
      }
      hdc = GetDC(hWnd);
      hdcMem = CreateCompatibleDC(hdc);
      hBitmap = CreateCompatibleBitmap(hdc,cxTotal,cyTotal);
      ReleaseDC(hWnd,hdc);
      SelectObject(hdcMem,hBitmap);
      Rectangle(hdcMem,-1,-1,cxTotal+1,cyTotal+1);
      hBrush = CreateHatchBrush(HS_DIAGCROSS,0);
      SelectObject(hdcMem,hBrush);
      SetBkColor(hdcMem,RGB(0,127,255));
      Ellipse(hdcMem,cxMove,cyMove,cxTotal-cxMove,cyTotal-cyMove);
      DeleteDC(hdcMem);
      DeleteObject(hBrush);
      return 0;
      break;
    }
    // move the ball
    if (Msg == WM_TIMER)
    {
      if (!hBitmap)
      {
        break;
      }
      hdc = GetDC(hWnd);
      hdcMem = CreateCompatibleDC(hdc);
      SelectObject(hdcMem,hBitmap);
      BitBlt(hdc,xCenter-cxTotal/2,yCenter-cyTotal/2,cxTotal,cyTotal,hdcMem,0,0,SRCCOPY);
      ReleaseDC(hWnd,hdc);
      DeleteDC(hdcMem);
      xCenter += cxMove;
      yCenter += cyMove;
      if (xCenter+cxRadius>=cxClient||xCenter-cxRadius<=0)
      {
          cxMove = -cxMove;
      }
      if (yCenter+cyRadius >= cyClient || yCenter-cyRadius <= 0)
      {
          cyMove = -cyMove;
      }
      return 0;
      break;
    }
    // clean up and exit program
    if (Msg == WM_DESTROY)
    {
      if (hBitmap)
      {
        DeleteObject(hBitmap);
      }
      KillTimer((HWND)Form1,1);
      PostQuitMessage(0);
      return 0;
    }
    break;
  }
  return DefWindowProc(hWnd, Msg, wParam, lParam);
}

Sorry but There are about 23 Warnings and 1 Error

hexonflux
Newbie Poster
12 posts since Dec 2004
Reputation Points: 10
Solved Threads: 1
 

Strange, I just did a cut and paste into Dev-C++ (V4.9.9.1) and it compiled fine! Make sure you are compiling with GCC/G++ and not mingw32 directly! Check Tools>Compiler Options>Programs. That's the setting with the newest install.

vegaseat
DaniWeb's Hypocrite
Moderator
5,987 posts since Oct 2004
Reputation Points: 1,345
Solved Threads: 1,417
 

sorry, but it`s giving several link errors with bloodshed dev c++.one of the errors is
[Linker error] undefined reference to `GetStockObject@4'

varunrathi
Light Poster
41 posts since Aug 2004
Reputation Points: 10
Solved Threads: 1
 

You need to compile this program as a Windows Application! The word GUI implies this.

vegaseat
DaniWeb's Hypocrite
Moderator
5,987 posts since Oct 2004
Reputation Points: 1,345
Solved Threads: 1,417
 

Looks like some hand holding is in order:
In DevCpp go FILE then NEW then Project, select Windows Application, give it a name (eg. Ball) click OK, the make a directory somewhere and save. DevCpp comes up with a template, delete that and cut and paste this code into the editor page. Then compile and run.

vegaseat
DaniWeb's Hypocrite
Moderator
5,987 posts since Oct 2004
Reputation Points: 1,345
Solved Threads: 1,417
 

BCX is working well but seems to be complicating the code somewhat. a lot of the BCX code seems at first glance a bit unnessecary... an example came with DevC++ which is a bit shorter but uses a bitmap...

1o0oBhP
Posting Pro in Training
445 posts since Dec 2004
Reputation Points: 16
Solved Threads: 6
 

Loading a bitmap and its mask from a resource would be much simpler code, but then it is difficult to post such a thing here.

vegaseat
DaniWeb's Hypocrite
Moderator
5,987 posts since Oct 2004
Reputation Points: 1,345
Solved Threads: 1,417
 

do you mean because of OS dependancy? you already said it is windows app so the dev-c++ posting shouldnt be a problem? If you mean because of the resource cant you paste each file in code tags with the filename at the top? :)

1o0oBhP
Posting Pro in Training
445 posts since Dec 2004
Reputation Points: 16
Solved Threads: 6
 

I would have to supply the actual bitmap files!

vegaseat
DaniWeb's Hypocrite
Moderator
5,987 posts since Oct 2004
Reputation Points: 1,345
Solved Threads: 1,417
 

I simplified the code somewhat by removing the run one instance only feature.

vegaseat
DaniWeb's Hypocrite
Moderator
5,987 posts since Oct 2004
Reputation Points: 1,345
Solved Threads: 1,417
 

works fine for me :-)

Young Teck 06
Posting Pro in Training
440 posts since Sep 2004
Reputation Points: 12
Solved Threads: 0
 

is there a way we can change the speed?

xgills
Newbie Poster
3 posts since Apr 2006
Reputation Points: 10
Solved Threads: 0
 

You can change the speed in this commented line:
// 50ms here, lower value gives higher speed
SetTimer((HWND)Form1,1,50,NULL);

vegaseat
DaniWeb's Hypocrite
Moderator
5,987 posts since Oct 2004
Reputation Points: 1,345
Solved Threads: 1,417
 

There is a problem, I just haven't found it yet. :lol: Just kidding. Looks great and works fine. Kudo's.

Lazaro Claiborn
Junior Poster
171 posts since Jan 2007
Reputation Points: 11
Solved Threads: 13
 

Am a new c++ programmer.

I refer to the code " Bouncing Ball" which is a GUI, now there is a rectangle created, i managed to change the color the rectangle in the main window and what my may problem is how to make the rectangle fixed and not only increase to be a full rectangle after the ball has hit both ends, how do i achieve that?

Secondly, i would love to then after making a 'fixed' rectangle, i would like to make the ball change color as it hits one side of the rectangle and change back to the original color as its starts coming back and approaches the other side and again change color as it hits the other side and change back again as it approaches the other side and keep repeating this cycle...

I need the rectangle to be fully drawn or fixed EVEN before the ball starts moving and then the change of colors issue.

PLEASE ASSITS

lucamarcus
Newbie Poster
2 posts since Oct 2007
Reputation Points: 10
Solved Threads: 0
 

whoa very cool program nice job! I am a beginner and really enjoy these simple program samples.

stickyroehl
Newbie Poster
1 post since Jan 2010
Reputation Points: 10
Solved Threads: 0
 

This is really cool but I am fairly new at this and I was wondering like how does it work and where did you learn these codes. THANKS!!!!

Kontext
Newbie Poster
3 posts since Mar 2011
Reputation Points: 10
Solved Threads: 0
 

To start down this road, check out http://www.winprog.org/tutorial/ (it's not going to answer your questions right away, but once you get going you'll understand what's going on).

P.S. This thread is ancient. Sometimes better to let them rest and start a new one.

jonsca
Quantitative Phrenologist
Team Colleague
5,621 posts since Sep 2009
Reputation Points: 1,165
Solved Threads: 581
 

this helped me understand building images within code, but is possible to add sprites and gui to the game by creating them in paint and linking them in the code? if anyone has any experiance in this add my msn or email me at SNIPPED i would really apreciate it, thanks sorry for bumping an old post but this post actually introduced me to this site XD

mosher66
Newbie Poster
1 post since Apr 2012
Reputation Points: 0
Solved Threads: 0
 

Post: Markdown Syntax: Formatting Help
You