From: Michael Kelly Date: 2005-08-05T16:49:45+09:00 Subject: Question about WIN32OLE_EVENT. ------_=_NextPart_001_01C59992.3C23E412 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable So, I'm clear on how to attach to events: =20 @ie =3D WIN32OLE.new( 'InternetExplorer.Application' ) browserEvents =3D WIN32OLE_EVENT.new( @ie, 'DWebBrowserEvents2' ) browserEvents.on_event { |*args| eventHandler( *args ) } =20 But how does one detach from events? =20 I'm working on a little utility that will generate Watir scripts using IE automation. In the following code I am attaching to the browser events to capture when a new HTML document is loaded. When a document is loaded I want to attach to the document's events. When a new document is loaded I want to detach from the old document's events. =20 Here's the code so far. At the moment, each newly loaded document adds to a growing list of event handlers, causing each click to produce multiple calls to printClickStatement. =20 Thanks, =20 -=3Dmichael=3D- =20 #requires require 'win32ole' =20 ##////////////////////////////////////////////////////////////////////// /////////////////////////////// ## ## Main WatirMaker class. It handles the IE automation, which primarily means event handling. ## ##////////////////////////////////////////////////////////////////////// /////////////////////////////// class WatirMaker=20 =20 =20 ##////////////////////////////////////////////////////////////////////// //////////////////////////// ## ## Initializer executed when "new" is called. ## =20 ##////////////////////////////////////////////////////////////////////// //////////////////////////// def initialize =20 end =20 =20 ##////////////////////////////////////////////////////////////////////// //////////////////////////// ## ## Handles all events from the browser and the HTML document. ## =20 ##////////////////////////////////////////////////////////////////////// //////////////////////////// def eventHandler( event, *args ) case event when "BeforeNavigate2" webBrowser =3D args[0] url =3D args[1] frameName =3D args[3] =20 if frameName =3D=3D "" @webBrowsers =3D Hash.new if @documentEventHandlers !=3D nil @documentEventHandlers.each_value { |value| value.on_event( 'onclick' ) {} } end @documentEventHandlers =3D Hash.new end =20 @webBrowsers[url] =3D webBrowser printNavigateComment( url, frameName ) =20 when "NavigateComplete2" #printNavigateComment( args[1], nil ) =20 when "DocumentComplete" url =3D args[1] webBrowser =3D @webBrowsers[url] if ( webBrowser.Type =3D=3D "HTML Document" && !@documentEventHandlers.has_key?( url ) ) @documentEventHandlers[url] =3D=20 WIN32OLE_EVENT.new( webBrowser.document, 'HTMLDocumentEvents2' ) @documentEventHandlers[url].on_event( 'onclick' ) { |*args|=20 printClickStatement( args[0] )=20 } end =20 when "OnQuit" throw :done end end =20 =20 ##////////////////////////////////////////////////////////////////////// //////////////////////////// ## ## Print comment showing the page navigated to. ## =20 ##////////////////////////////////////////////////////////////////////// //////////////////////////// def printNavigateComment( url, frameName ) puts "" puts "# frame loaded: '" + frameName + "'" if frameName !=3D nil puts "# navigated to: '" + url + "'" puts "" end =20 =20 ##////////////////////////////////////////////////////////////////////// //////////////////////////// ## ## Print Watir statement for click events. ## =20 ##////////////////////////////////////////////////////////////////////// //////////////////////////// def printClickStatement( eventObj ) =20 how, what =3D getHowWhat( eventObj.srcElement ) =20 case eventObj.srcElement.tagName when "INPUT" case eventObj.srcElement.getAttribute( "type" ) when "submit" # TODO: must figure out a way to get the frame that contains the srcElement. The frame=20 # will be necessary to properly reference the element. puts "ie.button( " + how + ", '" + what + "' ).click" end =20 end =20 end =20 =20 ##////////////////////////////////////////////////////////////////////// //////////////////////////// ## ## Returns the "how" and the "what" values. ## ## Note: may need different getHowWhat methods for different element types because each element=20 ## type supports different "how" values. ## =20 ##////////////////////////////////////////////////////////////////////// //////////////////////////// def getHowWhat( element ) =20 if element.getAttribute( "id" ) !=3D "" return ":id", element.getAttribute( "id" ) elsif element.getAttribute( "name" ) !=3D "" return ":name", element.getAttribute( "name" ) else # TODO: must get the actual index of the item using the=20 # IHTMLDocument3::getElementsByTagName method return ":index", 1 =20 =20 end =20 end =20 =20 ##////////////////////////////////////////////////////////////////////// //////////////////////////// ## ## Starts recording all interactions with IE. ## =20 ##////////////////////////////////////////////////////////////////////// //////////////////////////// def startRecording =20 # initialize IE @ie =3D WIN32OLE.new( 'InternetExplorer.Application' ) @ie.visible =3D TRUE @ie.gohome =20 browserEvents =3D WIN32OLE_EVENT.new( @ie, 'DWebBrowserEvents2' ) =20 browserEvents.on_event { |*args| eventHandler( *args ) } =20 # print script header puts "##///////////////////////////////////////////////////////////////////// /////////////////////////////" puts "##" puts "## Watir script recorded by WatirMaker." puts "##" puts "##///////////////////////////////////////////////////////////////////// /////////////////////////////" puts "" puts "#requires" puts "require 'watir'" puts "" puts "#includes" puts "include Watir" puts "" puts "ie =3D IE.new" puts "ie.set_fast_speed()" puts "ie.ie.gohome" puts "" =20 # capture events catch( :done ) { loop { WIN32OLE_EVENT.message_loop } } =20 # IE takes a moment to close. =20 # Making it invisible in the interim produces a slightly nicer user experience. @ie.visible =3D FALSE end =20 end # end class =20 --=20 Michael Kelly=20 Sr. Software Engineer=20 Eleven Wireless Inc. - The Possibilities are Wireless=20 http://www.elevenwireless.com =20 =20 =20 ------_=_NextPart_001_01C59992.3C23E412--