Hi All
I'm would like to inherit ContextMenuStrip which is a MS Control.
This is what i do.
1. Create a new interited control from the menu - File\Abl Inherited Control. I fill up the name of the new control and i choose the control which i would like to inherit.
2. I add the new control into OpenEdge Controls.
3. Then the control is placed onto the form. As soon as i do this i'm getting error message:
Multiple markers at this line
- ** C:\PO Workspace\DataSetLab\hist.cls Could not understand line 504. (196)
- Mismatched number of parameters supplied to 'abc123'. Expecting 0 but 1 were
specified. (2680)
on the line which was just generated. THIS-OBJECT:abc1231 = NEW abc123(THIS-OBJECT:components).
Any help?
Thanks
Peter
I use OE 10.2b
Do you have a constructor that takes an components (System.ComponentModel.IContainer) argument?
-- peter
on the line which was just generated. THIS-OBJECT:abc1231 = NEW abc123(THIS-OBJECT:components).
The Visual Designer detects (using Reflection) that the base type has a constructor that takes an IContainer as a parameter. Just add:
CONSTRUCTOR PUBLIC abc123 (INPUT container AS System.ComponentModel.IContainer):
SUPER (INPUT container).
END CONSTRUCTOR .
To your abc123 (strange name, I'd say) class.
Do you have a constructor that takes an components (System.ComponentModel.IContainer) argument?
Probably not.
Mike,Peter
I'm sorry about the class name.
I did try your solution Mike. I'm getting another error message when i try to place object onto the form.
DYNAMIC-NEW cannot instantiate class poContextMenuStrip (already renamed ) because the wrong number of parameters were passed to the constructor, or the constuctor was not PUBLIC (14758).
I did try to inherit treeview with no problem.
Thanks
Peter
Did you remove the default constructor? Should have both ones.
One for runtime (IContainer) and one for adding it to the form (default constructor).
I did try to inherit treeview with no problem.
MS TreeView only has the default constructor, not the IContainer one. The ContextMenu is a Component (not a Control), so it's member of the Component container so that it can properly be disposed when the Form closes.
No i didn't. When i inherited the control there was only one constructor in the source code.
And what's the current status? There should be two constructors.
I've just created the new one. I ticked "Generate super class constructors" and the second constructor was created and all error messages disapeared.
CONSTRUCTOR PUBLICpoContextMenuStrip ( ):
SUPER( ).
InitializeComponent().
CATCH e AS Progress.Lang.Error:
UNDO, THROW e.
END CATCH.
END CONSTRUCTOR.
CONSTRUCTOR PUBLIC poContextMenuStrip ( INPUT container AS System.ComponentModel.IContainer ):
SUPER (INPUT container).
END CONSTRUCTOR.
Just another question. There is missing code in the second constructor. I know i can just copy it there from the first one but does it have any particular reason why it is not generated?
Thank you
Peter
Just another question. There is missing code in the second constructor. I know i can just copy it there from the first one but does it have any particular reason why it was not generated?
That should be asked to the developer of OEA. But I'd rather remove the CATCH block from the first constructor as well.
Thank you very much for all your effort Mike.
Have a nice weekend.
Peter
Have a nice weekend.
You must have missed the soccer score...
Have a nice weekend.
You must have missed the soccer score...
You're talking about 2-2 after being 0-2 down?
(Have no fear, the "Mannschaft" will be there at the end)
-- peter
(Have no fear, the "Mannschaft" will be there at the end)
It's easy to say when your personal bio give's you three teams
I'd contact tech support or log it in on the support website.
http://web.progress.com/en/support/index.html
Just another question. There is missing code in the
second constructor. I know i can just copy it there from the first one
but does it have any particular reason why it is not generated?
The default constructor is generated as part of the code that specifically deals with .net based code which knows you are building a form and it needs to call InitializeComponent. It always needs to be there, so it is always added. All the other constructors are handled in the generic class generating code (which the new form wizard gets most of its behavior) which does not know that you are dealing with .net code, so it isn't smart enough to generate the call to InitializeComponent.
But I'd rather remove the
CATCH block from the first constructor as well.
EEK! DON"T DO THAT. The catch block is there so that a proper exception is caught and thrown back to the designer if your code fails to construct the object properly. If it isn't there, no exception is thrown, just a generic ABL error, and the designer doesn't know what to do with it. In that case you get a very ugly OpenEdge dialog box which hangs the entire UI until you clear it.
The Visual Designer runs all of its UI code in the same thread the ABL is running in ( it is the same process after all). If an error occurs while creating the class (any ABL error), the Visual Designer has to wait until the dialog is cleared before it returns control back to .NET and the VD code. There are other bad things that happen when the UI thread is blocked by ABL dialogs, but that should be reason enough to leave it there.
The catch block is there so that a proper exception is caught and thrown back to the designer if your code fails to construct the object properly.
CATCH for the prupose of reTHROWing the error? Isn't that done by ROUTINE-LEVEL ON ERROR, UNDO THROW as well? What's the difference and where's that documented?
If that's really the case, I'd suggest to generate a warning comment (like on initializeComponents).
You can add the routine-level statement which will do the same thing if you really must and then you can remove catch block. But that statement is optional from the wizard.
The catch is also there to handle exceptions from the base class' constructor which need to make it out past the current constructor. Otherwise they'll end up as errors/dialogs if you don't rethrow them; not just for errors from InitializeComponent which has its own catch block. Unlike java/c# you have to catch and rethrow at every level. You can do it globally to a compilation unit (.cls/.p), or you can do it on individual blocks, but you have to get all of them. The thought was it was too easy (and optional) to remove the routine-level statement, so as insurance the catch rethrow gets added at every level so the designer doesn't end up blocked.
There is already a pending change request to add a warning comment to the code, but it hasn't been implemented yet.
You can add the routine-level statement which will do the same thing if you really must and then you can remove it. But that statement is optional from the wizard.
I'm glad to hear that RLOEUT does the same. Makes sense then and in our coding standard for all classes the statement is NOT optional, it's mandatory. And in 10.2B the OpenEdge Architect remembers your decision in the wizard.
Thank you for explanation Matthew.
Important is i know what to do now so i can finish my work. I was just quite confused because in visual studio a didn't have any problem like this.