Topic : C Windows Programming
Author : Vijay Mukhi
Page : << Previous 10  
Go to page :


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_CLOSE which 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 not reach the ‘ DefWindowProc() ‘, and hence you cannot close your window. The MessageBox which we have put inside the WM_DESTROY will also not be seen.

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

#include <windows.h>
#include<stdio.h>
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","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 in WM_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 three methods 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 window’s 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 back untampered 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 a WM_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 down our window without any problems.

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

#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_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 window from 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 code passed in WM_DESTROY other than the MessageBox. This is bad programming. You’ll realise that because ‘ 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 wait’s. This is what gives Microsoft Windows the ability to multitask i.e. because it has blocking functions.

Let's understand that, the moment you click on the window or press a key on the keyboard, the ‘ GetMessage() ’ function gets called. Windows knows, that the first parameter of this function, is a pointer to a structure that looks like MSG. This structure takes the same four parameters as the callback function ‘ zzz ’. So ‘ GetMessage() ’ fills up this structure and it returns a ‘ non 0 ’ value. It is the job of ‘ DispatchMessage() ’, who is given the address of this same structure, to now call your callback function. So we are always waiting at the ‘ GetMessage() ’ function. The only way this ‘ GetMessage() ’ function will return a ‘ 0 ‘ value, is when it receives a ‘ WM_QUIT ‘ message. The job of ‘ PostQuitMessage()’ function is to send a ‘ WM_QUIT ’ Message to the ‘ GetMessage() ’ function. Now because we have not put in the ‘ PostQuitMessage(0) ’ function in ‘ WM_DESTROY ’ the WM_QUIT message is not passed to the ‘ GetMessage() ’ and hence it is still waiting and because of this you window is not deleted from memory.

All that if Microsoft had done was, if in their ‘ DefWindowProc() ’ function, they had an ‘ if ’ statement that said, ‘ x = = WM_DESTROY ’ PostQuitMessage(0) we would have had no problems and would not have had to learn this function.

Wrapping it up...

Well friends you can breathe a sigh of relief. That was the last program under ‘ C ‘ Windows Programming. We sincerly hope that you have learnt something out of this session, and if worse comes to worst, you should at least be able to say that you are a ‘ C ‘ Windows programer. We have tried to be meticulious with each program, and tried to explain each of them in a manner which may be easy to follow and understand.

Page : << Previous 10