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 Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Position form in another form when radio clicked 1

TheLazyPig

Programmer
Sep 26, 2019
106
PH
Hi!

Can I position my form (frmchecks.scx) to appear inside another form (branch.scx) when the radio button is clicked? It works when I change the Top and Left but if I do this will it stay in the position even if the device changes?

branch_fp9.png checks_fp9.png<-- changes depend on the radio button

frmchecks.scx should be in the yellow square below.

branch2_fp9.png

Thanks for the replies. :)
 
Hello,

why not put the content of form frmchecks inside a container and put in mainform and make it visible .t. / .f. depending on radio buttons ?
If it has own buttons, disbale maiform buttons/controls if container is visible

What do you mean with "device changes" ? Moving mainform to other screen with different resolution ?
 
Hi!
Can I position my form (frmchecks.scx) to appear inside another form (branch.scx) when the radio button is clicked? It works when I change the Top and Left but if I do this will it stay in the position even if the device changes?
View attachment 1523 View attachment 1524<-- changes depend on the radio button
frmchecks.scx should be in the yellow square below.
View attachment 1525
Thanks for the replies. :)
Yes, it's possibly, but how as Tom... Why?!?

PUBLIC m.poFormMain, m.poFormChild


m.poFormMain=CREATEOBJECT("_formMain")
m.poFormMain.Name="MAINFORM"
m.poFormChild=CREATEOBJECT("_formChild")
m.poFormChild.Name="CHILDFORM"

SHOW WINDOW ("CHILDFORM") IN WINDOW ("MAINFORM")

m.poFormChild.ChangePosByParent(m.poFormMain)


m.poFormMain.Visible=.T.
susp

DEFINE CLASS _formMain AS FORM
Name="_formMain"
Height=500
Width=500

PROCEDURE Resize
m.poFormChild.ChangePosByParent(m.poFormMain)
ENDPROC

ENDDEFINE


DEFINE CLASS _formChild AS FORM
Name="_formChild"
Height=250
Width=500

PROCEDURE Init
This.AddObject("Label1","Label")
This.Label1.Caption="Child form"
This.Label1.Visible=.T.
ENDPROC

PROCEDURE ChangePosByParent
LPARAMETERS m.loForm
This.Move(0, m.loForm.Height/2, m.loForm.Width-SYSMETRIC(3)*2, m.loForm.Height/2-SYSMETRIC(4)*2-SYSMETRIC(9))
ENDPROC
ENDDEF
 
For me Ideal solution will be to put Page Frame control and convert all your radio buttons to Pages. This will be more clear, easy and simpler solution to implement.

Please explore Page Frame control and that should solve your issue. Your page frame could look like below with individual page having required fields:

1737109573194.png
 
Last edited:
I second Premal Vala. But is there any reason you have all separate forms? If there is any reason, like all of them having a private datasession and separation of data from the main form, then the normal way to use them is as a satellite/popup form.

You may have the idea popup forms are bad, as they are suppresed by Browsers, for example, but that has it's own reasons. Spare the free area of your main form, put buttons or a commanfbutton group on it to start the different child forms and let the user decide here they want to move it, display it nonoverlapping, for example, and the user may even steart two or three of the smaller satellite forms, it could even be useful to have multiple of them side by side. That way you also have the least need for changes.

On top of that you could offer dockable forms. That won't allow a head area that stays visible, but adds a pageframe interface without needing to rearrange anything. Maybe only allow the popup forms to dock into each other and keep the main form undockable and not allowing docking, then you have the always present main form as header to all the other forms.
 
Last edited:
Yes, my first thought was a pageframe. And if you don't want to use the tabs, you can turn them off and have the radio buttons activate the appropriate one.
 
