Form object's event can't see inherited method - delphi

Problem summary: The OnClick event of a TForm object says that it can't find the method I specify; this method is defined in the Form's superclass, which I expected it to be inherited.
Here I define the base type (i.e. superclass) for the "RAM Editor" window, including a button and what its OnClick event should do.
// File: RAM_Editor_Common.pas
type
TfrmBaseRamEditor = class(TForm)
btnMapfileLaden: TToolButton;
procedure MapfileLaden1Click(Sender: TObject);
// ....
procedure TfrmBaseRamEditor.Mapfileladen1Click(Sender: TObject);
begin
if not OpenDialog2.Execute then Exit;
StatusBar1.Panels[2].Text := OpenDialog2.FileName;
end;
Here I define the sub-class:
// File: RAM_Editor_SXcp.pas
TfrmRAM_Editor_SXcp = class(RAM_Editor_Common.TfrmBaseRamEditor)
Here the sub-class's Form makes use of the button and sets the OnClick event to the method that was defined in the super-class:
// File: RAM_Editor_SXcp.dfm
object frmRAM_Editor_SXcp: TfrmRAM_Editor_SXcp
// ....
// ....
object btnMapfileLaden: TToolButton
Left = 75
Top = 0
Hint = 'Mapfile laden'
Caption = 'btnMapfileLaden'
OnClick = MapfileLaden1Click
ImageIndex = 5
ParentShowHint = False
ShowHint = False
end
But when I attempt to compile I get the error:
"The MapfileLaden1Click method referenced by btnMapfileLaden.OnClick does not exist. Remove this reference?"
Why can it not see the inherited method?

Your .dfm file is incorrect instead of:
object frmRAM_Editor_SXcp: TfrmRAM_Editor_SXcp
you need
inherited frmRAM_Editor_SXcp: TfrmRAM_Editor_SXcp
Similarly instead of:
object btnMapfileLaden: TToolButton
you need
inherited btnMapfileLaden: TToolButton
I guess you are trying to inject a common base class into an existing hierarchy. You've made the changes needed in the .pas file, but failed to make the corresponding changes needed in the .dfm file. The inherited keyword in the .dfm file is required by visual form inheritance.

Related

C++: How do I make a VCL component reference itself?

I'm using C++ Builder in RAD Studio 10.2. I'm not sure if I asked this correctly in the title, but what I'm trying to say is that whenever I use the C++ keyword 'this', it references the Parent of the component that I'm trying to access, but not the component itself.
For example, the code below changes the Form's color and font color instead of the Panel's color and font color:
void __fastcall TForm1::Panel1MouseEnter(TObject *Sender)
{
this->Color = cl3DLight;
this->Font->Color = clMaroon;
}
Also, if I do the same as above but omit the keyword 'this', it still changes the Form's properties instead of the Panel's (see code below).
void __fastcall TForm1::Panel1MouseEnter(TObject *Sender)
{
Color = cl3DLight;
Font->Color = clMaroon;
}
How would I code this so it accesses the Panel's 'Color' and 'Font->Color' instead of the Form's? Thank you.
Note: The reason that I haven't just done it as: Panel1->Color = "cl3DLight"; is because I'm trying to find a way to do it for components created at run-time.
The Sender parameter represents the component that is generating the event. You can typecast that pointer to the proper type in order to access that component's properties.
If you know for sure that everything attached to the event is a TPanel, you can typecast it directly (as Remy pointed out in comments below):
void __fastcall TForm1::Panel1MouseEnter(TObject *Sender)
{
TPanel *panel = static_cast<TPanel *>(Sender);
panel->Color = cl3DLight;
panel->Font->Color = clMaroon;
}
If you're using the same event handler for different control types, you can test for the appropriate type instead:
void __fastcall TForm1::Panel1MouseEnter(TObject *Sender)
{
TPanel *panel = dynamic_cast<TPanel *>(Sender);
if (panel)
{
panel->Color = cl3DLight;
panel->Font->Color = clMaroon;
}
}

how to use overridden methods defined in a class, in another class?

