Solved

Shell as child of MDI

Posted on 1998-12-22
11
478 Views
Last Modified: 2012-08-13
I have a program that from an MDI form the file menu lets you start a program that will come up in a shell and gain focus.  What I want is that shell to be a child of the MDI form so that you will be able to run both the shell program and the vb program.
0
Comment
Question by:zaq
  • 3
  • 3
  • 3
  • +2
11 Comments
 
LVL 13

Expert Comment

by:Mirkwood
Comment Utility
As an MDI child window is impossible. An MDI window needs to contain more information than a regular window.
It is possible to make the application a child window using the SetParent api.
You first have to get the window handle of the launched application and then make it your child using the SetParent API.

One trick that is often used is to change the style of the child window and remove all borders and caption. Now create a MDI form and make the launched application a child of this MDI form. This works ok for 80%. The problem is that accelerator keys do not work and that the TAB key does not work anymore.
0
 

Author Comment

by:zaq
Comment Utility
how do I do this?  How do get the window handle of the application?
0
 
LVL 13

Expert Comment

by:Mirkwood
Comment Utility
Using the findwindow api for example

Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long

Private Sub Command1_Click()
    Dim pmHwnd As Long
    Dim dvHwnd As Long
    Dim lvHwnd As Long
    pmHwnd = FindWindowEx(0, 0, "Progman", "Program Manager")
    dvHwnd = FindWindowEx(pmHwnd, 0, "SHELLDLL_DefView", "")
    lvHwnd = FindWindowEx(dvHwnd, 0, "SysListView32", "")
    MsgBox lvHwnd
End Sub

-- Another example
  hwndexpl = FindWindow("IEFrame", 0)   ' Find Internet Explorer
    hwndsizerebar = FindWindowEx(hwndexpl, 0,   "SizableReBar", "")    ' Find the sizable rebar toolbar control
    hwndrebar = FindWindowEx(hwndsizerebar, 0, "ReBarWindow32", "") ' Find the rebar toolbar control
    hwndcomboex = FindWindowEx(hwndrebar, 0, "ComboBoxEx32", "")  ' Find the extended combobox control on the toolbar
    hwndcombo = FindWindowEx(hwndcomboex, 0, "ComboBox", "")  ' Find the combobox control with the extended combo
    hwndedit = FindWindowEx(hwndcombo, 0, "Edit", "") 'Find the editbox within the combobox

0
 
LVL 3

Expert Comment

by:jjmartin
Comment Utility
It is possible to bring it up and force it to be a child of the MDI form.  I need to find my code on this.  I will get back to you.
0
 
LVL 3

Expert Comment

by:jjmartin
Comment Utility
Post your email address, and I will send you a project that will show you how to force other applictions to be Children of your MDI form. It is much to long to post here.
0
What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 13

Expert Comment

by:Mirkwood
Comment Utility
JJMartin: Does it integrate well when you maximize the child window. And what is the principe it work on. Is it like I described and are you experiencing the problems I described?
0
 
LVL 3

Expert Comment

by:jjmartin
Comment Utility
Using the hwnd and task id, it literally makes the shelled application a child of your MDI.  It minimizes within the MDI form, and the MDI form has the control to kill the child window.  Howver, you still have the same limitations you would have with any shelled appliction.  I am still working on a problem with the MDI taking the child windows menu bar though.
0
 

Author Comment

by:zaq
Comment Utility
my email address is trolli@ctc.com
0
 
LVL 4

Expert Comment

by:idcanada
Comment Utility
0
 

Author Comment

by:zaq
Comment Utility
The people that left comments already mentioned that same file and emailed it to me, that you mentioned idcanada.  Therefore I believe the credit should go to them.  Sorry.
0
 
LVL 1

Accepted Solution

by:
mathies earned 350 total points
Comment Utility
You have to find the handle of the application you start from shell command using  the description of the window.  A application have always the same Description, but not the same handle.

You can use these 3 function to retrieve the handle by description.
Note: You window should be in top level list to be able to find it.

Private Function GetBaseName$(ByVal Source$)
' If source$ is a path, this function retrieves the
' basename, or filename sans path
' source$ MUST be a valid filename
'

