mirror of
https://github.com/xiaoyifang/goldendict-ng.git
synced 2024-11-30 17:24:08 +00:00
a8589b39bf
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.
115 lines
2.9 KiB
C++
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;
|
|
}
|