Jump to content

IUIAutomation MS framework automate chrome, FF, IE, ....


junkew
 Share

Recommended Posts

I get similar results. How do you interpret the value of $vt = 47663 (0xBA2F)? This seems to be an illegal value.

Since $iPropertyId = 30005 and 30005 means UIA_NamePropertyId which is represented by a BSTR, I would expect a value of vt = VT_BSTR (= 8). Or at least the last 8 bits to have a value of 8. And I would expect the data (the BSTR) to contain the value "Klok", because that's what we get from $oSender.

If we can't interpret $vt properly according to your link in post 358, how should we then be able to read the data of the variant. We need the variant type to read the data.

I still don't think we can use $newValue to get the data. That would have been much easier. I think we need $oSender to get the data.

Link to comment
Share on other sites

think we need people like @Trancexx or @Progandy

  • No clue how to get directly the data out of the $newValue which just should be a normal variant coming in
  • for me the workaround by getting the property myself is fine not sure why getting it directly would be nicer/better/quicker if it could work

not sure if the  0x00000008 neccesarily refers to the VT_BSTR value,
I have seen multiple others flowing by for $newValue so assume its a pointer location
 
oIUIAutomationPropertyChangedEventHandler_HandlePropertyChangedEvent: $iPropertyId = 30005, $newValue = 0x00020008
 
 

oIUIAutomationPropertyChangedEventHandler_HandlePropertyChangedEvent: $iPropertyId = 30005, $newValue = 0x00010008
AutomationId    303
Handle    65712
Name      Klok
Class     TrayClockWClass
Ctrl type 50033
Ctrl name deelvenster
Value     18:44, ?zondag, ?1-?2-?2015
NewValue     Klok
  • apparently also breaking on 
    oIUIAutomationPropertyChangedEventHandler_HandlePropertyChangedEvent: $iPropertyId = 30005, $newValue = 0x00020008
    oIUIAutomationPropertyChangedEventHandler_HandlePropertyChangedEvent: $iPropertyId = 30005, $newValue = 0x00170008
  • Definitions in CUIAutomation2 looks fine to me but anyway tried with the commented ones to
    Global $dtagIUIAutomationPropertyChangedEventHandler = "HandlePropertyChangedEvent hresult(ptr;int;variant);"
    ;~ Global $dtagIUIAutomationPropertyChangedEventHandler = "HandlePropertyChangedEvent hresult(ptr;int;variant*);"
    ;~ Global $dtagIUIAutomationPropertyChangedEventHandler = "HandlePropertyChangedEvent hresult(ptr;int;ptr*);"
    However found this with google so could be above definition is incorrect
    public void HandlePropertyChangedEvent(IUIAutomationElement elem, int propertyID, object obj)
  • running it thru dr memory
oIUIAutomationPropertyChangedEventHandler_HandlePropertyChangedEvent: $iPropertyId = 30005, $newValue = 0x00010008
~~Dr.M~~
~~Dr.M~~ Error #22: UNINITIALIZED READ: reading register esi
~~Dr.M~~ # 0 OLEAUT32.dll!VariantCopy                        +0xb      (0x75bf48fc <OLEAUT32.dll+0x48fc>)
~~Dr.M~~ # 1 ex34_events.exe!?                               +0x0      (0x00e6edc9 <ex34_events.exe+0x1edc9>)
~~Dr.M~~ # 2 ex34_events.exe!?                               +0x0      (0x00eafbdf <ex34_events.exe+0x5fbdf>)
~~Dr.M~~ # 3 ex34_events.exe!?                               +0x0      (0x00eb0d19 <ex34_events.exe+0x60d19>)
~~Dr.M~~ # 4 ex34_events.exe!?                               +0x0      (0x00e60cf3 <ex34_events.exe+0x10cf3>)
~~Dr.M~~ # 5 ex34_events.exe!?                               +0x0      (0x00e63f4b <ex34_events.exe+0x13f4b>)
~~Dr.M~~ # 6 ex34_events.exe!?                               +0x0      (0x00e5ef8c <ex34_events.exe+0xef8c>)
~~Dr.M~~ # 7 ex34_events.exe!?                               +0x0      (0x00e5eb87 <ex34_events.exe+0xeb87>)
~~Dr.M~~ # 8 ex34_events.exe!?                               +0x0      (0x00e634eb <ex34_events.exe+0x134eb>)
~~Dr.M~~ # 9 ex34_events.exe!?                               +0x0      (0x00e5ecc5 <ex34_events.exe+0xecc5>)
~~Dr.M~~ #10 ex34_events.exe!?                               +0x0      (0x00e52af4 <ex34_events.exe+0x2af4>)
~~Dr.M~~ #11 ex34_events.exe!?                               +0x0      (0x00eb0bed <ex34_events.exe+0x60bed>)
~~Dr.M~~ #12 RPCRT4.dll!NdrServerInitialize                  +0x23f    (0x763b5932 <RPCRT4.dll+0x35932>)
~~Dr.M~~ #13 RPCRT4.dll!NdrStubCall2                         +0x255    (0x764305f1 <RPCRT4.dll+0xb05f1>)
~~Dr.M~~ #14 ole32.dll!WdtpInterfacePointer_UserUnmarshal    +0x256e   (0x74ecd7e6 <ole32.dll+0x13d7e6>)
~~Dr.M~~ #15 OLEAUT32.dll!CreateErrorInfo                    +0x267    (0x75bfffd3 <OLEAUT32.dll+0xffd3>)
~~Dr.M~~ #16 ole32.dll!WdtpInterfacePointer_UserUnmarshal    +0x25fe   (0x74ecd876 <ole32.dll+0x13d876>)
~~Dr.M~~ #17 ole32.dll!WdtpInterfacePointer_UserUnmarshal    +0x2b58   (0x74ecddd0 <ole32.dll+0x13ddd0>)
~~Dr.M~~ #18 ole32.dll!CoTaskMemFree                         +0x1b01   (0x74de8a43 <ole32.dll+0x58a43>)
~~Dr.M~~ #19 ole32.dll!CoTaskMemFree                         +0x19f6   (0x74de8938 <ole32.dll+0x58938>)
~~Dr.M~~ Note: @0:00:29.867 in thread 4260
~~Dr.M~~ Note: instruction: movzx  (%esi) -> %edi
$vt = 0;00000000;4;0
AutomationId    303
Handle    65712
Name      Klok
Class     TrayClockWClass
Ctrl type 50033
Ctrl name deelvenster
Value     19:44, ?zondag, ?1-?2-?2015
NewValue     Klok

