The First Windows Program in C
To keep things simple we would begin with a program that merely displays a “Hello” message in a message box. Here is the program…
int _stdcall WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdline, int nCmdShow )
MessageBox ( 0, “Hello!”, “Title”, 0 ) ;
return ( 0 ) ;
Naturally a question would come to your mind—how do I create and run this program and what output does it produce. Firstly take a look at the output that it produces. Here it is…
Let us now look at the steps that one needs to carry to create and execute this program:
- Start VC++ from ‘Start | Programs | Microsoft Visual C++ 6.0’. The VC++ IDE window will get displayed.
- From the File | New menu, select ‘Win32 Application’, and give a project name, say, ‘sample1’. Click on OK.
- From the File | New menu, select ‘C++ Source File’, and give a suitable file name, say, ‘sample1’. Click on OK.
- The ‘Win32 Application-Step 1 of 1’ window will appear. Select ‘An empty project’ option and click ‘Finish’ button.
- A ‘New Project Information’ dialog will appear. Close it by clicking on OK.
- Again select ‘File | New | C++ Source File’. Give the file name as ‘sample1.c’. Click on OK.
- Type the program in the ‘sample1.c’ file that gets opened in the VC++ IDE.
- Save this file using ‘Save’ option from the File menu.
To execute the program follow the steps mentioned below:
- From the Build menu, select ‘Build sample1.exe’.
- Assuming that no errors were reported in the program, select ‘Execute sample1.exe’ from the Build menu.
Let us now try to understand the program.
The way every C under DOS program begins its execution with main( ), every C under Windows program begins its execution with WinMain( ). Thus WinMain( ) becomes the entry point for a Windows program. A typical WinMain( ) looks like this:
int __stdcall WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow )
Note the __stdcall before WinMain( ). It indicates the calling convention used by the WinMain( ) function. Calling Conventions indicate two things:
- The order (left to right or right to left) in which the arguments are pushed onto the stack when a function call is made.
- Whether the caller function or called function removes the arguments from the stack at the end of the call.
Out of the different calling conventions available most commonly used conventions are __cdecl and __stdcall . Both these calling conventions pass arguments to functions from right to left.
In __cdecl the stack is cleaned up by the calling function, whereas in case of __stdcall the stack is cleaned up by the called function.
All API functions use __stdcall calling convention. If not mentioned, __cdecl calling convention is assumed by the compiler.
HINSTANCE and LPSTR are nothing but typedefs. The first is an unsigned int and the second is a pointer to a char. These macros are defined in ‘windows.h’. This header file must always be included while writing a C program under Windows. hInstance, hPrevInstance, lpszCmdLine and nCmdShow are simple variable names. In place of these we can use i, j, k and l respectively. Let us now understand the meaning of these parameters as well as the rest of the program.
WinMain( ) receives four parameters which are as under:
hInstance: This is the ‘instance handle’ for the running application. Windows creates this ID number when the application starts. We will use this value in many Windows functions to identify an application’s data.
A handle is simply a 32-bit number that refers to an entity. The entity could be an application, a window, an icon, a brush, a cursor, a bitmap, a file, a device or any such entity.
The actual value of the handle is unimportant to your programs, but the Windows module that gives your program the handle knows how to use it to refer to an entity.
What is important is that there is a unique handle for each entity and we can refer and reach the entity only using its handle.
hPrevInstance: This parameter is a remnant of earlier versions of Windows and is no longer significant. Now it always contains a value 0. It is being persisted with only to ensure backward compatibility
lpszCmdLine: This is a pointer to a character string containing the command line arguments passed to the program. This is similar to the argv, argc parameters passed to main( ) in a DOS program.
nCmdShow: This is an integer value that is passed to the function. This integer tells the program whether the window that it creates should appear minimized, as an icon, normal, or maximized when it is displayed for the first time.
The MessageBox( ) function pops up a message box whose title is ‘Title’ and which contains a message ‘Hello!’.
Returning 0 from WinMain( ) indicates success, whereas, returning a nonzero value indicates failure.
Instead of printing ‘Hello!’ in the message box we can print the command line arguments that the user may supply while executing the program. The command line arguments can be supplied to the program by executing it from Start | Run as shown below.
Please note that :
‘myapp.exe’ is the name of our application, whereas, ‘abc ijk xyz’ represents command line arguments. The parameter lpszCmdline points to the string “abc ijk xyz”. This string can be printed using the following statement.
MessageBox ( 0, lpszCmdline, “Title”, 0 ) ;
If the entire command line including the filename is to be retrieved we can use the GetCommandLine( ) function.