I'm trying to build a console app with Unicode support. I'm using VS.NET, and Unicode is enabled in the project settings. Param parsing doesn't work right, and I'm trying to isolate the problem by having it parrot my params back to me. If I reduce the main function to this:
I am almost 100% sure that Windows will always pass the program parameters as ANSI strings, and never as UNICODE strings. Why? Not sure, but I would dare say backwards compatibility.
Strange but true, even with UNICODE defined, and even with that silly main(int, TCHAR**) nonsense that the Wizard generates, the arguments are ASCII.
Defining UNICODE only switches on calling UNICODE versions of system calls. So if you want UNICODE program args, you need to call GetCommandLine and parse the args yourself.
This worked as expected. So, why does the wizard generate main(int, TCHAR*) if it seems to completely break command line arguments? I don't understand why it would put TCHAR* if only char* works.
I'm guessing it's because theoretically there could be a command line that uses UNICODE instead of ASCII, so when it passes you parameters, they would be in UNICODE.
main(int, TCHAR**) is just plain wrong. The whole #define _UNICODE was an idea borne out of expediency. If M$ had enough time, they'd have done it better.
The problem was, after the OS/2 / NT code split, a whole bunch of features were piled into NT to make it defence compliant. The feature list of NT was impressive, right down to that POSIX interface they promised. And among these promises was Unicode support.
The Unicode support works well; really well in fact. The problem was moving the old Windows 3.1/3.11 and Windows for Workgroups developers from the old WIN16 ASCII platform to the new shiny WIN32 Unicode platform.
What they came up with was this crazy scheme where the API calls have W on the end for Unicode, A on the end for ASCII and a _UNICODE macro that maps one or the other to function names, with the ASCII versions being mapped onto Unicode versions in the interface libraries. This necessitated a whole bunch of common string types and function names that could be mapped too to pass the args over.
Who ever wrote the Visual Studio wizard missed the point and thought it applied to things other than the WIN32 API, it doesn't. It doesn't apply to startup code, or main, or any such thing, just API calls.