Delphi. Dependency Injection With Spring

Этот пример можно найти в библиотеке Spring for Delphi, где-то примерно здесь

C:\Work\DSeattle\libs\sglienke-spring4d\Samples\IntroToDependencyInjection\6-UseContainer

Как это работает? Для начала нам нужно зарегистрировать в контейнере классы

unit uRegistrations;

interface

uses
  Spring.Container;

procedure RegisterTypes(const container: TContainer);

implementation

uses
  uOrderEntry,
  uOrderProcessor,
  uOrderValidator;

procedure RegisterTypes(const container: TContainer);
begin
  container.RegisterType<TOrderEntry>;
  container.RegisterType<TOrderValidator>;

  container.Build;
end;

end.

Теперь, в основном коде программы мы делаем примерно что-то такое…

...
  RegisterTypes(GlobalContainer);
  Order := TOrder.Create;
  try
    OrderValidator := GlobalContainer.Resolve<IOrderValidator>;
    OrderEntry := GlobalContainer.Resolve<IOrderEntry>;
    OrderProcessor := TOrderProcessor.Create(OrderValidator, OrderEntry);
    if OrderProcessor.ProcessOrder(Order) then
      Writeln('Order successfully processed....');
  finally
    Order.Free;
  end;
...

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

Когда нам понадобится другая реализация интерфейса, мы просто в одном месте подменим регистрацию, и на во всех 10 000 местах в проекте на надо будет ничего переписывать, и будет вызываться уже инстанс с новой реализацией.

Таким образом, достигнута слабая связность, что довольно удобно при перекомпоновке проекта.

Posted in Без рубрики | Comments Off on Delphi. Dependency Injection With Spring

Delphi. IDE Git Client

В Delphi есть довольно простой Git клиент, который позволят делать базовые операции commit, push, просмотр лога и др. Вызывается он из контекстного меню и выглядит примерно так…

Как его настроить и использовать читайте здесь и здесь

Posted in Без рубрики | Comments Off on Delphi. IDE Git Client

Delphi. Serialization / Deserialization. XML / JSON

XML

OmniXML is a smart way to serialize smth.

First point, your objects should be derived from

TPersistent, TCollection or TCollection item.

Second point. Saved information should be in published section.

I do it like this

uses
OmniXML, OmniXMLPersistent

Saving


var
o : TSomeObject; // derived from TPersistent
...
TOmniXMLWriter.SaveToFile( o, 'c:\path\file.xml', pfAttributes, ofIndent );

Loading

TOmniXMLWriter.LoadFromFile( o, 'c:\path\file.xml' ); 

JSON

I use superobject library, example from github

  TTest = class // Field, Property Support
  private
    FB: String;
    FSubObj: TSubObj;
    FSubRec: TSubRec;
    FTestSets: TTestSets;
    FH: TDateTime;
    FJ: TDate;
    FK: TTime;
    FList: TObjectList<TSubObj>; // or TList<>; But only object types are supported
  public
    A: Integer;
    B: TTestSet;
    C: Boolean;
    property D: String read FB write FB;
    property E: TSubRec read FSubRec write FSubRec;
    property F: TSubObj read FSubObj write FSubObj;
    property G: TTestSets read FTestSets write FTestSets;
    property H: TDateTime read FH write FH;
    property J: TDate read FJ write FJ;
    property K: TTime read FK write FK;
    property L: TObjectList<TSubObj> read FList write FList;
  end;
  
  TTestRec = record // Only Field Support
    A: Integer;
    B: TTestSet;
    C: Boolean;
    D: String;
    E: TSubRec;
    F: TSubObj;
    G: TTestSets;
    H: TDateTime;
    J: TDate;
    K: TTime;
    L: TObjectList<TSubObj>; // or TList<>; But only object types are supported
  end;
  
  implementation
  ...
  
  var 
    Parse: TTest; // For Class;
    S: String;
  begin
    Parse := TTest.FromJSON('{"A": 1, "B": 0, "C": true, "D": "Hello", "E":{"A": 3, "B": "Delphi"}, "F": {"A": 4, "B": 5}, "G": [0,2], "H": "2014-05-03T03:25:05.059", "J": "2014-05-03", "K": "03:25:05", "L":[{"A": 4, "B": 5},{"A": 6, "B": 7}] }');
    S := Parse.AsJSON;
  end;
  
  
  ...
  var
    Parse: TTestRec; // For Record;
    S: String;
  begin
    Parse := TJSON.Parse<TTestRec>('{"A": 1, "B": 0, "C": true, "D": "Hello", "E":{"A": 3, "B": "Delphi"}, "F": {"A": 4, "B": 5}, "G": [0,2], "H": "2014-05-03T03:25:05.059", "J": "2014-05-03", "K": "03:25:05", "L":[{"A": 4, "B": 5},{"A": 6, "B": 7}]}');  
    S := TJSON.Stringify<TTestRec>(Parse);
  end;

Also fix by krapotkin

Posted in Без рубрики | Comments Off on Delphi. Serialization / Deserialization. XML / JSON

