Блог Александра Божко
Архивы
Рубрики

Delphi

К сожалению, времени на всё запланированное банально не хватает. Смена хостера, обновление движка Delphifeeds и многое другое. Тем не менее, начал писать подробный мануал по созданию полноценного мобильного приложения и даже собрал команду болельщиков в этом начинании. Но быстро сказка сказывается, да не быстро дело делается. А пока решил сделать несколько постов в новую рубрику. Как следует из названия, здесь будут публиковаться “зарубки на память”, небольшие лайфхаки и прочие материалы, которые назвать оригинальными можно с натяжкой, но под рукой иметь полезно. Для начала маленький лайфхак для начинающих разработчиков.

Представьте, что в режиме проектирования вам нужно клонировать на форме какой-то сложный объект, например, DataSet. Казалось бы всё просто. Выделяете объект и копируете его в буфер обмена (Ctrl+C). Затем вставляете его на форму и переименовываете новый объект. Но здесь есть один не совсем приятный момент. Если мы откроем редактор полей, то обнаружим, что поля вновь созданного объекта не имеют осмысленных названий, а называются примерно так, как показано на рисунке.

Кроме типа поля из названия смысловой информации мы не получим. Конечно, в данном случае есть простое решение. Удаляем все поля, затем копируем все поля из исходного DataSet’а и вставляем в новый DataSet. Все поля приобретут осмысленные названия. которые мы сможем использовать в коде.

Но что делать, если копирование полей не поддерживается, как, например в TdxMemData от DevExpress? Конечно, можно создать заново все поля вручную, но значительно проще отредактировать код формы. Для этого я использую Notepad++. В принципе подойдёт любой редактор, с поддержкой глобальной замены текста. Всё просто. В Delphi IDE мы выбираем текстовое представление формы. Копируем и переносим код интересующего нас объекта вместе с вложенными объектами в редактор и производим замену по шаблону. После этого вставляем код нового объекта в исходный код формы. Что бы не возиться с описаниями объекта в pas-модуле, просто вырежьте и снова вставьте его на форму.

Технология App Tethering появилась еще в прошлой версии Delphi. И рассказать о ней я собирался еще после выхода XE6, однако, как это часто бывает “не дошли руки”. Этот механизм предназначен для взаимодействия приложений на разных устройствах. Примечательно, что он поддерживается как в VCL, так и в FireMonkey. В XE7 в App Tethering были добавлены новые возможности, что для меня стало очередным поводом разобраться и сделать пару примеров. Обдумывать идеи для тестового приложения долго не пришлось. Так получилось, что сейчас у меня на рабочем столе  стоит два ПК и, время от времени появляется планшет и смартфон (оба под управлением Android). Работаю я с этими устройствами практически одинаково интенсивно и, соответственно, возникает необходимость оперативно обмениваться не только файлами, но и текстовыми фрагментами, ссылками и т. д.. Конечно, существуют сотни программ, решающих это задачу, но коль скоро у нас имеется инструмент, то грех не написать собственное приложение, реализующее данный функционал.

В идеале мне бы хотелось бы создать некоторое приложение, работающее как под Windows, так и под Android, которое позволяло бы:

  • осуществлять обмен файлами между устройствами;
  • осуществлять обмен содержимым буфера обмена.

При этом хотелось бы исключить сложную процедуру настройки соединения для различных устройств.

Поскольку изобилия русскоязычных материалов по App Tethering пока не наблюдается, я буду перемежать рассказ о процессе разработки приложения  выдержками из документации.

Разработку начнем с реализации простейшего функцонала – обмена файлами между ПК. Для того, что бы упростить понимание принципов работы App Tethering создадим два приложения – приложение, передающее файлы (“передатчик”) и приложение, принимающее файлы (“приемник”). Во избежание путанницы я сознательно не стану использовать термины “клиент”, “сервер” и т.д. “Передатчик” реализуем на VCL, а “приемник” – на FireMonkey. Опять же все это из соображений наглядности. В идеале это должно быть одно мультиплатформенное приложение, совмещающее в себе функции приема и передачи файлов. К этому вопросу, надеюсь, мы вернемся чуть позже.

Итак создадим два приложения,VCL и FireMonkey(Multi-device application), назовем их PrjSender и PrjReceiver и объеденим их в одной группе проектов. Механизм App Tethering в Delphi реализуют всего два компонента TTetheringManager и TTetheringAppProfile  (менеджер и профиль). Размещаем их на главной (и пока единственной) форме обоих приложений. В обоих случаях для TetheringAppProfile устанавливаем значение свойства TetheringManager – TetheringManager1, таким образом связываем менеджер с профилем.

