Page 1 of 2

trichview and olevariant

Posted: Fri Aug 17, 2012 1:07 pm
by Alvaro
Good day.
Using the tips found in http://www.trichview.com/forums/viewtop ... ight=email, get email using the component TRichViewEdit and looked great. But this example sends the email client side and I'm adapting to the routine sending is done server side and how I use Delphi XE, the object must be passed as type OleVariant. My question is: how to send the client-side object and how can I read it on the server side (remote)?
Li also the topic that guides http://www.trichview.com/forums/viewtop ... olevariant send as SaveRTFToStream using the RTF TStringStream and receive through Stream.DataString, but server-side I could not turn on the type OleVariant Stream, someone could put an example? Thank you and sorry for language mistakes.

Posted: Fri Aug 17, 2012 3:06 pm
by Sergey Tkachenko
Can you create a simple project demonstrating the problem (encoding and decoding in the same application, with assignment instead of saving)?

Send it to richviewgmailcom.

Posted: Sat Aug 18, 2012 2:35 pm
by Alvaro
Dear Sergey, below is the code of the sending email server side (remote). Note that it is identical to the examples you've cited, but the error occurs in the use of variable OleVariant.
If you find it necessary, I can send you the two routines (client-side and server-side remote). Thank you.


function TDSServerSolERP.EnviaEmail2(const Destinatario, Assunto, Corpo,
Arquivo: string; InsereLogotipo: boolean; Anexos: OleVariant; ComCopia: string; RichViewEdit1: OleVariant): String;
var
FServidorSMTP: TIdSMTP;
FSSLHandlerSMTP: TIdSSLIOHandlerSocketOpenSSL;
FIdMessage: TIdMessage;

procedure BuildEmail;
var
Stream : TMemoryStream;
ws : String;
s : TRVRawByteString;
i : Integer;
txtpart, htmpart, txthtmpart, txthtmlimgpart : TIdText;
imgpart : TIdAttachmentMemory;
begin
// saving text
TxtPart := TIdText.Create( FIdMessage.MessageParts );
Stream := TMemoryStream.Create;

//RichViewEdit1.SaveTextToStreamW('', Stream, 80, False, False); //Original line...

TCustomRichViewEdit(RichViewEdit1).SaveTextToStreamW('', Stream, 80, False, False); This was my attempt to type cast,, but generates the error: E2089 Invalid typecast.

Posted: Sun Aug 19, 2012 10:59 am
by Sergey Tkachenko
TRichViewEdit cannot be converted to OleVariant, because Delphi component is not an OLE-compatible type.

Posted: Mon Aug 20, 2012 7:00 pm
by Alvaro
So there is a way to send and read the component remotely? Do you have any suggestions? Thank you.

Posted: Tue Aug 21, 2012 7:10 am
by Sergey Tkachenko
Sending the component? I am afraid no. You need to implement this functionality in another way.
Why do you want to send a component?

Posted: Tue Aug 21, 2012 12:16 pm
by Alvaro
My English is not good, but I tried to explain above: I would concentrate sending email server side. Using your examples, already works on the client side, but I wish all the routines were processed on the server due to performance, but by the way is not possible.

Posted: Thu Aug 23, 2012 11:35 am
by Sergey Tkachenko
Create your server application using TRichView. I do not know another solution.

Posted: Thu Aug 23, 2012 1:05 pm
by Alvaro
That's what I tried initially Sergey, creating a server application with component TRichView have no problems on the server side, what happens is that the problem goes to the client side because the Delphi XE can not send a component TRichView remotely (and not send other objects like ClientDataSet), so I tried send using a type OleVariant (as I did with the ClientDataSet), but I will not take more your time. I'll try to send him into a blob field through ClientDataSet and read it through ClientDataSet.Data propety. Thank you, have a nice day and congratulations for the great component that helps me so much. Hugs.

Posted: Thu Aug 23, 2012 4:06 pm
by Sergey Tkachenko
You should send data, not code/components.

Posted: Fri Aug 24, 2012 2:23 pm
by Alvaro
Is there any property of the RichView component like ClientDataSet.Data?

Posted: Sat Aug 25, 2012 5:58 pm
by Sergey Tkachenko
How to convert document in TRichView to OleVariant and back:

Code: Select all

function RVToVariant(rv: TCustomRichViewEdit): OleVariant;
var Stream: TMemoryStream;
begin
  Stream := TMemoryStream.Create;
  rv.SaveRVFToStream(Stream, False);
  Result := VarArrayCreate([0, Stream.Size-1], varByte);
  Move(Stream.Memory^, VarArrayLock(Result)^, Stream.Size);
  VarArrayUnlock(Result);
  Stream.Free;
end;

function VariantToRV(rv: TCustomRichView; v: OleVariant): Boolean;
var Stream: TMemoryStream;
    Size: Integer;
begin
  Result := False;
  if VarArrayDimCount(v)<>1 then
    exit;
  Stream := TMemoryStream.Create;
  Size := VarArrayHighBound(v,1)-VarArrayLowBound(v,1)+1;
  Stream.WriteBuffer(VarArrayLock(v)^, Size);
  VarArrayUnlock(v);
  Stream.Position := 0;
  rv.LoadRVFFromStream(Stream);
  Stream.Free;
  rv.Format;
  Result := True;
end;

Posted: Mon Aug 27, 2012 2:13 pm
by Alvaro
Sergey thank you. That was exactly what I wanted.
A hug.

Posted: Tue Aug 28, 2012 10:35 pm
by Alvaro
Sergei, I eliminated the line "rv.Format;" because it created two errors: 1. - The content sent to the memory was read only when a second email was sent 2. - 'Canvas does not allow drawing'. The error number 2 only occurred when I closed the client application and called it again. So I had to restart the application server to send the email. Somewhat confusing is not it? After several tests I saw that was enough to eliminate the rv.Format line, this problem may be the same as reported DavideCase (http://www.trichview.com/forums/viewtopic.php?t=5479). Searching the internet and read something about Canvas.Lock Canvas.Unlock. I was tested and the system worked with these lines and also without them. What do you think ?

Below like it is:

VariantToRV function (rv: TCustomRichView, v: OleVariant): Boolean;
var Stream: TMemoryStream;
Size: Integer;
begin
Result: = False;
if VarArrayDimCount (v) <> 1 then
exit;
Stream: = TMemoryStream.Create;
Size: VarArrayHighBound = (v 1) VarArrayLowBound (v, 1) +1;
Stream.WriteBuffer (VarArrayLock (v) ^, Size);
VarArrayUnlock (v);
Stream.Position: = 0;
rv.Canvas.Lock;
rv.LoadRVFFromStream (Stream);
Stream.Free;
/ / rv.Format;
rv.Canvas.UnLock;
Result: = True;
end;

Thanks.

Posted: Wed Aug 29, 2012 6:40 am
by Sergey Tkachenko
Format is necessary only if you want to display this TRichView, call its editing method, or save to RTF (and the document contains tables).

Why the error happens - it depends on the context where this function is called. Format should not be called in a thread, for example.