Advertisement

main() vs Winmain()

Started by July 30, 2000 04:43 AM
9 comments, last by gimp 24 years, 4 months ago
I''ve never really thought about this until recently... Whats the difference here? is there any really good reason to use winmain, seems like a whole lot of effort just to get rid of the initial console... Am I missing something here? gimp
Chris Brodie
Well, if you want windows to run your GUI program, then you NEED WinMain and WndProc. WinMain is your main function and WndProc is what handles your messages. It is a spec for Windows programs to use a different method than console/Dos programs. For your DOS/Console program, main() isn''t the first function that is called, there is some other behind the scenes stuff that the compiler does, it then calls the function main(). For win apps, there is also some behind the scenes stuff, then it calls WinMain so as not to confuse it with any other procedure.

I think it may be possible to have a main() function in your win app provided you still have WinMain, although I have not tried this


-Chris Bennett ("Insanity" of Dwarfsoft)

Check our site:
http://www.crosswinds.net/~dwarfsoft/
Check out our NPC AI Mailing List :
http://www.egroups.com/group/NPCAI/
made due to popular demand here at GDNet :)
Advertisement
i don't think he's talking about whether it's possible or not... i assume you mean 'why the hell does microsoft force us to write all that shit every time we want to make a window appear'

and, no it's not necessary

linux programs (even the windowed programs) all use main(), and then there is something like int x = CreateWindow (0, 0, 640, 480) or whatever.



Edited by - remo on July 30, 2000 7:42:25 AM
[email=ehremo@hotmail.com][/email]
Using main() in a windows program with WinMain() is kind of strange. I have actualy done this in my..uh..newbie stupid programming phase, well since then Im quite an advanced developer : )

Using main() in a windows program (GUI) will only make it used like any other function u make. Simply put u learn strange things when you are self-taught programmer of 6-7 years.

-John

X E R O-D E V E L O P M E N T
HTTP://WWW.X3R0.COM
X E R O-D E V E L O P M E N THTTP://WWW.X3R0.COM
Did you read the part where I was talking about BEHIND THE SCENES? What your compiler sticks in the beginning of the app? For Win apps it needs to some different setup from console apps, so it needs to distinguish this, therefore if you are creating a win app you need to use a different function. Obviously it is going to be called something like WinMain instead of KLDJSAkngdfali eh? And for Linux windowing? How much of the window do you have to set up for? I am just wondering if you are the person who has to write all that behind the scenes stuff (or if you use a lib or something)


-Chris Bennett ("Insanity" of Dwarfsoft)

Check our site:
http://www.crosswinds.net/~dwarfsoft/
Check out our NPC AI Mailing List :
http://www.egroups.com/group/NPCAI/
made due to popular demand here at GDNet :)
There is really no need for it, but if it saves me from typing more crap Im all for it. The function main (only in pure C) can be called from within a program (I dont think it has a use, but I dare someone to find one). I don''t think Winmain can, but its worth a shot.

-----------------------------

A wise man once said "A person with half a clue is more dangerous than a person with or without one."
-----------------------------A wise man once said "A person with half a clue is more dangerous than a person with or without one."The Micro$haft BSOD T-Shirt
Advertisement
Behind the scenes stuff: I don''t know what happens in a console app, but in a windows app, GetModuleHandle(), GetCommandLine() are called, then winmain is called. The two functions are to get the hInstance and lpCmdLine parameters respectively. This comes from what I do in Win32 ASM anyway.

------------------------------
#pragma twice
[ Note: The following is based on my experience and knowledge only. If you have evidence to the contrary, please enlighten me =) ]
Actually, You CAN use a regular

int main(int argc, char *argv[]);

as the entry point to create a Windows program. However, this can only be done in a program being built as a Windows CONSOLE application. You can still create Windows GUI elements (windows, dialogue boxes, etc) using the standard Windows API calls, but you have to do a TINY bit more housekeeping to do so. Once that is done, you can create windows using a method very much like the Linux/XWindows method mentioned above [win = CreateWindow(x, y, flag);]. This has definite advantages.