Для чего нужны эти компоненты? Документация гласит следующее:

Менеджер может обнаруживать и попарно связываться с другими менеджерами, представляющие удаленные профили, которые могут “расшаривать” данные для зарегистрированных профилей вашего менеджера. Менеджер может быть связан с одним или несколькими профилями. Основные функции менеджера:

  • Менеджер использует адаптеры, для поиска других менеджеров. Например, менеджер использует сетевой адаптер для подключения к другим менеджерам по сети;
  • Менеджер устанавливает связь с удаленными менеджерами (сопряжение);
  • Два парных менеджера позволяют своим профилям узнать о профилях других менеджеров, таким образом профили могут обмениваться данными друг с другом;
  • Менеджер предоставляет информацию от своих адаптеров протоколам своих профилей таким образом, что бы эти профили могли обмениваться данными друг с другом, используя собственные протоколы.

Все это звучит немного сумбурно, но попробуем разобраться во всем на практике. Прежде всего, нам нужно обеспечить соединение между двумя приложениями. В верхней части главной формы приложения-приемника разместим компонент ListBox (lbSenders) и кнопку (btnGetAvailableSenders). По нажатию на кнопку отобразим список доступных удаленных менеджеров. Для этого определим обработчик события OnEndManagersDiscovery следующим образом:

procedure TfRecMain.TetheringManager1EndManagersDiscovery(const Sender: TObject;
  const ARemoteManagers: TTetheringManagerInfoList);
var
  I: Integer;
begin
 lbSenders.Clear;

 for I := 0 to aRemoteManagers.Count - 1 do
 begin
  lbSenders.Items.Add(ARemoteManagers[i].ManagerText);
 end;

end;

А по нажатию на кнопку вызовем метод DiscoverManagers компонента TetheringManager.

procedure TfRecMain.btnGetavailableSendersClick(Sender: TObject);
var
i: integer;
begin
  for I := TetheringManager1.PairedManagers.Count - 1 downto 0 do
    TetheringManager1.UnPairManager(TetheringManager1.PairedManagers[I]);

  lbSenders.Clear;
  TetheringManager1.DiscoverManagers;

end;

Предварительно здесь мы очищаем список и разрываем все связи (метод UnPairManager). Читать далее

Пост шпаргалка. Если вы обладатель Delphi XE6 или Delphi XE7, вам не нужно делать каких-то хитрых телодвижений, для того, создания кнопок на панели, соответствующей приложению в TaskBar‘е. Вы можете воспользоваться компонентом TTaskBar и, таким образом, решить все проблемы. Но, что делать, пользователям Delphi предыдущих версий (попутно напомню,  что при покупке последней версии Delphi вы получаете ключи ко всем предыдущим версиям, начиная с Delphi 7)?

У Боба Сворта есть довольно подробный солюшн, но я нашел в нем некоторые неточности. Ниже приведу свою, немного модифицированную версию данного решения.

Создание TaskbarList‘а ничем особо не отличается. Этот код будет работать и в Windows 7 и в Windows 8:

 

  procedure CreateTaskBarList();
  begin
      TaskbarList := CreateComObject(CLSID_TaskbarList) as ITaskbarList;
      TaskbarList.HrInit;
      Supports(TaskbarList, IID_ITaskbarList2, TaskbarList2);
      Supports(TaskbarList, IID_ITaskbarList3, TaskbarList3);
      Supports(TaskbarList, IID_ITaskbarList4, TaskbarList4);

    if not Application.MainFormOnTaskBar then
      FormHandle := Application.Handle
    else FormHandle := Application.MainForm.Handle;

      TaskbarList3.ThumbBarSetImageList(FormHandle, FMain.ImageList2.Handle);
  end;

Естественно, предварительно нужно проверить версию Windows (она должна быть не ниже 7). Я делаю это так же как и Dr. Bob:

  NeedCreateTBwButtons:= ((Win32MajorVersion=6) and (Win32MinorVersion>0)) or (Win32MajorVersion>6);

В надежде на то, что в последующих версиях Windows этот функционал никуда не денется. Ниже приведены значения переменных для существующих версий системы.

