Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Embedded Windows Scripting (VBScript & JScript) and COM


  • Please log in to reply
68 replies to this topic
vashk
  • Members
  • 11 posts
  • Last active: Apr 02 2008 01:21 AM
  • Joined: 07 Jan 2008
I'm using WS library in the following code to work with some class objects. The code is accessing the objects without errors. But, I'm running into a problem when I call WS_Uninitialize() at the end. When I call it, AHK crashes after a second or two. If I don't call it, the objects persist over different function calls, even if I explicitly release the pointers. Is there something obvious I'm missing?

WC_GetMouseText()
{
    CoordMode ToolTip, Screen ;sets ToolTip mode to global coordinates
    CoordMode Mouse, Screen ;sets Mouse mode to global coordinates
    MouseGetPos mX, mY, w_hWnd, c_hWnd, 2
    
    WS_Initialize()
    c_suuid := "{8F267988-0CA4-418C-8F94-B4BC5862B390}" ;WCaptureX
    m_suuid := "{C7E06D1D-4099-43D4-8C22-718E39713773}" ;WMonitorX
    i_suuid := "{4B484CCE-9120-49B7-A5F2-B8B183BFD808}" ;WInput
    r_suuid := "{064E314E-2382-46F2-A93A-239C7115579A}" ;WResult
    
    pWcx := WS_CreateObject(c_suuid)
    pWmx := WS_CreateObject(m_suuid)
    pWi := WS_CreateObject(i_suuid)
    pWr := WS_CreateObject(r_suuid)
    ;debug_ToolTip( ErrorLevel )
    
    WS_AddObject(pWcx,"capture")
    WS_AddObject(pWmx,"monitor")
    WS_AddObject(pWi,"objInput")
    ;WS_AddObject(pWr,"objResult")
    
    WS_ReleaseObject(pWcx)
    WS_ReleaseObject(pWmx)
    WS_ReleaseObject(pWi)
    ;WS_ReleaseObject(pWr)
    
    ;Code = WS_codef("Call monitor.Start(%v,%v,%v)","key","mouse","bGesture")
            ;objResult = capture.Capture(objInput)
    WS_Exec("Call monitor.Start(2,2,True)")
    ;debug_ToolTip( ErrorLevel )

    Declarations =
    (
        Function GetText(hwnd,x,y)
            hwnd = CLng("&H" & hwnd)
            x = CLng("&H" & x)
            y = CLng("&H" & y)
            objInput.Hwnd = hwnd
            objInput.StartX = x
            objInput.StartY = y
            objInput.EndX = x
            objInput.EndY = y
            objInput.ContextWordsLeft = 1
            objInput.ContextWordsRight = 1
            objInput.Options = 1
            Set GetText = capture.Capture(objInput)
        End Function
    )
    WS_Exec(Declarations)
    ;debug_ToolTip(w_hWnd)
    h := SubStr(c_hWnd,3) ;need control hwnd to pass to capture method
    x := SubStr(mX,3)
    y := SubStr(mY,3)
    Code := WS_codef("GetText(%s,%s,%s)",h,x,y)
    WS_Eval(pWr,Code)
    WS_AddObject(pWr,"objResult")
    ;WS_Eval(context,"objResult.Context")
    WS_Eval(text,"objResult.Text")
    ;WS_Eval(locale,"objResult.Locale")
    ;WS_Eval(font,"objResult.Font")
    WS_ReleaseObject(pWr)
    ;debug_ToolTip( ErrorLevel ,"","",1500)
    debug_ToolTip(text)
    WS_Uninitialize() ;must call this to refresh objects
}


--v

erictheturtle
  • Members
  • 101 posts
  • Last active: Sep 04 2011 02:07 PM
  • Joined: 27 Jun 2007
I see you are creating the objects via their CLSID. If you can create them via the ProgID directly in VB code, could you try that?

Also, I see you are adding pWr back into the scripting environment as soon as you've received it in AHK. Could you change this:
Code := codef("GetText(%s,%s,%s)",h,x,y)
    WS_Eval(pWr,Code)
    WS_AddObject(pWr,"objResult")
	...
    WS_ReleaseObject(pWr)
to this?
Code := codef("Set objResult = GetText(%s,%s,%s)",h,x,y)
    WS_Exec(Code)
If changing these things fixes the problem, then ws4ahk probably has something wrong with it. If you've tried all these things already, then something could be really wrong with ws4ahk, or the object you're playing with might have the problem. I'll check more tomorrow.

I'm surprised someone is actually using the codef function :shock: But I see I failed to handle hexadecimal values for %v...I would like to fix that, but I don't think I can...
-m35

vashk
  • Members
  • 11 posts
  • Last active: Apr 02 2008 01:21 AM
  • Joined: 07 Jan 2008
eric,

Thank you for the fast response. You even answered some questions I was thinking about but hadn't asked :p

I implemented your suggestion to use WS_Exec(Code) setting the value in the VB and not bothering with keeping a pWr pointer. I've just started using your library, so I was trying many different things and missed that in the shuffle. It solves my persistence issue nicely. However I'm still seeing AHK crash if I use WS_Uninitialize()...

I'm thinking if I take your suggestion to instantiate inside VB code instead of WS_AddObject() it might help, but I'll have to take some time to debug it because the DLL complains when I try that. Come to think of it, it might be the DLL which is causing the crash in the first place. I'll respond again if I find a fix.

The hex code and codef use is not at all important. It's just a remnant of when I ran into some trouble early on with the VB end and made a workaround.

