Add a little Graphics to your Console

vegaseat 0 Tallied Votes 9K Views Share

Here is an example on how to put at least lines and circles onto your windows console display. Yes, you have to jump through a hoop to do it. Dev-C++ can do this thanks to some BCX generated code. You have to set up your project as a Console Application and link with libgdi32.a in the case of Dev-C++, or GDI32.lib with other compilers.

// draw two lines and a circle on your console screen
// original BCX basic code by Sir Joe Caverly
// translated to C code and modified to work with Dev-C++
// link with GDI32.lib or with Dev-C++ link libgdi32.a via
// Project>>Project Options>>Parameters>>Add Lib>>libgdi32.a
// this is a Windows Console Application


#include <windows.h>    // Win32API Header File
#include <cstring>
#include <cstdio>

using namespace std;

#define Red  RGB (255,0,0)
#define Lime RGB (206,255,0)
#define Blue RGB (0,0,255)

static HWND    hConWnd;

int     BCX_Line (HWND,int,int,int,int,int=0,HDC=0);
int     BCX_Circle (HWND,int,int,int,int=0,int=0,HDC=0);

HWND    GetConsoleWndHandle (void);

int main()
{
  hConWnd = GetConsoleWndHandle();
  if (hConWnd)
  {
    // be creative here, draw your own circles or lines

    //   hwin, centerX, centerY, radius, pencolor 
    BCX_Circle(hConWnd, 150, 130, 105, Blue);
    //   hwin, ulcX, ulcY, lrcX, lrcY, pencolor 
    BCX_Line(hConWnd, 5, 5, 300, 250, Red);
    BCX_Line(hConWnd, 295, 5, 5, 250, Lime);
    
    getchar();  // wait
  }
  return 0; 
}


int BCX_Line (HWND Wnd,int x1,int y1,int x2,int y2,int Pen,HDC DrawHDC)
{
  int a,b=0;
  HPEN hOPen;
  // penstyle, width, color
  HPEN hNPen = CreatePen(PS_SOLID, 2, Pen);
  if (!DrawHDC) DrawHDC = GetDC(Wnd), b = 1;
  hOPen = (HPEN)SelectObject(DrawHDC, hNPen);
  // starting point of line
  MoveToEx(DrawHDC, x1, y1, NULL);
  // ending point of line
  a = LineTo(DrawHDC, x2, y2);
  DeleteObject(SelectObject(DrawHDC, hOPen));
  if (b) ReleaseDC(Wnd, DrawHDC);
  return a;
}


// converts circle(centerX,centerY,radius,pen) to WinApi function
// ellipse inside box with upper left and lower right coordinates
int BCX_Circle(HWND Wnd,int X,int Y,int R,int Pen,int Fill,HDC DrawHDC)
{
  int a, b = 0;
  if (!DrawHDC) DrawHDC = GetDC(Wnd), b = 1;
  // penstyle, width, color
  HPEN   hNPen = CreatePen(PS_SOLID, 2, Pen);
  HPEN   hOPen = (HPEN)SelectObject(DrawHDC, hNPen);
  HBRUSH hOldBrush;
  HBRUSH hNewBrush;
  // if true will fill circle with pencolor
  if (Fill)
  {
    hNewBrush = CreateSolidBrush(Pen);
    hOldBrush = (HBRUSH)SelectObject(DrawHDC, hNewBrush);
  }
  else
  {
    hNewBrush = (HBRUSH)GetStockObject(NULL_BRUSH);
    hOldBrush = (HBRUSH)SelectObject(DrawHDC, hNewBrush);
  }
  a = Ellipse(DrawHDC, X-R, Y+R, X+R, Y-R);
  DeleteObject(SelectObject(DrawHDC, hOPen));
  DeleteObject(SelectObject(DrawHDC, hOldBrush));
  if (b) ReleaseDC(Wnd, DrawHDC);
  return a;
}


// the hoop ...
HWND GetConsoleWndHandle(void)
{
  HWND hConWnd;
  OSVERSIONINFO os;
  char szTempTitle[64], szClassName[128], szOriginalTitle[1024];

  os.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
  GetVersionEx( &os );
  // may not work on WIN9x
  if ( os.dwPlatformId == VER_PLATFORM_WIN32s ) return 0;

  GetConsoleTitle( szOriginalTitle, sizeof( szOriginalTitle ) );
  sprintf( szTempTitle,"%u - %u", GetTickCount(), GetCurrentProcessId() );
  SetConsoleTitle( szTempTitle );
  Sleep( 40 );
  // handle for NT
  hConWnd = FindWindow( NULL, szTempTitle );
  SetConsoleTitle( szOriginalTitle );

  // may not work on WIN9x
  if ( os.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
  {
    hConWnd = GetWindow( hConWnd, GW_CHILD );
    if ( hConWnd == NULL )  return 0;
    GetClassName( hConWnd, szClassName, sizeof ( szClassName ) );
    while ( strcmp( szClassName, "ttyGrab" ) != 0 )
    {
      hConWnd = GetNextWindow( hConWnd, GW_HWNDNEXT );
      if ( hConWnd == NULL )  return 0;
      GetClassName( hConWnd, szClassName, sizeof( szClassName ) );
    }
  }
  return hConWnd;
}
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

Replaced iostream and cin.get() with the cstdio header and getchar() to reduce the exe file size from 415k to 7k

wxstorm 0 Newbie Poster

The code works flawlessly. Is there a way to add to these features to plot graphs of functions? Or will that require more sophisticated code and libraries?

An example of what I mean is: using the BCX_Line function to draw a figure window, the X and Y axes, and then another function to plot--let's say sin(x) curve.

Ali.M.Habib 0 Newbie Poster

how can I move the drawen object using the mouse from his place to onther please

gh0sst 0 Newbie Poster

Hi!

How can I clear the screen of graphical images ?

I'm reffering to a function similar to BORLAND C's cleardevice() funcion.

Thanks in advance,

gh0sst

tordenflesk 0 Newbie Poster

The code snippet does not compile with Dev-C++ 4.9.9.2. The error messages look like this:
[Linker error] undefined reference to 'CreatePen@12'
[Linker error] undefined reference to 'SelectObject@8'
...
and so on..

Ancient Dragon 5,243 Achieved Level 70 Team Colleague Featured Poster

This thread was originally posted 5 years ago, before that version of the compiler existed. So use the code at your own risk.

mitrmkar 1,056 Posting Virtuoso

>> The code snippet does not compile with Dev-C++ 4.9.9.2. The error messages look like this:
>> [Linker error] undefined reference to 'CreatePen@12'
>> [Linker error] undefined reference to 'SelectObject@8'

See the code snippet comments, there it says;

  • with Dev-C++ link libgdi32.a via Project>>Project Options>>Parameters>>Add Lib>>libgdi32.a
petersvp 0 Newbie Poster

There is WIN32 API GetConsoleWindow() that directly returns the Console's HWND already.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.