I am sorry, I think my description was a little bit confusing. I want to create Aliases which I can use in my whole program so that I don't have always to check which API I need when I want to create a window.

I want to realize that when I say:

invoke CreateWindow, ...

CreateWindowA is invoked in Win9x, CreateWindowW in WinNT.

I know how to check the OS, I just don't know how to set these aliases.
I hope somebody can help me.

Quite a while ago, I remember a thread which discussed something very much like what you have described. The thread discussed modifying the jump table that MASM creates to handle calling procedures.

When the source code is assembled, you would have a default CreateWindow procedure which could be either the ANSI 'A', version or the Unicode 'W' version, this would be decided by you, the programmer. When the source is assembled, MASM creates a jump table with the CreateWindow procedure--as well as all the others you use/define--with the address of the address of the actual function. In the process of running your code, when you get to a procedure call, control is passed to an address in the jump table, which is a jump to another address. It is this address which can be changed at run time to cause your program to execute one routine when in an ANSI environment, and another routine when in a Unicode environment.

With this process, you would determine--at runtime initialization--which environment you are in, and modify the jump table once. Then each time the procedure is called, the appropriate routine will be called without any additional checking.

I've described this as if I really know what I'm talking about, but I don't! So, hopefully some one with more knowledge will be able to comment on and/or verify what I've just said.

This could also be used to run one routine for an MMX machine, and another on an SSE2 machine.? All with the same source and executable.

EliCZ has some includes for UNICODE support. Oddly, I can't find it on his web site. Maybe he includes it with other sources, or email him - he had the same problem you are experiencing.

Unicode is better imho because the Windows API uses it natively - ASCII API's are converted to Unicode. Unfortunately, it is not supported by MASM directly. GoASM does support Unicode to a greater degree.

The important bits are located in:
http://www.anticracking.sk/EliCZ/export/DrvSkel.zip

.\Common\APImacro.mac

You'll also have to create new includes for the API, and use a different Windows.inc, iirc. I have the full package on another drive - might be the one setting on my desk or the one that crashed...I also have it on CD.

I will find it because it sounds like exactly what you want. Many x86'ers decided Unicode was a waste of time and few have moved forward with it. There are some obsticals, but having a larger native audience is very important.

You are likely to find that about 1% of win9x boxes have the unicode layer added to them so you are basically stuck with handling both ANSI and unicode string data. The approach to take is OS version detection and switch to the code that suits either ANSI or UNICODE.

The includes in MASM32 are either ANSI with an equate after them or UNICODE which still retains the trailing "W" API name. You can store UNICODE string in resource files and obtain tem for use with an API call, with a bit of trickery you can use a macro to most literal strings in the data section and if you need to you can convert ANSI to UNICODE with an API call so there is probably a way to avoid complete string duplication in your code.

You are likely to find that about 1% of win9x boxes have the unicode layer added to them so you are basically stuck with handling both ANSI and unicode string data. The approach to take is OS version detection and switch to the code that suits either ANSI or UNICODE.

Isn't that exactly what I said I wanted to do?
My only problem is that I don't know how to switch between the APIs cleverly. What I want is that I check the OS at the start (I know how to do this part), then to set an Alias called "CreateWindow" referring either to "CreateWindowW" or to "CreateWindowA", so that I can say in the whole rest of the program simply "CreateWindow" and the right API is taken. I could create stuff like a single PROC for each API switching it, I just hope there is a more performant solution, just exchanging the pointers.

What I meant by 'different arguments' is that you need to pass Unicode strings to W functions and multi-byte strings to A functions. If you want to switch them at run-time, you could:

I could create stuff like a single PROC for each API switching it, I just hope there is a more performant solution, just exchanging the pointers.

You'd also need to convert the string arguments*. But this is a very bad idea, isn't it?

You are likely to find that about 1% of win9x boxes have the unicode layer added to them so you are basically stuck with handling both ANSI and unicode string data. The approach to take is OS version detection and switch to the code that suits either ANSI or UNICODE.

How about installing it yourself with your application or telling the user to install it.

The idea of having two versions of your software is appalling, IMHO.

* And returned strings, and another procedure for each callback procedure receiving/returning strings, etc.

But, as already mentioned, you will have to modify all string parameters as well.

Hi, this does not work out, as _imp_CreateWindowExW@48 does not exist (I am using MASM32).

Therefore, the link to the tutorial postet by jorgon does not work out for me.

I think I found the best solution for me, as I can get the pointer to the API, but I can't change it.
Still, I can do the push/call-Job. Just an example how it works out with a MessageBox (not so many arguments):

As implied by others, the above code won't work on both systems, as is. You will need to initialize every szText "constant" with the appropriate character code version.

MessageBoxW requires Unicode strings containing 16-bit (double byte) characters. It will not take UTF-8 (which is compatible with 8-bit ANSI), it will only do Unicode-16L (16-bit little-endian). You will get garbage characters (or a lot of missing ones) when displaying with the W version. If you convert all your strings to Unicode, then the A version will display only the first character because the second byte will be the end-of-string byte, 0.

thanks, I know that, I just wanted to show how I switched between the APIs.
In my real program I am going to write, of course this is solved in the proper way with a ANSI-String and a UNICODE-String, using some cool characters ;-D.

The only viable solution for the string data that saves massive duplication is to use resource strings that are ALWAYS stored as UNICODE. These can then be accessed by either ANSI or UNICODE version of the API LoadString().

The mess you are then left with is what is the most efficient way to write the dual code forms. Going through the entire code with .IF blocks for each API that is either ANSI or UNICODE would be very messy to code and very inefficient in size terms.

What may be worth a look is writing ANSI, UNICODE and common code as three blocks and switcing to the appropriate block at startup depending on the OS version.

hutch-- said what I wanted to say much better than I did (I didn't even know what to call it). The Unicode vs. ANSI is a good example of why we could use an example of modifying the IAT. What I envisioned when I originally read the previous thread, was a DLL which could be loaded at startup which could determine the environment and equpment, and modify the program to call the appropriate procedures, then unload the DLL. I think because of the problem "death" described, we might have to create procedures of our own, one each for each API or hardware reality we have to account for, and then use this as a wrapper to execute the appropriate code.

For example:

ANSI vs. Unicode
FPU vs. MMX
9x vs. NT
NT vs. XP
...

japheth tried to provide some code but I haven't seen a real program that does what we have discussed. I'm gonna play with it some, but if someone has a working example, please share :)