Click here to Skip to main content
13,402,312 members (55,427 online)
Rate this:
 
Please Sign up or sign in to vote.
See more:
Hi all,

I have a child form within my form. When I click inside the child form, the parent form (my form) loses focus. How can I prevent this from occurring and maintain focus of main parent form even if clicking in child form?

Just to clarify what I mean by "in-focus", this picture demonstrates a focused form (the one at the front), and a form that's not in focus (the one at the back):
http://www.functionx.com/vcsharp/images/modal1.gif

Thanks in advance. :D

My code:
<pre>Imports System.Runtime.InteropServices
Public Class Form1

    Private Const WM_SYSCOMMAND As Integer = &H112
    Private Const SC_MAXIMIZE As Integer = &HF030

    <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
    Public Shared Function SetParent(ByVal hWndChild As IntPtr, ByVal hWndNewParent As IntPtr) As IntPtr
    End Function

    <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
    Friend Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
    End Function

    Private Sub SetChildTimer1_Tick(sender As Object, e As EventArgs) Handles SetChildTimer1.Tick

        Dim NtPdProcess As Process = Process.GetProcessesByName("notepad").FirstOrDefault

        If NtPdProcess IsNot Nothing Then

            SetParent(NtPdProcess.MainWindowHandle, Panel1.Handle)
            SendMessage(NtPdProcess.MainWindowHandle, WM_SYSCOMMAND, SC_MAXIMIZE, 0)

        End If

    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim startInfo As New ProcessStartInfo("notepad.exe")
        Process.Start(startInfo)
    End Sub
End Class


What I have tried:

I've tried experimenting with ZOrder, but frankly, I'm not very experienced yet.
I've tried experimenting with ShowDialog's, to no avail.
Posted 18-Nov-17 12:55pm
Updated 19-Nov-17 1:32am
v2
Comments
JustWatchLittle 18-Nov-17 18:10pm
   
I assume you like to have Focus on the "main form" for Keyboard Input. I don't know it for vb.net but in other Tools there is something like "KeyPreview" for a form. Maybe there is something similar in vb.net?
hellboyf2 18-Nov-17 18:29pm
   
For keyboard input, but not only for keyboard input. I have other controls on my parent window too that require it to be in focus when interacting with the child form (e.g. menustrip - if the main form is not in focus, the user must click twice to open a menustrip title (first click to get the form in focus, second to register click on menustrip item). Thanks a lot for the suggestion though :)
CHill60 19-Nov-17 5:04am
   
How do you hope to interact with the child form if another form has focus?
Use key preview and pass anything that can't be handled by the child through to the parent
hellboyf2 19-Nov-17 5:14am
   
It;s okay, trust me, the child form can be interacted with even if it doesn't have focus (which is unusual, but true). Does this make a possible solution easier?
CHill60 19-Nov-17 6:13am
   
I asked "how". Perhaps the picture would have helped but the link does not work
hellboyf2 19-Nov-17 6:19am
   
Thanks for your reply, the link does work, but unfortunately CodeProject has a bug which means that it redirects straight to this page, try opening a new tab and inserting the URL.

By "interact with", I mean clicking on it.

I'm grateful for the help! :)
CHill60 19-Nov-17 6:24am
   
No, the link does not work. It is not a bug in Code project, it's your markup.[^]
CHill60 19-Nov-17 6:18am
   
Ok. I looked at the picture. The child form has focus. The form at back does not. Show dialog is probably the way forward but we can't help if you are too vague and don't share your code.
hellboyf2 19-Nov-17 6:26am
   
Thanks for the reply,

Here's my code (or I just posted a more readable version in my original question).

Imports System.Runtime.InteropServices
Public Class Form1

Private Const WM_SYSCOMMAND As Integer = &H112
Private Const SC_MAXIMIZE As Integer = &HF030

<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
Public Shared Function SetParent(ByVal hWndChild As IntPtr, ByVal hWndNewParent As IntPtr) As IntPtr
End Function

<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
Friend Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
End Function

Private Sub SetChildTimer1_Tick(sender As Object, e As EventArgs) Handles SetChildTimer1.Tick

Dim NtPdProcess As Process = Process.GetProcessesByName("notepad").FirstOrDefault

If NtPdProcess IsNot Nothing Then

SetParent(NtPdProcess.MainWindowHandle, Panel1.Handle)
SendMessage(NtPdProcess.MainWindowHandle, WM_SYSCOMMAND, SC_MAXIMIZE, 0)

End If

End Sub

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim startInfo As New ProcessStartInfo("notepad.exe")
Process.Start(startInfo)
End Sub
End Class

If you paste that into a new project, create a panel and a timer and name them appropriately, you can see what I'm talking about if you click on the child form. The parent form goes out of focus.

Unfortunately I'm too inexperienced to know how to implement ShowDialog - I have tried, by the way, but in this context, I don't know how to use it.

Thanks very much!
CHill60 19-Nov-17 6:34am
   
You've started another process. You are not displaying a "child window". I don't understand why you have a timer.
Use the "Improve question" link if you want to post code by the way.
I suggest you go back to the drawing board
hellboyf2 19-Nov-17 6:38am
   
The timer ticks every few seconds in case the notepad is slow to initiate, as you can see (I've posted a more readable version in my initial answer) the notepad application is set as child (the panel1 being its parent). The code works well, I just need my form to focus when interacting with the child (clicking on it).

Thanks

[EDIT]: Also, the timer function is important in case the file that I am loading to become my parent is a splash screen, each tick will initiate the code and look for whether or not the process "Is Not Nothing" and set it as child to the panel if it is a process.
hellboyf2 19-Nov-17 6:28am
   
"No, the link does not work. It is not a bug in Code project, it's your markup.[^]"

Oh, I see, apologies.
hellboyf2 19-Nov-17 6:43am
   
Also, here's a picture of the form, clearly displaying the notepad as child (no taskbar icon, is not independent, is "embedded" in my form: http://tinypic.com/r/2ce10ck/9
hellboyf2 19-Nov-17 14:54pm
   
Resolved!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month


Advertise | Privacy |
Web03 | 2.8.180218.2 | Last Updated 19 Nov 2017
Copyright © CodeProject, 1999-2018
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100