LMD VCL - LMD Packs: Difference between revisions

From LMD
Jump to navigation Jump to search
Balabuyew (talk | contribs)
 
(3 intermediate revisions by 2 users not shown)
Line 4: Line 4:
===Using Paste/Copy commands at runtime===
===Using Paste/Copy commands at runtime===
Copy:
Copy:
<pre class="brush:delphi">
<syntaxhighlight lang="delphi">
if assigned(LMDShellList1.selected) then
if assigned(LMDShellList1.selected) then
   LMDDoContextMenuVerb( LMDShellList1, (LMDShellList1.Selected as TLMDShellListItem).ShellItem, 'copy');
   LMDShellDoContextMenuVerb( LMDShellList1, (LMDShellList1.Selected as TLMDShellListItem).ShellItem, 'copy');
</pre>
</syntaxhighlight>
Paste:
Paste:
<pre class="brush:delphi">
<syntaxhighlight lang="delphi">
LMDDoContextMenuVerb( LMDShellList2, LMDShellFolder2.ActiveFolder,'paste');
LMDShellDoContextMenuVerb( LMDShellList2, LMDShellFolder2.ActiveFolder,'paste');
</pre>
</syntaxhighlight>


==LMD RichPack==
==LMD RichPack==
Line 27: Line 27:
===[Linker Error] Unresolved external "InternetCloseHandle" referenced from===
===[Linker Error] Unresolved external "InternetCloseHandle" referenced from===
Simply add wininet.lib to your project (file can be found in \lib directory of your C++ Builder / BDS / CRS installation). In recent IDEs you can also add<br>  
Simply add wininet.lib to your project (file can be found in \lib directory of your C++ Builder / BDS / CRS installation). In recent IDEs you can also add<br>  
<code>#pragma link "wininet.lib"</code><br> in your code.
<syntaxhighlight lang="cpp">
 
#pragma link "wininet.lib"
==NG Serialization==
</syntaxhighlight> in your code.
===How to serialize collections===
Serializing collections, including custom or standard collections (like TList) requires writing custom converters. For example, lets consider the folowing collection declaration:
 
<pre class="brush:delphi">
type
  TItem = class
  public
    X: Integer;
    Y: Integer;
  end;
 
  TItems = class(TObjectList<TItem>);
</pre>
 
To be able to serialize it, we need to declare a converter class, and '''associate''' this class with our collection using Converter attribute:
 
<pre class="brush:delphi">
type 
  TItemsConverter = class(TConverter)
  public
    function  GetReadMode: TReadMode; override;
    procedure Write(S: TSerializer; const V); override;
    procedure Read(D: TDeserializer; var V); override;
  end;
 
  [Converter(TItemsConverter)]
  TItems = class(TObjectList<TItem>);
</pre>
 
The converter can be implemented like this:
 
<pre class="brush:delphi">
function TItemsConverter.GetReadMode: TReadMode;
begin
  Result := rmFillRead; // Indicate fill-read mode.
end;
 
procedure TItemsConverter.Read(D: TDeserializer; var V);
var
  lst: TItems;
begin
  lst := TItems(V); // Since we work in fill-read mode,
                    // V already contains a reference to
                    // TItems instance; we should not
                    // create it here.
  lst.Clear;
 
  D.BeginArray;
  while D.HasNext do
    lst.Add(D.Value<TItem>);
  D.EndArray;
end;
 
procedure TItemsConverter.Write(S: TSerializer; const V);
var
  lst: TItems;
  i:  Integer;
begin
  S.BeginArray;
  lst := TItems(V);
  for i := 0 to lst.Count - 1 do
    S.Value(lst[i]);
  S.EndArray;
end;
</pre>
 
As can be seen, GetReadMode returns rmFillRead, which indicates that de-serializer should use fill-read mode. This means that no new TItems instance is created during de-serialization. This mode is especially usefull for collection like classes, because they usually owned by some other objects. For example, lets look at the following class:
 
<pre class="brush:delphi">
type 
  TOwner = class
  private
    FItems: TItems;
  public
    constructor Create;
    destructor  Destroy; override;
    property    Items: TItems read FItems;
  end;
 
constructor TOwner.Create;
begin
  inherited Create;
  FItems := TItems.Create;
end;
 
destructor TOwner.Destroy;
begin
  FItems.Free;
  inherited;
end;
</pre>
 
As can be seen, TItems collection is oqned by TOwner class. TOwner expose Items as read-only property, and thus, there no way to replace collection as a whole. Only collection content can be changed.
 
But, fortunately, TOwner class can be serialized and de-serialized, because TItems collection has fill-read mode converter:
 
<pre class="brush:delphi">
var
  src, dst: TOwner;
  stream:  TStream;
  s:        TBinarySerializer;
  d:        TBinaryDeserializer;
begin
  stream := TMemoryStream.Create;
  try
    src := TOwner.Create;
    src.Items.Add(TItem.Create);
    src.Items.Add(TItem.Create);
    src.Items.Add(TItem.Create);
 
    s := TBinarySerializer.Create(stream);
    s.Value(src);
    s.Free;
 
    stream.Position := 0;
 
    d  := TBinaryDeserializer.Create(stream);
    dst := d.Value<TOwner>;
    d.Free;
  finally
    stream.Free;
  end;
end;
</pre>
 
Please use the following link for more information about fill-read mode:
[http://www.lmd.de/downloads/tutorials/serialization/index.html?fill-read_mode.htm Fill-Read Mode]

Latest revision as of 14:09, 28 April 2022

[edit]

<< Back to Overview page

LMD ShellPack

Using Paste/Copy commands at runtime

Copy:

if assigned(LMDShellList1.selected) then
  LMDShellDoContextMenuVerb( LMDShellList1, (LMDShellList1.Selected as TLMDShellListItem).ShellItem, 'copy');

Paste:

LMDShellDoContextMenuVerb( LMDShellList2, LMDShellFolder2.ActiveFolder,'paste');

LMD RichPack

Which MS RichEdit DLL Version can I expect on a specific operating system?

Please check list of different RichEdit versions.

Searching for specific attributes

Q: I was trying out the LMD RTF wrapper (using BCB 6) and wanted to know what would be the best way to search for words or characters with a specific attribute. A:

  • Use FindTextEx
  • Check SelAttributes
    if attrs not ok then FindTextEx again.

LMD WebPack

[Linker Error] Unresolved external "InternetCloseHandle" referenced from

Simply add wininet.lib to your project (file can be found in \lib directory of your C++ Builder / BDS / CRS installation). In recent IDEs you can also add

#pragma link "wininet.lib"

in your code.