0

私は次のタスクを解決しようとしています: 私は OPERA ブラウザを持っていて、いつでもキャレット (テキスト カーソル) が存在するかどうかを知りたいです。たとえば、アドレスバーをクリックすると、キャレットが点滅していることを知りたいとします。次に、ページの空の場所をクリックすると、キャレットが存在しないことがわかります。

言い換えれば、テキスト要素が現在フォーカスされていることを定義したいと思います。

多くのアプリケーションでこのタスクを解決する方法を知っています。そのうちのいくつかは、編集などの標準のウィンドウ コントロールを使用するため、フォーカスされたウィンドウを取得し、WinApi でそのクラスを確認できます。

コントロールがネイティブ ウィンドウなしでレンダリングされる他のアプリケーションでは、オートメーション UI でこれを取得できます。

残念ながら、Opera にはメイン ウィンドウが 1 つしかなく、UI 自動化テクノロジへのアクセスは提供されません。

それで、誰かが私の目標に近づく方法を知っていますか?)

編集:

Eric Brown に感謝します。これが問題の解決策です。

// ConsoleForMSAA.cpp: определяет точку входа для консольного приложения.
//

#include "stdafx.h"
#include <OleAcc.h>
#include <iostream>

#pragma comment (lib, "oleacc.lib")

void ProcessCaretPos(HWND hwnd);

int _tmain(int argc, _TCHAR* argv[])
{

    for (;;)
    {
        // active toplevel window
        HWND hwnd = GetForegroundWindow();

        // current thread
        DWORD currentThreadId = GetCurrentThreadId();

        DWORD targetThreadId, targetProcessId;

        // target process and thread
        targetThreadId = GetWindowThreadProcessId(hwnd, &targetProcessId); 

        // attach current thread to target thread messaging queue
        BOOL attached = AttachThreadInput(currentThreadId, targetThreadId, true);

        // что это даст? Мы участвуем в обработке сообщений того потока
        // и все сис. вызовы, которые мы сделаем, будут посланы от имени того потока.
        if (attached)
        {
            try
            {
                // get focused window handle (focused child that of toplevel window)
                HWND targetWindow = GetFocus();

                // some procedure 
                ProcessCaretPos(targetWindow);
            }
            catch(...) {;}

            AttachThreadInput(currentThreadId, targetThreadId, false);
        }

        Sleep(1000);
    }
    return 0;
}

// 
void ProcessCaretPos(HWND hwnd)
{
    IAccessible *pAccCaret = NULL;

    VARIANT varCaret;
    RECT rcCaret;
    varCaret.vt = VT_I4;
    varCaret.lVal = CHILDID_SELF;

    if (SUCCEEDED(AccessibleObjectFromWindow(hwnd, OBJID_CARET, IID_IAccessible, (void **)&pAccCaret)))
    {
        HRESULT hr = pAccCaret->accLocation( &rcCaret.left, &rcCaret.top, &rcCaret.right, &rcCaret.bottom, varCaret);

        if (!hr)
        {
            std::cout << "caret positon: " << rcCaret.left << " " << rcCaret.top << " " << rcCaret.right << " " << rcCaret.bottom << "\n";
        }
        else
            std::cout << "there is nothing carets" << "\n"; 

        pAccCaret->Release();
    }
}
4

1 に答える 1