Solved

How to make an exe file into a child of another window

Posted on 2001-08-23
15
1,296 Views
Last Modified: 2012-06-21
I have an app that consists of numerous small exe files - necessary as the updates download over CDPD devices which are very slow.  We would like to have to whole app execute within a frame, with a vertical menu, similar to outlook.

We have solved almost everything except how to load the exe files as children of a fram contained on what would become the MDI parent.

Does anyone know of a way to do this, so the newly loaded exe file operates just as if it were a child, or owned window, of the frame.

We have some work-arounds, but they do not provide for minimization, maximixing, etc.  We would prefer a "true" child solution.
0
Comment
Question by:ronegger
  • 5
  • 2
  • 2
  • +5
15 Comments
 
LVL 15

Expert Comment

by:ameba
ID: 6419920
Hi, ronegger

VB6 doesn't support having MDI child in other EXE.
You can develop ActiveX controls and dinamically load them into MDI child form:
there was an article by Dan Appleman on how to do that, see VBPJ 3/99, and code sample is in vbpj0399da.zip file, if you have access to these on devx...
0
 
LVL 15

Expert Comment

by:ameba
ID: 6419959
Here is the link to article:
http://www.devx.com/upload/free/features/vbpj/1999/mar99/da0399/da0399.asp
Dynamic MDI Forms ? A New Approach
Three features in VB combine to make new architectures for dynamically extendable application frameworks.
by Dan Appleman
0
 
LVL 8

Expert Comment

by:Dave_Greene
ID: 6419985
I have done what your talking about.  But it wasn't with multiple exe's it was with multiple ActiveX.Dlls.  You either need to purchase a 3rd party tool to fool the MDI environment or write it yourself.  Depending on your resources, purchasing a package to help is the best idea.

I used the objective toolkit/x from stingray software.

0
 
LVL 8

Expert Comment

by:Dave_Greene
ID: 6419995
Here is the link to the above mentioned toolkit

http://www.roguewave.com/products/stingray/
0
 
LVL 6

Expert Comment

by:andyclap
ID: 6420110
I use the ocx approach myself, it's a very good way of doing things, especailly if you have a large development team. I can heartily recommend it.
Pulling forms out of other process spaces into your framework is not going to be very successful; even within the same process space (ie forms in dlls) causes havoc with VB's form mechanism - there is some VB specific 'thunderform' code going on behind the scenes which causes problems, especially with some of the newer common controls.
0
 
LVL 27

Expert Comment

by:Ark
ID: 6420184
Hi
Take a look at http://www.shrinkwrapvb.com/kidnap.htm

>>This is a really interesting sample VB5 project. Run this and you will see a "target" icon on an empty MDI form. Click and drag the "target" to any running app (notepad.exe or calc.exe for example). Kidnap will grab the external app, steal it's menu and make it a "child" window. I went so far as to make the menus functional in this demo, but until I learn more about cross-process subclassing, you are on your own if you want to subclass the external child window. *note* this sample uses subclassing which can cause problems in the VB IDE during break mode. If you want to step through the code, please comment out the SetWindowLong() statement in MDIForm_Load() and MDIForm_UnLoad() first<<

Cheers
0
 
LVL 4

Expert Comment

by:wileecoy
ID: 6420219
I have what I think will help.

I merged code from Microsoft's website in addition to an application that I downloaded for free (from somewhere) written by (I assume anyway) vbguy@i.am or http://i.am/vbguy.

I will post it in the following messages.

Start a standard exe project

You will need to copy and paste the code into notepad, and then save the files with the proper extension.

First, .frm for the form (frmMain.frm)
Second, .bas for module (module1.bas)
Third, .cls for class (Window.cls)