Win32MajorVersion Win32MinorVersion
6
  • Windows 8 (version 6.2)
  • Windows 7 (version 6.1)
  • Windows Vista (version 6.0)
5
  • Windows XP (version 5.1)
  • Windows 2000 (version 5.0)

А вот с кнопками на панели все не так просто. То, что показано в исходном примере работать будет. Но только для случая с одной кнопкой. Если внимательно почитать документацию, то в качестве параметра для метода ThumbBarAddButtons передается ссылка на массив THUMBBUTTON, а не на отдельную кнопку. Максимальное количество элементов в массиве – 7. Массив должен быть статическим.

Я описал его так:

ThbButtons: array [0..3] of TThumbButton;

Соответственно, кнопки я создаю следующим образом:

    ThbButtons[0].iId := 42;
    ThbButtons[0].iBitmap := 0;
    ThbButtons[0].dwMask := THB_FLAGS or THB_BITMAP or THB_TOOLTIP;
    ThbButtons[0].dwFlags :=  THBF_ENABLED;

    StrCopy(ThbButtons[0].szTip, PChar('Start Timer'));

    ThbButtons[1].iId := 43;
    ThbButtons[1].iBitmap := 1;

    ThbButtons[1].dwMask := THB_FLAGS or THB_BITMAP or THB_TOOLTIP;
    ThbButtons[1].dwFlags :=  THBF_ENABLED;

    StrCopy(ThbButtons[1].szTip, PChar('Pause Timer'));

    ThbButtons[2].iId := 44;
    ThbButtons[2].iBitmap := 2;

    ThbButtons[2].dwMask := THB_FLAGS or THB_BITMAP or THB_TOOLTIP;
    ThbButtons[2].dwFlags :=  THBF_ENABLED ;

    StrCopy(ThbButtons[2].szTip, PChar('Stop Timer'));

    ThbButtons[3].iId := 45;
    ThbButtons[3].iBitmap := 3;

    ThbButtons[3].dwMask := THB_FLAGS or THB_BITMAP or THB_TOOLTIP;
    ThbButtons[3].dwFlags :=  THBF_ENABLED;

    StrCopy(ThbButtons[3].szTip, PChar('Cancel'));

    TaskbarList3.ThumbBarAddButtons(FormHandle, 4, @ThbButtons);

Значения флагов, что называется “dwFlags”, не буду здесь их перечислять, для этого есть документация.

Как вы, наверное, уже догадались, здесь я реализовал кнопки  таймера. Обработчик события нажатия кнопок можно реализовать так. как и в базовом примере (отловить сообщение WM_COMMAND). В демонстрационном примере он у меня сработал, а вот в реальном приложении, – почему-то нет. Вероятно, где-то что-то перекрывается. Я не слишком огорчился сему факту, и использовал событие OnMessage компонента ApplicationEvents.

Получилось примерно так: Читать далее

В своем блоге Александр Бондарь публикует своего рода методические пособие по RAD Studio. Дело это, безусловно, полезное с точки зрения популяризации Delphi, поэтому этот блог и включен в ленту новостей Delphifeeds.Ru. Хотя, наверняка, для большинства читателей сайта, работающих с Delphi/C++ Builder на практике, в этих постах интересного мало. В свое время у меня был некоторый педагогический опыт и опыт написания методических пособий. К сожалению, с тех пор минуло довольно много времени и найти их я не смог. Но на волне ностальгии, меня посетила мысль в своем блоге дополнить данное пособие, парочкой интересных,  на мой взгляд, кейсов. Не думаю, что для профессионалов здесь будут какие-то откровения, но для “продвинутых” студентов это может быть интересно.

Этимология форм

Если говорить о формах, то весьма важно разобраться с их сущностью. Понятно, что речь идет об объекте, но объект этот не совсем обычный. Начальные значения его свойств хранятся в специальных файлах форм. В случае VCL они имеют расширение *.dfm, если речь идет о FireMonkey, то *.fmx. Данные файлы можно отредактировать, как с использованием IDE, так и в обычном текстовом редакторе. В первом случае, достаточно в редакторе форм из контекстного меню выбрать пункт View as Text. Во втором случае следует найти файл с именем модуля, содержащего форму и расширением *.dfm или  *.fmx, и открыть его в текстовом редакторе. После этого, можно поменять какое-либо из свойств формы, например, Caption и, вернувшись в редактор формы,  посмотреть как изменится внешний вид формы. Заодно и поэкспериментировать с кодировками. Читать далее