oIUIAutomationPropertyChangedEventHandler_HandlePropertyChangedEvent: $iPropertyId = 30005, $newValue = 0x00020008
~~Dr.M~~
~~Dr.M~~ Error #23: UNADDRESSABLE ACCESS: reading 0x00000000-0x00000002 2 byte(s)
~~Dr.M~~ # 0 OLEAUT32.dll!VariantClear                       +0x9      (0x75bf3eb7 <OLEAUT32.dll+0x3eb7>)
~~Dr.M~~ # 1 OLEAUT32.dll!VariantCopy                        +0x24     (0x75bf4916 <OLEAUT32.dll+0x4916>)
~~Dr.M~~ # 2 ex34_events.exe!?                               +0x0      (0x00e6edc9 <ex34_events.exe+0x1edc9>)
~~Dr.M~~ # 3 ex34_events.exe!?                               +0x0      (0x00eafbdf <ex34_events.exe+0x5fbdf>)
~~Dr.M~~ # 4 ex34_events.exe!?                               +0x0      (0x00eb0d19 <ex34_events.exe+0x60d19>)
~~Dr.M~~ # 5 ex34_events.exe!?                               +0x0      (0x00e60cf3 <ex34_events.exe+0x10cf3>)
~~Dr.M~~ # 6 ex34_events.exe!?                               +0x0      (0x00e63f4b <ex34_events.exe+0x13f4b>)
~~Dr.M~~ # 7 ex34_events.exe!?                               +0x0      (0x00e5ef8c <ex34_events.exe+0xef8c>)
~~Dr.M~~ # 8 ex34_events.exe!?                               +0x0      (0x00e5eb87 <ex34_events.exe+0xeb87>)
~~Dr.M~~ # 9 ex34_events.exe!?                               +0x0      (0x00e634eb <ex34_events.exe+0x134eb>)
~~Dr.M~~ #10 ex34_events.exe!?                               +0x0      (0x00e5ecc5 <ex34_events.exe+0xecc5>)
~~Dr.M~~ #11 ex34_events.exe!?                               +0x0      (0x00e52af4 <ex34_events.exe+0x2af4>)
~~Dr.M~~ #12 ex34_events.exe!?                               +0x0      (0x00eb0bed <ex34_events.exe+0x60bed>)
~~Dr.M~~ #13 RPCRT4.dll!NdrServerInitialize                  +0x23f    (0x763b5932 <RPCRT4.dll+0x35932>)
~~Dr.M~~ #14 RPCRT4.dll!NdrStubCall2                         +0x255    (0x764305f1 <RPCRT4.dll+0xb05f1>)
~~Dr.M~~ #15 ole32.dll!WdtpInterfacePointer_UserUnmarshal    +0x256e   (0x74ecd7e6 <ole32.dll+0x13d7e6>)
~~Dr.M~~ #16 OLEAUT32.dll!CreateErrorInfo                    +0x267    (0x75bfffd3 <OLEAUT32.dll+0xffd3>)
~~Dr.M~~ #17 ole32.dll!WdtpInterfacePointer_UserUnmarshal    +0x25fe   (0x74ecd876 <ole32.dll+0x13d876>)
~~Dr.M~~ #18 ole32.dll!WdtpInterfacePointer_UserUnmarshal    +0x2b58   (0x74ecddd0 <ole32.dll+0x13ddd0>)
~~Dr.M~~ #19 ole32.dll!CoTaskMemFree                         +0x1b01   (0x74de8a43 <ole32.dll+0x58a43>)
~~Dr.M~~ Note: @0:00:53.476 in thread 4260
~~Dr.M~~ Note: instruction: movzx  (%esi) -> %eax
Edited by junkew
Link to comment
Share on other sites

I'll make a test with some C++ code when I get the time for it. Then it's possible to inspect that variant more directly than it is in AutoIt.

Link to comment
Share on other sites

c++code only reveals that tagVariant needs an unsigned short instead of word but makes no difference

code below in vc++10 express edition (and windows 7 sdk stuff)

 

reveals a standard variant type. Based on the variant you should be able to get data out of the variant $newValue

 

probably some messing up between 32 and 64 bit windows versions

 

https://msdn.microsoft.com/en-us/library/windows/desktop/ff625914(v=vs.85).aspx#PropertyChangedHandler

 
// Defines an event handler for property-changed events, and listens for
// ToggleState property changes on the element specifies by the user.
#include <windows.h>
#include <stdio.h>
#include "StdAfx.h"
#include <UIAutomation.h>
 
class EventHandler:
    public IUIAutomationPropertyChangedEventHandler
{
private:
    LONG _refCount;
 
public:
    int _eventCount;
 
    //Constructor.
    EventHandler(): _refCount(1), _eventCount(0) 
    {
    }
 
    //IUnknown methods.
    ULONG STDMETHODCALLTYPE AddRef() 
    {
        ULONG ret = InterlockedIncrement(&_refCount);
        return ret;
    }
 
    ULONG STDMETHODCALLTYPE Release() 
    {
        ULONG ret = InterlockedDecrement(&_refCount);
        if (ret == 0) 
        {
            delete this;
            return 0;
        }
        return ret;
    }
 
    HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppInterface) 
    {
        if (riid == __uuidof(IUnknown))
            *ppInterface=static_cast<IUIAutomationPropertyChangedEventHandler*>(this);
        else if (riid == __uuidof(IUIAutomationPropertyChangedEventHandler)) 
            *ppInterface=static_cast<IUIAutomationPropertyChangedEventHandler*>(this);
        else 
        {
            *ppInterface = NULL;
            return E_NOINTERFACE;
        }
        this->AddRef();
        return S_OK;
    }
 
    // IUIAutomationPropertyChangedEventHandler methods.
    HRESULT STDMETHODCALLTYPE HandlePropertyChangedEvent(IUIAutomationElement* pSender, PROPERTYID propertyID, VARIANT newValue) 
    {
        _eventCount++;
        if (propertyID == UIA_ToggleToggleStatePropertyId) 
            wprintf(L">> Property ToggleState changed! ");
        else 
            wprintf(L">> Property (%d) changed! ", propertyID);
 
        if (newValue.vt == VT_I4) 
            wprintf(L"(0x%0.8x) ", newValue.lVal);
 
        wprintf(L"(count: %d)\n", _eventCount);
        return S_OK;
    }
};
 
int _tmain(int argc, _TCHAR* argv[])
{
    HRESULT hr;
    int ret = 0;
    IUIAutomationElement* pTargetElement = NULL;
    EventHandler* pEHTemp = NULL;
 
    CoInitializeEx(NULL,COINIT_MULTITHREADED);
 
    IUIAutomation* pAutomation = NULL;
    hr = CoCreateInstance(__uuidof(CUIAutomation), NULL, CLSCTX_INPROC_SERVER, __uuidof(IUIAutomation), (void**)&pAutomation);
    if (FAILED(hr) || pAutomation==NULL) 
    {
        ret = 1;
        goto cleanup;
    }
 
    wprintf(L"-Use the mouse to point to the element you want to listen from.\n");
    Sleep(3000);
 
    // Make this application dots-per-inch (DPI) aware.
    SetProcessDPIAware();
 
    // Get mouse cursor position and get element from point.
    POINT pt;
    GetPhysicalCursorPos(&pt);
    hr = pAutomation->ElementFromPoint(pt, &pTargetElement);
    if (FAILED(hr) || pTargetElement==NULL) 
    {
        ret = 1;
        goto cleanup;
    }
 
    pEHTemp = new EventHandler();
    if (pEHTemp == NULL) 
    {
        ret = 1;
        goto cleanup;
    }
 
    PROPERTYID pPIDProperties[] = { UIA_ToggleToggleStatePropertyId, UIA_NamePropertyId, UIA_AutomationIdPropertyId };
 
    wprintf(L"-Adding Event Handler.\n");
    hr = pAutomation->AddPropertyChangedEventHandlerNativeArray(pTargetElement, TreeScope_Subtree, NULL, (IUIAutomationPropertyChangedEventHandler*) pEHTemp, pPIDProperties, sizeof(pPIDProperties) / sizeof(pPIDProperties[0]));
    if (FAILED(hr)) 
    {
        ret = 1;
        goto cleanup;
    }
 
    wprintf(L"-Press any key to remove event handler and exit\n");
    getchar();
 
    wprintf(L"-Removing Event Handler.\n");
    hr = pAutomation->RemovePropertyChangedEventHandler(pTargetElement, (IUIAutomationPropertyChangedEventHandler*) pEHTemp);
    if (FAILED(hr)) 
    {
        ret = 1;
        goto cleanup;
    }
 
    // Release resources and terminate.
cleanup:
    if (pEHTemp != NULL) 
        pEHTemp->Release();
 
    if (pTargetElement != NULL) 
        pTargetElement->Release();
 
    if (pAutomation != NULL) 
        pAutomation->Release();
 
    CoUninitialize();
    return ret;
}
 
//int _tmain(int argc, _TCHAR* argv[])
//{
// return 0;
//}
Edited by junkew
Link to comment
Share on other sites

  • 3 weeks later...

please post a topic in general help and support and include output from simplespy.

Without any of that information its impossible to help

If possible find a generic reproducer of your problem

And do not forget to turn accessibility on in chrome

Link to comment
Share on other sites

Hi,

So there is not any simple function to send an e-mail automatically. I hope a simple function like this will exists in AutoIt built-in functions. 

SendAnEmail("ID","Subject", "Attachment1_file_path", "Attachment2_file_path",....)

This function will automatically opens chrome, and login to my gmail id. If i already logged in, then press the compose button and fill the ID area and subject and attach all the attachments and send the email. Can i get a simple function like this one? 

Spoiler

My Contributions

Glance GUI Library - A gui library based on Windows api functions. Written in Nim programming language.

UDF Link Viewer   --- A tool to visit the links of some most important UDFs 

 Includer_2  ----- A tool to type the #include statement automatically 

 Digits To Date  ----- date from 3 integer values

PrintList ----- prints arrays into console for testing.

 Alert  ------ An alternative for MsgBox 

 MousePosition ------- A simple tooltip display of mouse position

GRM Helper -------- A littile tool to help writing code with GUIRegisterMsg function

Access_UDF  -------- An UDF for working with access database files. (.*accdb only)

 

Link to comment
Share on other sites

yes, you can if you start coding with the simple functions in the iuiautomation library.

but for sure doing it thru UI interfaces is most likely not efficient and/or fast

suggestion is to post in general help and support of even in gmail forums

https://developers.google.com/gmail/api/guides/sending

http://en.wikipedia.org/wiki/Collaboration_Data_Objects

https://developers.google.com/gmail/api/downloads

Link to comment
Share on other sites

Hi junkew,

Thanks. let me read that links.

Spoiler

My Contributions

Glance GUI Library - A gui library based on Windows api functions. Written in Nim programming language.

UDF Link Viewer   --- A tool to visit the links of some most important UDFs 

 Includer_2  ----- A tool to type the #include statement automatically 

 Digits To Date  ----- date from 3 integer values

PrintList ----- prints arrays into console for testing.

 Alert  ------ An alternative for MsgBox 

 MousePosition ------- A simple tooltip display of mouse position

GRM Helper -------- A littile tool to help writing code with GUIRegisterMsg function

Access_UDF  -------- An UDF for working with access database files. (.*accdb only)

 

Link to comment
Share on other sites

Hi. I have a problem with run examples.

 

UIAWrappers.au3"(978,81) : warning: $STR_REGEXPMATCH: possibly used before declaration.

$iMatch = StringRegExp($propertyActualValue, $propertyVal, $STR_REGEXPMATCH)

 

I wrote some scripts but every time I run it I get new logfile - How can I disable it?

Also I have some problem with grids (DataGridCell). I can read row, column etc - But how I can read value in that grid?

Thanks for helping me

Link to comment
Share on other sites

I have installed the framework and simplespy seems to be working fine.

I adjusted all the variables, but not sure on this one:

const $cToolbarByName = "name:=Google Chrome Toolbar"  

What is the Toolbar element?

 

Running the code opens Chrome, but then i get this message:

"C:Documents and SettingsAdministratorDesktopchrome.au3" (35) : ==> Variable used without being declared.:
$oChrome=_UIA_getFirstObjectOfElement($oDesktop,"class:=Chrome_WidgetWin_1", $treescope_children)
 
 
Indeed i don't see oChrome declared anywhere? Should it be done by the includes or am i missing something?
 
EDIT must have a type as the downloaded example is working; will check tonight when more time :)
Edited by trekker
Link to comment
Share on other sites

A month ago, we had a discussion of a matter in post 337: How do we get information directly from the $newValue variant parameter in the callback function for the property changed event handler? The relevant posts are 349 and 357 - 364.

I have made a test with the following C++ code:

// Defines an event handler for property-changed events, and listens for
// ToggleState property changes on the element specifies by the user.
#include <windows.h>
#include <stdio.h>
#include <UIAutomation.h>

void UIAPrintProperty( IUIAutomationElement *pUIAutomationElement, PROPERTYID propertyId, char *text ) {
  VARIANT v;
  pUIAutomationElement->GetCurrentPropertyValue( propertyId, &v );
  if ( v.vt == VT_I4 )
  if ( strcmp( text, "Handle   " ) == 0 )
    printf( "   %s: 0x%p\n", text, v.lVal);
  else
    printf( "   %s: %d\n", text, v.lVal);
  else if ( v.vt == VT_BSTR ) {
  printf( "   %s: ", text );
  wprintf( L"%s\n", v.bstrVal ); }
}

class EventHandler:
  public IUIAutomationPropertyChangedEventHandler
{
private:
  LONG _refCount;

public:
  int _eventCount;

  //Constructor.
  EventHandler(): _refCount(1), _eventCount(0) 
  {
  }

  //IUnknown methods.
  ULONG STDMETHODCALLTYPE AddRef() 
  {
    ULONG ret = InterlockedIncrement(&_refCount);
    return ret;
  }

  ULONG STDMETHODCALLTYPE Release() 
  {
    ULONG ret = InterlockedDecrement(&_refCount);
    if (ret == 0) 
    {
      delete this;
      return 0;
    }
    return ret;
  }

  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppInterface) 
  {
    if (riid == __uuidof(IUnknown))
      *ppInterface=static_cast<IUIAutomationPropertyChangedEventHandler*>(this);
    else if (riid == __uuidof(IUIAutomationPropertyChangedEventHandler)) 
      *ppInterface=static_cast<IUIAutomationPropertyChangedEventHandler*>(this);
    else 
    {
      *ppInterface = NULL;
      return E_NOINTERFACE;
    }
    this->AddRef();
    return S_OK;
  }

  // IUIAutomationPropertyChangedEventHandler methods.
  HRESULT STDMETHODCALLTYPE HandlePropertyChangedEvent(IUIAutomationElement* pSender, PROPERTYID propertyID, VARIANT newValue) 
  {
    _eventCount++;
    wprintf(L">> Property %d changed. ", propertyID);

    wprintf(L"newValue.vt = %d. ", newValue.vt);
    if (newValue.vt == VT_I4) 
      wprintf(L"0x%0.8x. ", newValue.lVal);
    else if ( newValue.vt == VT_BSTR )
      wprintf( L"newValue.bstrVal = %s.\n", newValue.bstrVal );

    //wprintf(L"Count: %d\n", _eventCount);

    UIAPrintProperty( pSender, UIA_NativeWindowHandlePropertyId,     "Handle   " );
    UIAPrintProperty( pSender, UIA_NamePropertyId,                   "Name     " );
    UIAPrintProperty( pSender, UIA_ClassNamePropertyId,              "Class    " );
    UIAPrintProperty( pSender, UIA_ControlTypePropertyId,            "Ctrl type" );
    UIAPrintProperty( pSender, UIA_LocalizedControlTypePropertyId,   "Ctrl name" );
    UIAPrintProperty( pSender, UIA_LegacyIAccessibleValuePropertyId, "Value    " );

    return S_OK;
  }
};

