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();
}
}