До Нового года осталось совсем немного, и к новогодне-рождественским праздникам, как вы, наверняка, знаете, компания Embarcadero приготовила чудесные подарки для покупателей своих продуктов. Подробнее о праздничных акциях компании написано здесь. Но совершенно недавно, компания объявила еще об одном подарке для Delphi разработчиков.

Книга – лучший подарок! Этот лозунг, рожденный во времена книжного дефицита, пожалуй, актуален на все времена. Конечно, если книга стоящая. А, на мой взгляд, именно таковой является Coding In Delphi Ника Ходжеса. Думаю, сам автор в представлениях особо не нуждается, и его имя под текстом говорит о многом.

Что касается непосредственно книги, то в отличии от большинства Delphi-книг, это не учебник, рассказывающий о возможностях продукта и их использовании. Это книга о языке Delphi. Именно о языке и грамотном применении языковых конструкций Coding In Delphi. Думаю, этот труд будет полезен как начинающим, так и опытным разработчикам. Особенно, с учетом того, что язык Delphi со времен Delphi 7 довольно серьезно обновился и начал поддерживать абсолютно новые языковые конструкции (например, дженерики, анонимные методы и т.д.).

Но ценность книги заключается даже не в том, что в ней довольно подробно описаны практики применения тех или иных языковых возможностей, а, скорее в том, что книга учит осознано создавать грамотный код. Учит именно тому, что отличает программирование от “формошлепства”, которым почему-то так часто попрекают Delphi-разработчиков.

Естественно, книга англоязычная, но если соберется сообщество энтузиастов, я с удовольствием бы принял участие в ее переводе на русский.

Для тех, кто хочет получить эту книгу уже сейчас – достаточно купить Delphi XE5.

 

Еще при подготовке к харьковскому мероприятию в рамках Мирового тура RAD Studio XE5 я столкнулся с небольшой проблемой в работе с SQLite с помощью FireDAC. Если заполненную в Windows приложении базу перенести вместе с приложением на Android, кириллические строки в базе перестают читаться (вместо букв отображаются знаки вопроса). Однако, если заполнять базу непосредственно на мобильном устройстве, русские символы считываются вполне корректно. Данные из базы заполненной в стороннем приложении, или в Delphi приложении, использующем другие компоненты доступа к данным, так же отображались нормально. Слету найти решения не удалось, и мне пришлось процитировать известного украинского футбольного специалиста: “Будем разбираться!”

В отличие от последнего, разобраться с описанной проблемой мне удалось. По умолчанию при подключении к SQLite в FireDAC используется формат строк ANSI.

Если принудительно установить Unicode, то все будет работать как надо. Но есть и неприятный момент. Изменив формат строк придется во всех наборах данных пересоздать список полей, а так же заново подключить компоненты, отвечающие за отображение и ввод данных. Поэтому лучше позаботиться о кодировке сразу.

 

Делу время, а потехе час. Это я к тому, что помимо исследований Delphi для Android (а вы уже тестируете бету?) есть работа, которую нужно делать.  За сим, очередной пост-шпаргалка, возможно, кому-нибудь пригодится.

В коде моих проектов имеется множество функций, подобных, приведенной ниже.

function TFMain.ExtDescrExists(): Boolean;
var
 qry: TADOQuery;
begin
 Result:= True;
 try
 qry:= TADOQuery.Create(Self);
 qry.Connection:= DM.cnDatabase;
 qry.SQL.Add('SELECT ExpenseID FROM tblProjectExpenses WHERE ExpenseDescription<>NULL');

 qry.Open;
 if qry.IsEmpty then
 begin
  Result:= False;
 end;
 qry.Close;
 finally
 FreeAndNil(qry);
 end;

end;

Откровенно говоря, подобный код мне не особо нравится, прежде всего из-за громоздкости. Обратите внимание на рисунок:

237matches

Необходимость повторного использования кода в данном случае очевидна. Однако, сделать универсальное решение не совсем просто, поскольку в некоторых случаях проверяется наличие записей в таблице, в других – требуется извлечь значения различных типов. Чтобы решить эту задачу, я набросал небольшой класс: Читать далее

К сожалению, до сих пор опубликовано довольно мало материалов, посвященных практической работе в FireMonkey. Даже не смотря на то, что недавно была выпущена третья версия платформы и “новой” ее можно назвать с натяжкой. В данной серии постов мне хотелось бы детально описать полный цикл создания FireMonkey приложения, работающего с базой данных. Я преследую сразу две цели. Во-первых, создать пример для начинающих. Во-вторых, показать реальные возможности FireMonkey в том виде, в котором платформа существует сейчас.

