Коррекция шрифта в Object Inspector’е

Пробую Delphi XE7. Пока нравится. Поставил GExperts – очень уж я привык к сочетаниям Ctrl+Alt+Down и Ctrl+Alt+Up – переход к следующему/предыдущему объявлению идентификатора. CnPackWizards пока не вышел, но и без него вполне можно жить.
И тут вдруг бросилось в глаза, что у Object Inspector’а шрифт не такой, как везде… (везде – Tahoma 8, а тут – Segoe UI 9)
В GExperts вроде и была возможность менять шрифт инспектора, но почему-то пропала. Поэтому “накидал” на скорую руку пакет, исправляющий данную особенность, результат на картинке (было – стало):
image
Исходник пакета доступен на GitHub, или можно скачать zip-архив отсюда – в  папке ObjInspFntChngr. В модуле uObjInspFntChngr.pas через константы:

const
  PreferParentFont = True;
  PreferFontName = 'Tahoma';
  PreferFontSize = 8;

можно настроить шрифт по своему вкусу.

HINT: Возможно пакет поможет тем, у кого масштабирование текста в Windows больше 100%.

Для установки – открыть dproj-файл, правой кнопкой мыши в Project Manager’е – Install. Пакет можно использовать и в предыдущих версиях Delphi, для этого достаточно удалить dproj-файл и открыть пакет через dpk-файл.

Читать на сайте автора.

Helper для TMessage

В предыдущей заметке я упомянул о хелпере для отладки сообщений Windows. Эта заметка будет предельно краткой: ссылки на исходники и скриншот демки.

Исходник: модуль MsgHlpr.pas. Использовать можно так:

procedure TfrmMain.ApplicationEvents1Message(var Msg: TMsg; var Handled: Boolean);
begin
  Memo1.Lines.Add(Msg.ToString);
..

Демо-приложение:

image

Скачать: MsgHlpr.pas + демо — zip-архив, MsgHlpr.pas на GitHub, исходник демо на GitHub, исполняемый exe-файл демки (zip-архив, 447 КБ).

Работает в Delphi 2010 и выше, при желании легко адаптировать и к предыдущим версиям Delphi.

Читать на сайте автора.

Используем макросы в IDE-редакторе Delphi

Занимаясь отладкой процедур, связанных с обработкой сообщений, постоянно приходится делать сопоставление между кодом сообщения и его строковым наименованием. Ну, к примеру, «прилетает» код 6 — это WM_ACTIVATE. Или сложнее: код 274 (0x0112) = WM_SYSCOMMAND.

Мне это порядком надоело — решил сделать Helper для TMessage (попутно и для TMsg). Ну и в планах попробовать сделать Debugger Visualizer.
Однако о самом хелпере я постараюсь написать в следующий раз. В этой заметке хочу описать, как можно использовать кнопочки Record Macro и Playback Macro, которые находятся в левом нижнем углу строки состояния редактора кода.

(Кстати, мне впервые в жизни пришло в голову попробовать их использовать.)

Итак, я хочу получить код вида:
  case Msg of
    WM_NULL: Result := 'WM_NULL';
    WM_CREATE: Result := 'WM_CREATE';
    ...
    WM_APP: Result := 'WM_APP';
  end;

Идём в модуль Messages и копируем оттуда код:
  {$EXTERNALSYM WM_NULL}
  WM_NULL             = $0000;
  {$EXTERNALSYM WM_CREATE}
  WM_CREATE           = $0001;
  ...
  {$EXTERNALSYM WM_APP}
  WM_APP = $8000;

