goldendict-ng/wordbyauto.cc
Abs62 a8589b39bf Improvements in scan popup functionality.
1. Add search word under cursor through IAccessibleEx interface and UI Automation technology.
2. Reorganize GoldenDict main program and scan libraries interaction to reduce influence to other programs.
3. Fix crash in scan libraries in IE9 protected mode.
2011-07-09 23:26:30 +04:00

115 lines
2.9 KiB
C++

#include <windows.h>
#include <servprov.h>
#include <winable.h>
#include "wordbyauto.hh"
#include "uiauto.hh"
#include <cstdio>
#include "dprintf.hh"
class GDAutomationClient {
public:
GDAutomationClient();
~GDAutomationClient();
bool getWordAtPoint( POINT pt );
WCHAR *getText() { return buffer; };
private:
WCHAR buffer[256];
IUIAutomation *pGDAutomation;
IUIAutomationTreeWalker *pTree;
};
GDAutomationClient gdAuto;
GDAutomationClient::GDAutomationClient()
{
HRESULT hr;
CoInitializeEx( NULL, COINIT_APARTMENTTHREADED );
hr = CoCreateInstance( CLSID_CUIAutomation , NULL, CLSCTX_INPROC_SERVER, IID_IUIAutomation, (void**)&pGDAutomation );
if( hr != S_OK ) pGDAutomation = NULL;
pTree = NULL;
hr = pGDAutomation->get_RawViewWalker( &pTree );
memset( buffer, 0, sizeof(buffer) );
}
GDAutomationClient::~GDAutomationClient()
{
if( pTree != NULL ) pTree->Release();
if( pGDAutomation != NULL ) pGDAutomation->Release();
CoUninitialize();
}
bool GDAutomationClient::getWordAtPoint( POINT pt )
{
HRESULT hr;
IUIAutomationTextPattern *pTextPattern;
IUIAutomationTextRange *pTextRange;
IUIAutomationElement *pElement, *pParent;
BSTR bstr;
RECT r = { 0, 0, 0, 0 };
bool bGoUp;
DPRINTF("\nEntering getWordAtPoint\n");
if( pGDAutomation == NULL ) return false;
buffer[0] = 0;
pElement = NULL;
hr = pGDAutomation->ElementFromPoint( pt, &pElement );
DPRINTF("ElementFromPoint return hr=%08X, ptr=%p\n", hr, pElement);
if( hr != S_OK || pElement == NULL )
return false;
pTextPattern = NULL;
bGoUp = false;
while( pElement != NULL ) {
hr = pElement->GetCurrentPatternAs( UIA_TextPatternId, IID_IUIAutomationTextPattern, (void**)&pTextPattern );
if( hr == S_OK && pTextPattern != NULL )
break;
if( pTree == NULL ) {
pElement->Release();
return false;
}
pParent = NULL;
hr = pTree->GetParentElement( pElement, &pParent );
pElement->Release();
pElement = pParent;
bGoUp = TRUE;
}
if( pElement == NULL )
return false;
if( !bGoUp ) {
hr = pElement->get_CurrentBoundingRectangle( &r );
if( hr == S_OK) {
pt.x -= r.left;
pt.y -= r.top;
}
}
pElement->Release();
pTextRange = NULL;
hr = pTextPattern->RangeFromPoint( pt, &pTextRange );
pTextPattern->Release();
if( hr != S_OK || pTextRange == NULL )
return false;
hr = pTextRange->ExpandToEnclosingUnit( TextUnit_Word );
if( hr == S_OK) {
hr = pTextRange->GetText( 255, &bstr );
if (hr == S_OK) {
wsprintfW( buffer, L"%s", (LPCWSTR)bstr );
SysFreeString( bstr );
}
}
pTextRange->Release();
return ( buffer[0] != 0 );
}
WCHAR *gdGetWordAtPointByAutomation( POINT pt )
{
if( gdAuto.getWordAtPoint( pt ) ) return gdAuto.getText();
else return NULL;
}