Купить Delphi XE4 у официального реселлера. Скидка до 30-го июня

Купить Delphi XE4 у официального реселлера. Скидка до 30-го июня

Выбор средств разработки

Исходя из означенных целей, я буду использовать Delphi XE4 в качестве средства разработки.  SQLite в качестве СУБД.  Для доступа к данным – FireDAC, который совсем недавно появился в составе Delphi. В качестве средства инструмента для управления БД SQLiteSQLite Administrator (по рекомендации Владислава Баженова, в блоге которого вы можете найти достаточно материалов по работе с SQLite в Delphi). Читать далее

На прошлой неделе я стал обладателем Enterprise редакции FastReport. И в сегодняшнем посте хочу немного рассказать о возможностях старших редакций флагмана мирового отчетостроения.

Прежде всего, хочу отметить, что продукт великолепно документирован. Особенно приятно, что имеется  документация и на русском  языке. Три объемных руководства (пользователя, программиста и разработчика) дополнены обширным набором примеров, который обеспечивает «лёгкое вхождение» в продукт.

Для многих программистов FastReport стал основным средством построения отчетов в Delphi еще до появления  Embarcadero редакции. Редакция, вошедшая в состав RAD Studio, конечноимеет свои ограничения, но, тем не менее, предоставляет весь тот базовый набор функций, который был у предшественников. Я имею ввиду Rave Report и Quick Report, которые были «родными» для более ранних версий Delphi и C++ Builder. Впрочем, к моменту выхода Delphi XE2 мало кто пользовался этими средствами построения отчетов, по крайней мере, для новых проектов.

В свое время  я, как и многие, оказался непосредственно вовлечен в процесс перевода старого проекта на новую систему построения отчетов. Правда, на тот момент я использовал Basic Edition. Собственно, я уже писал о том, как можно «малой кровью» портировать отчет с Rave на FastReport. К слову, подобным образом поддерживается переход и с других устаревших систем построения отчетов, в частности  Quick Reports и Report Builder.

В этом обзоре я хочу рассказать, что же не вошло в Embarcadero редакцию FastReport.

Итак, кроме редакции, поставляемой в комплекте с Delphi/C++ Builder существует еще четыре варианта комплектации продукта – Basic, Standard, Professional и Enterpriseю Сразу приведу ссылку на сводную таблицу функционала в зависимости от редакции и немного прокомментирую  представленные в ней возможности. Читать далее

Вчера мне пришло письмо примерно следующего содержания.

Будьте  добры,  подскажите пожалуйста, пакеты обновлений на Delphi XE2 ставятся  последовательно,  т.е.  Upd1  затем  Upd2… или можно сразу ставить  четвертый  фикс?  У  вас  в  блоге   я, к сожалению, данной информации не нашел.

Я решил продублировать ответ на данный вопрос в блоге.

Обновления нужно ставить последовательно. В некоторых случаях, обновления требуют полной переустановки продукта. А лучше всего прочесть Release Note перед обновлением!
Но,   если  вы  устанавливаете  Delphi  с  образа  на  сайте,  читайте внимательно какие апдейты уже включены в установочный пакет.

Например, сейчас на EDN для зарегистрированных пользователей выложен следующий образ:

Delphi XE3 and C++Builder XE3 ISO (includes Update 1)

ISO for Delphi XE3 and C++Builder XE3 (this is one of multiple ISOs that make up RAD Studio XE3) (includes Update 1)

Как видите, в этот образ уже включен первый апдейт (не путайте с хотфиксами, которые включены в апдейт).
Если  же  Вы  пользуетесь  онлайн  установщиком,  то  как правило, все апдейты станут автоматически.

В  любом  случае,  в  комплекте  Delphi  поставляется утилита Check For Updates. Она сама вам расскажет, что нужно установить. Это официально рекомендованный вариант.

Если у вас возникли вопросы, связанные с лицензированием или использованием приобретенных продуктов Embarcadero – мои контакты на сайте http://delphixe.com.ua/. Буду рад помочь.

 

Продукты DevArt
Купить онлайн:



Читай русскоязычные Delphi блоги
Каталог блогов Blogdir.ru
Яндекс.Метрика