I already gave my advice and don't see any benefits of having an empty area in a form just to be able to position a form there. The sstraight forward way to have child forms (forms within forms) is creating a parent form that's capable to have child forms in it. In VFP that kind of parent form is a top level form. The property to set is ShowWindow. Setting a form "As Top Level Form" (2) it should become clear what "In Top Level Form" (1) means. Starting a form (DO FORM or CREATEOBJECT("formclass") - the way doesn't matter) from code of a top level form, an "In Top Level Form" then will become a child form that will be movable within the top level form only and that will move along with the top level form.

The use case that is what you use by default: Forms that all show in the VFP Screen (aka _SCREEN) form where the screen is usually empty (perhaps a background and acts as a desktop for all the application forms. Or instead of desktop (that should be reserved for the Windows Desktop, of course) it's just a parent form for all forms of the applicaiton, which keeps all the windows of one application together. I'd not consider it a good design to reserve a space for child forms, though. They still have a titlebar and are movable. And that's actually the major design of Windows itself. That's giving it the name. You have Windows and you're usually (within some rules about child windows containied within parents) free to move and arrange them as you like. That's what users expect of Windows applications. So a straight forward comple Winddows application design is to offer all forms to be movable anywhere on the Windows desktop, not confined to anything and not fixed into some predefined space, only. What you want is either a pageframe or container, not a form in a form.
 
你好!

单击单选按钮时,是否可以将我的表单 (frmchecks.scx) 定位为显示在另一个表单 (branch.scx) 中?当我更改 Top 和 Left 时它起作用,但如果我这样做,即使设备发生变化,它也会保持在原位吗?

View attachment 1523 View attachment 1524<--更改取决于单选按钮

frmchecks.scx 应位于下面的黄色方块中。

View attachment 1525

谢谢你的回复。:)
You can use Foxhwnd.ocx for this purpose if you stick to the original design. Foxhwnd.ocx can be found in the VFP6 installer, and details of how to use it can be found in the help file.
 
Not sure what foxhwnd.ocx is needed for. I found a mention of foxhwnd from Tamar mentioning it can be used as an image control by feeding it a picture you load with LOADPICTURE(). Overall foxhwnd seems to be an ActiveX container, that's now just the Olecontrol. Or it's lending the hwnd access to you, which now every form has as a property anyway. So overall I think it has been introduced in VFP5 just to be replaced by integrating it into VFP forms and the Ole(bound)control.

Anyway, hwnd can be used in the API call SetParent to force a window to be parent window. That's unnecessary as I said you can make use of the Top Level and In Top Level forms, but it's also a straight forward option. I just wouldn't recommend it.

I'd still like to hear about your motivation, "TheLazyPIg". Clearly you have all the forms you'd rather need as containers or pages of a pageframe, as the majority of answers recommend. I gave you the laziest option to just make it a feature instead of a bug or flaw to not be able to position a window inside another window and argue with the philosophy of the Windows OS, you'd just need to shrink your form to give room to the separate windows. And (I repeat myself) make use of the docking feature in one or the other way.

You can also get containers from your forms by opening them, use CTRL+A to select all form content and then use Save As Class from the main VFP IDE menu to save containers instead of the forms. You could then use these containers both as the only control in new empty forms or inside a page of a pageframe. And you then have a central place to modify these things and both change the mainform in which you embed them and the separate forms which each only consist of one such container class on them.

What you do all depends on the motivation for this. I think you have the stand alone forms for a reason and want to continue to offer them not only as a page of a pageframe in the new mainform, then just keeping them as separate forms also in context with your main form is still the simplest solution requiring the least work of changes. Creating containers from the forms with the "Save as Class" feature has not only the work to create all these container classes, it also means any code referring to THISFORM within any control will need to change to refer to the container. So there's more work to have this working and that's why you perhaps seek for the simple form in form solution. It can look llike seamless integration, if you remove the border and titlebar of the embedded form, it's still clunky in terms of the integration into the tab order of things and you still activate/deactivate forms, i.e. change from mainform to embedded form and back in focus and it's all not ideal to hack it that way. The only really lazy solution is to keep forms as forms outside the main form and have consistent UI in concordance with Windows guidelines, too. It's also sensible.

Here's one thing that can help as a compromise of just having a separate form appear anywhere for the user to arrange. You could position the form under the main form instead of at the footer area you kept empty (So still the same idea to not reserve that area and just display separate forms). But you could make it seem like magnetic borders, so the separate form moves with the main form. And even make that a general feature of another way of docking "magnetically" when two form borders come close enough and align good enough. If you're interested I could share code doing that feature both just programmatically and as a general UI feature a user could use to snap forms together at borders.
 
Last edited:
FoxPro for DOS has simply way how to shoe window inside another window: SHOW WINDOW [window_name] IN WINDOW [window_name]. This old command works within VFP forms too.
 
For me Ideal solution will be to put Page Frame control and convert all your radio buttons to Pages. This will be more clear, easy and simpler solution to implement.

Please explore Page Frame control and that should solve your issue. Your page frame could look like below with individual page having required fields:

View attachment 1526

I didn't use it because I hadn't tried it before and wanted to re-create the original UI of the program. Thank you I'll learn it from now. :)
 
Hello,

why not put the content of form frmchecks inside a container and put in mainform and make it visible .t. / .f. depending on radio buttons ?
If it has own buttons, disbale maiform buttons/controls if container is visible

What do you mean with "device changes" ? Moving mainform to other screen with different resolution
Oh, I didn't know about containers... I've never really explored all the tools. Thank you this might be the one the programmer used in the project. Will check this out too. :)