You will then need to add each of these to your project (and don't forget to remove the blank form that is automatically created with your new project).

Before running the code you will also need to set your start-up to frmMain (project properties).

Wileecoy (see next messages)
0
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 
LVL 4

Expert Comment

by:wileecoy
ID: 6420222
VERSION 5.00
Begin VB.Form Form1
   Caption         =   "Form1"
   ClientHeight    =   5220
   ClientLeft      =   48
   ClientTop       =   348
   ClientWidth     =   8160
   LinkTopic       =   "Form1"
   ScaleHeight     =   5220
   ScaleWidth      =   8160
   StartUpPosition =   3  'Windows Default
   Begin VB.TextBox txtClassName
      Height          =   285
      Left            =   5148
      Locked          =   -1  'True
      TabIndex        =   10
      Top             =   1008
      Width           =   2895
   End
   Begin VB.CommandButton cmdCalc
      Caption         =   "Open Calculator In This Form"
      Height          =   264
      Left            =   108
      TabIndex        =   9
      Top             =   72
      Width           =   4080
   End
   Begin VB.CommandButton cmdExit
      Caption         =   "Exit"
      Height          =   264
      Left            =   6984
      TabIndex        =   8
      Top             =   72
      Width           =   1056
   End
   Begin VB.ComboBox cboChild
      Height          =   288
      Left            =   4500
      Style           =   2  'Dropdown List
      TabIndex        =   7
      Top             =   1656
      Width           =   3588
   End
   Begin VB.TextBox txtWindowText
      Height          =   285
      Left            =   5148
      Locked          =   -1  'True
      TabIndex        =   5
      Top             =   360
      Width           =   2895
   End
   Begin VB.CommandButton cmdRefresh
      Caption         =   "Refresh"
      Height          =   264
      Left            =   4500
      TabIndex        =   4
      Top             =   4896
      Width           =   3576
   End
   Begin VB.ListBox lstWindow
      Height          =   2928
      Left            =   4500
      TabIndex        =   3
      Top             =   1980
      Width           =   3576
   End
   Begin VB.TextBox txthWnd
      Height          =   285
      Left            =   5148
      Locked          =   -1  'True
      TabIndex        =   1
      Top             =   684
      Width           =   2895
   End
   Begin VB.CommandButton cmdTransfer
      Caption         =   "Transfer"
      Height          =   264
      Left            =   4500
      TabIndex        =   0
      Top             =   72
      Width           =   984
   End
   Begin VB.Label lblNote
      Alignment       =   2  'Center
      Caption         =   "Note: Only select Windows Explorer to transfer."
      Height          =   228
      Left            =   4464
      TabIndex        =   12
      Top             =   1404
      Width           =   3576
   End
   Begin VB.Label lblClassName
      AutoSize        =   -1  'True
      Caption         =   "Class:"
      Height          =   192
      Left            =   4680
      TabIndex        =   11
      Top             =   1044
      Width           =   420
   End
   Begin VB.Line Line1
      X1              =   4320
      X2              =   4320
      Y1              =   72
      Y2              =   5112
   End
   Begin VB.Label lblTitle
      Caption         =   "Title"
      Height          =   228
      Left            =   4644
      TabIndex        =   6
      Top             =   396
      Width           =   480
   End
   Begin VB.Label lblHWnd
      Caption         =   "hWnd"
      Height          =   228
      Left            =   4644
      TabIndex        =   2
      Top             =   720
      Width           =   480
   End
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Dim wnd As New Window
Dim m_hWnd As Long
Private Sub cboChild_Change()
    FillProps cboChild.ItemData(cboChild.ListIndex)
End Sub

Private Sub cmdCalc_Click()
Dim hWindow As Long

Shell "calc.exe", vbNormalFocus

'* Determine the handle to the Calculator window.
hWindow = FindWindow(vbNullString, "Calculator")

wnd.hwnd = hWindow
wnd.SetWindowParent Me.hwnd

'* Post a message to Calc to end its existence.
'X& = SendMessage(Handle, WM_SYSCOMMAND, SC_CLOSE, NILL)


End Sub

Private Sub cmdExit_Click()
    Unload Me
End Sub
Private Sub cmdRefresh_Click()
    lstWindow.Clear
    Dim sTitle As String, hwnd As Long
    hwnd = wnd.GetChildWindow(wnd.DesktopWindow)
    Do While hwnd <> 0
        wnd.hwnd = hwnd
        sTitle = wnd.GetText()
        If sTitle <> "" Then lstWindow.AddItem Trim(sTitle):  lstWindow.ItemData(lstWindow.NewIndex) = hwnd
        hwnd = wnd.NextWindow(hwnd)
    Loop
    lstWindow.ListIndex = 0
End Sub

Private Sub cmdTransfer_Click()
    If txtClassName.Text = "ExploreWClass" Then
        wnd.hwnd = Val(txthWnd)
        wnd.SetWindowParent Me.hwnd
    Else
        MsgBox "For safety purposes, please only choose Windows Explorer to transfer", vbOKOnly, "Transfer to Child"
    End If
End Sub
Public Function SetWindowParent(hwndNewParent As Long) As Long
    SetWindowParent = SetParent(hwnd, hwndNewParent)
End Function

Private Sub lstWindow_Click()
    cboChild.Clear
    Dim sTitle As String, hwnd As Long
    hwnd = wnd.GetChildWindow(lstWindow.ItemData(lstWindow.ListIndex))
    Do While hwnd <> 0
        wnd.hwnd = hwnd
        sTitle = wnd.GetText()
        If sTitle <> "" Then cboChild.AddItem Trim(sTitle): cboChild.ItemData(cboChild.NewIndex) = hwnd
        hwnd = wnd.NextWindow(hwnd)
    Loop
    If cboChild.ListCount > 0 Then cboChild.ListIndex = 0
    FillProps lstWindow.ItemData(lstWindow.ListIndex)
End Sub
Sub FillProps(lWindow As Long)
    Dim sClassName As String
    m_hWnd = lWindow
    wnd.hwnd = lWindow
    txtWindowText.Text = wnd.GetText()
    txthWnd.Text = m_hWnd
    'Get Window's Class Name
    txtClassName.Text = wnd.GetWindowClassName()
End Sub
0
 
LVL 4

Expert Comment

by:wileecoy
ID: 6420227
Attribute VB_Name = "Module1"
'Paste in notepad and save as Module1.bas
Public Declare Function FindWindow Lib "user32" _
         Alias "FindWindowA" _
         (ByVal lpClassName As String, _
         ByVal lpWindowName As String) As Long

Public hwnd As Long

0
 
LVL 4

Expert Comment

by:wileecoy
ID: 6420230
VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
  Persistable = 0  'NotPersistable
  DataBindingBehavior = 0  'vbNone
  DataSourceBehavior  = 0  'vbNone
  MTSTransactionMode  = 0  'NotAnMTSObject
END
Attribute VB_Name = "Window"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Explicit
'Window Functions
Private Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
Private Declare Function GetDesktopWindow Lib "user32" () As Long
Private Declare Function GetNextWindow Lib "user32" Alias "GetWindow" (ByVal hwnd As Long, ByVal wFlag 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 SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long

'Other Functions
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Declare Function GetWindowDC Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function SetParent Lib "user32" (ByVal hWndChild As Long, ByVal hwndNewParent As Long) As Long

' GetWindow() Constants
Private Const GW_HWNDFIRST = 0
Private Const GW_HWNDLAST = 1
Private Const GW_HWNDNEXT = 2
Private Const GW_HWNDPREV = 3
Private Const GW_OWNER = 4
Private Const GW_CHILD = 5
Private Const GW_MAX = 5

Public hwnd As Long
Public Function GetText() As String
Dim sText As String * 255
Dim tmpLen As Long
tmpLen = GetWindowText(hwnd, sText, 255)
GetText = Left(sText, tmpLen)
End Function
Public Function GetWindowClassName() As String
Dim sClass As String * 255
Dim tmpLen As Long
tmpLen = GetClassName(hwnd, sClass, 255)
GetWindowClassName = Left(sClass, tmpLen)
End Function
Public Function SetWindowParent(hwndNewParent As Long) As Long
SetWindowParent = SetParent(hwnd, hwndNewParent)
End Function
Public Function GetChildWindow(hwndParent As Long)
GetChildWindow = GetWindow(hwndParent, GW_CHILD)
End Function
Public Function NextWindow(hwnd As Long)
NextWindow = GetNextWindow(hwnd, GW_HWNDNEXT)
End Function
Public Function DesktopWindow() As Long
DesktopWindow = GetDesktopWindow
End Function
0
 
LVL 4

Accepted Solution

by:
wileecoy earned 200 total points
ID: 6420244
ok - after you save all of those to the proper file type from notepad, here is what you will have.

1.  on the left side of the form is a button that says "Open calculator in this form".

click on it and the windows calculator will open and be a child of the form.

2.  on the right side, click on the "Refresh" button.
That will populate the listbox with all of the running processes.

If you click on the item in the listbox, you will see 3 textboxes that will be populated with the Handle, Form Text, and Class of the item clicked.

If you then press the "Transfer" button, that application will be transfered as a child of the form.

Since this is a little dangerous, I added an If...Then that will only allow you to transfer a Windows Explorer form as a child.

However, if you are feeling courageous, remove that code, and see what you get.

Hope that helps - let me know if you have any questions.

hth - Wileecoy.
0
 
LVL 6

Expert Comment

by:pierrecampe
ID: 6420710
ping
0
 
LVL 8

Expert Comment

by:glass_cookie
ID: 6420788
Hi!

Here's 2 examples on how you can make an exe into a Mdi child:

Download...
http://www.vb-helper.com/HowTo/startinm.zip
Description: Start a program inside another program's MDI form (3K)


Download...
http://www.vb-helper.com/HowTo/startin.zip
Description: Start a program inside another (3K)

Hope it helps!

That's it!

glass cookie ; )
0
 
LVL 8

Expert Comment

by:glass_cookie
ID: 6420790
For the second example, the program would start in a picture box.  By doing that, you could treat the picture box as some kind of 'MDI form' : )
0
 
LVL 49

Expert Comment

by:Ryan Chong
ID: 6421461
<listening..>
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

There are many ways to remove duplicate entries in an SQL or Access database. Most make you temporarily insert an ID field, make a temp table and copy data back and forth, and/or are slow. Here is an easy way in VB6 using ADO to remove duplicate row…
Introduction While answering a recent question (http://www.experts-exchange.com/Q_27402310.html) in the VB classic zone, I wrote some VB code in the (Office) VBA environment, rather than fire up my older PC.  I didn't post completely correct code o…
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…

744 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

12 Experts available now in Live!

Get 1:1 Help Now