c++ memory

Upload: suneetsaini

Post on 10-Apr-2018

227 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/8/2019 C++ memory

    1/39

    ' C ' Windows Programming

    ' C ' Windows Programming ? Programming under Windows ? Do you really wish to learn ' C 'Programming under Windows ? Well, you have come to the right place. Now that you have finishedlearning ' C ' programming under DOS, it is high time you learnt something better. We will try to makeit easier for you but we hope that the batch of " anti-frustration " tablets - which you most probably had

    used while learning ' C ' under DOS - is not exhausted . If it is, we advise you to get a fresh batch now,and we assure you that you will need it now, more than ever before. Learning ' C ' programming underDOS, is not easy, as you undoubtedly know. But then, you should know that if you want to learnsomething better, it is bound to be more difficult, and you would have to work harder to understand it.So here we are, trying to help you understand ' C ' programming under Windows.

    These programs are written and explained with some assumptions, one of them being that you havethoroughly understood the concept of ' C ' programming under DOS and are well versed with it'sfunctionality. With this assumption, we shall go ahead and try to understand what ' C ' programmingunder Windows is all about.

    Creating your workspace...

    Before starting with the programming part, you have to know where to type out the program. For thisyou have to follow the steps given below.

    Click on Start and select Programs.

    Next, select Microsoft Visual C++ 5.0

    From here, select Microsoft Visual C++ 5.0 once again

    Now click on File and select New.

    You will now see a tabbed Dialog Box with Project already being selected

    From here, choose Win32 Application, type in the name of your project in the first edit box onthe right hand side of this dialog box, and click on O.K.

    Again, select File and select New.

    You will now see the same tabbed Dialog Box but with File being selected.

    Here, choose the Text File option, and put in the name of the file in the second edit box on theright. You have to end the file name with ' .c '

    You have now entered the world of ' C ' Windows Programming. There is no turning back. You have togo through this ordeal if you wish to learn at least something about ' C ' programming under Windows.

    Getting started...

    Let us start with a small program in ' C ' under Windows

    WinMain(HINSTANCE i,HINSTANCE j,char * k, int l){

    }

    In a ' C ' program under DOS, you know that the first function to be called is ' main()', and may start towonder where is ' main() ' in our program. Before you confuse yourself - trying to make some sense outof our program - please continue reading.

    In ' C ' Windows programming, the first function to be called is ' WinMain '. We already have thisfunction in our program (It should not take too much time to dawn upon you, that it is a function. Thisis because we all know that a function begins and ends with an open brace '{ ' and a close braces ' }' ) .Now some genius amongst you will undoubtedly ask as to why the function should be called '

  • 8/8/2019 C++ memory

    2/39

    WinMain ' and not ' xyz ' or any other name ? This being a very intelligent question, we feel that theanswer should also be equally intelligent. Many different answers come to our mind. But the bestexplanation we choose to give is as follows.

    The person who had designed Windows programming , visited a very well known astrologer, who aftersearching for some signs and reading scriptures, advised him to give the function a name of sevencharacters in length and with two of the characters in capital letters. This person promptly thought of

    naming it ' WindowMain ' - Windows, because it is a Windows program and Main because it is the firstfunction that is called in a ' C ' program . But then, he realised that the number of characters were morethan seven, so he simply shortened it to WinMain.

    Now if you believe this explanation, we can safely assume that you will belive anything we say, and wecan also safely assume that you can be fooled easily ( this being a blessing in disguise, as there aresome instances where we are forced to ask you to trust us, so that we can explain the concept better).Here, all we can say as to why it is called WinMain is, we do not know. The only person who cananswer this supposedly ' intelligent ' question, is the person who designed Windows programming. Butthen, as we do not know who he is - though we tried our level best to find out who the person is - we

    cannot come up with the actual reason. If you know who the person is, you can get back to us with hisname and address, so that we can ask him the reason why he named it

    ' WinMain ' and not xyz or whatever.

    Getting back to the program, we are saying that we have created a function called WinMain and it ispassed four parameters viz. HINSTANCE i,, HINSTANCE j, char * k and int l. Now, why we tooki,j,k,and l as the variables is also an interesting question. This is mainly because we had decided to usethese variables some years ago - due to some good reasons - and since then, we have faced no problemwhile using these variables. The reason, as to why we had decided on these particular variables, and notany other, has been forgotten. But, if by any chance, we happen to remember, and you are stillinterested, we'll let you know. Until then, we shall continue using the above variables, but you are free

    to use any variable you like.Now, whoever calls the function ' WinMain() ', puts the parameters of the function on the stack, andthey take up a certain amount of space on stack We shall explain what these parameters stand for. Thefirst parameter HINSTANCE, is an unsigned int. If you search through the header file you will find this parameter as a #define HINSTANCE = unsigned int. This parameter is written inuppercase, we have not used the lower case, so you should also write it in the uppercase only. This isbecause of the fact that anything written in upper case in ' C ' is assumed to be a ' Macro ' and byconvention all Macros are written in the uppercase.

    Before venturing into any field, it is always better to invoke the blessings of God. So after offeringprayers to God, and deciding on the auspicious time to start with your programming, type this programdown. To compile a program under C Windows, click on the menu option Build. In the box whichdrops down, select Build .exe . This will compile as well as link your program. After compiling thisshort program in ' C ' under Windows, what do you see? You see some errors on your screen. This isnot an auspicious start.

    But please do not panic and start praying all over again. The Gods are not displeased with you. Thereis a saying in English " To err is Human ". These errors are human errors. We have erred in the sensethat we have not included the required header file - where the macros are defined - into our program.

    Inclusion of header files...

  • 8/8/2019 C++ memory

    3/39

    So now we include that header file in our program

    #includeWinMain(HINSTANCE i,HINSTANCE j,char * k, int l){ }

    Now on compiling the program, you still get an error. But to your relief, you see that there is only one

    error. This goes to prove that the Gods have at least partially heard your prayers. Before you startwondering what went wrong , you have to understand what ' C ' Windows programming is all about. In' C ' programming, there is something known as a ' calling convertion '. This calling convention issomething like Diplomacy. Diplomacy means, that whenever you come into the presence of a Queen,you should go down on your knees.

    There is also a protocol in Diplomacy which specifies that when a President of a country comes toIndia, then it is the President of our country and not the Prime Minister who receives him. ThePresident of India does not have any power, but as he is the first citizen of our country, it is proper thatit is he who should meet the President of that country. Similarly, there is a rule in ' C ' which says thatwhen you push parameters on the stack, you push it in the reverse order. These rules which define howthe parameters are to be pushed on stack, are known as ' callingconventions '. So now, we also have to

    specify which calling convention, our function should use. In our program unfortunately, the WinMainfollows the Standard Calling Convention, which is different from the ' C ' Calling Convention. Sinceour program is a ' C ' program, all functions are assumed to be called in the ' C ' Calling Convention.But if we are to call a function in the Standard Calling Convention we have to put ' _stdcall ' before it.

    So here in our program we call the function in the Standard Calling Convention method.

    #include_stdcall WinMain(HINSTANCE i,HINSTANCE j,char * k, int l){}

    As soon as you put in ' _stdcall ' in front of the function you'll see that the colour of the word ' _stdcall '

    changes, this shows that it is a reserved word in Windows ' C ' program and it has a special meaning toit .' C ' understands what ' _stdcall ' is. Now when you compile the program you will not get any errors.You can now go ahead and build the program. To your relief there is still no errors.

    Now execute this program by choosing Build from the menubar and select Execute .exe . Onexecution, you will see that the program does not do anything. This is because there are no lines ofcode within WinMain() .

    Now to make our program do something useful, we add a MessageBox into our program whichappears as shown below.

    #include

    _stdcall WinMain(HINSTANCE i,HINSTANCE j,char * k, int l){

    MessageBox(0,"Hi","Bye",0);}

    Let us understand what is the code we have put inside our ' WinMain() '. We have put in a MessageBoxwhich is a function that is understood by ' C '. This function has to be passed four parameters as part ofit's syntax. Here we give you a bit of advise that we learnt very early in life. " Never argue with syntax". The first and last parameters, which are both ' 0 ', need not be understood by us at this stage. So,forgetting these parameters - though we have to pass them in our function as part of the precious syntax

  • 8/8/2019 C++ memory

    4/39

    - we can go to the second and third parameters and insert two strings ( you can pass any values youwish, but they should be such that they could be passed as strings). If you want to know why we used"Hi" and "Bye" as the parameters we can also provide you with an explanation. We have passed theseparameters as they were the first thing to come to our mind and they looked very friendly. You can passany string you want, we are not stopping you in any way. Now continuing with our program, why don'tyou build and execute it ?

    Ah! What do you see ? What you now see, is a cute little MessageBox with "Hi" and "Bye" in it .TheMessageBox disappears as soon as you click on the O.K. button in it. So finally, we have managed toget our program to do something for us.

    If you are in a mood of doing some R & D, we suggest that you try changing the last parameter from 0to 1 or 2 or 3 and so on till you get exhausted.We have tried our best to reach the last limit of thisparameter,but we got exasperated after we reached 1000000, and decided not to go any further. Do us afavour by not asking us as to how far you can go with these numbers. Do not, however, change the firstparameter at present. When you change the last parameter to 1, you do not get any errors after thecompilation and linking process. On executing the program, you see that there is a change in thenumber of buttons displayed in the MessageBox. Similarly, as you keep changing this last parameter,you will see that the appearence of the MessageBox keeps changing with only the messages remainingunchanged.

    Now let us change the code in the function as under;

    #include_stdcall WinMain(HINSTANCE i,HINSTANCE j,char * k, int l){

    char aa[100];sprintf (aa,"%d", i);MessageBox(0,aa,aa,0);

    }

    In this program we have defined an array ' aa ' of 100 characters. Let us see how we can store some

    value into it. So in our next line of code, the function ' sprintf ' is used to store the value of ' i ' - whichis the first parameter of our function ' WinMain() ' - in the array ' aa '. Now to give you an explanationof what the functions ' fprintf() ' and ' sprintf() ' do, would be an insult to your intelligence. Hence, theyare not explained here (you already know what they do, as it is assumed that you know ' C ' underDOS). Now when you build this program and execute it, you see a number displayed in theMessageBox. This number, is a number assigned to ' i ' by Microsoft Windows, and of no importanceto us, but to Windows it is an identifier. It tells Windows who we are, and the first parameter we havepassed to ' WinMain ' is this identifier. This identifier had to be given a name. It is called a handle inprogramming parlance, and so we shall also call it a handle . When we say that ' i ' is a handle inWindows, you have to realise that you should nottouch that variable. When we say ' not', it means thatyou should not touch this variable, do not try to reassign a value to it or try to increment its value or do

    any other thing to this variable. It is to your advantage that you leave this handle alone.

    Creating a window...

    Let us now proceed to somthing big - like creating our own window. Whenever we write "Windows"with the "W" in capitals, we are referring to the Microsoft Windows System. But when we write"window", we refer to our window application. In C under DOS we know that you faced manyproblems while creating the window. In Windows programming you will see that the creation is a biteasier. We already have two lines of code as our base. Let us go ahead with it and include some lines,one step at a time till we create our window.

  • 8/8/2019 C++ memory

    5/39

    #includeWNDCLASS a;_stdcall WinMain(HINSTANCE i,HINSTANCE j,char * k, int l){}

    You have the right to wonder what ' WNDCLASS ' means. Please bear with us for the moment andbuild this program. What do you find? You get no errors. This proves that ' WNDCLASS ' is somethingwhich is understood by ' C ' Windows. Lets also understand what it is that ' C ' understood. 'WNDCLASS ' is written in capitals and so we can say that it is a Macro. Where can a Macro be found?It is needless to say that it is found in the header file < windows.h >. Now since it is present in theheader file, you may want to know what it could be? It could be a long, or an unsigned int or anything. WNDCLASS is none of the above, it is a structure tag and has it's own set of pre-defined variables( If you want to know what a structure tag is, we advise you to get your fundamentals of ' C ' underDOS cleared ). Now by passing the above line we have created a structure ' a ' which looks like 'WNDCLASS '. We have chosen ' a ' as the name of our structure, because ' a ' is the first alphabet inEnglish and we felt that it should be accorded some respect.

    Now when you run this program you do not see any output. You may wonder, why even after creatinga structure, ' C ' under Windows is stupid and does not give you an output? But then you have merelycreated a structure, you have not initialised any of its member variables and so you can't expect ' C ' tocreate a window merely because you created a structure.

    Initialisation process...

    Lets move ahead and put a line of code in our function and try to initialise some of the members ofour structure.

    #include

    WNDCLASS a;_stdcall WinMain(HINSTANCE i,HINSTANCE j,char * k, int l){

    a.hInstance = i ;}

    Now fold your hands, and pray that you don't get any errors. Finish your prayers and compile theprogram. Great! your prayers have been answered. You get no errors. Is this a miracle? Well let us tryto explain this great phenomenon. You get no errors because if you look at the structure ' WNDCLASS', in the header file, you will see that ' hInstance ' is a member of this structure. Now since our structure

    ' a ' looks just like WNDCLASS, a also inherits these variables and can now call them as if theywere it's own. Now what is the data type of this member of ' a '. It is obvious that it has to be an ' int ',otherwise we would have had a type mismatch error.

    We add one more line of code to our program.

    #includeWNDCLASS a;_stdcall WinMain(HINSTANCE i,HINSTANCE j,char * k, int l){

    a.hInstance = i ;

  • 8/8/2019 C++ memory

    6/39

    a. lpszClassName = "Hi" ;}

    When you build the program, you still do not get any errors. Do not get exited. There are no errorsbecause 'a.lpszClassName' is also a member of ' WNDCLASS '. So now you know a second membersof our structure ' a '. This member of our structure is a string and we have initialised it to "Hi". Now

    why did we pass this string as " Hi "? Well it's like this, whenever you meet a good friend on the road,how do you greet him? Obviously you say "Hi". Similarly, we thought that when we walk down thestreets of Windows programming, and happen to see our window, it should greet us in a polite manner .You may not want your window to greet you politely, but we always like our windows to be polite.Even if this is the only virtue of our window that we may be able to boast about. Hence we have namedthis member as " Hi ".

    Putting an additional line of code, we get the following program.

    #includeWNDCLASS a;_stdcall WinMain(HINSTANCE i,HINSTANCE j,char * k, int l)

    {

    a.hInstance = i ;a. lpszClassName = "Hi" ;a.lpfnWndProc = zzz ;

    }

    Now you are in for a disappointment .On building the program you'll encounter an error. It is acompilation error which says " 'zzz' : undeclared identifier ". This is because ' zzz ' has not been definedby us. The error is not due to ' a.lpfnWndProc ' - otherwise it would have told you "' a.lpfnWndProc ' :undeclared identifier ". In our program we have initialised the third member of our structure ' a ' viz. '

    a.lpfnWndProc '. It has to point to the starting position of the function we shall define in the nextprogram.

    Now let us define the function zzz in our program

    #includeWNDCLASS a;long _stdcall zzz();_stdcall WinMain(HINSTANCE i,HINSTANCE j,char * k, int l){

    a.hInstance = i ;a. lpszClassName = "Hi" ;

    a.lpfnWndProc = zzz ;}long _stdcall zzz(UINT w,UINT x, UINT y, long z){}

    We now have a function prototype ' zzz ' in our program. This function follows the ' Standard CallingConvention ' and returns a ' long '. Now, whenever ' C ' encounters ' zzz ' it knows that it is the name ofa function . But what does the name of a function tell us? It only tells us where the function starts in

  • 8/8/2019 C++ memory

    7/39

    memory . If you had not defined the function, where would ' C ' search for it ? So we have to write thecode of the function in our program. Hence we have added another function ' zzz ' to our program. Thisfunction is passed four parameters. The first three parameters are Macros which are of the type 'unsigned ints ', while the fourth parameter is a ' long '.

    Now when you build this program you should not get any error. Even after writing so many lines ofcode in your program, on execution you see that it does nothing. This, to you, may seem very strange.

    But in actuality, what have we done? We have merely initialised some variables and declared afunction. We have not asked our program to do anything. So why should it do anything for us?

    We shall add some lines of code - which we had earlier learnt in ' C ' under DOS - to our program.

    #include #includeWNDCLASS a;long _stdcall zzz();FILE *fp;_stdcall WinMain(HINSTANCE i, HINSTANCE j, char *k, int l){

    a.hInstance = i;a.lpszClassName = "Hi" ;a.lpfnWndProc = zzz;fp = fopen("c:\\z.txt","w");fprintf(fp,"start\n");

    }long _stdcall zzz(UINT w, UINT x, UINT y, long z){

    fprintf(fp,"%u..%u..%u..%ld\n",w,x,y,z);if (x = = WM_DESTROY)

    PostQuitMessage(0);return DefWindowProc(w,x,y,z);

    }

    In this program we have used ' FILE '. This you have already learnt in ' C ' under DOS. Unfortunately,when we use ' FILE ', we also have to include it's header file . It is like the case when youbring home a pet dog. Well, bringing the pet is O.K. but then you also bring home additional problemslike feeding the pet, etc. You can't have a pet without also having the problems that it brings. Similarly,when you use ' FILE ', you have to include it's header file in our program, without which, it will give usan error. We have also added ' fprintf() ' statements in both our functions viz. ' WinMain() ' and ' zzz() '.We have put an ' fprintf() ' statement in ' zzz() ' to store the values of the four parameters we havepassed to the function in the z.txt file.

    What the last three lines of code of our function ' zzz() ' does, is not to be understood by you at this

    stage. It will be explained later. In the mean time, please take our word for it and write it as a part ofsyntax.

    When you build the program you do not get any errors. Before execution however you have to takecare that there is no file by the name ' z.txt ' in your root directory, because, on execution of thisprogram your existing file will be completely overwritten. Now on execution of the program you stilldo not see any output on screen. This is because the output is stored in ' z.txt ' in the root directory. Youcan see for yourself, the output present in ' z.txt '.

    The output in z.txt is as follows:

  • 8/8/2019 C++ memory

    8/39

    start

    But what is this ? You have only ' start 'as your output. Where are the values of the parameters of ourfunction ' zzz '. Go back to your program and see whether you have forgotten to put the ' fprintf 'statement in your function. You have it there. So what went wrong?

    Let us try to understand why this has happened. In the function zzz() we have used the ' fprintf() 'statement to print its parameters. But we have not called the function. This function gets called onlyafter we use a function called CreateWindow. We shall incorporate this function in our next program.

    Creation process...

    So let us try to create a window in our program.

    #include #includeWNDCLASS a;long _stdcall zzz();FILE *fp;

    _stdcall WinMain(HINSTANCE i, HINSTANCE j, char *k, int l){a.hInstance = i;a.lpszClassName = "Hi" ;a.lpfnWndProc = zzz;fp = fopen("c:\\z.txt","w");fprintf(fp,"start\n");

    CreateWindow("Hi","Bye",WS_OVERLAPPEDWINDOW,1,100,200,300,0,0,i,0) ;}long _stdcall zzz(UINT w, UINT x, UINT y, long z){

    fprintf(fp,"%u..%u..%u..%ld\n",w,x,y,z);

    if (x = = WM_DESTROY)PostQuitMessage(0);return DefWindowProc(w,x,y,z);

    }

    Phew! Just look at the number of parameters we have had to pass to our ' CreateWindow() ' function.Now why do we need to have so many parameters in our function, and what does each parametersignify? As to the question of why we need so many parameters, we do not know. You will have to askthe person who designed Windows programming for the reason. But as to what each of the parameterssignify, we shall try to explain them. The first parameter you pass is a string. This is the same string

    which we had given earlier to ' a.lpszClassName ' in our program. The second parameter is also astring, which we have initialised as "Bye". You can give any value you choose, to this string . Thisstring will appear as the title of your window. We would prefer to get rid of you as soon as possible andhence we have used "Bye" as our string. The third parameter is in capitals, hence it can be safely said tobe a Macro. This Macro WS_OVERLAPPEDWINDOW, is defined as an ' unsigned int ' in the headerfile . It is passed a number, which makes no sense to us. Whenever the user wants tominimize or maximize his window, in fact, do anything with it, he should be allowed to do so. Thisparameter provides Windows System with the required information, to allow the user to do whateverhe/she wants with the window.

  • 8/8/2019 C++ memory

    9/39

    Now, where do we want this window to appear ? i.e. At which position on the screen? This is specifiedby the next four parameters of our function CreateWindow() . The fourth and fifth parametersconstitute the' x ' & ' y ' co-ordinates of where our window is to be displayed on the screen. The sixthand seventh parameters specify its ' width ' and ' height '. The next two parameters i.e. the eighth andninth, are ' 0 ' and so it should not be any concern to you. When we close the window, we are askingMicrosoft Windows to do something for us. So it is now necessary to tell Microsoft Windows who we

    are. The tenth parameter is the handle of our window and this gives Microsoft Windows theinformation it requires. The last parameter is again ' 0 ', so we shall not explain it.

    Now when you compile and run the program you'll see that there is no change in the output eventhough we have added the CreateWindow() function. Let us try to understand what the problem is?

    When we are saying ' CreateWindow ', the poor function, as it is, is already loaded down with so manyparameters. And until now you haven't even said what the background colour should be or how youmouse should look like, the moment it enters the window. Now if you include these description asparameters to the 'CreateWindow()', then just imagine how large your function would become. Nowyou may keep creating windows. Microsoft wanted to make this creation process more effecient. Theysaw to it that this function did not land up with fifty parameters.

    Here, we want to create a window that looks like the class "Hi", which is the first parameter of ourfunction ' CreateWindow()'. But before this can be done, you have to first register the class i.e. "Hi".We register a class by giving it the address of a structure which looks like ' WNDCLASS '. When youregister a class, it means that the ' CreateWindow() ' function can access the members which we hadinitialised earlier.

    So far you have seen us speaking of " Hi " as a class, but may be wondering as to why it is called so?Well we have initialised a member ' lpszClassName ' to "Hi" and hence it is called as a class. A class isactually a hypothetical entity and it can't be physically shown. We have also initialised ' lpfnWndProc 'to zzz , so now whenever Windows wants to talk to us, he does not need to speak to ' WinMain() ' he

    will only talk to our ' zzz() ' function. That is why the function gets called four times. Now wheneverMicrofoft Windows wants to do something for us it would first need to know who we are and this isshown by the variable ' i '.

    Registering a class...

    Let us now learn how to register a class.

    #include #includeWNDCLASS a;long _stdcall zzz();FILE *fp;_stdcall WinMain(HINSTANCE i, HINSTANCE j, char *k, int l){

    a.hInstance = i;a.lpszClassName = "Hi" ;a.lpfnWndProc = zzz;fp = fopen("c:\\z.txt","w");fprintf(fp,"start\n");RegisterClass(&a);

    CreateWindow("Hi","Bye",WS_OVERLAPPEDWINDOW,1,100,200,300,0,0,i,0);}long _stdcall zzz(UINT w, UINT x, UINT y, long z)

  • 8/8/2019 C++ memory

    10/39

    {fprintf(fp,"%u..%u..%u..%ld\n",w,x,y,z);

    if (x = = WM_DESTROY)

    PostQuitMessage(0);return DefWindowProc(w,x,y,z);

    }

    The ' RegisterClass ' should have R and C in capitals. Why this is so, is not known to us. We have sofar never argued with syntax. They want the syntax of a function to be in a particular manner, so be it.We have always obliged them. If you want it to be worded differently, you can create your own versionof ' C ' Windows programming language. Once you have created your programming language, pleaselet us know, so that we can use your syntax. Until then, we shall use the function as it is. The 'RegisterClass() ' should be passed the address of our structure i.e.' a ' so that the compiler now knowswhose variables are to be registered in memory.

    After you compile and execute this program what do you see? Although we have executed theprogram only once, the ' zzz ' function is called four times. Now if you do not have the same output as

    us ( with regards to the numbers in our output) , please do not worry. These numbers tend to bedifferent at different times.

    The output that we get in ' z.txt ' is as follows:

    start

    1056..36..0..6618072

    1056..129..0..6618108

    1056..131..0..6618140

    1056..1..0..6618108

    Now let us put an ' fprintf ' statement after the RegisterClass and see what happens.

    #include #includeWNDCLASS a;long _stdcall zzz();FILE *fp;_stdcall WinMain(HINSTANCE i, HINSTANCE j, char *k, int l){

    a.hInstance = i;a.lpszClassName = "Hi" ;a.lpfnWndProc = zzz;fp = fopen("c:\\z.txt","w");

    fprintf(fp,"start\n");RegisterClass(&a);fprintf(fp,"start1\n");

    CreateWindow("Hi","Bye",WS_OVERLAPPEDWINDOW,1,100,200,300,0,0,i,0);}long _stdcall zzz(UINT w, UINT x, UINT y, long z){

    fprintf(fp,"%u..%u..%u..%ld\n",w,x,y,z);

    if (x = = WM_DESTROY)PostQuitMessage(0);

  • 8/8/2019 C++ memory

    11/39

    return DefWindowProc(w,x,y,z);}

    What happens now? Looking at the output, there are two things you notice at once. The first being, thatboth the ' fprintf() ' functions of WinMain are executed first. This shows that the function ' zzz ' getscalled only after the ' CreateWindow () ' function. The second thing you may have noticed is that the

    values of the parameters have also changed. Now did we not ask you to ignore the value of theseparameters, but you would not listen, you will still notice that the values of the parameters are different,ignore them in future. Our output however now looks as under:

    start

    start1

    1592..36..0..6618072

    1592..129..0..6618108

    1592..131..0..6618140

    1592..1..0..6618108

    You have still not been able to see a window as your output. For this however, you will have to firstcreate a variable and store the return value of the function CreateWindow() in it.

    Your program now looks as below

    #include #includeWNDCLASS a;long _stdcall zzz();HWND b;FILE *fp;_stdcall WinMain(HINSTANCE i, HINSTANCE j, char *k, int l){

    a.hInstance = i;a.lpszClassName = "Hi" ;a.lpfnWndProc = zzz;fp = fopen("c:\\z.txt","w");fprintf(fp,"start\n");RegisterClass(&a);fprintf(fp,"start1\n");

    b=CreateWindow("Hi","Bye",WS_OVERLAPPEDWINDOW,1,100,200,300,0,0,i,0);}long _stdcall zzz(UINT w, UINT x, UINT y, long z){

    fprintf(fp,"%u..%u..%u..%ld\n",w,x,y,z);

    if (x = = WM_DESTROY)

    PostQuitMessage(0);return DefWindowProc(w,x,y,z);

    }

    In this program,the variable b is of the type ' HWND '. HWND is a macro which is an ' unsigned int'. We have initialised b to the return value of the CreateWindow() function. Now ' b ' stands forthe number of the window which we have just created. It is possible to create multiple windows in oneapplication - each having it's own unique identification number, and now whenever Windows sees ' b ',it knows that our window is to be called.

  • 8/8/2019 C++ memory

    12/39

    When you compile the program and run it, you will still not be able to see your window. Don't feelfrustrated, just hold on to your patience a little while more, we are nearly home. We agree that you donot see the window. This is because when you say ' CreateWindow ' a window is created, but inmemory. To see it on the screen you will have to use the function ' ShowWindow() ' .

    A glimpse of the window...

    Let us put in the line of code in our program to display the window.#include #includeWNDCLASS a;long _stdcall zzz();HWND b;FILE *fp;_stdcall WinMain(HINSTANCE i, HINSTANCE j, char *k, int l){

    a.hInstance = i;a.lpszClassName = "Hi" ;a.lpfnWndProc = zzz;fp = fopen("c:\\z.txt","w");fprintf(fp,"start\n");RegisterClass(&a);fprintf(fp,"start1\n");

    b=CreateWindow("Hi","Bye",WS_OVERLAPPEDWINDOW,1,100,200,300,0,0,i,0);ShowWindow(b,1);

    }long _stdcall zzz(UINT w, UINT x, UINT y, long z){

    fprintf(fp,"%u..%u..%u..%ld\n",w,x,y,z);

    if (x = = WM_DESTROY)PostQuitMessage(0);

    return DefWindowProc(w,x,y,z);

    }

    Go ahead, you can build and run this program. Bingo! You can now see a window even if it is only fora nano second. Well you should be happy that you have now created your window, even if it is aliveonly for a nano second. But now and when you look at the output at DOS prompt in ' z.txt ' you will seethat the function ' zzz ' has now been called more often. Your output will be something like below.

    start

    start1

    1992..36..0..6618072

    1992..129..0..6618108

    1992..131..0..6618140

    :: :: :: ::

    :: :: :: ::

    :: :: :: ::

    We are forced into not displaying the entire output due to lack of space. Now if you are satisfied withthis achievement, we can assume that you are easily satisfied with very little. Now, now, don't get

  • 8/8/2019 C++ memory

    13/39

    frustrated. Take a dose of the " anti - frustration " tablet we had recommended and get back to work.Now that we have got the hang of creating a window, lets proceed further and try to keep our windowalive until it closes, only when we want it to.

    Capturing the window...

    Let us put some more code in our program.and see what it does.

    #include #includeWNDCLASS a;long _stdcall zzz();HWND b;MSG c;FILE *fp;_stdcall WinMain(HINSTANCE i, HINSTANCE j, char *k, int l){

    a.hInstance = i;a.lpszClassName = "Hi" ;a.lpfnWndProc = zzz;fp = fopen("c:\\a.txt","w");

    fprintf(fp,"start\n");RegisterClass(&a);fprintf(fp,"start1\n");

    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){

    fprintf(fp,"%u..%u..%u..%ld\n",w,x,y,z);

    if (x = = WM_DESTROY)

    PostQuitMessage(0);return DefWindowProc(w,x,y,z);

    }

    The new lines of code which we have passed i.e. GetMessage() and DispatchMessage() shall beexplained later. For the time being, just compile and run the program, keeping your faith in us.Executing the program, what do you see? Your faith in us is justified. We did not lead you astray. Youcan now view your window properly. But what is this? You have a window, but it is without clothes,you can see right through it. Are you not ashamed that your window is standing without any clothes infront of so many people ? Close it quickly. You now have a problem of providing your window withclothes. We shall learn, how to provide it with clothes, a little later. In the mean time, check your ' z.txt'. You'll see that the function ' zzz ' is now called more often that ever before. The ' z.txt ' file now looksas under

    start

    start1

    3816..36..0..6618072

    3816..129..0..6618108

    3816..131..0..6618140

  • 8/8/2019 C++ memory

    14/39

    3816..1..0..6618108

    :: :: :: ::

    :: :: :: ::

    :: :: :: ::

    Clothing the window...

    Let us proceed with the clothing of our window. Lets see what we can achieve by adding some morelines of code in our program.

    #include #includeWNDCLASS a;long _stdcall zzz();HWND b;MSG c;FILE *fp;_stdcall WinMain(HINSTANCE i, HINSTANCE j, char *k, int l){

    a.hInstance = i;a.lpszClassName = "Hi" ;a.lpfnWndProc = zzz;a.hbrBackground = GetStockObject(BLACK_BRUSH);a.hCursor = LoadCursor(0,IDC_CROSS);fp = fopen("c:\\a.txt","w");fprintf(fp,"start\n");RegisterClass(&a);fprintf(fp,"start1\n");

    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){

    fprintf(fp,"%u..%u..%u..%ld\n",w,x,y,z);

    if (x = = WM_DESTROY)PostQuitMessage(0);

    return DefWindowProc(w,x,y,z);}

    After you build and run the program, what do you see? You will see two things. One, that you nowhave a window which is completely clothed - though it appears to be in mourning as it is wearing dark

    black clothes - and the other, that the moment you bring the cursor inside the window, it changes to across ' + '. These changes are not appearing due to some black magic on our part. They are appearingbecause of the additional lines of code.

    Let us understand what these lines of codes mean. When you compiled this program you did not getany errors. This is because ' hbrBackground ' and ' hCursor ' are also members of our structure ' a '. Thefirst member ' hbrBackground ' is used to store the background colour of the window. To get thebackground colour, you have to use a function ' GetStockObject() '. This function is passed aparameter, which is a Macro. This Macro - has already been assigned the number of a colour in theheader file - knows which colour is to be displayed, which in our case is black. Now you can make

  • 8/8/2019 C++ memory

    15/39

    some changes to this parameter using ' WHITE_BRUSH ' or ' GRAY_BRUSH '. You will see a nicewhite coloured window if you use ' WHITE_BRUSH ' and an old grayish looking window if you usethe ' GRAY_BRUSH '. Similarly you are free to find out any other different colour in the header file aspart of your R & D. Likewise in ' hCursor ' you are storing the value of the cursor which you get usingthe function ' LoadCursor() ' . This Macro is also pre-defined with the number in the header file.

    You have now seen the window on your screen, but have you bothered to look at your output in the 'z.txt ' file? If you have taken the pain to do so, you will see that the output there looks more or less asbelow.

    start

    start1

    604..36..0..6618072

    604..129..0..6618108

    604..131..0..6618140

    604..1..0..6618108

    :: :: :: ::

    :: :: :: ::

    :: :: :: ::

    We know that you are too bored to keep going to the DOS prompt and seeing the output in the ' z.txt 'file. So let us now remove the ' FILE ' macro, and all the ' fprintf() ' functions from our program andexecute it, retaining only the following codes.

    #include #includeWNDCLASS a;

    long _stdcall zzz();HWND b;MSG c;_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_DESTROY)PostQuitMessage(0);

    return DefWindowProc(w,x,y,z);}

  • 8/8/2019 C++ memory

    16/39

    Bet you did not notice it while writing the program. The colour of the background has been changed byus in this program to a peace loving white. This has been done by changing the value of 'a.hbrBackground ' from 'BLACK_BRUSH ' to 'WHITE_BRUSH'. Now when you execute thisprogram, youll see that we still get our window - albeit one with a white background. If you get anyerrors, it means that either the Gods are angry with you or that you have not followed our coding

    correctly. Please recheck the code carefully and execute the program. It should not give you any errorsand on execution should display the window to you.

    Changing the size of our window during runtime...

    Let us now change our program a little.

    #include #includeWNDCLASS a;long _stdcall zzz();HWND b;MSG c;

    _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,SW_SHOWMAXIMIZED);while (GetMessage(&c,0,0,0))

    DispatchMessage(&c);}

    long _stdcall zzz(UINT w, UINT x, UINT y, long z){

    if (x = = WM_DESTROY)PostQuitMessage(0);

    return DefWindowProc(w,x,y,z);}

    The only change we made to our program is that we have changed the second parameter of ShowWindow() from ' 1 ' to ' SW_SHOWMAXIMIZED '. What does this do ? If you execute thisprogram you will see that our window now occupies the full screen. When you pass '

    SW_SHOWMAXIMIZED ' as the second parameter to the ShowWindow() function, the fourth,fifth, sixth and seventh parameter of the CreateWindow() will lose their meaning. Even if we changethem all to ' 0 ' the window will still be displayed over the whole screen. Similarly you can try with 'SW_SHOWMINIMIZED ' wherein your window will be in the minimised form when you execute theprogram no matter what you pass as the fourth, fifth, sixth and seventh parameters to ShowWindow.Then change this parameter to ' SW_SHOWNORMAL' . You will see that it works the same way as itdid when you used ' 1 '. You can even try to change the second parameter of ShowWindow() to 2and 3. You will see that when you use ' 2 ', it works in a manner similar to ' SW_SHOWMINIMIZED ',and when you use ' 3 ' it works similar to ' SW_SHOWMAXIMIZED '. You can change to only these

  • 8/8/2019 C++ memory

    17/39

    three numbers to have any meaning to your program, you try to change the parameter to any otherpositive number you will see that it works as if it takes ' 1 ' as the parameter.

    Trapping the mouse click in our window...

    Now let us tinker around with one of the parameter of the function ' zzz ' and see what happens.

    #include

    #includeWNDCLASS a;long _stdcall zzz();HWND b;MSG c;_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){

    MessageBox(0,"Hi","Hi",0);}

    if (x = = WM_DESTROY)PostQuitMessage(0);

    return DefWindowProc(w,x,y,z);}

    Whenever we say ' CreateWindow() ' or ' ShowWindow() ', the function ' zzz() ' gets called. Likewise,whenever Microsoft Windows wants to tell us something important, it calls the ' zzz ' function andconveys any information through it. It is high time that you learnt that ' x ', which is the secondparameter of the function ' zzz ', is used to tell us as to why Windows is calling the ' zzz() ' function.You don't have to wonder what WM_LBUTTONDOWN is. It is nothing but a Macro. So now

    whenever you click with the mouse on the window, Microsoft puts four parameters on the stack. Thesecond parameter is the number WM_LBUTTONDOWN. It is always easier to rememberWM_LBUTTONDOWN than to remember its number. So in our case, what the window has been told,is that the left mouse button has been clicked and held down. The moment you click on the window,the function ' zzz ' is called and it puts the four parameters of this function on the stack. The secondparameter i.e. ' x ' is now passed the number of ' WM_LBUTTONDOWN '. This is easily understoodbecause we have trapped the mousebuttons message, and the moment we click on our window, theMessageBox gets called. So now whenever you click with the left mouse button, you will see aMessageBox displayed on the window with the message "Hi" in it.

  • 8/8/2019 C++ memory

    18/39

    Now for your R & D you can change WM_LBUTTONDOWN to WM_LBUTTONUP or useWM_RBUTTONDOWN or change it to WM_RBUTTONUP. With the first change you will see thatthe MessageBox is seen only after you release the mousebutton. With the second change you would seethat now there is no MessageBox if you click with your left mouse button but you can see theMessageBox if you click with the right button. With the last change you will see the MessageBox beingdisplayed only after you release the right mousebutton.

    Now lets mess around with the parameters some more. We add the following lines of code to ourprogram which now looks as follows.

    #include #includeWNDCLASS a;long _stdcall zzz();HWND b;MSG c;_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,SW_SHOWMAXIMIZED);while (GetMessage(&c,0,0,0))

    DispatchMessage(&c);}long _stdcall zzz(UINT w, UINT x, UINT y, long z){

    if (x = = WM_LBUTTONDOWN)

    { char aa[100];int x1,y1;x1 = LOWORD(z);y1 = HIWORD(z);sprintf(aa,"%d..%d..",x1,y1);MessageBox(0,aa,aa,0);

    }

    if (x = = WM_DESTROY)PostQuitMessage(0);

    return DefWindowProc(w,x,y,z);}

    Here, we have created a character array ' aa ' of size 100. We have also defined two ints x1 and y1.Now let us remember that a long is four bytes in length. Can't we treat a long as if it were made up oftwo ints, of two bytes each. Well that is exactly what we have done (remember that the last parameterof our function ' zzz ' is a long with a variable 'z'). The first two bytes of the variable ' z ' are read intox1, while the second two bytes are read into y1. Let us now understand what is stored in ' z '. Themoment we click with our mousebutton in our window, the function ' zzz ' is called, and as usual, itputs the four parameters on the stack. The last parameter ' z ' stores the value of the ' x ' and ' y ' co-

  • 8/8/2019 C++ memory

    19/39

    ordinates of our window in it. Thus when we store the first two bytes of ' z ' in ' x1 ' we get the ' x ' co-ordinates of our window. The next two bytes store the y co-ordinate of our window. That is the job ofLOWORD(z) and HIWORD(z).

    Now whenever you click with the mousebutton on the window the ' x ' and ' y ' co-ordinates of thatposition is displayed in the MessageBox.

    Printing text on screen...Don't you feel bored looking at MessageBoxes all the time? You do! Well now that we have got thehang of how the ' C ' programming under Windows works, we shall try to do something in our window.In our next program we shall try to learn how to display some text on our window. So lets roll aheadand learn how it is done.

    #include #includeWNDCLASS a;long _stdcall zzz();HWND b;MSG c;

    _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){

    TextOut( LOWORD(z),HIWORD(z), "Hello",4);}

    if (x = = WM_DESTROY)

    PostQuitMessage(0);return DefWindowProc(w,x,y,z);

    }

    Now in this program, we have used another function of ' C ' Windows programming, viz. ' TextOut() '.We ask this function to print ' hello ' at the position the mouse is clicked on the window. For this wehave passed the parameters LOWORD(z) and HIWORD(z) to show the ' x ' and ' y ' co-ordinates of thewindow, as the first two parameters to our TextOut() function.We have also passed to this function,the string which we want to display on the screen, as the third parameter. The last parameter however isexplained in the next program.

    But when you compile this program the compiler is not satisfied with the number of parameters youhave passed. It gives you an error ,which states, " 'TextOutA' : too few actual parameters ". This shows

  • 8/8/2019 C++ memory

    20/39

    that we have passed the function a parameter too less.

    Now let us understand that, whenever we want to display text on the screen of our window, we have tospecify the font size, the colour, etc. Now how do we do this? Well whenever you want to specify thesethings, you have to use a Device Context called ' GetDC '. You have to pass this Device Context aparameter, which should be the number of our window. Where should we search for this windownumber? Don't worry, this window number is stored in the first parameter of our ' zzz ' function. This

    variable has to be passed as the parameter to the ' GetDC() ' function. You can check and see that both 'w ' and ' b ' - the variable which we used to create our window - will have the same value. Simplywriting 'GetDC(w)' will not solve your problem. This function returns an int which is stored in avariable and passed as the first parameter to the function ' TextOut '. For this purpose in our nextprogram we have created a variable ' h ' which looks like a Macro ' HDC '. This Macro has beenpredefined as an unsigned int in our header file .

    We don't know how it is with you, but with us, we have a rule that, whenever we borrow somethingfrom others, we should always return it back. This rule of ours applies in this program also. It is alwaysgood programming sense to return the variable, which we use, back to our function zzz() . We haveused the variables ' w ' and ' h ' in our ' GetDC ' Device Context, so it is only proper that we return thisDevice Context back. To return the variables, on exiting from GetDC() back to the function zzz() ,we have to use the function ' ReleaseDC() '. This function takes the window handle and Device Context- which we return - as its parameters.

    So now we have changed our program which looks as under.

    #include #includeWNDCLASS a;long _stdcall zzz();HWND b;HDC h;MSG c;_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);TextOut(h,LOWORD(z),HIWORD(z), "Hello",4);ReleaseDC(w,h);

    }

    if (x = = WM_DESTROY)PostQuitMessage(0);

  • 8/8/2019 C++ memory

    21/39

    return DefWindowProc(w,x,y,z);}

    Now on building this program, you get no errors. Now, when you click on the window you now see a"Hello" at the position where you have clicked on the window. What ? You are not getting a "Hello"?What do you get? You get " Hell ". Well you may have put " Hell " as your string. No? You have put "

    Hello ". Well it may be because of one of the two reasons. One being that you have really been goingthrough "Hell" in trying to understand ' C ' Windows programming. Or, it may be because you havepassed ' 4 ' as the fourth parameter of our TextOut function which specifies the number of characters ofthe string which has to be displayed on the screen. Try putting ' 5 ' as the parameter and run it. You willnow see " Hello " on your window.

    Changing the text colour...

    Let us make one small change to our program

    #include #includeWNDCLASS a;long _stdcall zzz();HWND b;HDC h;MSG c;_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);SetTextColor(h,RGB(255,0,0));TextOut(h,LOWORD(z),HIWORD(z), "Hello",4);ReleaseDC(w,h);

    }

    if (x = = WM_DESTROY)

    PostQuitMessage(0);return DefWindowProc(w,x,y,z);

    }

    We were not satisfied with getting the text on our screen in black. So with the ' SetTextColor() 'function, we are passing the colour we want the text to be printed in. Please do not try to correct ourincorrect spelling of the word colour in the program (We know the spelling of colour but the ' C '

  • 8/8/2019 C++ memory

    22/39

    program was designed by an American and all Americans spell colour as ' c.o.l.o.r ', so that is how youhave to spell it if you want your program to work). This function asks for two parameters. The firstparameter is a Device Context, so we pass it ' h ' which is assigned the value of our 'GetDC' DeviceContext. The second parameter is a function which specifies the colour we want.

    Now we shall explain what 'RGB()' function means. Windows knows only the three basic colours red,green and blue. So when you use 'RGB()' you have to specify as to how much of each colour you want.

    You can choose from a minimum of ' 0 ' to a maximum of ' 255 '. These requirements of yours arespecified as the three parameters to this ' RGB() ' function. They are then mixed together, to form thecolour which you want, and displays the text in that colour as your output. In our case we have chosenthe maximum value we can assign to ' red ', so do not be surprised and scream for help if you see "Hell"in blood red. You can choose some other value to specify the colour you want and check out the result -This can be a part of your R&D.

    Learning to write with the mouse...

    Have you ever had the urge to write on your window with a mouse. If you have the urge, then the nextprogram will help you to write on screen with your mouse.

    #include #includeWNDCLASS a;long _stdcall zzz();HWND b;HDC h;MSG c;_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);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. Nowwe are wanting to write with the mouse, hence the first thing is to call this Device Context. Here we areputting ' Pixels ' or dots on the screen when we say ' SetPixel () '. This function has to be passed four

  • 8/8/2019 C++ memory

    23/39

    parameters. The first should be the variable in which the return value of the ' GetDC() ' Device Contextis stored. The second and third parameters are the 'x ' and ' y ' co-ordinates of the position where youclick with the mouse on your screen. The last parameter specifies the colour, the pixel should appear onthe screen. When you build and execute this program, youll see a dot appearing on the screen at theposition 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 andagain umpteen number of times, to write a simple word on the screen. Well try making a change toyour program i.e. change WM_LBUTTONDOWN to WM_MOUSEMOVE. Now you will see thatwhen you move the mouse - without pressing the mousebutton - on your window screen, pixels startappearing at each of the mouse position. Now position your mouse at one corner of your window andmove it across the screen in a fast motion you see that five or six pixels appear on screen but when youmove the mouse slowly more number of pixels appear on your window. When you move your mousefast, the ' zzz ' function is called a fewer number of times whereas, if you move it slowly the function iscalled 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 wantto write something on the screen, well then use the keyboard. Why do you think all the companies keepproviding 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 nowdraw a straight line in our window.

    #include #includeWNDCLASS 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);

  • 8/8/2019 C++ memory

    24/39

    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. Theother 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 wheneveryou click on the window, it draws a line, from the position of the mouse on the screen to the top lefthand corner of our window.

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

    Adding one more line of code to your program you get

    #include #includeWNDCLASS 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 linedrawn from the top left hand corner of your screen to the position where the mouse has been clickedand again another line drawn which goes straight down from that position. This shows that, when themouse is clicked and the ' LineTo ' function is called, the active pixel which was at ' 0,0 ' in thebeginning, is now passed on to that position where the mouse is clicked. Hence when the second '

  • 8/8/2019 C++ memory

    25/39

    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 trailof 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 activepixel which we defined.

    #include #includeWNDCLASS 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 yourwindow screen, where the 'x ' co-ordinate is '1' and the ' y ' co-ordinate is ' 100 ' to the position wherethe 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 passedfour parameters. The first parameter is to be the ' GetDC() ' number, the second and third parameter arethe ' 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 usethe ' MoveToEx ' function.

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

  • 8/8/2019 C++ memory

    26/39

    #include #includeWNDCLASS 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 thedata 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 getscalled the line is drawn from the present mouse position to this active pixel. Now you can keep drawingas many lines as you want as the value of ' ii ' keeps alternating between ' 1 ' and ' 0 '.

    Designing with the mouse...

  • 8/8/2019 C++ memory

    27/39

    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. Youalso had to keep in mind that you had move the mouse fast when you had finished and wanted to moveout of the screen. It still showed a trail of pixels across the screen and thus ruined your design. Whenyou wanted to go back to the same position you came back to that position leaving a trail of pixelsbehind your mouse. Seeing your hurt expression we decided to show you another program where all

    these difficulties come to an end. So lets write the same type of program, but in a different manner.#include #includeWNDCLASS 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)

    {ii = 1;h = GetDC(w);MoveToEx(h,LOWORD(z),HIWORD(z),0);

    }

    if (x = = WM_LBUTTONUP){

    ii = 0;ReleaseDC(w,h);

    }

    if (x = = WM_MOUSEMOVE)

    { if( ii = = 1)LineTo(h,LOWORD(z),HIWORD(z));

    }

    if (x = = WM_DESTROY)PostQuitMessage(0);

    return DefWindowProc(w,x,y,z);}

    In this program we are using three of the mouse functions viz. the WM_LBUTTONDOWN,

  • 8/8/2019 C++ memory

    28/39

    WM_LBUTTONUP and the WM_MOUSEMOVE. By now you should be familiar with these threemouse button functions. Now when you click with the left mouse button and keep it pressed the first ' if' statement will get called. In this ' if ' statement we are merely initialising the active mouse pixel to thatposition where we have clicked with the mouse button. When you move the mouse - keeping the leftmouse button held down - you will now see that it keeps drawing a line to the previous pixel i.e. theactive pixel keeps changing. Now with moving the mouse on your window youll see that even if you

    move it fast there will be no blank trails in the mouse move. The code for this happening is passed inthe WM_MOUSEMOVE's ' if ' statement. The mouse will stop drawing on the screen the moment yourelease the mouse button. This is because of the code you have passed in the WM_LBUTTONUP's ' if 'statement that the moment you release the mouse button the value of ' ii ' changes back to ' 0 ' andhence ' WM_MOUSEMOVE ' does not get called.

    Isn't this program superior to the previous program - in the sense that you can now draw faster withyour mouse?

    Callback function...

    Now let us learn something which is different to these mouse moves. Let us learn what a callbackfunction is ? In a program, there is a function that is used ( by the Microsoft Windows in our case ) to

    let us know of any events that are taking place in our window. This function keeps getting calledrepeatedly and hence it is called as the callback function. In our program the function ' zzz ' gets calledevery time the windows wants to tell us whatever is happening in it. Hence, this is our callbackfunction.

    Let us put some different code in our program and see what happens.

    #include #includeWNDCLASS a;long _stdcall zzz();HWND b;MSG c;

    _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,2);while(GetMessage(&c,0,0,0))DispatchMessage(&c);

    }long _stdcall zzz(UINT w, UINT x, UINT y, long z){

    if (x = = WM_QUERYOPEN){

    MessageBox(0,"Hi","Hi",0);return 0;

    }if (x = = WM_DESTROY)

    PostQuitMessage(0);return DefWindowProc(w,x,y,z);

  • 8/8/2019 C++ memory

    29/39

    }

    In our previous programs, after execution, whenever we had minimized and maximized the window itused to get maximized without giving us any problems. We had never understood then - nor cared -which function was getting called, when our window was being maximized.

    On executing our program, the window is displayed in the minimized state. Now click on it to

    maximize it. Youll now see that it does not get maximized, in fact try clicking on it as many number oftimes as you want, it will stubbornly refuse to get maximized. Now Windows whenever it is asked tomaximizes a window it asks a question. He asks whether we want him to maximize the window for us,yes or no? At this point in time, it asks us the question by sending us a WM_QUERYOPEN Message.If you return a ' 0 ' in response to this question, it means that you are telling Windows not to maximizeour window. Previously in all our other programs, we had never tried to trap this message anywhere. Soit turned to DefWindowProc() . Now DefWindowProc() by default always returns 1 and hence thewindow used to get maximized. But in this program we have trapped this message and returned ' 0 ' toit , which means that we are now telling Windows not to maximize our application. Hence now findyourself unable to maximize your application. To now remove this program from memory you have toeither press ' Alt-F4 ', or go to the status bar - to the position where our window has been minimized -

    and click with the right mouse button and close the window. There is also another way to remove thiswindow from memory which will be explained later.

    Creating a MenuBar...

    Enough of these commands, now let us try to create a MenuBar. By now you should be able to writethe shortest program in ' C ' under Windows without any problem. So lets create a new projectworkspace and open a text file. We have created a project ' aa ' in our root directory along with a File ofthe type ' TextFile ' called as ' aa.c ' . We advise you to do the same as it will be easier to understand.Lets write that program we have learnt and insert one more line to the code and see what happens.

    #include #include

    WNDCLASS a;long _stdcall zzz();HWND b;MSG c;_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);a.lpszMenuName = "AAA";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_DESTROY)PostQuitMessage(0);

    return DefWindowProc(w,x,y,z);

  • 8/8/2019 C++ memory

    30/39

    }

    Compile and execute this program to see what happens. On execution there is nothing additional to ourwindow. Now the question is, what new thing have we learnt in this program? Well, at a glance, wehave at least shown you one more member of the structure ' a ' i.e. our structure which looks like 'WNDCLASS '. It is this member of the structure, which stores the menu name.

    Now we have to understand that a menu has nothing to do with your program. All that we can now dois, in a separate file i.e. a rc file, we can writing code which will display a menu for us. This file shouldbe saved as an ' .rc ' file. For accomplishing this task we can go to the DOS prompt and create a newfile in our directory aa having the name ' aa.rc '. In this file we type in the following details

    AAA MENUBEGINMENUITEM "A1",100MENUITEM "A2",101END

    What do these lines of code mean? Here we are passing the codes which specify as to what we want todo with the MenuBar. These codes will be explained, but before that why don't we go back to ourprogram and insert this file into our project? To insert this file into our project follow the followingsteps:

    Select Project from your menu bar

    Choose Add to projects

    Choose files

    Here you will see a dialog box, where you should click on aa.rc and select " insert ".

    Now that your insertion is complete you can build the program once again. On execution of theprogram you can see a MenuBar with " A1 " and " A2 " on your window.

    Let us explain what has happened. Whenever you have to pass some codes of our MenuBar - which arenot part of the actual creation of the window - you have to pass them in a separate file. This file iscalled a resource file and it is to be saved as a ' .rc ' file. By the insertion of this resource file in ourproject, the compiler on compilation reads its contents. Now seeing that the first line of the resourcefile is the name of our MenuBar it promptly displays the MenuBar on our window screen.

    While we are in the topic of resource files let us also understand as to what code we have passed to ourMenuBar. The first line shows the name as "AAA" and that it is our Menu name. Now any code wehave to pass in the resource file has to start with a " begin " statement. The compiler now knows thatwe have started with our coding part and reads it accordingly. In the third line we have a "menuitem"which is "A1", this has been given a number viz. ' 100 ' - in future whenever we call our command

    button and specify ' 100 ' it knows which menu item is to be called - we can understand the use of ' 100' better in another program. In the meantime lets continue with our understanding of the other lines ofthe file. The fourth line is similar to the third line with the exception that the menuitem's name andnumber is different. Don't you think that it is always good to end whatever you have begun? Well thelast line ends the code you had started when you said begin. The statements in the resource files are notcase sensitive, except for the numbers which should be in the lower case.

    Creating a popup...

  • 8/8/2019 C++ memory

    31/39

    Let us now learn how to create a popup. To create a popup you just have to change the resousce file inthe following manner.

    AAA MENUBEGINPOPUP "ABC"BEGINMENUITEM "A1",100

    MENUITEM "A2",101ENDEND

    When you say " popup " the compiler knows that you want to create a popup menubar. Now inside a "begin " statement we have another " begin " statement in which you display the menu items you wantto see in your popup. Since we have two " begin " statements in our resource file we also should alsohave two " end " statement in it.

    Individual selection of menuitems...

    Let us learn how to select a menuitem from our MenuBar.

    #include #includeWNDCLASS a;long _stdcall zzz();HWND b;MSG c;_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);a.lpszMenuName = "AAA";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_COMMAND){

    MessageBox(0,"Hi","Hello",0);

    }

    if (x = = WM_DESTROY)PostQuitMessage(0);

    return DefWindowProc(w,x,y,z);}

    The ' WM_COMMAND ' which is used here, captures the selection of the menuitems. But here wehave not specified, as to which menuitem when clicked, is to display the MessageBox. So, on clickingany of the two menuitems, you see the same MessageBox being displayed.

  • 8/8/2019 C++ memory

    32/39

    Importance of the numbers passed to our menuitems...

    So far in our previous programs, you have learnt what three, of the four parameters, of our callbackfunction mean viz. ' w ' which is our window number, ' x ' which tells us as to why our window is beingcalled and ' z ' which tells us what is the position of the mouse on our screen. Let us now learn what theother parameter ' y ' does. The parameter ' y ' is number which tells us the selection made in ourwindow. Let us now use this parameter to capture the menuitem we want to select from our MenuBar.

    Here we shall also learn the importance of the number which we had passed as a value in our resourcefile.

    #include #includeWNDCLASS a;long _stdcall zzz();HWND b;MSG c;_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);a.lpszMenuName = "AAA";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_COMMAND)

    { if(y = =100){

    MessageBox(0,"Hi","Hi",0);}elseif(y = =101){

    MessageBox(0,"Bye","Bye",0);}

    }

    if (x = = WM_DESTROY)PostQuitMessage(0);

    return DefWindowProc(w,x,y,z);}

    In this program the additional code which you have passed in ' WM_COMMAND ' specifies themenuitem you have selected. Remember, we had given ' 100 ' as the number to ' A1 ' and ' 101 ' to ' A2', hence on selection of ' A1 ' we get a different MessageBox as compared to the MessageBox we getwhen we select 'A2 '.

  • 8/8/2019 C++ memory

    33/39

    Now that you have learnt about MenuBars, menuitems and popups why don't you try to create aMenuBar with two or more popups and different menuitems as part of your R & D.

    Capturing the System's Menuitem...

    Now that you have learnt of how to capture the menuitems selected from your popup, we shall learnhow to capture the menuitems of the System popup.

    To do this you have to first learn where the System menu exists. Now if you were an observant person,you would have seen that when your window is created, on the topmost left hand corner of yourwindow there is a picture. This picture is provided by Microsoft Windows, to our window - the onewhich we create in our program - free of charge. When you click with the mouse on this picture, thatyou will see your System popup menu displayed.

    So lets learn how to trap these command.

    #include #includeWNDCLASS a;long _stdcall zzz();HWND b;

    MSG c;_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);a.lpszMenuName = "AAA";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_SYSCOMMAND){

    MessageBox(0,"Hi","Hi",0);}

    if (x == WM_DESTROY)

    PostQuitMessage(0);return DefWindowProc(w,x,y,z);

    }

    Now on execution of our program, whenever you click on any of the Systems menu item you will seethe MessageBox being displayed. You will also see that when you click anywhere on the SystemMenuBar - it being in someway or the other effecting your System popup - your MessageBox beingdisplayed.

    Lets make a small change in our program and see what it does.

    #include

  • 8/8/2019 C++ memory

    34/39

    #includeWNDCLASS a;long _stdcall zzz();HWND b;MSG c;_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);a.lpszMenuName = "AAA";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_SYSCOMMAND && y == SC_CLOSE){

    MessageBox(0,"Hi","Hi",0);return 1;

    }

    if (x == WM_DESTROY)PostQuitMessage(0);

    return DefWindowProc(w,x,y,z);}

    There are two changes in our program. We have extended the ' if ' statement by anding it with the ' y '

    parameter to trap the close button of the System menu popup. We have also returned a value to our ' if 'condition. Execute the program and try to close it. What do you see? Don't you see your MessageBox ?Well, go ahead and close your window. Go ahead, we dare you to close the window using any of thelimited commands at your disposal. Well you can't ? Now, now don't get upset. Just like in our normalmenu we had given the numbers ' 100 ' , ' 101 ' to our menuitems, similarly the Windows menu has alsogiven our applications menuitems the numbers ' SC_CLOSE ', 'SC_MOVE ', ' SC_SIZE', etc. In ourprogram we have trapped the ' SC_CLOSE ' number in our ' if ' statement, so now you will see theMessageBox being displayed only when you click on close or you click on the x on your menu baror you use "Alt+F4". You click on any other menuitem, you will not see the MessageBox. Keep inmind that your parameter ' x ' i.e. which tells us when the callback function is called, is 'WM_SYSCOMMAND '. To get out of your window you have to press " Ctrl + Alt + Del " only once.

    You will get a dialog box. select " Bye " from it and say " End Task " to come out of the program. Ifyou press " Ctrl + Alt + Del " twice you will be rebooting your machine.

    Let us learn why you could not close the window. Normally when you close the window, your 'if 'condition does not return a value. So whenever you click on ' x ' on the Menubar or you press 'Alt + F4' or say close on the System Menu, you return the values used - in the callback function - in the 'DefWindowProc() ', and after it receives all the values, DefWindowProc() start it's shutdownprocess and closes your window. Now when you return a value in the ' if ' statement, you say that the DefWindowProc() is not to be called and since it does not get called, the values of ' x ' and ' y ' -which in our case is "WM_SYSCOMMAND' and 'SC_CLOSE' respectively - does not reach it. And

  • 8/8/2019 C++ memory

    35/39

    since the values of ' x ' and ' y ' do not reach it, the DefWindowProc() does not start the shutdownprocedure of our window and it can't close. You now have to call the anytime troubleshooter " Ctrl +Alt + Del " button to shutdown our window.

    Now lets remove the return statement, and put in some other code.

    #include #include

    WNDCLASS a;long _stdcall zzz();HWND b;MSG c;_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);a.lpszMenuName = "AAA";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_SYSCOMMAND && y == SC_CLOSE){

    MessageBox(0,"Hi","Hi",0);}if(x == WM_CLOSE){

    MessageBox(0,"Close","Close",0);}if (x == WM_DESTROY)

    PostQuitMessage(0);return DefWindowProc(w,x,y,z);

    }

    After you compile and run this program you now see two MessageBoxes. The first with the message"Hi" in it and the second with the message "close" in it. This shows that when you close the windowi.e. when you click on " close " in the System menu or you press " Alt + F4 " or when you click on th 'x'on the System's MenuBar, DefWindowProc() receives the values of ' x ' and ' y ' and sends yourwindow a WM_CLOSE message.You will however encounter the same problem you had in the

    previous program if you return a value to it i.e. you will be unable to close your window.

    Now lets add just two more lines of code to our program.

    #include #includeWNDCLASS a;long _stdcall zzz();HWND b;MSG c;_stdcall WinMain(HINSTANCE i, HINSTANCE j, char *k, int l)

  • 8/8/2019 C++ memory

    36/39

    {a.hInstance = i;a.lpszClassName = "Hi" ;a.lpfnWndProc = zzz;a.hbrBackground = GetStockObject(WHITE_BRUSH);a.hCursor = LoadCursor(0,IDC_CROSS);a.lpszMenuName = "AAA";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_SYSCOMMAND && y == SC_CLOSE){

    MessageBox(0,"Hi","Hi",0);}if(x == WM_CLOSE){

    MessageBox(0,"Close","Close",0);}if (x == WM_DESTROY){

    MessageBox(0,"in Wm_Destroy", "in Wm_Destroy",0);PostQuitMessage(0);

    }return DefWindowProc(w,x,y,z);

    Run the program, and close the window. What do you find ? You find that, you are now getting threeMessageBoxes. This shows that when you close the window even the WM_DESTROY gets called aspart of the shutdown process. But this WM_DESTROY gets called after WM_CLOSE. So we now

    know that, whenever you want to close your window DefWindowProc() first calls SC_CLOSEwhich calls WM_CLOSE which in turn calls WM_DESTROY.

    Give the WM_CLOSE a return value and you will see that again the value of ' x ' and ' y ' does notreach the DefWindowProc() , and hence you cannot close your window. The MessageBox which wehave put inside the WM_DESTROY will also not be seen.

    Now lets also pass the ' if ' statement of WM_CLOSE a ' DestroyWindow() ' and see what happens.Our program now looks as under.

    #include #includeWNDCLASS a;

    long _stdcall zzz();HWND b;MSG c;_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);a.lpszMenuName = "AAA";

  • 8/8/2019 C++ memory

    37/39

    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_SYSCOMMAND && y == SC_CLOSE){

    MessageBox(0,"Hi","Hi",0);}if(x == WM_CLOSE){

    MessageBox(0,"Close","Bye",0);DestroyWindow(w);return 1;

    }if (x == WM_DESTROY){

    MessageBox(0,"in wm_destroy", "in wm_destroy", 0);

    PostQuitMessage(0);}return DefWindowProc(w,x,y,z);

    }

    You now see that all three MessageBoxes are called. But now, inspite of giving a return value inWM_CLOSE, you notice that the window closes.

    Well, let us understand why this is happening. When ever you close the window using any of the threemethods to close the window i.e. when you click on " close " in the System menu or you press " Alt +F4 " or when you click on th 'x' on your windows MenuBar, your window receives a '

    WM_SYSCOMMAND ' and a ' SC_CLOSE ' which is given to DefWindowProc() . Now DefWindowProc() has an ' if ' statement in it by which it sends our window a ' WM_CLOSE 'message. So now if you do not do anything with the ' WM_CLOSE ' message and give it backuntampered to DefWindowProc() it invokes a function called ' DestroyWindow() '. The job of 'DestroyWindow() ' is to remove your window from the screen and send your callback function aWM_DESTROY message. Now as we were doing the same shutdown process which DefWindowProc() uses - when he receives the WM_CLOSE message - we were able to close downour window without any problems.

    So far the only function that we have not learnt about is the PostQuitMessage() function. Let usremove this function in our next program and see what changes take place to our window and why.

    #include #includeWNDCLASS 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)

  • 8/8/2019 C++ memory

    38/39

    {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_SYSCOMMAND && y == SC_CLOSE){

    MessageBox(0,"Hi","Hi",0);}if(x == WM_CLOSE){

    MessageBox(0,"Close","Close",0);

    DestroyWindow(w);return 1;

    }if (x == WM_DESTROY){

    MessageBox(0,"in wm_destroy", "in wm_destroy", 0);}return DefWindowProc(w,x,y,z);

    }

    Here, as explained in the previous program, the DestroyWindow() function removes the windowfrom the screen and sends a WM_DESTROY to DefWindowProc() . But now when

    DefWindowProc() receives a WM_DESTROY he does nothing because there is no line of codepassed in WM_DESTROY other than the MessageBox. This is bad programming. Youll realise thatbecause DestroyWindow() function was called, the window is removed from the screen. But in your WinMain() , you are still waiting in a while loop with a GetMessage() function. Now GetMessage() is a blocking function. When we say blocking it means that the function waits. This iswhat gives Microsoft Windows the ability to multitask i.e. because it has blocking functions.