What do you mean with "device changes" ? Moving mainform to other screen with different resolution
Yes, screen resolution.
 
The real problem is the project itself doesn't have the .pjx file and the other forms I needed so I have to re-create the program itself. :cry:
 
I second Premal Vala. But is there any reason you have all separate forms? If there is any reason, like all of them having a private datasession and separation of data from the main form, then the normal way to use them is as a satellite/popup form.

You may have the idea popup forms are bad, as they are suppresed by Browsers, for example, but that has it's own reasons. Spare the free area of your main form, put buttons or a commanfbutton group on it to start the different child forms and let the user decide here they want to move it, display it nonoverlapping, for example, and the user may even steart two or three of the smaller satellite forms, it could even be useful to have multiple of them side by side. That way you also have the least need for changes.

On top of that you could offer dockable forms. That won't allow a head area that stays visible, but adds a pageframe interface without needing to rearrange anything. Maybe only allow the popup forms to dock into each other and keep the main form undockable and not allowing docking, then you have the always present main form as header to all the other forms.
The form changes because of the radio button the content is not the same that's why I have separate forms.
 
For me Ideal solution will be to put Page Frame control and convert all your radio buttons to Pages. This will be more clear, easy and simpler solution to implement.

Please explore Page Frame control and that should solve your issue. Your page frame could look like below with individual page having required fields:

View attachment 1526
How did you put the Documents from and Others tab in the second row?
 
Hi,

The form changes because of the radio button the content is not the same that's why I have separate forms.
How did you put the Documents from and Others tab in the second row?

You may want to have a look at the demo code below - not very fancy, but it might give you an idea.

Code:
oForm = CREATEOBJECT("clsMainForm")
oForm.Visible = .T.
oForm.SHOW()

Read EVENTS

CLOSE ALL

CLEAR ALL

RETURN
        
*!*    Define Main Form Class

Define CLASS clsMainForm AS FORM

    Caption = "Test Pageframe"
    Left = 12
    Top = 12
    Height = _screen.Height - 24
    Width = _screen.Width - 24 && 1680
    BorderStyle = 2
    WindowState = 2
    WindowType = 0
    BackColor = RGB(210, 210, 210)
    Themes = .F.

*!*    ADD exitbutton to form

    Add OBJECT cmdExit AS COMMANDBUTTON WITH;
          Caption = "Exit", ;
          FontSize = 12, ;
          FontBold = .T., ;
          Backcolor = RGB(192,192,192), ;
          ForeColor = RGB(255,0,0), ;
          Left = ThisForm.Width - 120, ;
          Top = ThisForm.Height - (48 + 24), ;
          Width = 120, ;
          Height = 48, ;
          Alignment = 2
          
*!*    ADD label to form

    ADD OBJECT lblIntro as label WITH ;
        Left = 240, Top = 48, autosize = .T., Caption = "Whatever you want", FontBold = .T., FontItalic = .T., FontSize = 24
        
*!*    ADD optiongroup to form

    ADD OBJECT opgPages as OptionGroup WITH ;
        Left = 12, Top = 42, ButtonCount = 6, Autosize = .T.
        
        PROCEDURE opgPages.Init()
            FOR i = 1 TO This.ButtonCount
                WITH This.Buttons(i)
                    .AutoSize = .T.
                    .Caption = "Click to activate page " + ALLTRIM(STR(i))
                ENDWITH
            ENDFOR
        ENDPROC
        
        PROCEDURE opgPages.Click()
            LOCAL lni
            
            lni = This.Value
            
            WITH ThisForm.pgfMain
                    .ActivePage = lni
                    .Click
            ENDWITH 
        ENDPROC
        
    ADD OBJECT chkTabs as Checkbox WITH ;
        Top = 142, Left = ThisForm.Width - 180, Value = .F., AutoSize = .T., Caption = "Show Tabs of PageFrame"
        
        PROCEDURE chkTabs.Click
            WITH ThisForm
                .opgPages.Value = ThisForm.pgfMain.ActivePage
                .opgPages.Enabled = !(This.Value)
                .pgfMain.Tabs = This.Value
                .Refresh()
            ENDWITH
        ENDPROC
            
