How to send attachment using TIdyAttachment ?
How to convert this TIdAttachment.Create(msg.MessageParts, 'c:\attach.bmp'); delphi statement to c++ builder ?
How to use this abstract class in c++ builder? Due to it's being abstract I cannot create an instance of it !!!
Note that TIdAttachment is indeed abstract (as Remy Lebeau noted in a comment). Use TIdAttachmentFile instead. In C++, I guess it should look like (Update: I see you already found that):
TIdAttachmentFile *attachment = new TIdAttachmentFile(msg->MessageParts, "C:\\attach.bmp");
FWIW, named constructor calls like TMyClass.Create(args) in Delphi are translated as new TMyClass(args) in C++Builder. That is why Delphi often overloads Create, instead of using differently named constructors like CreateWithSpecialParams. In Delphi, a constructor can have any name, but not in C++.
Note that in Delphi you can have a constructor Create(Integer) and a constructor CreateEx(Integer) and they are distinguishable. This is not translatable to C++Builder, since both translate to MyClass(int), so doing that should be avoided if the Delphi programmer wants his or her class to be usable in C++Builder.
Related
I am new of Delphi. In the documentation of TStrem class, i read it is an abstract class.
So i think the compiler goes in error when i try to create it with
stream := TStream.Create();
Why not?
The Delphi language doesn't really have any formal concept of abstract class.
It is true that you can define a class to be abstract:
type
TMyClass = class abstract
end;
But you can perfectly well instantiate this class. In fact class abstract in Delphi is a feature used only by the long abandoned Delphi .net compiler.
A more useful definition of an abstract class is one that contains abstract methods. If you attempt to instantiate such a class, then a compiler warning will be emitted. Those warnings can be promoted to errors by way of a compiler option, if you wish.
When the documentation refers to TStream as being abstract it in fact means that it is "conceptually" abstract. In fact it does not even have any abstract methods, so by my definition above it is not abstract.
I'm really not sure why TStream does not contain abstract methods. I would suggest that the GetSize, SetSize, Read, Write and Seek should really be declared abstract. I suspect that if the class were being designed today then they would be declared abstract and likely they are not for historical reasons.
Instantiating TStream is a very common mistake made by programmers less experienced in the Delphi RTL. Once the mistake has been made a couple of times, the lesson is usually learnt. Unfortunately the system provides no easy way for this mistake to be flagged up. Each and every new programmer just has to learn the hard way.
I downloaded the OTL http://www.omnithreadlibrary.com/
and compile the D2007 grouproj, install the package, without problem.
I then create a simple console application that uses OtlParallel unit, of course, I add the OtlParallel and some other pas files to the project.
But it complains that Generics.Collections is not found.
The documentation says:
High-level abstractions are implemented in the OtlParallel unit. They are all created through the factory class Parallel. High-level code intensively uses anonymous methods and generics which makes Delphi 2009 the minimum supported version.
This us of both generics and anonymous methods makes this unit completely incompatible with Delphi 2007.
If you wish to use a construct like Parallel.For with Delphi 2007 and OTL then you will have to back-port OtlParallel yourself. Without anonymous methods this is very difficult to do and achieve the same fluid style of code. You would have to use procedural types instead of anonymous methods. And you would have to implement closures manually.
So instead of using
TProc = reference to procedure;
you would use
TMethod = procedure of object;
And then to implement this you create a class or record with a parameterless method. You'll need to add whatever state is needed as members of the type, and populate those members. That is in essence a manual implementation of a closure with variable capture. And you'll need to deal with lifetime. Make sure that the instances outlive the parallel loop.
Good luck!
I am using Lazarus 1.0.4 with FPC 2.6
I am trying to create a TList of an own class (I just use string here, because it is more easy), but when I try to use
type
TStringList = specialize TList<string>;
it says "Specialization is only supported for generic types.
What am I doing wrong?
Might as well post it as answer, since it seems to have done the trick.
You need to use the fgl unit. See the Wiki at freepascal.org.
I'm trying to create a shell extension to provide EXIF information for JPEG files in Windows Explorer "infotips", and am using Lazarus as this needs to produce an x64 DLL.
Does Lazarus support multiple inheritance with interfaces, and if so, how do I go about it?
for example, something like:
type
IInfoTips = interface(IPersistFile, IQueryInfo)
Thanks,
Mark
No, interfaces in FPC does not support multi-inheritance yet.
What you can do is letting the implementation class inherit from both interfaces:
type
TMyInfoTips = class(TInterfacedObject, IPersistFile, IQueryInfo)
But not at interface level, as you wish. Such statements won't compile:
type
IInfoTips = interface(IPersistFile, IQueryInfo)
You can only "inherit" from a single interface type.
Delphi does not support it either. Only the defunct Delphi for .Net compiler did... but because .Net/C# IR supports (and expects) the feature.
I'm also missing this feature in Delphi or FPC.
Both interfaces are defined in shlobj for Free Pascal/Lazarus, just like on Delphi. If symbols changed units during the Delphi lifetime, we try to put them in the more recent units, but there is a large backlog there.
All this should be largely Delphi compatible, maybe it is easier if you explained what exactly doesn't work like expected.
Added after Arnaud's comments:
No it does not. Objects implement interfaces in Pascal. I don't really understand why it is really important to do this anyway. Sure it is a bit of syntactic sugar, but since any delphi style interface implements Iunknown, you can just query an interface for another interface:
uses activex;
var x :IPersistfile;
y :IPersistStream;
begin
x.queryinterface(IID_IPersistStream,y);
end.
I'm attempting to write a unit test for a simple factory class that creates one of several possible implementing objects and returns it as an interface reference.
DUnit has a built in procedure, CheckIs(AObject: TObject; AClass: TClass; msg: string), that based on its name and the parameters it accepts should fail the test if the object's class type doesn't match the expected one. The only problem is it requires an object reference not an interface reference.
So I'm trying to use CheckTrue and perform the comparison in the body of the test but I'm not as familiar with Delphi's type checking support as I am with C#'s.
I know the is operator is out of the question since it only works with object references.
CheckTrue(LMyInterfaceReference {comparison here} TMyClass);
Any suggestions?
BTW, I'm using Delphi 2009 so I don't have access to the new RTTI support added in 2010+.
I'm wondering why you MUST have to test this... maybe you really don't have to.
But if knowing the underlying object of a Interface is a must, you have two choices:
Add a method to the interface which returns the underlying object, just a TObject, and implement this in each class just by returning self.
Hack a bit, for example using this Interface to object routine.
If you don't like hacks and don't feel like upgrading to Delphi 2010+ you may use an interface like this:
IImplementingObjectInterface = interface
function GetImplementingObject: TObject;
end;
Make sure your objects also implement this interface and use it to extract the implementing object. If you need to do this for a lot of objects you can define your own TInterfacedObject derivate that already implements this so you can simply change your inheritance and be done.
Barry Kelly (one of the main Embarcadero Delphi Compiler Engineers) wrote a nice An ugly alternative to interface to object casting this week.
It answers your question.
The fun is that Hallvard Vassbotn wrote a very similar piece of code back in 2004.
From Delphi 2010 on, you can just use an is check or as cast to go back from interface references to object references.
--jeroen