Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I write a Windows application without using WinMain?

Windows GUI applications written in C/C++ have 'WinMain' as an entry point (rather than 'main'). My understanding of this is that the compiler generates a 'main' function to be called by the C Runtime. This 'main' function sets up the necessary environment for the GUI and calls into 'WinMain' (specifying the instance handles etc.).

In short, I believe console and GUI application startup to differ in the following way:

Console application: C Runtime --> 'main' function (hand-coded)

GUI application: C Runtime --> 'main' function (compiler-generated) --> 'WinMain' function (hand-coded)

I would like to both validate this understanding and find out how I can hand-code a Windows GUI with just a 'main' function (i.e. without having to write 'WinMain').

like image 594
Matthew Murdoch Avatar asked Feb 19 '09 09:02

Matthew Murdoch


People also ask

How can I get hInstance without WinMain?

You can use GetModuleHandle(0); to get the programs hInstance . Just passing 0 as the hInstance parameter worked for me. Passing 0 retrieves the handle of the calling process, not the calling module. If the library/framework is implemented as a DLL, you would end up with the wrong handle.

Should I use WinMain or wWinMain?

The WinMain function is identical to wWinMain, except the command-line arguments are passed as an ANSI string. The Unicode version is preferred. You can use the ANSI WinMain function even if you compile your program as Unicode. To get a Unicode copy of the command-line arguments, call the GetCommandLine function.

How do you make Windows in C++?

To create a Windows desktop project in Visual StudioFrom the main menu, choose File > New > Project to open the Create a New Project dialog box. At the top of the dialog, set Language to C++, set Platform to Windows, and set Project type to Desktop.

How is WinMain called?

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


2 Answers

You have an incorrect understanding. The difference between main and WinMain, apart from some differet initialization code, is the parameters passed to it.

main looks like this:

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

While WinMain looks like this:

int WINAPI WinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    int nCmdShow
);

Something has to setup those parameters and make the call, and that's the startup code. When you compile and link a program, one of the linker parameters is the entry point, and that will be, depending on a console or GUI app, a different bit of startup code.

You can certainly write your own startup code, just go into your visual c++ source directory and you can find the startup code, it's called crt0.c and it's in the VC\crt\src directory.

like image 88
Erik Funkenbusch Avatar answered Sep 23 '22 04:09

Erik Funkenbusch


With Just main, you can not code Winmain. For justifications, Following statements were taken from http://blogs.msdn.com/oldnewthing/archive/2007/12/03/6644060.aspx

[In Windows Programming,] Why wasn't the application entry point called main? Well, for one thing, the name main was already taken, and Windows didn't have the authority to reserve an alternate definition. There was no C language standardization committee back then; C was what Dennis said it was, and it was hardly guaranteed that Dennis would take any special steps to preserve Windows source code compatibility in any future version of the C language. Since K&R didn't specify that implementations could extend the acceptable forms of the main function, it was entirely possible that there was a legal C compiler that rejected programs that declared main incorrectly. The current C language standard explicitly permits implementation-specific alternate definitions for main, but requiring all compilers to support this new Windows-specific version in order to compile Windows programs would gratuitously restrict the set of compilers you could use for writing Windows programs.

If you managed to overcome that obstacle, you'd have the problem that the Windows version of main would have to be something like this:

int main(int argc, char *argv[], HINSTANCE hinst,
         HINSTANCE hinstPrev, int nCmdShow);

Due to the way C linkage was performed, all variations of a function had to agree on the parameters they had in common. This means that the Windows version would have to add its parameters onto the end of the longest existing version of main, and then you'd have to cross your fingers and hope that the C language never added another alternate version of main. If you went this route, your crossed fingers failed you, because it turns out that a third parameter was added to main some time later, and it conflicted with your Windows-friendly version.

Suppose you managed to convince Dennis not to allow that three-parameter version of main. You still have to come up with those first two parameters, which means that every program's startup code needs to contain a command line parser. Back in the 16-bit days, people scrimped to save every byte. Telling them, "Oh, and all your programs are going to be 2KB bigger" probably wouldn't make you a lot of friends. I mean, that's four sectors of I/O off a floppy disk!

But probably the reason why the Windows entry point was given a different name is to emphasize that it's a different execution environment. If it were called main, people would take C programs designed for a console environment, throw them into their Windows compiler, and then run them, with disastrous results.

Hope this clears your doubts.

like image 37
lakshmanaraj Avatar answered Sep 22 '22 04:09

lakshmanaraj