int main(int argc, char* argv[]) 
{
  HRESULT hr;
  int ret = 0;
  IUIAutomationElement* pTargetElement = NULL;
  EventHandler* pEHTemp = NULL;

  CoInitializeEx(NULL,COINIT_MULTITHREADED);

  IUIAutomation* pAutomation = NULL;
  hr = CoCreateInstance(__uuidof(CUIAutomation), NULL, CLSCTX_INPROC_SERVER, __uuidof(IUIAutomation), (void**)&pAutomation);
  if (FAILED(hr) || pAutomation==NULL) 
  {
    ret = 1;
    goto cleanup;
  }

  wprintf(L"-Use the mouse to point to the element you want to listen from.\n");
  Sleep(3000);

  // Make this application dots-per-inch (DPI) aware.
  //SetProcessDPIAware();

  // Get mouse cursor position and get element from point.
  POINT pt;
  GetCursorPos(&pt);
  //GetPhysicalCursorPos(&pt);
  hr = pAutomation->ElementFromPoint(pt, &pTargetElement);
  if (FAILED(hr) || pTargetElement==NULL) 
  {
    ret = 1;
    goto cleanup;
  }

  pEHTemp = new EventHandler();
  if (pEHTemp == NULL) 
  {
    ret = 1;
    goto cleanup;
  }

  //PROPERTYID pPIDProperties[] = { UIA_ToggleToggleStatePropertyId };
  PROPERTYID pPIDProperties[] = { UIA_NamePropertyId };

  wprintf(L"-Adding Event Handler.\n");
  hr = pAutomation->AddPropertyChangedEventHandlerNativeArray(pTargetElement, TreeScope_Subtree, NULL, (IUIAutomationPropertyChangedEventHandler*) pEHTemp, pPIDProperties, sizeof(pPIDProperties) / sizeof(pPIDProperties[0]));
  if (FAILED(hr)) 
  {
    ret = 1;
    goto cleanup;
  }

  wprintf(L"-Press any key to remove event handler and exit\n");
  getchar();

  wprintf(L"-Removing Event Handler.\n");
  hr = pAutomation->RemovePropertyChangedEventHandler(pTargetElement, (IUIAutomationPropertyChangedEventHandler*) pEHTemp);
  if (FAILED(hr)) 
  {
    ret = 1;
    goto cleanup;
  }

  // Release resources and terminate.
cleanup:
  if (pEHTemp != NULL) 
    pEHTemp->Release();

  if (pTargetElement != NULL) 
    pTargetElement->Release();

  if (pAutomation != NULL) 
    pAutomation->Release();

  CoUninitialize();
  return ret;
}

Because the issue in post 337 is about name property changes, I'm using UIA_NamePropertyId instead of UIA_ToggleToggleStatePropertyId.

To test the code you need some name property changes. A control where the name changes regularly, so you can see some events. You can find such controls in Windows Task Manager. In the status bar in the bottom of the window you find three labels that shows some numbers. These numbers are added directly to the label name. When the numbers are updated and added to the label name, it generates name property change events.

This is the output for the CPU Usage:

-Use the mouse to point to the element you want to listen from.
-Adding Event Handler.
-Press any key to remove event handler and exit
>> Property 30005 changed. newValue.vt = 8. newValue.bstrVal = CPU Usage: 1%.
   Handle   : 0x00000000
   Name     : CPU Usage: 1%
   Class    :
   Ctrl type: 50020
   Ctrl name: text
   Value    :
>> Property 30005 changed. newValue.vt = 8. newValue.bstrVal = CPU Usage: 1%.
   Handle   : 0x00000000
   Name     : CPU Usage: 1%
   Class    :
   Ctrl type: 50020
   Ctrl name: text
   Value    :
>> Property 30005 changed. newValue.vt = 8. newValue.bstrVal = CPU Usage: 1%.
   Handle   : 0x00000000
   Name     : CPU Usage: 1%
   Class    :
   Ctrl type: 50020
   Ctrl name: text
   Value    :
>> Property 30005 changed. newValue.vt = 8. newValue.bstrVal = CPU Usage: 1%.
   Handle   : 0x00000000
   Name     : CPU Usage: 1%
   Class    :
   Ctrl type: 50020
   Ctrl name: text
   Value    :
>> Property 30005 changed. newValue.vt = 8. newValue.bstrVal = CPU Usage: 0%.
   Handle   : 0x00000000
   Name     : CPU Usage: 0%
   Class    :
   Ctrl type: 50020
   Ctrl name: text
   Value    :
>> Property 30005 changed. newValue.vt = 8. newValue.bstrVal = CPU Usage: 1%.
   Handle   : 0x00000000
   Name     : CPU Usage: 1%
   Class    :
   Ctrl type: 50020
   Ctrl name: text
   Value    :
>> Property 30005 changed. newValue.vt = 8. newValue.bstrVal = CPU Usage: 1%.
   Handle   : 0x00000000
   Name     : CPU Usage: 1%
   Class    :
   Ctrl type: 50020
   Ctrl name: text
   Value    :
>> Property 30005 changed. newValue.vt = 8. newValue.bstrVal = CPU Usage: 1%.
   Handle   : 0x00000000
   Name     : CPU Usage: 1%
   Class    :
   Ctrl type: 50020
   Ctrl name: text
   Value    :
>> Property 30005 changed. newValue.vt = 8. newValue.bstrVal = CPU Usage: 1%.
   Handle   : 0x00000000
   Name     : CPU Usage: 1%
   Class    :
   Ctrl type: 50020
   Ctrl name: text
   Value    :
>> Property 30005 changed. newValue.vt = 8. newValue.bstrVal = CPU Usage: 5%.
   Handle   : 0x00000000
   Name     : CPU Usage: 5%
   Class    :
   Ctrl type: 50020
   Ctrl name: text
   Value    :
>> Property 30005 changed. newValue.vt = 8. newValue.bstrVal = CPU Usage: 0%.
   Handle   : 0x00000000
   Name     : CPU Usage: 0%
   Class    :
   Ctrl type: 50020
   Ctrl name: text
   Value    :
>> Property 30005 changed. newValue.vt = 8. newValue.bstrVal = CPU Usage: 0%.
   Handle   : 0x00000000
   Name     : CPU Usage: 0%
   Class    :
   Ctrl type: 50020
   Ctrl name: text
   Value    :
>> Property 30005 changed. newValue.vt = 8. newValue.bstrVal = CPU Usage: 1%.
   Handle   : 0x00000000
   Name     : CPU Usage: 1%
   Class    :
   Ctrl type: 50020
   Ctrl name: text
   Value    :
>> Property 30005 changed. newValue.vt = 8. newValue.bstrVal = CPU Usage: 1%.
   Handle   : 0x00000000
   Name     : CPU Usage: 1%
   Class    :
   Ctrl type: 50020
   Ctrl name: text
   Value    :
>> Property 30005 changed. newValue.vt = 8. newValue.bstrVal = CPU Usage: 0%.
   Handle   : 0x00000000
   Name     : CPU Usage: 0%
   Class    :
   Ctrl type: 50020
   Ctrl name: text
   Value    :
>> Property 30005 changed. newValue.vt = 8. newValue.bstrVal = CPU Usage: 1%.
   Handle   : 0x00000000
   Name     : CPU Usage: 1%
   Class    :
   Ctrl type: 50020
   Ctrl name: text
   Value    :
>> Property 30005 changed. newValue.vt = 8. newValue.bstrVal = CPU Usage: 7%.
   Handle   : 0x00000000
   Name     : CPU Usage: 7%
   Class    :
   Ctrl type: 50020
   Ctrl name: text
   Value    :
