QA@IT
«回答へ戻る

2
 最初の質問ではメニューバーの内容のみしか取得が出来ませんでしたが、
 その後、子のアイテムを取得すれば良いことが判りました。
 
-^^^
+~~~
 private static CKeyControl GetControlInfo()
 {
 	// アクティブなウィンドウハンドルの取得
 		ListAccObject(child);
 	}
 }
-^^^
 
+~~~
+
 これでGetControlInfo()内のループでメニューバーのアイテム名(「ファイル」「編集」「書式」「表示」「ヘルプ」)が取得でき、
 ListAccObject()内で「ファイル」メニューの各項目名と、その中で選ばれている(ハイライトしている)項目が判別できるようになりました。
 しかし、これで取得出来たのは「ファイル」(先頭のメニュー)の子のみであり、「編集」や「表示」といったメニューの項目が得られずです。
 対象を右へ移動しながら子を得れば良いのかと考え、
 GetControlInfo()内を以下の様に書き換えました。
 
-^^^
+~~~
 AccessibleObjectFromWindow(hWndControl, OBJID.ID_MENU, out acc);
 object child = acc.accNavigate(NAVDIR_FIRSTCHILD, 0);
 while (child != null)
 	ListAccObject((IAccessible)child);
 	child = acc.accNavigate(NAVDIR_RIGHT, child);
 }
-^^^
+~~~
 
 ですが目的通りに動作してくれずにつまづいています。
 accNavigateで、対象を「ファイル」「編集」「書式」・・・と切り替えるためには

少々状況が変わりましたので質問を若干変えさせていただきます。
最初の質問ではメニューバーの内容のみしか取得が出来ませんでしたが、
その後、子のアイテムを取得すれば良いことが判りました。

private static CKeyControl GetControlInfo()
{
    // アクティブなウィンドウハンドルの取得
    IntPtr hWnd = GetForegroundWindow();
    // フォーカスを持つウィンドウハンドルの取得
    IntPtr hWndControl = GetFocusedHandleFromProcessWithWindow(hWnd);
    IAccessible acc = null;

    AccessibleObjectFromWindow(hWndControl, OBJID.ID_MENU, out acc);
    int count = acc.accChildCount;
    for (int i = 1; i <= count; i++)
    {
        try
        {
            string ctrlName = acc.get_accName(i);
            string ctrlType = Enum.ToObject(typeof(System.Windows.Forms.AccessibleRole), acc.get_accRole(i)).ToString();
            string ctrlState = Enum.ToObject(typeof(System.Windows.Forms.AccessibleStates), acc.get_accState(i)).ToString();
            Debug.WriteLine(String.Format("[ACC{0}: CTRL-Name[{1}], Type[{2}], State[{3}]", i, ctrlName, ctrlType, ctrlState));
        }
        catch { }
    }

    ListAccObject(acc);
}

private static void ListAccObject(IAccessible acc)
{
    if (acc.accChildCount <= 0) return;

    int num = 0;
    object[] obj = GetAccessibleChildren(acc, out num);

    foreach (IAccessible child in obj)
    {
        string ctrlName = String.Empty;
        string ctrlState = String.Empty;
        string ctrlType = String.Empty;

        int count = child.accChildCount;
        Debug.WriteLine("count = " + count);

        for (int i = 0; i < count; i++)
        {
            try
            {
                ctrlName = child.get_accName(i);
                ctrlType = Enum.ToObject(typeof(System.Windows.Forms.AccessibleRole), child.get_accRole(i)).ToString();
                ctrlState = Enum.ToObject(typeof(System.Windows.Forms.AccessibleStates), child.get_accState(i)).ToString();

                Debug.WriteLine(String.Format("{0}: CTRL-Name[{1}], Type[{2}], State[{3}]", i, ctrlName, ctrlType, ctrlState));
            }
            catch { }
        }

        ListAccObject(child);
    }
}

