Перейти к содержанию
Fire Monkey от А до Я

kami

Пользователи
  • Постов

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

  • Посещение

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

    41

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

  1. Похоже, ответ появился: https://en.delphipraxis.net/topic/2949-zxing-delphi-for-104/?do=findComment&comment=23777
  2. Т.е. прочитать, что они делают - это излишне? Бессмысленные действия, результат выполнения которых уже известен изначально. И всё остальное - тоже проигнорировано... Удачи.
  3. Form1.Edit1.Text:=Form1.Edit1.Text+ch; Вам еще в прошлом топике сказали - не нужно так делать. Обработчик хука должен максимально быстро вернуть управление. Любая обработка должна проводиться постфактум, асинхронно. Здесь вы без тени сомнения работаете с визуальными компонентами, вызов которых может и должен производиться только из главного потока вашего процесса. Откуда такая уверенность, что коллбак хука будет вызван именно в этом потоке? В вашем коде первые две строки бессмысленны, почитайте их описание в https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-mapvirtualkeyw , чтобы понять - почему. Читаем ремарки (часто ремарки - это самое главное ) для GetKeyboardState: https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getkeyboardstate и выясняем, что она привязана к вызывающему потоку. А LL - хуки вызываются как минимум в контексте установившего их процесса, скорее всего (лень читать доку) - в контексте установившего хук потока. Потому и не отрабатывает, что GetKeyboardState для получения нужного эффекта должен вызываться в контексте чужого потока в чужом процессе. Чтобы отвязаться - следует использовать (как следует из тех же ремарков по ссылке выше) GetAsyncKeyState.
  4. Исчерпывающее описание проблемы. Вам сама операционная система говорит - нельзя так делать, вы тормозите ВСЁ что только можно, в результате ваш хук признается вредоносным и исключается из цепочки. Но вы упорный... Ждите ответа. Но в своем коде, а не в хуке. А в свой код передавайте данные асинхронно, через тот же postMessage
  5. PeekMessage - бессмысленно и даже вредно с флагом PM_REMOVE. Убрать. SendMessage - эта функция отправляет данные окну и дожидается, пока окно их обработает. А хук ждать не должен, его задача - максимально быстро отработать. Заменить на PostMessage. длл здесь не нужна. LL-хуки работают из любого места. Просто перенести весь код в exe.
  6. Не надо TCPServerов на клиентах. Ничего хорошего из этого не выйдет, как минимум потому что белые IP есть у 1% пользователей сотовой связи, к остальным будет не подключиться извне. TCP соединение позволяет обеспечить двусторонний обмен. Любой из корреспондентов (и клиент и сервер) в любой момент времени вправе отправить в соединение данные. На стороне TCP сервера для этого нужно отправить данные в конкретное соединение с конкретным клиентом, а на клиентской - и выбирать ничего не надо, у TCP-клиента только одно соединение.
  7. WebSockets обеспечивает обратную связь "сервер-клиент", в отличие от обычного http, где идет клиент-сервер. Увы, насколько я знаю - это доступно только на Indy (буду очень рад, если ошибаюсь), а (далее всё очень субъективно) с индейцами у меня как-то не сложилось...
  8. Это зависит от того, какого эффекта надо добиться. Если queue вызываете из не-анонимного потока кодом вида Self.Queue(myProcedure) - то при уничтожении потока всё что он отдал в очередь на выполнение в главный поток, будет уничтожено. Без выполнения. Если вызывать как TThread.Queue(nil, myProcedure) - то не будет уничтожено. Но в этом случае, само собой, нельзя обращаться к полям и методам этого потока. Если требуется обращение только к полям - заведите локальные переменные и работайте с ними. Например, так: procedure TmyThread.Execute; var SomeValue, SomeAnotherValue: string; begin ..... SomeValue:=Self.FInternalValue; // Self пишу только для понимания, что Fxxx - это поле в экземпляре потока SomeAnotherValue:=Self.FInternalAnotherValue; TThread.Queue(nil, procedure begin ShowMessage(SomeValue + SomeAnotherValue); // эти переменные доживут до выполнения анонимки даже если потока уже не будет. end; );
  9. Покажите, пожалуйста, правильную задачу, которую пытаетесь решить.
  10. Тут нет кода, выполняемого в доп.потоке. Метод Synchronize делает следующее: "приостановить выполнение себя (т.е. доп.потока), переключиться в основной поток, выполнить там действие и после этого вернуться в себя (в доп.поток)". Ввиду того, что в коде доп.потока есть только synchronize - то единственное, что поток делает - ждёт, пока выполнится его действие в основном потоке. То есть - является абсолютно бессмысленным.
  11. Поставьте бряк внутри метода _ReciveMessage и удивитесь - в каком потоке он вызывается. Ну или напишите if TThread.Current.ThreadID<>MainThreadID then // мог слегка ошибиться с наименованиями переменных - пишу по памяти, но вроде это они и есть. Алярма!!! (тут что-нибудь сигнализирующее что всё неправильно). Включая режим буквоедства: смените названия на ReceiveMessage и PackedNumber. Глаз цепляется
  12. Опять пошли в какие-то обходные маневры... Решение для винды: uses FMX.Platform.Win, Winapi.Windows; procedure TForm5.FormCreate(Sender: TObject); // Form5 - это окно-"всплывашка". Не забываем выставить в инспекторе объектов stayOnTop, стиль border-а и т.п. var myHWND: THandle; ExStyle: NativeInt; begin myHWND:= WindowHandleToPlatform(Handle).Wnd; Winapi.Windows.SetParent(myHWND, 0); ExStyle := GetWindowLong(myHWND, GWL_EXSTYLE); SetWindowLong(myHWND, GWL_EXSTYLE, ExStyle or WS_EX_TOOLWINDOW or WS_EX_NOACTIVATE); Возможно, этот код будет актуальнее смотреться в OnShow, а не в onCreate.
  13. У меня - нет. Емнип, Owner-ом для всех наброшенных на форму компонентов выступает сама форма. Вне зависимости от уровня вложенности визуальных компонентов. Для невизуальных объектов овнер нужен, если они покладены на форму в дизайн-тайме. Parent-а у невизуального объекта нет, а правило "не ты создал - не тебе удалять" выполняться должно. Это из того, что на поверхности. А какие реальные причины заставили иметь не только парента, но и овнера, да еще и для дизайн-тайм... Возможно, действительно без них никак. Давайте только без привлечения ARC "ничего удалять не надо, если и владелец и родитель удалятся, ссылки на объект закончатся и он самоуничтожится".
  14. Понаехавших - нет, не учат. Раненых особенно. Тебе эпитеты тоже подобрать? По сути вопроса? Как ты говоришь "накидывание" возникло от того, что для решения не самого сложного вопроса здесь озвучены (в том числе -тобой) рекомендации и выводы, от которых потом сложно не удивляться - откуда столько говнокода в экосистеме Делфи? Да вот отсюда, из таких топиков на форумах, которые неокрепшие (да и окрепшие) умы впитывают и несут потом в массы. Удивительно, что еще не затронули "уникальное имя нужно, потому что по нему потом будем искать этот компонент"...
  15. Upd. Нет, похоже в fmx механизм FreeNotification не используется для уничтожения. Но это не мешает всему хозяйству уничтожаться корректно, какие бы родители с владельцами ни указывались
  16. Предположил на основании твоего вывода " не будет ошибки дублирования? по моему будет ", который проверяется и опровергается за 2 минуты. В результате вместо того, чтобы понять откуда ноги растут у ошибки дублирования имен - вы имеете костыли типа "по этой причине именовали := 'frame_'+i.toString; "
  17. Уничтожение и в VCL и в FMX идет именно Parent-ом. Owner получал уведомления (FreeNotification / RemoveFreeNotifications) и убирал высвобожденные ссылки из своего списка на уничтожение. Потом уничтожал свое. Это дефолтное поведение, сложившееся издавна, оно же без изменений перекочевало в FMX, единственное - находятся методы FreeNotification / RemoveFreeNotifications в разных классах. Нет, это далеко не так. Parent-ом действительно уничтожается всё дочернее. Но Owner после этого ничего сделать уже не может, потому что он уже не знает об уничтоженном компоненте: destructor TComponent.Destroy; begin ... if FOwner <> nil then FOwner.RemoveComponent(Self); Ну и напоследок: procedure TForm12.btn1Click(Sender: TObject); var fm: TForm; fr: TFrame13; i: Integer; begin fm := TForm12.Create(Self); // создаем дубликат try for i := 0 to 5 do begin fr := TFrame13.Create(Self); // Owner - главная форма // на фрейм накидал эдитов, лейблов - чтобы не пусто было. fr.Name := 'fr' + IntToStr(i); fr.Parent := fm; // а Parent - вторая форма того же класса. fr.Align := TAlignLayout.Right; end; fm.ShowModal; finally fm.Free; // уничтожаем вторую форму end; // и потом, при закрытии главной формы всё кошерно. end; Что я делаю не так?
  18. Вы выискиваете какие-то обходные маневры, генерацию уникальных имен с привлечением guid, обнуление имени после создания... а на самом деле ничего из этих костылей не нужно.
  19. Родитель-то как раз не nil. Владелец nil. Позвольте поинтересоваться, а какой профит помимо счастья обладания геморроем (который сам себе же и сделал) принесет создание компонента с указанием владельца? Единственный плюс, который мог бы быть - владелец при высвобождении себя уничтожает всё, чем он владеет. Но вот беда-то... родитель тоже это делает, причем - раньше. И благодаря подпискам на уведомления владелец узнаёт, что компонента, которым он владел, уже нет, т.е. попытки двойного уничтожения НЕ будет.
  20. попробовать религия не позволяет? Только что написанный код: var i: Integer; fr: TFrame13; // отдельный фрейм, у которого в ObjectInspector так и написано: Name = Frame13 begin for i := 0 to 5 do begin fr:=TFrame13.Create(nil); fr.Parent:=Self; fr.Align:=alRight; end; всё отрабатывает без проблем, никаких вопросов по именованию рантайм-компонентов не возникает.
  21. помнится, отвечал уже кому-то на форуме. Для динамически создаваемых компонентов просто не указывайте имя. Не нужно оно им. Тогда эта проблема отпадает сама собой.
  22. И еще в тему ForceQueue. Как-то раз потребовалась мне конструкция типа "отложенное действие после отложенного действия". Дык вот, если сделать вот так: TThread.ForceQueue( procedure begin SomeAction; ForceQueue(SomeAnotherAction); end); то SomeAnotherAction выполнится сразу же вслед за SomeAction, а не на новом витке Application.Idle. Всё дело в том, что выполнятель Queued-действий просто достает их из списка, пока не закончатся. Т.е. выполняется первый ForceQueue, а вложенный, как таковой, не выполняется: второе действие помещается в список, тут же достается из него и сразу же выполняется! Как результат - при таком вызове де-факто получается срабатывает только первый ForceQueue, а вместо второго выполняется прямой вызов действия.
  23. тут нет потока. forceQueue не использует создание потоков, оно пишет напрямую в структуры синхронизации. Я у себя уже давно сделал хелпер с одним методом - Release. И его использую не получая сообщений от компилятора.
  24. В обработке сообщения производить действия, которые способны генерировать кучу сообщений, которые приведут к обработке того же сообщения, в котором... , имхо, не есть хорошо. Вместо вот такого экранирования я бы попробовал использовать TThread.ForceQueue(procedure begin код, завязанный на IME end);
×
×
  • Создать...