>> Property 30005 changed. newValue.vt = 8. newValue.bstrVal = CPU Usage: 4%.
   Handle   : 0x00000000
   Name     : CPU Usage: 4%
   Class    :
   Ctrl type: 50020
   Ctrl name: text
   Value    :
>> Property 30005 changed. newValue.vt = 8. newValue.bstrVal = CPU Usage: 2%.
   Handle   : 0x00000000
   Name     : CPU Usage: 2%
   Class    :
   Ctrl type: 50020
   Ctrl name: text
   Value    :
>> Property 30005 changed. newValue.vt = 8. newValue.bstrVal = CPU Usage: 4%.
   Handle   : 0x00000000
   Name     : CPU Usage: 4%
   Class    :
   Ctrl type: 50020
   Ctrl name: text
   Value    :

The output is as expected: 30005 is the name property, the variant type vt = 8 is a BSTR, and the variant value bstrVal = "CPU Usage: 1%" matches the name property from the sender object (pSender).

If you make the same test with this AutoIt code:

#include "CUIAutomation2.au3"
#include "SafeArray.au3"
 
Opt( "MustDeclareVars", 1 )
 
Global Const $S_OK = 0x00000000
Global Const $E_NOINTERFACE = 0x80004002
Global Const $sIID_IUnknown = "{00000000-0000-0000-C000-000000000046}"
Global Const $tagVARIANT = "word vt;word r1;word r2;word r3;ptr data; ptr;"
 
Global $tIUIAutomationPropertyChangedEventHandler, $oIUIAutomationPropertyChangedEventHandler
 
Global $oUIAutomation
 
MainFunc()
 
 
 
Func MainFunc()
 
  $oIUIAutomationPropertyChangedEventHandler = ObjectFromTag( "oIUIAutomationPropertyChangedEventHandler_", $dtagIUIAutomationPropertyChangedEventHandler, $tIUIAutomationPropertyChangedEventHandler, True )
  If Not IsObj( $oIUIAutomationPropertyChangedEventHandler ) Then Return
 
  $oUIAutomation = ObjCreateInterface( $sCLSID_CUIAutomation, $sIID_IUIAutomation, $dtagIUIAutomation )
  If Not IsObj( $oUIAutomation ) Then Return
 
  Local $pUIElement
  $oUIAutomation.GetRootElement( $pUIElement ) ; Desktop
  If Not $pUIElement Then Return
 
#cs
  ; Use this code to call the AddPropertyChangedEventHandlerNativeArray method, which takes a normal array of property identifiers instead of a SAFEARRAY.
  ; Because of threading issues, calling this method instead of AddPropertyChangedEventHandler may lead to unexpected/incomplete results.
  Local $tPropertyArray = DllStructCreate( "int[2]" )
  DllStructSetData( $tPropertyArray, 1, $UIA_NamePropertyId, 1 )
  DllStructSetData( $tPropertyArray, 1, $UIA_ToggleToggleStatePropertyId, 2 )
  $oUIAutomation.AddPropertyChangedEventHandlerNativeArray( $pUIElement, $TreeScope_Descendants, 0, $oIUIAutomationPropertyChangedEventHandler, $tPropertyArray, 2 )
#ce
 
  ; Use this code to call the AddPropertyChangedEventHandlerNativeArray method, which takes a pointer to a SAFEARRAY of property identifiers.
  ; Because of threading issues, calling this method instead of AddPropertyChangedEventHandler appears to be preferable for automation of some applications.
 
  ; Create a SAFEARRAY vector having a number of rows equal to the number of property identifiers you will be monitoring for changes
  Local $ptrSafeArray = SafeArrayCreateVector( "int", 2 )
 
  ; Write SAFEARRAY structure
  Local Const $tagSAFEARRAY = "ushort cDims; ushort fFeatures; ulong cbElements; ulong cLocks; ptr pvData; ulong cElements; long lLbound"
  Local $tSAFEARRAY = DllStructCreate( $tagSAFEARRAY, $ptrSafeArray )
 
#cs
  ConsoleWrite( @CRLF & "SafeArray structure" & @CRLF )
  ConsoleWrite( "$tSAFEARRAY size       = " & DllStructGetSize( $tSAFEARRAY ) & @CRLF )
  ConsoleWrite( "$tSAFEARRAY cDims      = " & DllStructGetData( $tSAFEARRAY, "cDims" ) & @CRLF )
  ConsoleWrite( "$tSAFEARRAY fFeatures  = " & "0x" & Hex( DllStructGetData( $tSAFEARRAY, "fFeatures" ) ) & @CRLF )
  ConsoleWrite( "$tSAFEARRAY cbElements = " & DllStructGetData( $tSAFEARRAY, "cbElements" ) & @CRLF )
  ConsoleWrite( "$tSAFEARRAY cLocks     = " & DllStructGetData( $tSAFEARRAY, "cLocks" ) & @CRLF )
  ConsoleWrite( "$tSAFEARRAY pvData     = " & DllStructGetData( $tSAFEARRAY, "pvData" ) & @CRLF )
  ConsoleWrite( "$tSAFEARRAY cElements  = " & DllStructGetData( $tSAFEARRAY, "cElements" ) & @CRLF )
  ConsoleWrite( "$tSAFEARRAY lLbound    = " & DllStructGetData( $tSAFEARRAY, "lLbound" ) & @CRLF )
#ce
 
 
  ; Put the property identifiers corresponding to the properties you will be monitoring as elements into the SafeArray
  SafeArrayPutElement( $ptrSafeArray, 0, $UIA_NamePropertyId )
  ;SafeArrayPutElement( $ptrSafeArray, 1, $UIA_AutomationIdPropertyId )
 
  #cs
  Local $pValue
  ConsoleWrite( @CRLF & "Get the two conditions" & @CRLF )
  SafeArrayGetElement( $ptrSafeArray, 0, $pValue )
  ConsoleWrite( "int 1 = " &  $pValue & @CRLF )
  SafeArrayGetElement( $ptrSafeArray, 1, $pValue )
  ConsoleWrite( "int 2 = " &  $pValue & @CRLF )
  #ce
 
  ; Add the PropertyChangedEventHandler
  $oUIAutomation.AddPropertyChangedEventHandler( $pUIElement, $TreeScope_Descendants, 0, $oIUIAutomationPropertyChangedEventHandler, Ptr($ptrSafeArray))
 
  HotKeySet( "{ESC}", "Quit" )
 
  While Sleep(100)
  WEnd

  SafeArrayDestroy( $ptrSafeArray )
 
EndFunc
 
Func Quit()
  $oIUIAutomationPropertyChangedEventHandler = 0
  DeleteObjectFromTag( $tIUIAutomationPropertyChangedEventHandler )
  Exit
EndFunc
 
 
 
Func _UIA_getPropertyValue( $obj, $id )
  Local $vVal
  $obj.GetCurrentPropertyValue( $id, $vVal )
  Return $vVal
EndFunc

