1

Konu: Creating form with objects on it programatically

Hello:

I have only created forms with the Form designer before, never programatically. Now, however, I would like to create a menu on a form with a container on the form and a command button group on the container. The user will enter the number of buttons and their captions in a config file, and from those values, and some set formulas, I want the size of the buttons, the distance between them, and the distance between the buttons and the four sides of the container to be calculated (I think I can figure that part out). However, I assume I need to do this programaticall, but I do not know how to create a form with a container on it, and a command button group on the container. How, in essence, do you do it?

Thanks,

Hans L

2

Re: Creating form with objects on it programatically

Here is a rough sample as a starter:

Visual Fox Pro
Create Cursor buttonGroup (GroupId i, pixelsBetween i, layOut c(1))

Insert Into buttonGroup Values (1,5,'V')
Insert Into buttonGroup Values (2,2,'H')
 
Create Cursor buttonDef (buttonCaption c(50),  buttonGroup i)
Insert Into buttonDef Values ('Caption X 1',  1)
Insert Into buttonDef Values ('Caption X 2',  1)
Insert Into buttonDef Values ('Caption X 3',  1)
Insert Into buttonDef Values ('Caption X 4',  1)
Insert Into buttonDef Values ('Caption X 5',  1)
Insert Into buttonDef Values ('Caption Y 1',  2)
Insert Into buttonDef Values ('Caption Y 2',  2)
Insert Into buttonDef Values ('Caption Y 3',  2)
 
Public oForm
oForm = Createobject('myForm')
oForm.Show()
 
Define Class myForm As Form
  Add Object btnAddButtons As CommandButton With Top=5,Left=5,Caption="Add buttons"
  Add Object buttonContainer As Container With Top=35,Left=10
 
  Procedure btnAddButtons.Click
    Local lnTop,lnLeft,ix, lcName, lnHeight, lnWidth, lnR, lnB
    Store 0 To lnTop,lnLeft,lnR,lnB
    Select buttonGroup
    Scan
      Select buttonCaption From buttonDef Where buttonGroup=buttonGroup.GroupId Into Array aButtons
 
      lcName = Textmerge('btnGroup<<PADL(buttonGroup.groupId,2,"0")>>')
      Thisform.buttonContainer.Newobject(m.lcName,'CommandGroup')
 
      With Evaluate('thisform.buttonContainer.'+m.lcName)
        .Top = m.lnTop
        .Left = m.lnLeft
        Store 0 To lnHeight, lnWidth
        .ButtonCount = Alen(aButtons)
        For ix = 1 To .ButtonCount
          With .Buttons[m.ix]
            .Caption = Trim(aButtons[m.ix])
            .Width = 100
            .Height = 30
            If buttonGroup.layOut = 'V'
              .Top  = (m.ix - 1) * (.Height + buttonGroup.pixelsBetween)
              .Left = 0
            Else
              .Top  = 0
              .Left = (m.ix - 1) * (.Width + buttonGroup.pixelsBetween)
            Endif
            lnHeight = .Top + .Height
            lnWidth = .Left + .Width
          Endwith
        Endfor
        .Height = m.lnHeight
        .Width = m.lnWidth
        If buttonGroup.layOut = 'V'
          lnLeft = .Left + .Width + 10 && a little spacing
        Else
          lnTop = .Top + .Height + 10
        Endif
        .SetAll('Visible',.T.)
        .Visible = .T.
        lnR = Max(m.lnR, .Left + .Width)
        lnB = Max(m.lnB, .Top + .Height)
      Endwith
    Endscan
    Thisform.buttonContainer.Height = m.lnB
    Thisform.buttonContainer.Width = m.lnR
  Endproc
Enddefine

3

Re: Creating form with objects on it programatically

This is rough? :-) I'll start looking at it right away.  Thanks,

Hans

4

Re: Creating form with objects on it programatically

Well, I did not look at this right away, but now I have, and I have experimented a lot.

