Winmain

WinMain() is the C entry point function of any windows application. Like normal DOS/console based application which has main() function as C entry point, in windows we have WinMain() instead. WinMain() is a function which is called by system during creation of a process. First argument is the instance handle of the current process. Next is the previous instance. Command line arguments comes as next argument. Finally shell passes the show/display attribute of main window. WinMain returns success as zero and error as non zero.

WinMain function

The WinMain function is called by the system as the initial entry point for a Win32-based application.

WinMain prototype


int WINAPI WinMain(
  HINSTANCE hInstance,     /* [input] handle to current instance */
  HINSTANCE hPrevInstance, /* [input] handle to previous instance */
  LPSTR lpCmdLine,         /* [input] pointer to command line */
  int nCmdShow             /* [input] show state of window */
);

Parameters

  • hInstance - Handle to the current instance of the application.
  • hPrevInstance - Handle to the previous instance of the application. For a Win32-based application, this parameter is always NULL.
  • lpCmdLine - Pointer to a null-terminated string specifying the command line for the application, excluding the program name. To retrieve the entire command line, use the GetCommandLine() function.
  • nCmdShow - Specifies how the window is to be shown.

Return Values

If the function succeeds, terminating when it receives a WM_QUIT message, it should return the exit value contained in that message's wParam parameter. If the function terminates before entering the message loop, it should return zero.

wWinMain

The wWinMain is the wide character version of WinMain. An application written with wide char support or international language support should implement wWinMain. The only difference here is the lpCmdLine parameter. It is poining to a wide char string. GetCommandLineW() is used to access this parameter.

wWinMain prototype


int WINAPI wWinMain(
  HINSTANCE hInstance,     /* [input] handle to current instance */
  HINSTANCE hPrevInstance, /* [input] handle to previous instance */
  PWSTR lpCmdLine,         /* [input] pointer to command line */
  int nCmdShow             /* [input] show state of window */
);

Winmain@16 error in c

There are two types of Win32 application possible in Windows with VC++ or other compilers.

  • Console command line applications - These are equivalent to DOS text based applications and they runs under command prompt. main() function the entry point for these application.
  • Win32 applications - These are Windows native Win32 applications. They generally creates an overlapping window in the desktop screen.

Win32 applications should contain a defined entry function Winmain. crtstartup calls the the winmain. main() does not have a role here. Linker will generate undefined reference to WinMain@16 when there is no definition find in the source file. This error is very common to developers who moves from DOS to Windows programming environment.

Winmain command line arguments

The third argument to Winmain is the shell command line arguments string. An application process this string to know the parameters passed in the command line. We are printing this command line string in the message box window. This is one of the smallest window based application application.

WinMain Demo Application command line arguments

Winmain command line arguments demo

#include <windows.h>

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
   MessageBox(NULL, lpCmdLine, "WinMain Demo", 0);

  return 0;
}

Winmain command line arguments

c:\winmain\Debug>winmain.exe This is our WinMain Demo. Happy programming!

WinMain life cycle diagram

WinMain Application process life cycle

Win32 program can be executed by double clicking the executable from explorer window or from command line by typing the command name and argument to it. Windows operating system shell (cmd.exe) or explorer acts as a parent process. It invokes CreateProcess() API and provides executable path, command line arguments, environment variables and other necessary parameters. Windows kernel subsystem creates a process or task and one new main thread begins execution. Parent process wait till the end of execution of this child process. This process main thread takes the entry point function which is WinMain(). C Win32 compiler takes care of this mapping. It places a startup routine which is needed by C program startup and WinMain() is the first entry function called. WinMain() generally creates a main Window and process a message loop till the main window is dismissed. Here we have called MessageBox() function to create a popup dialog box. This dialog will stay in the screen and WinMain() will be in execution. This function comes from user32.dll and the message loop is processed inside this win32 library. This message loop waits till we press escape or hit enter or click on OK button. The dialog message loop ends and MessageBox() function returns. Now it reaches at the end of WinMain() and it returns 0 or success. This return value is processed in C startup and passed to ExitProcess() call. ExitProcess() informs Windows kernel task scheduler to end the process or main thread and mark the exit code of the process as zero or success. Now this process ends and parent process can read the status exit code.

