Has anyone ever solved the problems with Using SetParent and putting the forms within a Modal form?
Printable View
Has anyone ever solved the problems with Using SetParent and putting the forms within a Modal form?
solved what problems? famine?
Please describe the problem you are having.
Ok, I'll try to explain it clearly!
My parent form is Modal. I have two other forms that I use SetParent to display them with in the Modal Form via two Frames.
One on the forms has text boxes on it, when you click on the textbox, the form kind of blinks, but the textbox doesn't keep the focus...
Focus seems to return to the parent form...
If I don't display the parent form modal, all works fine..
Attached is a simple example of what I am talking about....
Well I don't know if this helps or not but you don't need form4 (at least in the sample project). Change your project's properties so that the Startup Object is Sub Main and then put this in Module1.
VB Code:
Public Sub Main() Load Form1 Call SetParent(Form2.hWnd, Form1.Frame1.hWnd) Call SetParent(Form3.hWnd, Form1.Frame2.hWnd) Form2.Move 0, 0, Form1.Frame1.Width, Form1.Frame1.Height Form3.Move 0, 0, Form1.Frame2.Width, Form1.Frame2.Height Form2.Show Form3.Show End Sub
This is just a little sample to show what is happening.. Something I just threw together..
The application that I am dealing with is humongous...
So I wanted to make sure it wasn't something else going on in it.....
Okay, my "solution" should have been
Are you saying that you want to set Form1 to vbModal and yet be able to enter data into Form2 and/or Form3? If so then that's not possible but you could fake it by setting the Enabled property to False temporarily on all the forms you don't want people to be able to access.VB Code:
Public Sub Main() Call SetParent(Form2.hWnd, Form1.Frame1.hWnd) Call SetParent(Form3.hWnd, Form1.Frame2.hWnd) Form2.Move 0, 0, Form1.Frame1.Width, Form1.Frame1.Height Form3.Move 0, 0, Form1.Frame2.Width, Form1.Frame2.Height Form2.Show Form3.Show [HL="#FFFF80"]Form1.Show[/HL] End Sub
Yes, Form1 does need to be modal.
The program was using a Sheridan control to do this (SSSplitter), but I wanted to get rid of the SSSplitter since it was causing some other issues.
One thing the SSSplitter did was allowed the form to be modal with forms in each of its panes...
Microsoft mentions that you should do something with WM_CHANGEUISTATE/WM_UPDATEUISTATE when you use SetParent, so I was going to look into that as well....
Just didn't know if anyone else had found a way around this other than disabling/enabling the other forms....
The following seems to fix the problems with a Modal form and the SetParent API Call (at least in this project)....
My humongous project still doesn't work, so I am trying to figure out what would make the below or attached code break.....
VB Code:
Public Const GWL_WNDPROC = (-4) Public Const GWL_HINSTANCE = (-6) Public Const GWL_HWNDPARENT = (-8) Public Const GWL_ID = (-12) Public Const GWL_STYLE = (-16) Public Const GWL_EXSTYLE = (-20) Public Const GWL_USERDATA = (-21) Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long Public Declare Function SetParent Lib "user32" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long Public Sub NewAttachSubForm(ByVal NewParent As Frame, ByVal TheForm As Form) Debug.Print SetWindowLong(TheForm.hwnd, GWL_STYLE, GetWindowLong(TheForm.hwnd, GWL_STYLE) Or WS_CHILD) Call SetParent(TheForm.hwnd, NewParent.hwnd) TheForm.Move 0, 0, NewParent.Width, NewParent.Height TheForm.Visible = True End Sub '''''' In Form1..... Private Sub Form_Load() Call NewAttachSubForm(Form1.Frame1, Form2) Call NewAttachSubForm(Form1.Frame2, Form3) Form2.Move 0, 0, Form1.Frame1.Width, Form1.Frame1.Height Form3.Move 0, 0, Form1.Frame2.Width, Form1.Frame2.Height Form2.Show Form3.Show Form4.Show Form4.Move 0, 0 Me.Show vbModal End Sub Private Sub Form_Resize() Me.Frame1.Move 0, 0, Me.ScaleWidth, Me.ScaleHeight \ 2 Me.Frame2.Move 0, Me.Frame1.Top + Me.Frame1.Height, Me.ScaleWidth, Me.ScaleHeight \ 2 Form2.Move 0, 0, Form1.Frame1.Width, Form1.Frame1.Height Form3.Move 0, 0, Form1.Frame2.Width, Form1.Frame2.Height End Sub
This fixes the issue of Form1 appearing to lose focus (Caption color changing) as well...
Forgot that in my code...... dumb, dumb, dumb..... Just noticed that someone forgot the Option Explicit in the module!
VB Code:
Public Const WS_CHILD = &H40000000
So now SetParent even works with Modal Forms... Also makes it appear the the Parent Form Keeps Focus!!!!
Now, another problem with SetParent!
It seems that if I do:
VB Code:
Call SetWindowLong(MyForm.hwnd, GWL_STYLE, GetWindowLong(MyForm.hwnd, GWL_STYLE) Or WS_CHILD)
If my form loses focus and then gets focus back, the Up/Down Arrows and PageUp/Down Keys won't work on the Datagrid...
Any ideas???
I attached a stupid little test program that I have been messing with trying to fix this new problem....
I haven't tried your new sample project but before I do let me ask why do you use forms in frames? Why not put whatever controls you need in the frames themselves?
Wasn't exactly my choice on how to do it, but it is a very large VB 6.0 project.
What they did was create some common forms that other forms need to use regularly.
Then on the forms that need the common forms, they used Sheridans SSSplitter Control to bring the Common forms in.
I found the problem with the datagrids, and it seemed to be the Splitters fault, so I changed from the Splitter to Frames and the SetParent API.
This fixed the datagrid problem until I did the SetWindowLong API call, then it breaks just like the Splitter (which must be doing the same thing).... The SetWindowLong needs to be done, otherwise the Parent Form loses focus when the child form is entered.... (also major problems if the form is displayed modally.....)
Hopefully that kind of explained it! :)
This problem doesn't seem to happen with the Mircorsoft Flexgrid....
Can the Flexgrid be dropped in in place of a DataGrid?
Are there any known problems with the Flexgrid?
Don't know if anyone cares, but it also happens with the FlexGrid, but I did find a workaround for it, I added a text box to the screen with the DataGrid and simply put it behind the DataGrid, then do the following:
VB Code:
Private Sub DataGrid1_Click() me.txtDataGridFocusOnly.SetFocus Me.DataGrid1.SetFocus End Sub
Seems like I'm the only one that ran into the problem, since no one else seemed to know about it! But now it is really resolved..............