I have one crucial question. In the program above, if I do not want to click a button in order to get the other buttons to appear, what should i do? Let me be more specific.

---------------
Define Class myForm As Form

*  Add Object btnAddButtons As CommandButton With Top=5,Left=5,Caption="Add buttons"

  Add Object buttonContainer As Container With Top=35,Left=10


  Procedure btnAddButtons.Click

.....

------------------------------

I have "commented out" (*) one line above, and I do not want "Procedure btnAddButtons.Click" to be a click procedure. I want the menu buttons to appear without clicking  when I run this program, but I have not been able to figure out how to do it. I would want the "Procedure" to be exactly as is, and to "run" it without having to click a button.

Any tip would be welcome.

Regards,

Hans L

5

Re: Creating form with objects on it programatically

You would simply give a custom procedure name to that btnAddButtons.Click. Like this:

Visual Fox Pro
Define Class myForm As Form

  Add Object btnAddButtons As CommandButton With Top=5,Left=5,Caption="Add buttons"
  Add Object buttonContainer As Container With Top=35,Left=10
 
  Procedure AddButtonsFromDefinition && btnAddButtons.Click
    Local lnTop,lnLeft,ix, lcName, lnHeight, lnWidth, lnR, lnB
    Store 0 To lnTop,lnLeft,lnR,lnB
    Select buttonGroup
    Scan
      Select buttonCaption From buttonDef Where buttonGroup=buttonGroup.GroupId Into Array aButtons
 
      lcName = Textmerge('btnGroup<<PADL(buttonGroup.groupId,2,"0")>>')
      Thisform.buttonContainer.Newobject(m.lcName,'CommandGroup')
 
      With Evaluate('thisform.buttonContainer.'+m.lcName)
        .Top = m.lnTop
        .Left = m.lnLeft
        Store 0 To lnHeight, lnWidth
        .ButtonCount = Alen(aButtons)
        For ix = 1 To .ButtonCount
          With .Buttons[m.ix]
            .Caption = Trim(aButtons[m.ix])
            .Width = 100
            .Height = 30
            If buttonGroup.layOut = 'V'
              .Top  = (m.ix - 1) * (.Height + buttonGroup.pixelsBetween)
              .Left = 0
            Else
              .Top  = 0
              .Left = (m.ix - 1) * (.Width + buttonGroup.pixelsBetween)
            Endif
            lnHeight = .Top + .Height
            lnWidth = .Left + .Width
          Endwith
        Endfor
        .Height = m.lnHeight
        .Width = m.lnWidth
        If buttonGroup.layOut = 'V'
          lnLeft = .Left + .Width + 10 && a little spacing
        Else
          lnTop = .Top + .Height + 10
        Endif
        .SetAll('Visible',.T.)
        .Visible = .T.
        lnR = Max(m.lnR, .Left + .Width)
        lnB = Max(m.lnB, .Top + .Height)
      Endwith
    Endscan
    Thisform.buttonContainer.Height = m.lnB
    Thisform.buttonContainer.Width = m.lnR
  Endproc
Enddefine

and you would explicitly call it from anywhere you want (typically form.Init):

Visual Fox Pro
thisform.AddButtonsFromDefinition()

You might also have Procedure btnAddButtons.Click calling the same thisform.AddButtonsFromDefinition() - unlikely but you can.

6

Re: Creating form with objects on it programatically

Thank you very much, Cetin. I'll try it out this afternoon (if my eyes will allow it; I am going to the eye doctor this morning, and will get drops to dilate my eyes :-(

Hans L

7

Re: Creating form with objects on it programatically

Oh you are going to get Atropin! I don't think that you could try after Atropin, your vision would be blurred. Wish you recover soon.

8

Re: Creating form with objects on it programatically

