Class WinWindow

  1. lib/win_window.rb
Parent: Object

WinWindow: A Ruby library to wrap windows API calls relating to hWnd window handles.

The WinWindow class represents a window, wrapping a hWnd and exposing a Ruby API corresponding to many useful Windows API functions relating to a hWnd.

Constants

All = Enumerator.new(WinWindow, :each_window)   Enumerable object that iterates over every available window

May raise a WinWindow::SystemError from WinWindow.each_window

Attributes

hwnd [R] handle to the window - a positive integer. (properly, this is a pointer, but we deal with it as a number.)

Public class methods

desktop_window ()

Returns a WinWindow representing the desktop window. The desktop window covers the entire screen. The desktop window is the area on top of which other windows are painted.

msdn.microsoft.com/en-us/library/ms633504%28VS.85%29.aspx

[show source]
# File lib/win_window.rb, line 1356
  def self.desktop_window
    hwnd=WinUser.GetDesktopWindow
    if hwnd == 0
      nil
    else
      self.new(hwnd)
    end
  end
each_window ( {|win_window| ...}

Iterates over every window yielding a WinWindow object.

use WinWindow::All if you want an Enumerable object.

Raises a WinWindow::SystemError if a System Error occurs.

msdn.microsoft.com/en-us/library/ms633497.aspx

For System Error Codes see msdn.microsoft.com/en-us/library/ms681381(VS.85).aspx

[show source]
# File lib/win_window.rb, line 1253
  def self.each_window # :yields: win_window
    enum_windows_callback= WinUser.window_enum_callback do |hwnd,lparam|
      yield WinWindow.new(hwnd)
      WIN_TRUE
    end
    begin
      ret=WinUser.EnumWindows(enum_windows_callback, nil)
    ensure
      WinUser.remove_window_enum_callback(enum_windows_callback)
    end
    if ret==WIN_FALSE
      system_error "EnumWindows"
    end
    nil
  end
find_all_by_text (text)

returns all WinWindow objects found whose text matches what is given

May raise a WinWindow::SystemError from WinWindow.each_window

[show source]
# File lib/win_window.rb, line 1286
  def self.find_all_by_text(text)
    WinWindow::All.select do |window|
      text===window.text # use triple-equals so regexps try to match, strings see if equal 
    end
  end
find_first_by_text (text)

returns the first window found whose text matches what is given

May raise a WinWindow::SystemError from WinWindow.each_window

[show source]
# File lib/win_window.rb, line 1277
  def self.find_first_by_text(text)
    WinWindow::All.detect do |window|
      text===window.text # use triple-equals so regexps try to match, strings see if equal 
    end
  end
find_only_by_text (text)

returns the only window matching the given text. raises a WinWindow::MatchError if more than one window matching given text is found, so that you can be sure you are returned the right one (because it’s the only one)

behavior is slightly more complex than that - if multiple windows match the given text, but are all in one heirarchy (all parents/children of each other), then this returns the highest one in the heirarchy.

if there are multiple windows with titles that match which are all in a parent/child relationship with each other, this will not error and will return the innermost child whose text matches.

May also raise a WinWindow::SystemError from WinWindow.each_window

[show source]
# File lib/win_window.rb, line 1305
  def self.find_only_by_text(text)
    matched=WinWindow::All.select do |window|
      text===window.text
    end
#    matched.reject! do |win|          # reject win where
#      matched.any? do |other_win|     # exists any other_win 
#        parent=other_win.parent
#        win_is_parent=false
#        while parent && !win_is_parent
#          win_is_parent ||= win==parent
#          parent=parent.parent
#        end
#        win_is_parent                  # such that win is parent of other_win
#      end
#    end
    matched.reject! do |win|           # reject any win where
      matched.any? do |other_win|      # any other_win
        parent=win.parent
        other_is_parent=false
        while parent && !other_is_parent
          other_is_parent ||= other_win==parent
          parent=parent.parent
        end
        other_is_parent                 # is its parent
      end
    end

    if matched.size != 1
      raise MatchError, "Found #{matched.size} windows matching #{text.inspect}; there should be one"
    else
      return matched.first
    end
  end
foreground_window ()

Returns a WinWindow representing the current foreground window (the window with which the user is currently working).

msdn.microsoft.com/en-us/library/ms633505%28VS.85%29.aspx

[show source]
# File lib/win_window.rb, line 1343
  def self.foreground_window
    hwnd=WinUser.GetForegroundWindow
    if hwnd == 0
      nil
    else
      self.new(hwnd)
    end
  end
lock_set_foreground_window ()

The foreground process can call the #lock_set_foreground_window function to disable calls to the #set_foreground! function.

Disables calls to #set_foreground!

msdn.microsoft.com/en-us/library/ms633532%28VS.85%29.aspx

[show source]
# File lib/win_window.rb, line 675
  def self.lock_set_foreground_window
    ret= WinUser.LockSetForegroundWindow(LSFW_LOCK)
    ret != WIN_FALSE # todo: raise system error? 
  end
new (hwnd)

creates a WinWindow from a given hWnd handle (integer)

raises ArgumentError if the hWnd is not an Integer greater than 0

[show source]
# File lib/win_window.rb, line 397
  def initialize(hwnd)
    raise ArgumentError, "hwnd must be an integer greater than 0; got #{hwnd.inspect} (#{hwnd.class})" unless hwnd.is_a?(Integer) && hwnd > 0
    @hwnd=hwnd
  end
unlock_set_foreground_window ()

The foreground process can call the #lock_set_foreground_window function to disable calls to the #set_foreground! function.

Enables calls to #set_foreground!

msdn.microsoft.com/en-us/library/ms633532%28VS.85%29.aspx

[show source]
# File lib/win_window.rb, line 685
  def self.unlock_set_foreground_window
    ret= WinUser.LockSetForegroundWindow(LSFW_UNLOCK)
    ret != WIN_FALSE # todo: raise system error? 
  end

Public instance methods

== (oth)

Alias for #eql?

ancestor_parent ()

Retrieves the parent window. This does not include the owner, as it does with #parent

msdn.microsoft.com/en-us/library/ms633502(VS.85).aspx

[show source]
# File lib/win_window.rb, line 494
  def ancestor_parent
    ret_hwnd=WinUser.GetAncestor(hwnd, GA_PARENT)
    @ancestor_parent= ret_hwnd > 0 ? self.class.new(ret_hwnd) : nil
  end
ancestor_root ()

Retrieves the root window by walking the chain of parent windows.

msdn.microsoft.com/en-us/library/ms633502(VS.85).aspx

[show source]
# File lib/win_window.rb, line 502
  def ancestor_root
    ret_hwnd=WinUser.GetAncestor(hwnd, GA_ROOT)
    @ancestor_root= ret_hwnd > 0 ? self.class.new(ret_hwnd) : nil
  end
ancestor_root_owner ()

Retrieves the owned root window by walking the chain of parent and owner windows returned by GetParent.

msdn.microsoft.com/en-us/library/ms633502(VS.85).aspx

[show source]
# File lib/win_window.rb, line 511
  def ancestor_root_owner
    ret_hwnd=WinUser.GetAncestor(hwnd, GA_ROOTOWNER)
    @ancestor_root_owner= ret_hwnd > 0 ? self.class.new(ret_hwnd) : nil
  end
bring_to_top! ()

brings the window to the top of the Z order. If the window is a top-level window, it is activated. If the window is a child window, the top-level parent window associated with the child window is activated.

msdn.microsoft.com/en-us/library/ms632673(VS.85).aspx

[show source]
# File lib/win_window.rb, line 738
  def bring_to_top!
    ret=WinUser.BringWindowToTop(hwnd)
    ret != WIN_FALSE
  end
capture_to_bmp_blob (options={})

captures this window to a bitmap image (a screenshot).

Returns the bitmap as represented by a blob (a string) of bitmap data, including the BITMAPFILEHEADER, BITMAPINFOHEADER, and data. This can be written directly to a file (though if you want that, #capture_to_bmp_file is probably what you want), or passed to ImageMagick, or whatever you like.

takes an options hash. see the documentation on #capture_to_bmp_structs for what options are accepted.

[show source]
# File lib/win_window.rb, line 1058
  def capture_to_bmp_blob(options={})
    capture_to_bmp_structs(options).map do |struct|
      if struct.is_a?(FFI::Pointer)
        ptr=struct
        size=ptr.size
      else
        ptr=struct.to_ptr
        size=struct.class.real_size
      end
      ptr.get_bytes(0, size)
    end.join("")
  end
capture_to_bmp_file (filename, options={})

captures this window to a bitmap image (a screenshot).

stores the bitmap to a filename specified in the first argument.

takes an options hash. see the documentation on #capture_to_bmp_structs for what options are accepted.

[show source]
# File lib/win_window.rb, line 1077
  def capture_to_bmp_file(filename, options={})
    File.open(filename, 'wb') do |file|
      file.write(capture_to_bmp_blob(options))
    end
  end
capture_to_bmp_structs (options={})

Creates a bitmap image of this window (a screenshot).

Returns the bitmap as represented by three FFI objects: a BITMAPFILEHEADER, a BITMAPINFOHEADER, and a pointer to actual bitmap data.

See also #capture_to_bmp_blob and #capture_to_bmp_file - probably more useful to the user than this method.

takes an options hash:

  • :dc => what device context to use
    • :client - captures the client area, which excludes window trimmings like title bar, resize bars, etc.
    • :window (default) - capturse the window area, including window trimmings.
  • :set_foreground => whether to try to set this to be the foreground
    • true - calls to #set_foreground!
    • false - doesn’t call to any functions to set this to be the foreground
    • :really (default) - calls to #really_set_foreground!. this is the default because really being in the foreground is rather important when taking a screenshot.
[show source]
# File lib/win_window.rb, line 968
  def capture_to_bmp_structs(options={})
    options=handle_options(options, :dc => :window, :set_foreground => :really)
    case options[:set_foreground]
    when :really
      really_set_foreground!
    when true
      set_foreground!
    when false,nil
    else
      raise ArgumentError, ":set_foreground option is invalid. expected values are :really, true, or false/nil. received #{options[:set_foreground]} (#{options[:set_foreground].class})"
    end
    if options[:set_foreground]
      # if setting foreground, sleep a tick - sometimes it still hasn't show up even when it is 
      # the foreground window; sometimes it's still only partway-drawn 
      sleep 0.2 
    end
    case options[:dc]
    when :client
      rect=self.client_rect
      dc=WinUser.GetDC(hwnd) || system_error("GetDC")
    when :window
      rect=self.window_rect
      dc=WinUser.GetWindowDC(hwnd) || system_error("GetWindowDC")
    else
      raise ArgumentError, ":dc option is invalid. expected values are :client or :window; received #{options[:dc]} (#{options[:dc].class})"
    end
    width=rect[:right]-rect[:left]
    height=rect[:bottom]-rect[:top]
    begin
      dc_mem = WinGDI.CreateCompatibleDC(dc) || system_error("CreateCompatibleDC")
      begin
        bmp = WinGDI.CreateCompatibleBitmap(dc, width, height) || system_error("CreateCompatibleBitmap")
        begin
          WinGDI.SelectObject(dc_mem, bmp) || system_error("SelectObject")
          WinGDI.BitBlt(dc_mem, 0, 0, width, height, dc, 0, 0, SRCCOPY) || system_error("BitBlt")
          
          bytes_per_pixel=3
          
          bmp_info=WinGDI::BITMAPINFOHEADER.new
          { :Size => WinGDI::BITMAPINFOHEADER.real_size, # 40
            :Width => width,
            :Height => height,
            :Planes => 1,
            :BitCount => bytes_per_pixel*8,
            :Compression => 0,
            :SizeImage => 0,
            :XPelsPerMeter => 0,
            :YPelsPerMeter => 0,
            :ClrUsed => 0,
            :ClrImportant => 0,
          }.each_pair do |key,val|
            bmp_info[key]=val
          end
          bmp_row_size=width*bytes_per_pixel
          bmp_row_size+=bmp_row_size%4 # row size must be a multiple of 4 (size of a dword)
          bmp_size=bmp_row_size*height
          
          bits=FFI::MemoryPointer.new(1, bmp_size)
          
          WinGDI.GetDIBits(dc_mem, bmp, 0, height, bits, bmp_info, DIB_RGB_COLORS) || system_error("GetDIBits")
          
          bmp_file_header=WinGDI::BITMAPFILEHEADER.new
          { :Type => 'BM'.unpack('S').first, # must be 'BM'
            :Size => WinGDI::BITMAPFILEHEADER.real_size + WinGDI::BITMAPINFOHEADER.real_size + bmp_size,
            :Reserved1 => 0,
            :Reserved2 => 0,
            :OffBits => WinGDI::BITMAPFILEHEADER.real_size + WinGDI::BITMAPINFOHEADER.real_size
          }.each_pair do |key,val|
            bmp_file_header[key]=val
          end
          return [bmp_file_header, bmp_info, bits]
        ensure
          WinGDI.DeleteObject(bmp)
        end
      ensure
        WinGDI.DeleteDC(dc_mem)
      end
    ensure
      WinUser.ReleaseDC(hwnd, dc)
    end
  end
child_button (button_text)

returns a WinWindow that is a child of this that matches the given button_text (Regexp or #to_s-able) or nil if no such child exists.

“&” is stripped when matching so don’t include it. String comparison is case-insensitive.

May raise a WinWindow::SystemError from #each_child

[show source]
# File lib/win_window.rb, line 1216
  def child_button(button_text)
    children.detect do |child|
      child.class_name=='Button' && button_text.is_a?(Regexp) ? child.text.tr('&', '') =~ button_text : child.text.tr('&', '').downcase==button_text.to_s.tr('&', '').downcase
    end
  end
child_control_with_preceding_label (preceding_label_text, options={})

Finds a child of this window which follows a label with the given text.

Options:

  • :control_class_name is the class name of the control you are looking for. Defaults to nil, which accepts any class name.
  • :label_class_name is the class name of the label preceding the control you are looking for. Defaults to ‘Static’
[show source]
# File lib/win_window.rb, line 1229
  def child_control_with_preceding_label(preceding_label_text, options={})
    options=handle_options(options, :control_class_name => nil, :label_class_name => "Static")
    
    prev_was_label=false
    control=self.children.detect do |child|
      ret=prev_was_label && (!options[:control_class_name] || child.class_name==options[:control_class_name])
      prev_was_label= child.class_name==options[:label_class_name] && preceding_label_text===child.text
      ret
    end
  end
child_of? (parent)

tests whether a window is a child window or descendant window of a specified parent window. A child window is the direct descendant of a specified parent window if that parent window is in the chain of parent windows; the chain of parent windows leads from the original overlapped or pop-up window to the child window.

msdn.microsoft.com/en-us/library/ms633524(VS.85).aspx

[show source]
# File lib/win_window.rb, line 556
  def child_of?(parent)
    parent_hwnd= parent.is_a?(self.class) ? parent.hwnd : parent
    child=WinUser.IsChild(parent_hwnd, hwnd)
    child!=WIN_FALSE
  end
children ()

returns an Enumerable object that can iterate over each child of this window, yielding a WinWindow object

may raise a WinWindow::SystemError from #each_child

[show source]
# File lib/win_window.rb, line 1135
  def children
    Enumerator.new(self, :each_child)
  end
children_recursive (options={})

returns an Enumerable object that can iterate over each child of this window recursively, yielding a WinWindow object for each child.

[show source]
# File lib/win_window.rb, line 1162
  def children_recursive(options={})
    Enumerator.new(self, :recurse_each_child, options)
  end
class_name ()

retrieves the name of the class to which this window belongs

msdn.microsoft.com/en-us/library/ms633582(VS.85).aspx

[show source]
# File lib/win_window.rb, line 576
  def class_name
    buff_size=256
    buff=" "*buff_size
    len=WinUser.GetClassNameA(hwnd, buff, buff_size)
    @class_name=buff.to_s[0...len]
  end
click! ()

tries to click on this Window (using PostMessage sending BM_CLICK message).

Clicking might not always work! Especially if the window is not focused (frontmost application). The BM_CLICK message might just be ignored, or maybe it will just focus the hwnd but not really click.

[show source]
# File lib/win_window.rb, line 910
  def click!
    WinUser.PostMessageA(hwnd, BM_CLICK, 0, nil)
  end
click_child_button_try_for! (button_text, time, options={}) {|| ...}

Give the name of a button, or a Regexp to match it (see #child_button). keeps clicking the button until the button no longer exists, or until the given block is true (ie, not false or nil)

Options:

  • :interval is the length of time in seconds between each attempt (default 0.05)
  • :set_foreground is whether the window should be activated first, since button-clicking is much more likely to fail if the window isn’t focused (default true)
  • :exception is the exception class or instance that will be raised if we can’t click the button (default nil, no exception is raised, the return value indicates success/failure)

Raises ArgumentError if invalid options are given. Raises a WinWindow::NotExistsError if the button doesn’t exist, or if this window doesn’t exist, or a WinWindow::SystemError if a System Error occurs (from #each_child)

[show source]
# File lib/win_window.rb, line 1194
  def click_child_button_try_for!(button_text, time, options={})
    options=handle_options(options, {:set_foreground => true, :exception => nil, :interval => 0.05})
    button=child_button(button_text) || (raise WinWindow::NotExistsError, "Button #{button_text.inspect} not found")
    waiter_options={}
    waiter_options[:condition]=proc{!button.exists? || (block_given? && yield)}
    waiter_options.merge!(options.reject{|k,v| ![:exception, :interval].include?(k)})
    Waiter.try_for(time, waiter_options) do
      if options[:set_foreground]
        show_normal!
        really_set_foreground!
      end
      button.click!
    end
    return waiter_options[:condition].call
  end
client_rect ()

Returns a Rect struct with members left, top, right, and bottom indicating the coordinates of a window’s client area. The client coordinates specify the upper-left and lower-right corners of the client area. Because client coordinates are relative to the upper-left corner of a window’s client area, the coordinates of the upper-left corner are (0,0).

msdn.microsoft.com/en-us/library/ms633503%28VS.85%29.aspx

[show source]
# File lib/win_window.rb, line 934
  def client_rect
    rect=WinUser::Rect.new
    ret=WinUser.GetClientRect(hwnd, rect)
    if ret==WIN_FALSE
      self.class.system_error "GetClientRect"
    else
      rect
    end
  end
close! ()

minimizes this window (but does not destroy it) (why is it called close? I don’t know)

msdn.microsoft.com/en-us/library/ms632678(VS.85).aspx

[show source]
# File lib/win_window.rb, line 747
  def close!
    ret=WinUser.CloseWindow(hwnd)
    ret != WIN_FALSE
  end
destroy! ()

destroy! destroys the window. #destroy! sends WM_DESTROY and WM_NCDESTROY messages to the window to deactivate it and remove the keyboard focus from it. #destroy! also destroys the window’s menu, flushes the thread message queue, destroys timers, removes clipboard ownership, and breaks the clipboard viewer chain (if the window is at the top of the viewer chain).

If the specified window is a parent or owner window, #destroy! automatically destroys the associated child or owned windows when it destroys the parent or owner window. #destroy! first destroys child or owned windows, and then it destroys the parent or owner window. #destroy! also destroys modeless dialog boxes.

msdn.microsoft.com/en-us/library/ms632682(VS.85).aspx

[show source]
# File lib/win_window.rb, line 876
  def destroy!
    ret=WinUser.DestroyWindow(hwnd)
    ret != WIN_FALSE
  end
each_child () {|WinWindow.new(chwnd)| ...}

iterates over each child, yielding a WinWindow object.

raises a WinWindow::NotExistsError if the window does not exist, or a WinWindow::SystemError if a System Error errors.

use #children to get an Enumerable object.

msdn.microsoft.com/en-us/library/ms633494(VS.85).aspx

For System Error Codes see msdn.microsoft.com/en-us/library/ms681381(VS.85).aspx

[show source]
# File lib/win_window.rb, line 1111
  def each_child
    raise WinWindow::NotExistsError, "Window does not exist! Cannot enumerate children." unless exists?
    enum_child_windows_callback= WinUser.window_enum_callback do |chwnd, lparam|
      yield WinWindow.new(chwnd)
      WIN_TRUE
    end
    begin
      ret=WinUser.EnumChildWindows(hwnd, enum_child_windows_callback, nil)
    ensure
      WinUser.remove_window_enum_callback(enum_child_windows_callback)
    end
    if ret==0
      self.class.system_error("EnumChildWindows")
      # actually, EnumChildWindows doesn't say anything about return value indicating error encountered.
      # Although EnumWindows does, so it seems sort of safe to assume that would apply here too. 
      # but, maybe not - so, should we raise an error here? 
    end
    nil
  end
enabled_popup ()

The retrieved handle identifies the enabled popup window owned by the specified window (the search uses the first such window found using GW_HWNDNEXT); otherwise, if there are no enabled popup windows, nil is returned.

msdn.microsoft.com/en-us/library/ms633515(VS.85).aspx

[show source]
# File lib/win_window.rb, line 478
  def enabled_popup
    popup_hwnd=WinUser.GetWindow(hwnd, GW_ENABLEDPOPUP)
    @enabled_popup= popup_hwnd > 0 && popup_hwnd != self.hwnd ? self.class.new(popup_hwnd) : nil
  end
end_task! (force=false)

called to forcibly close the window.

the argument force, if true, will force the destruction of the window if an initial attempt fails to gently close the window using WM_CLOSE.

if false, only the close with WM_CLOSE is attempted

msdn.microsoft.com/en-us/library/ms633492(VS.85).aspx

[show source]
# File lib/win_window.rb, line 889
  def end_task!(force=false)
    ret=WinUser.EndTask(hwnd, 0, force ? WIN_TRUE : WIN_FALSE)
    ret != WIN_FALSE
  end
eql? (oth)

true if comparing an object of the same class with the same hwnd (integer)

[show source]
# File lib/win_window.rb, line 1167
  def eql?(oth)
    oth.class==self.class && oth.hwnd==self.hwnd
  end
exists? ()

determines whether the specified window handle identifies an existing window

msdn.microsoft.com/en-us/library/ms633528(VS.85).aspx

[show source]
# File lib/win_window.rb, line 612
  def exists?
    ret=WinUser.IsWindow(hwnd)
    ret != WIN_FALSE
  end
force_minimize! ()

Windows 2000/XP: Minimizes the window, even if the thread that owns the window is not responding. This should only be used when minimizing windows from a different thread.

msdn.microsoft.com/en-us/library/ms633548(VS.85).aspx

[show source]
# File lib/win_window.rb, line 860
  def force_minimize!
    ret=WinUser.ShowWindow(hwnd, SW_FORCEMINIMIZE)
    ret != WIN_FALSE
  end
foreground? ()

returns true if this is the same Window that is returned from WinWindow.foreground_window

[show source]
# File lib/win_window.rb, line 660
  def foreground?
    self==self.class.foreground_window
  end
hide! ()

Hides the window and activates another window.

msdn.microsoft.com/en-us/library/ms633548(VS.85).aspx

[show source]
# File lib/win_window.rb, line 755
  def hide!
    ret=WinUser.ShowWindow(hwnd, SW_HIDE)
    ret != WIN_FALSE
  end
hung_app? ()

determine if Microsoft Windows considers that a specified application is not responding. An application is considered to be not responding if it is not waiting for input, is not in startup processing, and has not called PeekMessage within the internal timeout period of 5 seconds.

msdn.microsoft.com/en-us/library/ms633526.aspx

[show source]
# File lib/win_window.rb, line 568
  def hung_app?
    hung=WinUser.IsHungAppWindow(hwnd)
    hung != WIN_FALSE
  end
iconic? ()

whether the window is minimized (iconic).

msdn.microsoft.com/en-us/library/ms633527(VS.85).aspx

[show source]
# File lib/win_window.rb, line 628
  def iconic?
    ret=WinUser.IsIconic(hwnd)
    ret != WIN_FALSE
  end
inspect ()
[show source]
# File lib/win_window.rb, line 402
  def inspect
    retrieve_text
    class_name
    Object.instance_method(:inspect).bind(self).call
  end
last_active_popup ()

determines which pop-up window owned by this window was most recently active

msdn.microsoft.com/en-us/library/ms633507(VS.85).aspx

[show source]
# File lib/win_window.rb, line 519
  def last_active_popup
    ret_hwnd=WinUser.GetLastActivePopup(hwnd)
    @last_active_popup= ret_hwnd > 0 ? self.class.new(ret_hwnd) : nil
  end
maximize! ()

Maximizes this window. (note: exact same as show_maximized!)

msdn.microsoft.com/en-us/library/ms633548(VS.85).aspx

[show source]
# File lib/win_window.rb, line 789
  def maximize!
    ret=WinUser.ShowWindow(hwnd, SW_MAXIMIZE)
    ret != WIN_FALSE
  end
minimize! ()

Minimizes this window and activates the next top-level window in the Z order.

msdn.microsoft.com/en-us/library/ms633548(VS.85).aspx

[show source]
# File lib/win_window.rb, line 814
  def minimize!
    ret=WinUser.ShowWindow(hwnd, SW_MINIMIZE)
    ret != WIN_FALSE
  end
minimized? ()

Alias for #iconic?

owner ()

The retrieved handle identifies the specified window’s owner window, if any.

msdn.microsoft.com/en-us/library/ms633515(VS.85).aspx

[show source]
# File lib/win_window.rb, line 486
  def owner
    owner_hwnd=WinUser.GetWindow(hwnd, GW_OWNER)
    @owner= owner_hwnd > 0 ? self.class.new(owner_hwnd) : nil
  end
parent ()

retrieves a handle to this window’s parent or owner

msdn.microsoft.com/en-us/library/ms633510(VS.85).aspx

[show source]
# File lib/win_window.rb, line 536
  def parent
    parent_hwnd=WinUser.GetParent(hwnd)
    @parent= parent_hwnd > 0 ? self.class.new(parent_hwnd) : nil
  end
pretty_print (pp)
[show source]
# File lib/win_window.rb, line 408
  def pretty_print(pp)
    retrieve_text
    class_name
    pp.pp_object(self)
  end
process_id ()

returns the process identifier that created this window

msdn.microsoft.com/en-us/library/ms633522%28VS.85%29.aspx

[show source]
# File lib/win_window.rb, line 603
  def process_id
    lpdwProcessId=FFI::MemoryPointer.new(Types[:LPDWORD])
    WinUser.GetWindowThreadProcessId(hwnd, lpdwProcessId)
    lpdwProcessId.get_ulong(0)
  end
real_class_name ()

retrieves a string that specifies the window type

msdn.microsoft.com/en-us/library/ms633538(VS.85).aspx

[show source]
# File lib/win_window.rb, line 586
  def real_class_name
    buff_size=256
    buff=" "*buff_size
    len=WinUser.RealGetWindowClassA(hwnd, buff, buff_size)
    @real_class_name=buff.to_s[0...len]
  end
really_set_foreground! (options={})

really sets this to be the foreground window.

  • restores the window if it’s iconic.
  • attempts to circumvent a lock disabling calls made by set_foreground!
  • then calls set_foreground!, which should then work with that lock disabled. tries this for a few seconds, checking if it was successful.

if you want it to raise an exception if it can’t set the foreground window, pass :error => true (default is false)

[show source]
# File lib/win_window.rb, line 705
  def really_set_foreground!(options={})
    options=handle_options(options, :error => false)
    try_harder=false
    mapped_vk_menu=WinUser.MapVirtualKeyA(VK_MENU, 0)
    Waiter.try_for(2, :exception => (options[:error] && WinWindow::Error.new("Failed to set foreground window"))) do
      if iconic?
        restore!
      end
      if try_harder
        # Simulate two single ALT keystrokes in order to deactivate lock on SetForeGroundWindow before we call it.
        # See LockSetForegroundWindow, http://msdn.microsoft.com/en-us/library/ms633532(VS.85).aspx
        # also keybd_event, see http://msdn.microsoft.com/en-us/library/ms646304(VS.85).aspx
        #
        # this idea is taken from AutoIt's setforegroundwinex.cpp in SetForegroundWinEx::Activate(HWND hWnd)
        # keybd_event((BYTE)VK_MENU, MapVirtualKey(VK_MENU, 0), 0, 0);
        # keybd_event((BYTE)VK_MENU, MapVirtualKey(VK_MENU, 0), KEYEVENTF_KEYUP, 0);
        2.times do
          ret=WinUser.keybd_event(VK_MENU, mapped_vk_menu, KEYEVENTF_KEYDOWN, nil)
          ret=WinUser.keybd_event(VK_MENU, mapped_vk_menu, KEYEVENTF_KEYUP, nil)
        end
      else
        try_harder=true
      end
      set_foreground!
      foreground?
    end
  end
recurse_each_child (options={}) {|win_window| ...}

iterates over each child recursively, yielding a WinWindow object for each child.

raises a WinWindow::NotExistsError if the window does not exist, or a WinWindow::SystemError if a System Error errors.

use #children_recursive to get an Enumerable object.

[show source]
# File lib/win_window.rb, line 1145
  def recurse_each_child(options={})
    options=handle_options(options, :rescue_enum_child_windows => true)
    ycomb do |recurse|
      proc do |win_window|
        yield win_window
        begin
          win_window.each_child do |child_window|
            recurse.call child_window
          end
        rescue SystemError
          raise unless options[:rescue_enum_child_windows] && $!.function=='EnumChildWindows'
        end
      end
    end.call(self)
  end
restore! ()

Activates and displays the window. If the window is minimized or maximized, the system restores it to its original size and position. An application should use this when restoring a minimized window.

msdn.microsoft.com/en-us/library/ms633548(VS.85).aspx

[show source]
# File lib/win_window.rb, line 842
  def restore!
    ret=WinUser.ShowWindow(hwnd, SW_RESTORE)
    ret != WIN_FALSE
  end
retrieve_text ()

This is similar to #text that one is GetWindowText(hwnd) this one is SendMessage(hwnd, WM_GETTEXT) differences are documented here: msdn.microsoft.com/en-us/magazine/cc301438.aspx and here: blogs.msdn.com/oldnewthing/archive/2003/08/21/54675.aspx

[show source]
# File lib/win_window.rb, line 442
  def retrieve_text
    buff_size=retrieve_text_length+1
    buff=" "*buff_size
    len= WinUser.SendMessageA(hwnd, WM_GETTEXT, buff_size, buff)
    @text=buff[0...len]
  end
retrieve_text_length ()

similar to #text_length; differences between that and this are the same as between #text and #retrieve_text

[show source]
# File lib/win_window.rb, line 451
  def retrieve_text_length
    len= WinUser.SendMessageA(hwnd, WM_GETTEXTLENGTH, 0, nil)
    len
  end
send_close! ()

sends notification that the window should close. returns nil (we get no indication of success or failure).

msdn.microsoft.com/en-us/library/ms632617%28VS.85%29.aspx

[show source]
# File lib/win_window.rb, line 898
  def send_close!
    buff_size=0
    buff=""
    len=WinUser.SendMessageA(hwnd, WM_CLOSE, buff_size, buff)
    nil
  end
send_set_text! (text)

sets text by sending WM_SETTEXT message. this different than #set_text! in the same way that #retrieve_text is different than #text

[show source]
# File lib/win_window.rb, line 468
  def send_set_text!(text)
    ret=WinUser.SendMessageA(hwnd, WM_SETTEXT, 0, text.dup)
    nil
  end
set_foreground! ()

puts the thread that created the specified window into the foreground and activates the window. Keyboard input is directed to the window, and various visual cues are changed for the user. The system assigns a slightly higher priority to the thread that created the foreground window than it does to other threads.

If the window was brought to the foreground, the return value is true.

If the window was not brought to the foreground, the return value is false.

msdn.microsoft.com/en-us/library/ms633539(VS.85).aspx

[show source]
# File lib/win_window.rb, line 654
  def set_foreground!
    ret= WinUser.SetForegroundWindow(hwnd)
    ret != WIN_FALSE
  end
set_parent! (parent)

changes the parent window of this child window

msdn.microsoft.com/en-us/library/ms633541(VS.85).aspx

[show source]
# File lib/win_window.rb, line 544
  def set_parent!(parent)
    parent_hwnd= parent.is_a?(self.class) ? parent.hwnd : parent
    new_parent=WinUser.SetParent(hwnd, parent_hwnd)
    new_parent > 0 ? self.class.new(new_parent) : nil
  end
set_text! (text)

changes the text of the specified window’s title bar (if it has one). If the specified window is a control, the text of the control is changed. However, #set_text! cannot change the text of a control in another application (see #send_set_text!)

msdn.microsoft.com/en-us/library/ms633546(VS.85).aspx

[show source]
# File lib/win_window.rb, line 461
  def set_text!(text)
    set=WinUser.SetWindowTextA(hwnd, text)
    set != WIN_FALSE
  end
show! ()

Activates the window and displays it in its current size and position.

msdn.microsoft.com/en-us/library/ms633548(VS.85).aspx

[show source]
# File lib/win_window.rb, line 806
  def show!
    ret=WinUser.ShowWindow(hwnd, SW_SHOW)
    ret != WIN_FALSE
  end
show_default! ()

Sets the show state based on the SW_ value specified in the STARTUPINFO structure passed to the CreateProcess function by the program that started the application.

msdn.microsoft.com/en-us/library/ms633548(VS.85).aspx

[show source]
# File lib/win_window.rb, line 851
  def show_default!
    ret=WinUser.ShowWindow(hwnd, SW_SHOWDEFAULT)
    ret != WIN_FALSE
  end
show_maximized! ()

Activates the window and displays it as a maximized window. (note: exact same as maximize!)

msdn.microsoft.com/en-us/library/ms633548(VS.85).aspx

[show source]
# File lib/win_window.rb, line 781
  def show_maximized!
    ret=WinUser.ShowWindow(hwnd, SW_SHOWMAXIMIZED)
    ret != WIN_FALSE
  end
show_min_no_active! ()

Displays the window as a minimized window. This is similar to show_minimized!, except the window is not activated.

msdn.microsoft.com/en-us/library/ms633548(VS.85).aspx

[show source]
# File lib/win_window.rb, line 823
  def show_min_no_active!
    ret=WinUser.ShowWindow(hwnd, SW_SHOWMINNOACTIVE)
    ret != WIN_FALSE
  end
show_minimized! ()

Activates the window and displays it as a minimized window.

msdn.microsoft.com/en-us/library/ms633548(VS.85).aspx

[show source]
# File lib/win_window.rb, line 773
  def show_minimized!
    ret=WinUser.ShowWindow(hwnd, SW_SHOWMINIMIZED)
    ret != WIN_FALSE
  end
show_na! ()

Displays the window in its current size and position. This is similar to show!, except the window is not activated.

msdn.microsoft.com/en-us/library/ms633548(VS.85).aspx

[show source]
# File lib/win_window.rb, line 832
  def show_na!
    ret=WinUser.ShowWindow(hwnd, SW_SHOWNA)
    ret != WIN_FALSE
  end
show_no_activate! ()

Displays the window in its most recent size and position. This is similar to show_normal!, except the window is not actived.

msdn.microsoft.com/en-us/library/ms633548(VS.85).aspx

[show source]
# File lib/win_window.rb, line 798
  def show_no_activate!
    ret=WinUser.ShowWindow(hwnd, SW_SHOWNOACTIVATE)
    ret != WIN_FALSE
  end
show_normal! ()

Activates and displays a window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when displaying the window for the first time.

msdn.microsoft.com/en-us/library/ms633548(VS.85).aspx

[show source]
# File lib/win_window.rb, line 765
  def show_normal!
    ret=WinUser.ShowWindow(hwnd, SW_SHOWNORMAL)
    ret != WIN_FALSE
  end
switch_to! (alt_tab=false)

switch focus and bring to the foreground

the argument alt_tab, if true, indicates that the window is being switched to using the Alt/Ctl+Tab key sequence. This argument should be false otherwise.

msdn.microsoft.com/en-us/library/ms633553(VS.85).aspx

[show source]
# File lib/win_window.rb, line 640
  def switch_to!(alt_tab=false)
    WinUser.SwitchToThisWindow(hwnd, alt_tab ? WIN_TRUE : WIN_FALSE)
  end
text ()

retrieves the text of this window’s title bar (if it has one). If this is a control, the text of the control is retrieved. However, #text cannot retrieve the text of a control in another application (see #retrieve_text)

msdn.microsoft.com/en-us/library/ms633520(VS.85).aspx

[show source]
# File lib/win_window.rb, line 419
  def text
    buff_size=text_length+1
    buff="\001"*buff_size
    len= WinUser.GetWindowTextA(hwnd, buff, buff_size)
    @text=buff[0...len]
  end
text_length ()

length of the window text, see #text

similar to #text, cannot retrieve the text of a control in another application - see #retrieve_text, #retrieve_text_length

msdn.microsoft.com/en-us/library/ms633521(VS.85).aspx

[show source]
# File lib/win_window.rb, line 432
  def text_length
    len= WinUser.GetWindowTextLengthA(hwnd)
    len
  end
thread_id ()

returns the identifier of the thread that created the window

msdn.microsoft.com/en-us/library/ms633522%28VS.85%29.aspx

[show source]
# File lib/win_window.rb, line 596
  def thread_id
    WinUser.GetWindowThreadProcessId(hwnd, nil)
  end
top_window ()

examines the Z order of the child windows associated with self and retrieves a handle to the child window at the top of the Z order

msdn.microsoft.com/en-us/library/ms633514(VS.85).aspx

[show source]
# File lib/win_window.rb, line 528
  def top_window
    ret_hwnd= WinUser.GetTopWindow(hwnd)
    @top_window= ret_hwnd > 0 ? self.class.new(ret_hwnd) : nil
  end
visible? ()

visibility state of the specified window

msdn.microsoft.com/en-us/library/ms633530(VS.85).aspx

[show source]
# File lib/win_window.rb, line 620
  def visible?
    ret=WinUser.IsWindowVisible(hwnd)
    ret != WIN_FALSE
  end
window_rect ()

Returns a Rect struct with members left, top, right, and bottom indicating the dimensions of the bounding rectangle of the specified window. The dimensions are given in screen coordinates that are relative to the upper-left corner of the screen.

msdn.microsoft.com/en-us/library/ms633519%28VS.85%29.aspx

[show source]
# File lib/win_window.rb, line 919
  def window_rect
    rect=WinUser::Rect.new
    ret=WinUser.GetWindowRect(hwnd, rect)
    if ret==WIN_FALSE
      self.class.system_error "GetWindowRect"
    else
      rect
    end
  end