On Fri, Jun 20, 2008 at 16:05, Nicholas Calvert <nick.calvert / gmail.com> wrote:
> Thanks Jano. If you have a minute, do you think you could run through
> that code and explain what its doing? I am new to Ruby and a large
> portion of that went over my head :)

1. You'll find documentation for CoCreateGuid here:
http://msdn.microsoft.com/en-us/library/ms688568(VS.85).aspx
and for StringFromGUID2 here:
http://msdn.microsoft.com/en-us/library/ms683893(VS.85).aspx
(these are C functions from ole32.dll)

2. I call them using WIN32API, conveniently wrapped by windows-pr gem
from win32utils project.

### these are from windows-pr gem
require 'windows/com'
require 'windows/unicode'

### helper function to strip everything past the first NULL character.
Copied from some file in win32utils
class String
 # Return the portion of the string up to the first NULL character.  This
 # was added for both speed and convenience.
 def nstrip
   self[ /^[^\0]*/ ]
 end
end

class Guid

 BUFFER_SIZE = 100

 attr_reader :data

### two ways of using this class - 1. either provide GUID in binary
form Guid.new(data) or create a new one (Guid.new)
 def initialize(data = nil)  ### nil is default value for data parameter
   @data = data
   create if data.nil? ### if there's no data, call create
 end

### create new guid
 def create
   @data = 0.chr * 16  ### make empty buffer for the binary GUID "\0\0\0\0...\0"
   raise 'GUID Error' unless CoCreateGuid(@data) ### call the API. the
call will place the created GUID in @data.
 end

 ### convert binary guid to string representation
 def to_s
   ret = 0.chr * BUFFER_SIZE ### temporary buffer to place the string form
   i = StringFromGUID2(@data, ret, BUFFER_SIZE) ### call the API
### API returns zero-terminated wide string. this is the conversion to
ordinary ruby string.
### wide_to_multi is from windows/unicode
   wide_to_multi(ret[0..i*2]).nstrip
 end

private

### this code includes COM and Unicode modules into this class, so
that we can use them.
 include Windows::COM
 include Windows::Unicode

end

### this line is kind of idiom/guard
### it allows to specify code to be run when the file is run directly.
This code will not run
### if this file is required or included in another file. (script vs. library)
if File.expand_path(__FILE__) == File.expand_path($0)
 puts Guid.new.to_s
end

----

Ok, and now ask questions! ;-)
J.