Class: Windows::API
- Inherits:
-
Object
- Object
- Windows::API
- Defined in:
- lib/windows/api.rb
Defined Under Namespace
Classes: Error
Constant Summary collapse
- VERSION =
'0.2.2'
Instance Attribute Summary collapse
-
#dll_name ⇒ Object
readonly
Returns the value of attribute dll_name.
-
#function_name ⇒ Object
readonly
Returns the value of attribute function_name.
-
#prototype ⇒ Object
readonly
Returns the value of attribute prototype.
-
#return_type ⇒ Object
readonly
Returns the value of attribute return_type.
Class Method Summary collapse
-
.auto_constant ⇒ Object
Returns the value of the @auto_constant class instance variable.
-
.auto_constant=(bool) ⇒ Object
Automatically sets a constant to match the function name.
-
.auto_method ⇒ Object
Returns the value of the auto_method class instance variable.
-
.auto_method=(bool) ⇒ Object
If this option is set to true then a corresponding method is automatically generated when you create a new Windows::API object.
-
.auto_namespace ⇒ Object
Returns the value of the auto_namespace class instance variable.
-
.auto_namespace=(namespace) ⇒ Object
Sets the value of the auto_namespace class nstance variable.
-
.auto_unicode ⇒ Object
Returns the value of the auto_unicode class instance variable.
-
.auto_unicode=(bool) ⇒ Object
If set to true, and the auto_constant variable is set, then the automatic constant generation will generate the explicit ANSI (‘A’) and Unicode/wide (‘W’) versions of the function passed to the constructor, if such versions exist.
Instance Method Summary collapse
-
#call(*args) ⇒ Object
Calls the function name set in the constructor.
-
#initialize(func, proto = 'V', rtype = 'L', dll = 'kernel32') ⇒ API
constructor
call-seq: API.new(func, proto=‘V’, rtype=‘L’, dll=‘kernel32’).
Constructor Details
#initialize(func, proto = 'V', rtype = 'L', dll = 'kernel32') ⇒ API
call-seq:
API.new(func, proto='V', rtype='L', dll='kernel32')
Creates and returns a new Windows::API object. The func is the name of the Windows function.
The proto is the function prototype for func. This can be a string or an array of characters. The possible valid characters are ‘I’ (integer), ‘B’ (BOOL), ‘L’ (long), ‘V’ (void), or ‘P’ (pointer). The default is void (‘V’).
The rtype argument is the return type for the function. The valid characters are the same as for the proto. The default is long (‘L’).
The ‘B’ (BOOL) return type is the same as ‘I’ (Integer). This is significant only if the API.auto_method option is set to true, in which case it alters the generated method definition slightly. See the API.auto_method= class method for more information.
The dll is the name of the DLL file that the function is exported from. The default is ‘kernel32’.
If the function cannot be found then an API::Error is raised (a subclass of RuntimeError).
308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 |
# File 'lib/windows/api.rb', line 308 def initialize(func, proto='V', rtype='L', dll='kernel32') # Convert literal data types to values that win32-api understands if proto.is_a?(Array) proto.each_with_index{ |pt, index| if pt.length > 1 proto[index].replace(DATA_TYPES[pt]) end } end if rtype.length > 1 rtype.replace(DATA_TYPES[rtype]) end @function_name = func @prototype = proto @return_type = rtype == 'B' ? 'I' : rtype @dll_name = dll @boolean = rtype == 'B' ? true : false begin @api = Win32::API.new(func, proto, rtype, dll) rescue RuntimeError => err raise Error, err end api_a = nil api_w = nil # If the auto_unicode option is set, and the func is not already # an explicit ANSI or Unicode function name, generate Win32::API # objects for those functions as well. Ignore errors because not # all functions have explicit ANSI or Unicode equivalents. # if Windows::API.auto_unicode begin if func[-1].chr != 'A' api_a = Win32::API.new("#{func}A", proto, rtype, dll) end rescue RuntimeError end begin if func[-1].chr != 'W' api_w = Win32::API.new("#{func}W", proto, rtype, dll) end rescue RuntimeError end end # Automatically define a constant matching the function name if the # auto_constant option is set. # if Windows::API.auto_constant && Windows::API.auto_namespace if Windows::API.auto_namespace != 'Windows' namespace = class_for(Windows::API.auto_namespace) else namespace = Windows::API.auto_namespace end namespace.const_set(func, @api) # Automatically define the explicit ANSI and Unicode functions # as constants as well, if appropriate. # if Windows::API.auto_unicode namespace.const_set("#{func}A", api_a) if api_a namespace.const_set("#{func}W", api_w) if api_w end end # Automatically define a method in the auto_namespace if the # auto_method option is set. The explicit ANSI and Unicode methods # are added as well if the auto_unicode option is set to true. # if Windows::API.auto_method && Windows::API.auto_namespace if proto == 'V' proto = '' else n = 0 if proto.is_a?(String) proto = proto.split('').map{ |e| n += 1 e.downcase + n.to_s }.join(', ') else proto = proto.map{ |e| n += 1 e.downcase + n.to_s }.join(', ') end end if @boolean string = <<-EOC module #{Windows::API.auto_namespace} def #{func}(#{proto}) #{func}.call(#{proto}) != 0 end EOC if api_a string << %Q{ def #{func}A(#{proto}) #{func}A.call(#{proto}) != 0 end } end if api_w string << %Q{ def #{func}W(#{proto}) #{func}W.call(#{proto}) != 0 end } end string << 'end' else string = <<-EOC module #{Windows::API.auto_namespace} def #{func}(#{proto}) #{func}.call(#{proto}) end EOC if api_a string << %Q{ def #{func}A(#{proto}) #{func}A.call(#{proto}) end } end if api_w string << %Q{ def #{func}W(#{proto}) #{func}W.call(#{proto}) end } end string << 'end' end eval(string) end end |
Instance Attribute Details
#dll_name ⇒ Object (readonly)
Returns the value of attribute dll_name.
279 280 281 |
# File 'lib/windows/api.rb', line 279 def dll_name @dll_name end |
#function_name ⇒ Object (readonly)
Returns the value of attribute function_name.
278 279 280 |
# File 'lib/windows/api.rb', line 278 def function_name @function_name end |
#prototype ⇒ Object (readonly)
Returns the value of attribute prototype.
280 281 282 |
# File 'lib/windows/api.rb', line 280 def prototype @prototype end |
#return_type ⇒ Object (readonly)
Returns the value of attribute return_type.
281 282 283 |
# File 'lib/windows/api.rb', line 281 def return_type @return_type end |
Class Method Details
.auto_constant ⇒ Object
Returns the value of the @auto_constant class instance variable. The default is nil, i.e. none. See the Windows::API.auto_constant= documentation for more information.
123 124 125 |
# File 'lib/windows/api.rb', line 123 def self.auto_constant @auto_constant end |
.auto_constant=(bool) ⇒ Object
Automatically sets a constant to match the function name.
The standard practice for defining Windows::API objects is to use a constant that matches the function name. For example, this is a typical idiom:
module Windows
module File
GetFileAttributes = API.new('GetFileAttributes', 'P','L')
end
end
With the API.auto_constant value set to true you can avoid the assignment step and the matching constant name will be automatically set for you in the namespace defined in API.auto_namespace. In other words, this example is identical to the one above:
module Windows
module File
API.auto_constant = true
API.auto_namespace = 'Windows::File'
API.new('GetFileAttributes', 'P', 'L')
end
end
If the auto_constant class variable is set to true, but no auto_namespace is set, an error will be raised. Note that the namespace must refer to an existing module (not a class). – TODO: If there’s a way to automatically grab the namespace internally, nesting and all, I’d love to know the solution.
159 160 161 |
# File 'lib/windows/api.rb', line 159 def self.auto_constant=(bool) @auto_constant = bool end |
.auto_method ⇒ Object
Returns the value of the auto_method class instance variable. Used in conjunction with auto_unicode. See API.auto_method= for more information.
186 187 188 |
# File 'lib/windows/api.rb', line 186 def self.auto_method @auto_method end |
.auto_method=(bool) ⇒ Object
If this option is set to true then a corresponding method is automatically generated when you create a new Windows::API object.
For example, instead of doing this:
module Windows
module File
GetFileAttributes = API.new('GetFileAttributes', 'P', 'L')
def GetFileAttributes(x)
GetFileAttributes.call(x)
end
end
end
You can do this, and have the method autogenerated for you.
module Windows
module File
API.auto_namespace = 'Windows::File'
API.auto_constant = true
API.auto_method = true
GetFileAttributes = API.new('GetFileAttributes', 'P', 'L')
end
end
If the Windows::API object is declared to be a boolean in the constructor, then the method definition automatically includes a ‘!= 0’ clause at the end of the call. That way, you can do ‘if SomeMethod(x)’ instead of having to do ‘if SomeMethod(x) != 0’, and it will do the right thing.
If the API.auto_unicode option is also set to true, then you will get three method definitions. The standard function name, the explicit ANSI (‘A’) version and the explicit Unicode/wide version (‘W’). The exception to this rule is that the explicit ANSI and Unicode methods will NOT be generated if the function passed to the constructor already ends with ‘A’ or ‘W’.
229 230 231 |
# File 'lib/windows/api.rb', line 229 def self.auto_method=(bool) @auto_method = bool end |
.auto_namespace ⇒ Object
Returns the value of the auto_namespace class instance variable. Used in conjunction with API.auto_constant and/or API.auto_method.
166 167 168 |
# File 'lib/windows/api.rb', line 166 def self.auto_namespace @auto_namespace end |
.auto_namespace=(namespace) ⇒ Object
Sets the value of the auto_namespace class nstance variable. The default is nil, i.e. none. Use in conjunction with the auto_constant and/or auto_method class variables, this method will automatically set a constant and/or method in namespace equal to the function name set in the constructor.
The namespace must refer to an existing module, not a class.
178 179 180 |
# File 'lib/windows/api.rb', line 178 def self.auto_namespace=(namespace) @auto_namespace = namespace end |
.auto_unicode ⇒ Object
Returns the value of the auto_unicode class instance variable. This is used in conjunction with the auto_method and/or auto_constant class variables. Not significant if neither of those variables are set.
237 238 239 |
# File 'lib/windows/api.rb', line 237 def self.auto_unicode @auto_unicode end |
.auto_unicode=(bool) ⇒ Object
If set to true, and the auto_constant variable is set, then the automatic constant generation will generate the explicit ANSI (‘A’) and Unicode/wide (‘W’) versions of the function passed to the constructor, if such versions exist. Likewise, if the the auto_method variable is set, then explicit ANSI and Unicode methods are generated.
Here’s a typical idiom:
module Windows
module Path
API.auto_namespace = Windows::Path
API.auto_constant = true
API.new('shlwapi', 'PathAddBackslash', 'P', 'P')
API.new('shlwapi', 'PathAddBackslashA', 'P', 'P')
API.new('shlwapi', 'PathAddBackslashW', 'P', 'P')
end
end
That can be reduced to this:
module Windows
module Path
API.auto_namespace = Windows::Path
API.auto_constant = true
API.auto_unicode = true
API.new('shlwapi', 'PathAddBackslash', 'P', 'P')
end
end
This value is ignored if the function passed to the constructor already ends with an ‘A’ or ‘W’.
274 275 276 |
# File 'lib/windows/api.rb', line 274 def self.auto_unicode=(bool) @auto_unicode = bool end |
Instance Method Details
#call(*args) ⇒ Object
Calls the function name set in the constructor.
459 460 461 |
# File 'lib/windows/api.rb', line 459 def call(*args) @api.call(*args) end |