views:

270

answers:

4

Hi, I just started learning programming for windows in c++. I had this crazy image, that win32 programming is based on calling windows functions and sending parameters to and from them. Like, when you want to create window, you call some win32 function that handles windows GUI and say "Hi, please, create me new window, 100 x 100 px, with two buttons", and that GUI function says "Hi, no problem, when something happends, like user clicks one button, I will change this variable xy located in this location".

So, I thought that it will be very similiar to console programming. But the very first instruction surprised me. I always thought that every program executes main() function first. So, when I launch app, windows stores some parameters on top of stack and run that application. So I assumed that initializing main() is just a c++ way to tell the compiler where the first instruction should be.

But in win32 programming, there is function called WinMain() which starts first. So I am little confused. I thought it´s rule that compiler must have main() to start with, that main just defines where it starts, like some start point identifier.

So, please, why is there WinMain() function instead of main()? When I thought that C++ programming is as logical as assembler, it confuses me once again.

+6  A: 

main() is as arbitrary an entry point as WinMain() is. The standard only requires a function named main for consistency. The entry point (whether it's main or WinMain) is actually called by a hidden function that is the real entry point. On some platforms that "real" entry point is called something like _start. It's that function that does all of the initial work like initializing globals, setting up the environment, etc., and then it calls main(). On Windows, that start function happens to call WinMain() if available.

Edit: check out this answer for a more detailed explanation.

greyfade
+2  A: 

To understand how Win32 application works requires additional effort compared to usual console application.

"I had this crazy image, that win32 programming is based on calling windows functions and sending parameters to and from them"

my hints ...

1 )True , but also windows message that are the beats of a Windows Application , some example include WM_CREATE, WM_MOUSExx , WM_KEYxx , WM_PAINT where xx can be DOWN UP and so on . Messages are sent to your application by Windows itself , it is up to you to define a specific function to trap them (the "WindowFunc"). There are hundreds of messages, luckily is not necessary to understand all them at first .

2) Every widget you can imagine to create in your app is a "Window" , and you can create Windows by CreateWindow function .Each window will be identified by a 32 bit integer value the so called Window Handle (HWND)

3 There are so many different class of windows as you can imagine (mainwindow , clientarea , edit, button) both available from the system and also created by yourself... Windows are different as they belong from different WindowClass ...

To define a WindowClass you have to fill a WNDCLASS c structure and call RegisterClass A field in the struct is a pointer to the WindowFunc

4 The WindowFunc is a function that takes 4 input parameters (HWND,WM_XX,wParam,lParam) That function will be called from the system as soon as something happens regarding that window (HWND)

said that let me rewrite your statement

"Like, when you want to create window, you call some win32 function that handles windows GUI and say "Hi, please, create me new window, 100 x 100 px, with two buttons", and that GUI function says "Hi, no problem, when something happends, like user clicks one button, ...I will send you a message to the windowFunc as the user click... please check for the messagetype by yourself and if it is the WM_MOUSEDOWN you was waiting for then change the value for xy

What else ? i suggest to look at some simple sample in the sdk to get confident on how a win 32 app flow is

cheers

luca
+1  A: 

It is just a convention for native Win32 programs. You can easily change it, the MSVC linker accepts the /ENTRY:main command line option to change the entry point name to "main". You will however also have to change the signature of the main() function, it takes different arguments:

int APIENTRY main(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
  // etc..
}

Which I guess was the point of giving it a different name 20 years ago.

Hans Passant
actually, the entry point doesn't receive any parameters. The library version calls APIs like GetCommandLine and GetStartupInfo and then calls main or WinMain (or wmain or _wWinMain). Also, "Win3" is a poor way of saying "16-bit Windows", since Windows NT 3.x was natively 32-bit.
Ben Voigt
IIRC `hPrevInstance` is a legacy from Windows 1, not 3.
MSalters
A: 

YOu can check this article and another one from a microsoft developer. Briefly there're several reasons: the name are arbitrary, windows' WinMain required a different signature, windows predates c++ standarization.

Ismael