(50 pts) Making another window a child

I'd like to know the CORRECT way to make another application a child to your application.  I'm pretty sure you use the SetParent API, but I tried it and can't seem to get it to work right.

I'll award the 50 points to the first to correctly provide sample code on how to make a program like NOTEPAD a child to your application... making your application act like an MDI form and NOTEPAD like an MDI child form,

Thank You,

HATCHET
LVL 3
HATCHETAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

y2kwackoCommented:
make your form an MDI Parent then add this to your form

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function SetParent Lib "user32" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long

Private Sub MDIForm_Load()
Dim NotePad As Long, st_parent As Long

NotePad& = FindWindow("Notepad", vbNullString)
st_parent& = SetParent(NotePad&, Me.hWnd)
End Sub

Enjoy,
Kevin
P.S. Make sure notepad is loaded before running your program
0
asaflahv1Commented:
This example need several controls on a form:
1. a picture box named  - picChild
2. a textbox named - txtProgram
3. and two  comman buttons - cmdRun and cmdFree
once you have that, just cut and paste the given code:

Option Explicit

Private Const GW_HWNDNEXT = 2

Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Private Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As Long, ByVal lpWindowName As Long) As Long
Private Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function SetParent Lib "user32" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long

Private old_parent As Long
Private child_hwnd As Long

' Return the window handle for an instance handle.
Private Function InstanceToWnd(ByVal target_pid As Long) As Long
Dim test_hwnd As Long
Dim test_pid As Long
Dim test_thread_id As Long

    ' Get the first window handle.
    test_hwnd = FindWindow(ByVal 0&, ByVal 0&)

    ' Loop until we find the target or we run out
    ' of windows.
    Do While test_hwnd <> 0
        ' See if this window has a parent. If not,
        ' it is a top-level window.
        If GetParent(test_hwnd) = 0 Then
            ' This is a top-level window. See if
            ' it has the target instance handle.
            test_thread_id = GetWindowThreadProcessId(test_hwnd, test_pid)

            If test_pid = target_pid Then
                ' This is the target.
                InstanceToWnd = test_hwnd
                Exit Do
            End If
        End If

        ' Examine the next window.
        test_hwnd = GetWindow(test_hwnd, GW_HWNDNEXT)
    Loop
End Function

Private Sub cmdFree_Click()
    SetParent child_hwnd, old_parent

    cmdRun.Enabled = True
    cmdFree.Enabled = False
End Sub

Private Sub cmdRun_Click()
Dim pid As Long
Dim buf As String
Dim buf_len As Long

    ' Start the program.
    pid = Shell(txtProgram.Text, vbNormalFocus)
    If pid = 0 Then
        MsgBox "Error starting program"
        Exit Sub
    End If

    ' Get the window handle.
    child_hwnd = InstanceToWnd(pid)

    ' Reparent the program so it lies inside
    ' the PictureBox.
    old_parent = SetParent(child_hwnd, picChild.hwnd)

    cmdRun.Enabled = False
    cmdFree.Enabled = True
End Sub

Private Sub Form_Resize()
Dim hgt As Single

    hgt = ScaleHeight - picChild.Top
    If hgt < 120 Then hgt = 120

    picChild.Move 0, picChild.Top, ScaleWidth, hgt
End Sub

good luck with it...
bye bye.

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
HATCHETAuthor Commented:
y2kwacko,

So you're saying make my program an MDI and then make the 3rd party software a "TRUE" child window in it?  Never thought of that.    =]   I'll give it a try and see what happens.

HATCHET
0
HATCHETAuthor Commented:
y2kwacko,

I did try your solution and it DID work... however, I hate working with MDI forms and its just not the best solution.  Sorry.

__________________________________________________________

asaflahv1,

I tried your code, but it would not work either.  Didn't give any errors, but just didn't work.  I did take your idea of using the PictureBox control as the parent object and used the following code that DID work.  Because you were close to the answer and gave me the idea for the answer, I'll give you the points.  Please answer the question.

__________________________________________________________


Option Explicit

' Function Declarations
Private Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function SetParent Lib "user32" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long
Private Declare Function MoveWindow Lib "user32" (ByVal hwnd As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal bRepaint As Long) As Long

' Variable Declarations
Private Handle As Long
Private OldParent As Long

Private Sub Form_Load()
 
  Dim MyAnswer As VbMsgBoxResult
  Dim Result As Long
 
FindWind:
 
  ' Check if NOTEPAD is running
  Handle = FindWindow("Notepad", vbNullString)
 
  ' If it's not, then prompt the user to start it and then continue.
  If Handle = 0 Then
    MyAnswer = MsgBox("Click OK when notepad is open.", vbOKCancel, " ")
    If MyAnswer = vbCancel Then
      Unload Me
      Exit Sub
    Else
      GoTo FindWind
    End If
 
  ' If it is running, continue
  Else
    ' Get the old parent so you can return it there later
    OldParent = GetParent(Handle)
    DoEvents
   
    ' Set the NOTEPAD's new parent to the PictureBox control
    Result = SetParent(Handle, Picture1.hwnd)
   
    ' Check if it worked, and if it did, move it to the top corner
    If Result = 0 Then
      MsgBox "Error setting the window as a child.", vbOKOnly + vbExclamation, " "
      Unload Me
      Exit Sub
    Else
      MoveWindow Handle, 0, 0, 500, 500, True
    End If
  End If
 
End Sub

Private Sub Form_Unload(Cancel As Integer)
 
  ' Set NOTEPAD's parent back to what it was before
  SetParent Handle, OldParent
 
End Sub
0
HATCHETAuthor Commented:
Adjusted points to 50
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic Classic

From novice to tech pro — start learning today.