Close! On the list of medication that my doctor gave me, Atropine is on the row below the one he prescribed to me, namely Brimonidine (generic, cheap ... or cheaper :-) (it was called "Alphagan before). It is a replacement for Travatan, which made my eyelashes grow fast, and some grew inward and irritated my eye).

This is for glaucoma.

However, the drops I talked about originally were drops to dilate my eyes for the examination. However, I can see very well now. I have noticed that my doctor  lately have given me dilation drops that affect me seeing much less than in the past. Great!

I also have macular degeneration ("wet") in my left eye, and I got two shots in the eye, on Dec 2007 and Jan 2008, and I have needed no more shots since then.

Living in Cleveland, where the famous Cleveland Clinic is located, does not hurt when you have these things.

Regards,

Hans L

9

Re: Creating form with objects on it programatically

Hm, I made the changes to the code, but I still do not know how to call the procedure (I understand the changes, though).

I assume I will run the file with the code above (let's call it Mainmenu.prg) from the main file (the one that starts the whole application. Let's call it "Main.prg).

So, Mainmenu runs (I actually just highlight Mainmenu and click Run in the Project Manager). and with the code as it is now, the result is a form with a container. But I want to run the procedure at the same time, so I tried the following:

...

Visual Fox Pro
ENDDEFINE

 
Thisform.AddButtonsFromDefinition()


(and a few variations), but it does nothing. How do I get the procedure to run at the same time? 


-------------------

I also have two other questions regarding the code:


Visual Fox Pro
Public oForm

 
oForm = Createobject('myForm')
 
oForm.Show()


As far as I can glean from the documentation, myForm should be an existing class, but it is not created until later:

Visual Fox Pro
Define Class myForm As Form


How come it still works?

--------------

Visual Fox Pro
Define Class myForm As Form

 
  Add Object btnAddButtons As CommandButton With Top=5,Left=5,Caption="Add buttons"
 
  Add Object buttonContainer As Container With Top=35,Left=10

Am I correct in assuming that the reason one would make a class here is that otherwise, one could not add the objects btnAddButtons and buttonContainer to the form?


As you can see from my questions, I am very uncertain about the reasons for and order of this coding. Thanks in advance for a brief explanation.

Regards,

Hans L

10

Re: Creating form with objects on it programatically

Oh I see your confusion.
First, I am against public variables (except a special one created in main.prg - custom application object). I use public oForm and all those define ... enddefine just for the sake of being able to send a testable form in pure code on a forum. Normally I would use form designer as any other human:)

Using form designer it would be easy to understand.
1) Create a new form - say named TestForm
Modify form TestForm

2) Put a Container from form controls toolbar on to form and name it "buttonContainer" - same name in our sample.

3) From menu, Form\New method and name it "AddButtonsFromDefinition" - again just for the sake of keeping naming same with the sample

4) Open the code window for that new method
-either from properties window locate and dblclick on method name
-or dblclick on form and select "AddButtonsFromDefinition" from drop down on top right

5) Paste the code between:
Procedure AddButtonsFromDefinition && btnAddButtons.Click
...
endproc

removing those 2 lines (paste the body of the code only)

6) Assuming wewould do the call in form.Init, open form's Init method code window and add:

thisform.AddButtonsFromDefinition()

7) Save and run the form (assumed you already had the definitions cursor/table)

If we were doing this in code then would add this code:

Visual Fox Pro
Define Class myForm As Form

  Add Object btnAddButtons As CommandButton With Top=5,Left=5,Caption="Add buttons"
  Add Object buttonContainer As Container With Top=35,Left=10
 
        *** Here is new codeaddition
       Procedure Init
           thisform.AddButtonsFromDefinition()
      endproc
 
* ... other codes as before
enddefine

In other words

Visual Fox Pro
define class ....

   add ....
...
enddefine

are simply programmatic way of defining a form in code (without a VCX or SCX), we didn't really needed it to be a class but wanted to be able to post on forum (otherwise I would need to zip and send scx/sct files).

11

Re: Creating form with objects on it programatically

Okay, Cetin, while I have not looked at your post in detail, I have been enlightened. I thought, based on the post of yours that I have read, that you avoided designers like pest, and that you created as much as you could in code. Okay, I now have to turn my mind around 180 degrees :-)

