// 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 hav e not // misunderstood we are talking about the windows API (Application Programming // Interface) , so all Windows haters please take the back seat ! I must tell y ou // I too am an amateur when it comes to Windows programming , and this is a res ult // 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 an y // mistakes in this code or its explanation. If you have any comments or questi ons // 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 proba bly // 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 clas s // 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 differ ent // set of arguments explained below. // // HINSTANCE hInstance // ------------------- // This is the [h]andle to the [Instance] of the windows class in the memory. I t // is a handle to the executable module in the memory and plays an important ro le // when it comes to manipulating independent modules and stuff.(Dont worry abou t // 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]oin ter // 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 s ingle // 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 th e // 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 ico n, // background colors etc which are defined in WNDCLASSEX struct. The window cla ss // also holds a pointer to the Procedure(or function) which controls the behavi our // 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 behaviou r // 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 windo w // 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. T he // 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 it s // 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 w indow // 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 creati on // data which is the data that can be sent to the window being created , respec tively // 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 w indow // The parameters are the handle to the window we created and the parameter // nCmdShow which is one of the arguments of WinMain(..). The nCmdShow specifie s // the state of the window. Through the command line arguments it can be specif ied // 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. Th e // 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 a s // 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 mes sage. // This is done by the function PosQuitMessage(..) function , which sends a mes sage // WM_QUIT. But this is not processed by this function. The GetMessage(..) func tionn // 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 programmer s // 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.