Здравствуйте, Cannol, Вы писали:
C>Я не очень с WinAPI, прошу уточнить: C>1. WM_MOUSEDOWN не нашёл в хидерах/документации, видимо, можно использовать WM_LBUTTONDOWN/WM_LBUTTONUP вместо этого?
Конечно же... сорри.
C>Т.е., после вызова SetCursorPos() я всё равно пробовал отправлять сообщения о нажатии вместе с координатами клика (pt.x, pt.y). C>Так всё равно не работает. Или может, у меня тут где-то ошибка? Или по отдельности надо отправлять сообщение (отдельно перемещение и отдельно клик)?
"Нормальным" приложениям было бы достаточно посылки сообщений мыши и/или клавиатуры. Так на вид мне лично больше ничего в глаза не бросилось. Тем более ваш же код вполне успешно кликает на системное меню.
Поэтому... не знаю, медитация с spyxx, смотрите какие он сообщения получает, с какими координатами ну и вообще что там происходит.
Я так понял, что код вполне нормально кликает на браузер, когда он в видимой области экрана? Соответственно, опять приходим к мыслям о координатах / каком-то их клиппинге. Вопрос тока где он происходит и можно ли с этим что-то сделать.
WM_LBUTTONDOWN работает с клиентскими координатами, а у вас там nRelX (pt.X) и я не особо понял, что там к чему. Возможно стоит тоже обратить внимание. Не везде и не во всех сообщениях отсчет координат одинаковый!
PS: Да и ClipCursor используется. Правильно/достаточно ли я не знаю.
Здравствуйте, Carc, Вы писали: C>Можно юзать SendInput — обычно работает.
Да, его и использую больше всего.
Я писал: C>Т.е., после вызова SetCursorPos() я всё равно пробовал отправлять сообщения о нажатии вместе с координатами клика (pt.x, pt.y). C>Так всё равно не работает.
Уже более понятно с сообщением о координатах, сейчас без всякого SetCursorPos() управляюсь. Когда окно физически видно — всё отлично. Но снова, как только окно делается скрытым или выводится за пределы рабочего стола — ввод не ловится в том окне. Увы:
...
else if (byCodeOption == 1)
{
#define ABSOLUTE_XY_MAX 65535
INPUT input={0};
// left movementint screenX = GetSystemMetrics(SM_CXSCREEN);
int screenY = GetSystemMetrics(SM_CYSCREEN);
input.type = INPUT_MOUSE;
input.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE; // mouse movement
input.mi.dx = pt.x * (ABSOLUTE_XY_MAX / screenX); input.mi.dy = pt.y * (ABSOLUTE_XY_MAX / screenY);
SendInput(1, &input, sizeof(INPUT));
Sleep(1);
// left down
ZeroMemory(&input,sizeof(INPUT)); //clear out input
input.type = INPUT_MOUSE;
input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN; // mouse button down
SendInput(1,&input,sizeof(INPUT));
Sleep(1);
// left up
ZeroMemory(&input,sizeof(INPUT)); //clear out input
input.type = INPUT_MOUSE;
input.mi.dwFlags = MOUSEEVENTF_LEFTUP; // mouse button up
SendInput(1,&input,sizeof(INPUT));
}
Здравствуйте, Cannol, Вы писали:
C>Здравствуйте, Carc, Вы писали: C>>Можно юзать SendInput — обычно работает. C>Да, его и использую больше всего.
C>Я писал: C>>Т.е., после вызова SetCursorPos() я всё равно пробовал отправлять сообщения о нажатии вместе с координатами клика (pt.x, pt.y). C>>Так всё равно не работает.
C>Уже более понятно с сообщением о координатах, сейчас без всякого SetCursorPos() управляюсь. Когда окно физически видно — всё отлично. Но снова, как только окно делается скрытым или выводится за пределы рабочего стола — ввод не ловится в том окне. Увы: C>
C>...
C>else if (byCodeOption == 1)
C>{
C> #define ABSOLUTE_XY_MAX 65535
C> INPUT input={0};
C> // left movement
C> int screenX = GetSystemMetrics(SM_CXSCREEN);
C> int screenY = GetSystemMetrics(SM_CYSCREEN);
C> input.type = INPUT_MOUSE;
C> input.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE; // mouse movement
C> input.mi.dx = pt.x * (ABSOLUTE_XY_MAX / screenX); input.mi.dy = pt.y * (ABSOLUTE_XY_MAX / screenY);
чего то мне не нравится выше флаги
If MOUSEEVENTF_ABSOLUTE value is specified, dx and dy contain normalized absolute coordinates between 0 and 65,535. The event procedure maps these coordinates onto the display surface. Coordinate (0,0) maps onto the upper-left corner of the display surface; coordinate (65535,65535) maps onto the lower-right corner. In a multimonitor system, the coordinates map to the primary monitor.
Чего та вычисления неясные?
// А вот тут что не нужно что ли координаты указывать?
C>Не судьба, видимо, с IE подружиться.
Думаю, надо прощее быть…
Выносить функцию сенд-инпученья в отдельный модуль, и гонять ее тестами и смотреть что к чему.
Сдается мне всё должно работать, только нужно четко и аккуратно с параметрами и ремарками из МСДЫНъ.
А то там вон много чего про флаги в MSDN сказано, что координаты могут относиться только к основному монитору и все такое.
Плюс. Ну безусловно, коды возврата WinAPI функций надо проверять, в нашем случае SendInput. Ну заобязательно просто. Они много чего могут сказать, может что-то просто не отрабатывает и все тут.
И PS: как уже писал выше, такой SendInput ловится на раз LowLevel-хуком (там флаги это показывают), и соответственно нечто сбоку работающее может запросто фильтровать такой искуственный ввод, и просто его не пропускать. В частности и сам Internet Explorer.
Ну это уже из разряда страшилок, но все же…
Здравствуйте, Carc, Вы писали: C>чего то мне не нравится выше флаги C>
C>If MOUSEEVENTF_ABSOLUTE value is specified, dx and dy contain normalized absolute coordinates between 0 and 65,535. The event procedure maps these coordinates onto the display surface. Coordinate (0,0) maps onto the upper-left corner of the display surface; coordinate (65535,65535) maps onto the lower-right corner. In a multimonitor system, the coordinates map to the primary monitor.
Ну да. Если неабсолютные координаты, тогда надо привязываться к предыдущей позиции мыши. Зачем это надо.
C>Чего та вычисления неясные?
Там я перевожу координаты клика внутри того скрытого окна (pt.x, pt.y) в координаты клика внутри рабочего стола (input.mi.dx, input.mi.dy). Те, что внутри окна — вот они:
const int nSizeX = rcClip.right - rcClip.left;
const int nSizeY = rcClip.bottom - rcClip.top;
// Calculate the click coordinates for the target window.
pt.x = Round(((double) relative_point->x / m_wGaugeWidth) * nSizeX) + rcClip.left;
pt.y = Round(((double) relative_point->y / m_wGaugeHeight) * nSizeY) + rcClip.top;
C>// А вот тут что не нужно что ли координаты указывать? C>
Вероятно, по крайней мере необязательно. По крайней мере этот код с тремя этими SendInput() работает нормально, когда окно видимо.
C>>Не судьба, видимо, с IE подружиться. C>Думаю, надо прощее быть… C>Выносить функцию сенд-инпученья в отдельный модуль, и гонять ее тестами и смотреть что к чему. C>Сдается мне всё должно работать, только нужно четко и аккуратно с параметрами и ремарками из МСДЫНъ. C>А то там вон много чего про флаги в MSDN сказано, что координаты могут относиться только к основному монитору и все такое. C>Плюс. Ну безусловно, коды возврата WinAPI функций надо проверять, в нашем случае SendInput. Ну заобязательно просто. Они много чего могут сказать, может что-то просто не отрабатывает и все тут.
Спасибо! Эти советы буду иметь в виду, но пока я смещаюсь в сторону Sciter. Слишком много времени потратил, и с учётом того, что при таком подходе "может запросто фильтровать такой искуственный ввод", и так далее.
Здравствуйте, Cannol, Вы писали:
C>Вероятно, по крайней мере необязательно. По крайней мере этот код с тремя этими SendInput() работает нормально, когда окно видимо.
Ну дык попробовать варианты,
1) Сделать окно в пределах рабочего стола, и попробовать с SendInput, что будет если окно видимо, и что будет если невидимо…
2) Второй вариант: оставлять окно с Internet Explorer видимым (убрав с панели задач), но задвинуть его за края экрана. И опять попробовать с SendInut.
Ну и посмотреть в каком варианте работает, а в каком нет.
C>Спасибо! Эти советы буду иметь в виду, но пока я смещаюсь в сторону Sciter. Слишком много времени потратил, и с учётом того, что при таком подходе "может запросто фильтровать такой искуственный ввод", и так далее.
Именно со Sciter у меня опыта раз-два и обчелся. Но поработал с HTMLayout (по сути библиотека предшественник Sciter), там немало нюансов. Но попробовать точно стоит. Там хотя бы менее "черный ящик". Посмотреть что да как реагирует проще. Ну и автор Sciter — s-smile — тут же на RSDN и пристутствует.
Ребята, вопрос насчёт Sciter:
я вот скачал, почитал доки и посмотрел примеры, но не совсем пока понял — внутренне там какой браузер? Chrome, IE, или какой-то свой собственный?
В примерах вижу одни JavaScriptы и прочее такое, а чистый HTML будет ли поддерживать, не совсем понятно.
Здравствуйте, Cannol, Вы писали:
C>Ребята, вопрос насчёт Sciter: C>я вот скачал, почитал доки и посмотрел примеры, но не совсем пока понял — внутренне там какой браузер? Chrome, IE, или какой-то свой собственный? C>В примерах вижу одни JavaScriptы и прочее такое, а чистый HTML будет ли поддерживать, не совсем понятно.
Да, будет поддерживать и чистый HTML — вполне себе распрекрасно…
Здравствуйте, Cannol, Вы писали:
C>Ребята, вопрос насчёт Sciter: C>я вот скачал, почитал доки и посмотрел примеры, но не совсем пока понял — внутренне там какой браузер? Chrome, IE, или какой-то свой собственный?
Насколько я знаю, свой собственный. Но это лучше узнать и c-smile.
Итак, sciter технически как раз подходит.
Но увы, руководство решило, что не готово выделить средства для ENTERPRISE лицензии. (Вроде как мы не можем пользоваться более дешёвой лицензией — у нас более 20 человек.)
Еще мне посоветовали LibRocket. Но я пришёл к выводу, что это скорее для GUI нужно. Мне полноценного HTML браузера и не надо, но тут используется RML (лишь похожий на HTML), и похоже, что только локально.
Т.е. вызовы только вида "LoadDocument("../../assets/demo.rml");", а не "http://***".
Пробовал взять разные HTML файлы и тупо переименовать в RML и подсунуть, но таки не отображает. Встроенный Logger ругается много на что.
Ссылки на удалённые ресурсы тоже конвертит во что-то локальное.
Другие библиотеки никто не подскажет? Пока копаю в сторону Chromium и Webkit.