*!*    Add pageframe to Form

    ADD OBJECT pgfMain AS PageFrame WITH ;
        PAGECOUNT = 6, ;
        LEFT = 12, ;
        TOP = 184, ;
        WIDTH = THISFORM.WIDTH - 12, ;
        HEIGHT = THISFORM.HEIGHT - 272, ;
        Tabs = .F.
    
        PROCEDURE pgfMain.Init()
            LOCAL loPage as Object
                
            FOR i = 1 TO This.pageCount
                loPage = This.Pages(i)
                
                WITH loPage
                    .Caption = ICASE(i = 1, "Page One", i = 2, "Page Two", i = 3, "Page Three", i = 4, "Page Four", ;
                                    i = 5, "Page Five","Page Six" )
                    .FontBold = .T.
                    .FontName = "Verdana"
                    .FontSize = 12
                    .Forecolor = ICASE(i = 1, RGB(0,0,255), i = 2, RGB(0,0,0), i = 3, RGB(0,0,255), ;
                                    i = 4, RGB(128,64,64), i = 5, RGB(0,128,0), RGB(255,128,0))

                    .Addobject("lblPage", "lblLabel")
                    .lblPage.Top = 120
                    .lblPage.Left = i * 210
                    .lblPage.Caption = "This is label on page" + " " + ALLTRIM(STR(i))
                ENDWITH
            ENDFOR
        ENDPROC

    PROCEDURE cmdExit.CLICK
        CLEAR Events
    ENDPROC
    
    PROCEDURE Destroy()
        This.cmdExit.Click()
    ENDPROC
      
ENDDEFINE

**********

DEFINE CLASS lblLabel as Label
    Visible = .T.
    Left = 12
    Top = 24
    Height = 48
    FontSize = 18
    FontName = "Verdana"
    BorderStyle = 1
    Backcolor = RGB(255,255,128)
    Caption = "Label"
    Autosize = .T.
ENDDEFINE         

*********

hth

MarK
 
The form changes because of the radio button the content is not the same that's why I have separate forms.
That's not a reason to create forms, that's a reason for having a pageframe. Especially when you created forms to display in that area, that's nonsensical design, just look back at the answer of Premal Vala with a screenshot of the tabs a pageframe could have that replace your radio buttons. Since tabs can span multiple lines you don't even need to shorten the captions, they can be 1:1 the captions of your radio buttons.
If you want to save space, then you could also make a combobox for choosing the page and make the tabs invisible and switch to the page number associated with the selection of a combobox. Or as I suggested, since you now have the forms, make it a feature, not a bug, to display them separately.
 
Last edited:
That's not a reason to create forms, that's a reason for having a pageframe.
That's because I wanted to re-create the original UI and thought that he used forms. I'm already changing it to pageframe now. :)
 
FYI this is the program I'm re-creating. :)

mailingsys1.png mailingsys2.png
It was created in 2007.
 
Okay, but the first thing that should come to your mind to do something similar in VFP is a container, not a form. Why did you go for forms immediately? You see a bunch of controls in a reserved free area. The designer of that old program should have used a pageframe, too, by the way, but he was likely using containers at that place, he made visible=.T. or .F. It's not a nice way also to design and maintain this. A pageframe also has it's pages at designtime and you can also switch between them to design and modify them. It's the simplest way to have a set of areas to display at the same place.

If you like the choices to be on the side, instead of the top, there are the pageframeproperties taborientation, where you can decide whether tabs are on the top (normal default), bottom, left or right, tabstretch, which determines whether you have a single row of tabs or - better in your case with the many options you have - multiple rows, and finally tabstyle, which determines whether tabs all have just the size necessary for the caption and there's free space after the last tab or whether the tabs always extend over the whole width or height of the pageframe and the captions are displayed justified within the tabs (each tab caption centered).

As others and I have also said, you could also use a pageframe with no tabs, just set the pageframe.tabs property .F. - and then have your radio buttons (in VFP an option group) to pick an option or a button group to have a staple of buttons looking like page tabs with their caption still horizontal (pageframe taborientations left and right have tabs with captions written vertically). So you could easily adapt to what you see there, but even with the argument the user acceptance is best when the new application just looks, feels, reacts and works exactly the same: Why even bother to recreate it then? You should improve what you're able to improve to more normal UI designs, like a pageframe is. If that gives you the idea to create forms and not even simply containers or - as most here got the same idea - a pageframe. It doesn't require to start a form and position it in a prereserved space, it consists of pages which are at the prereseved spaces, you can - if ou llike that for a start - have an empty page, too, then user pick a page by tab and that appears - without any code. It's exactly what you want and does not even require creating a container and place it there

Do you not knew the pageframe? What controls of VFP are you using regularly? No pageframe? No grid? No combobox, listbox? Too complicated? Take a look at a project called solution:
Code:
Modify Project (_samples+"solution\solution.pjx")
And then switch to the "Code" tab of the project manager (by the way, a good example of a pageframe you certainly know and use, too) and start main.prg with the Run button. Then ou can search and pick examples also about things like the VFP controls and how they work, with demonstration and source code (as the whole project source code is).
 
Last edited:

Part and Inventory Search

Sponsor

Back
Top