Topic : C Windows Programming
Author : Vijay Mukhi
Page : << Previous 7  Next >>
Go to page :


x, UINT y, long z)
{
   if (x = = WM_LBUTTONDOWN)
   {
      h = GetDC(w);
      SetPixel(h,LOWORD(z),HIWORD(z),RGB(255,0,0));
      ReleaseDC(w,h);
   }
   if (x = = WM_DESTROY)
      PostQuitMessage(0);
   return DefWindowProc(w,x,y,z);
}

Whenever we want to see something on the screen we have to call the ' GetDC ' Device Context. Now we are wanting to write with the mouse, hence the first thing is to call this Device Context. Here we are putting ' Pixels ' or dots on the screen when we say ' SetPixel () '. This function has to be passed four parameters. The first should be the variable in which the return value of the ' GetDC() ' Device Context is stored. The second and third parameters are the 'x ' and ' y ' co-ordinates of the position where you click with the mouse on your screen. The last parameter specifies the colour, the pixel should appear on the screen. When you build and execute this program, you’ll see a dot appearing on the screen at the position where you have clicked with the mouse.

You should be happy that you can now, not only write but also draw with your mouse on your window. We can however bet that you are unhappy, as you have to keep clicking with the mouse again and again umpteen number of times, to write a simple word on the screen. Well try making a change to your program i.e. change WM_LBUTTONDOWN to WM_MOUSEMOVE. Now you will see that when you move the mouse - without pressing the mousebutton - on your window screen, pixels start appearing at each of the mouse position. Now position your mouse at one corner of your window and move it across the screen in a fast motion you see that five or six pixels appear on screen but when you move the mouse slowly more number of pixels appear on your window. When you move your mouse fast, the ' zzz ' function is called a fewer number of times whereas, if you move it slowly the function is called more number of times. Hence you see more pixels appearing on the screen.

You may still not be satisfied as you have to move your mouse slowly across the screen when you want to write something on the screen, well then use the keyboard. Why do you think all the companies keep providing you with keyboards if all the writing could be done with a mouse.

Drawing a line...

If you have finished with you artistic skills we can proceed further in a newer direction. Let us now draw a straight line in our window.

#include <windows.h>
#include<stdio.h>
WNDCLASS a;
long _stdcall zzz();
HWND b;
MSG c;
HDC h;
_stdcall WinMain(HINSTANCE i, HINSTANCE j, char *k, int l)
{
   a.hInstance = i;
   a.lpszClassName = "Hi" ;
   a.lpfnWndProc = zzz;
   a.hbrBackground = GetStockObject(WHITE_BRUSH);
   a.hCursor = LoadCursor(0,IDC_CROSS);
   RegisterClass(&a);
b=CreateWindow("Hi","Bye",WS_OVERLAPPEDWINDOW,1,100,200,300,0,0,i,0);
   ShowWindow(b,1);
   while(GetMessage(&c,0,0,0))
   DispatchMessage(&c);
}
long _stdcall zzz(UINT w, UINT x, UINT y, long z)
{
   if (x = = WM_LBUTTONDOWN)
   {
      h = GetDC(w);
      LineTo(h,LOWORD(z),HIWORD(z));
      ReleaseDC(w,h);
   }
   if (x = = WM_DESTROY)
      PostQuitMessage(0);
   return DefWindowProc(w,x,y,z);
}


You can see how easy it is to draw a line in the above program. You just have to call the function ' LineTo() ', pass it three parameters - the first being the value of our ' GetDC ' Device Context. The other two parameters are the ' x ' and ' y ' co-ordinates of your mouse position - and you see the line. Well, the job is done, we have drawn the line in our window. But don't you find it odd, that whenever you click on the window, it draws a line, from the position of the mouse on the screen to the top left hand corner of our window.

Let us understand what happens. When we call the ' GetDC ' function it makes the position ' 0,0 ' of your window as the active pixel. Hence whenever you click on the window the line will be drawn from that active pixel to the position where your mouse is.

Adding one more line of code to your program you get

#include <windows.h>
#include<stdio.h>
WNDCLASS a;
long _stdcall zzz();
HWND b;
MSG c;
HDC h;
_stdcall WinMain(HINSTANCE i, HINSTANCE j, char *k, int l)
{
   a.hInstance = i;
   a.lpszClassName = "Hi" ;
   a.lpfnWndProc = zzz;
   a.hbrBackground = GetStockObject(WHITE_BRUSH);
   a.hCursor = LoadCursor(0,IDC_CROSS);
   RegisterClass(&a);
b=CreateWindow("Hi","Bye",WS_OVERLAPPEDWINDOW,1,100,200,300,0,0,i,0);
   ShowWindow(b,1);
   while(GetMessage(&c,0,0,0))
   DispatchMessage(&c);
}
long _stdcall zzz(UINT w, UINT x, UINT y, long z)
{
   if (x = = WM_LBUTTONDOWN)
   {
      h = GetDC(w);
      LineTo(h,LOWORD(z),HIWORD(z));
      LineTo(h,LOWORD(z),HIWORD(z));
      ReleaseDC(w,h);
   }
   if (x = = WM_DESTROY)
      PostQuitMessage(0);
   return DefWindowProc(w,x,y,z);
}

What did this additional code avail us? If you think nothing, think again. Don't you now see a line drawn from the top left hand corner of your screen to the position where the mouse has been clicked and again another line drawn which goes straight down from that position. This shows that, when the mouse is clicked and the ' LineTo ' function is called, the active pixel which was at ' 0,0 ' in the beginning, is now passed on to that position where the mouse is clicked. Hence when the second ' LineTo ' function is called, it is from this position that the line is drawn on our window.