I will read your post tomorrow (when I sober up ... okay, not sober up, but when I am less tired). No matter what, I have learned a lot from reading your previous posts.

Always a pleasure,

Hans L

12

Re: Creating form with objects on it programatically

Now, I have worked through this, created a form and a container, and got something that works more or less as I want ti (but not entiely yet). I have one question, but will post the code first.

Visual Fox Pro
Create Cursor buttonGroup (GroupId i, pixelsBetween i)

 
Insert Into buttonGroup Values (1,15)
 
 
 
* Buttons, max. 9, and max 25 characters per label (check for these two restrictions)
 
 
Create Cursor buttonDef (buttonCaption c(50),  buttonGroup i)
 
Insert Into buttonDef Values ('\< ',  1)
Insert Into buttonDef Values ('\<APPLICATIONS', 1)
Insert Into buttonDef Values ('\< ',  1)
Insert Into buttonDef Values ('\< ',  1)
Insert Into buttonDef Values ('\<HARDWARE', 1)
Insert Into buttonDef Values ('\< ',  1)
Insert Into buttonDef Values ('\< ',  1)
Insert Into buttonDef Values ('\<SETTINGS', 1)  && This must be next to the last menu option.
Insert Into buttonDef Values ('\<EXIT', 1)      && This must be the last menu option.
 
*
 
Local lnTop, lnLeft, ix, lnCaplen, lnButtonHeigth, lnButtonwidth
 
Store 0 To lnTop,lnLeft, lnCaplen
 
lnButtonHeight = 30
 
Select buttonGroup  && Activates cursor (temporary table)
 
SCAN
 
    Select buttonCaption From buttonDef Where buttonGroup=buttonGroup.GroupId AND buttonCaption <> '\< ' Into Array aButtons
 
    Thisform.buttonContainer.Newobject('cmgMenugroup','CommandGroup')
 
*    Thisform.buttonContainer.Newobject('lblMainmenu','Lable')
 
*    Thisform.buttonContainer.Newobject('linMainmenu','Line')
 
 
 
    With Thisform.buttonContainer.cmgMenugroup  && Commandgroup
 
        .Top = 60  && m.lnTop
 
        .Left = 10  && m.lnLeft
 
        Store 0 To lnHeight, lnWidth
 
        .ButtonCount = Alen(aButtons)
 
        FOR ix = 1 TO .ButtonCount
 
            WITH .Buttons[m.ix]    &&                                 THIS LINE 1         
 
                .Caption = Trim(aButtons[m.ix])  &&               THIS LINE 2
 
                IF lnCaplen < LEN(.Caption) 
 
                    lnCaplen = LEN(.Caption) && lnLblblen = width of the widest label
 
                ENDIF
 
                .Height = lnButtonHeight
 
                .Top  = ((m.ix - 1) * 1.5 * .Height) + buttonGroup.pixelsBetween
 
                .Left = 15
 
            ENDWITH
 
        ENDFOR
 
           lnCaplen = lnCaplen - 2  && lnCaplen = length of the longest caption
 
           lnButtonwidth = 20 + (lnCaplen * 10)
 
        .Height = (.ButtonCount * lnButtonHeight) + ((.ButtonCount + 1) * buttonGroup.pixelsBetween)
 
       .buttons[m.ix].width = lnCaplen  &&  THIS LINE 3 : I get error message that "Buttons" is not an object.
 
        .Width = lnButtonwidth + 20
 
        .Left = 10 && a little spacing
 
        .SetAll('Visible',.T.)
 
        .Visible = .T.
 
    ENDWITH
 
ENDSCAN
 
WITH Thisform.buttonContainer
 
    .Height = .cmgMenuGroup.Height + 75
 
    .Width = .cmgMenuGroup.Width + 20
 
    .Top = 50
 
    .Left = 100
 
ENDWITH



