Dl/win32 EnumWindows loops correctly then segfaults

Hi All,

Googling for “ruby win32api EnumWindows” led me to this four-year-old
post from “Shusaku”:
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/54587

What I want to do (for now) is list all of the windows currently open on
the system, with their captions. (Ultimately I want to write an script
that will save and restore the positions of various windows on the
desktop, such as positioning my IM client so that it looks “docked”.)

When I run this script, it seems to run just fine, listing 148 open
windows, about 1/3 of which have captions. Then it crashes with this
message:


./scratch.rb:23: [BUG] Segmentation fault
ruby 1.8.4 (2005-12-24) [i386-cygwin]

Aborted (core dumped)

Any ideas? As the message indicates, this is ruby 1.8.4 running in
Cygwin. This is on a Windows XP Media Center Edition laptop with an AMD
64 Turion, if that matters.

When I run Shusaku’s original code, it closes all open IE windows… and
then segfaults. So I’m thinking maybe the EnumWindows loop isn’t
terminating correctly, or I’m simply using this code wrong. Help?

Here’s the script:


#!/usr/bin/env ruby

list all windows on the machine and their captions…

require ‘dl’

User32 = DL.dlopen(‘user32’)
enum_windows = User32[‘EnumWindows’, ‘IPL’]
post_message = User32[‘PostMessage’, ‘ILILL’]
get_class_name = User32[‘GetClassName’, ‘ILpI’]
get_window_text = User32[‘GetWindowText’, ‘ILpI’]

BUF_SIZE = 250
TRUE = 1

buff = " " * BUF_SIZE

enum_windows_proc = DL.callback(‘ILL’) {|hwnd,lparam|
r,rs = get_window_text.call(hwnd, buff, buff.size)
puts “#{sprintf(‘0x%08x’, hwnd)}: #{rs[1].to_s}”
TRUE
}
r,rs = enum_windows.call( enum_windows_proc, 0)

-dB