RVFontComboBox and RVFontSizeComboBox association not workin

General TRichView support forum. Please post your questions here
Post Reply
PioPio
Posts: 41
Joined: Mon Feb 18, 2013 4:21 pm

RVFontComboBox and RVFontSizeComboBox association not workin

Post by PioPio »

Hello,

I am developing a component acting as a frame and containing several functions buttons bold, italic, foreground colour, Font selection and relevant size etc.
The idea is to drop this component in a form and then drop one of the TCustomRichView descendents. This way you can pilot all TCustomRichView descendants by one component.

My component is a TFrame descendant and the following is the object declaration:
type
TRVEditFrame = class(TFrame)
.....
private
{ Private declarations }
FRVEditor:TCustomRichView;
public
{ Public declarations }
FButtonSaveClick:TNotifyEvent;
protected
procedure notification(
acomponent:TComponent;aoperation:TOperation);override;
published
end;


I started developing the component and when it comes to associate RVFontComboBox1.Editor and RVFontSizeComboBox1.Editor to the TCustomRichView dropped the component crashes.

Below you will see the code. If I comment the two lines, as below, the component works fine but I don't have RVFontComboBox1.Editor and RVFontSizeComboBox1.Editor associated to TCustomRichView. That means you cannot see the list of the fonts and size as soon as the component is shown.

Code: Select all

procedure TRVEditFrame.notification(acomponent: TComponent;
  aoperation: TOperation);
begin
	inherited;
	if acomponent is TCustomRichView then
		if aoperation=opRemove then begin
			if acomponent=FRVEditor then
				FRVEditor:=nil;
		end
		else begin
  			FRVEditor:=TCustomRichView(acomponent);
//			RVFontComboBox1.Editor:=FRVEditor;
	//		RVFontSizeComboBox1.Editor:=FRVEditor;
		end;

How can I solve this ?

Many thanks
Pio Pio
Sergey Tkachenko
Site Admin
Posts: 17569
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

Are you sure, that at this line

Code: Select all

 FRVEditor:=TCustomRichView(acomponent); 
acomponent is always TCustomRichView? This code is called for all components inserted at the frame.
PioPio
Posts: 41
Joined: Mon Feb 18, 2013 4:21 pm

Post by PioPio »

Sergey Tkachenko wrote:Are you sure, that at this line

Code: Select all

 FRVEditor:=TCustomRichView(acomponent); 
acomponent is always TCustomRichView? This code is called for all components inserted at the frame.
Hi Sergey,

Just to make sure, I have amended the procedure this way:

Code: Select all

procedure TRVEditFrame.Notification(acomponent: TComponent;
  aoperation: TOperation);
begin
   inherited;
   if acomponent is TCustomRichView then begin
      if aoperation=opRemove then begin
         if acomponent=FRVEditor then
            FRVEditor:=nil;
      end
      else begin
         FRVEditor:=TCustomRichView(acomponent);
         RVFontComboBox1.Editor:=FRVEditor;
         RVFontSizeComboBox1.Editor:=FRVEditor;
      end;
  end
end;
Now I am 100% sure the part you point out is executed if acomponent is TCustomRichView or any descendant only.

I compiled the new version and made a test. The result is the same error First chance exception at $00405460. Exception class $C0000005 with message 'access violation at 0x00405460: read of address 0x00000000'. Process Project2.exe (5812)
Sergey Tkachenko
Site Admin
Posts: 17569
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

Yes, now this line is called when FRVEditor is created.
But it may be created before RVFontComboBox1 and/or RVFontSizeComboBox1, so they may be nil at this point.
PioPio
Posts: 41
Joined: Mon Feb 18, 2013 4:21 pm

Post by PioPio »

Sergey Tkachenko wrote:Yes, now this line is called when FRVEditor is created.
But it may be created before RVFontComboBox1 and/or RVFontSizeComboBox1, so they may be nil at this point.
So I should move the RVFontComboBox1 and/or RVFontSizeComboBox1 assignments where they are not nil. Problem is I don't know where as the container is a TFrame and there is no onshow method in TFrames.

What do you suggest ?

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

Post by Sergey Tkachenko »