Delphi. Lambda. Anonymous methods

Example

program LambdaExamples;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

type
  TSayHello = reference to function(aName: string): string;

  TFuncOfIntToString = reference to function(x: Integer): string;

  TFuncOfString = reference to function(a, b: string): string;

  TMethodReference = reference to procedure(aArg: string);

  TSomeClass = class
    procedure Foo(aArg: string);
  end;

var
  myFunc: TFuncOfIntToString;
  concater: TFuncOfString;
  someClassInstance: TSomeClass;
  m: TMethodReference;
  sayHello: TSayHello;


// lets say we have following functions
procedure AnalyzeProcedure(func: TFuncOfIntToString);
begin
  // use argument
  WriteLn(func(12));
end;

function MakeConcat(y: Integer): TFuncOfString;
begin
  Result :=
    function(a, b: string): string
    begin
      Result := Format('%s %s %s', [a, b, y.ToString()]);
    end;
end;

{ TSomeClass }

procedure TSomeClass.Foo(aArg: string);
begin
  Writeln(aArg);
end;

begin

   // 1. lets say we in context of some class and we need to do
   // smth fast without overhead of instantiate new class
   // we can do it like this
  sayHello :=
    function(aName: string): string
    begin
      Result := Format('hello %s', [aName]);
    end;
  WriteLn(sayHello('Stan'));

  //2.  use lambda directly in another function
  AnalyzeProcedure(
    function(x: Integer): string
    begin
      Result := IntToStr(x);
    end);

  //3.  put lambda to variable
  myFunc :=
    function(x: Integer): string
    begin
      Result := IntToStr(x);
    end;

  AnalyzeProcedure(myFunc);

  //4.  --- Closure
  concater := MakeConcat(123);
  WriteLn(concater('a', 'b'));

  //5.  reference to method
  someClassInstance := TSomeClass.Create();
  try
    m := someClassInstance.Foo;
    m('this is reference to method');

    // ACHTUNG !!! DONT' DO LIKE THIS
    // someClassInstance.Foo := m;  << DANGER OF MEMORY LEAKS
  finally
    someClassInstance.Free();
  end;

  ReadLn;
end.
Posted in Без рубрики | Comments Off on Delphi. Lambda. Anonymous methods

Delphi. Jcl. HashMaps

Example

program JediHashMaps;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  JclContainerIntf,
  JclHashMaps;

var
  h: IJclIntegerIntegerMap;

const
  key = 1;
  value = 123;

begin
  h := TJclIntegerIntegerHashMap.Create(10);
  h.PutValue(key, value);

  if h.ContainsKey(key) then
    Writeln(Format('contains key %s with value %s', [key.ToString(), h.Items[key].ToString()]));

  ReadLn;
end.
Posted in Без рубрики | Comments Off on Delphi. Jcl. HashMaps

Icons. Collections

icons8

Posted in Без рубрики | Comments Off on Icons. Collections

DesignPatterns. Iterator

Простой пример итератора для коллекции

program IteratorPattern;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  uIterator in 'uIterator.pas';

var
  c: TCollection;
  i: TCustomIterator;

begin
  c := TCollection.Create();
  try
    c.Add(TStrObjForTest.Create('obj 1'));
    c.Add(TStrObjForTest.Create('obj 2'));
    c.Add(TStrObjForTest.Create('obj 3'));
    // iteration
    i := TCustomIterator.Create(c);
    try
      Writeln(TStrObjForTest(i.First).Value);
      while not i.IsDone do
        Writeln(TStrObjForTest(i.Next).Value);
      Readln;
    finally
      i.Free();
    end;
  finally
    c.Free();
  end;
end.
Continue reading
Posted in Без рубрики | Comments Off on DesignPatterns. Iterator

Delphi. UniGUI. Как отключить меню с сортировкой в гриде?

UniDBTreeGrid -> Columns -> Column[xxx] -> Menu -> MenuEnabled = False

Спасибо Delphi Developer с форума UniGUI!

Posted in Без рубрики | Comments Off on Delphi. UniGUI. Как отключить меню с сортировкой в гриде?

Delphi. Соответствие типов С и Delphi

C Type    | Pascal    | Description  
---------------------------------------------- 
LPSTR       PAnsiChar;  String >pointer  
LPCSTR      PAnsiChar;  String >pointer  
DWORD       Integer;    Whole numbers  
BOOL        LongBool;   Boolean values  
PBOOL       ^BOOL;      Pointer to a Boolean value  
Pbyte       ^Byte;      Pointer to a byte value  
PINT        ^Integer;   Pointer to an integer value  
Psingle     ^Single;    Pointer to a single (floating point) value  
PWORD       ^Word;      Pointer to a 16-bit value  
PDWORD      ^DWORD;     Pointer to a 32-bit value  
LPDWORD     PDWORD;     Pointer to a 32-bit value  
UCHAR       Byte;       8-bit values (can represent characters)  
PUCHAR      ^Byte;      Pointer to 8-bit values  
SHORT       Smallint;   16-bit whole numbers  
UINT        Integer;    32-bit whole numbers. Traditionally,  
                        this was used to represent unsigned integers,  
                        but Object Pascal does not have a true  
                        unsigned integer data type.  