Func oIUIAutomationPropertyChangedEventHandler_HandlePropertyChangedEvent( $pSelf, $pSender, $iPropertyId, $newValue ) ; Ret: long  Par: ptr;int;ptr
  ConsoleWrite( @CRLF & "oIUIAutomationPropertyChangedEventHandler_HandlePropertyChangedEvent: $iPropertyId = " & $iPropertyId & ", $newValue = " & $newValue & @CRLF )

  Local $oSender = ObjCreateInterface( $pSender, $sIID_IUIAutomationElement, $dtagIUIAutomationElement )
  $oSender.AddRef()
 
  ConsoleWrite( "Handle    " & _UIA_getPropertyValue( $oSender, $UIA_NativeWindowHandlePropertyId ) & @CRLF )
  ConsoleWrite( "Name      " & _UIA_getPropertyValue( $oSender, $UIA_NamePropertyId ) & @CRLF )
  ConsoleWrite( "Class     " & _UIA_getPropertyValue( $oSender, $UIA_ClassNamePropertyId ) & @CRLF )
  ConsoleWrite( "Ctrl type " & _UIA_getPropertyValue( $oSender, $UIA_ControlTypePropertyId ) & @CRLF )
  ConsoleWrite( "Ctrl name " & _UIA_getPropertyValue( $oSender, $UIA_LocalizedControlTypePropertyId ) & @CRLF )
  ConsoleWrite( "Value     " & _UIA_getPropertyValue( $oSender, $UIA_LegacyIAccessibleValuePropertyId ) & @CRLF )
 
  Return $S_OK
EndFunc

Func oIUIAutomationPropertyChangedEventHandler_QueryInterface( $pSelf, $pRIID, $pObj ) ; Ret: long  Par: ptr;ptr*
  Local $sIID = StringFromGUID( $pRIID )
  If $sIID = $sIID_IUnknown Then
    ConsoleWrite( "oIUIAutomationPropertyChangedEventHandler_QueryInterface: IUnknown" & @CRLF )
    DllStructSetData( DllStructCreate( "ptr", $pObj ), 1, $pSelf )
    Return $S_OK
  ElseIf $sIID = $sIID_IUIAutomationPropertyChangedEventHandler Then
    ConsoleWrite( "oIUIAutomationPropertyChangedEventHandler_QueryInterface: IUIAutomationPropertyChangedEventHandler" & @CRLF )
    DllStructSetData( DllStructCreate( "ptr", $pObj ), 1, $pSelf )
    Return $S_OK
  Else
    ConsoleWrite( "oIUIAutomationPropertyChangedEventHandler_QueryInterface: " & $sIID & @CRLF )
    Return $E_NOINTERFACE
  EndIf
EndFunc
 
Func oIUIAutomationPropertyChangedEventHandler_AddRef( $pSelf ) ; Ret: ulong
  ConsoleWrite( "oIUIAutomationPropertyChangedEventHandler_AddRef" & @CRLF )
  Return 1
EndFunc
 
Func oIUIAutomationPropertyChangedEventHandler_Release( $pSelf ) ; Ret: ulong
  ConsoleWrite( "oIUIAutomationPropertyChangedEventHandler_Release" & @CRLF )
  Return 1
EndFunc
 
 
 
Func StringFromGUID( $pGUID )
  Local $aResult = DllCall( "ole32.dll", "int", "StringFromGUID2", "struct*", $pGUID, "wstr", "", "int", 40 )
  If @error Then Return SetError( @error, @extended, "" )
  Return SetExtended( $aResult[0], $aResult[2] )
EndFunc
 
 
 
Func ObjectFromTag($sFunctionPrefix, $tagInterface, ByRef $tInterface, $fPrint = False, $bIsUnknown = Default, $sIID = "{00000000-0000-0000-C000-000000000046}") ; last param is IID_IUnknown by default
    If $bIsUnknown = Default Then $bIsUnknown = True
    Local $sInterface = $tagInterface ; copy interface description
    Local $tagIUnknown = "QueryInterface hresult(ptr;ptr*);" & _
            "AddRef dword();" & _
            "Release dword();"
    ; Adding IUnknown methods
    If $bIsUnknown Then $tagInterface = $tagIUnknown & $tagInterface
    ; Below line is really simple even though it looks super complex. It's just written weird to fit in one line, not to steal your attention
    Local $aMethods = StringSplit(StringReplace(StringReplace(StringReplace(StringReplace(StringTrimRight(StringReplace(StringRegExpReplace(StringRegExpReplace($tagInterface, "\w+\*", "ptr"), "\h*(\w+)\h*(\w+\*?)\h*(\((.*?)\))\h*(;|;*\z)", "$1\|$2;$4" & @LF), ";" & @LF, @LF), 1), "object", "idispatch"), "hresult", "long"), "bstr", "ptr"), "variant", "ptr"), @LF, 3)
    Local $iUbound = UBound($aMethods)
    Local $sMethod, $aSplit, $sNamePart, $aTagPart, $sTagPart, $sRet, $sParams, $hCallback
    ; Allocation
    $tInterface = DllStructCreate("int RefCount;int Size;ptr Object;ptr Methods[" & $iUbound & "];int_ptr Callbacks[" & $iUbound & "];ulong_ptr Slots[16]") ; 16 pointer sized elements more to create space for possible private props
    If @error Then Return SetError(1, 0, 0)
    For $i = 0 To $iUbound - 1
        $aSplit = StringSplit($aMethods[$i], "|", 2)
        If UBound($aSplit) <> 2 Then ReDim $aSplit[2]
        $sNamePart = $aSplit[0]
        $sTagPart = $aSplit[1]
        $sMethod = $sFunctionPrefix & $sNamePart
        If $fPrint Then
            Local $iPar = StringInStr( $sTagPart, ";", 2 ), $t
            If $iPar Then
                $t = "Ret: " & StringLeft( $sTagPart, $iPar - 1 ) & "  " & _
                     "Par: " & StringRight( $sTagPart, StringLen( $sTagPart ) - $iPar )
            Else
                $t = "Ret: " & $sTagPart
            EndIf
            Local $s = "Func " & $sMethod & _
                "( $pSelf ) ; " & $t & @CRLF & _
                "EndFunc" & @CRLF
            ConsoleWrite( $s )
        EndIf
        $aTagPart = StringSplit($sTagPart, ";", 2)
        $sRet = $aTagPart[0]
        $sParams = StringReplace($sTagPart, $sRet, "", 1)
        $sParams = "ptr" & $sParams
        $hCallback = DllCallbackRegister($sMethod, $sRet, $sParams)
        ConsoleWrite(@error & @CRLF & @CRLF)
        DllStructSetData($tInterface, "Methods", DllCallbackGetPtr($hCallback), $i + 1) ; save callback pointer
        DllStructSetData($tInterface, "Callbacks", $hCallback, $i + 1) ; save callback handle
    Next
    DllStructSetData($tInterface, "RefCount", 1) ; initial ref count is 1
    DllStructSetData($tInterface, "Size", $iUbound) ; number of interface methods
    DllStructSetData($tInterface, "Object", DllStructGetPtr($tInterface, "Methods")) ; Interface method pointers
    Return ObjCreateInterface(DllStructGetPtr($tInterface, "Object"), $sIID, $sInterface, $bIsUnknown) ; pointer that's wrapped into object
EndFunc
 
Func DeleteObjectFromTag(ByRef $tInterface)
    For $i = 1 To DllStructGetData($tInterface, "Size")
        DllCallbackFree(DllStructGetData($tInterface, "Callbacks", $i))
    Next
    $tInterface = 0
EndFunc

You'll get output like this:

HandlePropertyChangedEvent: $iPropertyId = 30005, $newValue = 0x00000008
Handle    0
Name      Processes: 56
Class     
Ctrl type 50020
Ctrl name text
Value     

HandlePropertyChangedEvent: $iPropertyId = 30005, $newValue = 0x00000008
Handle    0
Name      CPU Usage: 10%
Class     
Ctrl type 50020
Ctrl name text
Value     

HandlePropertyChangedEvent: $iPropertyId = 30005, $newValue = 0x00000008
Handle    0
Name      Commit Charge: 1101M / 3938M
Class     
Ctrl type 50020
Ctrl name text
Value     

