How to Create a Window in C

 // Language : C/C++
 // Compiled in : Borland C++ 5.5 , Mingw , ( Should compile in MS Visual C++ )
 // Platform : MS-Windows
 // I am : Vivek Mohan (vivekATsig9DOTcom)
 // You can copy this article and directly compile it.


 // INTRODUCTION
 // ============
 // Hi ! So you wanna know how to create a window in C++. Ahem ! Well if you have not 
 // misunderstood we are talking about the windows API (Application Programming
 // Interface) , so all Windows haters please take the back seat ! I must tell you
 // I too am an amateur when it comes to Windows programming , and this is a result
 // of what I jotted down while I was self studying programming for windows. So if
 // you are one of those expert programmers , please let me know if there are any 
 // mistakes in this code or its explanation. If you have any comments or questions
 // at all please mail me at the above mentioned address. 

 // THE LIBRARY
 // ===========

 # include <windows.h>

 // A line you must never miss while programming for windows
 // The win32 API library 

 // THE CLASS NAME
 // ==============

 const char g_szClassName [] = "My Window Class";

 // A name for our windows class. Wait ! Aha ! If I'm not mistaken you are probably

 // thinking that the windows class is a C++ class. No it is not. This is
 // completely different. It is just like what the word means. A particular class
 // of windows with a certain , set of characteristics and behaviour. 
 // You'll understand what I mean...eventually.
 //
 // But why const ?
 // ---------------
 // The class name is stored as a const char array because we won't be using 
 // this variable for long and are not going to modify it.
 //
 // But why the weird name , g_szClassName ?
 // ----------------------------------------
 // I don't know if this question does pop up into your mind , but
 // atleast it did in mine. Well firstly I must tell you that it is
 // not compulsory that you keep the same name , but these names are
 // kept in accordance to certain conventions. These conventions are
 // specific to win programming. Using these conventions makes sure
 // that other programmers can read your code without any difficulty.
 // Moreover as you move on you'll see that these words can be easily
 // identified for what they represent by a careful analysis.

 // PROTOTYPE FOR WndProc
 // =====================

 LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);

 // We'll discuss about the function when we actually 
 // define it.

 // MAIN
 // ====

 int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance ,
            LPSTR lpCmdLine , int nCmdShow )

 // if you have programmed in dos or unix , you may be familiar with the main()
 // function which is the entry point for code execution. Similarily for windows
 // programs WinMain is the entry point. But unlike the command line arguments
 // in dos or linux "int main(int argc,char *argv[])" , WinMain(..) has a different
 // set of arguments explained below.
 //
 // HINSTANCE hInstance
 // -------------------
 // This is the [h]andle to the [Instance] of the windows class in the memory. It
 // is a handle to the executable module in the memory and plays an important role
 // when it comes to manipulating independent modules and stuff.(Dont worry about
 // it now..!).
 //
 // HINSTANCE hPrevInstance
 // -----------------------
 // This is the [h]andle to the [Prev]ious [Instance] of the windows application. 
 // This is not at all important and is null for 32 bit windows programs.
 //
 // LPSTR lpCmdLine
 // ---------------
 // If you are wondering what LPSTR stands for , it is nothing but [L]ong [P]ointer 
 // to [STR]ing or char*. The long part is not important any more as far as
 // win32 is concerned. lpCmdLine stands for [l]ong [p]ointer to [C]o[m]man[d]
 // [Line] arguments. Unlike what you'd expect (as in dos or unix) , this is a single
 // string containing all of the command line arguments and does not include the
 // program name.
 //
 // int nCmdShow
 // ------------
 // This argument , as you'll see later, is useful in specifying the state of the
 // window when drawn (like Minimized , Maximized ..etc). This is the parameter
 // used in shortcuts to your applications in Windows when you want it to be
 // in Maximized mode or minimized or maybe just normal.

 {


 // REGISTERING A WINDOW CLASS
 // ==========================
 // A Window class holds the information about the type of window. This 
 // class needs to be registered with a particular set of attributes such as icon,
 // background colors etc which are defined in WNDCLASSEX struct. The window class
 // also holds a pointer to the Procedure(or function) which controls the behaviour
 // of the windows. Once registered , any number of windows can be created with
 // the same attribs without specifying the same all over again. 

	WNDCLASSEX wc;

 // A window class wc
 // Setting the different attributes of the window class
	
	wc.cbSize = sizeof(WNDCLASSEX);

 // cbSize holds the size of the struct WNDCLASSEX

	wc.style  = 0;

 // style stores the class style and can be usually set to 0

	wc.lpfnWndProc = WndProc ;

 // lpfnWndProc = [l]ong [p]ointer to [f]u[n]ction [WndProc]. This is a pointer to
 // the function WndProc which is the window procedure and controls the behaviour
 // of the window. Remember the function WndProc we prototyped a few pages back !


	wc.cbClsExtra  = 0;

 // cbClsExtra stores the amount of extra memory to be allocated
 // for this class of windows.This is also usually 0;

 	wc.cbWndExtra  = 0;

 // cbWndExtra stores the amount of extra memory to be allocated
 // for each window of this class. This is also usually set to 0.

	wc.hInstance   = hInstance;

 // Handle to the instance of the application
	
	wc.hIcon       = LoadIcon  (NULL,IDI_APPLICATION);

 // This is the icon (32x32) shown when the user presses alt+tab
 // to switch between applications. Don't worry about the function
 // LoadIcon (...) now.

	wc.hCursor     = LoadCursor(NULL,IDC_ARROW);


 // The cursor that'll be displayed over the window

	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);

 // Background brush to set the color of the window

	wc.lpszMenuName  = NULL;

 // Name of a menu resource to use with this class , since we don't need
 // no menus it is set to NULL.

	wc.lpszClassName = g_szClassName;

 // The name of the class to be identified with , if you remeber 
 // we had declared a const char array g_szClassName which stores'
 // our window class name

     wc.hIconSm       = LoadIcon(NULL,IDI_APPLICATION);

 // This is the handle to the icon displayed on the top left corner of the window
 // or on the taskbar.

 // REGISTERING THE WINDOW
 // ======================

	if(!RegisterClassEx(&wc))
	{

 // The RegisterClassEx(WNDCLASSEX&) function which takes the address of 
 // a window class struct , attempts to register it and returns a non-zero
 // value if it is able to do so. Else it returns 0.

        	MessageBox(NULL , "Failed to register window class" ,
                        "Error" , MB_ICONEXCLAMATION | MB_OK );

 // If the registration fails , A message is displayed using the MessageBox
 // function. After running the program you'll understand how the MessageBox(...) 
 // works so it doesn't need much explanation. 

 	        return 0;

 // Then return 0.

	}

 // CREATING A WINDOW
 // =================
 // Now comes the part where we have to create the window
 
     HWND hwnd;

 // A handle to the window we create. The function CreateWindowEx(..) creates a 
 // a window and returns the handle

     hwnd = CreateWindowEx(

 // The returned handle is stored in hwnd

                   WS_EX_CLIENTEDGE ,

 // Argument 1 : Is the style of the window , I have set it to 0, you can use
 // other values and see what happens.

                   g_szClassName    ,

 // Argument 2 : Is the name of the registered class , so that the creator knows
 // what class of window has to be created.

                   "Title Of Me Window !" ,

 // Argument 3 : Is the title of the window

                   WS_OVERLAPPEDWINDOW    ,

 // Argument 4 : Is a window style parameter. You can substitute integer values
 // for this and see what happens

                   CW_USEDEFAULT , CW_USEDEFAULT , 240 , 120 ,

 // Argument 5 , 6 , 7 , 8 : Specify the window's co-ordinates and dimensions. The
 // first two , the X and Y co-ords and the second two the width and the height of
 // the window. The CW_USEDEFAULT specifies that the window is free to choose its
 // position. You can also specify your own integer values

                   NULL , NULL , 

 // Argument 9 , 10 : are the handles to the Parent Window and Menu. Since our window
 // has no parent or a menu the values are set to NULL.

		   hInstance , NULL

 // Argument 11 , 12 : are the handle to the application instance and the creation 
 // data which is the data that can be sent to the window being created , respectively 
 // currently NULL.

            );

 // End of function

 // If handle to the newly created window is null , show an error and then exit

     if(hwnd == NULL)
     {
           MessageBox(NULL , "Failed to create window"
                        , "Error"
                        , MB_ICONEXCLAMATION | MB_OK );
           return 0;
     }


 // DRAWING THE WINDOW
 // ==================

      ShowWindow  (hwnd,nCmdShow);
      UpdateWindow(hwnd);

 // Now that the window has been created , it needs to be drawn and then updated to
 // make sure that it is properly drawn. The ShowWindow(...) command draws the window
 // The parameters are the handle to the window we created and the parameter
 // nCmdShow which is one of the arguments of WinMain(..). The nCmdShow specifies
 // the state of the window. Through the command line arguments it can be specified
 // wether the window should be minimized , maximized or visible...
 // You can use other values sch as SW_SHOWNORMAL or SW_SHOWMAXIMIZED or
 // SW_SHOWMINIMIZED etc.

 // MESSAGE LOOPING
 // ===============

	MSG Msg;

	while(GetMessage(&Msg,NULL,0,0))

 // The message looping is like an engine which drives the windows application.

 // What makes the window just stay right where it is until you either
 // move it or close it ? After the registering and window creation this
 // is the point where the real stuff takes place. 
 //
 // The Basic Job Of the Message Loop
 // ---------------------------------
 // 1 . get message from the message queue , if none wait for one.
 // 2 . translate the message
 // 3 . dispatch the message to the window or whereever applicable
 //
 // Messages are generated by the system whenever you move the mouse , click or
 // press a key on the keyboard. These messages are added to a message queue. The 
 // GetMessage(...) function gets one such message at a time and returns it.
 // If no message is available in the message queue then GetMessage(..)
 // blocks or waits till a message is generated.

	{


        	TranslateMessage(&Msg);

 // The TranslateMessage(..) function does additional processing.

        	DispatchMessage (&Msg);

 // This function after processing the messages dispatches the messages , where
 // it is meant to be so. It may be to the window we created or to the system or
 // another program.

      	}
	
	return Msg.wParam;
 }


 // WINDOW PROCEDURE
 // ================

 LRESULT CALLBACK WndProc (HWND hwnd , UINT msg,WPARAM wParam , LPARAM lParam)
 {

 // This is the definition of the function WndProc we protoyped a few pages back
 // If you remeber while registering the window class , we set the lpfnWndProc as
 // the below function. This means that the procedure for the window
 // is the function WndProc(...). The function accepts the message
 // and processes according to what it is (ie what we decide).

 // This function can be the Window procedure for the many windows and hence the 
 // handle to the window dispatching the message is passed.

         switch(msg)

 // Switch between different cases of message
         {

             case WM_CLOSE:

 // The message is to close the window
 // This message is sent when the user clicks on the X button on the top-right
 // hand corner of the window or presses Alt+F4.
 // You can add the MessageBox(...) function here and experiment

                  DestroyWindow  (hwnd);

 // The destroy window function sends the WM_DESTROY mesage to the window
 // This message is handled as another case below
                  break;
             case WM_DESTROY:

 // This message destroys the window and all its child windows , before removing the
 // window from the system.

                  PostQuitMessage(0);

 // Since we have only one window and no child windows , we just Post a quit message.
 // This is done by the function PosQuitMessage(..) function , which sends a message
 // WM_QUIT. But this is not processed by this function. The GetMessage(..) functionn
 // when gets this message , returns false and the message loop ends.

                  break;
             default:

                  return DefWindowProc(hwnd,msg,wParam,lParam);

 // This part is not so important right now.

          }

          return 0;
 }
 
 // Thats it. I hope you have liked this small effort to help all you programmers
 // out there new to win programming and wanting to create a window. 

 // Copyright : You are free to distribute this article as long as you don't
 // use it for profitable purposes (as if you can) ,and all the messages are
 // retained.