| || |
Extern.Declare to hook DLL and use function directly for a FarPoint Spreadsheet
Okay, here is one for the advanced folks on the group. I'm working with an application that has a FarPoint Spreadsheet in it for the grid/table of data. I'm using UFT 11.5. The FarPoint object gets recognized as a WinObject (not SwfObject) so I don't have access to the .object (native methods directly).
I know the FarPoint WinObject native class is fpspread70. I think I've found the DLL (spr32d70.dll) that it uses. So I've gone the route of directly accessing the DLL itself. Using Extern.Declare I can hook the DLL and try to map a function entry point. My code looks like this:
Dim FP70hWnd, sTxtVal, iRow, iCol
FP70hWnd = CLng(0)
sTxtVal = CStr("a")
iRow = CLng(1)
iCol = CLng(1)
FP70hWnd = Window("016901461 Opened by Test,").WinObject("Visit Relationships").GetROProperty("hWnd")
extern.Declare micInteger,"FPGetData","spr32d70.dll","SSGetData", micLong, micLong, micLong, micString+micByRef
iRet = extern.FPGetData(FP70hWnd, iCol, iRow, sTxtVal)
I get the correct hWnd value for the object (validated it by ObjectSpy). I've prototyped the entry point I want (based it on what I could find in the FarPoint documentation):
Syntax for C -- int SSGetData(HWND hWnd, SS_COORD Col, SS_COORD Row, LPTSTR Data);
The SS_COORD appear to be of Long Integer type.
I guess part of the problem is that I cannot determine if the extern.Declare really hooked the DLL correctly. Does anyone know if it returns a value to allow you to determine if it really mapped the entry point correctly. Looking at the online Help it doesn't appear to have a return value.
When I run the code I'm getting the General Run Error message from UFT. Basically I'm stuck and getting my butt kicked by this thing. Any help and ideas is appreciated. Thanks.
Test it out with .NET first just to make sure it's going the way you want...POC kinda thing. I'm not too sure the behavior of this application that you're using so I can't say if creating a new instance of the object will hook an already running application. If it doesn't you can check the ROT to see if it's exposed there (similar to the Office Automation Object Model).
If everything works out here, then you know the path you should take and apply that to QTP if you can. If you cannot, create a class library in .NET and use it in QTP to perform the desired actions.
Hope that helps some,
Not sure what you mean by test it out with .NET. I cannot use the .NET spy to see what is in the object because it is classed as a WinObject and the parent is also a Window type object. There isn't a .NET Swf type object to hook there.
I've got access to the online documentation for the FarPoint Spreadsheet v7 (DLL & OCX), and the function entry point is for the DLL. So that is how I'm trying to build it by, doing a bit of translation from their examples for use by UFT.
Not sure what you meant by 'ROT' and Office Automation Object Model (I assume you mean COM and references with it).
On your final point that may be the route I have to go. Create my own DLL bridge to hook the FarPoint DLL, utilize the References capability in .NET to map up the entry point functions I want and write it in a format that I can have UFT utilize. That is my last resort.
Thanks for the response, it is appreciated.
SSGetData, SSSetData, SSSetDataRange Functions
int SSGetData(HWND hWnd, SS_COORD Col, SS_COORD Row, LPTSTR Data);
Using Column and Row Properties
I checked signature and return of extern.Declare micInteger,"FPGetData","spr32d70.dll","SSGetData", micLong, micLong, micLong, micString+micByRef ; looks fine. Return is length of text.
This is not related to UFT but sibling , see if you get any clue
Calling DLL Functions From Tests - Known Limitations
can you please try FP70hWnd with UINT (int) instead of string in FPGetData call also?
Last edited by Yogi_Shukla; 05-07-2013 at 02:42 PM.
The link you gave on the SSGetData is pretty much the same page I pulled my information from. I have access to the online documentation for the FarPoint object. Also, the link to the SmartBear page I have already read. So we are on the same wavelength here.
I'll try the UINT on the call, but not really sure what you mean. I'll experiment, but need some more clarification of what you are trying to state.
So my question is what does SS_COORD really evaluate to. Is it an Integer or Long. That is what has me a bit confused, can't seem to find that in the online docs easily.
Thanks for the reply and help.
Sorry I may not be much help but SS_COORD seems to be Long.
UINT - unsigned integer I read for parameter, VBScript have no concept of unsigned so Cint coversion should be fine. But not sure... You can play around.
Jim, this could be a tricky issue. The thing is that when you define an API using extern.declare, the API doesn't know whether the declaration is correct or not. It is when you make the call the API will generate an issue. The API creates a stack based on the types of parameter you specify and the calls the API. So any mistake in the stack will create an error. The point Drew raised about .NET is a valid point. What you should do is that you should create a sample .NET program and try and figure out the correct way of communicating with the grid. Once the API works in .NET, it would be easier for you to port it VBScript version.
Okay, I'm following you. I'm pretty sure the target application is a C++ based one, but I see what you are saying by using a .NET based app with the object in it. Once I get it mapped out correctly using that I should be able to translate back to the C++ one and use UFT/VBScript to talk to it then.
If anything worth a shot. Thanks for the help.
Sorry for the cryptic language I was using...ROT (Runtime Object Table) shows applications that can be hooked basically; that's to say you can create an instance of an already running application. The Microsoft Office Automation Object Model is exposed in the ROT, hence it allows you to create an instance of an already running application. QTP isn't exposed in this fashion but it still hooks the already running instance. I am not up on COM so I am not so sure the inner workings of this.
If you download C# Express (Download | Microsoft Visual Studio 2012), you can reference the DLL that you're working with and view the entry point of the DLL (You could also do this with .NET Reflector). The .NET languages are strongly typed, so you don't have to wonder if what you're passing is correct or not, it will let you know. Then take this knowledge back to QTP and attempt the same steps you used with .NET code.
The bridge would be your last option as it requires external sources and makes it a pain for others to run. I doubt you'll have to go down this path as VBS should be able to do what's required to run the application.
If you need help with the .NET side, I would be happy to lend a hand.
Well people... it looks like this may be a dead end. Appears (from insider information) that the objects in question are in a Closed DLL. Thus no matter what I'm not getting in. I'll let you know, but it just has me shaking my head. Thanks to everyone who helped/responded so far.