HandlePropertyChangedEvent: $iPropertyId = 30005, $newValue = 0x00000008
Handle    0
Name      Processes: 56
Class     
Ctrl type 50020
Ctrl name text
Value     

HandlePropertyChangedEvent: $iPropertyId = 30005, $newValue = 0x00000008
Handle    0
Name      CPU Usage: 10%
Class     
Ctrl type 50020
Ctrl name text
Value     

HandlePropertyChangedEvent: $iPropertyId = 30005, $newValue = 0x00000008
Handle    0
Name      Commit Charge: 1101M / 3938M
Class     
Ctrl type 50020
Ctrl name text
Value     

HandlePropertyChangedEvent: $iPropertyId = 30005, $newValue = 0x00000008
Handle    0
Name      Processes: 56
Class     
Ctrl type 50020
Ctrl name text
Value     

HandlePropertyChangedEvent: $iPropertyId = 30005, $newValue = 0x00000008
Handle    0
Name      CPU Usage: 4%
Class     
Ctrl type 50020
Ctrl name text
Value     

HandlePropertyChangedEvent: $iPropertyId = 30005, $newValue = 0x00000008
Handle    0
Name      Commit Charge: 1101M / 3938M
Class     
Ctrl type 50020
Ctrl name text
Value     

HandlePropertyChangedEvent: $iPropertyId = 30005, $newValue = 0x00000008
Handle    0
Name      Processes: 56
Class     
Ctrl type 50020
Ctrl name text
Value     

HandlePropertyChangedEvent: $iPropertyId = 30005, $newValue = 0x00000008
Handle    0
Name      CPU Usage: 21%
Class     
Ctrl type 50020
Ctrl name text
Value     

HandlePropertyChangedEvent: $iPropertyId = 30005, $newValue = 0x00000008
Handle    0
Name      Commit Charge: 1102M / 3938M
Class     
Ctrl type 50020
Ctrl name text
Value     

HandlePropertyChangedEvent: $iPropertyId = 30005, $newValue = 0x00000008
Handle    0
Name      Processes: 56
Class     
Ctrl type 50020
Ctrl name text
Value     

HandlePropertyChangedEvent: $iPropertyId = 30005, $newValue = 0x00000008
Handle    0
Name      CPU Usage: 3%
Class     
Ctrl type 50020
Ctrl name text
Value     

HandlePropertyChangedEvent: $iPropertyId = 30005, $newValue = 0x00000008
Handle    0
Name      Commit Charge: 1102M / 3938M
Class     
Ctrl type 50020
Ctrl name text
Value

The $newValue variant parameter with a value of 0x00000008 is expected to be a pointer. But this is not a pointer. This is the first element of the variant structure, which is the variant type. Here we have a variant type with a value of 8, which means that the data in the variant is a BSTR.

We expect a pointer, but we are not getting a pointer. There is definitely something wrong with the AutoIt code.

Why do we expect a pointer? Because a variant is replaced by a pointer in the ObjectFromTag function by trancexx (in the regular expression).

Why have trancexx replaced a variant with a pointer? Because the callback function is implemented with DllCallbackRegister. This function takes only simple variables as parameters. A variant can't be used as parameter.

A variant is defined as a structure:

Global Const $tagVARIANT = "word vt;word r1;word r2;word r3;ptr data; ptr;"
This is a 16 byte/128 bit structure on a 32 bit system, and a 24 byte/192 bit structure on a 64 bit system. But DllCallbackRegister can't take a structure as parameter. It can take a pointer as parameter. That's the reason why trancexx have replaced the variant with a pointer.

And now we are approaching the real problem. The HandlePropertyChangedEvent method of the IUIAutomationPropertyChangedEventHandler interface object does not take a pointer to a variant as parameter. It takes a variant structure as parameter.

HandlePropertyChangedEvent is implemented with DllCallbackRegister. HandlePropertyChangedEvent needs a variant structure as parameter. DllCallbackRegister can't handle a variant structure.

There seems not to be an easy solution for this problem.

Link to comment
Share on other sites

Although not working as expected whats wrong by retrieving the property within the event instead of using newvalue parameter. In other words what am i missing as usefull information now newvalue has not the information directly but just retrieving the actual value gives me same resukt.

Link to comment
Share on other sites

Nothing wrong with this at all. But it would be easier and faster to get the new value directly from the $newValue parameter without the need to create the $oSender object.

Link to comment
Share on other sites

I see there is partialy support for AFX controls.

I just trying to get text from "Afx:StatusBar:400000:8:10003:10"

And I have only negative results.

But maybe I'am doing something wrong ?

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor other useful stuff click the following button:

Spoiler

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. 

My contribution (my own projects): * Debenu Quick PDF Library - UDF * Debenu PDF Viewer SDK - UDF * Acrobat Reader - ActiveX Viewer * UDF for PDFCreator v1.x.x * XZip - UDF * AppCompatFlags UDF * CrowdinAPI UDF * _WinMergeCompare2Files() * _JavaExceptionAdd() * _IsBeta() * Writing DPI Awareness App - workaround * _AutoIt_RequiredVersion() * Chilkatsoft.au3 UDF * TeamViewer.au3 UDF * JavaManagement UDF * VIES over SOAP * WinSCP UDF * GHAPI UDF - modest begining - comunication with GitHub REST APIErrorLog.au3 UDF - A logging Library * Include Dependency Tree (Tool for analyzing script relations) * Show_Macro_Values.au3 *

 

My contribution to others projects or UDF based on  others projects: * _sql.au3 UDF  * POP3.au3 UDF *  RTF Printer - UDF * XML.au3 UDF * ADO.au3 UDF SMTP Mailer UDF * Dual Monitor resolution detection * * 2GUI on Dual Monitor System * _SciLexer.au3 UDF * SciTE - Lexer for console pane

Useful links: * Forum Rules * Forum etiquette *  Forum Information and FAQs * How to post code on the forum * AutoIt Online Documentation * AutoIt Online Beta Documentation * SciTE4AutoIt3 getting started * Convert text blocks to AutoIt code * Games made in Autoit * Programming related sites * Polish AutoIt Tutorial * DllCall Code Generator * 

Wiki: Expand your knowledge - AutoIt Wiki * Collection of User Defined Functions * How to use HelpFile * Good coding practices in AutoIt * 

OpenOffice/LibreOffice/XLS Related: WriterDemo.au3 * XLS/MDB from scratch with ADOX

IE Related:  * How to use IE.au3  UDF with  AutoIt v3.3.14.x * Why isn't Autoit able to click a Javascript Dialog? * Clicking javascript button with no ID * IE document >> save as MHT file * IETab Switcher (by LarsJ ) * HTML Entities * _IEquerySelectorAll() (by uncommon) * IE in TaskSchedulerIE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) * PDF Related:How to get reference to PDF object embeded in IE * IE on Windows 11

I encourage you to read: * Global Vars * Best Coding Practices * Please explain code used in Help file for several File functions * OOP-like approach in AutoIt * UDF-Spec Questions *  EXAMPLE: How To Catch ConsoleWrite() output to a file or to CMD *

I also encourage you to check awesome @trancexx code:  * Create COM objects from modules without any demand on user to register anything. * Another COM object registering stuffOnHungApp handlerAvoid "AutoIt Error" message box in unknown errors  * HTML editor

winhttp.au3 related : * https://www.autoitscript.com/forum/topic/206771-winhttpau3-download-problem-youre-speaking-plain-http-to-an-ssl-enabled-server-port/

"Homo sum; humani nil a me alienum puto" - Publius Terentius Afer
"Program are meant to be read by humans and only incidentally for computers and execute" - Donald Knuth, "The Art of Computer Programming"
:naughty:  :ranting:, be  :) and       \\//_.