Where are these compobox placed? Are they on the same frame?
PioPio
Posts: 41
Joined: Mon Feb 18, 2013 4:21 pm

Post by PioPio »

Sergey Tkachenko wrote:Where are these compobox placed? Are they on the same frame?
yes they are. Here below an excerpt of the code

Code: Select all

	TRVEditFrame = class(TFrame)
		ImageList: TImageList;
		Toolbar1: TToolBar;
		tbSave: TToolButton;
		....
		RVFontSizeComboBox1: TRVFontSizeComboBox;
		RVFontComboBox1: TRVFontComboBox;
	end;
Sergey Tkachenko
Site Admin
Posts: 17569
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

Override Loaded method of your frame:

Code: Select all

procedure Loaded; override;

Code: Select all

procedure TRVEditFrame.Loaded; override;
begin
  inherited;
  RVFontComboBox1.Editor:=FRVEditor; 
  RVFontSizeComboBox1.Editor:=FRVEditor; 
end;
If you place this frame on a form at designtime, this method will be called automatically, when this frame is created and all its subcomponents and properties are loaded.
If you create this frame in code at runtime, call this method manually after creation.
Sergey Tkachenko
Site Admin
Posts: 17569
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

Hmm... If all the components on the same frame, why cannot you simply assign this property in the Object Inspector?
PioPio
Posts: 41
Joined: Mon Feb 18, 2013 4:21 pm

Post by PioPio »

Sergey Tkachenko wrote:Hmm... If all the components on the same frame, why cannot you simply assign this property in the Object Inspector?
I didn't think to the Loaded method. This did the trick :-)

Referring to the question above. I could designate the property via Object Inspector but I was looking for something easy to use. Just drop the component and it works out of the box.

Many thanks
Pio Pio
Sergey Tkachenko
Site Admin
Posts: 17569
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

But if all the components are in the same frame, you can assign links between them when designing the frame, and they will be retained when you use this frame, am I right?
PioPio
Posts: 41
Joined: Mon Feb 18, 2013 4:21 pm

Post by PioPio »

Sergey Tkachenko wrote:But if all the components are in the same frame, you can assign links between them when designing the frame, and they will be retained when you use this frame, am I right?
Hi Sergey,

Yes, that was the initial idea. I tried the following code:

Code: Select all

type
	TRVEditFrame = class(TFrame)
		RVFontSizeComboBox1: TRVFontSizeComboBox;
		RVFontComboBox1: TRVFontComboBox;
	private
	 { Private declarations }
		FRVEditor:TCustomRichView;
	public
	 { Public declarations }
    procedure Loaded;override;
	protected
		function GetRVEditor:TCustomRichView;
		procedure SetRVEditor(Editor:TCustomRichView);
	published
		property RVEditor:TCustomRichView read GetRVEditor write SetRVEditor;
	end;

	
	
procedure TRVEditFrame.Loaded;
begin
  inherited;
  if Assigned(RVEditor) then 
    SetRVEditor(RVEditor);
end;

function TRVEditFrame.GetRVEditor:TCustomRichView;
begin
	Result:=FRVEditor;
end;

procedure TRVEditFrame.SetRVEditor(Editor:TCustomRichView);
begin
	if Assigned(Editor) then begin
		FRVEditor:=Editor;

      RVAControlPanel1.DefaultControl:=FRVEditor;
      RVFontComboBox1.Editor:=FRVEditor;
      RVFontComboBox1.Font.Name:=RVAControlPanel1.DialogFontName;
      RVFontSizeComboBox1.Editor:=FRVEditor;
      RVFontSizeComboBox1.Font.Name:=RVAControlPanel1.DialogFontName;

	end;
end;
Then I registered the component, dropped it on a form and linked RVEditor, RVFontSizeComboBox1 and RVFontComboBox1 to a TCustomRichViewEdit descendent I dropped on the component on design time.

I ran the project but RVFontSizeComboBox1 and RVFontComboBox1 don't show the font name and relevant size as they do in your examples ActionTestRibbon for instance.

It seems RVFontSizeComboBox1.Editor and RVFontComboBox1.Editor are set to nil at runtime but I don't know why.
Post Reply