Page 1 of 1

my application doesn't work with delphi 2007

Posted: Thu Jun 14, 2007 4:07 pm
by safbay
Hello,

I have a big problem.
My component worked fine with delphi7 but when the company I
work for upgraded to delphi 2007 my Richview component wich is integraded with our system stopped working.

I get the error, access violation, when I try to initialize TJvsRichTextEditor like this: TJvsRichTextEditor.Create(nil).

Should I upgrade the source code so it works with Delphi 2007?
I use RichView 1.9.24.

Thank you.

some explanation

Posted: Fri Jun 15, 2007 9:55 am
by safbay
The thing is that my college has integrated the richview component with our system but now she has quit her job and the component is now my responsibility and i am completly confused..=)

It seemes like our UJvsRichTextEditor (TJvsRichTextEditor) unit is your unit3.pas i the richviewactions demoprojekt. She has changed the name and added som functions and procedures.

when we call:

Code: Select all

TJvsRichTextEditor.Create(nil); 
we end up in

Code: Select all

procedure TJvsRichTextEditor.FormCreate(Sender: TObject);
begin
  // Almost all these assignments could be done at design time in the Object Inspector
  // But in this demo we do not want to modify rvActionsResource
  // (and we recommend to use a copy of it in your applications)
 //rvActionsResource :=  TrvActionsResource.Create(self);
  rvActionsResource.rvActionSave1.OnDocumentFileChange := rvActionSave1DocumentFileChange;

  // Code for making color-picking buttons stay pressed while a
  // color-picker window is visible.
  rvActionsResource.rvActionColor1.OnShowColorPicker := ColorPickerShow;
  rvActionsResource.rvActionColor1.OnHideColorPicker := ColorPickerHide;
  rvActionsResource.rvActionParaColor1.OnShowColorPicker := ColorPickerShow;
  rvActionsResource.rvActionParaColor1.OnHideColorPicker := ColorPickerHide;
  rvActionsResource.rvActionFontColor1.OnShowColorPicker := ColorPickerShow;
  rvActionsResource.rvActionFontColor1.OnHideColorPicker := ColorPickerHide;
  rvActionsResource.rvActionFontBackColor1.OnShowColorPicker := ColorPickerShow;
  rvActionsResource.rvActionFontBackColor1.OnHideColorPicker := ColorPickerHide;

  // Delphi 4 and 5 do not have ActionComponent property for actions.
  // Coloring actions have a substitution - CallerControl property
  // It is ignored in Delphi 6 and 7
  //rvActionsResource.rvActionParaColor1.CallerControl := ToolButton39;
  rvActionsResource.rvActionFontBackColor1.CallerControl := ToolButton38;
  rvActionsResource.rvActionFontColor1.CallerControl := ToolButton36;

  {$IFDEF RICHVIEWDEF6}
  // AutoComplete feature causes OnClick generation when editing combo-box's text.
  // Since in OnClick we move input focus in RichViewEdit1, this effect is
  // undesirable
  cmbFont.AutoComplete := False;
  cmbFontSize.AutoComplete := False;
  {$ENDIF}

  {self.RichViewEdit1.OnChange    := DoOnChange;
  self.RichViewEdit1.OnClick     := DoOnClick;
  self.RichViewEdit1.OnDblClick  := DoOnDblClick;
  self.RichViewEdit1.OnExit      := DoOnExit;
  self.RichViewEdit1.OnEnter     := DoOnEnter; }

  rvActionsResource.rvActionSave1.Visible := false; //No save menu item
  ToolButton2.Visible := false; //No save button
  RVRuler1.Visible := false; //No ruler
  SetLanguage(999); //Default language is International English

  //start
  rvActionsResource.rvActionNew1.ExecuteTarget(RichViewEdit1);

  //Remove RVT files as an option from save and open dialogs
   rvActionsResource.rvActionOpen1.Filter := rvActionsResource.rvActionOpen1.Filter - [ffiRVF];
   rvActionsResource.rvActionSaveAs1.Filter := rvActionsResource.rvActionSaveAs1.Filter - [ffeRVF];
end;
And then we get the null pointer och the system crashes. That is not so diffuclt to understand because rvActionsResource is never initiliazed. TrvActionsResource.Create(self); is commentended as you can see. But how did it run in delphi7 is beyound my intelligence..=).when I uncomment the line I dont get the nullpointer and the richview component appears and I can start using it. But when I have written som text and want to save the text, nothing is saved!

This is the code that executes when I press Save in the dialog:

Code: Select all

function TJvsRichTextEditor.GetText: string;
begin

  Result := self.RichViewEdit1.GetText;

end;



function TCustomRichViewEdit.GetText: string;
var
  rtfStream : TMemoryStream;
  rtfBuffer : string;
begin
  begin
    rtfStream := TMemoryStream.Create();
    rtfBuffer := '';
    try
      // When we save the text the rtfstream will add som
      //rtf information even thow we we didn't write any text
      if Self.Text<>'' then begin//
      Self.SaveRTFToStream(rtfStream, false);
      end;//
      rtfStream.Position := 0;
      SetLength(rtfBuffer, rtfStream.Size);
      rtfStream.ReadBuffer(Pointer(rtfBuffer)^, rtfStream.Size);
      Result := rtfBuffer;
    finally
      rtfStream.Free;
    end;
  end