I looked at the two lines && THIS LINE 1 and && THIS  LINE 2, and thought they were in essence the same as && THIS LINE 3. What I want to do at && THIS LINE 3 is to set the width of all buttons in the command group to the same width. Since this does not seem to work, how could I do it?

Hope this is clear enough. The code is a modification of your code above. (I think I can also eliminate the array and just work with the cursor, but that is for later.)

Regards,

Hans L

13

Re: Creating form with objects on it programatically

They would be essentially the same if THIS LINE 3 was in for loop too. The error message is a bit misleading. "Buttons" exists as a collection, but after the loop m.ix has a value of actual buttoncount + 1, hence Buttons[m.ix] doesn't exist. In other words:

Visual Fox Pro
for ix = 1 to 5

*do nothing
endfor
? m.ix && prints 6

I made a little touch to code:

       
       

Visual Fox Pro
.ButtonCount = Alen(aButtons)

 
        LOCAL lnWMax
        lnWMax = 0
        For ix = 1 To .ButtonCount
          With .Buttons[m.ix]    &&                                 THIS LINE 1
            .Caption = Trim(aButtons[m.ix])  &&               THIS LINE 2
 
            .Height = m.lnButtonHeight
 
            .Top  = ((m.ix - 1) * 1.5 * .Height) + buttonGroup.pixelsBetween
 
            .Left = 15
 
            .Autosize = .T.
            .Visible = .T.
            lnWMax = MAX(.Width, m.lnWMax)
            .Autosize = .F.
 
          Endwith
        Endfor
 
        .Height = (.ButtonCount * lnButtonHeight) + ((.ButtonCount + 1) * buttonGroup.pixelsBetween)
 
        .SetAll('Width', m.lnWMax)  &&  THIS LINE 3 : I get error message that "Buttons" is not an object.
 
        .Width = m.lnWMax + 15 * 2
 
        .Left = 10 && a little spacing
 
        .SetAll('Visible',.T.)
 
        .Visible = .T.

If you use len() instead, what you get is width in characters but you need the width in pixels. Autosizing the button and then getting width is a simple way to do it without using win32 API.

14

Re: Creating form with objects on it programatically

Aha, the loop!!!  Will look at your new code.

Thank you, Cetin.

Hans L

15

Re: Creating form with objects on it programatically

Cetin, in your first post of this thread, with the large code chunk, there is a Scan...Endscan, and within that Scan...Endscan, there is a For...Endfor (see below).  I have a question about this. The scan means that the records of the cursor are scanned, one after the other. I assume that this means that for each record, the For...Endfor does its thing, and the same thing, for every record. If this is correct, its seems to be extra work (time), but I assume that you put the For...Endfor where you put it because it was easier and more efficient than trying to put it outside the scan!? 

I have the same situation now, trying to get basically the same For...Endfor to work outside the Scan, but if I do not have to, I may as well leave it inside the Scan...Endscan.


Visual Fox Pro
For ix = 1 To .ButtonCount

 
          With .Buttons[m.ix]
 
            .Caption = Trim(aButtons[m.ix])
 
            .Width = 100
 
            .Height = 30
 
            If buttonGroup.layOut = 'V'
 
              .Top  = (m.ix - 1) * (.Height + buttonGroup.pixelsBetween)
 
              .Left = 0
 
            Else
 
              .Top  = 0
 
              .Left = (m.ix - 1) * (.Width + buttonGroup.pixelsBetween)
 
            Endif
 
            lnHeight = .Top + .Height
 
            lnWidth = .Left + .Width
 
          Endwith
 
Endfor

Thanks,

Hans L

16

Re: Creating form with objects on it programatically

Hans,
There are 2 cursors, one for the group and one for the items in that group. That means two loops. Those loops both might be scan...endscan, for...endfor or a mix (what I did was a mix - scan outer groups and for ... endfor items per group).

17

Re: Creating form with objects on it programatically

Yes, I know. But what I am saying is that for every turn of the outer loop, the inner loop does all its turns.

Hans L

18 Son düzenleyen, Hans L (29.01.2010 05:42:56)