Here is how it works:
Windows Console Apps include the libraries needed for some basic windows interfaces, but not the special ones used for Windows GUI projects. Thus, the entrypoint stub (the main() procedure) must be defined by you.
When building a Windows GUI app, the library included actually contains a Main() function that performs the added housekeeping mentioned above, and then makes a call to an external stub that is used as the entry point into the programmer''s code. This is the WinMain().
Thus, in reality, both use the Main() entry point (which is the standard entrypoint for C/C++ compilers to use), but when making a Non-Console Windows app, the Main() is already defined in a precompiled Microsoft library. When it has executed the GUI coded needed to get things like an application instance and other such things, it passes them off to some function named "WinMain" that is defiend as an extern to the Module. This stub is where you can start doing your work.

So, what is the real difference?

In general, I would say that for a major project (like a game) it would be best to use the Windows Console build (and thuse create your own Main()).
Here is why:
All C/C++ applications have a Main() function. That means that it will compile fine for all OS platforms. If you enter through a Main(), then use #defines to use different window/GUI routines for appropriate operating systems, your code will work just as well on Linux as it will on W2k. If you use a WinMain, however, your code is from the start Windows specific, and will not be portable without a completely separate source build for other OS''. (Some might say the fact that so little is known about the Main() method for Windows programs is due to Microsofts attempt to foster Non-Portable code creation).

This method is commonly used fot that very reason. Examples include the demos in the book "The OpenGL SuperBible" (using the GL Utility Toolkit [GLUT] requires the Main() entrypoint method) and Quake/Quake2/Quake 3 Arena (see the WinQuake source found in Id Software''s web site: ftp://ftp.idsoftware.com ).

Hopefully this has been helpful. If any of you have any interest, I could try to write an article for GameDev on this subject, explaining it in further (or at least clearer) detail.

-- Nathan Hoobler

while(1)
fork();
-- Nathan Hoobler

Having two entry points is indeed useful.

Take a look at the screen saver code on Microsoft''s site. They use
both main() and WinMain() as entry points to their program and then
call the same function from that point on.

Here''s the startup code:

    int _stdcallDummyEntry( void ){    int i;    STARTUPINFO si;    LPTSTR pszCmdLine = GetCommandLine();    if ( *pszCmdLine == TEXT(''\"'')) {        /*         * Scan, and skip over, subsequent characters until         * another double-quote or a null is encountered.         */        while (*(pszCmdLine = CharNext(pszCmdLine)) &&              (*pszCmdLine != TEXT(''\"'')) );        /*         * If we stopped on a double-quote (usual case), skip         * over it.         */        if ( *pszCmdLine == TEXT(''\"'') )            pszCmdLine++;    }    else {        while ((UINT)*pszCmdLine > (UINT)TEXT('' ''))            pszCmdLine = CharNext(pszCmdLine);    }    /*     * Skip past any white space preceeding the second token.     */    while (*pszCmdLine && ((UINT)*pszCmdLine <= (UINT)TEXT('' ''))) {        pszCmdLine = CharNext(pszCmdLine);    }    si.dwFlags = 0;    GetStartupInfo(&si);    i = WinMainN(GetModuleHandle(NULL), NULL, pszCmdLine,        si.dwFlags & STARTF_USESHOWWINDOW ? si.wShowWindow : SW_SHOWDEFAULT);    ExitProcess(i);    return i;   // We never comes here.}//----------------------------------------------------------------------------// main() entry point to satisfy old NT screen saversvoid _cdecl main( int argc, char *argv[] ) {    DummyEntry();}//----------------------------------------------------------------------------// WinMain() entry point to satisfy old NT screen saversint PASCAL WinMain( HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int nCmdShow ) {    DummyEntry();    return 0;    // reference unreferenced parameters    (void)hInst;    (void)hPrev;    (void)szCmdLine;    (void)nCmdShow;}    

Thanks a lot Nathan, thats pretty much what I was hoping to hear. My plan and code structure it put together to support Win32, LInux and Beos. I was uncomfortable with having different starting points for different OS''s. (Each OS folder has a start.cpp, all except Win32 just have a main(). To make it more contrived this is in the ''common'' code area and thus to support the server and client I have to have a Winmain and Main function in this file and hope that that the project I select will pick the right one.

I asked this question due to seeing a Paul ''midnight'' Nettle''s terrain demo opengl app start just this way...

IN fact the reason I asked about this was that I was about to whip up a quick ''very first 3d engine'' then thought ugh! all that winproc shit again... I was about to design a WinMain.cpp, Winmain.h that just calls a main() function so to do gui stuff I''d just include these files and forget about all that other annoying stuff. This new stuff sounds interesting...

gimp
Chris Brodie

This topic is closed to new replies.

Advertisement