W8 или не W8 – вот в чем вопрос

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

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

События клавиатуры на форме в Delphi и C++Builder

Запустите на выполнение Delphi или C++Builder. Создайте новый проект, выбрав в меню File | New | VCL Forms Application — Delphi (File | New | VCL Forms Application – C++Builder).
 
 
 
 
 

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

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

События щелчка мышью на форме в Delphi и C++Builder

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

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

Как крутить… — Зубастые планеты.

rouse

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

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

Выложен Lazy Delphi Builder 1.14.14.362 и 364 (альфа)

Выложена версия Lazy Delphi Builder 1.14.14.362. Исправлен Exception при добавлении пути в Lazy Paths. В редакторе IDE search paths исправлены ошибки с подсветкой несуществующих папок.

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

Выложен Lazy Delphi Builder 1.14.14.362 и 364 (альфа)

Выложена версия Lazy Delphi Builder 1.14.14.362.

Исправлен Exception при добавлении пути в Lazy Paths.

В редакторе IDE search paths исправлены ошибки с подсветкой несуществующих папок.

Добавлена новая команда Replace selected with env var (auto) — которая заменяет часть пути на Environment variable (переменные ищутся в Lazy Environment variables и IDE environment variables)

Download
here

Lazy Delphi Builder 1.14.14.364 alpha.

обновлён JCL:

* исправлена ошибка с некорректным ключом dcc32 -N»Snamespace»

* улучшена поддержка версий Delphi XE2+

* другие исправления

Эту версию я ещё не тестировал. Если что-то найдёте — дайте знать.

[[ This is a content summary only. Visit my website for full links, other content, and more! ]]

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

Как послать доллар через RESTDebugger

rouse

Выдали мне партнёры точку доступа к данным и сказали: «Пиши в HTTP-заголовке ‘X-Auth: abracadabraabracadabraabracadabra$abracadabraabracadabraabracadabra’, а то неавторизованный доступ будет».
Я беру Fiddler (я его всегда беру),

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

Выложен Lazy Delphi Builder 1.14.14.360 (исправления ошибок)

01.04.2016. Lazy Delphi Builder 1.14.14.360: Исправления ошибок. Исправлены ошибки с относительными путями. Как для путей в LazyDBP файле так и для переменной $(BUILTIN_PROFILE_DIR) Консольная версия

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

Выложен Lazy Delphi Builder 1.14.14.360 (исправления ошибок)

01.04.2016. Lazy Delphi Builder 1.14.14.360:
Исправления ошибок.

Исправлены ошибки с относительными путями. Как для путей в LazyDBP файле так и для переменной $(BUILTIN_PROFILE_DIR)
Консольная версия не возвращала ERRORLEVEL если при удалении или создании папки случалась проблема
Очень тормозило построение дерева после удаления узла
MRU файлы. Последний загруженный отправляется наверх. Наконец-то.
Новый параметр командной строки /MaxProblemCountToStop
Значение BUILTIN_PROFILE_DIR переменной выводится после загрузки профиля в /debug режиме в консольной версии

 Скачивать

[[ This is a content summary only. Visit my website for full links, other content, and more! ]]

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

Почему тип анонимных функций не всегда полезен или о проблема присвоения reference to типу неанонимных функций

Сегодня снова об особенностях анонимных функций.
Два предыдущих поста:

  1. Просто баг в коде или особенность счетчика ссылок в замыканиях
  2. Немного про замыкание ( Одно замыкание на несколько анонимных функций в одном контексте)

  У типа анонимный функций есть замечательная возможность. В качестве обработчика можно присваивать не только анонимные функции, но и обычные методы и статические функции. Казалось бы, нет причин почему не использовать тип reference to всегда.
Однако есть ситуации, когда reference to тип может сыграть злую шутку. И я сейчас не про вопрос производительности, о котором я думаю большинство осведомлено. 
Проблема может возникнуть при передаче обычной процедуры или метода в параметр с анонимным типом. Покажем на примере. 
Наиболее распространенный вариант использования процедурных типов в реализации подписки на события.
  Пусть есть какой-нибудь список EventHandlers, и конечно же, как у правильных хипстеров он будет параметризован типом анонимной функций TList<TProc>. 
Заведем два метода для возможности подписаться на событие и отписаться от него:  Subscribe(AHandler: TProc) и Unsubscribe(AHandler: TProc): Boolean соответственно. Однако, крайне вероятно, вас постигнет неудача если в качестве обработчика вы используете неанонимную функцию.  По крайне мере отписаться вы уже не сможете. 

Вот код примера:

program ReferenceToProc;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils, System.Generics.Collections;
var
eventHandlers: TList<TProc>;

procedure Subscribe(AHandler: TProc);
begin
eventHandlers.Add(AHandler);
end;

function Unsubscribe(AHandler: TProc): Boolean;
begin
Writeln(eventHandlers.IndexOf(AHandler)); // 0
Result := eventHandlers.Remove(AHandler) >= 0;
end;

procedure HandlerProc;
begin
Writeln('Вызов статической процедуры');
end;

var
proc: TProc;
begin
eventHandlers:= TList<TProc>.Create;

proc := procedure()
begin
Writeln('Вызов анонимной функции')
end;

Subscribe(proc); // Подписываемся анонимной функцией
Writeln(Unsubscribe(proc)); // Метод вернул True, Успех:)

Subscribe(HandlerProc); // Подписываемся не анонимной функцией
Writeln(Unsubscribe(HandlerProc)); // Метод вернет False Fail:(
FreeAndNil(eventHandlers);
readln;
end.

  Вызов Unsubscribe  в строке  Writeln(Unsubscribe(HandlerProc)); вернет False. Причина впрочем прозаична, вызов метода HandlerProc заворачивается в анонимную функцию и каждый раз новую. Потому функция, которую подписали на событие, будет отличаться от функции, которую пытаемся отписать.

  Казалось бы, простая задача — реализовать список с обработчиками и методами подписки и отписки превращается не в самую тривиальную.

  Получается, что хранить обработчики лучше как TMethod, но если все же хотим уметь подписывать универсальные обработчики (анонимные и неанонимные), тогда придется для каждого типа писать свою логику сохранения в список и вызова обработчиков. Это будут либо overload методы, либо будем использовать Rtti  и методы параметризированные типом.

  TEvent = class
events: TList<TMethod>;
class procedure Subscribe(AProc: TProc); overload;
class procedure Subscribe(AProc: TProcedure); overload;
class procedure Subscribe<T>(AProc: T); overload;
end;

  А для преобразования анонимного метода в TMethod потребуется сочинять что то вроде того, что написано в Spring4D в Springs.Events.pas:

procedure MethodReferenceToMethodPointer(const AMethodReference; const AMethodPointer);
type
TVtable = array[0..3] of Pointer;
PVtable = ^TVtable;
PPVtable = ^PVtable;
begin
// 3 is offset of Invoke, after QI, AddRef, Release
PMethod(@AMethodPointer).Code := PPVtable(AMethodReference)^^[3];
PMethod(@AMethodPointer).Data := Pointer(AMethodReference);
end;

function TEvent.Cast(const handler): TMethod;
begin
if fTypeInfo.Kind = tkInterface then
MethodReferenceToMethodPointer(handler, Result)
else
Result := PMethod(@handler)^;
end;

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