end;
"Result" is empty and an empty string is saved. Why?

I Hope you can help me with my problem.
Thanks.

Posted: Wed Jun 20, 2007 1:27 pm
by Sergey Tkachenko
Check forms creation order.
Make sure that rvActionsResource is created before TJvsRichTextEditor.

Posted: Thu Jun 21, 2007 5:20 pm
by safbay
Hi, Sergey.

Thanks for your answer but I have already managed to correct the errors.

Error:
1) rvActionsResource is not initialized:
The error occured because of that in delphi 7 projektfile we told rvActionsResource to be autocreated but we missed that when we upgraded to delphi2007.

2) self.text (se the code above) in function TCustomRichViewEdit.GetText
returned an empty string.

The thing is that in delphi7 self.text ended up in:

Code: Select all

procedure TCustomRichView.WMGetTextLength(var Message: TMessage);
begin
  if (rvflCanProcessGetText in Flags) and
     not (csDestroying in ComponentState) then begin
    if ItemCount=0 then
      Message.Result := 0
    else
      Message.Result := RVGetTextLength(Self);
    end
  else
    inherited;
end;
and returned the correct string. But in Delphi2007 it didn't end up in "procedure TCustomRichView.WMGetTextLength".
That is because of the {$IFNDEF RICHVIEWDEF9} statement in RichView.pas :

Code: Select all

{$IFNDEF RICHVIEWDEF9}
    procedure WMGetTextLength(var Message: TMessage); message WM_GETTEXTLENGTH;
    procedure WMGetText(var Message: TMessage); message WM_GETTEXT;
    procedure WMSetText(var Message: TMessage); message WM_SETTEXT;
{$ENDIF}
So what i did was to change IFNDEF to IFDEF and now it works. Is it correct to do that??? Do I need to upgrade my version of the TRichview controller to a delphi2007 version, is there a delphi2007 version???
We use Trichview 1.9.24 together with the RichViewActions(ActionTest.dpr) demo projekt. Is there anything that I have to do or change because of that we are using delphi2007 now???

Thanks.

Posted: Fri Jun 22, 2007 1:25 am
by Sergey Tkachenko
WM_GETTEXT is blocked since Delphi 2005 because it conflicted with VCL implementation of this message. For example, application may crash when placing caret in table cell.
I do not recommend to activate this feature. Use other methods to get text from editor.

Posted: Fri Jun 22, 2007 12:26 pm
by safbay
Ok, thanks.
What other methods can I use?

Right now I am reading the text from the editor like this:

Code: Select all

function TCustomRichViewEdit.GetText: string; 
var 
  rtfStream : TMemoryStream; 
  rtfBuffer : string; 
begin 
  begin 
    rtfStream := TMemoryStream.Create(); 
    rtfBuffer := ''; 
    try 
      // When we save the text the rtfstream will add som 
      //rtf information even thow we we didn't write any text 
      if Self.Text<>'' then begin// 
      Self.SaveRTFToStream(rtfStream, false); 
      end;// 
      rtfStream.Position := 0; 
      SetLength(rtfBuffer, rtfStream.Size); 
      rtfStream.ReadBuffer(Pointer(rtfBuffer)^, rtfStream.Size); 
      Result := rtfBuffer; 
    finally 
      rtfStream.Free; 
    end; 
  end 
end; 
What do you suggest that I should do?

Thanks in advance.
//Safa

Posted: Sun Jun 24, 2007 7:42 am
by Sergey Tkachenko

Code: Select all

function TCustomRichViewEdit.GetText: string; 

  function IsEmpty: Boolean;
  begin
    Result := (ItemCount=0) or 
      ((ItemCount=1) and (GetItemStyle(0)=0) and (GetItemText(0)=''));
  end;

var 
  rtfStream : TMemoryStream; 
  rtfBuffer : string; 
begin 
  begin 
    rtfStream := TMemoryStream.Create(); 
    rtfBuffer := ''; 
    try 
      // When we save the text the rtfstream will add som 
      //rtf information even thow we we didn't write any text 
      if not IsEmpty then begin// 
      Self.SaveRTFToStream(rtfStream, false); 
      end;// 
      rtfStream.Position := 0; 
      SetLength(rtfBuffer, rtfStream.Size); 
      rtfStream.ReadBuffer(Pointer(rtfBuffer)^, rtfStream.Size); 
      Result := rtfBuffer; 
    finally 
      rtfStream.Free; 
    end; 
  end 
end; 

Posted: Sun Jun 24, 2007 7:55 pm
by safbay
Hello, Sergey..

Thanks for your guick answer.
But "function IsEmpty" doesn't alwalys work correct.

Scenario 1:
If type a word with the colour red and save it. If I then open the editor and delete the contents "IsEmpty" will return false. That is because GetItemStyle(0) returns 1.

Scenario 2:
If i type the word with no colour and save it and then deletes it, "IsEmpty" will return true. That is because GetItemStyle(0) returns 0 this time.

Should I change GetItemStyle(0)=0 to GetItemStyle(0)>=0 ??

Thanks.

Posted: Mon Jun 25, 2007 5:38 am
by Sergey Tkachenko
Yes, if you consider document without content but with modified text attributes empty.

Posted: Mon Jun 25, 2007 6:32 am
by safbay
Ok, thanks for your help. :)