これでGetControlInfo()内のループでメニューバーのアイテム名(「ファイル」「編集」「書式」「表示」「ヘルプ」)が取得でき、
ListAccObject()内で「ファイル」メニューの各項目名と、その中で選ばれている(ハイライトしている)項目が判別できるようになりました。
しかし、これで取得出来たのは「ファイル」(先頭のメニュー)の子のみであり、「編集」や「表示」といったメニューの項目が得られずです。

そこで、accNavigateなるメソッドの存在を知り、
対象を右へ移動しながら子を得れば良いのかと考え、
GetControlInfo()内を以下の様に書き換えました。

AccessibleObjectFromWindow(hWndControl, OBJID.ID_MENU, out acc);
object child = acc.accNavigate(NAVDIR_FIRSTCHILD, 0);
while (child != null)
{
    ListAccObject((IAccessible)child);
    child = acc.accNavigate(NAVDIR_RIGHT, child);
}

ですが目的通りに動作してくれずにつまづいています。
accNavigateで、対象を「ファイル」「編集」「書式」・・・と切り替えるためには
この方法ではNGでしょうか。

何かアドバイスをいただけると大変助かります。
宜しくお願い致します。

少々状況が変わりましたので質問を若干変えさせていただきます。
最初の質問ではメニューバーの内容のみしか取得が出来ませんでしたが、
その後、子のアイテムを取得すれば良いことが判りました。

~~~
private static CKeyControl GetControlInfo()
{
	// アクティブなウィンドウハンドルの取得
	IntPtr hWnd = GetForegroundWindow();
	// フォーカスを持つウィンドウハンドルの取得
	IntPtr hWndControl = GetFocusedHandleFromProcessWithWindow(hWnd);
	IAccessible acc = null;

	AccessibleObjectFromWindow(hWndControl, OBJID.ID_MENU, out acc);
	int count = acc.accChildCount;
	for (int i = 1; i <= count; i++)
	{
	    try
	    {
	        string ctrlName = acc.get_accName(i);
	        string ctrlType = Enum.ToObject(typeof(System.Windows.Forms.AccessibleRole), acc.get_accRole(i)).ToString();
	        string ctrlState = Enum.ToObject(typeof(System.Windows.Forms.AccessibleStates), acc.get_accState(i)).ToString();
	        Debug.WriteLine(String.Format("[ACC{0}: CTRL-Name[{1}], Type[{2}], State[{3}]", i, ctrlName, ctrlType, ctrlState));
	    }
	    catch { }
	}

	ListAccObject(acc);
}

private static void ListAccObject(IAccessible acc)
{
	if (acc.accChildCount <= 0) return;

	int num = 0;
	object[] obj = GetAccessibleChildren(acc, out num);

	foreach (IAccessible child in obj)
	{
		string ctrlName = String.Empty;
		string ctrlState = String.Empty;
		string ctrlType = String.Empty;

		int count = child.accChildCount;
		Debug.WriteLine("count = " + count);

		for (int i = 0; i < count; i++)
		{
			try
			{
				ctrlName = child.get_accName(i);
				ctrlType = Enum.ToObject(typeof(System.Windows.Forms.AccessibleRole), child.get_accRole(i)).ToString();
				ctrlState = Enum.ToObject(typeof(System.Windows.Forms.AccessibleStates), child.get_accState(i)).ToString();

				Debug.WriteLine(String.Format("{0}: CTRL-Name[{1}], Type[{2}], State[{3}]", i, ctrlName, ctrlType, ctrlState));
			}
			catch { }
		}

		ListAccObject(child);
	}
}

~~~

これでGetControlInfo()内のループでメニューバーのアイテム名(「ファイル」「編集」「書式」「表示」「ヘルプ」)が取得でき、
ListAccObject()内で「ファイル」メニューの各項目名と、その中で選ばれている(ハイライトしている)項目が判別できるようになりました。
しかし、これで取得出来たのは「ファイル」(先頭のメニュー)の子のみであり、「編集」や「表示」といったメニューの項目が得られずです。

