Processing OleDragDrop

General TRichView support forum. Please post your questions here
Post Reply
vit
Posts: 115
Joined: Tue Feb 03, 2009 3:11 pm

Processing OleDragDrop

Post by vit »

Hi!

When user drags text from one place of document to another I whant to known what exactly he drags. I whant to analyse content and probably modify them before insert. It is important that I whant analyse exactly content in RVF format.

So I get as base this http://www.trichview.com/forums/viewtop ... dataobject topic and write OnOleDrag event handler:

(AcceptDragDropFormats is [rvddRVF])

Code: Select all

procedure TForm1.RVEOleDrop(Sender: TCustomRichView;
  const DataObject: IDataObject; Shift: TShiftState; X, Y: Integer;
  PossibleDropEffects: TRVOleDropEffects; var DropEffect: TRVOleDropEffect;
  var DoDefault: Boolean);
var FmtEtc: TFormatEtc;
  StgMedium: TStgMedium;
  ptr: Pointer;
  s: String;
  p: Integer;
  ms: TMemoryStream;
begin
  DoDefault := False;

  FillChar(StgMedium, sizeof(StgMedium), 0);
  FillChar(FmtEtc, sizeof(FmtEtc), 0);
  //FmtEtc.cfFormat := CF_TEXT;
  FmtEtc.cfFormat := CFRV_RVF;
  FmtEtc.dwAspect := DVASPECT_CONTENT;
  FmtEtc.lindex := -1;
  FmtEtc.tymed := TYMED_HGLOBAL;
  if DataObject.GetData(FmtEtc, StgMedium)<>S_OK then
    exit;
  if StgMedium.tymed=TYMED_HGLOBAL then begin
    ptr := GlobalLock(StgMedium.HGlobal);
    try
      SetLength(s, GlobalSize(StgMedium.HGlobal) div sizeof(Char));
      Move(ptr^, PChar(s)^, Length(s)*sizeof(Char));
      ms := TMemoryStream.Create;
      try
        ms.Write(PChar(s)^, Length(s));
        ms.Position := 0;
        if not RVE.InsertRVFFromStreamEd(ms) then
          ShowMessage('Can''t insert RVF!');
      finally
        ms.Free;
      end;
    finally
      GlobalUnlock(StgMedium.HGlobal);
    end;
  end;
  ReleaseStgMedium(StgMedium);
end;
First I always seen message 'Can't insert RTF!'. After researches I found that first 4 bytes of S contains length of RVF data. Is it correct? And should I use this value to read data from ms? Or may be I can just read data until the end?

Also as you can see, I use CFRV_RVF to retreive data. Is it correct? Or I should use CF_TEXT insead (I never use Unicode).

And last. This code will work only when data is in RVF format. Can I be sure that if text dragged from TRichViewEdit it will be always in RVE? I guess that if data is not in RVF then

Code: Select all

DataObject.GetData(FmtEtc, StgMedium)<>S_OK
will be true


Thank you!
Sergey Tkachenko
Site Admin
Posts: 17569
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

For RVF, the first 4 bytes contains size (in bytes) of RVF content.

Code: Select all

procedure TForm3.RichViewEdit1OleDrop(Sender: TCustomRichView;
  const DataObject: IDataObject; Shift: TShiftState; X, Y: Integer;
  PossibleDropEffects: TRVOleDropEffects; var DropEffect: TRVOleDropEffect;
  var DoDefault: Boolean);
var FmtEtc: TFormatEtc;
  StgMedium: TStgMedium;
  ptr: Pointer;
  Size: Integer;
  ms: TMemoryStream;
begin
  DoDefault := False;

  FillChar(StgMedium, sizeof(StgMedium), 0);
  FillChar(FmtEtc, sizeof(FmtEtc), 0);
  //FmtEtc.cfFormat := CF_TEXT;
  FmtEtc.cfFormat := CFRV_RVF;
  FmtEtc.dwAspect := DVASPECT_CONTENT;
  FmtEtc.lindex := -1;
  FmtEtc.tymed := TYMED_HGLOBAL;
  if DataObject.GetData(FmtEtc, StgMedium)<>S_OK then
    exit;
  if StgMedium.tymed=TYMED_HGLOBAL then begin
    ptr := GlobalLock(StgMedium.HGlobal);
    try
      if GlobalSize(StgMedium.HGlobal)>4 then begin
        Size := PInteger(ptr)^;
        ms := TMemoryStream.Create;
        try
          ms.WriteBuffer((PRVAnsiChar(ptr)+sizeof(Integer))^, Size);
          ms.Position := 0;
          if not TCustomRichViewEdit(Sender).InsertRVFFromStreamEd(ms) then
            ShowMessage('Can''t insert RVF!');
        finally
          ms.Free;
        end;
      end;
    finally
      GlobalUnlock(StgMedium.HGlobal);
    end;
  end;
  ReleaseStgMedium(StgMedium);
end;
Post Reply