Finally I’d able to write my own implementation of the
Bersenham line drawing algorithm under win32 GDI.
I have used a mouse_click_state_machine state machine
class to track mouse clicks.
It will fill an entry when you first clicks and it will
fill the secondry ( x2,y2) when you hit another mouse
click.
Finally it uses the my implementation of Bersenham algo-
rithm to plot the line.
midpoint_line.cc
#include <windows.h>
#include "line_draw_algo.h"
#include "mouse_click_state_machine.h"
LRESULT CALLBACK WinProc(HWND,UINT,WPARAM,LPARAM);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpStr,int iCmdShow)
{
MSG msg;
WNDCLASS wndclass ;
HWND hwnd ;
static TCHAR szAppName []= TEXT("Midpoint");
// initialize the wndclass structure.
wndclass.style= CS_HREDRAW |CS_VREDRAW ;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);
wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszClassName = szAppName ;
wndclass.lpszMenuName= NULL;
wndclass.lpfnWndProc = WinProc ;
// Register the class
RegisterClass(&wndclass);
/*{
MessageBox(NULL ,TEXT("Register Class Failed!"),szAppName,0);
ExitProcess(0);
}*/
// then create the window
hwnd = CreateWindow( szAppName ,
szAppName ,
WS_OVERLAPPEDWINDOW ,
CW_USEDEFAULT ,CW_USEDEFAULT ,CW_USEDEFAULT,CW_USEDEFAULT ,
NULL ,
NULL ,
hInstance ,
NULL);
// Then show the window.
ShowWindow(hwnd , SW_SHOW);
// Update Window.
// Then enter to the message loop.
while( GetMessage( &msg, NULL ,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WinProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
PAINTSTRUCT ps ;
static MouseClickStateMachine mcsm;
POINT point ;
switch (message)
{
case WM_LBUTTONDOWN:
point.x= LOWORD(lParam);
point.y= HIWORD(lParam);
mcsm.MouseClick(point);
// initialize mcsm
mcsm.SetHWND(hWnd);
if( mcsm.GetState() == 3)
LineDraw (mcsm);
break;
case WM_RBUTTONDOWN:
break;
case WM_PAINT:
break;
case WM_CREATE:
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd,message,wParam,lParam);
}
return 0;
}
mouse_click_state_machine.h
#ifndef __MOUSE_CLICK_STATE_MACHINE__
#define __MOUSE_CLICK_STATE_MACHINE__
#include <windows.h>
class MouseClickStateMachine
{
int state; // initially this is in the
// start state.
HWND hwnd ;
int x1 ;
int y1;
int x2;
int y2 ;
public:
int GetState()
{
return state;
}
void SetHWND(HWND hWnd)
{
hwnd=hWnd;
}
HWND GetHWND()
{
return hwnd;
}
POINT& GetPointOne(POINT& point)
{
point.x = x1;
point.y = y1;
return point;
}
POINT& GetPointTwo(POINT& point)
{
point.x =x2;
point.y = y2;
return point;
}
void MouseClick(POINT &point)
{
if( state==3)
state=1;
if ( state==0)
{
MessageBox(NULL,\
TEXT("Exception: MouseClick was not initialized properly"),\
TEXT("Midpoint Algo"),MB_OK);
ExitProcess(1);
}
if ( state ==1)
{
// fill the x1 and y1
x1= point.x;
y1= point.y;
state++;
return;
}
if ( state ==2)
{
// fill the x2 and y2
x2 = point.x;
y2 = point.y;
}
state++;
}
MouseClickStateMachine()
{
state=1;
}
~MouseClickStateMachine()
{
}
};
#endif
line_draw_algo.h
#include <windows.h> #include "mouse_click_state_machine.h" void LineDraw(MouseClickStateMachine& mcsm); void LineDraw(int x1, int y1, int x2 , int y2);
line_draw_algo.cc
#include <windows.h>
#include "mouse_click_state_machine.h"
#include "line_draw_algo.h"
static HDC hDC;
int abs( int a , int b);
void swap(int&,int&);
void PutPixel(int,int);
void LineDraw( MouseClickStateMachine& mcsm)
{
POINT point;
mcsm.GetPointOne(point);
int x1= point.x;
int y1= point.y;
mcsm.GetPointTwo(point);
int x2= point.x;
int y2 = point.y;
hDC = GetDC(mcsm.GetHWND());
LineDraw (x1,y1,x2,y2);
ReleaseDC(mcsm.GetHWND(),hDC);
}
void LineDraw(int x1, int y1,int x2,int y2)
{
// so at last we are going to imlement the
// line drawing algorithm here.
// //--BersanHam Line drawing algorithm--// //
int step1 =0;
if (abs(x2-x1)< abs(y1-y2)){
// then swap the x1,y1 with x2,y2.
swap (x2,y2);
swap (y1,x1);
step1 = 0;
} else
{
//if ((x2-x1)>=abs (y2-y1))
// just do nothing..
step1= 1;
}
if (x1>x2)
{
swap(x1,x2);
swap(y1,y2);
}
int dx , dy;
dx=x2 -x1;
int step;
if(y1>y2)
{
step =0;
dy = y1 -y2 ;
}else
{
dy=y2-y1;
step =1;
}
int step_through_x;
int d = 2* dy;
int iN = 2* dy;
int iNE = 2*(dy-dx);
int y= y1;
for ( int x = x1 ; x <= x2 ; x++)
{
if ( step1==1)
PutPixel(x ,y);
if( step1==0)
PutPixel(y,x);
if ( d > 0)
{
d = d +iNE ;
if (step)
{
y++;
}else
{
y--;
}
}else
{
d = d + iN;
}
}
}
void swap(int &a,int &b)
{
int temp ;
temp = a ;
a = b;
b=temp ;
}
int abs( int x, int y)
{
return (x>y)?(x-y):(y-x);
}
void PutPixel(int x, int y)
{
//MessageBox( 0,"line draw algo -put pixel" ,"midpoint",MB_OK);
SetPixel(hDC,x,y,0xFF0000);
}
compile.bat –use only -g if you want to debug this under gdb.
g++ -c line_draw_algo.cc -g g++ -c midpoint_line.cc -g g++ -o midpoint.exe midpoint_line.o line_draw_algo.o -mwindows -g
here is how this looks.

Try it yourself ,
here you can find the binary files and source files for this project.To compile assume you
had already installed mingw g++ and set the paths, then run compile bat by opening a
command prompt.
and to execute hit midpoint.exe
http://www.programmersheaven.com/download/56372/download.aspx
– Happy C0ding–