Re: Creating form with objects on it programatically

I have continued to attempt to have menu option names and click event commands entered in only one place. Therefore, I have the following.


Main.prg -> Form A, Init -> Form A, Method X -> Z.prg, procedure MenuAgain -> etc.

Visual Fox Pro
*  [Form A, method X]

 
* Entering menu option names
* Entering click event commands (lcClick1 ... lcClick9)
...
 
Thisform.Newobject('cntMenuContainer','Container')  && Creating a container
 
DO MenuAgain WITH lcClick1, lcClick2, lcClick3, lcClick4, lcClick5,lcClick6, lcClick7, lcClick8, lcClick9
 
THISFORM.cntMenuContainer.NewObject('cmgMenugroup',clCommandGroup)
 
* Setting other values for commandbuttons, commandgroup and, container]
 
 
*  [Z.prg]
 
PROCEDURE MenuAgain LPARAMETERS lcClick1, lcClick2, lcClick3, lcClick4, lcClick5,lcClick6, lcClick7, lcClick8, lcClick9
 
     LOCAL lnRecordCount
 
     lnRecordCount = 0
 
    DEFINE CLASS clCommandGroup as CommandGroup
 
 
        SCAN FOR LEN(TRIM(ButtonCaption)) > 2
 
            lnRecordCount = lnRecordCount + 1
 
        ENDSCAN
 
        *
 
        ButtonCount = lnRecordCount
 
        *
 
        PROCEDURE Click
 
 
            DO CASE
 
                CASE This.Value = 1
 
                    &lcClick1
 
                CASE This.Value = 2       
 
                    &lcClick2
 
                …
 
            ENDCASE
 
        ENDPROC
 
    ENDDEFINE
 
ENDPROC

In Z.prg, at "LOCAL lnRecordCount", the "program" crashes, and shows the following error: “No PARAMETER statement is found” for “PROCEDURE Click”.

At one point, I did not have

    LOCAL lnRecordCount
   
    lnRecordCount = 0

and then, the "program" crashed at "PROCEDURE Click", with the same error message.

How come I get this error message?

Thanks,

Hans L

19

Re: Creating form with objects on it programatically

Ooooops, I did not realize that it had to be

PROCEDURE MenuAgain

LPARAMETERS lcClick1, lcClick2, lcClick3, lcClick4, lcClick5,lcClick6, lcClick7, lcClick8, lcClick9


Regards,

Hans L

20

Re: Creating form with objects on it programatically

You found the first typo. However there are others.
You cannot define ... enddefine a class in a procedure. In a code file, place define class ... enddefine (can be multiple) as the last part of commands.
I wouldn't use &lcClick but since I couldn't exactly understand the scenario can't suggest what to do instead (probably I would suggest using textmerge instead and compile the class code).

21

Re: Creating form with objects on it programatically

In the form method, I have

Visual Fox Pro
TEXT TO lcClick1  && Code for 1st button

 
    QUIT  [Just as an example]
 
ENDTEXT

Them, lcClick1 is 'sent' as a parameter to the prg file, where it looks like this:

do case

    case this.Value = 1

        &lcClick1
...


Regards,

Hans L

22

Re: Creating form with objects on it programatically

One more thing:

In the prg file, when I have this:

Visual Fox Pro
DEFINE CLASS clCommandGroup as CommandGroup

 
SET STEP ON
 
        ButtonCount = lnRecCnt
 
         PROCEDURE Click
 
            DO CASE
 
        CASE This.Value = 1
 
                &lcClick1

the horizontal, yellow button jumps directly to "PROCEDURE Click", thus bypassing both "DEFINE CLASS ..." and "ButtonCount = lnRecCnt".

That is strange, I believe. Seems nothing is defined.

Hans L

23

Re: Creating form with objects on it programatically

I have simplified the code.

Form method:

Visual Fox Pro
DO Main_Menu_Again.prg

Prg:

Visual Fox Pro
DEFINE CLASS clCommandGroup AS CommandGroup

 
    lnRecCnt = 4
 
    ButtonCount = lnRecCnt
 
    PROCEDURE Click
 
        DO CASE
 
            CASE This.Value = 1
 
                [Command 1]
 
            ...


Form method

Visual Fox Pro
THISFORM.cntMenuContainer.NewObject('cmgMenuGroup','clCommandGroup')


Error:  Class definition CLCOMMANDGROUP is not found.

What am I doing wrong?

Regards,

Hans L

24

Re: Creating form with objects on it programatically

set step on
should be at somewhere where there is procedural code. That is why it directly jumps to procedure. You have it at somewhere where it is unpredictable.
You are using object.NewObject method (there is also Newobject() function). object.Newobject syntax is:

object.NewObject( objectName, className, classLibName )

If you do not include classLibName parameter then the className should be in scope ( ie: 'set classlib to' which I never suggest to use ).

Also I repeat that you should avoid & as much as possible. & doesn't have a use case in VFP except in some SQL strings.

From what I understood so far I would do it like:

Visual Fox Pro
Local lcClassCode, lcCodeFile

lcClassCode = MenuAgain(m.lcClick1,m.lcClick2,...m.lcClick9)
lcCodeFile=Forcepath('MyClass.prg',Sys(2023))
Strtofile( m.lcClassCode, m.lcCodeFile)
Compile (m.lcCodeFile)
 
Thisform.cntMenuContainer.Newobject('cmgMenuGroup','clCommandGroup',m.lcCodeFile)
Thisform.cntMenuContainer.Visible = .T.
 
Procedure MenuAgain
  Lparameters lcClick1, lcClick2, lcClick3, lcClick4, lcClick5,lcClick6, lcClick7, lcClick8, lcClick9
  Local lnRecordCount
  lnRecordCount = 0
  *!*      Scan For Len(Trim(ButtonCaption)) > 2
  *!*        lnRecordCount = m.lnRecordCount + 1
  *!*      Endscan
 
  Local Array aButtonCount[1]
  Select Count(*) ;
    FROM myWhateverTableIsScanned ;
    WHERE Len(Trim(ButtonCaption)) > 2 ;
    INTO Array aButtonCount
  lnRecordCount = aButtonCount[1]
 
  Local ix, lcMyClass
  Set Textmerge To Memvar lcMyClass Noshow
  Set Textmerge On
\\Define Class clCommandGroup As CommandGroup
ButtonCount = << m.lnRecordCount >>
Procedure Click
\    Do Case
  For ix=1 To m.lnRecordCount
\      Case This.Value = << m.ix >>
\        << EVL(EVALUATE( 'm.lcClick' + LTRIM(STR( m.ix ))),'') >>
  Endfor
\    Endcase
Endproc
\Enddefine
  Set Textmerge To
  Set Textmerge Off
  Return m.lcMyClass
Endproc

However, I still think, if you know those codes at design time, then why is the need it to write it as if it is something decided and done at runtime.

25

Re: Creating form with objects on it programatically

cetinbasoz yazdı:


However, I still think, if you know those codes at design time, then why is the need it to write it as if it is something decided and done at runtime.


Thanks, Cetin.

I will only respond now to your last question. Nothing is decided upon or done by me, as the developer or user, at runtime. I am just striving at having a program structure such that I, as the developer, can use this menu program for almost all of my future applications. That means that I want to be able to enter menu option text and click commands in as simple a way as possible. All other parameters are determined by these two sets of data.

Once I enter the menu option text, the program is coded so that it sets all dimensions for the commandbutttons, commandgroup and container based on the width of the widest button and the number of buttons. The only thing that created in advance is the form, which I may be able to make into a class later on (?).

As it looks right now, I have to add the menu option text in the form method and the click commands in the prg file, but that is okay. It is really minimal work :-)

Now, all that remains is to get the darn thing to work, which I am sure will happen after I look at your new code above.

Regards,

Hans L