What happened to the Messenger Plus! forums on msghelp.net?
Shoutbox » MsgHelp Archive » Messenger Plus! for Live Messenger » Scripting » Active Accessibility Objects and ReadInterfacePtr

Active Accessibility Objects and ReadInterfacePtr
Author: Message:
matty
Scripting Guru
*****


Posts: 8336
Reputation: 109
39 / Male / Flag
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:

Javascript 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
Profile E-Mail PM Find Quote Report
Choli
Elite Member
*****

Avatar
Choli

Posts: 4714
Reputation: 42
42 / Male / Flag
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?
Javascript 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
Javascript 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 ReadDWORD?
Messenger Plus! en espaņol:
<< http://www.msgpluslive.es/ >>
<< http://foro.msgpluslive.es/ >>
:plus4:
02-05-2010 05:44 PM
Profile PM Find Quote Report
matty
Scripting Guru
*****


Posts: 8336
Reputation: 109
39 / Male / Flag
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
Profile E-Mail PM Find Quote Report
Mnjul
forum super mod
******

Avatar
plz wub me

Posts: 5396
Reputation: 58
– / Other / Flag
Joined: Nov 2002
Status: Away
RE: Active Accessibility Objects and ReadInterfacePtr
I think it's WORD, as VARTYPE is type-defined unsigned short.
http://msdn.microsoft.com/en-us/library/aa910805.aspx
02-05-2010 06:45 PM
Profile PM Web Find Quote Report
matty
Scripting Guru
*****


Posts: 8336
Reputation: 109
39 / Male / Flag
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
Profile E-Mail PM Find Quote Report
Eljay
Elite Member
*****

Avatar
:O

Posts: 2949
Reputation: 77
– / Male / –
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 :P

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 :P
02-08-2010 10:36 PM
Profile PM Find Quote Report
matty
Scripting Guru
*****


Posts: 8336
Reputation: 109
39 / Male / Flag
Joined: Dec 2002
Status: Away
O.P. RE: Active Accessibility Objects and ReadInterfacePtr
This works thanks to Patchy!

Javascript 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
Profile E-Mail PM Find Quote Report
Eljay
Elite Member
*****

Avatar
:O

Posts: 2949
Reputation: 77
– / Male / –
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 :P 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
Profile PM Find Quote Report
« Next Oldest Return to Top Next Newest »


Threaded Mode | Linear Mode
View a Printable Version
Send this Thread to a Friend
Subscribe | Add to Favorites
Rate This Thread:

Forum Jump:

Forum Rules:
You cannot post new threads
You cannot post replies
You cannot post attachments
You can edit your posts
HTML is Off
myCode is On
Smilies are On
[img] Code is On