Вставляем в новый модуль и начинаем макрос. По шагам:
  1. Нажимаю Ctrl+F (Панель поиска), указываю пробел, снимаю все флажки. Enter — чтобы запомнилось.
  2. Устанавливаю курсор на первой строке, нажимаю «Record Macro»:.
  3. Ctrl+Y — удаляем строку
  4. Ctrl+Вправо — курсор к началу идентификатора
  5. F3 — поиск до пробела
  6. Влево — курсор к концу идентификатора
  7. Ctrl+Shift+Влево — выделили идентификатор
  8. Ctrl+C — скопировали выделенное в буфер обмена
  9. Повторяем 5. и 6. — курсор к концу идентификатора
  10. Shift+End — выделение до конца строки
  11. Delete — удаляем выделенное
  12. Набираем на клавиатуре
    : Result := ‘
  13. Ctrl+V — вставили скопированное
  14. Набираем на клавиатуре
    ‘;
  15. Home — переход к началу строки
  16. Вниз — переход к следующей строке
  17. Нажимаю «Stop Recording Macro»:.
Макрос готов, теперь просто жамкаем в «Playback Macro»
пока не достигнем нужного результата.

Читать на сайте автора.

Для расовых ненавистников "with"

Коим я являюсь (ненавистником with)

Добрые люди предложили замену:

(procedure (A: TObject)

  begin
    A.Free;
  end)(TObject.Create);

Читать на сайте автора.

Простой текстовый итератор. Пример использования record в Delphi

Задача: осуществить перебор строковых значений в исходной строке, разделённых символом-разделителем, с учётом символа-кавычки.
Решение:

unit dnStringIterator;

interface

