kami

Пользователи
  • Публикаций

    595
  • Зарегистрирован

  • Посещение

  • Победитель дней

    39

Весь контент kami

  1. Это случайность (с) Мастер Шифу.
  2. Использовать вторую форму StrToDate, явно указывая FormatSettings. Свои, а не общесистемные.
  3. kami

    Хук на клавиатуру

    По большому счету там происходит всего одно: система смотрит, кто еще поставил хук такого же типа и вызывает его функцию. И далее и далее, пока не пройдет всех использовавших SetWindowsHookEx. Повторю - хуков в системе даже "в штатном режиме" установлено великое множество.
  4. kami

    Хук на клавиатуру

    Что может быть непонятно во фразе non-zero value из первоисточника? Скорее всего, возвращаемый результат интерпретируется как BOOL. У любого булеан-типа есть два значения: 0 = False, не 0 = True. Что там присваивают конкретные компиляторы для значения True - это их проблемы. Сравнение всегда ведется с нулем. Может да, а может и нет. Откуда вы знаете, какую логику заложили другие разработчики в свои хуки? Это исключительно их дело - считают ли они нужным
  5. kami

    Хук на клавиатуру

    Мало. If the hook procedure processed the message, it may return a nonzero value to prevent the system from passing the message to the rest of the hook chain or the target window procedure. Не вижу ничего запутанного. В штатной ситуации - вызываете следующий хук. А когда нужно, чтобы клавиша не добралась до адресата - не вызываете. Или же - вызываете, но Result возвращаете <>0. Я не знаю, какой из двух вариантов лучше - я давно уже не работал с WinAPI в этом ракурсе. Эксперименты вам всё покажут, там делов на 20 минут. Разные механизмы работы. Оба - system-wide.
  6. kami

    Хук на клавиатуру

    Нет, не убрать. В целях нормального функционирования в подавляющем большинстве случаев вы должны вызвать следующий хук. И только в исключительных ситуациях (в данном случае - когда клавишу нельзя "пропустить" дальше) - не вызывать. А вы считаете, что единственный на всю систему установили хук на клавиатуру ? :))) Их десятки, если не сотни. Тот же WH_KEYBOARD: система будет вызывать последовательно все KeyboardProc в порядке (емнип), обратном времени установки хука. Естественно, если вы скажете системе "можно отдать на обработку следующему хуку". Внимательно читаем раздел Result в https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms644984(v=vs.85).aspx Там, оказывается, уже всё предусмотрено и потенциально не надо даже пропускать вызов последующего хука. Хотя - лучше пропустить.
  7. kami

    Хук на клавиатуру

    Но результат функции хука нужно присвоить обязательно, вне зависимости от вызова следующего!
  8. kami

    Хук на клавиатуру

    не вызывать следующий хук
  9. наверное, действительно никто. Но вот методом интуитивного тыка это находится на раз. Должно быть так: А у вас, видимо, стоит emacs
  10. kami

    Хук на клавиатуру

    Более того - там уже есть виртуальный код клавиши. Еще проще.
  11. kami

    Хук на клавиатуру

    https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms644984(v=vs.85).aspx
  12. kami

    Хук на клавиатуру

    Так а в чем загвоздка-то? внутри этого хука доступен сканкод нажатой клавиши. Есть GetAsyncKeyState и много чего еще
  13. kami

    Хук на клавиатуру

    по тексту этой ошибки гуглится очень многое. Основной посыл: для WH_KEYBOARD, если указывать HInstance, то он должен быть инстансом dll. Потому что exe не инжектнется в чужой процесс. Можно указать вместо HInstance - 0, а последний параметр выставить в TThread.Current.ThreadID, но (повторюсь) я не уверен, что веббраузер работает только в контексте основного потока приложения.
  14. kami

    Хук на клавиатуру

    Было бы неплохо почитать, чем отличается WH_KEYBOARD от WH_KEYBOARD_LL. Принципы действия абсолютно разные. Вполне возможно, что окна браузера находятся в другом потоке. Посему для начала экспериментов вам нужен именно WH_KEYBOARD_LL Ну так нужно же понимать причину - почему он равен нулю. Обращаемся к первоисточнику. Смотрите, что вернется и узнавайте причину. Можно так: if CurrentHook = 0 then RaiseLastOSError. Нет. Здесь имеется ввиду не разрядность операционной системы, а именно разрядность процессов, запущенных в ней (в 64-битный процесс может быть загружена только 64-битная dll. В 32бита - 32). Кроме того, _LL хуки не зависят от разрядности процесса, поскольку работают в контексте установившего хук потока, им dll не требуется.
  15. kami

    Хук на клавиатуру

    Да куда угодно. Любой модуль, но скорее всего - модуль той формы, на которой лежит веббраузер (его же нужно "обойти"). Там же (например - в конструкторе / деструкторе формы) - регистрация и удаление хука. Ну вот например: https://ru.stackoverflow.com/a/538552/192901 (просмотрел бегло, но криминала нет, по крайней мере - система не помрет, что, кстати, весьма возможно при использовании глобальных хуков). вместо SendMessage подставить myForm.OnKeyDown(...); возможно - придется несколько поменять внутреннюю логику самого хука. Но основа останется без изменений: внутрь хука получается структура, описывающая "что произошло с клавиатурой". Вы ее обрабатываете, вызываете нужные методы и отдаете управление опять системе.
  16. kami

    Утечка памяти в TNotificationCenter | TNotification

    На windows спокойно задействуется механизм отлова утечек. Можно использовать куцый штатный (в dpr первой командой указать ReportMemoryLeaksOnShutdown := True или воспользоваться сторонними расширенными. Например - MadExcept имеет возможность показывать утечки памяти и ресурсов.
  17. Здесь ничего не меняли? (ну, Target, само собой должен быть Android)
  18. Если вы можете гарантировать, что Sender всегда будет типа TmyThread, то преимущество в использовании absolute есть: вы можете сразу работать с полем th как с экземпляром своего потока. Что это дает? Ну, допустим у вас запущено несколько потоков, каждый по завершению вызывает этот обработчик. Если в обработчике использовать поле класса, то вы будете работать с одним (скорее всего - последним созданным) экземпляром потока. А если оперировать Sender-ом, то работа будет вестись именно с тем, кто вызвал метод. Повторюсь - если можете гарантировать, что Sender будет нужного вам типа. Но лучше все-таки не надеяться на это, а выполнять явные преобразования: procedure TForm1.ThreadEnd(Sender:TObject); var th: TMyThread; begin if Sender is TmyThread then th:=TmyThread(Sender) else th:=nil; if not Assigned(th) then exit; // а вот далее th уже явно указывает на экземпляр TMyThread.
  19. Под iOS и Win я делал собственную клавиатуру, которая работала вместо системной (исключительно внутри своего приложения). При этом сами компоненты (тот же TEdit) не затрагивались, т.е. поведение клавиатуры оставалось абсолютно прозрачным. Подключили модуль - работает своя клавиатура. Отключили - работает системная. Если вы можете доработать ее и под андроид - могу выложить в открытый доступ. Предупреждаю, что сделать методом "чуть изменим код под другую платформу" не выйдет - подходы у всех систем принципиально отличаются друг от друга.
  20. kami

    PNG работа с чанками

    А что мешает использовать этот класс? Это не визуальный компонент, на форму его класть не надо.
  21. kami

    Поток на клиенте

    Так не вызывайте отрисовку на каждый принятый пакет. Пусть принятые данные кладутся в очередь (например - TQueue). Когда назревает необходимость отрисовки (допустим, по таймеру) - из очереди выгребаются все пакеты и данные рисуются сразу, всем скопом. По потоку: в соответствии с общими правилами - некорректно создавать объект в одном потоке и начинать его использовать в одном потоке, а основное использование вести в другом. Это я про TIDTCPClient. Перенесите его создание и уничтожение (кстати - а где деструктор?) в Execute вашего потока. На основании чего такой вывод? Я про первую часть - "поток отрабатывает сообщения с сервера"?
  22. В рантайме нет никаких дженериков. Компилятор преобразует все дженерики в реальные списки с необходимой типизацией. Поэтому - действительно никак. Вполне возможно, что даже is TObjectList<TMyClass> не сработает - компилятор вполне вправе посчитать исходный класс TObjectList<TMyClass> не тем, с которым производится is. Это неправильно. Потому что есть еще Insert, есть Update (в том числе - и InsertRange). Правильно - перекрыть метод Notify или реализовать обработчик события OnNotify (последнее даже создания наследников не требует). Вообще, если по каким-то причинам необходимо знать "владельца", было бы совсем хорошо сделать наследника от TRectangle, который будет реализовывать интерфейс наподобие такого: IOwneredIntf = interface ['{ADF563F3-B4CE-4E96-9559-F0FFC2936D5Z}'] function GetOwner: TObject; procedure SetOwner(const Value: TObject); property Owner: TObject read GetOwner write SetOwner; end; Список, который хочет установить владельческие отношения с этим TRectangle, в своем методе Notify приводит его к интерфейсу и устанавливает intf.Owner:=Self Ну и в обратном порядке - тоже. При этом появляется возможность работать со списком не только TRectangle, а вообще чем угодно, что поддерживает указанный интерфейс. И если список сделать тоже с поддержкой интерфейса (не знаю, какие методы в нем необходимы), то и сам объект может работать со своим владельцем абсолютно не интересуясь его типом.
  23. Можно это обойти (и довольно неплохо, не костыльно)... но это нужно кодить. Готового механизма нет.
  24. нет. Потому что элемент не принадлежит никакому листу. Это список знает, что при удалении элемента нужно сделать ему Free / заNil-ить ссылку на элемент. Только список. Сам объект (элемент списка) не подозревает о том, что он кому-то там "принадлежит".
  25. Не, оказывается я ошибся еще больше. Чтобы окончательно выяснить - залез на https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms644906(v=vs.85).aspx USER_TIMER_MINIMUM (0x0000000A), - минимально возможный интервал = 10мс. Но это недостижимый идеал :)))