You can try increasing the LOWORD(z) by some value and seeing the output. You can follow the trail of the active pixel, and see how it keeps changing as the next ' LineTo ' function gets called.

Let's try another program and see how we can draw a line form our mouse position to another active pixel which we defined.

#include <windows.h>
#include<stdio.h>
WNDCLASS a;
long _stdcall zzz();
HWND b;
MSG c;
HDC h;

_stdcall WinMain(HINSTANCE i, HINSTANCE j, char *k, int l)
{
   a.hInstance = i;
   a.lpszClassName = "Hi" ;
   a.lpfnWndProc = zzz;
   a.hbrBackground = GetStockObject(WHITE_BRUSH);
   a.hCursor = LoadCursor(0,IDC_CROSS);
   RegisterClass(&a);
b=CreateWindow("Hi","Bye",WS_OVERLAPPEDWINDOW,1,100,200,300,0,0,i,0);
   ShowWindow(b,1);
   while(GetMessage(&c,0,0,0))
   DispatchMessage(&c);
}
long _stdcall zzz(UINT w, UINT x, UINT y, long z)
{
   if (x = = WM_LBUTTONDOWN)
   {
      h = GetDC(w);
      MoveToEx(h,1,100,0);
      LineTo(h,LOWORD(z),HIWORD(z));
      ReleaseDC(w,h);
   }
   if (x = = WM_DESTROY)
      PostQuitMessage(0);
   return DefWindowProc(w,x,y,z);
}


In this program, you see that when you click on the window, a line is drawn from the position of your window screen, where the 'x ' co-ordinate is '1' and the ' y ' co-ordinate is ' 100 ' to the position where the mouse has been clicked. If you don't believe us, you can count the number of pixels and see for yourself whether we are bluffing. Now whenever we want to move the active pixel from the ' 0,0 ' position to a new position, we have to use the ' MoveToEx() ' function. This function has to be passed four parameters. The first parameter is to be the ' GetDC() ' number, the second and third parameter are the ' x ' and 'y' co-ordinates respectively. The last parameter is ' 0 ' and hence we will not explain it.

Whenever you want to change the active pixel from the ' 0,0 ' position to a new position you can use the ' MoveToEx ' function.

Using this function in our next program, we now try to draw a line between any two position in our window.

#include <windows.h>
#include<stdio.h>
WNDCLASS a;
long _stdcall zzz();
HWND b;
MSG c;
HDC h;
int ii = 0;
int x1,y1;
_stdcall WinMain(HINSTANCE i, HINSTANCE j, char *k, int l)
{
   a.hInstance = i;
   a.lpszClassName = "Hi" ;
   a.lpfnWndProc = zzz;
   a.hbrBackground = GetStockObject(WHITE_BRUSH);
   a.hCursor = LoadCursor(0,IDC_CROSS);
   RegisterClass(&a);
b=CreateWindow("Hi","Bye",WS_OVERLAPPEDWINDOW,1,100,200,300,0,0,i,0);
   ShowWindow(b,1);
   while(GetMessage(&c,0,0,0))
   DispatchMessage(&c);
}
long _stdcall zzz(UINT w, UINT x, UINT y, long z)
{
   if (x = = WM_LBUTTONDOWN)
   {
      if (ii = = 0)
      {
         ii = 1;
         x1 = LOWORD(z);
         y1 = HIWORD(z);
      }
      else
      {
         ii = 0;
         h = GetDC(w);
         MoveToEx(h,x1,y1,0);
         LineTo(h,LOWORD(z),HIWORD(z));
         ReleaseDC(w,h);
      }
   }
   if (x = = WM_DESTROY)
      PostQuitMessage(0);
   return DefWindowProc(w,x,y,z);
}

Let us understand what we have done in this program. We have declared three global variables of the data type ' int ' viz. ii , x1 and y1. Now when you click with the mouse on your window the value of ii, which is ' 0 ', changes to ' 1 ' and the 'x ' and ' y ' co-ordinates of this position get stored in ' x1 ' and ' y1 ' respectively. Now when you again click with the mouse, the value of ii changes back to ' 1 '. The ' MoveTo() ' functions then makes x1 and y1 the active pixel, so now when the ' LineTo ' function gets called the line is drawn from the present mouse position to this active pixel. Now you can keep drawing as many lines as you want as the value of ' ii ' keeps alternating between ' 1 ' and ' 0 '.

Designing with the mouse...

Previously, we had written a program where you were able to write with the mouse on your window. But there you had got bored with it as you had to move the mouse very slowly across the screen. You also had to keep in mind that you had move the mouse fast when you had finished and wanted to move out of the screen. It still showed a trail of pixels across the screen and thus ruined your design. When you wanted to go back to the same position you came back to that position leaving a trail of pixels behind your mouse. Seeing your hurt expression we decided to show you another program where all these difficulties come to an end. So let’s write the same type of program, but in a different manner.

#include <windows.h>
#include<stdio.h>
WNDCLASS a;
long _stdcall zzz();
HWND b;
MSG c;
HDC h;
int ii = 0;
int x1,y1;
_stdcall WinMain(HINSTANCE i, HINSTANCE j, char *k, int l)
{
   a.hInstance = i;
   a.lpszClassName = "Hi" ;
   a.lpfnWndProc =


Page : << Previous 7  Next >>