Добро пожаловать к нам в гости! Наш сайт посвящён программе NeoBook, с помощью которой вы легко сможете создавать собственные мультимедиа-приложения без необходимости изучать сложные языки программирования! Зарегистрируйтесь, чтобы стать членом нашего сообщества.
Однако функция GetCursorPos() показывает не верное разрешение.
У меня одно и то же показывает, что GetCursorPos, что из структуры MSLLHOOKSTRUCT. Сейчас специально запустил оба, одинаково показывают. +\- 1\2 пикселя.
Цитатаfrolandr ()
У меня установлен масштаб 125%, вот если разделить 1680/1344 или 1050/840, то и получаем коэффициент 1,25, что соответствует 125%.
Нашел такой вариант:
GetDeviceCaps(GetDC(0),LOGPIXELSX) или GetDeviceCaps(GetDC(0),LOGPIXELSY)
Число пикселей на логический дюйм... Без разницы какую использовать. При коэфициенте 1 = 96. 1,25 = 120. 1, 5 =144 и т.д. Т.е. я так понимаю, выдернуть и разделить на 96, вот и будет нужный коэфициент.
Цитатаfrolandr ()
Если бы я не далал скриншоты с помощью всевозможных плагинов, и затем сам не полез, я бы так и не знал этого.
Так то да. Я до нашего разговора вообще об этом не задумывлся. Если честно я вообще не понимаю для чего это сделано. Маленькое разрешение, как я понимаю, поддерживают любые мониторы. Что мешает уменьшить разрешение?
По факту происходит именно уменьшение разрешения, только с обратной стороны. Разрешение вроде как оставляют, но все объекты, шрифты увеличивают. И? вше разрешение = больше панорама. Больше, а соответственно ближе объекты = меньше панорама. В чем выгодали? Теперь решают проблему, как внедрить в приложения автоматическое изменение размеров объектов приложений.
Цитатаfrolandr ()
Попробуй теперь скриншот плагином ksFunctions сделать.
Даже если предположить, что разрешение осталось прежним (а если мышкой из угла в угол провести, то в это как бы и верится, но объекты (окна, кнопки и т.д.) пропорционально увеличились и приблизились, то естественно, если делать снимок по "старым" координатам, снимок захватит меньшую часть. Это как ты снимаешь, а к твоей камере подходят. Рарешение прежнее, размер человека прежний, но он просто приблизился и за счет этого увеличился. Если ты сначала мог его снять в полный рост, то в итоге в камеру уместится только глаз, или ноздря.
Цитатаfrolandr ()
К счастью нашел функцию, которая получает правильное разрешение.
Не та что выше дал? Другого я не нашел. Да и про эту методом тыка понял.
Добавлено (12 Июля 2023, 19:08) --------------------------------------------- Кстати если смотреть на это со стороны камеры, как описал выше, то если с камерой реальное пропорциональное приближение идет, то здесь идет увеличение не пропорционально, так как вмещается все в то же самое разрешение. Это как ты человека снял, приблизил, и после снимок уменьшил, что бы он впмсвося в экран. А соответственно пришлось бы и разрешение фото уменьшить, иначе не впишется. Вот и получается. что разрешение экрана вроде бы как прежнее, а разрешение картинки уменьшается.
У меня одно и то же показывает, что GetCursorPos, что из структуры MSLLHOOKSTRUCT. Сейчас специально запустил оба, одинаково показывают. +\- 1\2 пикселя.
А масштаб у тебя отличный от 100%? Если 100 %, то результаты будут идентичны.
Добавлено (12 Июля 2023, 21:27) ---------------------------------------------
Цитатаmishem ()
Нашел такой вариант:
GetDeviceCaps(GetDC(0),LOGPIXELSX) или GetDeviceCaps(GetDC(0),LOGPIXELSY)
Число пикселей на логический дюйм... Без разницы какую использовать. При коэфициенте 1 = 96. 1,25 = 120. 1, 5 =144 и т.д. Т.е. я так понимаю, выдернуть и разделить на 96, вот и будет нужный коэфициент.
Верно БЫ, но вот у меня этот и подобные показывают 96 всегда, при любом масштабе. Не знаю почему.
Добавлено (12 Июля 2023, 21:31) --------------------------------------------- Было свободное время, накидал локальный хук мыши. Хотел было его добавить к плагину, но опять эта разница с координатами, а если вычислять, то снова подтормаживать будет.
Добавлено (12 Июля 2023, 21:37) ---------------------------------------------
Цитатаmishem ()
Так то да. Я до нашего разговора вообще об этом не задумывлся. Если честно я вообще не понимаю для чего это сделано. Маленькое разрешение, как я понимаю, поддерживают любые мониторы. Что мешает уменьшить разрешение?
Вот и я не знал, в 13-14 году когда писал, не было у меня винды 8,1 и не знал об этом. Не давно нужно было сделать скриншот окна программы, где был Грид2 Андрея. Вадим подсказал плагин ksFunctions. Делаю им скрин, у меня пол окна, несколько часов промучался, так и не понял. Координаты из НЕО брал тоже самое. Когда писал свой плагин, думал тот старый, а уменя получится, тоже столкнулся с этой проблемой. Что только не перепробовал, в том числе и что ты привел результат нулевой. Вот кое-как откопал недокументированную функцию, вернее параметр функции. Только тогда получил верные координаты.
Добавлено (12 Июля 2023, 21:40) ---------------------------------------------
Цитатаmishem ()
По факту происходит именно уменьшение разрешения, только с обратной стороны. Разрешение вроде как оставляют, но все объекты, шрифты увеличивают. И? вше разрешение = больше панорама. Больше, а соответственно ближе объекты = меньше панорама. В чем выгодали? Теперь решают проблему, как внедрить в приложения автоматическое изменение размеров объектов приложений.
Да, там полная фигня. Вроде при увеличении масштаба правильные координаты 1344 у меня, но если что-то делать програмно, то они как бы 1680, все это очень запутывает!
Добавлено (12 Июля 2023, 21:41) ---------------------------------------------
Цитатаmishem ()
Не та что выше дал? Другого я не нашел. Да и про эту методом тыка понял.
Нет, она у меня тоже не работает, все время 96 пикселей. Я вот чем пользуюсь:
Код
W = GetDeviceCaps(hdc, DESKTOPHORZRES); //дает фактическую ширину дисплея с эффектом DPI True (масштабирования) H = GetDeviceCaps(hdc, DESKTOPVERTRES); //дает фактическую высоту дисплея с эффектом DPI True (масштабирования)
Добавлено (12 Июля 2023, 21:48) ---------------------------------------------
Цитатаmishem ()
Кстати если смотреть на это со стороны камеры, как описал выше, то если с камерой реальное пропорциональное приближение идет, то здесь идет увеличение не пропорционально, так как вмещается все в то же самое разрешение. Это как ты человека снял, приблизил, и после снимок уменьшил, что бы он впмсвося в экран. А соответственно пришлось бы и разрешение фото уменьшить, иначе не впишется. Вот и получается. что разрешение экрана вроде бы как прежнее, а разрешение картинки уменьшается.
Может ошибка какая у них? У меня просто зрение ухудшилось к 50 годам. компы виной вот я и увеличил масштаб до 125. Однако думаю при увеличении масштаба должны были увеличиться размеры иконок, ярлыков, шрифта, а на деле получается намудрили и с разрешением экрана, он как бы и остался прежний 1680, потому что и картинка десктопа таже и вот програмно получаю 1680, а она как бы и 1344. Заморочка короче.
Сообщение отредактировано frolandr - Ср, 12 Июля 2023, 21:30
А ты вычисляй за пределами хука. Т.е. в хуке только определяй что именно нужно выполнить, а выполнения производи уже когда вышел из хука. Т.е. передаешь параметры в глобальные переменные, а уже когда вышел за пределы хука из подпрограммы выполняешь все намеченные действия. Это у меня теория, хочу сам попробовать все вынести за пределы хука, но пока некогда. Тормознулся.
Добавлено (13 Июля 2023, 19:51) --------------------------------------------- И почему у тебя получение цвета под курсором должно тормозить, тоже не понятно. У меня такой код
Код
//Цвет пикселя DC := GetWindowDC(GetDesktopWindow); ColorValue := GetPixel(DC,MausPos.x,MausPos.y);
//Цвет в RGB Красный цвет Зеленый цвет Синий цвет Form1.Label6.Caption := IntToStr(GetRValue(ColorValue)) +','+ IntToStr(GetGValue(ColorValue)) +','+ IntToStr(GetBValue(ColorValue)); ReleaseDC( 0, DC );
Хотя это тоже все нужно выносить за монитор. И да, я не использую mesage, хотя может быть это не правильно. Не хочешь читать хелп?
А ты считаешь, что если код вынести в функцию, то тормозов не будет? Функцию же тоже запускать нужно, она работает, это время, она запускает подпрограмму с нео, это тоже время.
Я вообще в функции обработчике кнопок только флаги ставил. т.е. нажата левая кнопка, ставлю флаг, а при установке хука запускаю таймер, функция запущенная таймером проверяет есть ли флаг, есть обрабатыват код, нет дальше караулит.
Какая разница, выполнение кода идет же по цепочке. Вот если бы были асинхронный функции, запустил ее и она отработает как бы параллельно, хотя в js так не говорят. В с++ запускаются дополнительные потоки, но он не работает в нео.
Добавлено (13 Июля 2023, 20:03) ---------------------------------------------
Цитатаmishem ()
//Цвет пикселя DC := GetWindowDC(GetDesktopWindow); ColorValue := GetPixel(DC,MausPos.x,MausPos.y);
//Цвет в RGB Красный цвет Зеленый цвет Синий цвет Form1.Label6.Caption := IntToStr(GetRValue(ColorValue)) +','+ IntToStr(GetGValue(ColorValue)) +','+ IntToStr(GetBValue(ColorValue)); ReleaseDC( 0, DC );
Ну да, код такой:
Код
HWND hwnd = GetDesktopWindow(); //получаем значение дескриптора окна рабочего стола //HDC hdc = GetDC(hwnd); //получаем дескриптор дисплейного контекста устройства, 0 - экран int PixelRGB = GetPixel(GetDC(hwnd), CoordsX, CoordsY);
Добавлено (13 Июля 2023, 20:19) --------------------------------------------- Проблема не в доп. коде, которым получаем цвет пикселя или hwnd окна. Проблема в том, что как то не правильно я обрабатываю этот хук. Как я понял, каждое сообщение записывается и их нужно извлекать.
Код
int MyHook::Messsages(){ while (msg.message != WM_QUIT){ //while we do not close our application if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){ TranslateMessage(&msg); DispatchMessage(&msg); } Sleep(1); } UninstallHook(); //if we close, let's uninstall our hook return (int)msg.wParam; //return the messages }
Сообщение отредактировано frolandr - Чт, 13 Июля 2023, 20:19
Я с похмелья, голова не работает. Попробую вкратце описать как у меня это происходит. Запускаю Хук. FHook := SetWindowsHookEx(WH_MOUSE_LL, @HookProc, 0, 0);
WH_MOUSE_LL - Устанавливает процедуру фильтра (hook), которая осуществляет текущий контроль за низкоуровневыми событиями ввода данных от мыши.
Когда происходит любое событие мыши, запускается функция HookProc. Как хочешь ее можешь обозвать.
function HookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
Не буду описывать, выше по ссылкам есть описание.
И в ней уже выполняется определение, какое именно событие мыши произошло. Как я понимаю, эта функция должна отработать как можно быстрее и передать дальше, другим приложениям которые запрашивают подобную информацию. А таких в системе много. Если ты не передашь инфу дальше, то приложения которые должны были получить после тебя, отработают не правильно. Отсюда тормоза, зависания и т.д.
Передача должна происходить в любом случае, обрабатываешь ты полученную инфу, не обрабатываешь, ошибка пришла или нет и т.д. Т.е.:
begin if nCode < 0 then //Если ошибка... Result := CallNextHookEx(FHook, nCode, wParam, lParam) //Отправляем дальше сообщение другим приложениям.
end; WM_MOUSEHWHEEL : begin Form1.Label3.Caption:= 'WM_MOUSEHWHEEL'; Form1.Label4.Caption:= IntToStr(Smallint(HiWord(PMSLLHOOKSTRUCT(lParam).mouseData))); end; end;
Но думаю что это не правильно. Как уже раньше говорил, здесь нужно передать только параметры, а код выполнять после того как функция отработает.
И в конце обязательно опять делаем перенаправление.
//перенаправить (hook) в следующий фильтр в текущей цепочке фильтров событий Result := CallNextHookEx(FHook, nCode, wParam, lParam); end;
Вот в этом месте, или за пределами функции уже вызывать функцию которая продолжит выполнение заданных параметров. Это мое мнение как дилетанта. Возможно я что то не правильно понимаю. Нужно литературу читать, особенно по хукам и очень внимательно.
Т.е. как я понимаю. Функция отработала и передала сообщение дальше. Мы ее не задерживаем. Если же мы пытаемся внутри обрабатывать события, то пока мы их обрабатываем, приходит уже новое событие и толкает в зад предыдущее, тем самым создавая тормоза. Так как мы держим не только себя, но и все те приложения которые уже все обработали и ждут новых сообщений. А их нет. Так как мы их задерживаем.
Добавлено (15 Июля 2023, 13:18) --------------------------------------------- И еще упустил не маловажную деталь. При закрытии, крахе приложения нужно обязательно предусмотреть удаление хука. Он сам не удаляется.
UnhookWindowsHookEx(FHook);
Добавлено (15 Июля 2023, 13:31) --------------------------------------------- Вообще хук делается через dll, и вот уже из нее приходят Messsages. Опять же, на сколько я понимаю, раз я хук вызываю не из dll, то и Messsage мне не нужны. Все эти сообщения приходят в wParam, lParam. Их просто нужно оттуда получить, а не из Messsage. В wParam пиходит код\название события, в lParam доплнительные данные. Такие как прокрутка колеса, координаты мыши и т.д.
Добавил возможность установки подпрограмм на события кнопок и колесика, вроде бы зависаний при работе подпрограмм нет. Вернул также возможность получения размеров объекта и цвета пикселя. Однако не злоупотребляйте, устанавливая все сразу. Можно включать выборочно в зависимости от задачи. По этому думаю разделить команду по установке хука и настройки параметров отображения координат и пр. Для того, чтобы при изменении настроек постоянно не выключить и снова включать хук.
Обратите внимание! Если во время выполнения одной подпрограммы вы инициируется другую, то вам может показаться странным их выполнение. Все дело в том, что виндовс работает с сообщениями по принципу LIFO (последним пришёл — первым ушёл), т.е. событие записанное последним, отработает первым.
Для примера во второй демке: крутите вы колесико мыши к себе, окно с текстом начнет опускаться вниз, пока отрабатывает программа вы сменили направление и начали крутить колесико от себя. В этом случае окно с текстом сразу пойдет вверх, а после того как отработает новая подпрограмма, окно с текстом снова пойдет вниз.
Так работает по умолчанию. Не знаю правильно ли это в отношении плагина, но пока я не смог изменить направление на FIFO. отсортировать и проч.
Добавлено (16 Июля 2023, 16:19) --------------------------------------------- mishem, к стати, ты прав, если увеличен масштаб, то и размер рабочего стола уменьшается. В связи с этим для мыши получаю координаты из обычной функции, а не из структуры. Ну а вот при получении цвета наоборот нужны координаты с учетом масштабирования, беру их из структуры. Вот такая белиберда
Сообщение отредактировано frolandr - Вс, 16 Июля 2023, 16:22
В обеих плюс, так как в переменной уже есть минус. Плюс на минус дает минус, плюс на плюс дает плюс.
Как вариант в примере еще для новеньких показал бы как количество строк прокрутки можно вытягивать из реестра и использовать в подпрограмме. Т.е. по умолчанию 3 или 4, не помню, но у каждого может быть свое значение. Получать это значение и умножать на то, что приходит в переменной [faMouseWhellScroll].
Кстати если есть желание, можешь еще плагин "помучать". Вот первое попавшееся про мышь. Кстати только сейчас узнал что -1, прокрутка на весь экран.
Ну я бы в подпрограмме удалил бы ту "портянку" и написал бы что в одной, что в другой:
Ну я же там просто написал две команды, а затем накопировал , чтобы посмотреть не будет ли виснуть. Я часто копирую куски кода, а из-за этого ошибки. В плагине накопировал, потерял установку подпрограммы для LEFT_UP.
Цитатаmishem ()
Как вариант в примере еще для новеньких показал бы как количество строк прокрутки можно вытягивать из реестра и использовать в подпрограмме. Т.е. по умолчанию 3 или 4, не помню, но у каждого может быть свое значение. Получать это значение и умножать на то, что приходит в переменной [faMouseWhellScroll].
Может позже сделаю, примеры в демке не цель, с плагином намучался и некоторые вещи, например, про очередь не все еще понятно. В идеале хотелось бы менять очередь, переворачивать, сортировать, или вообще удалять некоторые сообщения и т.д. В сам плагин можно еще кое-что добавить.
Цитатаmishem ()
Вот первое попавшееся про мышь.
Посмотрю позже, дела домашние накопились, много время уделял плагину.
frolandr, возможно читал? Наткнулся на интересную статью.
Сейчас прочту.
Добавил несколько команд в плагин для получения информации о мыши и ее настройках. Именно к хуку они не имеют отношения, по этому данные можно получать без его установки.
Добавлено (17 Июля 2023, 18:34) --------------------------------------------- Статья от 2003 года, с того времени многое изменилось. Архив видимо удален, не могу скачать.
Спасибо, посмотрел. Интересно, множество информации в сети о хуках и все берут информацию о событии из коллбэк функции, сразу как они срабатывают, а этот автор берет ее из структуры MSG. Но вот нет не где информации как удалять эти сообщения о событиях. Есть функция GetMessage вот она читает и удаляет, она работает, но для нее нужен вечный цикл while, пробовал так, работает но может зависнуть и прогу не выключить. Есть другая функция PeekMessage она читает и в зависимости от последнего флага может удалять, ей не нужен вечный цикл, но блин она не удаляет, хотя должна. В сети нашел только один пост, пользователь тоже пишет, что не удаляет она сообщения. К стати, за 20 лет виндовс изменились, пишут, что даже если написать полностью нерабочий хук, то виндовс просто будет его игнорировать, а этот автор пишет, что раньше в старых виндовс до 2000, были с этим большие проблемы.
Где то мне встечалось, может и ошибаюсь, что сообщения сами удаляются,после 40.
Но я не пойму,зачем они тебе вообще нужны, сообщения.Сообщение, как я понимаю, формирует dll библиотека, а уже из приложения ты получаешь это сообщение.
Из приложения ты не можешь поставить некоторые хуки, так как подвесишь систему. Не смогу наверно тебе объяснить, так как сам возможно не правильно понимаю, потому что многого не знаю. Например обращение к окну. Ты ставишь хук на окно. Щелкаешь или наводишь мышь на него и начинается вечный цикл или зависон. Хук твоему же приложению передает событие, но приложение не может его обработать, потому что не получило ответ на посланное событие, так как оно же и должно послать этот ответ.
Некоторые хуки можно обработать на прямую, но опять же не рекомендуется, и их не так то много. В них как раз входят клава и мышь на низком уровне. Не хочешь читать хелп?
Где то мне встечалось, может и ошибаюсь, что сообщения сами удаляются,после 40.
Не попадалась такая информация. Вся виндовс построена на сообщениях, мышь передает сообщения, клавиатура, одно окно передает сообщение другому и т.д. При нажатии на кнопки мыши эти сообщения пересылаются и записываются. При чем они записываются сверху, т.е. оно зайдет последним. Ну это как в трубу попало первым сообщение, а другие его утолкали в самый конец, а чтобы вынуть из этой трубы, сначала нужно вынуть то, что зашло последним, и т.д., когда еще доберемся до первого предмета. Т.е. есть записанное сообщение от левой кнопки и оно первое, записалось, затем пользователь начинает постоянно кликать правой кнопкой мыши и выполняется подпрограмма повешенная на правую кнопку, а та подпрограмма, что повешена на левую так и будет ожидать, пока до нее дойдет очередь. Я вот не знаю, а вдруг через определенное время или по количеству оно вообще сотрется, то первое или второе. Все, что мне бы хотелось это как-то попробовать перевернуть эту очередь и если пользователь кликнул на левую кнопку 5 раз, то пусть они и отработают сначала, а уж затем другие клики правой кнопки. Ну или запретить записывать сообщения другой кнопки, пока первая не отработает. Это хорошо на проге написанной на бильдере можно несколько потоков сделать и тогда они будут выполняться асинхронно, в НЕО же так нельзя.
Все, что мне бы хотелось это как-то попробовать перевернуть эту очередь
Так я ж тебе говорил выше, в хуке отлавливай события и помещай их в глобальную переменную, а в отдельной подпрограмме обрабатывай.
Например левый клик = 1, правй клик равно 2. К примеру ты хуке поучил 11212. Если выполняешь подпрограмму из хука, то он будет обрабатывать по твоим словам в обратном порядке: 21211. Вынеси это в переменную. В хуке: присваиваиваешь переменной, из другой функции выполняешь подпрограмму отталкиваясь от значений в переменной. Выполнил подпрорамму 1го значения, удалил его из переменной и перешел к следующему.
Дело в том, что в добавок ко всему, сама НБ выполняет подпрограммы в зависимости от последования вызова. Ты вызвал первую подпрограмму и следом вторую. Вторая разорвет код первой подпрограммы, выполнится, а после продолжит выполняться первая.
Что бы этого не происходило, в коде плагина не нужно вызывать следующую подпрограмму пока не отработала предыдущая. Это тоже можно отслеживать с помощью переменной. Например послал подпрограмму и присвоил переменной +1. Подпрограмма по завершению должна прислать -1. Если переменная не равна 0, не вызывать следующую подпрограмму пока она не будет равна 0.
Как то так. Надеюсь понятно...
Добавлено (18 Июля 2023, 17:33) ---------------------------------------------
Цитатаfrolandr ()
можно несколько потоков сделать
Кто тебе мещает сделать псевдо много поточность с помощью таймера? Код в таймере, на сколько я понимаю, должен по идее прерываться когда выполняется хук. Т.е. таймер хук тормозить не будет. И еще раз, не пользуйся Sleep. Не хочешь читать хелп?
Так я ж тебе говорил выше, в хуке отлавливай события и помещай их в глобальную переменную, а в отдельной подпрограмме обрабатывай.
В колбеке у меня только флаги поднимает. На каждое событие отдельная подпрограмма написана. Которая и запускает подпрограммы, она же и флаги снимает.
Цитатаmishem ()
Например левый клик = 1, правй клик равно 2. К примеру ты хуке поучил 11212. Если выполняешь подпрограмму из хука, то он будет обрабатывать по твоим словам в обратном порядке: 21211. Вынеси это в переменную. В хуке: присваиваиваешь переменной, из другой функции выполняешь подпрограмму отталкиваясь от значений в переменной. Выполнил подпрорамму 1го значения, удалил его из переменной и перешел к следующему.
Так у меня и сделано почти так этим колхозом. Это неправильно, виндовс сама посылает сообщения я их принимаю, а вот сортировать или очистить не могу. Вернее очистить могу, но вечным циклом, что не есть гуд. Та команда, которая должна читать и очищать без цикла, почему то не работает. Может только у меня и еще у одного чела больше инфы не нашел.
Цитатаmishem ()
Кто тебе мещает сделать псевдо много поточность с помощью таймера?
А тебе известен способ кроме таймера или создания другого процесса или еще потока, как по другому можно запустить подпрограмму? Тут я не знаю такого. В JS можно async функцию создать и вызвать, вызвал ее, одна цепочка в подпрограмму ушла, а другая дальше по главной идет. Однако, если у тебя дальше в главной нужны результаты, то нужно все равно дождаться выполнения асинхронной функции, по этому добавляешь await. В каком то языке, не помню, можно было при помощи команды CALL вызвать подпрограмму, а цепочка выполнения также дальше шла.
Добавлено (18 Июля 2023, 18:25) ---------------------------------------------
Цитатаmishem ()
И еще раз, не пользуйся Sleep.
начитался плохих примеров по хукам. Видел несколько таких, я вообще не понял для чего они там это делают.
Добавлено (18 Июля 2023, 18:32) ---------------------------------------------
Цитатаmishem ()
Дело в том, что в добавок ко всему, сама НБ выполняет подпрограммы в зависимости от последования вызова. Ты вызвал первую подпрограмму и следом вторую. Вторая разорвет код первой подпрограммы, выполнится, а после продолжит выполняться первая.
Вот в том то и беда. Это плохо, но если сделать выполнение второй подпрограммы только после выполения первой тоже не лучше. Если первая подпрограмма длинная, которая будет отрабатывать 5-10 сек. То юзер успеет 20 раз кликнуть другой кнопкой мыши, и тогда попрет 20 раз выполнении другой подпрограммы. Тут конечно можно ограничить одним, но опять же не все так радужно, мы же не можем знать сколько именно раз запускать другую подпрограмму, может нужно не 1, а 3... Вот если бы все выполнялось асинхронно, вот это был бы идеальный выход.
Сообщение отредактировано frolandr - Вт, 18 Июля 2023, 18:33
Вот если бы все выполнялось асинхронно, вот это был бы идеальный выход.
Забудь вообще и не возвращайся к этой мысле. Это я тебе как дилетант дилетанту говорю.
Цитатаfrolandr ()
Если первая подпрограмма длинная, которая будет отрабатывать 5-10 сек.
Это первая ошибка в понимании. Длинная это из 10000+ строк?
Не забывай что ты смотришь в отладчик в реальном времени. То что у тебя происходит в отладчике 10 сек, в скомпилированном варианте 0,01 сек. Это в НБ, в Делфи еще раз в 100 быстрее.
Но это не значит, что код не нужно оптимизировать. 0,1 сек в нескольких местах, складывается в секунды.
Цитатаfrolandr ()
мы же не можем знать сколько именно раз запускать другую подпрограмму, может нужно не 1, а 3...
Почему не можем? Но дело даже не в этом....
Ниже прикрепил проект. Запусти его с отладчиком. Нажми на кнопку быстро как сможешь несколько раз. И работать будет не правильно, и сабатывать через раз.... Теперь запусти в скомпилированном варианте и попробуй сделать то же самое. Сомневаюсь что у тебя получится нажать даже хотя бы два раза.
Увеличь цикл в подпрограмме что бы добиться успеть нажать 2 раза. Найди разницу в скорости.
Ну и там же посмотри как отследить количество запущенных подпрограмм. Код не идеален. Первое что пришло в голову. Даже можно сказать не верный. Хотя...
Добавлено (18 Июля 2023, 19:43) ---------------------------------------------
Цитатаmishem ()
Увеличь цикл в подпрограмме что бы добиться успеть нажать 2 раза.
Попробовал. Цикл в 500 уже не срабатывает. В 200 уже не успеваю нажать. Много подпрограмм в 200 строк?
Но при желании можно отследить, работает подпрограмма в НБ или нет, и если работает, ставить в очередь следующий запуск.
Добавлено (18 Июля 2023, 19:55) --------------------------------------------- Ну а у ебя можешь переменную [Clic] использовать как счетчик подпрограмм, а SetVar "[Start]" "[Start]+1" заменить на [Clic] - 1.
Т.е. в функции хука плюсовать подпрограммы, в функции вызова минусовать. Точно так же можешь обрабатывать какую именно подпрограмму вызывать. Т.е. к примеру в переменной [Clic] не плюсовать, а складывать массив, 1=лев. клик, 2 = пр.клик, 3 = ср. и т.д. После из массива получать первый элемент. Как подпрограмма отработала, первый элемент удалять и опять получать первый пока не закончаться. В другой переменной вести подсчет элементов... Развивай мысль. Описывть дольше чем код написать.
Это первая ошибка в понимании. Длинная это из 10000+ строк?
Смотря еще какие команды в подпрограмме. Вот перемещение объектов тяжело в НЕО происходит. Если просто арифметические команды, то много быстрее.
Цитатаmishem ()
Не забывай что ты смотришь в отладчик в реальном времени. То что у тебя происходит в отладчике 10 сек, в скомпилированном варианте 0,01 сек. Это в НБ, в Делфи еще раз в 100 быстрее.
Если честно, то я отладчиком только и начал пользоваться во время разработки хука. До этого всегда компилил, затем проверял. Я на НЕО ну от силы 20 программ написал разной сложности и это с 2008 примерно года, т.е. фактически 3-5 программ в год, затем перерыв несколько лет, затем снова писал. Фактически забывалось многое. Я много встроенных команд не знаю. С объектами по минимуму работал, скрыть-показать Плагины тоже только по особой необходимости. Я даже для себя так и не понял, что лучше в НЕО подпрограммы или функции в библиотеку писать. Функции вроде понятнее(привычнее, можно аргументы передать), но они как бы отдельные и не записываются в общий код, их нужно с проектом все время таскать.
Добавлено (18 Июля 2023, 20:26) ---------------------------------------------
Цитатаmishem ()
Ну а у ебя можешь переменную [Clic] использовать как счетчик подпрограмм, а SetVar "[Start]" "[Start]+1" заменить на [Clic] - 1.
Т.е. в функции хука плюсовать подпрограммы, в функции вызова минусовать. Точно так же можешь обрабатывать какую именно подпрограмму вызывать. Т.е. к примеру в переменной [Clic] не плюсовать, а складывать массив, 1=лев. клик, 2 = пр.клик, 3 = ср. и т.д. После из массива получать первый элемент. Как подпрограмма отработала, первый элемент удалять и опять получать первый пока не закончаться. В другой переменной вести подсчет элементов...
Виндовс это все сама делает. Все записывает, все извлекает.
Изменить отработку подпрограмм можно как угодно, т.е. так же как ты и пишешь, только записывать все не в переменную, а в массив, его и перевернуть легче и отфильтровать и т.д.. Нужно иметь определенную цель, тогда и писать можно. Я же не знаю что правильно и как лучше. Т.е. как сейчас, или просто отрабатывать сначала одну подпрограмму, потом другую. У меня сейчас 9 таймеров. Думал будут параллельно работать, но след. подпрограмма прерывает предыдущую и выполняется сама, а след. за ней может ее прервать и сама начать выполняться, потом вторая завершится и толко после первая. Чтобы выполнять по одной подпрограмме я могу вообще 1 таймер оставить и тогда все подпрограммы будут по очереди выполняться.
А тебе известен способ кроме таймера или создания другого процесса или еще потока, как по другому можно запустить подпрограмму?
Я не знаю как у тебя там все организовано. Я и в Делфи полный профан. Вершки схватываю и понимаю как понимаю. Петра не хватает, или Дембель хотя бы подключился, а то тоже пропал.
Таймер хорош только для краткосрочного вызова, там где цикл излишний, или наоборот для долгосрочного. Т.е. часа через 2 или 24 что то запустить. Постоянный таймер не приветствуется в моем понимании.
Фнкция SetWindowsHookEx запускает монитор. Т.е. она запускает функцию которая отслеживает определенные события которые тебе нужно обработать. Для этого, ты для каждого события можешь вызвать другую функцию. Эта продолжит мониторить, а другая будет обрабатывть события. Из другой функции ты можешь вызвать еще десяток функций которые тебе нужны в то или иное время. Т.е. если подпрограмма в нб установлена, вызвать функцию которая будет обрабатывать подпрограмму(ы).
В моем понимании, зачем прогонять весь код который уже по определению не будет выполняться, лучше перескочить сразу в другую функцию, оттуда в следующую и т.д.
Т.е. минимизируешь условия, а основной код для каждого условия переносишь в разные функции. Не в одной функции вся портянка выполнения, типа если да = выполнить код из 100 строк, если нет = тоже выполнить код из 100 строк. А там еще с 10ток условий в которых тже по 100 строк кода на каждое условие. Не хочешь читать хелп?
Единицы знают. Кто работает над этим постоянно. Как Петр говорил, скопипастить мало, нужно понимать что и зачем там написано.
Делай как понимаешь и считаешь правильно. Со временем поймешь где ошибался. Монитор мыши это самое простое наверно из мониторов. Я в том году по моему, или раньше делал монитор клавы. Вот там с наскока не разберешься.
Сейчас поднял исходники, и вижу что нужно переделать, а тогда считал что все правильно. Некоторые вещи и сейчас не понимаю и не знаю как получить. Нужно азы изучать, а на них времени катастрофически не хватает. Я с тобой все дела забросил, а у меня их тут не в проворот. Нужно с силами собраться и послать комп куда подальше. Не хочешь читать хелп?
Единицы знают. Кто работает над этим постоянно. Как Петр говорил, скопипастить мало, нужно понимать что и зачем там написано.
В этом то и беда. ВинАпи это фактически свой язык, это не Делфи, не с++. Т.е. пишешь та в Делфи, а функции применяешь из ВинАпи.
Добавлено (18 Июля 2023, 20:54) ---------------------------------------------
Цитатаfrolandr ()
Делай как понимаешь и считаешь правильно. Со временем поймешь где ошибался. Монитор мыши это самое простое наверно из мониторов. Я в том году по моему, или раньше делал монитор клавы. Вот там с наскока не разберешься.
В мониторе клавы всего одно событие нужно отрабатывать это keydown, в мониторе мыши как минимум 9. Нужна одна подпрограмма, которая преоразует кейкод. Принцип конечно очень похожий . Возможно ошибаюсь, только когда делать начнешь, только тогда поймешь, можно затормозить на какой нибудь мелочи, а подсказать не кому.