そこで、accNavigateなるメソッドの存在を知り、
対象を右へ移動しながら子を得れば良いのかと考え、
GetControlInfo()内を以下の様に書き換えました。

~~~
AccessibleObjectFromWindow(hWndControl, OBJID.ID_MENU, out acc);
object child = acc.accNavigate(NAVDIR_FIRSTCHILD, 0);
while (child != null)
{
	ListAccObject((IAccessible)child);
	child = acc.accNavigate(NAVDIR_RIGHT, child);
}
~~~

ですが目的通りに動作してくれずにつまづいています。
accNavigateで、対象を「ファイル」「編集」「書式」・・・と切り替えるためには
この方法ではNGでしょうか。

何かアドバイスをいただけると大変助かります。
宜しくお願い致します。

回答を投稿

少々状況が変わりましたので質問を若干変えさせていただきます。
最初の質問ではメニューバーの内容のみしか取得が出来ませんでしたが、
その後、子のアイテムを取得すれば良いことが判りました。

^^^
private static CKeyControl GetControlInfo()
{
// アクティブなウィンドウハンドルの取得
IntPtr hWnd = GetForegroundWindow();
// フォーカスを持つウィンドウハンドルの取得
IntPtr hWndControl = GetFocusedHandleFromProcessWithWindow(hWnd);
IAccessible acc = null;

AccessibleObjectFromWindow(hWndControl, OBJID.ID_MENU, out acc);
int count = acc.accChildCount;
for (int i = 1; i <= count; i++)
{
    try
    {
        string ctrlName = acc.get_accName(i);
        string ctrlType = Enum.ToObject(typeof(System.Windows.Forms.AccessibleRole), acc.get_accRole(i)).ToString();
        string ctrlState = Enum.ToObject(typeof(System.Windows.Forms.AccessibleStates), acc.get_accState(i)).ToString();
        Debug.WriteLine(String.Format("[ACC{0}: CTRL-Name[{1}], Type[{2}], State[{3}]", i, ctrlName, ctrlType, ctrlState));
    }
    catch { }
}

ListAccObject(acc);

}

private static void ListAccObject(IAccessible acc)
{
if (acc.accChildCount <= 0) return;

int num = 0;
object[] obj = GetAccessibleChildren(acc, out num);

foreach (IAccessible child in obj)
{
    string ctrlName = String.Empty;
    string ctrlState = String.Empty;
    string ctrlType = String.Empty;

    int count = child.accChildCount;
    Debug.WriteLine("count = " + count);

    for (int i = 0; i < count; i++)
    {
        try
        {
            ctrlName = child.get_accName(i);
            ctrlType = Enum.ToObject(typeof(System.Windows.Forms.AccessibleRole), child.get_accRole(i)).ToString();
            ctrlState = Enum.ToObject(typeof(System.Windows.Forms.AccessibleStates), child.get_accState(i)).ToString();

            Debug.WriteLine(String.Format("{0}: CTRL-Name[{1}], Type[{2}], State[{3}]", i, ctrlName, ctrlType, ctrlState));
        }
        catch { }
    }

    ListAccObject(child);
}

}
^^^

これでGetControlInfo()内のループでメニューバーのアイテム名(「ファイル」「編集」「書式」「表示」「ヘルプ」)が取得でき、
ListAccObject()内で「ファイル」メニューの各項目名と、その中で選ばれている(ハイライトしている)項目が判別できるようになりました。
しかし、これで取得出来たのは「ファイル」(先頭のメニュー)の子のみであり、「編集」や「表示」といったメニューの項目が得られずです。

そこで、accNavigateなるメソッドの存在を知り、
対象を右へ移動しながら子を得れば良いのかと考え、
GetControlInfo()内を以下の様に書き換えました。

^^^
AccessibleObjectFromWindow(hWndControl, OBJID.ID_MENU, out acc);
object child = acc.accNavigate(NAVDIR_FIRSTCHILD, 0);
while (child != null)
{
ListAccObject((IAccessible)child);
child = acc.accNavigate(NAVDIR_RIGHT, child);
}
^^^

