mirror of
https://github.com/xiaoyifang/goldendict-ng.git
synced 2024-11-27 19:24:08 +00:00
Merge pull request #26 from Abs62/master
Improvements in scan popup functionality. Now it can work with Internet Explorer 9.
This commit is contained in:
commit
f65c98c8e1
18
config.cc
18
config.cc
|
@ -102,6 +102,9 @@ Preferences::Preferences():
|
|||
scanPopupModifiers( 0 ),
|
||||
scanPopupAltMode( false ),
|
||||
scanPopupAltModeSecs( 3 ),
|
||||
scanPopupUseUIAutomation( true ),
|
||||
scanPopupUseIAccessibleEx( true ),
|
||||
scanPopupUseGDMessage( true ),
|
||||
pronounceOnLoadMain( false ),
|
||||
pronounceOnLoadPopup( false ),
|
||||
#ifdef Q_WS_WIN
|
||||
|
@ -597,6 +600,9 @@ Class load() throw( exError )
|
|||
c.preferences.scanPopupAltMode = ( preferences.namedItem( "scanPopupAltMode" ).toElement().text() == "1" );
|
||||
if ( !preferences.namedItem( "scanPopupAltModeSecs" ).isNull() )
|
||||
c.preferences.scanPopupAltModeSecs = preferences.namedItem( "scanPopupAltModeSecs" ).toElement().text().toUInt();
|
||||
c.preferences.scanPopupUseUIAutomation = ( preferences.namedItem( "scanPopupUseUIAutomation" ).toElement().text() == "1" );
|
||||
c.preferences.scanPopupUseIAccessibleEx = ( preferences.namedItem( "scanPopupUseIAccessibleEx" ).toElement().text() == "1" );
|
||||
c.preferences.scanPopupUseGDMessage = ( preferences.namedItem( "scanPopupUseGDMessage" ).toElement().text() == "1" );
|
||||
|
||||
c.preferences.pronounceOnLoadMain = ( preferences.namedItem( "pronounceOnLoadMain" ).toElement().text() == "1" );
|
||||
c.preferences.pronounceOnLoadPopup = ( preferences.namedItem( "pronounceOnLoadPopup" ).toElement().text() == "1" );
|
||||
|
@ -1106,6 +1112,18 @@ void save( Class const & c ) throw( exError )
|
|||
opt.appendChild( dd.createTextNode( QString::number( c.preferences.scanPopupAltModeSecs ) ) );
|
||||
preferences.appendChild( opt );
|
||||
|
||||
opt = dd.createElement( "scanPopupUseUIAutomation" );
|
||||
opt.appendChild( dd.createTextNode( c.preferences.scanPopupUseUIAutomation ? "1":"0" ) );
|
||||
preferences.appendChild( opt );
|
||||
|
||||
opt = dd.createElement( "scanPopupUseIAccessibleEx" );
|
||||
opt.appendChild( dd.createTextNode( c.preferences.scanPopupUseIAccessibleEx ? "1":"0" ) );
|
||||
preferences.appendChild( opt );
|
||||
|
||||
opt = dd.createElement( "scanPopupUseGDMessage" );
|
||||
opt.appendChild( dd.createTextNode( c.preferences.scanPopupUseGDMessage ? "1":"0" ) );
|
||||
preferences.appendChild( opt );
|
||||
|
||||
opt = dd.createElement( "pronounceOnLoadMain" );
|
||||
opt.appendChild( dd.createTextNode( c.preferences.pronounceOnLoadMain ? "1" : "0" ) );
|
||||
preferences.appendChild( opt );
|
||||
|
|
|
@ -159,6 +159,9 @@ struct Preferences
|
|||
unsigned long scanPopupModifiers; // Combination of KeyboardState::Modifier
|
||||
bool scanPopupAltMode; // When you press modifier shortly after the selection
|
||||
unsigned scanPopupAltModeSecs;
|
||||
bool scanPopupUseUIAutomation;
|
||||
bool scanPopupUseIAccessibleEx;
|
||||
bool scanPopupUseGDMessage;
|
||||
|
||||
// Whether the word should be pronounced on page load, in main window/popup
|
||||
bool pronounceOnLoadMain, pronounceOnLoadPopup;
|
||||
|
|
|
@ -37,7 +37,10 @@ win32 {
|
|||
LIBS += -liconv \
|
||||
-lwsock32 \
|
||||
-lwinmm \
|
||||
-lpsapi
|
||||
-lpsapi \
|
||||
-lole32 \
|
||||
-loleaut32 \
|
||||
-ladvapi32
|
||||
LIBS += -lvorbisfile \
|
||||
-lvorbis \
|
||||
-logg \
|
||||
|
@ -257,8 +260,12 @@ SOURCES += folding.cc \
|
|||
mainstatusbar.cc \
|
||||
gdappstyle.cc
|
||||
win32 {
|
||||
SOURCES += mouseover_win32/ThTypes.c
|
||||
HEADERS += mouseover_win32/ThTypes.h
|
||||
SOURCES += mouseover_win32/ThTypes.c \
|
||||
wordbyauto.cc \
|
||||
guids.c
|
||||
HEADERS += mouseover_win32/ThTypes.h \
|
||||
wordbyauto.hh \
|
||||
uiauto.hh
|
||||
}
|
||||
RESOURCES += resources.qrc \
|
||||
flags.qrc
|
||||
|
|
9
guids.c
Normal file
9
guids.c
Normal file
|
@ -0,0 +1,9 @@
|
|||
#define INITGUID
|
||||
#include <basetyps.h>
|
||||
|
||||
DEFINE_GUID(IID_IUIAutomation, 0x30cbe57d, 0xd9d0, 0x452a, 0xab, 0x13, 0x7a, 0xc5, 0xac, 0x48, 0x25, 0xee);
|
||||
DEFINE_GUID(CLSID_CUIAutomation, 0xff48dba4, 0x60ef, 0x4201, 0xaa, 0x87, 0x54, 0x10, 0x3e, 0xef, 0x59, 0x4e);
|
||||
DEFINE_GUID(IID_IUIAutomationElement, 0xd22108aa, 0x8ac5, 0x49a5, 0x83, 0x7b, 0x37, 0xbb, 0xb3, 0xd7, 0x59, 0x1e);
|
||||
DEFINE_GUID(IID_IUIAutomationTextPattern, 0x32eba289, 0x3583, 0x42c9, 0x9c, 0x59, 0x3b, 0x6d, 0x9a, 0x1e, 0x9b, 0x6a);
|
||||
DEFINE_GUID(IID_IUIAutomationTextRange, 0xa543cc6a, 0xf4ae, 0x494b, 0x82, 0x39, 0xc8, 0x14, 0x48, 0x11, 0x87, 0xa8);
|
||||
DEFINE_GUID(IID_IUIAutomationTreeWalker, 0x4042c624, 0x389c, 0x4afc, 0xa6, 0x30, 0x9d, 0xf8, 0x54, 0xa5, 0x41, 0xfc);
|
291
locale/ru_RU.ts
291
locale/ru_RU.ts
|
@ -37,47 +37,47 @@
|
|||
<context>
|
||||
<name>ArticleMaker</name>
|
||||
<message>
|
||||
<location filename="../article_maker.cc" line="112"/>
|
||||
<location filename="../article_maker.cc" line="113"/>
|
||||
<source>No translation for <b>%1</b> was found in group <b>%2</b>.</source>
|
||||
<translation>В группе <b>%2</b> не найдено перевода для <b>%1</b>.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../article_maker.cc" line="117"/>
|
||||
<location filename="../article_maker.cc" line="118"/>
|
||||
<source>No translation was found in group <b>%1</b>.</source>
|
||||
<translation>В группе <b>%1</b> перевод не найден.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../article_maker.cc" line="136"/>
|
||||
<location filename="../article_maker.cc" line="137"/>
|
||||
<source>Welcome!</source>
|
||||
<translation>Добро пожаловать!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../article_maker.cc" line="138"/>
|
||||
<location filename="../article_maker.cc" line="139"/>
|
||||
<source><h3 align="center">Welcome to <b>GoldenDict</b>!</h3><p>To start working with the program, first visit <b>Edit|Dictionaries</b> to add some directory paths where to search for the dictionary files, set up various Wikipedia sites or other sources, adjust dictionary order or create dictionary groups.<p>And then you're ready to look up your words! You can do that in this window by using a pane to the left, or you can <a href="Working with popup">look up words from other active applications</a>. <p>To customize program, check out the available preferences at <b>Edit|Preferences</b>. All settings there have tooltips, be sure to read them if you are in doubt about anything.<p>Should you need further help, have any questions, suggestions or just wonder what the others think, you are welcome at the program's <a href="http://goldendict.org/forum/">forum</a>.<p>Check program's <a href="http://goldendict.org/">website</a> for the updates. <p>(c) 2008-2011 Konstantin Isakov. Licensed under GPLv3 or later.</source>
|
||||
<translation><h3 align="center">Добро пожаловать в <b>GoldenDict</b>!</h3><p>Если вы запустили программу в первый раз, укажите пути к словарям в <b>Правка|Словари</b>. Там же Вы можете указать различные сайты Википедии или другие источники данных, настроить порядок просмотра словарей или создать словарные группы.<p>После этого Вы можете приступать к поиску слов. Слова можно искать в левой области данного окна. При работе в других приложениях можно искать слова, используя <a href="Работа с всплывающим окном">всплывающее окно</a>. <p>В меню <b>Правка|Параметры</b>.Вы можете настроить приложение по своему вкусу. Все параметры имеют подсказки, показываемые при наведении курсора на них. Обращайте, пожалуйста, на них внимание, когда у Вас возникают затруднения с настройкой.<p>Если Вам требуется дополнительная помощь, возникли какие-то вопросы, пожелания и т.п., обращайтесь на <a href="http://goldendict.org/forum/">форум программы</a>.<p>Обновления программы доступны на её <a href="http://goldendict.org/">вебсайте</a>.<p>© Константин Исаков (ikm@goldendict.org), 2008-2011. Лицензия: GNU GPLv3 или более поздняя версия.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../article_maker.cc" line="154"/>
|
||||
<location filename="../article_maker.cc" line="155"/>
|
||||
<source>Working with popup</source>
|
||||
<translation>Работа с всплывающим окном</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../article_maker.cc" line="156"/>
|
||||
<location filename="../article_maker.cc" line="157"/>
|
||||
<source><h3 align="center">Working with the popup</h3>To look up words from other active applications, you would need to first activate the <i>"Scan popup functionality"</i> in <b>Preferences</b>, and then enable it at any time either by triggering the 'Popup' icon above, or by clicking the tray icon down below with your right mouse button and choosing so in the menu you've popped. </source>
|
||||
<translation><h3 align="center">Всплывающее окно</h3>Для поиска слов из других приложений, вам нужно включить <i>«Разрешить всплывающее окно»</i> в <b>Параметрах</b> и после этого включить всплывающее окно кнопкой «Сканировать» в основном окне или в контекстном меню значка в системном лотке.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../article_maker.cc" line="163"/>
|
||||
<location filename="../article_maker.cc" line="164"/>
|
||||
<source>Then just stop the cursor over the word you want to look up in another application, and a window would pop up which would describe it to you.</source>
|
||||
<translation>Теперь подведите курсор мыши к какому-либо слову в приложении, и появится всплывающее окно с переводом или значением этого слова.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../article_maker.cc" line="166"/>
|
||||
<location filename="../article_maker.cc" line="167"/>
|
||||
<source>Then just select any word you want to look up in another application by your mouse (double-click it or swipe it with mouse with the button pressed), and a window would pop up which would describe the word to you.</source>
|
||||
<translation>Теперь выделите какое-либо слово в приложении (двойным щелчком, или же проводя по ним курсором мыши при зажатой левой кнопке), и появится всплывающее окно с переводом или значением этого слова.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../article_maker.cc" line="243"/>
|
||||
<location filename="../article_maker.cc" line="244"/>
|
||||
<source>(untitled)</source>
|
||||
<translation>(без имени)</translation>
|
||||
</message>
|
||||
|
@ -85,27 +85,27 @@
|
|||
<context>
|
||||
<name>ArticleRequest</name>
|
||||
<message>
|
||||
<location filename="../article_maker.cc" line="402"/>
|
||||
<location filename="../article_maker.cc" line="404"/>
|
||||
<source>From </source>
|
||||
<translation>Из словаря </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../article_maker.cc" line="415"/>
|
||||
<location filename="../article_maker.cc" line="417"/>
|
||||
<source>Query error: %1</source>
|
||||
<translation>Ошибка поиска: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../article_maker.cc" line="514"/>
|
||||
<location filename="../article_maker.cc" line="516"/>
|
||||
<source>Close words: </source>
|
||||
<translation>Близкие слова: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../article_maker.cc" line="585"/>
|
||||
<location filename="../article_maker.cc" line="587"/>
|
||||
<source>Compound expressions: </source>
|
||||
<translation>Составные выражения: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../article_maker.cc" line="613"/>
|
||||
<location filename="../article_maker.cc" line="615"/>
|
||||
<source>Individual words: </source>
|
||||
<translation>Отдельные слова: </translation>
|
||||
</message>
|
||||
|
@ -113,88 +113,103 @@
|
|||
<context>
|
||||
<name>ArticleView</name>
|
||||
<message>
|
||||
<location filename="../articleview.cc" line="727"/>
|
||||
<location filename="../articleview.cc" line="757"/>
|
||||
<location filename="../articleview.cc" line="766"/>
|
||||
<location filename="../articleview.cc" line="1136"/>
|
||||
<location filename="../articleview.cc" line="1154"/>
|
||||
<location filename="../articleview.cc" line="1164"/>
|
||||
<location filename="../articleview.cc" line="1187"/>
|
||||
<location filename="../articleview.cc" line="605"/>
|
||||
<source>Resource</source>
|
||||
<translation>Ресурс</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../articleview.cc" line="610"/>
|
||||
<source>Audio</source>
|
||||
<translation>Аудио</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../articleview.cc" line="620"/>
|
||||
<source>Definition: %1</source>
|
||||
<translation>Определение: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../articleview.cc" line="791"/>
|
||||
<location filename="../articleview.cc" line="821"/>
|
||||
<location filename="../articleview.cc" line="830"/>
|
||||
<location filename="../articleview.cc" line="1200"/>
|
||||
<location filename="../articleview.cc" line="1218"/>
|
||||
<location filename="../articleview.cc" line="1228"/>
|
||||
<location filename="../articleview.cc" line="1251"/>
|
||||
<source>GoldenDict</source>
|
||||
<translation>GoldenDict</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../articleview.cc" line="727"/>
|
||||
<location filename="../articleview.cc" line="791"/>
|
||||
<source>The referenced resource doesn't exist.</source>
|
||||
<translation>Запрошенный ресурс не найден.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../articleview.cc" line="767"/>
|
||||
<location filename="../articleview.cc" line="831"/>
|
||||
<source>The referenced audio program doesn't exist.</source>
|
||||
<translation>Указанная аудио-программа не найдена.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../articleview.cc" line="897"/>
|
||||
<location filename="../articleview.cc" line="961"/>
|
||||
<source>&Open Link</source>
|
||||
<translation>&Открыть ссылку</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../articleview.cc" line="903"/>
|
||||
<location filename="../articleview.cc" line="967"/>
|
||||
<source>Open Link in New &Tab</source>
|
||||
<translation>Открыть ссылку в новой &вкладке</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../articleview.cc" line="910"/>
|
||||
<location filename="../articleview.cc" line="974"/>
|
||||
<source>Open Link in &External Browser</source>
|
||||
<translation>Открыть ссылку во внешнем &браузере</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../articleview.cc" line="923"/>
|
||||
<location filename="../articleview.cc" line="987"/>
|
||||
<source>&Look up "%1"</source>
|
||||
<translation>&Поиск «%1»</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../articleview.cc" line="931"/>
|
||||
<location filename="../articleview.cc" line="995"/>
|
||||
<source>Look up "%1" in &New Tab</source>
|
||||
<translation>Поиск «%1» в &новой вкладке</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../articleview.cc" line="946"/>
|
||||
<location filename="../articleview.cc" line="1010"/>
|
||||
<source>Look up "%1" in %2</source>
|
||||
<translation>Поиск «%1» в %2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../articleview.cc" line="954"/>
|
||||
<location filename="../articleview.cc" line="1018"/>
|
||||
<source>Look up "%1" in %2 in &New Tab</source>
|
||||
<translation>Поиск «%1» в %2 в &новой вкладке</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../articleview.cc" line="1093"/>
|
||||
<location filename="../articleview.cc" line="1157"/>
|
||||
<source>Playing a non-WAV file</source>
|
||||
<translation>Проигрывание отличного от WAV файла</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../articleview.cc" line="1094"/>
|
||||
<location filename="../articleview.cc" line="1158"/>
|
||||
<source>To enable playback of files different than WAV, please go to Edit|Preferences, choose the Audio tab and select "Play via DirectShow" there.</source>
|
||||
<translation>Чтобы включить возможность проигрывания файлов типов, отличных от WAV, пожалуйста зайдите в Правка|Параметры, выберите вкладку Аудио и выберите режим "Вывод звука через DirectShow".</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../articleview.cc" line="1136"/>
|
||||
<location filename="../articleview.cc" line="1200"/>
|
||||
<source>Failed to run a player to play sound file: %1</source>
|
||||
<translation>Невозможно запустить проигрыватель звукового файла: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../articleview.cc" line="1154"/>
|
||||
<location filename="../articleview.cc" line="1218"/>
|
||||
<source>Failed to create temporary file.</source>
|
||||
<translation>Ошибка создания временного файла.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../articleview.cc" line="1164"/>
|
||||
<location filename="../articleview.cc" line="1228"/>
|
||||
<source>Failed to auto-open resource file, try opening manually: %1.</source>
|
||||
<translation>Ошибка открытия файла ресурса, попробуйте открыть вручную: %1.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../articleview.cc" line="1187"/>
|
||||
<location filename="../articleview.cc" line="1251"/>
|
||||
<source>The referenced resource failed to download.</source>
|
||||
<translation>Невозможно загрузить указанный ресурс.</translation>
|
||||
</message>
|
||||
|
@ -1623,52 +1638,52 @@
|
|||
<translation>Загрузка...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cc" line="1968"/>
|
||||
<location filename="../mainwindow.cc" line="2005"/>
|
||||
<source>Skip This Release</source>
|
||||
<translation>Пропустить данную версию</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cc" line="2076"/>
|
||||
<location filename="../mainwindow.cc" line="2113"/>
|
||||
<source>You have chosen to hide a menubar. Use %1 to show it back.</source>
|
||||
<translation>Вы скрыли главное меню. Чтобы вернуть его, используйте %1.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cc" line="2076"/>
|
||||
<location filename="../mainwindow.cc" line="2114"/>
|
||||
<source>Ctrl+M</source>
|
||||
<translation>Ctrl+M</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cc" line="2215"/>
|
||||
<location filename="../mainwindow.cc" line="2255"/>
|
||||
<source>Page Setup</source>
|
||||
<translation>Параметры страницы</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cc" line="2216"/>
|
||||
<location filename="../mainwindow.cc" line="2256"/>
|
||||
<source>No printer is available. Please install one first.</source>
|
||||
<translation>В системе не установлено ни одного принтера.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cc" line="2233"/>
|
||||
<location filename="../mainwindow.cc" line="2273"/>
|
||||
<source>Print Article</source>
|
||||
<translation>Печать статьи</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cc" line="2254"/>
|
||||
<location filename="../mainwindow.cc" line="2294"/>
|
||||
<source>Save Article As</source>
|
||||
<translation>Сохранить статью как</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cc" line="2254"/>
|
||||
<location filename="../mainwindow.cc" line="2294"/>
|
||||
<source>Html files (*.html *.htm)</source>
|
||||
<translation>Файлы Html (*.html *.htm)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cc" line="2269"/>
|
||||
<location filename="../mainwindow.cc" line="2309"/>
|
||||
<source>Error</source>
|
||||
<translation>Ошибка</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cc" line="2270"/>
|
||||
<location filename="../mainwindow.cc" line="2310"/>
|
||||
<source>Can't save article: %1</source>
|
||||
<translation>Невозможно сохранить статью: %1</translation>
|
||||
</message>
|
||||
|
@ -1678,23 +1693,23 @@
|
|||
<translation>Словарей: %1, статей: %2, слов: %3</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cc" line="1827"/>
|
||||
<location filename="../mainwindow.cc" line="1864"/>
|
||||
<source>Failed to initialize hotkeys monitoring mechanism.<br>Make sure your XServer has RECORD extension turned on.</source>
|
||||
<translation>Ошибка инициализации механизма отслеживания горячих клавиш.<br>Убедитесь, что ваш XServer поддерживает расширение RECORD.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cc" line="1961"/>
|
||||
<location filename="../mainwindow.cc" line="1998"/>
|
||||
<source>New Release Available</source>
|
||||
<translation>Доступна новая версия</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cc" line="1962"/>
|
||||
<location filename="../mainwindow.cc" line="1999"/>
|
||||
<source>Version <b>%1</b> of GoldenDict is now available for download.<br>Click <b>Download</b> to get to the download page.</source>
|
||||
<translation>Версия <b>%1</b> программы GoldenDict доступа для загрузки.<br>
|
||||
Нажмите <b>Загрузить</b>, чтобы перейти на страницу загрузки.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cc" line="1967"/>
|
||||
<location filename="../mainwindow.cc" line="2004"/>
|
||||
<source>Download</source>
|
||||
<translation>Загрузить</translation>
|
||||
</message>
|
||||
|
@ -1795,19 +1810,19 @@
|
|||
<translation>(без имени)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cc" line="1033"/>
|
||||
<location filename="../mainwindow.cc" line="1039"/>
|
||||
<source>%1 - %2</source>
|
||||
<translation>%1 - %2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cc" line="1451"/>
|
||||
<location filename="../mainwindow.cc" line="1467"/>
|
||||
<source>WARNING: %1</source>
|
||||
<translation>Внимание: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="14"/>
|
||||
<location filename="../mainwindow.cc" line="1033"/>
|
||||
<location filename="../mainwindow.cc" line="1826"/>
|
||||
<location filename="../mainwindow.cc" line="1039"/>
|
||||
<location filename="../mainwindow.cc" line="1863"/>
|
||||
<source>GoldenDict</source>
|
||||
<translation>GoldenDict</translation>
|
||||
</message>
|
||||
|
@ -2204,13 +2219,13 @@ the application.</source>
|
|||
<translation>Переводить выбранное слово по двойному щелчку</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="311"/>
|
||||
<location filename="../preferences.ui" line="324"/>
|
||||
<source>Chooses whether the scan popup mode is on by default or not. If checked,
|
||||
the program would always start with the scan popup active.</source>
|
||||
<translation>Включать или нет режим всплывающего окна при запуске программы.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="492"/>
|
||||
<location filename="../preferences.ui" line="505"/>
|
||||
<source>Normally, in order to activate a popup you have to
|
||||
maintain the chosen keys pressed while you select
|
||||
a word. With this enabled, the chosen keys may also
|
||||
|
@ -2226,22 +2241,22 @@ be pressed shortly after the selection is done.</source>
|
|||
того, как слово было выделено.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="572"/>
|
||||
<location filename="../preferences.ui" line="664"/>
|
||||
<source>Hotkeys</source>
|
||||
<translation>Горячие клавиши</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="591"/>
|
||||
<location filename="../preferences.ui" line="683"/>
|
||||
<source>Use the following hotkey to show or hide the main window:</source>
|
||||
<translation>Использовать следующую комбинацию для показа/скрытия основного окна:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="622"/>
|
||||
<location filename="../preferences.ui" line="714"/>
|
||||
<source>Use the following hotkey to translate a word from clipboard:</source>
|
||||
<translation>Использовать следующую комбинацию для перевода слова из буфера обмена:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="669"/>
|
||||
<location filename="../preferences.ui" line="761"/>
|
||||
<source>The hotkeys are global and work from any program and within any context as long as GoldenDict is running in background.</source>
|
||||
<translation>Горячие клавиши являются глобальными и работают из любой программы и в любом состоянии, до тех пор пока GoldenDict работает в фоне.</translation>
|
||||
</message>
|
||||
|
@ -2279,7 +2294,7 @@ With this on however, it will hide the main window.</source>
|
|||
<translation>Прятать главное окно по клавише ESC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="293"/>
|
||||
<location filename="../preferences.ui" line="306"/>
|
||||
<source>When enabled, a translation popup window would be shown each time
|
||||
you point your mouse on any word on the screen (Windows) or select
|
||||
any word with mouse (Linux). When enabled, you can switch it on and
|
||||
|
@ -2290,134 +2305,134 @@ off from main window or tray icon.</source>
|
|||
включить или отключить в основном окне и в контекстом меню значка в системном лотке.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="299"/>
|
||||
<location filename="../preferences.ui" line="312"/>
|
||||
<source>Enable scan popup functionality</source>
|
||||
<translation>Разрешить всплывающее окно</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="315"/>
|
||||
<location filename="../preferences.ui" line="328"/>
|
||||
<source>Start with scan popup turned on</source>
|
||||
<translation>Включить режим всплывающего окна при запуске</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="322"/>
|
||||
<location filename="../preferences.ui" line="335"/>
|
||||
<source>With this enabled, the popup would only show up if all chosen keys are
|
||||
in the pressed state when the word selection changes.</source>
|
||||
<translation>Показывать всплывающее окно, только если все выбранные клавиши
|
||||
находятся в зажатом состоянии в момент выделения слова.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="326"/>
|
||||
<location filename="../preferences.ui" line="339"/>
|
||||
<source>Only show popup when all selected keys are kept pressed:</source>
|
||||
<translation>Показывать всплывающее окно только при зажатых клавишах:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="365"/>
|
||||
<location filename="../preferences.ui" line="378"/>
|
||||
<source>Left Ctrl only</source>
|
||||
<translation>При зажатии левой клавиши Ctrl</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="368"/>
|
||||
<location filename="../preferences.ui" line="381"/>
|
||||
<source>Left Ctrl</source>
|
||||
<translation>Левый Ctrl</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="375"/>
|
||||
<location filename="../preferences.ui" line="388"/>
|
||||
<source>Right Shift only</source>
|
||||
<translation>При зажатии правой клавиши Shift</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="378"/>
|
||||
<location filename="../preferences.ui" line="391"/>
|
||||
<source>Right Shift</source>
|
||||
<translation>Правый Shift</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="385"/>
|
||||
<location filename="../preferences.ui" line="398"/>
|
||||
<source>Alt key</source>
|
||||
<translation>При зажатии любой клавиши Alt</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="388"/>
|
||||
<location filename="../preferences.ui" line="401"/>
|
||||
<source>Alt</source>
|
||||
<translation>Alt</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="395"/>
|
||||
<location filename="../preferences.ui" line="408"/>
|
||||
<source>Ctrl key</source>
|
||||
<translation>При зажатии любой клавиши Ctrl</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="398"/>
|
||||
<location filename="../preferences.ui" line="411"/>
|
||||
<source>Ctrl</source>
|
||||
<translation>Ctrl</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="405"/>
|
||||
<location filename="../preferences.ui" line="418"/>
|
||||
<source>Left Alt only</source>
|
||||
<translation>При зажатии левой клавиши Alt</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="408"/>
|
||||
<location filename="../preferences.ui" line="421"/>
|
||||
<source>Left Alt</source>
|
||||
<translation>Левый Alt</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="415"/>
|
||||
<location filename="../preferences.ui" line="428"/>
|
||||
<source>Shift key</source>
|
||||
<translation>При зажатии любой клавиши Shift</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="418"/>
|
||||
<location filename="../preferences.ui" line="431"/>
|
||||
<source>Shift</source>
|
||||
<translation>Shift</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="425"/>
|
||||
<location filename="../preferences.ui" line="438"/>
|
||||
<source>Right Alt only</source>
|
||||
<translation>При зажатии правой клавиши Alt</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="428"/>
|
||||
<location filename="../preferences.ui" line="441"/>
|
||||
<source>Right Alt</source>
|
||||
<translation>Правый Alt</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="435"/>
|
||||
<location filename="../preferences.ui" line="448"/>
|
||||
<source>Right Ctrl only</source>
|
||||
<translation>При зажатии правой клавиши Ctrl</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="438"/>
|
||||
<location filename="../preferences.ui" line="451"/>
|
||||
<source>Right Ctrl</source>
|
||||
<translation>Правый Ctrl</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="445"/>
|
||||
<location filename="../preferences.ui" line="458"/>
|
||||
<source>Left Shift only</source>
|
||||
<translation>При зажатии левой клавиши Shift</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="448"/>
|
||||
<location filename="../preferences.ui" line="461"/>
|
||||
<source>Left Shift</source>
|
||||
<translation>Левый Shift</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="455"/>
|
||||
<location filename="../preferences.ui" line="468"/>
|
||||
<source>Windows key or Meta key</source>
|
||||
<translation>При зажатии клавиши Windows или Meta</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="458"/>
|
||||
<location filename="../preferences.ui" line="471"/>
|
||||
<source>Win/Meta</source>
|
||||
<translation>Win или Meta</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="498"/>
|
||||
<location filename="../preferences.ui" line="511"/>
|
||||
<source>Keys may also be pressed afterwards, within</source>
|
||||
<translation>Задержка проверки модификаторов</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="505"/>
|
||||
<location filename="../preferences.ui" line="518"/>
|
||||
<source>To avoid false positives, the keys are only monitored
|
||||
after the selection's done for a limited amount of
|
||||
seconds, which is specified here.</source>
|
||||
|
@ -2426,12 +2441,54 @@ seconds, which is specified here.</source>
|
|||
промежутка времени, который и задается здесь.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="529"/>
|
||||
<location filename="../preferences.ui" line="542"/>
|
||||
<source>secs</source>
|
||||
<translation>секунд(ы)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="679"/>
|
||||
<location filename="../preferences.ui" line="566"/>
|
||||
<source>Try to use IAccessibleEx interface to retrieve word under cursor.
|
||||
This technology works only with some programs that support it.
|
||||
Don't select this option if you don't use such programs.</source>
|
||||
<translation>Использовать интерфейс IAccessibleEx для получения слова под курсором.
|
||||
Эта технология работает только с теми программами, которые поддерживают её.
|
||||
Не включайте этот режим, если не пользуетесь такими программами.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="571"/>
|
||||
<source>Use IAccessibleE&x</source>
|
||||
<translation>Использовать IAccessibleE&x</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="591"/>
|
||||
<source>Use special GoldenDict message to ask other programs about a word under cursor.
|
||||
This technology works only with some programs that support it.
|
||||
Don't select this option if you don't use such programs.</source>
|
||||
<translation>Использовать специальный запрос GoldenDict для получения слова под курсором.
|
||||
Эта технология работает только с теми программами, которые поддерживают её.
|
||||
Не включайте этот режим, если не пользуетесь такими программами.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="596"/>
|
||||
<source>Use GD message</source>
|
||||
<translation>Использовать запрос GoldenDict</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="618"/>
|
||||
<source>Try to use UI Automation technology to retrieve word under cursor.
|
||||
This technology works only with some programs that support it.
|
||||
Don't select this option if you don't use such programs.</source>
|
||||
<translation>Использовать технологию UI Automation для получения слова под курсором.
|
||||
Эта технология работает только с теми программами, которые поддерживают её.
|
||||
Не включайте этот режим, если не пользуетесь такими программами.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="623"/>
|
||||
<source>Use UI Automation</source>
|
||||
<translation>Использовать UI Automation</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="771"/>
|
||||
<source><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
|
@ -2444,108 +2501,108 @@ p, li { white-space: pre-wrap; }
|
|||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" color:#ff0000;">Замечание: Кажется, Вы используете версию X.Org XServer, в которой отсутствует поддержка расширения RECORD. Вероятно, горячие клавиши в GoldenDict не заработают. Эта проблема должна быть исправлена на стороне XServer. Более подробную информацию смотрите на </span><a href="https://bugs.freedesktop.org/show_bug.cgi?id=20500"><span style=" text-decoration: underline; color:#0000ff;">bug entry</span></a><span style=" color:#ff0000;"> и, если хотите, оставляйте там свои пожелания.</span></p></body></html></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="717"/>
|
||||
<location filename="../preferences.ui" line="809"/>
|
||||
<source>&Audio</source>
|
||||
<translation>&Аудио</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="736"/>
|
||||
<location filename="../preferences.ui" line="828"/>
|
||||
<source>Pronunciation</source>
|
||||
<translation>произношение</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="742"/>
|
||||
<location filename="../preferences.ui" line="834"/>
|
||||
<source>Auto-pronounce words in main window</source>
|
||||
<translation>Автоматически произносить слова в главном окне</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="749"/>
|
||||
<location filename="../preferences.ui" line="841"/>
|
||||
<source>Auto-pronounce words in scan popup</source>
|
||||
<translation>Автоматически произносить слова во всплывающем окне</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="759"/>
|
||||
<location filename="../preferences.ui" line="851"/>
|
||||
<source>Playback</source>
|
||||
<translation>Воспроизведение</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="765"/>
|
||||
<location filename="../preferences.ui" line="857"/>
|
||||
<source>Use Windows native playback API. Limited to .wav files only,
|
||||
but works very well.</source>
|
||||
<translation>Использовать внутренние средства Windows для проигрывания. Поддерживаются
|
||||
только файлы типа .wav, однако воспроизведение всегда работает хорошо.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="769"/>
|
||||
<location filename="../preferences.ui" line="861"/>
|
||||
<source>Play via Windows native API</source>
|
||||
<translation>Воспроизведение внутренними средствами Windows</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="776"/>
|
||||
<location filename="../preferences.ui" line="868"/>
|
||||
<source>Play audio via Phonon framework. May be somewhat unstable,
|
||||
but should support most audio file formats.</source>
|
||||
<translation>Воспроизводить через систему Phonon. Иногда работает нестабильно,
|
||||
зато поддерживает большинство аудио-форматов.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="780"/>
|
||||
<location filename="../preferences.ui" line="872"/>
|
||||
<source>Play via Phonon</source>
|
||||
<translation>Воспроизведение через Phonon</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="792"/>
|
||||
<location filename="../preferences.ui" line="884"/>
|
||||
<source>Use any external program to play audio files</source>
|
||||
<translation>Использовать любую внешнюю программу для проигрывания аудио-файлов</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="795"/>
|
||||
<location filename="../preferences.ui" line="887"/>
|
||||
<source>Use external program:</source>
|
||||
<translation>Воспроизведение через внешнее приложение:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="832"/>
|
||||
<location filename="../preferences.ui" line="924"/>
|
||||
<source>&Network</source>
|
||||
<translation>&Сеть</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="851"/>
|
||||
<location filename="../preferences.ui" line="943"/>
|
||||
<source>Enable if you wish to use a proxy server
|
||||
for all program's network requests.</source>
|
||||
<translation>Включите, если хотите использовать прокси-сервер
|
||||
для всех сетевых запросов программы.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="855"/>
|
||||
<location filename="../preferences.ui" line="947"/>
|
||||
<source>Use proxy server</source>
|
||||
<translation>Использовать прокси-сервер</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="869"/>
|
||||
<location filename="../preferences.ui" line="961"/>
|
||||
<source>Type:</source>
|
||||
<translation>Тип:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="879"/>
|
||||
<location filename="../preferences.ui" line="971"/>
|
||||
<source>Host:</source>
|
||||
<translation>Сервер:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="889"/>
|
||||
<location filename="../preferences.ui" line="981"/>
|
||||
<source>Port:</source>
|
||||
<translation>Порт:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="910"/>
|
||||
<location filename="../preferences.ui" line="1002"/>
|
||||
<source>User:</source>
|
||||
<translation>Имя пользователя:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="920"/>
|
||||
<location filename="../preferences.ui" line="1012"/>
|
||||
<source>Password:</source>
|
||||
<translation>Пароль:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="955"/>
|
||||
<location filename="../preferences.ui" line="1047"/>
|
||||
<source>Enabling this would make GoldenDict block most advertisements
|
||||
by disallowing content (images, frames) not originating from the site
|
||||
you are browsing. If some site breaks because of this, try disabling this.</source>
|
||||
|
@ -2555,12 +2612,12 @@ you are browsing. If some site breaks because of this, try disabling this.</sour
|
|||
из-за этого функционировать, попробуйте запретить эту опцию.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="960"/>
|
||||
<location filename="../preferences.ui" line="1052"/>
|
||||
<source>Disallow loading content from other sites (hides most advertisements)</source>
|
||||
<translation>Запретить загрузку информации с других сайтов (убирает большую часть рекламы)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="967"/>
|
||||
<location filename="../preferences.ui" line="1059"/>
|
||||
<source>Enabling this would allow to listen to sound pronunciations from
|
||||
online dictionaries that rely on Flash or other web plugins.
|
||||
Plugin must be installed for this option to work.</source>
|
||||
|
@ -2569,12 +2626,12 @@ Plugin must be installed for this option to work.</source>
|
|||
Чтобы это работало, плагины должны быть установлены.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="972"/>
|
||||
<location filename="../preferences.ui" line="1064"/>
|
||||
<source>Enable web plugins</source>
|
||||
<translation>Разрешить веб-плагины</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="995"/>
|
||||
<location filename="../preferences.ui" line="1087"/>
|
||||
<source>When this is enabled, the program periodically
|
||||
checks if a new, updated version of GoldenDict
|
||||
is available for download. If it is so, the program
|
||||
|
@ -2587,7 +2644,7 @@ GoldenDict. Если новая версия появилась, програм
|
|||
страницу загрузки.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.ui" line="1002"/>
|
||||
<location filename="../preferences.ui" line="1094"/>
|
||||
<source>Check for new program releases periodically</source>
|
||||
<translation>Проверять наличие новой версии</translation>
|
||||
</message>
|
||||
|
@ -2607,17 +2664,17 @@ GoldenDict. Если новая версия появилась, програм
|
|||
<translation>Lingvo</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.cc" line="139"/>
|
||||
<location filename="../preferences.cc" line="147"/>
|
||||
<source>Play via DirectShow</source>
|
||||
<translation>Воспроизведение через DirectShow</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.cc" line="322"/>
|
||||
<location filename="../preferences.cc" line="333"/>
|
||||
<source>Changing Language</source>
|
||||
<translation>Смена языка</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../preferences.cc" line="323"/>
|
||||
<location filename="../preferences.cc" line="334"/>
|
||||
<source>Restart the program to apply the language change.</source>
|
||||
<translation>Перезапустите программу, чтобы изменение языка вошло в силу.</translation>
|
||||
</message>
|
||||
|
|
206
mouseover.cc
206
mouseover.cc
|
@ -5,7 +5,13 @@
|
|||
#include <algorithm>
|
||||
|
||||
#ifdef Q_OS_WIN32
|
||||
#undef WINVER
|
||||
#define WINVER 0x0500
|
||||
#include <sddl.h>
|
||||
#include <accctrl.h>
|
||||
#include <aclapi.h>
|
||||
#include "mouseover_win32/ThTypes.h"
|
||||
#include "wordbyauto.hh"
|
||||
#endif
|
||||
|
||||
MouseOver & MouseOver::instance()
|
||||
|
@ -18,12 +24,72 @@ MouseOver & MouseOver::instance()
|
|||
#ifdef Q_OS_WIN32
|
||||
const UINT WM_MY_SHOW_TRANSLATION = WM_USER + 301;
|
||||
static wchar_t className[] = L"GoldenDictMouseover";
|
||||
typedef BOOL WINAPI ( *ChangeWindowMessageFilterFunc )( UINT, DWORD );
|
||||
|
||||
#ifndef CHANGEFILTERSTRUCT
|
||||
typedef struct tagCHANGEFILTERSTRUCT {
|
||||
DWORD cbSize;
|
||||
DWORD ExtStatus;
|
||||
} CHANGEFILTERSTRUCT, *PCHANGEFILTERSTRUCT;
|
||||
#endif
|
||||
|
||||
MouseOver::MouseOver()
|
||||
{
|
||||
typedef BOOL WINAPI ( *ChangeWindowMessageFilterExFunc )( HWND, UINT, DWORD, PCHANGEFILTERSTRUCT );
|
||||
|
||||
#endif // Q_OS_WIN32
|
||||
|
||||
#ifdef Q_OS_WIN32
|
||||
|
||||
extern "C" BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
|
||||
LPCWSTR StringSecurityDescriptor,
|
||||
DWORD StringSDRevision,
|
||||
PSECURITY_DESCRIPTOR *SecurityDescriptor,
|
||||
PULONG SecurityDescriptorSize );
|
||||
|
||||
|
||||
static void SetLowLabelToGDSynchroObjects()
|
||||
{
|
||||
// The LABEL_SECURITY_INFORMATION SDDL SACL to be set for low integrity
|
||||
#define LOW_INTEGRITY_SDDL_SACL_W L"S:(ML;;NW;;;LW)"
|
||||
DWORD dwErr = ERROR_SUCCESS;
|
||||
PSECURITY_DESCRIPTOR pSD = NULL;
|
||||
|
||||
PACL pSacl = NULL; // not allocated
|
||||
BOOL fSaclPresent = FALSE;
|
||||
BOOL fSaclDefaulted = FALSE;
|
||||
LPCWSTR pwszMapFileName = L"GoldenDictTextOutHookSharedMem";
|
||||
LPCWSTR pwszSpyMutexName = L"GoldenDictTextOutSpyMutex";
|
||||
LPCWSTR pwszHookMutexName = L"GoldenDictTextOutHookMutex";
|
||||
|
||||
if( ConvertStringSecurityDescriptorToSecurityDescriptorW( LOW_INTEGRITY_SDDL_SACL_W, 1 /* SDDL_REVISION_1 */, &pSD, NULL ) )
|
||||
{
|
||||
if( GetSecurityDescriptorSacl(pSD, &fSaclPresent, &pSacl, &fSaclDefaulted))
|
||||
{
|
||||
// Note that psidOwner, psidGroup, and pDacl are
|
||||
// all NULL and set the new LABEL_SECURITY_INFORMATION
|
||||
|
||||
dwErr = SetNamedSecurityInfoW( (LPWSTR)pwszMapFileName,
|
||||
SE_KERNEL_OBJECT, LABEL_SECURITY_INFORMATION, NULL, NULL, NULL, pSacl);
|
||||
|
||||
dwErr = SetNamedSecurityInfoW( (LPWSTR)pwszSpyMutexName,
|
||||
SE_KERNEL_OBJECT, LABEL_SECURITY_INFORMATION, NULL, NULL, NULL, pSacl);
|
||||
|
||||
dwErr = SetNamedSecurityInfoW( (LPWSTR)pwszHookMutexName,
|
||||
SE_KERNEL_OBJECT, LABEL_SECURITY_INFORMATION, NULL, NULL, NULL, pSacl);
|
||||
|
||||
}
|
||||
LocalFree(pSD);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // Q_OS_WIN32
|
||||
|
||||
MouseOver::MouseOver() :
|
||||
pPref(NULL)
|
||||
{
|
||||
#ifdef Q_OS_WIN32
|
||||
HMODULE hm;
|
||||
ChangeWindowMessageFilterFunc changeWindowMessageFilterFunc = NULL;
|
||||
ChangeWindowMessageFilterExFunc changeWindowMessageFilterExFunc = NULL;
|
||||
mouseOverEnabled = false;
|
||||
|
||||
ThTypes_Init();
|
||||
|
@ -37,17 +103,17 @@ MouseOver::MouseOver()
|
|||
|
||||
wcex.cbSize = sizeof( WNDCLASSEX );
|
||||
|
||||
wcex.style = 0;
|
||||
wcex.lpfnWndProc = ( WNDPROC ) eventHandler;
|
||||
wcex.cbClsExtra = 0;
|
||||
wcex.cbWndExtra = 0;
|
||||
wcex.hInstance = GetModuleHandle( 0 );
|
||||
wcex.hIcon = NULL;
|
||||
wcex.hCursor = NULL,
|
||||
wcex.hbrBackground = NULL;
|
||||
wcex.lpszMenuName = NULL;
|
||||
wcex.lpszClassName = className;
|
||||
wcex.hIconSm = NULL;
|
||||
wcex.style = 0;
|
||||
wcex.lpfnWndProc = ( WNDPROC ) eventHandler;
|
||||
wcex.cbClsExtra = 0;
|
||||
wcex.cbWndExtra = 0;
|
||||
wcex.hInstance = GetModuleHandle( 0 );
|
||||
wcex.hIcon = NULL;
|
||||
wcex.hCursor = NULL,
|
||||
wcex.hbrBackground = NULL;
|
||||
wcex.lpszMenuName = NULL;
|
||||
wcex.lpszClassName = className;
|
||||
wcex.hIconSm = NULL;
|
||||
|
||||
RegisterClassEx( &wcex );
|
||||
|
||||
|
@ -58,6 +124,23 @@ MouseOver::MouseOver()
|
|||
if ( spyDll )
|
||||
activateSpyFn = ( ActivateSpyFn ) GetProcAddress( spyDll, "ActivateTextOutSpying" );
|
||||
|
||||
// Allow messages from low intehrity process - for Vista and Win7
|
||||
hm = GetModuleHandle( __TEXT("user32.dll"));
|
||||
if ( hm != NULL ) {
|
||||
changeWindowMessageFilterExFunc = (ChangeWindowMessageFilterExFunc)GetProcAddress( hm, "ChangeWindowMessageFilterEx" );
|
||||
if( changeWindowMessageFilterExFunc ) {
|
||||
CHANGEFILTERSTRUCT cfs = { sizeof( CHANGEFILTERSTRUCT ), 0 };
|
||||
changeWindowMessageFilterExFunc( GlobalData->ServerWND, WM_MY_SHOW_TRANSLATION, 1 /* MSGFLT_ALLOW */, &cfs );
|
||||
} else {
|
||||
changeWindowMessageFilterFunc = (ChangeWindowMessageFilterFunc)GetProcAddress( hm, "ChangeWindowMessageFilter" );
|
||||
if( changeWindowMessageFilterFunc )
|
||||
changeWindowMessageFilterFunc( WM_MY_SHOW_TRANSLATION, 1 /* MSGFLT_ADD */ );
|
||||
}
|
||||
}
|
||||
|
||||
//Allow object access from low intehrity process - for Vista and Win7
|
||||
SetLowLabelToGDSynchroObjects();
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -85,51 +168,83 @@ void MouseOver::disableMouseOver()
|
|||
|
||||
#ifdef Q_OS_WIN32
|
||||
|
||||
LRESULT MouseOver::makeScanBitMask()
|
||||
{
|
||||
LRESULT res = 0;
|
||||
if( pPref == NULL )
|
||||
return 0;
|
||||
if( !pPref->enableScanPopupModifiers || checkModifiersPressed( pPref->scanPopupModifiers ) ) {
|
||||
res = GD_FLAG_METHOD_STANDARD;
|
||||
if( pPref->scanPopupUseUIAutomation !=0 )
|
||||
res |= GD_FLAG_METHOD_UI_AUTOMATION;
|
||||
if( pPref->scanPopupUseIAccessibleEx !=0 )
|
||||
res |= GD_FLAG_METHOD_IACCESSIBLEEX;
|
||||
if( pPref->scanPopupUseGDMessage !=0 )
|
||||
res |= GD_FLAG_METHOD_GD_MESSAGE;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
LRESULT CALLBACK MouseOver::eventHandler( HWND hwnd, UINT msg,
|
||||
WPARAM wparam, LPARAM lparam )
|
||||
{
|
||||
if ( msg == WM_MY_SHOW_TRANSLATION )
|
||||
{
|
||||
// Don't handle word without necessity
|
||||
LRESULT res = instance().makeScanBitMask();
|
||||
|
||||
bool bNeedHandle = false;
|
||||
emit instance().askNeedWord( &bNeedHandle );
|
||||
if( !bNeedHandle ) return 0;
|
||||
if( res == 0 )
|
||||
return 0; // Don't handle word without necessity
|
||||
|
||||
int wordSeqPos;
|
||||
if( wparam != 0) //Ask for methods of word retrieving
|
||||
return res;
|
||||
|
||||
int wordSeqPos = 0;
|
||||
QString wordSeq;
|
||||
|
||||
// Is the string in utf8 or in locale encoding?
|
||||
|
||||
gd::wchar testBuf[ 256 ];
|
||||
|
||||
long result = Utf8::decode( GlobalData->CurMod.MatchedWord,
|
||||
strlen( GlobalData->CurMod.MatchedWord ),
|
||||
testBuf );
|
||||
|
||||
if ( result >= 0 )
|
||||
if( GlobalData->CurMod.WordLen == 0)
|
||||
{
|
||||
// It seems to be
|
||||
QString begin = QString::fromUtf8( GlobalData->CurMod.MatchedWord,
|
||||
GlobalData->CurMod.BeginPos ).normalized( QString::NormalizationForm_C );
|
||||
|
||||
QString end = QString::fromUtf8( GlobalData->CurMod.MatchedWord +
|
||||
GlobalData->CurMod.BeginPos ).normalized( QString::NormalizationForm_C );
|
||||
|
||||
wordSeq = begin + end;
|
||||
wordSeqPos = begin.size();
|
||||
if( ( res & GD_FLAG_METHOD_UI_AUTOMATION ) == 0 )
|
||||
return 0;
|
||||
POINT pt = GlobalData->CurMod.Pt;
|
||||
WCHAR *pwstr = gdGetWordAtPointByAutomation( pt );
|
||||
if( pwstr == NULL ) return 0;
|
||||
wordSeq = QString::fromWCharArray( pwstr );
|
||||
}
|
||||
else
|
||||
{
|
||||
// It's not, so interpret it as in local encoding
|
||||
QString begin = QString::fromLocal8Bit( GlobalData->CurMod.MatchedWord,
|
||||
GlobalData->CurMod.BeginPos ).normalized( QString::NormalizationForm_C );
|
||||
|
||||
QString end = QString::fromLocal8Bit( GlobalData->CurMod.MatchedWord +
|
||||
GlobalData->CurMod.BeginPos ).normalized( QString::NormalizationForm_C );
|
||||
// Is the string in utf8 or in locale encoding?
|
||||
|
||||
wordSeq = begin + end;
|
||||
wordSeqPos = begin.size();
|
||||
gd::wchar testBuf[ 256 ];
|
||||
|
||||
long result = Utf8::decode( GlobalData->CurMod.MatchedWord,
|
||||
strlen( GlobalData->CurMod.MatchedWord ),
|
||||
testBuf );
|
||||
|
||||
if ( result >= 0 )
|
||||
{
|
||||
// It seems to be
|
||||
QString begin = QString::fromUtf8( GlobalData->CurMod.MatchedWord,
|
||||
GlobalData->CurMod.BeginPos ).normalized( QString::NormalizationForm_C );
|
||||
|
||||
QString end = QString::fromUtf8( GlobalData->CurMod.MatchedWord +
|
||||
GlobalData->CurMod.BeginPos ).normalized( QString::NormalizationForm_C );
|
||||
|
||||
wordSeq = begin + end;
|
||||
wordSeqPos = begin.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
// It's not, so interpret it as in local encoding
|
||||
QString begin = QString::fromLocal8Bit( GlobalData->CurMod.MatchedWord,
|
||||
GlobalData->CurMod.BeginPos ).normalized( QString::NormalizationForm_C );
|
||||
|
||||
QString end = QString::fromLocal8Bit( GlobalData->CurMod.MatchedWord +
|
||||
GlobalData->CurMod.BeginPos ).normalized( QString::NormalizationForm_C );
|
||||
|
||||
wordSeq = begin + end;
|
||||
wordSeqPos = begin.size();
|
||||
}
|
||||
}
|
||||
|
||||
// Now locate the word inside the sequence
|
||||
|
@ -139,7 +254,7 @@ LRESULT CALLBACK MouseOver::eventHandler( HWND hwnd, UINT msg,
|
|||
if ( wordSeq[ wordSeqPos ].isSpace() )
|
||||
{
|
||||
// Currently we ignore such cases
|
||||
return DefWindowProc( hwnd, msg, wparam, lparam );
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
if ( !wordSeq[ wordSeqPos ].isLetterOrNumber() )
|
||||
|
@ -163,7 +278,7 @@ LRESULT CALLBACK MouseOver::eventHandler( HWND hwnd, UINT msg,
|
|||
if ( end - begin == 1 )
|
||||
{
|
||||
// Well, turns out it was just a single non-letter char, discard it
|
||||
return DefWindowProc( hwnd, msg, wparam, lparam );
|
||||
return 0;
|
||||
}
|
||||
|
||||
word = wordSeq.mid( begin, end - begin );
|
||||
|
@ -203,6 +318,7 @@ LRESULT CALLBACK MouseOver::eventHandler( HWND hwnd, UINT msg,
|
|||
}
|
||||
|
||||
emit instance().hovered( word );
|
||||
return 0;
|
||||
}
|
||||
|
||||
return DefWindowProc( hwnd, msg, wparam, lparam );
|
||||
|
|
14
mouseover.hh
14
mouseover.hh
|
@ -2,6 +2,8 @@
|
|||
#define __MOUSEOVER_HH_INCLUDED__
|
||||
|
||||
#include <QObject>
|
||||
#include "config.hh"
|
||||
#include "keyboardstate.hh"
|
||||
|
||||
#ifdef Q_OS_WIN32
|
||||
#include <windows.h>
|
||||
|
@ -15,7 +17,7 @@
|
|||
///
|
||||
/// The Windows platform is the only one supported; it works with the help of
|
||||
/// two external .dll files,
|
||||
class MouseOver: public QObject
|
||||
class MouseOver: public QObject, public KeyboardState
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -29,18 +31,21 @@ public:
|
|||
/// Disables mouseover.
|
||||
void disableMouseOver();
|
||||
|
||||
/// Set pointer to program configuration
|
||||
void setPreferencesPtr( Config::Preferences const *ppref ) { pPref = ppref; };
|
||||
|
||||
signals:
|
||||
|
||||
/// Emitted when there was some text under cursor which was hovered over.
|
||||
void hovered( QString const & );
|
||||
/// Ask for need to handle word under cursor
|
||||
void askNeedWord( bool * );
|
||||
|
||||
private:
|
||||
|
||||
MouseOver();
|
||||
~MouseOver();
|
||||
|
||||
Config::Preferences const *pPref;
|
||||
|
||||
#ifdef Q_OS_WIN32
|
||||
|
||||
static LRESULT CALLBACK eventHandler( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam );
|
||||
|
@ -50,6 +55,9 @@ private:
|
|||
HINSTANCE spyDll;
|
||||
bool mouseOverEnabled;
|
||||
|
||||
/// Create mask for scan methods
|
||||
LRESULT makeScanBitMask();
|
||||
|
||||
#endif
|
||||
|
||||
};
|
||||
|
|
108
mouseover_win32/GetWordByIAccEx.c
Normal file
108
mouseover_win32/GetWordByIAccEx.c
Normal file
|
@ -0,0 +1,108 @@
|
|||
#include <windows.h>
|
||||
#include <wtypes.h>
|
||||
#include "ThTypes.h"
|
||||
#include "IAccExInt.h"
|
||||
#include "GetWordByIAccEx.h"
|
||||
|
||||
GetPhysicalCursorPosFunc getPhysicalCursorPosFunc;
|
||||
|
||||
BOOL FindGetPhysicalCursorPos()
|
||||
{
|
||||
HMODULE hm;
|
||||
getPhysicalCursorPosFunc = NULL;
|
||||
hm = GetModuleHandle( "user32.dll" );
|
||||
if( hm != NULL ) {
|
||||
getPhysicalCursorPosFunc = (GetPhysicalCursorPosFunc)GetProcAddress( hm, "GetPhysicalCursorPos" );
|
||||
}
|
||||
return( getPhysicalCursorPosFunc != NULL );
|
||||
}
|
||||
|
||||
|
||||
HRESULT GetParentAccessibleObject( IAccessible* pAcc, IAccessible** ppAccParent )
|
||||
{
|
||||
IDispatch* pDispatch = NULL;
|
||||
|
||||
*ppAccParent = NULL;
|
||||
if ( pAcc == NULL )
|
||||
return E_INVALIDARG;
|
||||
HRESULT hr = pAcc->lpVtbl->get_accParent( pAcc, &pDispatch );
|
||||
if ( ( hr == S_OK ) && ( pDispatch != NULL ) ) {
|
||||
hr = pDispatch->lpVtbl->QueryInterface( pDispatch, &IID_IAccessible, (void**)ppAccParent );
|
||||
pDispatch->lpVtbl->Release( pDispatch );
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
BOOL getWordByAccEx( POINT pt )
|
||||
{
|
||||
HRESULT hr;
|
||||
IAccessible *pAcc, *pAccParent;
|
||||
ITextProvider *pText;
|
||||
ITextRangeProvider *pTextRange;
|
||||
VARIANT var;
|
||||
long idChild;
|
||||
BSTR bstr = NULL;
|
||||
int n;
|
||||
UiaPoint upt;
|
||||
POINT ppt = { 0, 0 };
|
||||
|
||||
if( getPhysicalCursorPosFunc != NULL ) {
|
||||
getPhysicalCursorPosFunc( &ppt );
|
||||
} else {
|
||||
ppt = pt;
|
||||
}
|
||||
|
||||
upt.x = ppt.x;
|
||||
upt.y = ppt.y;
|
||||
|
||||
pAcc = NULL;
|
||||
hr = AccessibleObjectFromPoint( ppt, &pAcc, &var );
|
||||
idChild = var.lVal;
|
||||
|
||||
if( hr != S_OK || pAcc == NULL) {
|
||||
VariantClear( &var );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pText = NULL;
|
||||
while( pAcc != NULL) {
|
||||
hr = GetPatternFromIAccessible( pAcc, 0, UIA_TextPatternId, &IID_ITextProvider, (void **)&pText );
|
||||
if( hr == S_OK && pText != NULL )
|
||||
break;
|
||||
pAccParent = NULL;
|
||||
hr = GetParentAccessibleObject( pAcc, &pAccParent );
|
||||
pAcc->lpVtbl->Release( pAcc );
|
||||
pAcc = pAccParent;
|
||||
}
|
||||
if( pAcc == NULL )
|
||||
return FALSE;
|
||||
|
||||
pAcc->lpVtbl->Release( pAcc );
|
||||
|
||||
pTextRange = NULL;
|
||||
hr = pText->lpVtbl->RangeFromPoint( pText, upt, &pTextRange );
|
||||
if( hr != S_OK || pTextRange == NULL ) {
|
||||
pText->lpVtbl->Release( pText );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
hr = pTextRange->lpVtbl->ExpandToEnclosingUnit( pTextRange, TextUnit_Word );
|
||||
if( hr == S_OK) {
|
||||
bstr = NULL;
|
||||
hr = pTextRange->lpVtbl->GetText( pTextRange, 255, &bstr );
|
||||
if (hr == S_OK) {
|
||||
n = SysStringLen( bstr );
|
||||
if( n != 0 ) {
|
||||
n = WideCharToMultiByte( CP_UTF8, 0, (LPCWSTR)bstr, n, GlobalData->CurMod.MatchedWord, sizeof( GlobalData->CurMod.MatchedWord ) - 1, NULL, NULL );
|
||||
GlobalData->CurMod.WordLen = n;
|
||||
GlobalData->CurMod.MatchedWord[n] = 0;
|
||||
}
|
||||
SysFreeString( bstr );
|
||||
}
|
||||
}
|
||||
pTextRange->lpVtbl->Release( pTextRange );
|
||||
pText->lpVtbl->Release( pText );
|
||||
|
||||
return TRUE;
|
||||
}
|
19
mouseover_win32/GetWordByIAccEx.h
Normal file
19
mouseover_win32/GetWordByIAccEx.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
#ifndef __GetWordByIAccEx_H_DEFINED_
|
||||
#define __GetWordByIAccEx_H_DEFINED_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef BOOL (*GetPhysicalCursorPosFunc)(LPPOINT);
|
||||
extern GetPhysicalCursorPosFunc getPhysicalCursorPosFunc;
|
||||
|
||||
BOOL FindGetPhysicalCursorPos();
|
||||
|
||||
BOOL getWordByAccEx( POINT pt );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -87,8 +87,10 @@ static BOOL HookImportFunction(HMODULE hModule, LPCSTR szImportModule, LPCSTR sz
|
|||
MEMORY_BASIC_INFORMATION mbi_thunk;
|
||||
DWORD dwOldProtect;
|
||||
|
||||
VirtualQuery(pRealThunk, &mbi_thunk, sizeof(MEMORY_BASIC_INFORMATION));
|
||||
VirtualProtect(mbi_thunk.BaseAddress, mbi_thunk.RegionSize, PAGE_READWRITE, &mbi_thunk.Protect);
|
||||
if( !VirtualQuery(pRealThunk, &mbi_thunk, sizeof(MEMORY_BASIC_INFORMATION)) )
|
||||
return FALSE;
|
||||
if( !VirtualProtect(mbi_thunk.BaseAddress, mbi_thunk.RegionSize, PAGE_READWRITE, &mbi_thunk.Protect) )
|
||||
return FALSE;
|
||||
if (paOrigFuncs)
|
||||
*paOrigFuncs = (PROC)pRealThunk->u1.Function;
|
||||
pRealThunk->u1.Function = (DWORD)paHookFuncs;
|
||||
|
|
113
mouseover_win32/IAccEx.c
Normal file
113
mouseover_win32/IAccEx.c
Normal file
|
@ -0,0 +1,113 @@
|
|||
#include <windows.h>
|
||||
#include <winable.h>
|
||||
#include "IAccExInt.h"
|
||||
|
||||
const long UIA_InvokePatternId = 10000;
|
||||
const long UIA_SelectionPatternId = 10001;
|
||||
const long UIA_ValuePatternId = 10002;
|
||||
const long UIA_RangeValuePatternId = 10003;
|
||||
const long UIA_ScrollPatternId = 10004;
|
||||
const long UIA_ExpandCollapsePatternId = 10005;
|
||||
const long UIA_GridPatternId = 10006;
|
||||
const long UIA_GridItemPatternId = 10007;
|
||||
const long UIA_MultipleViewPatternId = 10008;
|
||||
const long UIA_WindowPatternId = 10009;
|
||||
const long UIA_SelectionItemPatternId = 10010;
|
||||
const long UIA_DockPatternId = 10011;
|
||||
const long UIA_TablePatternId = 10012;
|
||||
const long UIA_TableItemPatternId = 10013;
|
||||
const long UIA_TextPatternId = 10014;
|
||||
const long UIA_TogglePatternId = 10015;
|
||||
const long UIA_TransformPatternId = 10016;
|
||||
const long UIA_ScrollItemPatternId = 10017;
|
||||
const long UIA_LegacyIAccessiblePatternId = 10018;
|
||||
const long UIA_ItemContainerPatternId = 10019;
|
||||
const long UIA_VirtualizedItemPatternId = 10020;
|
||||
const long UIA_SynchronizedInputPatternId = 10021;
|
||||
|
||||
HRESULT GetIAccessibleExFromIAccessible( IAccessible *pAcc, long idChild, IAccessibleEx **ppaex )
|
||||
{
|
||||
*ppaex = NULL;
|
||||
IAccessibleEx *paex;
|
||||
IServiceProvider *pSp = NULL;
|
||||
//char s[500];
|
||||
HRESULT hr = pAcc->lpVtbl->QueryInterface( pAcc, &IID_IServiceProvider, (void **)&pSp );
|
||||
/*
|
||||
wsprintf(s,"GD:QueryInterface (IServiceProvider) return hr=%08X, ptr=%p\n", hr, pSp);
|
||||
OutputDebugString(s);
|
||||
*/
|
||||
if( hr != S_OK ) return hr;
|
||||
if( pSp == NULL ) return E_NOINTERFACE;
|
||||
|
||||
paex = NULL;
|
||||
hr = pSp->lpVtbl->QueryService( pSp, &IID_IAccessibleEx, &IID_IAccessibleEx, (void **)&paex );
|
||||
pSp->lpVtbl->Release( pSp );
|
||||
/*
|
||||
wsprintf(s,"GD:QueryService (IAccessibleEx) return hr=%08X, ptr=%p\n", hr, paex);
|
||||
OutputDebugString(s);
|
||||
*/
|
||||
if( hr != S_OK ) return hr;
|
||||
if( paex == NULL ) return E_NOINTERFACE;
|
||||
|
||||
if(idChild == CHILDID_SELF) {
|
||||
*ppaex = paex;
|
||||
} else {
|
||||
IAccessibleEx *paexChild = NULL;
|
||||
hr = paex->lpVtbl->GetObjectForChild( paex, idChild, &paexChild );
|
||||
/*
|
||||
wsprintf(s,"GD: GetObjectForChild return hr=%08X, ptr=%p (ChildID=%i)\n", hr, paexChild, idChild);
|
||||
OutputDebugString(s);
|
||||
*/
|
||||
paex->lpVtbl->Release( paex );
|
||||
if( hr != S_OK ) return hr;
|
||||
if(paexChild == NULL) return E_NOINTERFACE;
|
||||
*ppaex = paexChild;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT GetIRawElementProviderFromIAccessible( IAccessible * pAcc, long idChild, IRawElementProviderSimple **ppEl )
|
||||
{
|
||||
*ppEl = NULL;
|
||||
IAccessibleEx *paex;
|
||||
//char s[500];
|
||||
HRESULT hr = GetIAccessibleExFromIAccessible( pAcc, idChild, &paex );
|
||||
if( hr != S_OK ) return hr;
|
||||
|
||||
hr = paex->lpVtbl->QueryInterface( paex, &IID_IRawElementProviderSimple, (void **)ppEl );
|
||||
/*
|
||||
wsprintf(s,"GD:QueryInterface (IRawElementProviderSimple) return hr=%08X, ptr=%p\n", hr, ppEl);
|
||||
OutputDebugString(s);
|
||||
*/
|
||||
paex->lpVtbl->Release( paex );
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT GetPatternFromIAccessible( IAccessible * pAcc, long idChild, PATTERNID patternId, REFIID iid, void **ppv )
|
||||
{
|
||||
IRawElementProviderSimple * pel;
|
||||
//char s[500];
|
||||
HRESULT hr = GetIRawElementProviderFromIAccessible( pAcc, idChild, &pel );
|
||||
if( hr != S_OK ) return hr;
|
||||
if( pel == NULL ) return E_NOINTERFACE;
|
||||
|
||||
IUnknown * pPatternObject = NULL;
|
||||
hr = pel->lpVtbl->GetPatternProvider( pel, patternId, &pPatternObject );
|
||||
/*
|
||||
wsprintf(s,"GD:GetPatternProvider return hr=%08X, ptr=%p\n", hr, pPatternObject);
|
||||
OutputDebugString(s);
|
||||
*/
|
||||
pel->lpVtbl->Release( pel );
|
||||
if( hr != S_OK ) return hr;
|
||||
if( pPatternObject == NULL ) return E_NOINTERFACE;
|
||||
|
||||
*ppv = NULL;
|
||||
hr = pPatternObject->lpVtbl->QueryInterface( pPatternObject, iid, ppv );
|
||||
/*
|
||||
wsprintf(s,"GD:QueryInterface (TextPattern) return hr=%08X, ptr=%p\n", hr, ppv);
|
||||
OutputDebugString(s);
|
||||
*/
|
||||
pPatternObject->lpVtbl->Release( pPatternObject );
|
||||
if( *ppv == NULL ) return E_NOINTERFACE;
|
||||
return hr;
|
||||
}
|
167
mouseover_win32/IAccExInt.h
Normal file
167
mouseover_win32/IAccExInt.h
Normal file
|
@ -0,0 +1,167 @@
|
|||
#ifndef __UIAUTO_HH_INCLUDED__
|
||||
#define __UIAUTO_HH_INCLUDED__
|
||||
|
||||
//#include <objbase.h>
|
||||
#include <unknwn.h>
|
||||
#include <oaidl.h>
|
||||
#include <oleacc.h>
|
||||
#include <servprov.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const IID IID_IAccessibleEx;
|
||||
extern const IID IID_IRawElementProviderSimple;
|
||||
extern const IID IID_ITextProvider;
|
||||
extern const IID IID_ITextRangeProvider;
|
||||
|
||||
typedef int PROPERTYID;
|
||||
typedef int PATTERNID;
|
||||
typedef int TEXTATTRIBUTEID;
|
||||
|
||||
typedef struct _UiaPoint
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
} UiaPoint;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ProviderOptions_ClientSideProvider = 0x1,
|
||||
ProviderOptions_ServerSideProvider = 0x2,
|
||||
ProviderOptions_NonClientAreaProvider = 0x4,
|
||||
ProviderOptions_OverrideProvider = 0x8,
|
||||
ProviderOptions_ProviderOwnsSetFocus = 0x10,
|
||||
ProviderOptions_UseComThreading = 0x20
|
||||
} ProviderOptions;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SupportedTextSelection_None = 0,
|
||||
SupportedTextSelection_Single = 1,
|
||||
SupportedTextSelection_Multiple = 2
|
||||
} SupportedTextSelection;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TextUnit_Character = 0,
|
||||
TextUnit_Format = 1,
|
||||
TextUnit_Word = 2,
|
||||
TextUnit_Line = 3,
|
||||
TextUnit_Paragraph = 4,
|
||||
TextUnit_Page = 5,
|
||||
TextUnit_Document = 6
|
||||
} TextUnit;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TextPatternRangeEndpoint_Start = 0,
|
||||
TextPatternRangeEndpoint_End = 1
|
||||
} TextPatternRangeEndpoint;
|
||||
|
||||
/* UIA_PatternIds */
|
||||
extern const long UIA_InvokePatternId;
|
||||
extern const long UIA_SelectionPatternId;
|
||||
extern const long UIA_ValuePatternId;
|
||||
extern const long UIA_RangeValuePatternId;
|
||||
extern const long UIA_ScrollPatternId;
|
||||
extern const long UIA_ExpandCollapsePatternId;
|
||||
extern const long UIA_GridPatternId;
|
||||
extern const long UIA_GridItemPatternId;
|
||||
extern const long UIA_MultipleViewPatternId;
|
||||
extern const long UIA_WindowPatternId;
|
||||
extern const long UIA_SelectionItemPatternId;
|
||||
extern const long UIA_DockPatternId;
|
||||
extern const long UIA_TablePatternId;
|
||||
extern const long UIA_TableItemPatternId;
|
||||
extern const long UIA_TextPatternId;
|
||||
extern const long UIA_TogglePatternId;
|
||||
extern const long UIA_TransformPatternId;
|
||||
extern const long UIA_ScrollItemPatternId;
|
||||
extern const long UIA_LegacyIAccessiblePatternId;
|
||||
extern const long UIA_ItemContainerPatternId;
|
||||
extern const long UIA_VirtualizedItemPatternId;
|
||||
extern const long UIA_SynchronizedInputPatternId;
|
||||
|
||||
#define INTERFACE IRawElementProviderSimple
|
||||
DECLARE_INTERFACE_(IRawElementProviderSimple, IUnknown)
|
||||
{
|
||||
STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;
|
||||
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
|
||||
STDMETHOD_(ULONG,Release)(THIS) PURE;
|
||||
|
||||
STDMETHOD(get_ProviderOptions)(THIS_ ProviderOptions *) PURE;
|
||||
STDMETHOD(GetPatternProvider)(THIS_ PATTERNID, IUnknown **) PURE;
|
||||
STDMETHOD(GetPropertyValue)(THIS_ PROPERTYID, VARIANT *) PURE;
|
||||
STDMETHOD(get_HostRawElementProvider)(THIS_ IRawElementProviderSimple **) PURE;
|
||||
};
|
||||
#undef INTERFACE
|
||||
|
||||
#define INTERFACE ITextRangeProvider
|
||||
DECLARE_INTERFACE_(ITextRangeProvider, IUnknown)
|
||||
{
|
||||
STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;
|
||||
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
|
||||
STDMETHOD_(ULONG,Release)(THIS) PURE;
|
||||
|
||||
STDMETHOD(Clone)(THIS_ ITextRangeProvider **) PURE;
|
||||
STDMETHOD(Compare)(THIS_ ITextRangeProvider *, BOOL *) PURE;
|
||||
STDMETHOD(CompareEndpoints)(THIS_ TextPatternRangeEndpoint, ITextRangeProvider *, TextPatternRangeEndpoint, int *) PURE;
|
||||
STDMETHOD(ExpandToEnclosingUnit)(THIS_ TextUnit) PURE;
|
||||
STDMETHOD(FindAttribute)(THIS_ TEXTATTRIBUTEID, VARIANT, BOOL, ITextRangeProvider **) PURE;
|
||||
STDMETHOD(FindText)(THIS_ BSTR, BOOL, BOOL, ITextRangeProvider **) PURE;
|
||||
STDMETHOD(GetAttributeValue)(THIS_ TEXTATTRIBUTEID, VARIANT *) PURE;
|
||||
STDMETHOD(GetBoundingRectangles)(THIS_ SAFEARRAY **) PURE;
|
||||
STDMETHOD(GetEnclosingElement)(THIS_ IRawElementProviderSimple **) PURE;
|
||||
STDMETHOD(GetText)(THIS_ int, BSTR *) PURE;
|
||||
STDMETHOD(Move)(THIS_ TextUnit, int, int *) PURE;
|
||||
STDMETHOD(MoveEndpointByUnit)(THIS_ TextPatternRangeEndpoint, TextUnit, int *) PURE;
|
||||
STDMETHOD(MoveEndpointByRange)(THIS_ TextPatternRangeEndpoint, ITextRangeProvider *, TextPatternRangeEndpoint) PURE;
|
||||
STDMETHOD(Select)(THIS) PURE;
|
||||
STDMETHOD(AddToSelection)(THIS) PURE;
|
||||
STDMETHOD(RemoveFromSelection)(THIS) PURE;
|
||||
STDMETHOD(ScrollIntoView)(THIS_ BOOL) PURE;
|
||||
STDMETHOD(GetChildren)(THIS_ SAFEARRAY **) PURE;
|
||||
};
|
||||
#undef INTERFACE
|
||||
|
||||
#define INTERFACE ITextProvider
|
||||
DECLARE_INTERFACE_(ITextProvider, IUnknown)
|
||||
{
|
||||
STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;
|
||||
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
|
||||
STDMETHOD_(ULONG,Release)(THIS) PURE;
|
||||
|
||||
STDMETHOD(GetSelection)(THIS_ SAFEARRAY **) PURE;
|
||||
STDMETHOD(GetVisibleRanges)(THIS_ SAFEARRAY **) PURE;
|
||||
STDMETHOD(RangeFromChild)(THIS_ IRawElementProviderSimple *, ITextRangeProvider **) PURE;
|
||||
STDMETHOD(RangeFromPoint)(THIS_ UiaPoint, ITextRangeProvider **pRetVal) PURE;
|
||||
STDMETHOD(get_DocumentRange)(THIS_ ITextRangeProvider **) PURE;
|
||||
STDMETHOD(get_SupportedTextSelection)(THIS_ SupportedTextSelection *) PURE;
|
||||
};
|
||||
#undef INTERFACE
|
||||
|
||||
#define INTERFACE IAccessibleEx
|
||||
DECLARE_INTERFACE_(IAccessibleEx, IUnknown)
|
||||
{
|
||||
STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;
|
||||
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
|
||||
STDMETHOD_(ULONG,Release)(THIS) PURE;
|
||||
|
||||
STDMETHOD(GetObjectForChild)(THIS_ long, IAccessibleEx **) PURE;
|
||||
STDMETHOD(GetIAccessiblePair)(THIS_ IAccessible **, long *) PURE;
|
||||
STDMETHOD(GetRuntimeId)(THIS_ SAFEARRAY **) PURE;
|
||||
STDMETHOD(ConvertReturnedElement)(THIS_ IRawElementProviderSimple *, IAccessibleEx **) PURE;
|
||||
};
|
||||
#undef INTERFACE
|
||||
|
||||
HRESULT GetIAccessibleExFromIAccessible( IAccessible *pAcc, long idChild, IAccessibleEx **ppaex );
|
||||
HRESULT GetIRawElementProviderFromIAccessible( IAccessible * pAcc, long idChild, IRawElementProviderSimple **ppEl );
|
||||
HRESULT GetPatternFromIAccessible( IAccessible * pAcc, long idChild, PATTERNID patternId, REFIID iid, void **ppv );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // UIAUTO_HH
|
|
@ -1,4 +1,4 @@
|
|||
GCC:=i686-pc-mingw32-gcc.exe -W -Wall -s -O2
|
||||
GCC:=gcc.exe -W -Wall -s -O2
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
|
@ -16,6 +16,15 @@ HookImportFunction.o: HookImportFunction.c
|
|||
GetWord.o: GetWord.c
|
||||
$(GCC) -c $<
|
||||
|
||||
IAccEx.o: IAccEx.c
|
||||
$(GCC) -c $<
|
||||
|
||||
GetWordByIAccEx.o: GetWordByIAccEx.c
|
||||
$(GCC) -c $<
|
||||
|
||||
guids.o: guids.c
|
||||
$(GCC) -c $<
|
||||
|
||||
GdTextOutHook.dll libGdTextOutHook.a: TextOutHook.o HookImportFunction.o GetWord.o
|
||||
$(GCC) -shared -o GdTextOutHook.dll $^ -lgdi32 -Wl,--out-implib,libGdTextOutHook.a
|
||||
|
||||
|
@ -25,5 +34,5 @@ TextOutSpy.o: TextOutSpy.c
|
|||
ThTypes.o: ThTypes.c
|
||||
$(GCC) -c $<
|
||||
|
||||
GdTextOutSpy.dll libGdTextOutSpy.a: TextOutSpy.o ThTypes.o
|
||||
$(GCC) -shared -o GdTextOutSpy.dll $^ -lgdi32 -Wl,--out-implib,libGdTextOutSpy.a
|
||||
GdTextOutSpy.dll libGdTextOutSpy.a: TextOutSpy.o ThTypes.o IAccEx.o guids.o GetWordByIAccEx.o
|
||||
$(GCC) -shared -o GdTextOutSpy.dll $^ -lgdi32 -luuid -loleacc -loleaut32 -Wl,--out-implib,libGdTextOutSpy.a
|
||||
|
|
|
@ -525,9 +525,9 @@ DWORD wso;
|
|||
case DLL_PROCESS_ATTACH:
|
||||
if(hHookMutex==0) {
|
||||
hHookMutex = CreateMutex(NULL, FALSE, "GoldenDictTextOutHookMutex");
|
||||
if(hHookMutex==0) return(FALSE);
|
||||
if(hHookMutex==0)
|
||||
return(FALSE);
|
||||
}
|
||||
//ThTypes_Init();
|
||||
InstallTextOutHooks();
|
||||
break;
|
||||
|
||||
|
@ -541,7 +541,6 @@ DWORD wso;
|
|||
hHookMutex=0;
|
||||
}
|
||||
}
|
||||
//Thtypes_End();
|
||||
break;
|
||||
|
||||
case DLL_THREAD_ATTACH:
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
#include "TextOutSpy.h"
|
||||
#include "ThTypes.h"
|
||||
#include "GDDataTranfer.h"
|
||||
#include "GetWordByIAccEx.h"
|
||||
|
||||
const int MOUSEOVER_INTERVAL = 300;
|
||||
const int REQUEST_MESSAGE_INTERVAL = 500;
|
||||
const int WM_MY_SHOW_TRANSLATION = WM_USER + 301;
|
||||
|
||||
HINSTANCE g_hInstance = NULL;
|
||||
HANDLE hSynhroMutex = 0;
|
||||
HANDLE hSynhroMutex = 0, hHookMutex = 0;
|
||||
HINSTANCE hGetWordLib = 0;
|
||||
UINT_PTR TimerID = 0;
|
||||
typedef void (*GetWordProc_t)(TCurrentMode *);
|
||||
|
@ -29,9 +30,29 @@ HWND WndParent,WndChild;
|
|||
|
||||
static void SendWordToServer()
|
||||
{
|
||||
DWORD SendMsgAnswer;
|
||||
if(uGdAskMessage) {
|
||||
LRESULT lr;
|
||||
DWORD SendMsgAnswer, flags;
|
||||
LRESULT lr;
|
||||
if (hGetWordLib == 0) {
|
||||
hGetWordLib = LoadLibrary(GlobalData->LibName);
|
||||
if (hGetWordLib) {
|
||||
GetWordProc = (GetWordProc_t)GetProcAddress(hGetWordLib, "__gdGetWord");
|
||||
}
|
||||
else {
|
||||
hGetWordLib = (HINSTANCE)-1;
|
||||
}
|
||||
}
|
||||
|
||||
// Ask for needing to retrieve word - WPARAM = 1
|
||||
lr = SendMessageTimeout(GlobalData->ServerWND, WM_MY_SHOW_TRANSLATION, 1, 0, SMTO_ABORTIFHUNG, MOUSEOVER_INTERVAL, &SendMsgAnswer);
|
||||
if( lr == 0 || SendMsgAnswer == 0) //No answer or no needing
|
||||
return;
|
||||
|
||||
GlobalData->CurMod.MatchedWord[0] = 0;
|
||||
GlobalData->CurMod.WordLen = 0;
|
||||
GlobalData->CurMod.BeginPos = 0;
|
||||
flags = SendMsgAnswer;
|
||||
|
||||
if( ( flags & GD_FLAG_METHOD_GD_MESSAGE ) != 0 && uGdAskMessage != 0 ) {
|
||||
int n;
|
||||
gds.dwSize = sizeof(gds);
|
||||
gds.cwData = Buffer;
|
||||
|
@ -51,23 +72,28 @@ DWORD SendMsgAnswer;
|
|||
return;
|
||||
}
|
||||
}
|
||||
if (hGetWordLib == 0) {
|
||||
hGetWordLib = LoadLibrary(GlobalData->LibName);
|
||||
if (hGetWordLib) {
|
||||
GetWordProc = (GetWordProc_t)GetProcAddress(hGetWordLib, "__gdGetWord");
|
||||
}
|
||||
else {
|
||||
hGetWordLib = (HINSTANCE)-1;
|
||||
}
|
||||
}
|
||||
if (GetWordProc) {
|
||||
|
||||
if( ( flags & GD_FLAG_METHOD_STANDARD ) != 0 && GetWordProc != 0 ) {
|
||||
GlobalData->CurMod.WND = GlobalData->LastWND;
|
||||
GlobalData->CurMod.Pt = GlobalData->LastPt;
|
||||
GetWordProc(&(GlobalData->CurMod));
|
||||
if (GlobalData->CurMod.WordLen > 0) {
|
||||
SendMessageTimeout(GlobalData->ServerWND, WM_MY_SHOW_TRANSLATION, 0, 0, SMTO_ABORTIFHUNG, MOUSEOVER_INTERVAL, &SendMsgAnswer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if( ( flags & GD_FLAG_METHOD_IACCESSIBLEEX ) != 0 ) {
|
||||
getWordByAccEx( GlobalData->LastPt );
|
||||
if (GlobalData->CurMod.WordLen > 0) {
|
||||
SendMessageTimeout(GlobalData->ServerWND, WM_MY_SHOW_TRANSLATION, 0, 0, SMTO_ABORTIFHUNG, MOUSEOVER_INTERVAL, &SendMsgAnswer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if( ( flags & GD_FLAG_METHOD_UI_AUTOMATION ) != 0 ) {
|
||||
PostMessage( GlobalData->ServerWND, WM_MY_SHOW_TRANSLATION, 0, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
void CALLBACK TimerFunc(HWND hWnd,UINT nMsg,UINT nTimerid,DWORD dwTime)
|
||||
|
@ -86,6 +112,7 @@ DWORD wso;
|
|||
LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
DWORD wso;
|
||||
|
||||
if ((nCode == HC_ACTION) && ((wParam == WM_MOUSEMOVE) || (wParam == WM_NCMOUSEMOVE)) && (GlobalData != NULL)) {
|
||||
wso = WaitForSingleObject(hSynhroMutex, 0);
|
||||
if (wso == WAIT_OBJECT_0 || wso == WAIT_ABANDONED) {
|
||||
|
@ -165,10 +192,16 @@ BOOL APIENTRY DllMain (HINSTANCE hInst /* Library instance handle. */ ,
|
|||
g_hInstance = hInst;
|
||||
if(hSynhroMutex==0) {
|
||||
hSynhroMutex = CreateMutex(NULL, FALSE, "GoldenDictTextOutSpyMutex");
|
||||
if(hSynhroMutex==0) return(FALSE);
|
||||
if(hSynhroMutex==0) {
|
||||
return(FALSE);
|
||||
}
|
||||
}
|
||||
if(hHookMutex==0) {
|
||||
hHookMutex = CreateMutex(NULL, FALSE, "GoldenDictTextOutHookMutex");
|
||||
}
|
||||
ThTypes_Init();
|
||||
uGdAskMessage = RegisterWindowMessage(GD_MESSAGE_NAME);
|
||||
FindGetPhysicalCursorPos();
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
|
@ -190,6 +223,14 @@ BOOL APIENTRY DllMain (HINSTANCE hInst /* Library instance handle. */ ,
|
|||
if ((hGetWordLib != 0)&&(hGetWordLib != (HINSTANCE)(-1))) {
|
||||
FreeLibrary(hGetWordLib);
|
||||
}
|
||||
if(hHookMutex) {
|
||||
DWORD wso = WaitForSingleObject(hHookMutex, 5000);
|
||||
if (wso == WAIT_OBJECT_0 || wso == WAIT_ABANDONED) {
|
||||
ReleaseMutex(hHookMutex);
|
||||
CloseHandle(hHookMutex);
|
||||
hHookMutex=0;
|
||||
}
|
||||
}
|
||||
Thtypes_End();
|
||||
break;
|
||||
|
||||
|
|
|
@ -5,8 +5,12 @@ TGlobalDLLData *GlobalData = NULL;
|
|||
|
||||
void ThTypes_Init()
|
||||
{
|
||||
if (!MMFHandle)
|
||||
if (!MMFHandle) {
|
||||
MMFHandle = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(TGlobalDLLData), "GoldenDictTextOutHookSharedMem");
|
||||
}
|
||||
if (!MMFHandle) {
|
||||
MMFHandle = OpenFileMappingA(FILE_MAP_READ | FILE_MAP_WRITE, 0, "GoldenDictTextOutHookSharedMem");
|
||||
}
|
||||
if (!GlobalData && MMFHandle != NULL)
|
||||
GlobalData = MapViewOfFile(MMFHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,11 @@
|
|||
|
||||
#include <windows.h>
|
||||
|
||||
#define GD_FLAG_METHOD_STANDARD 0x00000001
|
||||
#define GD_FLAG_METHOD_GD_MESSAGE 0x00000002
|
||||
#define GD_FLAG_METHOD_IACCESSIBLEEX 0x00000004
|
||||
#define GD_FLAG_METHOD_UI_AUTOMATION 0x00000008
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
|
|
8
mouseover_win32/guids.c
Normal file
8
mouseover_win32/guids.c
Normal file
|
@ -0,0 +1,8 @@
|
|||
#define INITGUID
|
||||
#include <basetyps.h>
|
||||
|
||||
DEFINE_GUID(IID_IAccessibleEx, 0xf8b80ada, 0x2c44, 0x48d0, 0x89, 0xbe, 0x5f, 0xf2, 0x3c, 0x9c, 0xd8, 0x75);
|
||||
DEFINE_GUID(IID_IRawElementProviderSimple, 0xd6dd68d1, 0x86fd, 0x4332, 0x86, 0x66, 0x9a, 0xbe, 0xde, 0xa2, 0xd2, 0x4c);
|
||||
DEFINE_GUID(IID_ITextProvider, 0x3589c92c, 0x63f3, 0x4367, 0x99, 0xbb, 0xad, 0xa6, 0x53, 0xb7, 0x7c, 0xf2);
|
||||
DEFINE_GUID(IID_ITextRangeProvider, 0x5347ad7b, 0xc355, 0x46f8, 0xaf, 0xf5, 0x90, 0x90, 0x33, 0x58, 0x2f, 0x63);
|
||||
|
|
@ -118,6 +118,9 @@ Preferences::Preferences( QWidget * parent, Config::Preferences const & p ):
|
|||
|
||||
ui.scanPopupAltMode->setChecked( p.scanPopupAltMode );
|
||||
ui.scanPopupAltModeSecs->setValue( p.scanPopupAltModeSecs );
|
||||
ui.scanPopupUseUIAutomation->setChecked( p.scanPopupUseUIAutomation );
|
||||
ui.scanPopupUseIAccessibleEx->setChecked( p.scanPopupUseIAccessibleEx );
|
||||
ui.scanPopupUseGDMessage->setChecked( p.scanPopupUseGDMessage );
|
||||
|
||||
// Different platforms have different keys available
|
||||
|
||||
|
@ -132,6 +135,13 @@ Preferences::Preferences( QWidget * parent, Config::Preferences const & p ):
|
|||
ui.rightShift->hide();
|
||||
#endif
|
||||
|
||||
//Platform-specific options
|
||||
|
||||
#ifndef Q_OS_WIN32
|
||||
// ui.groupBox_ScanPopupTechnologies->hide();
|
||||
ui.tabWidget->removeTab( 5 );
|
||||
#endif
|
||||
|
||||
// Sound
|
||||
|
||||
#ifdef Q_WS_WIN
|
||||
|
@ -222,6 +232,9 @@ Config::Preferences Preferences::getPreferences()
|
|||
|
||||
p.scanPopupAltMode = ui.scanPopupAltMode->isChecked();
|
||||
p.scanPopupAltModeSecs = ui.scanPopupAltModeSecs->value();
|
||||
p.scanPopupUseUIAutomation = ui.scanPopupUseUIAutomation->isChecked();
|
||||
p.scanPopupUseIAccessibleEx = ui.scanPopupUseIAccessibleEx->isChecked();
|
||||
p.scanPopupUseGDMessage = ui.scanPopupUseGDMessage->isChecked();
|
||||
|
||||
p.pronounceOnLoadMain = ui.pronounceOnLoadMain->isChecked();
|
||||
p.pronounceOnLoadPopup = ui.pronounceOnLoadPopup->isChecked();
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>572</width>
|
||||
<height>347</height>
|
||||
<height>357</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
@ -275,7 +275,7 @@ With this on however, it will hide the main window.</string>
|
|||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_10">
|
||||
<item>
|
||||
<spacer name="verticalSpacer_7">
|
||||
<spacer name="verticalSpacer_16">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
|
@ -556,7 +556,7 @@ seconds, which is specified here.</string>
|
|||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
|
@ -1018,6 +1018,72 @@ download page.</string>
|
|||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_Advanced">
|
||||
<attribute name="title">
|
||||
<string>Ad&vanced</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_11">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_ScanPopupTechnologies">
|
||||
<property name="title">
|
||||
<string>ScanPopup extra technologies</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_13">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="scanPopupUseIAccessibleEx">
|
||||
<property name="toolTip">
|
||||
<string>Try to use IAccessibleEx technology to retrieve word under cursor.
|
||||
This technology works only with some programs that support it
|
||||
(for example Internet Explorer 9).
|
||||
It not needed to select this option if you don't use such programs.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use &IAccessibleEx</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="scanPopupUseUIAutomation">
|
||||
<property name="toolTip">
|
||||
<string>Try to use UI Automation technology to retrieve word under cursor.
|
||||
This technology works only with some programs that support it.
|
||||
It not needed to select this option if you don't use such programs.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use &UIAutomation</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="scanPopupUseGDMessage">
|
||||
<property name="toolTip">
|
||||
<string>Try to use special GoldenDict message to retrieve word under cursor.
|
||||
This technology works only with some programs that support it.
|
||||
It not needed to select this option if you don't use such programs.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use &GoldenDict message</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_17">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
@ -1069,7 +1135,6 @@ download page.</string>
|
|||
<tabstop>proxyPort</tabstop>
|
||||
<tabstop>proxyUser</tabstop>
|
||||
<tabstop>proxyPassword</tabstop>
|
||||
<tabstop>enableScanPopup</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="resources.qrc"/>
|
||||
|
|
|
@ -158,8 +158,7 @@ ScanPopup::ScanPopup( QWidget * parent,
|
|||
connect( &mouseGrabPollTimer, SIGNAL( timeout() ),
|
||||
this, SLOT(mouseGrabPoll()) );
|
||||
|
||||
connect( &MouseOver::instance(), SIGNAL( askNeedWord( bool * ) ),
|
||||
this, SLOT( needHandleWord( bool * ) ), Qt::DirectConnection );
|
||||
MouseOver::instance().setPreferencesPtr( &( cfg.preferences ) );
|
||||
}
|
||||
|
||||
ScanPopup::~ScanPopup()
|
||||
|
@ -777,8 +776,3 @@ void ScanPopup::mutedDictionariesChanged()
|
|||
if ( dictionaryBar.toggleViewAction()->isChecked() )
|
||||
definition->updateMutedContents();
|
||||
}
|
||||
|
||||
void ScanPopup::needHandleWord( bool *pNeed )
|
||||
{
|
||||
*pNeed = !cfg.preferences.enableScanPopupModifiers || checkModifiersPressed( cfg.preferences.scanPopupModifiers );
|
||||
}
|
||||
|
|
|
@ -137,8 +137,6 @@ private slots:
|
|||
void altModeExpired();
|
||||
void altModePoll();
|
||||
|
||||
void needHandleWord(bool *pNeed);
|
||||
|
||||
/// Called repeatedly once the popup is initially engaged and we monitor the
|
||||
/// mouse as it may move away from the window. This simulates mouse grab, in
|
||||
/// essense, but seems more reliable. Once the mouse enters the window, the
|
||||
|
|
330
uiauto.hh
Normal file
330
uiauto.hh
Normal file
|
@ -0,0 +1,330 @@
|
|||
#ifndef __UIAUTO_HH_INCLUDED__
|
||||
#define __UIAUTO_HH_INCLUDED__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <oleacc.h>
|
||||
|
||||
EXTERN_C const IID IID_IUIAutomation;
|
||||
EXTERN_C const IID CLSID_CUIAutomation;
|
||||
EXTERN_C const IID IID_IUIAutomationElement;
|
||||
EXTERN_C const IID IID_IUIAutomationTextPattern;
|
||||
EXTERN_C const IID IID_IUIAutomationTextRange;
|
||||
EXTERN_C const IID IID_IUIAutomationTreeWalker;
|
||||
|
||||
typedef interface IUIAutomationElement IUIAutomationElement;
|
||||
typedef interface IUIAutomationElementArray IUIAutomationElementArray;
|
||||
typedef interface IUIAutomationTextPattern IUIAutomationTextPattern;
|
||||
typedef interface IUIAutomationTextRange IUIAutomationTextRange;
|
||||
typedef interface IUIAutomationTextRangeArray IUIAutomationTextRangeArray;
|
||||
typedef interface IUIAutomationCacheRequest IUIAutomationCacheRequest;
|
||||
typedef interface IUIAutomationTreeWalker IUIAutomationTreeWalker;
|
||||
typedef interface IUIAutomationCondition IUIAutomationCondition;
|
||||
typedef interface IUIAutomationEventHandler IUIAutomationEventHandler;
|
||||
typedef interface IUIAutomationPropertyChangedEventHandler IUIAutomationPropertyChangedEventHandler;
|
||||
typedef interface IUIAutomationStructureChangedEventHandler IUIAutomationStructureChangedEventHandler;
|
||||
typedef interface IUIAutomationFocusChangedEventHandler IUIAutomationFocusChangedEventHandler;
|
||||
typedef interface IUIAutomationProxyFactory IUIAutomationProxyFactory;
|
||||
typedef interface IUIAutomationProxyFactoryEntry IUIAutomationProxyFactoryEntry;
|
||||
typedef interface IUIAutomationProxyFactoryMapping IUIAutomationProxyFactoryMapping;
|
||||
|
||||
typedef void *UIA_HWND;
|
||||
typedef int PROPERTYID;
|
||||
typedef int EVENTID;
|
||||
typedef int PATTERNID;
|
||||
typedef int CONTROLTYPEID;
|
||||
typedef int TEXTATTRIBUTEID;
|
||||
|
||||
enum TreeScope
|
||||
{
|
||||
TreeScope_Element = 0x1,
|
||||
TreeScope_Children = 0x2,
|
||||
TreeScope_Descendants = 0x4,
|
||||
TreeScope_Parent = 0x8,
|
||||
TreeScope_Ancestors = 0x10,
|
||||
TreeScope_Subtree = ( ( TreeScope_Element | TreeScope_Children ) | TreeScope_Descendants )
|
||||
};
|
||||
|
||||
enum PropertyConditionFlags
|
||||
{
|
||||
PropertyConditionFlags_None = 0,
|
||||
PropertyConditionFlags_IgnoreCase = 0x1
|
||||
};
|
||||
|
||||
enum OrientationType
|
||||
{
|
||||
OrientationType_None = 0,
|
||||
OrientationType_Horizontal = 1,
|
||||
OrientationType_Vertical = 2
|
||||
};
|
||||
|
||||
enum SupportedTextSelection
|
||||
{
|
||||
SupportedTextSelection_None = 0,
|
||||
SupportedTextSelection_Single = 1,
|
||||
SupportedTextSelection_Multiple = 2
|
||||
};
|
||||
|
||||
enum TextPatternRangeEndpoint
|
||||
{
|
||||
TextPatternRangeEndpoint_Start = 0,
|
||||
TextPatternRangeEndpoint_End = 1
|
||||
};
|
||||
|
||||
enum TextUnit
|
||||
{
|
||||
TextUnit_Character = 0,
|
||||
TextUnit_Format = 1,
|
||||
TextUnit_Word = 2,
|
||||
TextUnit_Line = 3,
|
||||
TextUnit_Paragraph = 4,
|
||||
TextUnit_Page = 5,
|
||||
TextUnit_Document = 6
|
||||
};
|
||||
|
||||
enum ProviderOptions
|
||||
{
|
||||
ProviderOptions_ClientSideProvider = 0x1,
|
||||
ProviderOptions_ServerSideProvider = 0x2,
|
||||
ProviderOptions_NonClientAreaProvider = 0x4,
|
||||
ProviderOptions_OverrideProvider = 0x8,
|
||||
ProviderOptions_ProviderOwnsSetFocus = 0x10,
|
||||
ProviderOptions_UseComThreading = 0x20
|
||||
} ;
|
||||
|
||||
/* UIA_PatternIds */
|
||||
const long UIA_InvokePatternId = 10000;
|
||||
const long UIA_SelectionPatternId = 10001;
|
||||
const long UIA_ValuePatternId = 10002;
|
||||
const long UIA_RangeValuePatternId = 10003;
|
||||
const long UIA_ScrollPatternId = 10004;
|
||||
const long UIA_ExpandCollapsePatternId = 10005;
|
||||
const long UIA_GridPatternId = 10006;
|
||||
const long UIA_GridItemPatternId = 10007;
|
||||
const long UIA_MultipleViewPatternId = 10008;
|
||||
const long UIA_WindowPatternId = 10009;
|
||||
const long UIA_SelectionItemPatternId = 10010;
|
||||
const long UIA_DockPatternId = 10011;
|
||||
const long UIA_TablePatternId = 10012;
|
||||
const long UIA_TableItemPatternId = 10013;
|
||||
const long UIA_TextPatternId = 10014;
|
||||
const long UIA_TogglePatternId = 10015;
|
||||
const long UIA_TransformPatternId = 10016;
|
||||
const long UIA_ScrollItemPatternId = 10017;
|
||||
const long UIA_LegacyIAccessiblePatternId = 10018;
|
||||
const long UIA_ItemContainerPatternId = 10019;
|
||||
const long UIA_VirtualizedItemPatternId = 10020;
|
||||
const long UIA_SynchronizedInputPatternId = 10021;
|
||||
|
||||
#define INTERFACE IUIAutomation
|
||||
DECLARE_INTERFACE_(IUIAutomation, IUnknown)
|
||||
{
|
||||
STDMETHOD(CompareElements)(THIS_ IUIAutomationElement *, IUIAutomationElement *, BOOL *) PURE;
|
||||
STDMETHOD(CompareRuntimeIds)(THIS_ SAFEARRAY *, SAFEARRAY *, BOOL *) PURE;
|
||||
STDMETHOD(GetRootElement)(THIS_ IUIAutomationElement **) PURE;
|
||||
STDMETHOD(ElementFromHandle)(THIS_ UIA_HWND, IUIAutomationElement **) PURE;
|
||||
STDMETHOD(ElementFromPoint)(THIS_ POINT, IUIAutomationElement **) PURE;
|
||||
STDMETHOD(GetFocusedElement)(THIS_ IUIAutomationElement **) PURE;
|
||||
STDMETHOD(GetRootElementBuildCache)(THIS_ IUIAutomationCacheRequest *, IUIAutomationElement **) PURE;
|
||||
STDMETHOD(ElementFromHandleBuildCache)(THIS_ UIA_HWND, IUIAutomationCacheRequest *, IUIAutomationElement **) PURE;
|
||||
STDMETHOD(ElementFromPointBuildCache)(THIS_ POINT, IUIAutomationCacheRequest *, IUIAutomationElement **) PURE;
|
||||
STDMETHOD(GetFocusedElementBuildCache)(THIS_ IUIAutomationCacheRequest *, IUIAutomationElement **) PURE;
|
||||
STDMETHOD(CreateTreeWalker)(THIS_ IUIAutomationCondition *, IUIAutomationTreeWalker **) PURE;
|
||||
STDMETHOD(get_ControlViewWalker)(THIS_ IUIAutomationTreeWalker **) PURE;
|
||||
STDMETHOD(get_ContentViewWalker)(THIS_ IUIAutomationTreeWalker **) PURE;
|
||||
STDMETHOD(get_RawViewWalker)(THIS_ IUIAutomationTreeWalker **) PURE;
|
||||
STDMETHOD(get_RawViewCondition)(THIS_ IUIAutomationCondition **) PURE;
|
||||
STDMETHOD(get_ControlViewCondition)(THIS_ IUIAutomationCondition **) PURE;
|
||||
STDMETHOD(get_ContentViewCondition)(THIS_ IUIAutomationCondition **) PURE;
|
||||
STDMETHOD(CreateCacheRequest)(THIS_ IUIAutomationCacheRequest **) PURE;
|
||||
STDMETHOD(CreateTrueCondition)(THIS_ IUIAutomationCondition **) PURE;
|
||||
STDMETHOD(CreateFalseCondition)(THIS_ IUIAutomationCondition **) PURE;
|
||||
STDMETHOD(CreatePropertyCondition)(THIS_ PROPERTYID, VARIANT, IUIAutomationCondition **) PURE;
|
||||
STDMETHOD(CreatePropertyConditionEx)(THIS_ PROPERTYID, VARIANT, enum PropertyConditionFlags, IUIAutomationCondition **) PURE;
|
||||
STDMETHOD(CreateAndCondition)(THIS_ IUIAutomationCondition *, IUIAutomationCondition *, IUIAutomationCondition **) PURE;
|
||||
STDMETHOD(CreateAndConditionFromArray)(THIS_ SAFEARRAY *, IUIAutomationCondition **) PURE;
|
||||
STDMETHOD(CreateAndConditionFromNativeArray)(THIS_ IUIAutomationCondition **, int , IUIAutomationCondition **) PURE;
|
||||
STDMETHOD(CreateOrCondition)(THIS_ IUIAutomationCondition *, IUIAutomationCondition *, IUIAutomationCondition **) PURE;
|
||||
STDMETHOD(CreateOrConditionFromArray)(THIS_ SAFEARRAY *, IUIAutomationCondition **) PURE;
|
||||
STDMETHOD(CreateOrConditionFromNativeArray)(THIS_ IUIAutomationCondition **, int , IUIAutomationCondition **) PURE;
|
||||
STDMETHOD(CreateNotCondition)(THIS_ IUIAutomationCondition *, IUIAutomationCondition **) PURE;
|
||||
STDMETHOD(AddAutomationEventHandler)(THIS_ EVENTID, IUIAutomationElement *, enum TreeScope, IUIAutomationCacheRequest *, IUIAutomationEventHandler *) PURE;
|
||||
STDMETHOD(RemoveAutomationEventHandler)(THIS_ EVENTID, IUIAutomationElement *, IUIAutomationEventHandler *) PURE;
|
||||
STDMETHOD(AddPropertyChangedEventHandlerNativeArray)(THIS_ IUIAutomationElement *, enum TreeScope, IUIAutomationCacheRequest *,
|
||||
IUIAutomationPropertyChangedEventHandler *, PROPERTYID *, int) PURE;
|
||||
STDMETHOD(AddPropertyChangedEventHandler)(THIS_ IUIAutomationElement *, enum TreeScope, EVENTID, IUIAutomationCacheRequest *,
|
||||
IUIAutomationPropertyChangedEventHandler *, SAFEARRAY *) PURE;
|
||||
STDMETHOD(RemovePropertyChangedEventHandler)(THIS_ IUIAutomationElement *, IUIAutomationPropertyChangedEventHandler *) PURE;
|
||||
STDMETHOD(AddStructureChangedEventHandler)(THIS_ IUIAutomationElement *, enum TreeScope, IUIAutomationCacheRequest *, IUIAutomationStructureChangedEventHandler *) PURE;
|
||||
STDMETHOD(RemoveStructureChangedEventHandler)(THIS_ IUIAutomationElement *, IUIAutomationStructureChangedEventHandler *) PURE;
|
||||
STDMETHOD(AddFocusChangedEventHandler)(THIS_ IUIAutomationCacheRequest *, IUIAutomationFocusChangedEventHandler *) PURE;
|
||||
STDMETHOD(RemoveFocusChangedEventHandler)(THIS_ IUIAutomationFocusChangedEventHandler *) PURE;
|
||||
STDMETHOD(RemoveAllEventHandlers)(THIS) PURE;
|
||||
STDMETHOD(IntNativeArrayToSafeArray)(THIS_ int *, int, SAFEARRAY **) PURE;
|
||||
STDMETHOD(IntSafeArrayToNativeArray)(THIS_ SAFEARRAY *, int **, int *) PURE;
|
||||
STDMETHOD(RectToVariant)(THIS_ RECT, VARIANT *) PURE;
|
||||
STDMETHOD(VariantToRect)(THIS_ VARIANT, RECT *) PURE;
|
||||
STDMETHOD(SafeArrayToRectNativeArray)(THIS_ SAFEARRAY *, RECT **, int *) PURE;
|
||||
STDMETHOD(CreateProxyFactoryEntry)(THIS_ IUIAutomationProxyFactory *, IUIAutomationProxyFactoryEntry **) PURE;
|
||||
STDMETHOD(get_ProxyFactoryMapping)(THIS_ IUIAutomationProxyFactoryMapping **) PURE;
|
||||
STDMETHOD(GetPropertyProgrammaticName)(THIS_ PROPERTYID, BSTR *) PURE;
|
||||
STDMETHOD(GetPatternProgrammaticName)(THIS_ PATTERNID, BSTR *) PURE;
|
||||
STDMETHOD(PollForPotentialSupportedPatterns)(THIS_ IUIAutomationElement *, SAFEARRAY **, SAFEARRAY **) PURE;
|
||||
STDMETHOD(PollForPotentialSupportedProperties)(THIS_ IUIAutomationElement *, SAFEARRAY **, SAFEARRAY **) PURE;
|
||||
STDMETHOD(CheckNotSupported)(THIS_ VARIANT, BOOL *) PURE;
|
||||
STDMETHOD(get_ReservedNotSupportedValue)(THIS_ IUnknown **) PURE;
|
||||
STDMETHOD(get_ReservedMixedAttributeValue)(THIS_ IUnknown **) PURE;
|
||||
STDMETHOD(ElementFromIAccessible)(THIS_ IAccessible *, int, IUIAutomationElement **) PURE;
|
||||
STDMETHOD(ElementFromIAccessibleBuildCache)(THIS_ IAccessible *, int, IUIAutomationCacheRequest *, IUIAutomationElement **) PURE;
|
||||
};
|
||||
#undef INTERFACE
|
||||
|
||||
#define INTERFACE IUIAutomationElement
|
||||
DECLARE_INTERFACE_(IUIAutomationElement, IUnknown)
|
||||
{
|
||||
STDMETHOD(SetFocus)(THIS) PURE;
|
||||
STDMETHOD(GetRuntimeId)(THIS_ SAFEARRAY **) PURE;
|
||||
STDMETHOD(FindFirst)(THIS_ enum TreeScope, IUIAutomationCondition *, IUIAutomationElement **) PURE;
|
||||
STDMETHOD(FindAll)(THIS_ enum TreeScope, IUIAutomationCondition *, IUIAutomationElementArray **) PURE;
|
||||
STDMETHOD(FindFirstBuildCache)(THIS_ enum TreeScope, IUIAutomationCondition *, IUIAutomationCacheRequest *, IUIAutomationElement **) PURE;
|
||||
STDMETHOD(FindAllBuildCache)(THIS_ enum TreeScope, IUIAutomationCondition *, IUIAutomationCacheRequest *, IUIAutomationElementArray **) PURE;
|
||||
STDMETHOD(BuildUpdatedCache)(THIS_ IUIAutomationCacheRequest *, IUIAutomationElement **) PURE;
|
||||
STDMETHOD(GetCurrentPropertyValue)(THIS_ PROPERTYID, VARIANT *) PURE;
|
||||
STDMETHOD(GetCurrentPropertyValueEx)(THIS_ PROPERTYID, BOOL, VARIANT *) PURE;
|
||||
STDMETHOD(GetCachedPropertyValue)(THIS_ PROPERTYID, VARIANT *) PURE;
|
||||
STDMETHOD(GetCachedPropertyValueEx)(THIS_ PROPERTYID, BOOL, VARIANT *) PURE;
|
||||
STDMETHOD(GetCurrentPatternAs)(THIS_ PATTERNID, REFIID, void **) PURE;
|
||||
STDMETHOD(GetCachedPatternAs)(THIS_ PATTERNID, REFIID, void **) PURE;
|
||||
STDMETHOD(GetCurrentPattern)(THIS_ PATTERNID, IUnknown **) PURE;
|
||||
STDMETHOD(GetCachedPattern)(THIS_ PATTERNID, IUnknown **) PURE;
|
||||
STDMETHOD(GetCachedParent)(THIS_ IUIAutomationElement **) PURE;
|
||||
STDMETHOD(GetCachedChildren)(THIS_ IUIAutomationElement **) PURE;
|
||||
STDMETHOD(get_CurrentProcessId)(THIS_ int *) PURE;
|
||||
STDMETHOD(get_CurrentControlType)(THIS_ CONTROLTYPEID *) PURE;
|
||||
STDMETHOD(get_CurrentLocalizedControlType)(THIS_ BSTR *) PURE;
|
||||
STDMETHOD(get_CurrentName)(THIS_ BSTR *) PURE;
|
||||
STDMETHOD(get_CurrentAcceleratorKey)(THIS_ BSTR *) PURE;
|
||||
STDMETHOD(get_CurrentAccessKey)(THIS_ BSTR *) PURE;
|
||||
STDMETHOD(get_CurrentHasKeyboardFocus)(THIS_ BOOL *) PURE;
|
||||
STDMETHOD(get_CurrentIsKeyboardFocusable)(THIS_ BOOL *) PURE;
|
||||
STDMETHOD(get_CurrentIsEnabled)(THIS_ BOOL *) PURE;
|
||||
STDMETHOD(get_CurrentAutomationId)(THIS_ BSTR *) PURE;
|
||||
STDMETHOD(get_CurrentClassName)(THIS_ BSTR *) PURE;
|
||||
STDMETHOD(get_CurrentHelpText)(THIS_ BSTR *) PURE;
|
||||
STDMETHOD(get_CurrentCulture)(THIS_ int *) PURE;
|
||||
STDMETHOD(get_CurrentIsControlElement)(THIS_ BOOL *) PURE;
|
||||
STDMETHOD(get_CurrentIsContentElement)(THIS_ BOOL *) PURE;
|
||||
STDMETHOD(get_CurrentIsPassword)(THIS_ BOOL *) PURE;
|
||||
STDMETHOD(get_CurrentNativeWindowHandle)(THIS_ UIA_HWND *) PURE;
|
||||
STDMETHOD(get_CurrentItemType)(THIS_ BSTR *) PURE;
|
||||
STDMETHOD(get_CurrentIsOffscreen)(THIS_ BOOL *) PURE;
|
||||
STDMETHOD(get_CurrentOrientation)(THIS_ enum OrientationType *) PURE;
|
||||
STDMETHOD(get_CurrentFrameworkId)(THIS_ BSTR *) PURE;
|
||||
STDMETHOD(get_CurrentIsRequiredForForm)(THIS_ BOOL *) PURE;
|
||||
STDMETHOD(get_CurrentItemStatus)(THIS_ BSTR *) PURE;
|
||||
STDMETHOD(get_CurrentBoundingRectangle)(THIS_ RECT *) PURE;
|
||||
STDMETHOD(get_CurrentLabeledBy)(THIS_ IUIAutomationElement **) PURE;
|
||||
STDMETHOD(get_CurrentAriaRole)(THIS_ BSTR *) PURE;
|
||||
STDMETHOD(get_CurrentAriaProperties)(THIS_ BSTR *) PURE;
|
||||
STDMETHOD(get_CurrentIsDataValidForForm)(THIS_ BOOL *) PURE;
|
||||
STDMETHOD(get_CurrentControllerFor)(THIS_ IUIAutomationElementArray **) PURE;
|
||||
STDMETHOD(get_CurrentDescribedBy)(THIS_ IUIAutomationElementArray **) PURE;
|
||||
STDMETHOD(get_CurrentFlowsTo)(THIS_ IUIAutomationElementArray **) PURE;
|
||||
STDMETHOD(get_CurrentProviderDescription)(THIS_ BSTR *) PURE;
|
||||
STDMETHOD(get_CachedProcessId)(THIS_ int *) PURE;
|
||||
STDMETHOD(get_CachedControlType)(THIS_ CONTROLTYPEID *) PURE;
|
||||
STDMETHOD(get_CachedLocalizedControlType)(THIS_ BSTR *) PURE;
|
||||
STDMETHOD(get_CachedName)(THIS_ BSTR *) PURE;
|
||||
STDMETHOD(get_CachedAcceleratorKey)(THIS_ BSTR *) PURE;
|
||||
STDMETHOD(get_CachedAccessKey)(THIS_ BSTR *) PURE;
|
||||
STDMETHOD(get_CachedHasKeyboardFocus)(THIS_ BOOL *) PURE;
|
||||
STDMETHOD(get_CachedIsKeyboardFocusable)(THIS_ BOOL *) PURE;
|
||||
STDMETHOD(get_CachedIsEnabled)(THIS_ BOOL *) PURE;
|
||||
STDMETHOD(get_CachedAutomationId)(THIS_ BSTR *) PURE;
|
||||
STDMETHOD(get_CachedClassName)(THIS_ BSTR *) PURE;
|
||||
STDMETHOD(get_CachedHelpText)(THIS_ BSTR *) PURE;
|
||||
STDMETHOD(get_CachedCulture)(THIS_ int *) PURE;
|
||||
STDMETHOD(get_CachedIsControlElement)(THIS_ BOOL *) PURE;
|
||||
STDMETHOD(get_CachedIsContentElement)(THIS_ BOOL *) PURE;
|
||||
STDMETHOD(get_CachedIsPassword)(THIS_ BOOL *) PURE;
|
||||
STDMETHOD(get_CachedNativeWindowHandle)(THIS_ UIA_HWND *) PURE;
|
||||
STDMETHOD(get_CachedItemType)(THIS_ BSTR *) PURE;
|
||||
STDMETHOD(get_CachedIsOffscreen)(THIS_ BOOL *) PURE;
|
||||
STDMETHOD(get_CachedOrientation)(THIS_ enum OrientationType *) PURE;
|
||||
STDMETHOD(get_CachedFrameworkId)(THIS_ BSTR *) PURE;
|
||||
STDMETHOD(get_CachedIsRequiredForForm)(THIS_ BOOL *) PURE;
|
||||
STDMETHOD(get_CachedItemStatus)(THIS_ BSTR *) PURE;
|
||||
STDMETHOD(get_CachedBoundingRectangle)(THIS_ RECT *) PURE;
|
||||
STDMETHOD(get_CachedLabeledBy)(THIS_ IUIAutomationElement **) PURE;
|
||||
STDMETHOD(get_CachedAriaRole)(THIS_ BSTR *) PURE;
|
||||
STDMETHOD(get_CachedAriaProperties)(THIS_ BSTR *) PURE;
|
||||
STDMETHOD(get_CachedIsDataValidForForm)(THIS_ BOOL *) PURE;
|
||||
STDMETHOD(get_CachedControllerFor)(THIS_ IUIAutomationElementArray **) PURE;
|
||||
STDMETHOD(get_CachedDescribedBy)(THIS_ IUIAutomationElementArray **) PURE;
|
||||
STDMETHOD(get_CachedFlowsTo)(THIS_ IUIAutomationElementArray **) PURE;
|
||||
STDMETHOD(get_CachedProviderDescription)(THIS_ BSTR *) PURE;
|
||||
};
|
||||
#undef INTERFACE
|
||||
|
||||
#define INTERFACE IUIAutomationTextPattern
|
||||
DECLARE_INTERFACE_(IUIAutomationTextPattern, IUnknown)
|
||||
{
|
||||
STDMETHOD(RangeFromPoint)(THIS_ POINT, IUIAutomationTextRange **) PURE;
|
||||
STDMETHOD(RangeFromChild)(THIS_ IUIAutomationElement *, IUIAutomationTextRange **) PURE;
|
||||
STDMETHOD(GetSelection)(THIS_ IUIAutomationTextRangeArray **) PURE;
|
||||
STDMETHOD(GetVisibleRanges)(THIS_ IUIAutomationTextRangeArray **) PURE;
|
||||
STDMETHOD(get_DocumentRange)(THIS_ IUIAutomationTextRange **) PURE;
|
||||
STDMETHOD(get_SupportedTextSelection)(THIS_ enum SupportedTextSelection *) PURE;
|
||||
};
|
||||
#undef INTERFACE
|
||||
|
||||
#define INTERFACE IUIAutomationTreeWalker
|
||||
DECLARE_INTERFACE_(IUIAutomationTreeWalker, IUnknown)
|
||||
{
|
||||
STDMETHOD(GetParentElement)(THIS_ IUIAutomationElement *, IUIAutomationElement **) PURE;
|
||||
STDMETHOD(GetFirstChildElement)(THIS_ IUIAutomationElement *, IUIAutomationElement **) PURE;
|
||||
STDMETHOD(GetLastChildElement)(THIS_ IUIAutomationElement *, IUIAutomationElement **) PURE;
|
||||
STDMETHOD(GetNextSiblingElement)(THIS_ IUIAutomationElement *, IUIAutomationElement **) PURE;
|
||||
STDMETHOD(GetPreviousSiblingElement)(THIS_ IUIAutomationElement *, IUIAutomationElement **) PURE;
|
||||
STDMETHOD(NormalizeElement)(THIS_ IUIAutomationElement *, IUIAutomationElement **) PURE;
|
||||
STDMETHOD(GetParentElementBuildCache)(THIS_ IUIAutomationElement *, IUIAutomationCacheRequest *, IUIAutomationElement **) PURE;
|
||||
STDMETHOD(GetFirstChildElementBuildCache)(THIS_ IUIAutomationElement *, IUIAutomationCacheRequest *, IUIAutomationElement **) PURE;
|
||||
STDMETHOD(GetLastChildElementBuildCache)(THIS_ IUIAutomationElement *, IUIAutomationCacheRequest *, IUIAutomationElement **) PURE;
|
||||
STDMETHOD(GetNextSiblingElementBuildCache)(THIS_ IUIAutomationElement *, IUIAutomationCacheRequest *, IUIAutomationElement **) PURE;
|
||||
STDMETHOD(GetPreviousSiblingElementBuildCache)(THIS_ IUIAutomationElement *, IUIAutomationCacheRequest *, IUIAutomationElement **) PURE;
|
||||
STDMETHOD(NormalizeElementBuildCache)(THIS_ IUIAutomationElement *, IUIAutomationCacheRequest *, IUIAutomationElement **) PURE;
|
||||
STDMETHOD(get_Condition)(THIS_ IUIAutomationCondition **) PURE;
|
||||
};
|
||||
#undef INTERFACE
|
||||
|
||||
#define INTERFACE IUIAutomationTextRange
|
||||
DECLARE_INTERFACE_(IUIAutomationTextRange, IUnknown)
|
||||
{
|
||||
STDMETHOD(Clone)(THIS_ IUIAutomationTextRange **) PURE;
|
||||
STDMETHOD(Compare)(THIS_ IUIAutomationTextRange *, BOOL *) PURE;
|
||||
STDMETHOD(CompareEndpoints)(THIS_ enum TextPatternRangeEndpoint, IUIAutomationTextRange *, enum TextPatternRangeEndpoint, int *) PURE;
|
||||
STDMETHOD(ExpandToEnclosingUnit)(THIS_ enum TextUnit) PURE;
|
||||
STDMETHOD(FindAttribute)(THIS_ TEXTATTRIBUTEID, VARIANT, BOOL, IUIAutomationTextRange **) PURE;
|
||||
STDMETHOD(FindText)(THIS_ BSTR, BOOL, BOOL, IUIAutomationTextRange **) PURE;
|
||||
STDMETHOD(GetAttributeValue)(THIS_ TEXTATTRIBUTEID, VARIANT *) PURE;
|
||||
STDMETHOD(GetBoundingRectangles)(THIS_ SAFEARRAY **) PURE;
|
||||
STDMETHOD(GetEnclosingElement)(THIS_ IUIAutomationElement **) PURE;
|
||||
STDMETHOD(GetText)(THIS_ int, BSTR *) PURE;
|
||||
STDMETHOD(Move)(THIS_ enum TextUnit, int, int *) PURE;
|
||||
STDMETHOD(MoveEndpointByUnit)(THIS_ enum TextPatternRangeEndpoint, enum TextUnit, int *) PURE;
|
||||
STDMETHOD(MoveEndpointByRange)(THIS_ enum TextPatternRangeEndpoint, IUIAutomationTextRange *, enum TextPatternRangeEndpoint) PURE;
|
||||
STDMETHOD(Select)(THIS) PURE;
|
||||
STDMETHOD(AddToSelection)(THIS) PURE;
|
||||
STDMETHOD(RemoveFromSelection)(THIS) PURE;
|
||||
STDMETHOD(ScrollIntoView)(THIS_ BOOL) PURE;
|
||||
STDMETHOD(GetChildren)(THIS_ IUIAutomationElementArray **) PURE;
|
||||
};
|
||||
#undef INTERFACE
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // UIAUTO_HH
|
114
wordbyauto.cc
Normal file
114
wordbyauto.cc
Normal file
|
@ -0,0 +1,114 @@
|
|||
#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;
|
||||
}
|
6
wordbyauto.hh
Normal file
6
wordbyauto.hh
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef __WORD_BY_AUTO_HH_INCLUDED
|
||||
#define __WORD_BY_AUTO_HH_INCLUDED
|
||||
|
||||
WCHAR *gdGetWordAtPointByAutomation( POINT pt );
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue