Hi all,

It turns out that some Win32 functions, such as AttachConsole(), are
only conditionally available, and depend on the values of specific
macros.

From
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winprog
/winprog/using_the_windows_headers.asp

"Certain functions that depend on a particular version of Windows are
declared using conditional code. This enables you to use the compiler to
detect whether your application uses functions that are not supported on
its target version(s) of Windows. To compile an application that uses
these functions, you must define the appropriate macros. Otherwise, you
will receive the C2065 error message."

This will be more of an issue when 64-bit Windows becomes more popular,
though I am even hitting it currently with some of the Win32Utils
extensions I've been working on.

Now, we could leave it up to individual extension authors to set this
themselves manually, but that's a pain, and error prone (it's easy to
forget, and some may not know to do it in the first place).  I thought
it would be nice if mkmf would set it for us.  So, I submit the
following patch for consideration:

--- mkmf.orig	Fri Dec 10 14:13:25 2004
+++ mkmf.rb	Fri Dec 10 14:54:46 2004
@@ -956,6 +956,58 @@
   mfile.close if mfile
 end
 
+def set_win32_macro
+   require "Win32API"
+
+   # We need to modify $CPPFLAGS based on the platform so that we can
see
+   # certain functions.
+
+   GetVersionEx = Win32API.new('kernel32','GetVersionEx','P','I')
+   swCSDVersion = "\0" * 128
+   OSVERSIONINFO = [148,0,0,0,0,swCSDVersion].pack("LLLLLa128")
+   GetVersionEx.call(OSVERSIONINFO)
+   info = OSVERSIONINFO.unpack("LLLLLa128")
+
+   major, minor = info[1,2]
+   platform = info[4]
+
+   # Default to NT
+   macro = "_WIN32_WINNT="
+
+   # Change if needed, or skip 
+   if platform == 1    # Windows 95, 98 and ME
+      macro = "_WIN32_WINDOWS="
+   elsif platform == 0 # Windows 3.51 or earlier
+      macro = nil
+   end
+
+   # Skipped if Windows 3.51 or earlier
+   if macro
+      case major
+         when 5
+            case minor
+               when 2   # 2003
+                  macro += "0x0502"
+               when 1   # XP
+                  macro += "0x0501"
+               else     # 2000
+                  macro += "0x0500"
+            end
+         when 4
+            case minor
+               when 0   # NT or 95
+                  macro += "0x0400"
+               when 90  # ME
+                  macro += "0x0500"
+               when 10  # 98
+                  macro += "0x0410"
+            end 
+      end
+
+      $CPPFLAGS += " -D#{macro}"
+   end
+end
+
 def init_mkmf(config = CONFIG)
   $enable_shared = config['ENABLE_SHARED'] == 'yes'
   $defs = []
@@ -982,6 +1034,10 @@
 
   $LOCAL_LIBS = ""
 
+  if File::ALT_SEPARATOR
+     set_win32_macro
+  end
+
   $cleanfiles = []
   $distcleanfiles = []
 

I realize that there are times when authors may still need to set
$CPPFLAGS manually (see the example near the bottom of the link I've
provided), but I think it's reasonable to put the onus on the extension
developer in such uncommon situations.  A note in the README for Win32
could be added to point out this possibility.

Regards,

Dan