On Error GoTo ErrorHandle

    Do While InStr(Source$, "\") <> 0
        Source$ = Mid$(Source$, InStr(Source$, "\") + 1)
    Loop
    If InStr(Source$, ":") <> 0 Then
        Source$ = Mid$(Source$, InStr(Source$, ":") + 1)
    End If
    GetBaseName$ = Source$

    Exit Function

ErrorHandle:
    MsgErr
    Resume Next

End Function
'******************************************************************


'******************************************************************
Private Function GetWindowDesc$(ByVal hwnd)
'   Builds a string descrbing the window in format
'   handle, source application, class
'   seperated by tabs
'

    Dim Desc$
    Dim tbuf$

   Dim inst As Long
   Dim dummy As Long
   
On Error GoTo ErrorHandle

    ' Include the windows handle first
    Desc$ = "&H" + Hex$(hwnd) + Chr$(9)

    ' Get name of source app
    tbuf$ = String$(256, 0) ' Predefine string length
    ' Get instance for window
    inst = GetWindowWord(hwnd, GWW_HINSTANCE)
   
    ' Get the module filename
    dummy = GetModuleFileName(inst, tbuf$, 255)
    tbuf$ = GetBaseName$(tbuf$)
   

    ' The following two lines are equivalent
    'tbuf$ = agGetStringFromLPSTR$(tbuf$)
    ' If InStr(tbuf$, Chr$(0)) Then tbuf$ = Left$(tbuf$, InStr(tbuf$, Chr$(0)) - 1)
   
    ' And add it to the description
    Desc$ = Desc$ + tbuf$ + Chr$(9)

    ' Finally, add the class name
    tbuf$ = String$(256, 0) ' Initialize space again
    dummy = GetClassName(hwnd, tbuf$, 255)
    'tbuf$ = agGetStringFromLPSTR(tbuf$)
    If InStr(tbuf$, Chr$(0)) Then tbuf$ = Left$(tbuf$, InStr(tbuf$, Chr$(0)) - 1)

    Desc$ = Desc$ + tbuf$

    ' And return the description
    GetWindowDesc$ = Desc$

    Exit Function

ErrorHandle:
    MsgErr
    Resume Next

End Function

'******************************************************************
Private Function GetWindowhWnd$(ByVal hwnd)
'   Builds a string descrbing the window in format
'   handle, source application, class
'   seperated by tabs
'
   Dim Desc$
   Dim tbuf$
   Dim inst As Long
   Dim dummy As Long

On Error GoTo ErrorHandle

    ' Include the windows handle first
    Desc$ = "&H" + Hex$(hwnd) + Chr$(9)

    ' Get name of source app
    tbuf$ = String$(256, 0) ' Predefine string length
    ' Get instance for window
    inst = GetWindowWord(hwnd, GWW_HINSTANCE)
   
    ' Get the module filename
    dummy = GetModuleFileName(inst, tbuf$, 255)
    tbuf$ = GetBaseName$(tbuf$)
   

    ' Finally, add the class name
    tbuf$ = String$(256, 0) ' Initialize space again
    dummy = GetClassName(hwnd, tbuf$, 255)
   
    ' And return the description
    GetWindowhWnd$ = Desc$

    Exit Function

ErrorHandle:
    MsgErr
    Resume Next

End Function
'******************************************************************


'******************************************************************
Private Function GetWindowName$(ByVal hwnd)
'   Builds a string descrbing the window in format
'   handle, source application, class
'   seperated by tabs
'
    Dim Desc$
    Dim tbuf$
   
    #If Win32 Then
        Dim inst As Long
        Dim dummy As Long
    #Else
        Dim inst As Integer
        Dim dummy As Integer
    #End If

On Error GoTo ErrorHandle


    ' Include the windows handle first
    Desc$ = "&H" + Hex$(hwnd) + Chr$(9)

    ' Get name of source app
    tbuf$ = String$(256, 0) ' Predefine string length
    ' Get instance for window
    inst = GetWindowWord(hwnd, GWW_HINSTANCE)
   
    ' Get the module filename
    dummy = GetModuleFileName(inst, tbuf$, 255)
    tbuf$ = GetBaseName$(tbuf$)
   

    ' The following two lines are equivalent
    'tbuf$ = agGetStringFromLPSTR(tbuf$)
    ' If InStr(tbuf$, Chr$(0)) Then tbuf$ = Left$(tbuf$, InStr(tbuf$, Chr$(0)) - 1)
   
    ' And add it to the description
    Desc$ = Desc$ + tbuf$ + Chr$(9)

    ' Finally, add the class name
    tbuf$ = String$(256, 0) ' Initialize space again
    dummy = GetClassName(hwnd, tbuf$, 255)
    'tbuf$ = agGetStringFromLPSTR(tbuf$)
    If InStr(tbuf$, Chr$(0)) Then tbuf$ = Left$(tbuf$, InStr(tbuf$, Chr$(0)) - 1)
   
    Desc$ = tbuf$

    ' And return the description
    GetWindowName$ = Desc$

    Exit Function

ErrorHandle:
    MsgErr
    Resume Next

End Function
'******************************************************************


After yo have just to change the attribute to your window to transform this window child of the window you want


Public Sub AddChild(strDescription As String, objParent As Object, Optional blnLike As Boolean = False)
'************************************************************************
'PURPOSE    This function loop in all top level window and search for   *
'           the windows description match with strDescription parameter *
'INPUT:     String to compare with window description                   *
'************************************************************************
'Note Chaine = TACTICIAN if you search for Tactician description
 
   Dim lngCurrHwnd As Long
   Dim lngParentHwnd As Long
   Dim lngChildHwnd As Long
   Dim lngDesktopHwnd As Long
   Dim lngTmpHwnd As Long
   
On Error GoTo ErrorHandle
       
   
    ' The desktop is the highest window
    lngDesktopHwnd = GetDesktopWindow()
   
    'Initialisation
    lngParentHwnd = objParent.hwnd
   
    ' It's first child is the 1st top level window
    lngCurrHwnd = GetWindow(lngDesktopHwnd, GW_CHILD)

    ' Now LOOP all top level windows
    Do
      'If description match with request string
      If blnLike Then
         If UCase(GetWindowName$(lngCurrHwnd)) Like UCase(strDescription) Then
         
            'Window search found
            lngChildHwnd = GetWindowhWnd$(lngCurrHwnd)
           
            'Make this window a child window
            lngTmpHwnd = GetWindowLong(lngChildHwnd, GWL_STYLE)
            lngTmpHwnd = SetWindowLong(lngChildHwnd, GWL_STYLE, lngTmpHwnd + WS_CHILD)
           
            'Set the parent of the window
            lngTmpHwnd = SetParent(lngChildHwnd, lngParentHwnd)
           
            'Don't notify parent if child close
            lngTmpHwnd = GetWindowLong(lngChildHwnd, GWL_EXSTYLE)
            lngTmpHwnd = SetWindowLong(lngChildHwnd, GWL_EXSTYLE, lngTmpHwnd + WS_EX_NOPARENTNOTIFY)
           
            'Hide child window
            lngTmpHwnd = ShowWindow(lngChildHwnd, SW_HIDE)
            lngTmpHwnd = ShowWindow(lngChildHwnd, SW_SHOW)
           
            Exit Do
           
         End If
      Else
         If UCase(GetWindowName$(lngCurrHwnd)) = UCase(strDescription) Then
         
            'Window search found
            lngChildHwnd = GetWindowhWnd$(lngCurrHwnd)
           
            'Make this window a child window
            lngTmpHwnd = GetWindowLong(lngChildHwnd, GWL_STYLE)
            lngTmpHwnd = SetWindowLong(lngChildHwnd, GWL_STYLE, lngTmpHwnd + WS_CHILD)
           
            'Set the parent of the window
            lngTmpHwnd = SetParent(lngChildHwnd, lngParentHwnd)
           
            'Don't notify parent if child close
            lngTmpHwnd = GetWindowLong(lngChildHwnd, GWL_EXSTYLE)
            lngTmpHwnd = SetWindowLong(lngChildHwnd, GWL_EXSTYLE, lngTmpHwnd + WS_EX_NOPARENTNOTIFY)
           
            'Hide child window
            lngTmpHwnd = ShowWindow(lngChildHwnd, SW_HIDE)
           
            Exit Do
           
         End If
      End If
     
      'get the net window
      lngCurrHwnd = GetWindow(lngCurrHwnd, GW_HWNDNEXT)

    Loop While lngCurrHwnd <> 0
   
   
    Exit Sub

ErrorHandle:
    MsgErr
    Resume Next

End Sub






0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

Introduction While answering a recent question about filtering a custom class collection, I realized that this could be accomplished with very little code by using the ScriptControl (SC) library.  This article will introduce you to the SC library a…
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…

772 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

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now