PUINT       ^UINT;      Pointer to 32-bit whole numbers  
ULONG       Longint;    32-bit whole numbers. Traditionally,  
                        this was used to represent unsigned integers,  
                        but Object Pascal does not have a true  
                        unsigned integer data type.  
PULONG      ^ULONG;     Pointer to 32-bit whole numbers  
PLongint    ^Longint;   Pointer to 32-bit values  
PInteger    ^Integer;   Pointer to 32-bit values  
PSmallInt   ^Smallint;  Pointer to 16-bit values  
PDouble     ^Double;    Pointer to double (floating point) values  
LCID        DWORD;      A local identifier  
LANGID      Word;       A language identifier  
THandle     Integer;    An object handle. Many Windows API functions return a value  
                        of type THandle, which identobject ifies that object within  
                        Windows'internal object tracking tables.  
PHandle     ^THandle;   A pointer to a handle  
WPARAM      Longint;    A 32-bit message parameter. Under earlier versions of Windows,  
                        this was a 16-bit data type.  
LPARAM      Longint;    A 32-bit message parameter  
LRESULT     Longint;    A 32-bit function return value  
HWND        Integer;    A handle to a window. All windowed controls, child windows,  
                        main windows, etc., have a corresponding window handle that  
                        identifies them within Windows'internal tracking tables.  
HHOOK       Integer;    A handle to an installed Windows system hook  
ATOM        Word;       An index into the local or global atom table for a string  
HGLOBAL     THandle;    A handle identifying a globally allocated dynamic memory object.  
                        Under 32-bit Windows, there is no distinction between globally  
                        and locally allocated memory.  
HLOCAL      THandle;    A handle identifying a locally allocated dynamic memory object.  
                        Under 32-bit Windows, there is no distinction between globally  
                        and locally allocated memory.  
FARPROC     Pointer;    A pointer to a procedure, usually used as a parameter type in  
                        functions that require a callback function  
HGDIOBJ     Integer;    A handle to a GDI object. Pens, device contexts, brushes, etc.,  
                        all have a handle of this type that identifies them within  
                        Windows'internal tracking tables.  
HBITMAP     Integer;    A handle to a Windows bitmap object  
HBRUSH      Integer;    A handle to a Windows brush object  
HDC         Integer;    A handle to a device context  
HENHMETAFILE  Integer;  A handle to a Windows enhanced metafile object  
HFONT       Integer;    A handle to a Windows logical font object  
HICON       Integer;    A handle to a Windows icon object  
HMENU       Integer;    A handle to a Windows menu object  
HMETAFILE   Integer;    A handle to a Windows metafile object  
HINST       Integer;    A handle to an instance object  
HMODULE     HINST;      A handle to a module  
HPALETTE    Integer;    A handle to a Windows color palette  
HPEN        Integer;    A handle to a Windows pen object  
HRGN        Integer;    A handle to a Windows region object  
HRSRC       Integer;    A handle to a Windows resource object  
HKL         Integer;    A handle to a keyboard layout  
HFILE       Integer;    A handle to an open file  
HCURSOR     HICON;      A handle to a Windows mouse cursor object  
COLORREF    DWORD;      A Windows color reference value, containing values  
                        for the red, green, and of ;bsp;blue components of a color 

Источник

Posted in Без рубрики | Comments Off on Delphi. Соответствие типов С и Delphi

Delphi. UniGUI. PopupMenu

Подключим всплывающее меню. Выглядеть это может так

Само подключение всплывающего меню происходит в коде, в событии OnCellContextClick

procedure TMainForm.UniDBGrid1CellContextClick(Column: TUniDBGridColumn; X, Y: Integer);
begin
  if ClientDataSet.State in dsEditModes then
    UniPopupMenu2.Popup(X, Y, UniDBGrid1)
  else
    UniPopupMenu1.Popup(X, Y, UniDBGrid1);
end;

Само Popup меню один в один с традиционным дельфийским аналогом. Нам просто нужно разместить его на форме и настроить в дизайнере.

Ну и обработка некоторых событий наших меню

TMainForm.Cancel1Click(Sender: TObject);
begin
  if ClientDataSet.State in dsEditModes then
    ClientDataSet.Cancel;
end;

procedure TMainForm.DeleteRowClick(Sender: TObject);
begin
  ClientDataSet.Delete;
end;

procedure TMainForm.EditClick(Sender: TObject);
begin
  ClientDataSet.Edit;
end;

procedure TMainForm.InsertRowClick(Sender: TObject);
begin
  ClientDataSet.Insert;
end;

procedure TMainForm.PostClick(Sender: TObject);
begin
  if ClientDataSet.State in dsEditModes then
    ClientDataSet.Post;
end;
Posted in Без рубрики | Comments Off on Delphi. UniGUI. PopupMenu