Forum: Ruby dl/win32 EnumWindows loops correctly then segfaults

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
David B. (Guest)
on 2006-04-12 10:12
(Received via mailing list)
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/...

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
This topic is locked and can not be replied to.