ですが目的通りに動作してくれずにつまづいています。
accNavigateで、対象を「ファイル」「編集」「書式」・・・と切り替えるためには
この方法ではNGでしょうか。

何かアドバイスをいただけると大変助かります。
宜しくお願い致します。

少々状況が変わりましたので質問を若干変えさせていただきます。
最初の質問ではメニューバーの内容のみしか取得が出来ませんでしたが、
その後、子のアイテムを取得すれば良いことが判りました。

^^^
private static CKeyControl GetControlInfo()
{
	// アクティブなウィンドウハンドルの取得
	IntPtr hWnd = GetForegroundWindow();
	// フォーカスを持つウィンドウハンドルの取得
	IntPtr hWndControl = GetFocusedHandleFromProcessWithWindow(hWnd);
	IAccessible acc = null;

	AccessibleObjectFromWindow(hWndControl, OBJID.ID_MENU, out acc);
	int count = acc.accChildCount;
	for (int i = 1; i <= count; i++)
	{
	    try
	    {
	        string ctrlName = acc.get_accName(i);
	        string ctrlType = Enum.ToObject(typeof(System.Windows.Forms.AccessibleRole), acc.get_accRole(i)).ToString();
	        string ctrlState = Enum.ToObject(typeof(System.Windows.Forms.AccessibleStates), acc.get_accState(i)).ToString();
	        Debug.WriteLine(String.Format("[ACC{0}: CTRL-Name[{1}], Type[{2}], State[{3}]", i, ctrlName, ctrlType, ctrlState));
	    }
	    catch { }
	}

	ListAccObject(acc);
}

private static void ListAccObject(IAccessible acc)
{
	if (acc.accChildCount <= 0) return;

	int num = 0;
	object[] obj = GetAccessibleChildren(acc, out num);

	foreach (IAccessible child in obj)
	{
		string ctrlName = String.Empty;
		string ctrlState = String.Empty;
		string ctrlType = String.Empty;

		int count = child.accChildCount;
		Debug.WriteLine("count = " + count);

		for (int i = 0; i < count; i++)
		{
			try
			{
				ctrlName = child.get_accName(i);
				ctrlType = Enum.ToObject(typeof(System.Windows.Forms.AccessibleRole), child.get_accRole(i)).ToString();
				ctrlState = Enum.ToObject(typeof(System.Windows.Forms.AccessibleStates), child.get_accState(i)).ToString();

				Debug.WriteLine(String.Format("{0}: CTRL-Name[{1}], Type[{2}], State[{3}]", i, ctrlName, ctrlType, ctrlState));
			}
			catch { }
		}

		ListAccObject(child);
	}
}
^^^

これでGetControlInfo()内のループでメニューバーのアイテム名(「ファイル」「編集」「書式」「表示」「ヘルプ」)が取得でき、
ListAccObject()内で「ファイル」メニューの各項目名と、その中で選ばれている(ハイライトしている)項目が判別できるようになりました。
しかし、これで取得出来たのは「ファイル」(先頭のメニュー)の子のみであり、「編集」や「表示」といったメニューの項目が得られずです。

そこで、accNavigateなるメソッドの存在を知り、
対象を右へ移動しながら子を得れば良いのかと考え、
GetControlInfo()内を以下の様に書き換えました。

^^^
AccessibleObjectFromWindow(hWndControl, OBJID.ID_MENU, out acc);
object child = acc.accNavigate(NAVDIR_FIRSTCHILD, 0);
while (child != null)
{
	ListAccObject((IAccessible)child);
	child = acc.accNavigate(NAVDIR_RIGHT, child);
}
^^^

ですが目的通りに動作してくれずにつまづいています。
accNavigateで、対象を「ファイル」「編集」「書式」・・・と切り替えるためには
この方法ではNGでしょうか。

何かアドバイスをいただけると大変助かります。
宜しくお願い致します。