Tutorial :Why is WinAPI so much different from “normal” C?


I wonder why the WinAPI is so much different from "normal" C programming?

I mean, in school I learned that every C programm has a main() function (WinAPI uses WinMain with some special parameters), some variable types like int, long, char etc. (WinAPI uses things like LPCSTR, BOOL, etc.) so why did Microsoft decide to go such a different way with their OS API?

When I saw my first WinAPI program I it looks more like a new language to me... ;)


The original Windows API was designed in the 1984-85 time frame, over 25 years ago. Hungarian Notation was all the rage, so putting the type of a variable into the declaration was the thing to do. For example, in pure C, there is no way to indicate a 'far' pointer, which is what the LP in LPCSTR indicates, but in 1985, it was very important to distinguish between regular pointers and far pointers. (That importance went by the wayside when 32-bit windows took over in the mid-90s, but the syntax persists...)

Also, C doesn't really distinguish between just a pointer to a char and a pointer to a static string. Thus the lpsz types.

In the end, it's about bringing a stronger, consistent typing to the parameters than plain C allowed in 1984. As for the WinMain, it's because a Windows program is pretty fundamentally different from a command line program. If you look in the library, you'd probably find a main() function that sets up the parameters and then calls into an extern WinMain function (i.e. yours).


There are two major reasons:

  • Complexity. The C language is minimal, providing the building blocks on which more complex architectures can be constructed. LPCSTR, BOOL and other types that you find in Win32 are typedefs or structs built on top of C.
  • Event orientation. C is usually taught assuming that your program is proactive and in control of things. In an event-oriented environment, such as Windows (or any other GUI-based OS), your program is called by the OS, so it usually sits there in a loop waiting for messages to arrive.

The APIs of other GUI-based OSs may feel different to Win32, because there is no single solution, but the problem they are solving is the same one.


Microsoft's Raymand Chen writes in his blog:

Although the function WinMain is documented in the Platform SDK, it's not really part of the platform. Rather, WinMain is the conventional name for the user-provided entry point to a Windows program.

The real entry point is in the C runtime library, which initializes the runtime, runs global constructors, and then calls your WinMain function (or wWinMain if you prefer a Unicode entry point).


I'd say most of it is a question of style. The standards grew out of the Unix world, so for example the library functions have short names, and there aren't a whole lot of typedefs. I presume that reflects the choices of the designers of C and Unix. On the other hand Windows has LongFunctionNamesInMixedCase, and LOTSOFTYPEDEFS, *PTYPEDEFSFORPOINTERSTOO.

Some of it is also the perception of necessity. For example WinMain() has things like nCmdShow, because graphical apps will call ShowWindow() and I suppose they wanted to be able to pass the argument to that to a newly launched process. Whether or not that is actually needed might be another question.

And of course, some of the APIs do very different things. In Windows there's a lot of emphasis on passing messages, and processing messages on a per-thread basis. CreateFile() has a lot of flags that the Unix world doesn't have, including sharing modes which determine what another process can do while you have a file open.


They really didn't "go such a different way," as you put it.

WinMain() is simply the entry point looked for by the Windows OS. Conceptually, it's no different than main().

As for the symbol definitions (LPCSTR, BOOL, etc.), part of this is for ease of use. For example, it's shorter to write LPCSTR than const char *. Another example is the BOOL typedef which is not supported by the C language. The other reason is to insulate the developer from changes to the underlying hardware, e.g., the change from 16-bit to 32-bit to 64-bit architectures.

By no means should this answer be considered exhaustive. It's just a couple of things that I've noticed from the programming I've done with the Win32/MFC.


Windows API programming is event driven, while, up until that point, most C programming was linear. WinMain() is thus a shortcut into the libraries for writing using OS functionality - while main() is part of the C language.

While we're on the subject, C has few built in types, and, at the time, had few ways of indicating them. The windows "types" (HWND, LPSTR, BOOL, etc) reflect data types commonly used in windows programming, and make an attempt to indicate to the programmer what the data types will be.

The Hungarian notation is a bit of a mis-use of the original versions, in that there are an unnecessary number of qualifiers in many variables.

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Next Post »