I have a form (A), with a button, which opens another different style of form (B). I can open a number of forms (B), by pressing the button on (A). However, when these (B) forms are open, I can only select the last one opened (or form (A)), I can't even shuffle the forms around the screen, I can only move the last one opened. I thought there would be a windows 'CLassStyle' setting for this within the ff 'workspace' when the form is designed, or do I have to write code to enable any form to be selected?
You are probably creating 'modal' forms, and you seem to be needing 'modeless' forms.
Can't remember how to define this in FF though ... :(
[added later]
No, I think I am wrong. In the case of modal forms, you wouldn't be able to click the button on the main form to open a new B form ...
[/added later]
I just tried what you described in one of my existing programs.
I can open multiple 'B forms' and move any one of them around as I please ....
You need to show us the code you are using to initiate the opening of the popup forms. Probably a modal/non-modal issue or you are not specifying the correct parent form handle?
Button press on the A form resistor_show(hwnd_resistor,true)
B form creation Function RESISTOR_WM_CREATE ( _
hWndForm as HWnd, _ ' handle of Form
ByVal UserData as Integer _ ' optional user defined value
) as Long
rtagnumber = rtagnumber +1
FF_Control_SetTag( hwndform, Str(rtagnumber) )
FF_TextBox_SetText(hwnd_resistor_text1(0),"R" + Str(rtagnumber ))
Function = 0 ' change according to your needs
End Function
rtagnumber is shared, set initially to 0, and each B form is displayed and correctly named in 'Text1(0)' as R1, R2, R3 etc. when Button pressed on the A form
Is that the code you wanted to see, or is there more?
I'm trying to replicate something I wrote about 20 years ago, then using IBM Visual Age for Smalltalk for OS2 ::)
Ray,
The syntax of the _Show command is:
MyForm_Show(hwndParent, ShowModalFlag, Optional UserData)
The handle 'hwndParent' should be the handle of the
parent form (The A form, mentioned in your first post). Is that the case in your code?
The parameter name
seems to suggest that the form uses its own handle as 'parent'. But I could be wrong.
Furthermore, try using
%False for parameter 'ShowModalFlag' to create a non-modal (or 'modeless') form.
That's what I most often use in my programs (unless the newly shown form
really has to be modal).
Quote from: raymw on March 07, 2017, 02:09:10 PM
Button press on the A form resistor_show(hwnd_resistor,true)
B form creation Function RESISTOR_WM_CREATE ( _
hWndForm as HWnd, _ ' handle of Form
ByVal UserData as Integer _ ' optional user defined value
) as Long
rtagnumber = rtagnumber +1
FF_Control_SetTag( hwndform, Str(rtagnumber) )
FF_TextBox_SetText(hwnd_resistor_text1(0),"R" + Str(rtagnumber ))
Function = 0 ' change according to your needs
End Function
rtagnumber is shared, set initially to 0, and each B form is displayed and correctly named in 'Text1(0)' as R1, R2, R3 etc. when Button pressed on the A form
Is that the code you wanted to see, or is there more?
I'm trying to replicate something I wrote about 20 years ago, then using IBM Visual Age for Smalltalk for OS2 ::)
Thanks. setting the resistor_show to resistor_show(hwnd_resistor, false)
was all that was needed...
I can now struggle with the rest of what I'm trying to do.
OK, I can open a number of forms, and have given each one a unique tag, (and a reference in a textbox) but how do I programmatically select them to carry out calculations on the values I've entered in the textboxes? Whatever I do, it only seems I can access the last form opened. I need something along the lines of 'get textbox values from form with tag number 5'.
When you have multiple forms, don't use a direct reference to the texbox like
FF_TextBox_GetText(HWND_FORM1_TEXTBOX1)
Instead use
FF_TextBox_GetText(GetDlgItem(hWndForm, IDC_FORM1_TEXTBOX1))
That should work.
Thanks for the reply. My problem lies, initially, in selecting the forms programmatically. I can manually move the curser to any form, and enter values in its textboxes. I then want the program to iterate over each form and do some calculations. I have assigned a unique tag to each form, I am wanting to be able to select a specific form by its tag number, to carry out the calculation, based on the entries made in the form's textboxes, but I am always only able to programmatically access the last form opened.
An easy way to track your open modeless forms would be to track the HWND that is returned from your:
resistor_show(hwnd_resistor, false)
You could create a global/shared array of HWND's that you can resize every time you create a new form.
(off the top of my head)
SHARED gFormHandles(ANY) AS HWND
...
...
...
i = UBOUND(gFormHandles)
REDIM PRESERVE gFormHandles(i+1)
gFormHandles(i+1) = resistor_show(hwnd_resistor, false)
You can then easily iterate over all your forms:
FOR i AS LONG = LBOUND(gFormHandles) TO UBOUND(gFormHandles)
' Get the info from your textboxes
sText = AfxGetWindowText( GetDlgItem(gFormHandles(i), IDC_FORM1_TEXTBOX1) )
NEXT
Another approach could be to use the EnumWindows api approach and test each found form for a TAG or classname or some other identifier. Using the HWND returned in the callback function you could do your calculations.
https://msdn.microsoft.com/en-us/library/windows/desktop/ms633497(v=vs.85).aspx
A bit of a struggle, but managed to get there, having gone down a number of wrong turns, so thanks for pointing in a suitable direction.
I broke it down into single steps, printing values as I went.
When creating the resistor form, I copied the form hwnd's as suggested, into an array. I then could get to an individual text box in any resistor form, in the following manner
Dim rr as String
Dim ahwin as HWnd
For i as Long = LBound(gFormHandles) To UBound(gFormHandles)
Print gformhandles(i) ,"form handle"
ahwin = GetDlgItem(gformhandles(i),idc_resistor_text1(0))
Print ahwin, "ahwin text1(0) handle"
rr=FF_TextBox_GetText(ahwin)
Print rr ,"rr thats what I want"
Next
I will remove the prints, and maybe compress the code a bit, but most likely I'll keep it simple, and put it in a function.