Again, thanks for the suggestions and the cool library to play with.

:p
--v

tank
  • Administrators
  • 4345 posts
  • AutoHotkey Foundation
  • Last active: May 02 2019 09:16 PM
  • Joined: 21 Dec 2007
strange i wonder why it crashes i use this library alot and never experience a problem wiht crashing ahk
Never lose.
WIN or LEARN.

erictheturtle
  • Members
  • 101 posts
  • Last active: Sep 04 2011 02:07 PM
  • Joined: 27 Jun 2007
vashk

I took another long look at your code, and you've written it basically how I would. So my final troubleshooting suggestion is to re-write the code entirely in VB, VBA, or VBScript, and feeding it some numbers from Window Spy (manually copy-paste the values into the script). If it crashes in these environments, then we can be sure the COM object(s) are the source of the crash.

If you {aren't sure how to write | don't really want to write | don't have time to write | don't really care to write | have betting things to do than write | are enjoying leisurely walks on the beach instead of writing} this test by sometime tomorrow, I'll write it up and post it along with some instructions.
-m35

vashk
  • Members
  • 11 posts
  • Last active: Apr 02 2008 01:21 AM
  • Joined: 07 Jan 2008
I found a quick fix using the current code which requires the script to wait at least 1500 ms before calling WS_Uninitialize(). With the usage I have in mind, it's a perfectly acceptable delay. I don't want to call it multiple times within that period, so I don't think a Timer would work well.

WC_GetMouseText()
{
    ...
    WS_Exec(Code)
    WS_Eval(text,"objResult.Text")
    ...
    Sleep 1500
    WS_Uninitialize()
}

This prevents the crash. I'm investigating whether this has to do with the DLL I'm using... I suspect it does.

The last issue I'm having occurs when objResult.Text contains non-Latin-encoded characters. WS_Eval(text,"objResult.Text") assigns "????" to the text variable. It's definitely the Latin "?" (%3f) not Unicode. A MsgBox in VB confirms that objResult.Text is retrieving the correctly encoded text, but there is no clean way I can think of to put it into an AHK variable without proper Unicode support.
--v

erictheturtle
  • Members
  • 101 posts
  • Last active: Sep 04 2011 02:07 PM
  • Joined: 27 Jun 2007
Sorry I didn't get this posted yesterday.

Your script converted to VBS
' fill in these values 
c_sprogid = "" ' WCaptureX PROGID
m_sprogid = "" ' WMonitorX PROGID
i_sprogid = "" ' WInput PROGID
r_sprogid = "" ' WResult PROGID


' use the other script to get the x, y 
' and HWND of the window and control  
mX = 0 'paste value here
mY = 0 'paste value here
w_hWnd = 0 'paste HWND here
c_hWnd = 0 'paste HWND here


Function GetText(hwnd,x,y)
	'hwnd = CLng("&H" & hwnd)
	'x = CLng("&H" & x)
	'y = CLng("&H" & y)
	objInput.Hwnd = hwnd
	objInput.StartX = x
	objInput.StartY = y
	objInput.EndX = x
	objInput.EndY = y
	objInput.ContextWordsLeft = 1
	objInput.ContextWordsRight = 1
	objInput.Options = 1
	Set GetText = capture.Capture(objInput)
End Function


Set capture   = CreateObject(c_sprogid)
Set monitor   = CreateObject(m_sprogid)
Set objInput  = CreateObject(i_sprogid)
'Set objResult = CreateObject(r_sprogid)

Call monitor.Start(2,2,True)

Set objResult = GetText(c_hWnd, mX, mY)

WScript.Echo objResult.Context
WScript.Echo objResult.Text   
WScript.Echo objResult.Locale 
WScript.Echo objResult.Font   	


Little AHK program to get the HWND and coordinates
CoordMode ToolTip, Screen ;sets ToolTip mode to global coordinates
CoordMode Mouse, Screen ;sets Mouse mode to global coordinates

Msgbox % "Ctrl+Left Click to capture values." 


^LButton::

	MouseGetPos mX, mY, w_hWnd, c_hWnd, 2
	
	SetFormat, integer, d
	VariableContainingAnInteger += 0
	mX += 0
	mY += 0
	w_hWnd += 0
	c_hWnd += 0
	
	s := "mX = " mX "`nmY = " mY "`nw_hWnd = " w_hWnd "`nc_hWnd = " c_hWnd
	
	Tooltip % s "`n`nThis is copied to the clipboard"
	
	Clipboard := s
	
	Return

If you could fill in the blanks in the VB script and test it, I'd be very interested in the results.

In any case, I'm glad you found a workaround for the crash.

Unicode you say? Mmm, yes. Adjusting ws4ahk to return Unicode text wouldn't be too much work, although you're right that AHK doesn't have good handling for it.
-m35

strifej
  • Members
  • 2 posts
  • Last active: Jun 16 2013 02:16 PM
  • Joined: 14 Feb 2013

I know this is a really old thread, but was wondering if anyone ever modified wsa4hk to work with Autohotkey_L?  It works fine with the older Ansi version, but would like to move up to a newer ahk if possible.

 

For me, it fails to initialize on _L.  I've tested on Win7 and WinXP AHK v. 110501.

 

Thanks



jethrow
  • Moderators
  • 2854 posts
  • Last active: May 17 2017 01:57 AM
  • Joined: 24 May 2009

You are correct - this thread is really old. Since the last post in 2008, AHK(_L) has implemented native COM support. You'd probably be better going that route.