What is Winmain?

WinMain() is the C entry point function of any windows application. DOS/console based applications use main() as the C programming entry point function however windows Win32 graphical applications use WinMain() as the entry point function.

WinMain() is a function which is called by the operating system during creation of a process. First argument is the instance handle of the current application process. Next argument is the handle of the previous instance (used in Win16 programs, no longer used in Win32). The command line arguments from operating system shell comes as next argument. Finally operating system passes the window show attribute of main window. WinMain returns success as zero and error as non zero.

WinMain function and C prototype

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


int WINAPI WinMain(
  HINSTANCE hInst,     /* handle to current instance */
  HINSTANCE hPrevInst, /* handle to previous instance */
  LPSTR strCmdLine,    /* ASCII string pointer to command line */
  int nCmdShow         /* show state of window */
);

Parameters

  • hInst - Handle to the current running instance of the application.
  • hPrevInst - Handle to the previous instance of the process. This was used in Win16 application and no longer used in Win32-based application (This is always NULL).
  • strCmdLine - Pointer to a null-terminated ASCII string holding the input command line from the , 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.

What is wWinMain function?

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,     /* handle to current instance */
  HINSTANCE hPrevInstance, /* handle to previous instance */
  PWSTR lpCmdLine,         /* UNICODE string pointer to command line */
  int nCmdShow             /* 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 string

How to know the string arguments passed to my application? Command line argument string argument passed to an application process. This is the third argument to Winmain which comes from shell of the operating system. An application parses this string to know the parameters passed in the command line. An editor like notepad or wordpad etc takes the text file path as the input and display the content to the user. Here is an application code where we are printing this command line string in the message box window. This is one of the smallest window based application application to print the string in a GUI environment.

Winmain display command line arguments in message box

#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 Demo Application command line arguments

WinMain life cycle diagram

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().

WinMain Application process life cycle

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 argument passing example

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

Similar articles

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 ...

#