Its impossible to help you with Win32API when you aren't even saying what exactly you are trying to do, or dll/library you are trying to do it with. The Ruby side of Win32API isn't really that difficult, but you do need to to know the library you are using in order to use it.
Here's an example from the MCI Audio Player script I wrote.
MCISendString = Win32API.new('winmm', 'mciSendString', 'PPLL', 'L')
First, we create an object to hold the Win32API instance. Convention is to use the same of the function you are creating a wrapper for, in this case it is MCISendString.
Next, we create the Win32API object, which takes 4 arguments.
- 1. The name of dll. This example uses a library found in System32 on all Windows systems, so I don't need a path or anything. If it was your own custom library, you need to include a path, or simply place the dll in the game's main directory. The dll I am getting a function from is "winmm"
- 2. This the name of the function you are getting. You have to know what functions are in the library for this. If its your own custom-made dll, then you would know this. I know it because you can find the documentation for it on MSDN. This site is invaluable when using Windows API functions, and you will need it for the following 2 arguments as well.
- 3. This argument defines the argument types that will be passed to the function you are wrapping. I am sure if you looked at the Win32API documentation, then you saw the different "key" letters to use. For the most part, "p" is for pointer, which is most commonly used for objects and strings, "I" is for integer (a 4-byte number), "L" is for long (an 8-byte number). There are others, but those are the most common. If you look at the mciSendString documentation, we see that it takes 4 arguments.
MCIERROR mciSendString(
LPCTSTR lpszCommand,
LPTSTR lpszReturnString,
UINT cchReturn,
HANDLE hwndCallback
);
The first is the command to send to MCI, which is a string: "P"
The second is the string, or buffer that the function will write the the result of the function to: "P"
The third is the size of the buffer we are pointing to, in bytes: "I"
The fourth is the handle used for the callback. In this particular situation, we don't really need this. A handle is simply a number used to identify a window in Windows. Its simply an integer: "I"
- 4. this last argument for a Win32API object is similar to the last argument, but instead we are defining the type used for the return value. The documentation for mciSendString says this:
QuoteReturn value
Returns zero if successful or an error otherwise. The low-order word of the returned DWORD value contains the error return value. If the error is device-specific, the high-order word of the return value is the driver identifier; otherwise, the high-order word is zero. For a list of possible error values, see MCIERR Return Values.
The long and the short, it returns a number. If no error occurs, its 0, otherwise its the error code, which we would need to use "mciGetErrorString" to get the message for. The argument return type therefore is an integer: "I"
Okay, now we have constructed the wrapper for the function, which is stored in the Ruby constant "MCISendString". In order to use it, you have to use the "call" method, and pass it arguments that match the type you defined in the constructor.
From here, you would need to know the proper commands to send to the MCI, but that's not part of what you are trying to learn, so don't get hung up on that. I'll give two examples, the first is a simple call without needing to "get a value", and the second with one.
errorCode = MCISendString.call('close all', nil, 0, 0)
The first argument is a string which is the command.
The second argument is are buffer for the return value. Since we don't care about a return value, we can simply pass nil, and nothing will be written to.
The third argument is the size of the buffer, in our case 0, since we are not passing one.
The fourth is the handle. We don't care about that either in this example since it has no bearing. Other times you may need to pass this, which you can make a Win32API function and "GetWindowHandle" to get this value. We aren't worrying about it, so just say 0.
If everything went okay, errorCode should be equal to 0. If there was an error, it would now contain the MCI error code. Not all functions even return a value, which you would have defined the return type as "V" for void if that was the case.
Alright, now for another example that gets a string value from the method. Win32API cannot just simply return a string, just primitive types, and a Ruby string is an entirely different animal from a Windows string. What we do is create a place in memory for it to write data to, like this.
This creates an "empty" string that is 128 bytes.
To use it to get a value, you would do something like this:
MCISendString.call("status ALIASNAME volume", data, 128, 0)
The first argument is our command.
the second is the buffer we created. It will contain the value after the call. We are actually only sending a pointer to it, not the actual object, but you don't really need to worry about that.
The third argument is the size of the buffer. We made ours 128 bytes, so we pass that.
The fourth is the handle argument again, which we are disregarding and simply passing 0.
Now, after the call is made, "buffer" now contains the value of the volume, but it is also stilled padded with all the extra bytes we used. It is still 128 bytes, so we need to remove the extra empty bytes.
Now, if you read the value of "buffer", it will contain the value of the volume as a string. If you wanted to convert it to an integer for further processing, you could simply use "to_i" on it to convert.
This is a basic example using an existing and well-documented function, so as you can see, you need to be more specific if you wanted detailed help on a particular library. Feel free to ask any questions. I'm sick of typing, so I am gonna end it here.