I am having some problems in an exercise that I'm doing for the graphical interfaces course. I'm writing a program in F# defined in this way:
I have a class A, in which I override the method OnPaint;
I have another class B, in which I override the OnPaint method, OnMouse[Down/Move/Up] methods, etc.
I would use the overridden OnPaint method in A into the overridden OnPaint method defined in B (obviously, the OnPaint method in A, is defined in the class A, which means that I have to instantiate a type A object).
My question is: how can I do that? Do I need to define necessarily a method in A in which I pass a PaintEventArgs.Graphics parameter with the same tasks of the OnPaint method of A instead of override the OnPaint method in A?
An example:
I've to do something like this:
type Ellipse() =
...
override this.OnPaint e =
e.Graphics.DrawEllipse(10.f, 10.f, 30.f, 30.f)
type classThatUseEllipse() =
let ell = new Ellipse()
...
override this.OnPaint e =
ell.OnPaint(e)
Or something like this?:
type Ellipse() =
...
let myOnPaint (e:PaintEventArgs) =
e.Graphics.DrawEllipse(10.f, 10.f, 30.f, 30.f)
type classThatUseEllipse() =
let ell = new Ellipse()
...
override this.OnPaint e =
ell.myOnPaint(e)
Or these two versions are the same?
I'm asking this because often the first version gave problems.

How to update polymer element attribute from dart code

I am trying to learn dart and polymer. Here repository that I try to learn on:
https://bitbucket.org/romanoff/polymer_sample
When I try to set attribute from dart code of one custom element to other custom element, it doesn't seem to work. Here is line where I try to do this:
https://bitbucket.org/romanoff/polymer_sample/src/f8314627fe8eee9f6fde58c300acf081b396f927/web/clickcounter/clickcounter.dart?at=master#cl-33
Have also tried following options:
var timer = $['timer'].xtag;
timer.textValue = 'Text value set form attached handler';
var timer = $['timer'];
timer.setAttribute('textValue', 'Text value set form attached handler');
There are two ways
$['timer'].attributes['textValue'] = 'Text value set form attached handler';
or
import 'path_to_dart_file_containing_timer_component#;
...
($['timer'] as MyTimer).textValue = 'Text value set form attached handler';
where MyTimer is the name of the class of your timer element
and your timer component class has a field
#published String textValue;

FMX - Cancel URL loading

Is there any way to cancel URL loading using property TCustomWebBrowser.OnShouldStartLoadWithRequest?
Type of this property is declared as
TWebBrowserShouldStartLoadWithRequest = procedure(ASender: TObject; const URL: string) of object;
So it doesn't return any value based on which one could decide whether to stop or continue URL loading...

How do you pass statements through an addEventListener?

Iv been trying to pass arguments through an addEventListener event in actionscript such as...
target.addEventListener("pComp", rakeSoil(target));
but i get errors.
Iv tried to google but no luck :/
Thanks for replying if you do :)
The target is already passed as part of the event, either event.currentTarget or event.target will be what you want.
If you want something else passed, create a custom event. Add the property to the custom event.
Try adding an additional method as your event listener:
target.addEventListener ("pComp", targetListener);
...
private function targetListener (event:Event):void {
rakeSoil (event.currentTarget);
}
How this is what you want:
{
var target:EventDispatcher = ...;
Function rakeSoil = function (e:Event):void
{
// handle target
}
target.addEventListener("pComp", rakeSoil);
}
rakeSoil is a first class function(or closure), when event is dispatched, it will be invoked, and you can access 'target' in it.
EDIT:
Have a look at Closure (computer science)
I have always found anonymous functions to be more trouble than they are worth. I would simply follow the standard event handler code layout. It's more formal and takes a little more effort up front, but there is no ambiguity and it is far more readable when you return to it a year from now (reduces head-scratching duration):
// Target extends EventDispatcher
private var target:Target;
public function listenToTarget();
{
target = new Target();
target.addEventListener("pComp", pCompHandler);
}
private function pCompHandler(event:Event):void
{
target.rakeSoil();
}
Although, now that I look at it more closely, why are you having this object do something that Target should be capable of handling internally on its own?

Resources