0

I'm trying to solve following task: I have OPERA browser and I want to find out, whether caret (text cursor) exist at any time. For example, I click on address bar, and I want to know that the caret is blinking now. Then I click on empty place on the page and I know that there is no caret exists.

In other words I want to define that some text element is in focus now.

I know how to solve this task in many applications, some of them uses standard windows controls such as Edit, so I can obtain focused window and check it's class with WinApi.

In other applications, where controls are rendering without native windows, I can obtain this with Automation UI.

But for my regret Opera has only one main window and doesn't provide access for UI automation technology.

So, does anybody know how approach my goal?)

EDIT:

Thanks for Eric Brown, this is solution of problem:

// 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

1

你可能不走运。但是,如果 Opera 使用系统插入符(它可能不使用;例如,IE 不使用),您可以尝试使用 MSAA 来查询系统插入符位置:

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)))
{
     hr = pAccCaret->accLocation( &rcCaret.left, &rcCaret.top, &rcCaret.right, &rcCaret.bottom, varCaret);

     pAccCaret->Release();
}
于 2013-08-10T16:23:03.937 回答