SetParent with a Modal form

TheRealWoody
06-09-2005, 04:03 AM
Hi,

Is it possible to display a modal child form over another form. I can get the form to display but I then can't click on any of the controls etc.

I have a project with two forms (Form1 & Form2). Form1 has a command button on it with the following code.


Private Sub Command1_Click()
Dim f2 As Form2
Set f2 = New Form2
Load f2
f2.Left = 0
f2.Top = 0
setparent f2.hWnd, Me.hWnd
f2.Show vbModal
Unload f2
Set f2 = Nothing
End Sub


Anyone have any ideas why I can't access any of the controls on Form2?

Woody

George7a
06-09-2005, 06:38 AM
If you want it to be form inside form, I think this will help

http://www.xtremevbtalk.com/showthread.php?t=226780&highlight=Form+inside+MDI

TheRealWoody
06-09-2005, 07:18 AM
If you want it to be form inside form, I think this will help

http://www.xtremevbtalk.com/showthread.php?t=226780&highlight=Form+inside+MDI

Thanks George but I can't use an MDI form unfortunately. The form that is being displayed modally (Form2 in my example) is actually in an OCX rather than in the current project. I also thought that MDI forms couldn't be shown modally?

The real problem I have is a bit more complicated. My system is made up of many forms from many different components. Some of these forms have multiple pages in them from the user perspective. I have written a program which will raise an event back to anyone who cares each time a user navigates between pages, either via the task bar or within one of the forms. The problem I have is that my SHELLHOOK doesn't receive a HSHELL_WINDOWACTIVATED message when my modal form is shown. By default the parent window of the modal form is the desktop however if I use the SetParent API, and use the form on which my OCX is sitting as the parent, I can see my modal form at the top of the ZOrder in the child window list of my parent form. The only issue is that my modal form doesn't respond to any keyboard or mouse events after I have used the SetParent API.

You can recreate the problem by using the code in my original post. However, now you know more about what I am trying to do, can you think of any other ways round it?

Thanks

Woody


gets notified each time a window becomes activated. If the window is known to have more than one page on it then my program will loop through the child windows

tintino
06-14-2005, 01:26 AM
I believe showing a window "modal" implies just this:

Any user input is BLOCKED for any other window in the whole THREAD, except for the modal window. And a normal VB app is single threaded.

I think you have 2 choices:

1. Use multithreading..look up plenty examples on the net.
2. Dont make the window modal. - as that blocks user input to all the rest of windows in your thread.... instead use other ways to keep the window on top if thats what you want...

TheRealWoody
06-14-2005, 03:13 AM
I believe showing a window "modal" implies just this:

Any user input is BLOCKED for any other window in the whole THREAD, except for the modal window. And a normal VB app is single threaded.

Thanks Tintino,

So what your saying is that displaying a modal form blocks every other window in the thread, and as I have made my modal form a child of one of the blocked windows it also becomes 'blocked'. Is this right?

TheRealWoody
06-14-2005, 08:07 AM
Is there any way, given a hWnd (window handle), that I can tell if that window is displaying a modal form?

pebtos
06-14-2005, 08:48 AM
I'm not quite following I think. Couldn't you use the second argument of the Show method to set the parent.

f2.Show vbModal, Me

TheRealWoody
06-14-2005, 09:22 AM
I'm not quite following I think. Couldn't you use the second argument of the Show method to set the parent.

f2.Show vbModal, Me

Well that's what I would have thought but it doens't seem to work like that. If you use
f2.Show vbModal, Me
when I check who the parent window is (using Spy++) I am told it is the desktop. However, when I use the SetParent API the parent really is Form1.

This becomes a problem for me becuase after I recive a HSHELL_WINDOWACTIVATED message I loop throught the child windows for that form to find out what page it is on. However my modal form isn't showing as a child window.

tintino
06-16-2005, 04:32 AM
Thanks Tintino,

So what your saying is that displaying a modal form blocks every other window in the thread, and as I have made my modal form a child of one of the blocked windows it also becomes 'blocked'. Is this right?


Exactly, once you show a window modal, you can't click on ANYTHING in your app exept in the window thats modal.

VB just stops sending user input messages to all your top windows exept your modal window... and the modal window has to be a top window not a child.
Here's why
Top windows get user input first... u can tell by the existance of events like KeyPreview() - then its forwarded to the child.

So by setting form2 modal, form1 is not getting any user input messages.
But Since your form2 is a child now, the top window - form1 will not be able to forward the user input to a child (form2) since it never even gets it..

Therefore you've just frozen your whole app. And the user can't do anything anymore except alt-ctrl-del :P

That being said, the window procedure of the modal window is still running, still process anything you send it, except that the parent (form1) is not sending it any...

So if you wanna do something to form2, or to any child of form2, you will have to SendMessage() the appropiate user input to that hwnd directly.
Like say u wanna close form2 at this point: you would SendMessage (form2.hwnd, WM_CLOSE,0,0)

TheRealWoody
06-24-2005, 03:52 AM
Okay, I kindda got round my problem by doing the following.

When my program with the shell hook receives an activate message (and it has identified the window as one of mine) it checks if the foreground window has the same hWnd as the window that has just been activated. If it doesn't then it must be a modal form being displayed. So it loops through the desktops child windows until it finds the modal form being displayed.

This seems to work - although if anyone can think of any reasons why this method may be 'bad' please let me know.

The problem I have is that when I display the modal form no activate message in generated. If I go to another window, then back to my modal form I get the activate message I can identify the window. Presumably this is because the parent window is already active and therefore hasn’t been activated?

Any thoughts on how to make “from.show vbmodal” generate an activate message. Could I use SendMessage in the modal forms activate event passing the hWnd of the parent? Any other ideas?

EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum