我正在尝试解决以下任务: 我有OPERA浏览器,我想知道,是否随时存在插入符号(文本光标)。例如,我点击地址栏,我想知道插入符号现在闪烁。然后我点击页面上的空白位置,我知道没有插入符号。
换句话说,我想定义一些文本元素现在是焦点。
我知道如何在许多应用程序中解决此任务,其中一些使用标准的Windows控件,如Edit,因此我可以获得焦点窗口并使用WinApi检查它的类。
在其他应用程序中,控件在没有本机窗口的情况下呈现,我可以使用Automation UI获取它。
但遗憾的是,Opera只有一个主窗口,并且不提供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();
}
}
答案 0 :(得分: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();
}