Winmain arguments

This demo program takes application and its argument from user and uses CreateProcess Win32 API to create a child process. It takes argv[1] from user argument and passes to the CreateProcess. This argument is space seperated and first token is the application name and rest is the arguments to the application. This becomes the lpCmdLine of the process. argv[2] is converted to integer and passes to CreateProcess. It becomes the nCmdShow argument. nCmdShow has the following possible values.

  1. SW_HIDE - Window is hidden.
  2. SW_SHOWNORMAL/SW_NORMAL - Window is shown as normal.
  3. SW_SHOWMINIMIZED - Window is shown as minimized.
  4. SW_SHOWMAXIMIZED - Window is shown as maximized in full screen.


#include "stdafx.h"
#include <windows.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
  STARTUPINFO si;
  PROCESS_INFORMATION pi;

  if( argc < 3)
  {
    printf("syntax: CreateProcessDemo \n");
    printf("Define & Value \n");
    printf("SW_HIDE 0\n");
    printf("SW_SHOWNORMAL 1\n");
    printf("SW_NORMAL 1\n");
    printf("SW_SHOWMINIMIZED 2\n");
    printf("SW_SHOWMAXIMIZED 3\n");
    return -1;
  }
  ZeroMemory( &si, sizeof(si) );
  si.cb = sizeof(si);
  si.dwFlags = STARTF_USESHOWWINDOW;
  si.wShowWindow = atoi(argv[2]);
  ZeroMemory( &pi, sizeof(pi) );

  if(!CreateProcess( NULL,   /* No module name (use command line)*/
        argv[1],        /* Command line */
        NULL,           /* Process handle not inheritable */
        NULL,           /* Thread handle not inheritable */
        FALSE,          /* Set handle inheritance to FALSE*/
        0,              /* No creation flags */
        NULL,           /* Use parent's environment block */
        NULL,           /* Use parent's starting directory */
        &si,            /* Pointer to STARTUPINFO structure */
        &pi )           /* Pointer to PROCESS_INFORMATION structure */
    ) 
  {
    return -1;
  }

  WaitForSingleObject( pi.hProcess, INFINITE );
  CloseHandle( pi.hProcess );
  CloseHandle( pi.hThread );
  return 0;
}


We are creating a process with notepad. We are providing our source code file as the argument of the notepad. Notepad launches and opens our file. We have provided nCmdShow as SW_SHOWNORMAL. So it is getting displayed as normal. Every time we double click on text files in windows explorer, windows shell does these in background.

C:\Users\Documents>CreateProcessDemo
syntax: CreateProcessDemo  
Define & Value
SW_HIDE             0
SW_SHOWNORMAL       1
SW_NORMAL           1
SW_SHOWMINIMIZED    2
SW_SHOWMAXIMIZED    3

C:\Users\Documents>CreateProcessDemo "notepad.exe C:\Users\Documents\CreateProcessDemo.cpp" 1

CreateProcess & WinMain arguments

About our authors: Team EQA

Further readings

Where is WinMain() function in MFC application ?

MFC hides WinMain in its framework and includes source file on WinMain(). This explains how framework calls global CWinApp::Initinstance() from entry WinMain.

What is the utility of CWinApp class?

This is constructed during global C++ objects are constructed and is already available when Windows calls the WinMain function, which is supplied by the ...

Basic steps in Win32 GUI Application with source code.

Define a custom Window class structure, Register the class name, CreateWindow, Show windows and write message get and dispatch loop statements. Define the Window CallBack procedure and write the handlers.

What is a Window CallBack procedure and what is its utility?

DispatchMessage() is a API which indirectly triggers the Window CallBack procedure. Message structure members from this function are passed to the CallBack procedure. CallBack procedure should implement event handlers depending on the need of the application.

What are LPARAM and WPARAM in window proc function?

LPARAM and WPARAM are the two parameters in Window CallBack procedure. They signifies parameters of various events. They are used in handing individual events.

What are the basic steps of a typical MFC based application?

We need to write WinMain and need to follow all these in a Win32 application. However we need not to write much if we are writing an application with MFC ...

#