= win_gui
    by: Arvicco
    url: http://github.com/arvicco/win_gui

== DESCRIPTION:

Welcome to WinGui!

WinGui is a module that provides convenient wrapper methods for multiple Win32 API
functions (mostly from user32.dll) dealing with Windows GUI manipulation/automation.
In addition to straightforward API wrappers, it also defines more Ruby-like
abstractions and convenience methods for manipulating windows and other GUI 
elements (such as WinGui::Window class and its methods).

It is still work in progress, only a small number of user32 API functions wrapped so far...

== SUMMARY

So you want to write a simple program that makes some Win32 API function calls.
You searched MSDN high and low and you now know exactly what functions you need.
All you want is just putting those function calls into your Ruby code without too
much pain. You'd love this to be more or less natural extension of your Ruby code,
preferably not turning your code base into an ugly C++ like spaghetty
of CamelCase calls, String/Array pack/unpack gymnastics, buffer allocations,
extracting return values from [in/out] parameters and checking return codes for 0.

You can definitely use excellent 'win32-api' gem by Daniel J. Berger and Park Heesob
that allows you to define Win32 API objects for any function you can find on MSDN,
execute calls on them and even define callback objects that some of those API functions expect.

However, that gem will only take you so far. You'll still have to handle (somewhat)
gory details of argument preparation, mimicking pointers with Strings and stuff.
For example, consider the amount of code needed to complete a task as simple as
getting unicode title text for the window that you already have handle for:

  api = Win32::API.new( 'GetWindowTextW', ['L', 'P', 'I'], 'L', 'user32' )
  buffer = "\x00" * 1024  # I just hope it will be enough...
  num_chars = api.call( window_handle, buffer, buffer.size)
  title = if num_chars == 0
    nil                   
  else
     buffer.force_encoding('utf-16LE').encode('utf-8').rstrip
  end

Ew, ugly. What about getting information about process id for a known window?

  api = Win32::API.new( 'GetWindowThreadProcessId', ['L', 'P'], 'L' , 'user32' )
    process_packed = [1].pack('L')
    thread = api.call(window_handle, process_packed)
    process = process_packed.unpack('L').first

Wow, packing and unpacking arrays into String to get hold of a simple integer id.
Just great. Now, wouldn't it be MUCH better if you can just say something like this:

  title = window_text( window_handle)
  thread, process = window_thread_process_id( window_handle)

What about API functions expecting callbacks? Well, something like this may be nice:

  enum_child_windows( parent_handle, message ){|child_handle, message| puts child_handle }

If you think about it, callbacks are not much more than code blocks, so let's not be afraid
to treat them as such. It would be also good if test functions return true/false instead of
zero/nonzero, find functions return nil if nothing was found etc...

So this is an idea behind WinGui library - make Win32 API functions more fun to use
and feel more natural inside Ruby code. Following the principle of least surprise, we
define methods with Rubyesque names (minimized? instead of IsMinimized, etc), minimum
arguments with sensible defaults, explicit return values and generous use of attached blocks.

Well, we even keep a backup solution for those diehard Win32 API longtimers who would rather
allocate their buffer strings by hand and mess with obscure return codes. If you use original
CamelCase method name instead of Rubyesque snake_case one, it will expect those standard
parameters you know and love from MSDN, return your zeroes instead of nils and support no
other enhancements.

And if you do not see your favorite Windows API function amoung those already defined, it is
quite easy to define new one with def_api class method that does a lot of heavy lifting for
you and can be customized with options and code blocks to give you reusable API wrapper method
with the exact behavior you need.

== DOCUMENTATION:

See WinGui and WinGui::Window for documentation

== REQUIREMENTS:

Only works with Ruby 1.9.1+ since it uses some of the most recent features (block
arguments given to block, etc...)

== FEATURES/PROBLEMS:

This project is quite new, so it may be not suitable for production-quality systems yet.
Contributors always welcome!

== INSTALL:

  $ sudo gem install win_gui

== SYNOPSIS:

  require 'win_gui'
  include WinGui

More examples will follow when the code is closer to production quality...  

== CREDITS:

This library started as an extension of ideas and code described in excellent book
"Scripted GUI Testing with Ruby" by Ian Dees.

== Note on Patches/Pull Requests

* Fork the project.
* Make your feature addition or bug fix.
* Add tests for it. This is important so I don't break it in a
  future version unintentionally.
* Commit, do not mess with rakefile, version, or history.
  (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
* Send me a pull request. Bonus points for topic branches.

== LICENSE:

Copyright (c) 2009 Arvicco. See LICENSE for details