Anticipating Errors :  "Any program that accepts data from a user must include code to validate that data before sending it to the data store. You cannot rely on the data store, ...., or even your programming language to notify you of problems. You must check every byte entered by your users, making sure that data is the correct type for its field and that required fields are not empty."

Signature last update: 2023-04-24

Link to comment
Share on other sites

Is the Spy tool able to identify and mark the control with a red box? If this is the case then please post the output.

If not then try to identify the control with Inspect.exe from Windows SDK.

Link to comment
Share on other sites

I PM you this because "some way" , for me, it is restricted content.

EDIT: There is Company name and Phone number, and maybe some other data.

Edited by mLipok

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor other useful stuff click the following button:

Spoiler

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. 

My contribution (my own projects): * Debenu Quick PDF Library - UDF * Debenu PDF Viewer SDK - UDF * Acrobat Reader - ActiveX Viewer * UDF for PDFCreator v1.x.x * XZip - UDF * AppCompatFlags UDF * CrowdinAPI UDF * _WinMergeCompare2Files() * _JavaExceptionAdd() * _IsBeta() * Writing DPI Awareness App - workaround * _AutoIt_RequiredVersion() * Chilkatsoft.au3 UDF * TeamViewer.au3 UDF * JavaManagement UDF * VIES over SOAP * WinSCP UDF * GHAPI UDF - modest begining - comunication with GitHub REST APIErrorLog.au3 UDF - A logging Library * Include Dependency Tree (Tool for analyzing script relations) * Show_Macro_Values.au3 *

 

My contribution to others projects or UDF based on  others projects: * _sql.au3 UDF  * POP3.au3 UDF *  RTF Printer - UDF * XML.au3 UDF * ADO.au3 UDF SMTP Mailer UDF * Dual Monitor resolution detection * * 2GUI on Dual Monitor System * _SciLexer.au3 UDF * SciTE - Lexer for console pane

Useful links: * Forum Rules * Forum etiquette *  Forum Information and FAQs * How to post code on the forum * AutoIt Online Documentation * AutoIt Online Beta Documentation * SciTE4AutoIt3 getting started * Convert text blocks to AutoIt code * Games made in Autoit * Programming related sites * Polish AutoIt Tutorial * DllCall Code Generator * 

Wiki: Expand your knowledge - AutoIt Wiki * Collection of User Defined Functions * How to use HelpFile * Good coding practices in AutoIt * 

OpenOffice/LibreOffice/XLS Related: WriterDemo.au3 * XLS/MDB from scratch with ADOX

IE Related:  * How to use IE.au3  UDF with  AutoIt v3.3.14.x * Why isn't Autoit able to click a Javascript Dialog? * Clicking javascript button with no ID * IE document >> save as MHT file * IETab Switcher (by LarsJ ) * HTML Entities * _IEquerySelectorAll() (by uncommon) * IE in TaskSchedulerIE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) * PDF Related:How to get reference to PDF object embeded in IE * IE on Windows 11

I encourage you to read: * Global Vars * Best Coding Practices * Please explain code used in Help file for several File functions * OOP-like approach in AutoIt * UDF-Spec Questions *  EXAMPLE: How To Catch ConsoleWrite() output to a file or to CMD *

I also encourage you to check awesome @trancexx code:  * Create COM objects from modules without any demand on user to register anything. * Another COM object registering stuffOnHungApp handlerAvoid "AutoIt Error" message box in unknown errors  * HTML editor

winhttp.au3 related : * https://www.autoitscript.com/forum/topic/206771-winhttpau3-download-problem-youre-speaking-plain-http-to-an-ssl-enabled-server-port/

"Homo sum; humani nil a me alienum puto" - Publius Terentius Afer
"Program are meant to be read by humans and only incidentally for computers and execute" - Donald Knuth, "The Art of Computer Programming"
:naughty:  :ranting:, be  :) and       \\//_.

Anticipating Errors :  "Any program that accepts data from a user must include code to validate that data before sending it to the data store. You cannot rely on the data store, ...., or even your programming language to notify you of problems. You must check every byte entered by your users, making sure that data is the correct type for its field and that required fields are not empty."

Signature last update: 2023-04-24

Link to comment
Share on other sites

You can get the text in the status bar with this code:

 

#include <CUIAutomation2.au3>

Example()

Func Example()

  ; Window handle
  Local $hWindow = WinGetHandle( "Info to identify window" ) ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  If Not $hWindow Then Return ConsoleWrite( "Window handle ERR" & @CRLF )
  ConsoleWrite( "Window handle OK" & @CRLF )

  ; Create UI Automation object
  Local $oUIAutomation = ObjCreateInterface( $sCLSID_CUIAutomation, $sIID_IUIAutomation, $dtagIUIAutomation )
  If Not IsObj( $oUIAutomation ) Then Return ConsoleWrite( "UI Automation object ERR" & @CRLF )
  ConsoleWrite( "UI Automation object OK" & @CRLF )

  ; Get UI Automation element from window handle
  Local $pWindow, $oWindow
  $oUIAutomation.ElementFromHandle( $hWindow, $pWindow )
  $oWindow = ObjCreateInterface( $pWindow, $sIID_IUIAutomationElement, $dtagIUIAutomationElement )
  If Not IsObj( $oWindow ) Then Return ConsoleWrite( "Automation element from window ERR" & @CRLF )
  ConsoleWrite( "Automation element from window OK" & @CRLF )

  ; Condition to find status bar
  Local $pCondition
  $oUIAutomation.CreatePropertyCondition( $UIA_ControlTypePropertyId, $UIA_ToolBarControlTypeId, $pCondition )
  If Not $pCondition Then Return ConsoleWrite( "Condition ERR" & @CRLF )
  ConsoleWrite( "Condition OK" & @CRLF )

  ; Find status bar
  Local $pStatusBar, $oStatusBar
  $oWindow.FindFirst( $TreeScope_Descendants, $pCondition, $pStatusBar )
  If Not $pStatusBar Then Return ConsoleWrite( "Status bar not found ERR" & @CRLF )
  $oStatusBar = ObjCreateInterface( $pStatusBar, $sIID_IUIAutomationElement, $dtagIUIAutomationElement )
  ConsoleWrite( "Status bar found OK" & @CRLF )

  ; Get name
  ConsoleWrite( _UIA_getPropertyValue( $oStatusBar, $UIA_NamePropertyId ) & @CRLF )

EndFunc


Func _UIA_getPropertyValue( $obj, $id )
  Local $tVal
  $obj.GetCurrentPropertyValue( $id, $tVal )
  If Not IsArray( $tVal ) Then Return $tVal
  Local $tStr = $tVal[0]
  For $i = 1 To UBound( $tVal ) - 1
    $tStr &= "; " & $tVal[$i]
  Next
  Return $tStr
EndFunc
Link to comment
Share on other sites

  • 3 weeks later...

@ junkew

Hi, I am interested in your udf. However, I cannot use it well. I want to automate firefox and the autoit report the following information:

>"C:Program Files (x86)AutoIt3SciTE..autoit3.exe" /ErrorStdOut "E:autoittestff.au3"    
"E:autoittestff.au3" (48) : ==> Variable used without being declared.:
$oFF=_UIA_getFirstObjectOfElement($oDesktop,"class:=MozillaWindowClass", $treescope_children)
$oFF=_UIA_getFirstObjectOfElement(^ ERROR

>Exit code: 1    Time: 14.41

My system is Win7 x64 firefox is Ver 36.0.4. 

How can I resolve this problem?

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...