type
  TStringValuesIterator = record
  type
    TCallBack = reference to procedure (const AValue: string);
    TOptions = set of (ioTrimValues, ioDequoteValues);
  private
    FSourceString: string;
    FDelimiter, FQuoteChar: Char;
    FCheckQuotes: Boolean;
    FOptions: TOptions;
    FOffset, FLength: Integer;
    FCurrent: string;
  public
    constructor Init(const ASourceString: string; ADelimiter: Char; AQuoteChar: Char = #0; AOptions: TOptions = []);
    function GetEnumerator: TStringValuesIterator;
    function MoveNext: Boolean;
    procedure Run(ACallBack: TCallBack); inline;
    property Current: string read FCurrent;
  end;

implementation

uses
  SysUtils;

{ TStringValuesIterator }

constructor TStringValuesIterator.Init(const ASourceString: string; ADelimiter, AQuoteChar: Char; AOptions: TOptions);
begin
  FSourceString := ASourceString;
  FDelimiter := ADelimiter;
  FQuoteChar := AQuoteChar;
  FOffset := 1;
  FLength := Length(FSourceString);
  FOptions := AOptions;
  FCurrent := '';

  FCheckQuotes := FQuoteChar <> #0;

  // нельзя, чтобы символ разделитель совпадал с символом-кавычкой:
  Assert(not FCheckQuotes or (FDelimiter <> FQuoteChar));
  // нельзя использовать ioDeqouteValues, если не указан QuoteChar
  Assert(FCheckQuotes or not (ioDequoteValues in FOptions));
end;

function TStringValuesIterator.GetEnumerator: TStringValuesIterator;
begin
  Result := Self;
end;

function TStringValuesIterator.MoveNext: Boolean;
var
  IsInQuote: Boolean;
  CurPos: Integer;
  Ch: Char;
begin
  Result := (FLength > 0) and (FOffset 

Примеры использования

С явным объявлением дополнительной переменной:
var
  svi: TStringValuesIterator;
begin
  svi.Init(TestString, ',');
  while svi.MoveNext do
    Memo1.Lines.Add(svi.Current);
end;

Без явного объявления дополнительной переменной, используя with:

begin
  with TStringValuesIterator.Init(TestString, ',') do
    while MoveNext do
      Memo1.Lines.Add(Current);
end;

Используя анонимную процедуру:

begin
  TStringValuesIterator.Init(TestString, ',').Run(
    procedure (const AValue: string)
    begin
      Memo1.Lines.Add(AValue);
    end
  );
end;

Используя for-in синтаксис:

var
  Tmp: string;
begin
  for Tmp in TStringValuesIterator.Init(TestString, ',') do
    Memo1.Lines.Add(Tmp);
end;

Читать на сайте автора.

Калькулятор восхода солнца, заката и истинного полудня

Читать на сайте автора.

Отправка сообщений в Microsoft Outlook. Скрытие окон безопасности

Всем доброго времени суток дорогие читатели блога. Давно я ничего не писал в блог, на этот раз решил исправиться. Передо мной стала задача разработать систему заявок на одном предприятии. Так вот, в одном приложении мне необходимо было сделать, чтобы копия заявки приходила на электронный адрес исполнителя. Все система моя работает на MS SQL Server, электронные адреса исполнителей хранятся там же.

На предприятии у нас работает Microsoft Outlook (установлен сервер) и соответственно на каждом рабочем месте свой клиент с учетной записью. Программа должна записывать заявку в базу данных, а копию отправлять по электронной почте, подключаясь к почтовому ящику пользователя (под его учетной записью, то есть, от его имени).

В принципе тут ничего сложного нет, можно для этих целей использовать MAPI, но минус в этом заключается в том, что когда используется MAPI, то пользователю показывается сообщение о том, что к Вашему ящику пытаются получить доступ, это может быть вредоносное ПО и так далее. Эта лишняя информация для пользователя (в моем случае), потому что они начнут паниковать, когда будут составлять заявку, будут звонить, что вредоносное ПО и так далее. Мне пришлось решать проблему по поводу скрытия данного уведомления. На предприятии у нас используется Microsoft Outlook 2003, поэтому в настройках безопасности там нельзя было выключить данный пункт, по крайней мере, я не знал, как это сделать.

Программа установлена более чем на 100 компьютерах. На некоторых компьютерах мне удалось решить данную проблему при помощи установки Microsoft Outlook Express, так как там имеется пункт по поводу отключения безопасности. В этом случае, отправка сообщений производится в фоном режиме, то есть, пользователю не придется нажимать на кнопку Да, что якобы какое-то программное обеспечение пытается получить доступ к учетной записи в электронной почте. На остальные компьютерах по прежнему был установлен Microsoft Outlook 2003 и там никак нельзя было менять его на более низкую версию. Полазив немного в Интернете, я нашел довольно интересную программу, которая называется ClickYes.

Программа очень полезная и интересная, по крайней мере, в моих целях она мне очень пригодилась. Но один ее очень большой минус – это то, что она является платной. Как Вам сказать платной, есть более ранние версии программы – они бесплатны, а уже новые версии, начиная с 2010 года – уже платные. На нее имеется тестовый период в 30 дней. Программа ClickYes предназначена для того, чтобы скрывать это самое окно безопасности в Microsoft Outlook.

Бесплатные версии его не скрывают, а просто нажимают на кнопку Да, в течение 10 секунд, то есть, пользователь видит это окно все равно и может сам нажать на него в течение 10 секунд, что касается версии с 2010 года (платная версия), то она полностью скрывает это окно безопасности и пользователь его вообще не видит. Конечно, можно было что-то подобное реализовать у себя, но я стал искать простой способ.

Этот способ заключался в том, что я возвращаю на все компьютеры версию Outlook до 2003 (Microsoft Outlook Express), а на сервере (где установлена база данных и серверная часть программы) устанавливаю Microsoft Outlook Express. С сервера и будет отправляться копия заявки на нужные адресаты (за это будет отвечать серверная часть программы). Так как в Outlook Express можно в настройках отключить уведомления безопасности, то я решил таким способом. Насколько я знаю, что в более старших версиях OutLook (после 2003) тоже можно отключать данные уведомления.

Самый простой способ – это установить Outlook Express на сервер и с него отправлять электронную почту на любые адреса (без разницы какой там будет установлен Outlook).

На сервере можно использовать следующий способ отправки сообщений при помощи MAPI:

procedure TForm3.Button2Click(Sender: TObject);
var
   lMail: TMapiControl;
begin
   try
      RichEdit2.Lines.Add('текст письма');
      lMail := TMapiControl.Create(Self);
       lMail.Reset;
       lMail.Recipients.Add(PChar('адресаты');
       lMail.Subject:='Заявка от: '+Ini.ReadString('Authorization','login','');
       lMail.Body:=RichEdit2.Text;
       lMail.ShowDialog:=False; //Показывать перед отправкой диалог мейл-клиента по умолчанию или нет.
     lMail.Sendmail;
    lMail.Free;
   except
    on e:Exception do
   end;
end;

Не забудьте в usesподключить модуль MAPI. Что касается адресатов, то можно отправлять сразу нескольким, тогда Вам придется каждого указывать через точку запятой. Думаю, что тут все понятно, особо ничего сложного нет.

Подведем итоги: если Вам требуется отправить письмо из своей программы при помощи клиента Microsoft Outlook и чтобы не появлялось окно безопасности, то можно воспользоваться версией Outlook Express (необходимо в настройках безопасности будет выставить), либо же другие версии, где эти уведомления отключаются. Можете разработать функционал, который сам будет скрывать данные окна (нажимать на нужные кнопки). Можете использовать сервер отправки сообщений, как я привел выше, а можете использовать программу ClickYes, которая очень мне понравилась, причем она не слишком дорогая. В конце я прикладываю скриншот одного модуля своей системы заявок, из которого осуществляется отправка электронной почты:

modul_zayv

Кстати, еще очень удобно отправлять сообщения из Outlook Express, так как она понимает HTML-разметку, и Вы с легкостью можете формировать внешний вид своего сообщения как Вам захочется. Это еще один плюс в пользу того, что лучше использовать Outlook Expres sна том же самом сервере. Не забудьте посмотреть статью про MAPI, там тоже имеется полезная информация.

Читать на сайте автора.

9. События формы. Лабораторные Delphi, C++ (5)

Основные события формы в Delphi и C++Builder

Здесь будут исследованы события формы, связанные с появлением формы на экране, переключением между формами одного приложения, закрытием и изменениями размера формы:

Читать на сайте автора.

8. События формы

Наиболее важные события формы представлены в следующей таблице.

Таблица 1. Основные события формы

Событие

Описание

OnActivate

Возникает после того, как форма становится активной — при первоначальном запуске приложения или когда форма после потери фокуса при перемещении фокуса к другой форме того же приложения вновь получает фокус.

OnClick

Возникает, когда пользователь щелкает левой кнопкой мыши по форме. Появляется после события OnMouseDown. Событие будет отправлено приложению лишь после того, как пользователь отпустит кнопку мыши.

OnClose

Возникает непосредственно перед закрытием формы, после события OnCloseQuery.

OnCloseQuery

Возникает до закрытия формы перед событием OnClose. В обработчике этого события можно на основании действий пользователя разрешить или отменить закрытие формы. Обработчику события передается параметр CanClose типа Boolean. Чтобы отменить закрытие формы свойству CanClose следует присвоить значение False. Значением по умолчанию является True — форма будет закрыта.

OnCreate

Возникает всего один раз в момент создания формы. Предшествует событиям OnShow и OnActivate.

OnDeactivate

Возникает при деактивации формы — при потере фокуса, когда клиент переключается на другую форму того же приложения.

OnDblClick

Возникает, когда пользователь дважды щелкает левой кнопкой мыши по форме. В этом случае порядок появления событий следующий:

·  OnMouseDown

·  OnClick

·  OnMouseUp

·  OnDblClick

·  OnMouseDown

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

OnKeyDown

Возникает при нажатии пользователем на клавиатуре любой клавиши, включая ту, которая не вводит никаких символов (Ctrl, Shift, Alt и т.д.). Предшествует событию OnKeyPress.

OnKeyPress

Возникает при нажатии пользователем на клавиатуре клавиши, которая позволяет ввести отображаемый символ. Происходит сразу после OnKeyDown.

OnKeyUp

Возникает, когда пользователь отпускает нажатую клавишу, включая ту, которая не вводит никаких символов (Ctrl, Shift, Alt и т.д.). Происходит после событий OnKeyDown и OnKeyPress.

OnMouseDown

Возникает, когда пользователь нажимает на форме любую кнопку мыши. Предшествует событию OnClick.

OnMouseEnter

Событие происходит, когда пользователь переводит указатель мыши на поверхность формы — перемещая его с другого компонента формы или из-за пределов формы.

OnMouseLeave

Возникает, когда указатель мыши покидает форму.

OnMouseMove

Возникает, когда указатель мыши перемещается на форме.

OnMouseUp

Событие возникает, когда пользователь нажимает любую кнопку мыши, а потом ее отпускает. Перед этим могут происходить все сопутствующие события.

OnMouseWeel

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

OnMouseWeelDown

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

OnMouseWeelUp

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

OnPaint

Возникает при прорисовке формы, когда размеры формы увеличиваются.

OnResize

Возникает при любом изменении размеров формы как в сторону увеличения, так и в сторону уменьшения.

OnShow

Возникает при начальной загрузке формы перед событием OnActivate, а также в случае, когда форма становится видимой (свойству Visible присваивается значение True).

Читать на сайте автора.

Создаем красивые слайды (слайд-шоу) в своем приложении при помощи PicShow

picshowВсем привет дорогие друзья. Совсем недавно передо мной встала одна проблема: создание слайдов (слайд-шоу) в собственном приложении. Другими словами, необходимо было организовать рекламу из картинок, с различными красивыми переходами, задержкой и так далее.

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

Немного поковырялся в сети Интернет и нашел достаточно интересных вариантов, в том числе как платных, так и бесплатных. Особенно мне приглянулся компонент PicShow, который является бесплатным и имеет в свое вооружении более 176 различных эффектов (переходов между слайдами, картинками). Особых проблем с установкой компонента не было, а также не было и проблем с его работой, ведь в архив с компонентом было отличное демо, представленное разработчиками, по которому можно сделать отличный собственный проект и понять, как компонент PicShow работает.

Начнем со скачивания компонента, а затем его установки. Скачать можно с официального сайта, пройдя по следующей ссылке. С установкой также не должно быть проблем, так как внутри архива (или на сайте) имеется отличная инструкция для установки. Но если все делать по-быстрому, то  заходим Component-Install Component, переходим во вкладку Into new package и там указываем путь к нашим pas-файлам компонента PicShow, после чего устанавливаем как обычный компонент и у нас должна появится новая вкладку Delphi Area, на которой и размещены:

  • TPicShow
  • TDBPicShow

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

PicShow1.StyleName:=’имя эффекта слайда’;
PicShow1.Picture.LoadFromFile(Filenames.Strings[count]);
PicShow1.Execute;

Первой строкой мы задаем имя нашего эффекта слайда, то есть эффект, который будет появляться при смене изображения. Второй строкой мы задаем путь к нашему слайду, то есть изображения, а при помощи последней строки кода, мы запускаем (выполняем) наш слайд. Чтобы это все было эффектно, красиво и с задержкой, данный код следует поместить на таймер и задать ему определенный интервал.

Для получения полного списка эффектов слайдов, можно воспользоваться следующей функцией:

GetStyleNames(Names: TStrings):Integer

Она возвратит список эффектов слайдов, которые Вы можете использовать в своем проекте, чтобы не прописывать их вручную. Кроме этого, можно задавать не имя самого эффекта, а его номер, это делается при помощи свойства Style:TShowStyle.

Как я уже сказал, ничего сложного в этом всем нет. Имеется отличное демо, инструкция по установке, официальный сайт, пример и простой компонент, из которого Вы можете делать эффектные, красивые слайды, примерно следующего формата:

picshow_delphi

Читать на сайте автора.