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

Шамсуддин

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

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

  • Посещение

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

    2

Сообщения, опубликованные Шамсуддин

  1. Доброго времени суток!

    Сделал простенький компонент для замены текста в документах Word (docx) и OpenDocument (odt). Особенностью данного компонента является отсутствие необходимости какого-либо дополнительного ПО типа MS Office или OpenOffice и использует только встроенные библиотеки. В связи с чем он может работать на различных платформах (но ещё не проверял :) ).

    DocumentProcessing.zip

    Как использовать:

    uses
      DocumentProcessing;
    
    ...
    
    procedure TForm2.Button1Click(Sender: TObject);
    var
      Document: TDocumentProcessor;
    begin
      Document:= TDocumentProcessor.Create(Self);
    
      Document.FilePath:= 'D:\test.docx';
      Document.Open(TDocumentKind.dkDocx);
      Document.ReplaceText('Familiya', 'Cat');
      Document.Save;
    
      Document.Open('D:\test.odt', TDocumentKind.dkOdt);
      Document.ReplaceText('Familiya', 'Cat', [rfReplaceAll]);
      Document.Save;
    end;

     

    Немного о принципе работы:

    Спойлер

    Думаю стоит немного объяснить принцип работы компонента.

    Дело в том, что в документах одно слово может храниться частями. Часто это бывает, если использовать использовать стили на части слова, например:

    Firemonkey

    В документе данное слово будет разделено на "Fire" и "monkey". Данному компоненту это не помеха, но стоит знать, что при замене вставленное слово будет иметь стиль левой части, т.е. если мы заменим "Firemonkey" на "Delphi", то отображаться он будет следующим образом:

    Delphi

    Проблемы:

    Спойлер

    1. Не знаю как реализовать чувствительность к регистру (связано с использованием функции IndexOf)

     

  2. 9 часов назад, Barbanel сказал:

    Т.е. в коммьюнити эдишн его не будет. Редиски!!! ?

    FMX Linux сторонний компонент и потому, если и будет бесплатным, то не скоро. И хоть он не их продукт, но в последнее время они, почему-то, его активно продвигают

  3. Если кому интересно, то я нашел данные вызовы событий мыши(да и вообще чего угодно) в файлах FMX.Platform.(Win, Android и т.д.). Вызов события происходит сперва у формы, после чего форма уже сама вызывает событие на нужном Control.

  4. В 02.07.2019 в 21:20, krapotkin сказал:

    нет никакой подстраховки)). не надо чудесизировать исполнение программы

    обработчик работает в главном потоке, и наша задача - дать ему с гарантией завершиться! исключительно для этого мы вызываем Synchronize() из другого потока

    программа придет туда не абы когда а только после выполнения всех текущих работ основного потока. То же самое можно достигнуть в windows сделав postMessage()

    Ну и создание объекта подчиняется тем же условиям. Если он РЕАЛЬНО не удалился, то самостоятельно убив его через DisposeOf, мы получим с большой вероятностью AV из-за того, что где-то ссылка на него еще есть!

     

    Перепроверил 3 раза на андроид.

    Первый раз без Sleep:

    TTask.Run(procedure
    begin
      TThread.Synchronize(nil, procedure
      begin
        FBackgroundLayout.Free; //FBackgroundLayout - родительский элемент
      end);
    end);

    Получил Access violation сразу при нажатии на кнопку.


    Второй раз так:

    TTask.Run(procedure
    begin
      Sleep(100);
    
      TThread.Synchronize(nil, procedure
      begin
        FBackgroundLayout.Free;
      end);
    end);

    При первом нажатии исключений нет, но FBackgroundLayout не удаляется(визуально) и соответственно на кнопку можно нажать ещё раз после чего сразу получаем AV, оно и понятно.

     Третий раз, уже основываясь на ваших сообщениях, о том, что нужно везде удалять ссылки, сделал так:

    TTask.Run(procedure
    begin
      Sleep(100);
    
      TThread.Synchronize(nil, procedure
      begin
        FBackgroundLayout.Parent.RemoveObject(FBackgroundLayout);
        FBackgroundLayout.Free;
        FBackgroundLayout:= nil;
      end);
    end);

    И теперь все работает.

     

    В моём случае, необходимости удаления подобным образом не было, поскольку ссылки на тот объект я в своём коде не хранил, а потому способ с DisposeOf работал. Но думаю, третий вариант использовать всё же лучше.

     

    UPD. Сделал четвертую проверку, перечитав ваше сообщение ещё раз) . Убрал поток:

    FBackgroundLayout.Parent.RemoveObject(FBackgroundLayout);
    FBackgroundLayout.Free;
    FBackgroundLayout:= nil;
    //Ну или FreeAndNil(FBackgroundLayout)

    И оно заработало! И без каких-либо ошибок.

     

    UPD 2. Теперь точно всё) Я вспомнил зачем создавал поток и ставил Sleep. Дело в том, что в Windows приложении, если при нажатии на кнопку удалить его сразу, то не будет сообщения о том, что произошло "MouseUp" кнопки, в связи с чем, рамки приложения (т.е. кнопки сворачивание, закрыть и т.д.) не реагируют на нажатия мыши до того, пока не нажмете на "нажимаемый" элемент в самом приложении. И потому 4 вариант не подходит для Windows приложений.

  5. 3 часа назад, krapotkin сказал:

    Вот disposeof чот не очень,  и sleep лишний а в целом норм

    Sleep как подстраховка,  чтобы все "внутренности" обработчика нажатия выполнились. В моём случае, такая задержка не критична и незаметна.

    1 час назад, krapotkin сказал:

    Создал объект - удали ссылки на него и сделай free. Ровно как и всегда

    Я делал так, но если сразу после уничтожение создать в том же контроле объект, то вылетает исключение(было давно, уже не помню какое, что-то типа такой объект уже есть). Поэтому использовал DisposeOf, поскольку он избавляется от объекта сразу.

    UPD. Сейчас перепроверил снова с Free, но почему-то исключение перестало вылетать, даже если не удалять на него ссылку, странно... Может это было на андроид.

    UPD 2. Во The Free and DisposeOf methods under ARC. Точно, это было на андроид :)

  6. Здравствуйте! Дело в том, что сейчас изучаю исходники компонентов и при изучения исходников TControl возник вопрос, а где и кто вызывает обработчики событий манипуляций с мышью, к примеру MouseDown(не OnMouseDown)? Пытался через поиск найти все ссылки на этот метод, но кроме как объявления и реализации этого метода ничего не нашел, т.е. не нашел места где этот метод вызывается.

  7. Я, конечно, извиняюсь за то, что поднимаю старую тему, но все жё к какому решению тут пришли? Довольно не хилое обсуждение шло, но при этом кода мало.

    По поводу Release в Tokyo он стал deprecated. На данный момент использую такое решение, по смыслу схожее с тем, что было в Release:

    TTask.Run(procedure
    begin
      Sleep(100);
    
      TThread.Synchronize(nil, procedure
      begin
        DisposeOf;
      end);
    end);

    Но может есть вариант получше?

  8. При использовании InterBase базы данных на Android у меня всплывает ошибка 'product INTERBASE is not licensed'. Покопавшись в интернете выснил, что нужно получить получить файлы регистрационный файл (reg_ibtogo.txt или reg_iblite.txt ), через сайт https://reg.codegear.com/srs6/activation.do , но я не знаю откуда взять регистрационный номер InterBase.

    Лицензия Delphi у меня Community Edition и в Lincese Manager у меня указан InterBase 2017 ToGo Edition 1 User. Это значит что я могу получить регистрационные файлы?

  9. Добрый день! Наткнулся на такой, вроде как, баг в свойстве GroupName TSpeedButton'а. Если в свойстве задать имя группы(GroupName), а потом убрать и запустить программу, то кнопка будет вести себя так же, как checkbox, т.е., если нажать один раз то isPressed станет равен True, второй раз False. Эта проблему можно решить удалив кнопку и заново создав ее, но хотелось бы узнать почему так происходит и можно ли это как-нибудь исправить?

    Sample.zip

  10. Добрый день! Возникла, довольно-таки, интересная проблема. Если по нажатию на элемент listbox мышью, реализовать всплывающее окно типа ShowMessage, то событие отжатия кнопки на контроле, в котором мы нажали не произойдет. Это заметно, по тому, как после закрытия ShowMessage, навести на listbox, то он продолжит выбирать элемент, также как, если мы это сделали бы удержав кнопку мыши на нем и начали бы проводить курсором по ней. Можно ли как-нибудь исправить это?

  11. wamaco, но тогда его вообще не возможно будет изменить. Мне нужно чтобы при достижении определенного значения ListBox перестал расширятся, а так сужаться он может хоть до 0.

    ZuBy, попробую этот способ. Я уже однажды делал так, но не срабатывало, наверное, потому что у меня был задан Align. 

  12. Как можно задать максимальный размер для компонентов с заданным align? Например, у меня есть Listbox, у него задан align=top и мне нужно, чтобы при достижения определенной ширины, он перестал расширяться.

  13. 3 часа назад, kami сказал:

    Фреймы с разделением логики работы между ними спасут отца русской демократии.

    Спасибо, именно разделение логики  работы мне и нужно было, просто не знал как правильно высказать.

    Тогда возникает другой вопрос. Почему при разработке андроид приложений не используют фреймы, а создают новую форму?

  14. Как лучше реализовать многодокументное приложение в Firemonkey? Я знаю, что это форма внутри формы(MDI), но читая об этом в интернете, узнал, что Microsoft не рекомендует этого делать. Если не рекомендует, значит есть какая-то причина и хотелось бы узнать почему. Есть какие-нибудь альтернативные варианты? Просто не хочется перегружать код, переходами между Layout или Panel.

×
×
  • Создать...