?
Solved

SetParent and getting focus.

Posted on 2009-02-10
10
Medium Priority
?
1,424 Views
Last Modified: 2013-12-20
Hi,

I've been trying to use SetParent to add new frames to one of my forms. From an aesthetic point of view it works fine, the frame containing a checkbox and a textbox are moved to the new parent. The problem is I cannot click on either the checkbox or the textbox without first clicking on another control on the new parent. A hack I have implemented right now is to use PostMessage WM_LBUTTONDOWN and UP on 0,0 of a control and it's working but if I use tab at all it stops taking focus again.

Has anybody any ideas as to how to avoid this behaviour? I tried http://support.microsoft.com/kb/289498 but if I SetWindowLong on the frame it turns into a block of grey and has the same problem, if I do it on the textbox and checkbox they dissappear.

Thanks in advance,
J
0
Comment
Question by:c0ldfyr3
  • 6
  • 4
10 Comments
 
LVL 6

Expert Comment

by:VK
ID: 23620568
Although my sample project possibly has not the same context as your project:
It contains form1 and form2.
Form1 is the start form and contains a frame1 containing a checkbox1, textbox1 and command1.
There is command2 on form1, when clicked it sets the parent of frame1 from form1 to form2.
As you described you have to click twice on form2 before e. g. the texbox gets the focus.

In my example the problem is that after setting the new parent form1 has still focus.
By the 1. click form2 gets focus. By the 2nd click the controls get the focus.
If you click first on the title bar of form2 then you can set the focus on all controls of form2
without clicking twice.

If there is a problem with setting focus on form2 with the simple form2.SetFocus try the
already included ForceToForeground procedure.

Tell me if i'm on the right track!

Form1.txt
Form2.txt
0
 
LVL 6

Expert Comment

by:VK
ID: 23621936
It have read KB289498 and realize i think i'm realizing your problem.
In my project (after SetParent ):

If Text1 gets the focus, form1 won't ever get the focus back!
The only way is to use the tab key to do that.

The problem after SetParent is:
1. If you click back on form1 windows "thinks" that you havent left form1 and that form1 doesn't need focussing.
2. The Tab order remains in the state before SetParent. Form1 will only get the focus if a control whose parent is form1 gets the focus.
Obviously SetParent isn't sufficient:

I have modified the code before:

I have implemented subclassing, which is necessary to get an event, when form1 has to get back
the focus. The call Form1.cmdFocus.SetFocus is used to set back the focus to form1.
You should move cmdFocus out of the visible area of form1.
Form1.txt
Form2.txt
Module1.txt
0
 
LVL 10

Author Comment

by:c0ldfyr3
ID: 23622051
Ah I forgot one vital piece of information which actually makes this error occur. They are MDIChild windows, the problem I'm having only happens with an MDI interface! Attached is an example.

http://c0ld.net/test_setparent.zip 
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 6

Accepted Solution

by:
VK earned 2000 total points
ID: 23623576
Need for  "hacking" is required because windows isn't designed for that purpose.

Look at this sample. The only problem is that we had to subclass every control
which is moved by SetParent and which can get the focus (and not only frame1 as in the sample).

Because windows will allways show the mdichild-window of a focused control in the foreground,
the only way is to minimize that mdi-child-window while the "moved" controls have focus and restore
the mdi-child-window after a no moved control has the focus.

In my sample i tried to avoid the multiple subclassing by suclassing the container of the moved
controls (here frame1).

The side effect of this approach is that the same control will activated each time when you click on frame1.
.
SetParent.zip
0
 
LVL 10

Author Comment

by:c0ldfyr3
ID: 23623890
At the moment I have a workaround which isn't very pretty. I have a treeview control on the NewParent frame which when clicked seems to stop this problem. It doesn't work if it's a textbox or other regular control for some reason, so what I'm doing is SendMessage WM_LBUTTONDOWN on load and it's working. There must be some clue here...
0
 
LVL 6

Expert Comment

by:VK
ID: 23624213
Look at this much simpler approach:

Instead of having MDIChilds i have done the below for each MDI-Child-Form
which has the same effect:

Private Sub Form_Load()
    Call SetParent(Me.hWnd, MDIForm1.hWnd)
End Sub

Then the focus-problem seemd to be solved.
The side effect is that if you click on form1 immediately form2 will be activated,
because a "moved" control will get focus.
test-setparent.zip
0
 
LVL 10

Author Comment

by:c0ldfyr3
ID: 23624290
The reason I started this thread was because we running out of controls on a form in a project I'm working on. If it involves subclassing to get them on there I'm not goin to proceed any further. What I've ended up doing is Controls.Add coupled with WithEvents and it's working ok. The only drawback is the placement and setup of the controls but ah well, thanks for your help anyway.
0
 
LVL 10

Author Comment

by:c0ldfyr3
ID: 23624300
Hey,

Yeah we have that behaviour already with another control set, we SetParent on the form instead of the frame but the new parent losing focus isn't a very desirable side effect =P
0
 
LVL 6

Expert Comment

by:VK
ID: 23624376
Look at this approch with ONE subclassing needed (no side effects):

test-setparent.zip
0
 
LVL 6

Expert Comment

by:VK
ID: 23624490
P.S.: To improve TAB-Behaviour the below is needed
cmdFocus.move -16000, -16000
cmdFocus.TabStop = False
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Most everyone who has done any programming in VB6 knows that you can do something in code like Debug.Print MyVar and that when the program runs from the IDE, the value of MyVar will be displayed in the Immediate Window. Less well known is Debug.Asse…
This article describes some techniques which will make your VBA or Visual Basic Classic code easier to understand and maintain, whether by you, your replacement, or another Experts-Exchange expert.
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
Suggested Courses
Course of the Month15 days, 2 hours left to enroll

840 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question