Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Create, Save and Modify a form by code

Status
Not open for further replies.

Irwin1985

Programmer
Feb 2, 2017
44
ES
Hi everyBody,

How can i build a form by code, save it as scx file and in the end show it into the form designer?

I want to do a kind of builder where the user (programmer) select some custom controls I've done and in the end click "Generate Form" button.

I tried the following code but didn't work:

oForm = CREATEOBJECT("frmTest")
oForm.SaveAs("MyForm")
DEFINE CLASS frmTest as Form
Height = 300
Width = 400
AutoCenter = .T.
BorderStyle = 2
Caption = "My Form Sample"
MaxButton = .F.
MinButton = .F.
WindowType = 1
ShowWindow = 1
Name = "FrmSample"

Add OBJECT Label1 AS label WITH ;
AutoSize = .T., ;
FontName = "MS Sans Serif", ;
FontSize = 8, ;
Caption = "Hello Wolrd",;
Height = 19, ;
Left = 50, ;
Top = 15, ;
Width = 79, ;
TabIndex = 1, ;
Name = "Label1"
enddefine

But when I open the SCX i get the followin error:

screenshot.165_ce4amm.png


Could you give me an example about creating and saving a form by code?

Thank you all...!
 
The problem is that you are defining your form class (frmTest) in memory. The class definition is available when you call CREATEOBJECT() and SaveAs, but not when you are loading the SCX. At the point at which you load the SCX, VFP doesn't know where to find the frmTest class, hence the error.

Try saving the class defintion (DEFINE CLASS .... ENDDEFINE) to a PRG file (or create it visually as a VCX). Then, when you open the SCX, use either SET PROCEDURE or SET CLASSLIB to point to that file.

Mike



__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
I don't think this can be done through regular coding. As the help file states,
VFP SP2 Help File said:
Note that only objects created from Visual FoxPro base classes can be saved. User-defined classes cannot be saved.
On the other hand, there is nothing magical about SCX files, they are just regular VFP tables, so you could build an SCX from your code, but this will require a lot of parsing & hacking & knowledge. Fortunately, there is a tool that already provides such service: look at FoxBin2Prg and see how could you integrate it with what you're trying to accomplish.
 
Guys,

I tried this

Set Safety Off
oForm = Createobject('form')
oForm.AddObject('label1','label')
oForm.label1.Left = 10
oForm.label1.Top = 30
oForm.label1.Caption = "Hello World!"
oForm.label1.AutoSize = .T.
oForm.AddObject('text','textbox')
oForm.Text.Left = 10
oForm.Text.Top = 10
oForm.AddObject("bt_close","CommandButton")
oForm.bt_close.Left = 10
oForm.bt_close.Top = 50
oForm.bt_close.Caption = "Close"
oForm.bt_close.Height = 27
oForm.SaveAs("test")
Release oForm
Modify Form test

It works but is it the correct way? in the other hand, how can I put some code into bt_close click event?

Thanks...!
 
It works because you're saving an object created from a base class (that is, [tt]oForm = Createobject('form')[/tt], instead of [tt]oForm = CREATEOBJECT("frmTest")[/tt], in your first post.

If you need to have a command button with a particular behavior, then subclass the CommandButton class and add it to the forms in which you require the object.
 
Atlopes,

I'm not sure I agree with you. I think this should work:

Code:
DEFINE CLASS frmTest as Form
Height = 300
Width = 400
  etc etc
ENDDEFINE

Save the above code in SomeForm.PRG.

Now do this:

Code:
SET PROCEDURE TO SomeForm
oForm = CREATEOBJECT("frmTest")
oForm.SaveAs("MyForm")

And to open the form:

Code:
SET PROCEUDRE TO SomeForm
DO FORM MyForm

If I've misunderstood anything, my apologies.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Mike, it raises an error 1881 ("Parent: Class definition <...> is not found").

Doesn't it also, in your system?

António
 
Mike,

I followed your instructions but it did not work.!
 
Well, I just ran my code, exactly as I posted it, and it seems to work fine. (Of course, you need to take out "etc etc" from the class definition, which I assume you have done. But, in any case, that wouldn't give a "class defintion is not found" error.)

Just to be sure, I set a few more properties in the class definition, and checked that I could see those settings (e.g. BackColor) in the running form. I also tried MODIFY FORM, and that correctly showed the form, based on the class definition, in the designer.

Still, it's two-against-one, so I won't press the point. But it would be nice to know why it didn't work for António and Irwin.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
No, no, Mike, don't give up. There is something odd going down here that requires further testing, but you may have a point, despite what the Help file says. I'll be back to this later in the day.
 
A couple of possible explanations come to mind:

1. SomeForm.PRG isn't present on the search path at the point of opening or modifying MyForm; or

2. You forgot to issue [tt]SET PROCEDURE TO Someform[/tt] before opening or modifying MyForm.

In fact, I just tried both those scenarios, and in both cases got the same "Parent: Class definition <...> is not found" that António saw. So one of those could be the reason it didn't work for you two.

Mike



__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
It's no good idea to save a scx or vcx based on a prg class. This is going to fail.

Also notice, you can set the name property to something differing from the classname for an object you instanciate (regularly VFP names Textboxes Text1,Text2, etc.), but in a class definition the name property must be the class name as specified by DEFINE CLASS. It's not solved, though, if you set both names equal in your section of DEFINE CLASS frmTest. Mike is right, that you have problems later finding the base class definition. you would need to save your prg class definition and set the SCX classloc and VFP will not expect the reference to a PRG in an SCX or VCX classloc field. Notice by the CREATEOBJECT you do you instanciate your frmTest class and you don't save a scx based on the native form class but based on frmTest. Even if it would work you'd need the frmTest class and the SCX, not just the SCX.

The problem becomes more obvious, if you try to saveasclass, you get error 1965: "One of the members of this class is based on a nonvisual class. Cannot write .VCX file."
It's a wonder you don't get the similar error 1968: "One of the members of this Form or FormSet is based on a nonvisual class. Cannot write .SCX file."

Maybe SaveAs literally only checks for the objects/controls on the form, not for the form itself, though it's not working for itself, too. The messages hint on the concept not being supported overall.

Take a look at another approach:
This roots in the problem of SCC of VFPs binary SCX/VCX files, which is very similar.

On the other hand to create an SCX in code you can base this on CREATE FORM, as I did in faq184-6512
It has a weakness in saving the SCX via KEYBOARD hotkeys sent to the class or form designer. But it shows how to get an object reference to a form in design mode, so methods like WriteMethod() and ReadMethod() are available. Also see the topic of builders, BuilderB and BuilderD. I still have yet not done any builder, it should be doable to define one, that actually has no real user interface and can just be called to create a SCX or VCX class based on data the builder would find in files at predefined locations, perhaps. Both of these approaches would most probably not work within an EXE, only within the VFP IDE.

Bye, Olaf.

Edit: References to Builder B and Builder D:

The latter is quite self referential and has no flesh and blood and link to Doug Hennigs Builder D tool.
 
I think the behavior is somehow erratic, and so probably not a good idea to go through this way.

I confirm that Mike steps work, at least most of the time. Eventually, when MODIFYing the Form, an error "<procedureFileName>.fxp is not a table" pops up. Apparently, it is safe to Cancel on this error. In these cases the form is modifiable, but not always doable (that is, issuing [tt]DO FORM[/tt] does not execute the form and no error is raised).

A side effect - and this I think that is always reproducible - is that VFP let a file handle to the <procedureFileName>.fxp hanging around. [tt]SET PROCEDURE TO[/tt] does not release the file handle (and Windows Explorer can not delete it), as occurs normally when a procedure file is unloaded. The only way is to either leave VFP or execute a [tt]CLEAR ALL[/tt].
 
I'm also coming round to the view that this might not be the right way to go about it. Perhaps we need to go back to the beginning, and look for some better way of achieving the original goal.

Irwin, perhaps you could give some more information about what you want to let the user do that they cannot easily do for themselves using the form designer.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Thank you all,

I am trying to do the following:

1. I have created some container-based controls, I have them in a visual class I did to improve the look of an application.

2. Doing it manually would involve a lot of work and the programmer might not understand how the class works.

3. What I am trying to do is that the user can choose the controls through a wizard and press a button to generate the form.

Thank you...!
 
I don't see why you say (2). If you have container based controls, all a developer needs to do is drag&drop them on a form from the classlib.

classusage_uda13f.png

Just drag&drop.

I don't think you need a builder or wizard to let code do this for a developer. If there are lots of things to configure in properties of the outer container or even code needs to be written in some methods, well, if the functionality is complex then it might be worth it, otherwise think of extending the design, so everything can be setup in perhaps just a bunch of new properties.

One thing is for sure, you can add a builder to the VFP IDE and let a developer having your control class on the form discover it by right click and choosing "Builder..." from the context menu. That's the usual way builders act on a form, by being done from the form designer in the context of a selected control, not as assistant to add a control.

If you really like the full blown experience to guide a developer through creating a form with your control(s), the way to do that would be by a Wizard. How wizards are written is open source, existing wizards like form wizard are part of the XSource.zip package you can get from MS official VFP9 downloads or from
Bye, Olaf.
 
Thanks Olaf,

The problem is that it is not only a container, it is a ribbon that I made and it carries tabs, groups, labels, vertical lines, buttons, etc. Going all that in design time is very tedious and I have already commented to some colleagues who have a hard time understanding how the ribbon is armed. That's why I need an assistant to make life easier for them.

Thank you all for your interest in helping me.
 
Well, of course I don't think the container is empty. I understand a ribbon can be very dynamically populated by very different things. A wizard then could be a way or still a builder starting with a rather empty unpopulated ribbon class. Last not least even the ribbon code itself could contain options and dialogs to modify itself. Just like Office allows to show/hide some things via options or lets you group commands. Or just like VFPs Toolbox is extensible.

The tools for extending the IDE are there.

Bye, Olaf.
 
You should be able to use a builder to do what you want. Take a look at the builders that come with VFP for ideas on how that works.

Tamar
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top