Active Accessibility Objects and ReadInterfacePtr |
Author: |
Message: |
matty
Scripting Guru
Posts: 8336 Reputation: 109
39 / /
Joined: Dec 2002
Status: Away
|
O.P. Active Accessibility Objects and ReadInterfacePtr
Ok so for those who do not understand the code please at the moment don't ask about it. I am stumped on the following:
js code: if (Messenger.MyStatus === STATUS_UNKNOWN) {
Debug.DebuggingWindowVisible = true;
var hWnd = Interop.Call('user32', 'FindWindowExW', Messenger.ContactListWndHandle, 0, 'Main Window Class', '');
hWnd = Interop.Call('user32', 'FindWindowExW', hWnd, 0, 'DirectUIHWND', '');
var IID_IAccessible = Interop.Allocate(16);
with (IID_IAccessible) {
WriteDWORD(0, 0x618736E0);
WriteWORD(4, 0x3C3D);
WriteWORD(6, 0x11CF);
SetAt(8, 0x81);
SetAt(9, 0xc);
SetAt(10, 0x0);
SetAt(11, 0xaa);
SetAt(12, 0x0);
SetAt(13, 0x38);
SetAt(14, 0x9b);
SetAt(15, 0x71);
}
var pAccessibleData = Interop.Allocate(4);
if(Interop.Call('oleacc', 'AccessibleObjectFromWindow', hWnd, 0xFFFFFFFC /* OBJID_CLIENT */, IID_IAccessible, pAccessibleData) === 0) {
var iAccessible = pAccessibleData.ReadInterfacePtr(0);
if(iAccessible) {
var iAccessibleChildren = Interop.Allocate(16*iAccessible.accChildCount);
var iAccessibleChildrenFound = Interop.Allocate(4);
if (Interop.Call('oleacc', 'AccessibleChildren', iAccessible, 0, iAccessible.accChildCount, iAccessibleChildren, iAccessibleChildrenFound) === 0){
for (var i=0; i<iAccessibleChildrenFound.ReadDWORD(0); ++i) {
if (iAccessibleChildren.ReadDWORD(i*16) === 0x9 /* VT_DISPATCH */) {
var iAccessibleChild = iAccessibleChildren.ReadInterfacePtr(i*16+8);
if (iAccessibleChild) {
try{
>>> Debug.Trace(iAccessible.accName(iAccessibleChild));<<<
}catch(e){
Debug.Trace('epic fail #5');
}
} else {
Debug.Trace('epic fail #4');
}
}
else {
Debug.Trace('epic ail #3');
}
}
}
else {
Debug.Trace('epic ail #2');
}
}
else {
Debug.Trace('epic ail #1');
}
}
}
Currently I have no problem getting the initial iAccessible interface. The problem lies with being able to get even the Names of the child objects.
I have tried many different variations for the highlighted code but to no avail. Note the code only works on the contact list window that is not signed in yet.
I have tried - iAccessibleChild.accName()
- Copying the pointer to a new databloc and using ReadInterfacePtr
- the list goes on; but I forget all that I have tried.
This post was edited on 02-03-2010 at 01:31 AM by matty.
|
|
02-03-2010 01:26 AM |
|
|
Choli
Elite Member
Choli
Posts: 4714 Reputation: 42
43 / /
Joined: Jan 2003
|
RE: Active Accessibility Objects and ReadInterfacePtr
quote: Originally posted by matty
iAccessibleChild.accName()
I'm not a expert in idispatch interfaces and these things but acording to IAccessible Interface it is either ".accName" (without parenthesis) or ".get_accName()". What I don't understand or know is if you have to use iAccessible.get_accName() or iAccessibleChild.get_accName()
quote: Originally posted by matty
Copying the pointer to a new databloc and using ReadInterfacePtr
with this you mean something like this?
js code: var temp = Interop.Allocate(4);
CopyMemory(temp, iAccessibleChildren.ReadDWORD(i*16+8), 4); // this copyMemory is this: http://msdn.microsoft.com/en-us/library/aa366535%28VS.85%29.aspx
var iAccessibleChild = temp.ReadInterfacePtr(0);
I don't know if this will work (because i don't understand if IDispatch is a pointer by itself or not (i'm a bit confused about what's being explained in VARIANT and VARIANTARG)
quote: Originally posted by matty
js code: if (iAccessibleChildren.ReadDWORD(i*16) === 0x9 /* VT_DISPATCH */) {
This is not the problem you're having, but don't you think that line should use ReadWORD instead of Read DWORD?
|
|
02-05-2010 05:44 PM |
|
|
matty
Scripting Guru
Posts: 8336 Reputation: 109
39 / /
Joined: Dec 2002
Status: Away
|
O.P. RE: Active Accessibility Objects and ReadInterfacePtr
quote: Originally posted by Choli
This is not the problem you're having, but don't you think that line should use ReadWORD instead of ReadDWORD?
Not by the looks of the VARIANT structure iAccessible uses:
http://msdn.microsoft.com/en-us/library/dd373687%28VS.85%29.aspx
|
|
02-05-2010 06:37 PM |
|
|
Mnjul
forum super mod
plz wub me
Posts: 5396 Reputation: 58
– / /
Joined: Nov 2002
Status: Away
|
|
02-05-2010 06:45 PM |
|
|
matty
Scripting Guru
Posts: 8336 Reputation: 109
39 / /
Joined: Dec 2002
Status: Away
|
O.P. RE: Active Accessibility Objects and ReadInterfacePtr
Interesting... I will give it a shot when I get home...
|
|
02-05-2010 07:01 PM |
|
|
Eljay
Elite Member
:O
Posts: 2949 Reputation: 77
– / / –
Joined: May 2004
|
RE: Active Accessibility Objects and ReadInterfacePtr
Just using .accName gets the property fine, the reason the exception is being thrown is that it is of type "unknown".
After many varied attempts at making it work, I have come to the conclusion JScript sucks at this stuff
Strangely enough, if you run it when signed in, all the children have accName type as unknown except for the advertisement area which actually returns a string containing the url of the advertisement. Even though the proper accName of that child should just be "Advertisement", with the url actually being the accName of another child of the Advertisement child, which I don't understand at all.
The only property that seems accessible is accChildCount, all others return type "unknown". Pity because this seems quite fun to play around with if it worked
|
|
02-08-2010 10:36 PM |
|
|
matty
Scripting Guru
Posts: 8336 Reputation: 109
39 / /
Joined: Dec 2002
Status: Away
|
O.P. RE: Active Accessibility Objects and ReadInterfacePtr
This works thanks to Patchy!
js code: if (Messenger.MyStatus === STATUS_UNKNOWN) {
Debug.DebuggingWindowVisible = true;
Debug.ClearDebuggingWindow();
var hWnd = Interop.Call('user32', 'FindWindowExW', Messenger.ContactListWndHandle, 0, 'Main Window Class', '');
hWnd = Interop.Call('user32', 'FindWindowExW', hWnd, 0, 'DirectUIHWND', '');
var IID_IAccessible = Interop.Allocate(16);
Interop.Call('ole32', 'IIDFromString', '{618736E0-3C3D-11CF-810C-00AA00389B71}', IID_IAccessible);
var pAccessibleData = Interop.Allocate(4);
if(Interop.Call('oleacc', 'AccessibleObjectFromWindow', hWnd, 0xFFFFFFFC, IID_IAccessible, pAccessibleData) === 0) {
var iAccessible = pAccessibleData.ReadInterfacePtr(0);
if(iAccessible) {
var iAccessibleChildren = Interop.Allocate(16*iAccessible.accChildCount);
var iAccessibleChildrenFound = Interop.Allocate(4);
if (Interop.Call('oleacc', 'AccessibleChildren', iAccessible, 0, iAccessible.accChildCount, iAccessibleChildren, iAccessibleChildrenFound) === 0){
Debug.Trace('Child Count: '+iAccessibleChildrenFound.ReadDWORD(0));
for (var i=0; i<iAccessibleChildrenFound.ReadDWORD(0); ++i) {
if (iAccessibleChildren.ReadDWORD(i*16) === 0x9) {
var iAccessibleChild = iAccessibleChildren.ReadInterfacePtr(i*16+8);
if (iAccessibleChild) {
try{
if (iAccessibleChild.accName(0).match ( /E-mail+/)) {
iAccessibleChild.accValue(0) = 'test@test.com';
}
if (iAccessibleChild.accName(0).match ( /Status+/)) {
//Doesn't work not sure why...
//iAccessibleChild.accValue(0) = 'Busy';
}
Debug.Trace(iAccessibleChild.accName(0)+': '+iAccessibleChild.accValue(0));
}catch(e){
//Most likely the password edit box as you cannot access it...
Debug.Trace(e.number + ' /\\ ' + e.description);
}
}
}
}
}
}
}
}
This post was edited on 02-09-2010 at 06:55 PM by matty.
|
|
02-09-2010 03:51 AM |
|
|
Eljay
Elite Member
:O
Posts: 2949 Reputation: 77
– / / –
Joined: May 2004
|
RE: Active Accessibility Objects and ReadInterfacePtr
Well that's an annoying simple way of doing it after all the crap I tried Now to clean up this mess you have created so it is actually useful!
Starting with the IID stuff which can just be done much simpler like so:
JScript code: Interop.Call('ole32', 'IIDFromString', '{618736E0-3C3D-11CF-810C-00AA00389B71}', IID_IAccessible);
It seems like a nice thing to make proper wrapper classes for, if only I could think of a good use for it...
|
|
02-09-2010 06:43 PM |
|
|
|
|