Win32API_Error class

Version 0.01, March 27, 2001

by Michael L. Semon (mlsemon@sega.net)

Purpose

The purpose of the Win32API_Error class is to provide basic declarations for the standard Win32 Error API functions. It has no public instance variables and does nothing behind the scenes to obscure the nature of the Win32 API.

The nice thing about using Win32API_Error is that you don't have to declare them in your code or debug the data types of the input and output parameters. Also, I've taken the time to glean the constants from header files as needed from the Microsoft Platform SDK. If you pass FORMAT_MESSAGE_ALLOCATE_BUFFER to a function that will accept it, you will be passing the correct value.

The bare-bones nature of Win32API_Error is good if you're used to calling API functions from C or Visual Basic. It may be not so good if you're used to using objects that take care of the background details for you. Feel free to inherit this class and make such an object.

Usage

To use the class Win32API_Error:

require 'Win32API_Error'

To use the constants that are useful while programming Win32API_Console:

include Win32API_Error_Const

I have not decided on whether to include the error constants from Winerror.h in the Microsoft Platform SDK. It would make me uneasy to include 1495 lines of paraphrased Microsoft information, all for the effect of slowing a program and wasting memory with lots of wasted constants. If you wish to make your own constants from Winerror.h, here's the script I used for internal testing:

errFile = File.open( "Winerror.h", "r" )
    errFile.each_line do |errLine|
        if errLine =~ /\s*#define\s+(\w+)\s+(\d+)L.*/
            puts "#{$1} = #{$2}"
        end
    end
errFile.close()

Documentation

There are notes for most of the functions, but these notes are specific either to Ruby or my way of calling the functions. I recommend that you download the Microsoft Platform SDK to learn about the Windows API functions. As an alternative, you can browse the SDK at msdn.microsoft.com.

Limitations and Potential Bugs

I have access only to Windows 98 SE and Windows Millennium Edition, so I have not tested features specific to Windows NT and Windows 2000. Fortunately, there are hardly any security structures in this module, so it shouldn't be much of a problem.

I have been programming Ruby since March 16--eleven days when I started this module--so I'm limited as to what I can do with the language.

The current implementation creates a Win32API object for each function that you call, caching the object in class variables on an as-needed basis. Everything should be okay, but let me know if anything is broken.

Thank you for your patience.

To Do

I haven't decided whether to include examples with each function. Suggestions and interesting snippets of code are welcome.

Methods

Beep

Usage

obj.Beep( dwFreq, dwDuration )

Notes

As stated in the SDK, this means "play the default system WAV file" on Win9x.

FatalAppExit

Usage

obj.FatalAppExit( uAction, lpMessageText )

Notes

This function needs a non-DOS context (new console made by AllocConsole, GUI window, etc.) to show a message box. Otherwise, it will kill the program without displaying a message box.

FlashWindow

Usage

obj.FlashWindow( hWnd, bInvert )

Notes

None.

FlashWindowEx

Usage

obj.FlashWindowEx( pfwi )

Notes

Pack pfwi like [cbSize, hwnd, dwFlags, uCount, dwTimeout].pack("LLLLL"). Set the cbSize part of that to 20: The function doesn't seem to accept any other number. For whatever reason, I can't get dwTimeout to take effect on my Win98 PC.

FormatMessage

Usage

nTCharsWritten = obj.FormatMessage( dwFlags, lpSource, dwMessageId, dwLanguageId, lpBuffer, nSize, va_list )

Notes

Yikes. It's like somebody decided that perror() was too easy to use for a C function and made a truly twisted version of it. I tested this function with va_list set to nil. Let me know if you know how to pack the va_list argument. I looked over stdarg.h in cygwin, and I have no idea of how to do it.

I stumbled upon the error ERROR_RPL_NOT_ALLOWED (4006) as I was testing the function:

Replication with a non-configured partner is not allowed.

I had to chuckle a bit.

GetLastError

Usage

nError = obj.GetLastError()

Notes

None.

MessageBeep

Usage

obj.MessageBeep( uType )

Notes

None.

SetErrorMode

Usage

uOldMode = obj.SetErrorMode( uMode )

Notes

None.

SetLastError

Usage

obj.SetLastError( dwErrCode )

Notes

None.

SetLastErrorEx

Usage

obj.SetLastErrorEx( dwErrCode, dwErrType )

Notes

None.