none
oleacc.dll AccessibleChildren - How to access Children of a Scollview, when they out of visible scroll area. RRS feed

  • Question

  • Hi,

    i want to process the Filelist of a Windows Explorer from another Process. (Vista, Windows 7)
    So i have the handle of that Window that displays the Files of a Directory, and i process that window using AccessibleChildren from oleacc.dll.

    Unfortunally AccessibleChildren only returns the items that visable with current scollbars. So how can i access all items of that List?

    Here is a codesnippet that demonstrate what i'm doing so far: 

    [DllImport("oleacc.dll")]
    public static extern int AccessibleObjectFromWindow(IntPtr hwnd, uint dwObjectID, ref Guid refID, ref Accessibility.IAccessible ppvObject);
    [DllImport("oleacc.dll")]
    public static extern int AccessibleChildren(Accessibility.IAccessible paccContainer, int iChildStart, int cChildren, [Out] object[] rgvarChildren, out int pcObtained);

    IntPtr hWnd = <Handle of Filelist (right side) within Windows Explorer>

    Accessibility.IAccessible ia=null;
    Win32.AccessibleObjectFromWindow(hWnd, (uint)OLEACC_OBJID.CLIENT, ref Win32.OLEACC_IID_IAccessible, ref ia);

    int _ChildCount = ia.accChildCount; // Returns only the items that currently visible

    object[] _Children = new object[_ChildCount];
    int _out;
    Win32.AccessibleChildren(ia, 0, _ChildCount - 1, _Children, out _out);

    for (int iChild = 0; iChild < _Children.Length; iChild++)
    {
    // Process List Items
    }

    does someone knows a solution?

    best regards
    Torsten

    Tuesday, July 3, 2012 9:34 AM

All replies

  • Hi Torsten,

    Can you post the whole complete code here?

    Have a nice day.


    Ghost,
    Call me ghost for short, Thanks
    To get the better answer, it should be a better question.

    Monday, July 9, 2012 6:42 AM
  • If an item is not visible, what kind of operation you want to apply to those invisible items? if you just want to get a list of child files' name, .NET has FileInfo and DirectoryInfo class for this purpose, as long as you get the folder path from explorer.

    Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This can be beneficial to other community members reading the thread.

    Regards,
    Eric Yang
    Microsoft Online Community Support

    Wednesday, July 18, 2012 8:30 AM
  • right back from holiday...

    i know FileInfo and DirectoryInfo class. My project is a more generic solution to extract Text from other Application Windows.
    (e.g. Filelist from Windows Explorer, Taskmanger, ...)
    Than the user can paste the extractet Text in other Applications (Word, excel, etc) 

    Here some more code that shows what i'm doing so far:


    if (this.spy.ClassName.ToLower().IndexOf("syslistview32") >= 0)
    {
      // e.g. for Windows-Explorer under xp:
      DoSysListView32(this.spy.HWnd);
    }
    if (this.spy.ClassName.ToLower().IndexOf("directuihwnd") >= 0)
    {
      // e.g. for Windows-Explorer under vista and above
      DoDirectUIWnd(this.spy.HWnd);
    }

    private void DoDirectUIWnd(IntPtr hWnd)
    {
      this.listView.Columns.Clear();
      this.listView.Items.Clear();

      Accessibility.IAccessible ia=null;
      //IAccessible
      try
      {
         Win32.AccessibleObjectFromWindow(hWnd, (uint)OLEACC_OBJID.CLIENT, ref Win32.OLEACC_IID_IAccessible, ref ia);
         if (ia != null)
         {
           object acc_State = ia.get_accState((int)OLEACC_OBJID.WINDOW);
           object acc_Role = ia.get_accRole((int)OLEACC_OBJID.WINDOW);
           if (acc_Role != null)
           {
             this.edtClassName.Text += " [" + Enum.GetName(typeof(OLEACC_ROLEID), acc_Role) + "]";
             if (acc_Role.Equals((int)OLEACC_ROLEID.ROLE_SYSTEM_LIST))
             {
               DoDirectUIWnd_LIST(ia);
               return;
             }
             // handle other OLEACC_ROLEID here
           }
         }
       }
       catch(Exception ex)
       {
       }
    }

    private void DoDirectUIWnd_LIST(Accessibility.IAccessible ia)
    {
      int _ChildCount = ia.accChildCount;
      object[] _Children = new object[_ChildCount];
      int _out;
      Win32.AccessibleChildren(ia, 0, _ChildCount - 1, _Children, out _out);

      for (int iChild = 0; iChild < _Children.Length; iChild++)
      {
        Accessibility.IAccessible _child = _Children[iChild] as Accessibility.IAccessible;
        if (_child == null)
           continue;

        object acc_State = _child.get_accState((int)OLEACC_OBJID.WINDOW);
        object acc_Role = _child.get_accRole((int)OLEACC_OBJID.WINDOW);
        if (acc_Role != null)
        {
          if (acc_Role.Equals((int)OLEACC_ROLEID.ROLE_SYSTEM_LISTITEM))
          {
             DoDirectUIWnd_LISTITEM(_child);
          }
        }
      }
    }


    private void DoDirectUIWnd_LISTITEM(Accessibility.IAccessible ia)
    {
      int _ChildCount = ia.accChildCount;
      object[] _Children = new object[_ChildCount];
      int _out;
      Win32.AccessibleChildren(ia, 0, _ChildCount, _Children, out _out);
      ListViewItem lvItem = new ListViewItem();

      for (int iChild = 0; iChild < _Children.Length; iChild++)
      {
        Accessibility.IAccessible _child = _Children[iChild] as Accessibility.IAccessible;
        if (_child == null)
          continue;

         object acc_State = _child.get_accState((int)OLEACC_OBJID.WINDOW);
         object acc_Role = _child.get_accRole((int)OLEACC_OBJID.WINDOW);
         if (acc_Role != null && acc_Role.Equals((int)OLEACC_ROLEID.ROLE_SYSTEM_TEXT))
         {
           string _accName = null;
           string _accValue = null;
           try
           {
             _accName = _child.get_accName((int)OLEACC_OBJID.WINDOW);
             _accValue = _child.get_accValue((int)OLEACC_OBJID.WINDOW);
           }
           catch
           {
          
           }

           if (_accName == null)
             continue;
           if (_accValue == null)
             _accValue = "";

           // Stuff tu put the content in my own ui:
           int col = this.FindColumnHeader(this.listView, _accName, true);
           if (col == 0)
           {
             lvItem.Text = _accValue;
           }
           if (col > 0)
           {
             while (lvItem.SubItems.Count <= col)
             {
               lvItem.SubItems.Add(""); 
             }
             lvItem.SubItems[col].Text = _accValue;
           }
         }
       }
       this.listView.Items.Add(lvItem);
    }

    best regards,
    Torsten

    Thursday, July 19, 2012 9:24 AM