[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 508
  • Last Modified:

Run external exe as a child

How can I call an external application (Such as notepad for a simple example)
and have it show up as a child form?
0
DPPro
Asked:
DPPro
  • 3
  • 2
1 Solution
 
jjmartinCommented:
Post your email address, and I can send you a sample project that will allow you to grab an external exe as a child to your MDI form.

There is to much code, and it is to involved to post here.
0
 
mcriderCommented:
jjmartin,

Please post your code here.  If someone else buys this question in the future, they will not have the code and will have lost their points...


Cheers!
0
 
jjmartinCommented:
OK, I'll go ahead and post it, but it wont be very pretty!  I'll dig it up in a few minutes.
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
jjmartinCommented:
Here is the code:

Copy the following code to notepad and name the file MDIMain.frm

########START CODE###########

VERSION 5.00
Begin VB.MDIForm fMain
   AutoShowChildren=   0   'False
   BackColor       =   &H8000000C&
   Caption         =   "Kidnapper Test Application"
   ClientHeight    =   6540
   ClientLeft      =   3000
   ClientTop       =   3435
   ClientWidth     =   6675
   Icon            =   "MDIMain.frx":0000
   LinkTopic       =   "MDIForm1"
   Begin VB.PictureBox picXY
      Align           =   1  'Align Top
      Height          =   345
      Left            =   0
      ScaleHeight     =   19
      ScaleMode       =   3  'Pixel
      ScaleWidth      =   441
      TabIndex        =   1
      Top             =   330
      Width           =   6675
   End
   Begin VB.PictureBox picHWND
      Align           =   1  'Align Top
      Height          =   330
      Left            =   0
      ScaleHeight     =   18
      ScaleMode       =   3  'Pixel
      ScaleWidth      =   441
      TabIndex        =   0
      Top             =   0
      Width           =   6675
   End
   Begin VB.Menu mnuFileTop
      Caption         =   "File"
      Begin VB.Menu mnuFileFree
         Caption         =   "Free Child"
      End
      Begin VB.Menu mnuSep
         Caption         =   "-"
      End
      Begin VB.Menu mnuFileExit
         Caption         =   "Exit"
      End
   End
End
Attribute VB_Name = "fMain"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
'****************************************************************
'*  VB file:   MDIMain.frm
'*
'*  UNUSUAL DEMO PROGRAM WHICH "GRABS" OTHER WINDOWS AND MAKES THEM "CHILDREN"
'*
'****************************************************************
Option Explicit
Private m_oldWindowProc As Long
Private m_hwndMsgText As String
Private m_xyMsgText As String
Private m_TargetOn As Boolean 'flag for mouse tracking

Private Sub MDIForm_Load()
    'subclass this parentForm
    m_oldWindowProc = SetWindowLong(Me.hwnd, GWL_WNDPROC, AddressOf MDIParentProc)

    'show user prompt
    m_hwndMsgText = "Selected hWnd will appear here"
    m_xyMsgText = "Click and drag target icon to select a window"
    'show "picker" icon
    Me.Picture = Me.Icon
    'refresh form
    Me.Show
   
End Sub

Public Sub UpdateLabels(ByVal X As Long, y As Long)
    Dim ptHwnd As Long
   
    'update the 2 picture controls on fMain
    ptHwnd = WindowFromPoint(X, y)
    m_xyMsgText = CStr(X) & " : " & CStr(y)
    m_hwndMsgText = "SNAGGED HWND = " & CStr(ptHwnd) & _
            " - CLASS NAME = " & vbGetClassName(ptHwnd)
    'show changes
    picXY.Refresh
    picHWND.Refresh

End Sub


Private Sub MDIForm_Unload(Cancel As Integer)
    'un-subclass this parentForm
    Call SetWindowLong(Me.hwnd, GWL_WNDPROC, m_oldWindowProc)
End Sub

Private Sub mnuFileExit_Click()
Unload Me
End Sub

Public Property Get DefWndProc() As Long
    DefWndProc = m_oldWindowProc
End Property

Public Property Get MDIClientHwnd() As Long
    MDIClientHwnd = GetWindow(Me.hwnd, GW_CHILD)
End Property

Private Sub MDIForm_MouseDown(Button As Integer, Shift As Integer, X As Single, y As Single)
    If X < 450 And y < 450 Then
        m_TargetOn = True
        Me.Picture = LoadPicture() 'hide icon
        Me.MousePointer = vbCustom 'show icon as cursor
        Me.MouseIcon = Me.Icon
    End If
End Sub

Private Sub MDIForm_MouseMove(Button As Integer, Shift As Integer, X As Single, y As Single)
    Dim pt As POINT
    'only process mouse moves when dragging
    'If GetCapture() = Me.hWnd Then
    If m_TargetOn Then
        Call GetCursorPos(pt)
        Call UpdateLabels(pt.X, pt.y)
    End If
End Sub

Private Sub MDIForm_MouseUp(Button As Integer, Shift As Integer, X As Single, y As Single)
    Dim pt As POINT
    Dim tmpHwnd As Long
    Dim Msg As String
   
    If m_TargetOn Then
        'here is where the interesting stuff happens
        Call GetCursorPos(pt)
        tmpHwnd = WindowFromPoint(pt.X, pt.y)
        If IsWindowSafeToSnag(tmpHwnd) Then
            tmpHwnd = vbGetTopLevelParent(tmpHwnd)
            Call vbMakeChildWindow(tmpHwnd, fMain)
        Else
            MsgBox "This window is not safe to snag!", vbCritical, App.Title
        End If
           
        'show info in labels
        If mKidnap.SnaggedHwnd Then
            m_hwndMsgText = "Snagged! hwnd: " & CStr(mKidnap.SnaggedHwnd) & " class: " & vbGetClassName(mKidnap.SnaggedHwnd)
        Else
            m_hwndMsgText = "Selected hWnd will appear here"
        End If
        m_xyMsgText = "Click and drag target icon to select a window"
        'refresh labels
        picHWND.Refresh
        picXY.Refresh
        Me.Picture = fMain.Icon
        Me.MousePointer = vbNormal
        m_TargetOn = False
    End If

End Sub

Private Sub mnuFileTop_Click()
    If 0 <> mKidnap.SnaggedHwnd Then
        mnuFileFree.Enabled = True
    Else
        mnuFileFree.Enabled = False
    End If
End Sub
Private Sub mnuFileFree_Click()

    Call mKidnap.ReleaseSnaggedWIndow

End Sub

Private Sub picHWND_Paint()
    Call TextOut(picHWND.hdc, 5, 0&, m_hwndMsgText, Len(m_hwndMsgText))
End Sub


Private Sub picXY_Paint()
    Call TextOut(picXY.hdc, 5, 0&, m_xyMsgText, Len(m_xyMsgText))
End Sub

#######END CODE#######




Copy the following code to notepad and name it APIDecs.bas

#######START CODE#######

Attribute VB_Name = "mAPIDeclares"
Option Explicit

Public Declare Function GetCapture Lib "user32" () As Long
Public Declare Function SetParent Lib "user32" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare Function WindowFromPoint Lib "user32" (ByVal x As Long, ByVal y As Long) As Long
Public Declare Function SetCapture Lib "user32" (ByVal hWnd As Long) As Long
Public Declare Function ReleaseCapture Lib "user32" () As Long
Public Declare Function ClientToScreen Lib "user32" (ByVal hWnd As Long, lpPoint As POINT) As Long
Public Declare Function GetParent Lib "user32" (ByVal hWnd As Long) As Long
Public 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
'PUBLIC Declare Function GetDesktopWindow Lib "user32" () As Long
Public Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Public Declare Function IsWindow Lib "user32" (ByVal hWnd As Long) As Long
Public Declare Function GetWindow Lib "user32" (ByVal hWnd As Long, ByVal wCmd As Long) As Long
Public Declare Function TextOut Lib "gdi32" Alias "TextOutA" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal lpString As String, ByVal nCount As Long) As Long
Public Declare Function SetWindowPos Lib "user32" (ByVal hWnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Declare Function GetCursorPos Lib "user32" (ByRef lpPoint As POINT) As Long      'C BOOL
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Public Declare Function GetMenu Lib "user32" (ByVal hWnd As Long) As Long ' hMenu
Public Declare Function SetMenu Lib "user32" (ByVal hWnd As Long, ByVal hmenu As Long) As Long 'C BOOL
Public Declare Function IsWindowVisible Lib "user32" (ByVal hWnd As Long) As Long 'C BOOL

Public Type POINT
    x As Long
    y As Long
End Type

Public Declare Function DefFrameProc Lib "user32" Alias "DefFrameProcA" ( _
                            ByVal hWnd As Long, _
                            ByVal hWndMDIClient As Long, _
                            ByVal uMsg As Long, _
                            ByVal wParam As Long, _
                            lParam As Any) As Long
Public Declare Function DefMDIChildProc Lib "user32" Alias "DefMDIChildProcA" _
                                    (ByVal hWnd As Long, _
                                    ByVal uMsg As Long, _
                                    ByVal wParam As Long, lParam As Any) As Long

Public Const WM_COMMAND = &H111
Public Const WM_MENUCHAR = &H120
Public Const WM_MENUSELECT = &H11F
Public Const WM_MDISETMENU = &H230
Public Const WM_MDIREFRESHMENU = &H234
Public Const WM_MOVE = &H3
Public Const WM_WINDOWPOSCHANGING = &H46
Public Const WM_MOVING = &H216
Public Const WM_SIZING = &H214
Public Const WM_ACTIVATE = &H6
Public Const WM_ACTIVATEAPP = &H1C
Public Const WM_CHILDACTIVATE = &H22
Public Const WM_CLOSE = &H10
Public Const WM_DESTROY = &H2
Public Const WM_MDIDESTROY = &H221
Public Const WM_SYSCOMMAND = &H112
Public Const WA_ACTIVE = 1
Public Const WA_CLICKACTIVE = 2
Public Const WA_INACTIVE = 0
Public Const SC_CLOSE = &HF060&
Public Const WM_SETFOCUS = &H7

Public Const WS_CHILD = &H40000000
Public Const WS_CLIPSIBLINGS = &H4000000
Public Const WS_CLIPCHILDREN = &H2000000
Public Const WS_EX_MDICHILD = &H40&
Public Const WS_EX_WINDOWEDGE = &H100&
Public Const GW_CHILD = 5
Public Const GWL_STYLE = (-16)
Public Const GWL_EXSTYLE = (-20)
Public Const HWND_TOPMOST = -1
Public Const HWND_NOTOPMOST = -2
Public Const SWP_NOMOVE = &H2
Public Const SWP_NOREDRAW = &H8
Public Const SWP_NOOWNERZORDER = &H200      '  Don't do owner Z ordering
Public Const SWP_NOSIZE = &H1
Public Const GWL_WNDPROC = (-4)

######END CODE#######




Copy the following code to notepad and name the file: MKidnap.bas

#####START CODE########
Attribute VB_Name = "mKidnap"
'****************************************************************
'*  VB file:   mKidnap.bas...
'*
'*  A very unusual sample program which demos working with
'*  windows in other processes from VB.  Be careful!
'*
'****************************************************************
Option Explicit
'module-level private storage
Private m_hwndSnaggedWindow As Long
Private m_SnaggedWindowProc As Long
Private m_SnaggedWindowStyles As Long
Private m_SnaggedWindowEXStyles As Long
Private m_SnaggedWindowOldParent As Long
Private m_SnaggedWindowMenu As Long
Private m_MDIParentOldMenu As Long

Public Property Get SnaggedHwnd() As Long
    SnaggedHwnd = m_hwndSnaggedWindow
End Property

Public Function IsWindowSafeToSnag(ByVal hwnd As Long) As Boolean
    'returns true if window is safe to snag
    'note - this is just for this demo proggy and is not a very professional way to do things :-)
        'exit if function failed or user clicked the desktop
   
    Dim UserRet As VbMsgBoxResult
   
    'make sure this is a window  :-)
    If 0 = IsWindow(hwnd) Then Exit Function
   
    'find parent window of selected point
    hwnd = vbGetTopLevelParent(hwnd)
   
'    If 0 <> IsWindowVisible(hWnd) Then
'        UserRet = MsgBox("The parent window of the select window is not visible! ( Class: " & _
'                    vbGetClassName(hWnd) & " )" & vbCrLf & _
'                    "Do you want to try to snag it anyway?", vbMsgBoxSetForeground Or _
'                                                                            vbQuestion Or vbDefaultButton2 Or _
'                                                                            vbSystemModal Or vbYesNo, _
'                                                                            App.Title)
'        If UserRet <> vbYes Then Exit Function
'    End If
   
    'exit if user clicked on the APP or a child window of it
    If fMain.hwnd = hwnd Then Exit Function
    If m_hwndSnaggedWindow = hwnd Then Exit Function
    'exit if user clicked on an icon on the desktop
    If UCase(vbGetClassName(hwnd)) = "PROGMAN" Then Exit Function
    'exit if user clicks on the taskbar window
    If UCase(vbGetClassName(hwnd)) = "SHELL_TRAYWND" Then Exit Function
    'exit if user clicks on the VB IDE
    If UCase(vbGetClassName(hwnd)) = "WNDCLASS_DESKED_GSK" Then Exit Function
    'exit if user clicks on a child window of the hidden VB IDE owner window
    If UCase(vbGetClassName(hwnd)) = "IDEOWNER" Then Exit Function
    'exit if the user clicks on WinHelp (it doesn't like to be captured)
    If UCase(vbGetClassName(hwnd)) = "MS_WINDOC" Then Exit Function
    'now we are sure the user chose a real window and its not our app or some obvious danger windows
    'let's snag it!
    IsWindowSafeToSnag = True
End Function
Public Function vbMakeChildWindow(ByVal ChildHwnd As Long, ByVal MDIParentForm As MDIForm) As Long
   
    Dim MDIClientWnd As Long 'the client area of the MDIParent
   
'    If 0 <> m_hwndSnaggedWindow Then 'release old snagged window
'        Call ReleaseSnaggedWIndow
'    End If
    'save info about the new child window and mess with it's bits...
    m_hwndSnaggedWindow = ChildHwnd
    m_SnaggedWindowStyles = GetWindowLong(ChildHwnd, GWL_STYLE)
    m_SnaggedWindowEXStyles = GetWindowLong(ChildHwnd, GWL_EXSTYLE)
    'we can get the window proc, and call it but can't use SetWindowLong() across processes :-(
    m_SnaggedWindowProc = GetWindowLong(ChildHwnd, GWL_WNDPROC)
    MDIClientWnd = GetWindow(MDIParentForm.hwnd, GW_CHILD) 'get client area of MDIWindow
    m_SnaggedWindowOldParent = SetParent(ChildHwnd, MDIClientWnd) 'now set our form as this window's parent!
    Call SetWindowLong(ChildHwnd, GWL_STYLE, WS_CHILD Or WS_CLIPSIBLINGS Or WS_CLIPCHILDREN) 'change the styles of the "Child"
    Call SetWindowLong(ChildHwnd, GWL_EXSTYLE, WS_EX_MDICHILD Or WS_EX_WINDOWEDGE)
    'now size and position the "victim" window inside our window
    Call MoveWindow(ChildHwnd, 5, _
                    30, _
                    (MDIParentForm.ScaleWidth / Screen.TwipsPerPixelX) - 10, _
                    (MDIParentForm.ScaleHeight / Screen.TwipsPerPixelY) - 70, _
                    -1&)
   
    'add menu to MDI parent and save old hmenus
    m_SnaggedWindowMenu = GetMenu(m_hwndSnaggedWindow)
    m_MDIParentOldMenu = GetMenu(MDIParentForm.hwnd)
    Debug.Print "MDI menu = " & m_MDIParentOldMenu
    Call SetMenu(m_hwndSnaggedWindow, 0&)
    'Call SendMessage(MDIParentForm.hwnd, WM_MDISETMENU, m_SnaggedWindowMenu, 0&)
    Call SetMenu(MDIParentForm.hwnd, m_SnaggedWindowMenu)
    'Call SendMessage(MDIParentForm.hwnd, WM_MDIREFRESHMENU, 0&, 0&)
    vbMakeChildWindow = True
End Function

Public Function ReleaseSnaggedWIndow() As Long
    If 0 = m_SnaggedWindowProc Then Exit Function
    Call SetMenu(m_hwndSnaggedWindow, m_SnaggedWindowMenu)
    'Call SendMessage(fMain.hwnd, WM_MDISETMENU, m_MDIParentOldMenu, 0&)
    Call SetMenu(fMain.hwnd, m_MDIParentOldMenu)
    Call SendMessage(fMain.hwnd, WM_MDIREFRESHMENU, 0&, 0&)
    Call SetParent(m_hwndSnaggedWindow, m_SnaggedWindowOldParent)
    Call SetWindowLong(m_hwndSnaggedWindow, GWL_STYLE, m_SnaggedWindowStyles)
    Call SetWindowLong(m_hwndSnaggedWindow, GWL_EXSTYLE, m_SnaggedWindowEXStyles)
    m_SnaggedWindowProc = 0
    m_hwndSnaggedWindow = 0
    m_SnaggedWindowStyles = 0
    m_SnaggedWindowEXStyles = 0
    m_SnaggedWindowOldParent = 0
    m_SnaggedWindowMenu = 0
    m_MDIParentOldMenu = 0
   
    ReleaseSnaggedWIndow = True
End Function


Public Function vbGetClassName(ByVal hwnd As Long) As String
    'returns class name for given hwnd
    'uses VB immediate window to report errors
    'returns vbNullString for invalid hwnd
    Dim sBuf As String
   
    If 0 = IsWindow(hwnd) Then Exit Function
    sBuf = String$(256, vbNullChar)
    If 0 = GetClassName(hwnd, sBuf, 255) Then
        Debug.Print "GetClassName() returned error in vbGetClassName()"
    Else
        If InStr(sBuf, vbNullChar) Then
            vbGetClassName = Left$(sBuf, InStr(sBuf, vbNullChar) - 1)
        End If
    End If
   
End Function

Public Function vbGetTopLevelParent(ByVal hwnd As Long) As Long
    'returns highest-level parent window of hWnd
    'if hWnd is the parent it just returns the input hWnd
    Dim ParentHwnd As Long
    Dim tmpHwnd As Long
   
    tmpHwnd = hwnd
    If 0 <> IsWindow(tmpHwnd) Then
        Do
            ParentHwnd = GetParent(tmpHwnd)
            If 0 = ParentHwnd Then  'ptHwnd must be top-level
                ParentHwnd = tmpHwnd
                Exit Do
            End If
            'Debug.Print "parenthwnd = " & parentHwnd
            tmpHwnd = ParentHwnd 'save parent's hwnd and try again
        Loop
    End If
    vbGetTopLevelParent = ParentHwnd
End Function

Public Function vbMakeWindowTopmost(ByVal hwnd As Long, Optional fOn As Boolean = True) As Long
    Dim flags As Long
    flags = SWP_NOMOVE Or SWP_NOSIZE
    If fOn Then
        flags = flags Or HWND_TOPMOST
    Else
        flags = flags Or HWND_NOTOPMOST
    End If
   
    vbMakeWindowTopmost = SetWindowPos(hwnd, 0&, 0&, 0&, 0&, 0&, flags)
   
       
End Function

'Private Function MDIChildWndProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
'    Dim tmpproc As Long
'    Select Case uMsg
''        Case WM_MDIACTIVATE, WM_MDICASCADE, WM_MDICREATE, WM_MDIDESTROY, _
''                WM_MDIMAXIMIZE, WM_MDIGETACTIVE, WM_MDIICONARRANGE, WM_SETTEXT, _
''                WM_MDINEXT, WM_MDIREFRESHMENU, WM_MDIRESTORE, WM_MDITILE, WM_MDISETMENU, _
''                WM_SIZE, WM_SIZING, WM_SYSCOMMAND, _
''                WM_MENUCHAR, WM_PARENTNOTIFY, WM_CHILDACTIVATE, WM_ACTIVATE, _
''                WM_ACTIVATEAPP, WM_KILLFOCUS, WM_SYSCHAR, WM_SYSKEYDOWN, WM_SYSKEYUP, _
''                WM_KEYDOWN, WM_KEYUP, WM_SETFOCUS
''
''        Case WM_MOVE, WM_MOVING, WM_WINDOWPOSCHANGING
'
'
'        Case WM_CLOSE, WM_DESTROY, WM_MDIDESTROY
'                Debug.Print "WM_CLOSE"
'                tmpproc = m_SnaggedWindowProc
'                Call ReleaseSnaggedWIndow
'                MDIChildWndProc = CallWindowProc(tmpproc, hwnd, uMsg, wParam, lParam)
'        Case Else
'                Debug.Print uMsg
'                MDIChildWndProc = CallWindowProc(m_SnaggedWindowProc, hwnd, uMsg, wParam, lParam)
'                'MDIChildWndProc = DefMDIChildProc(hWnd, uMsg, wParam, ByVal lParam)
'                'MDIChildWndProc = -1
'    End Select
'
'    Exit Function
'
'MyWindowProcErrorHandler:
'    If Err.Number = 9 Then
'        Exit Function
'    Else
'        Resume Next
'    End If
'End Function

Public Function MDIParentProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Dim UserRet As VbMsgBoxResult
    Select Case uMsg
'        Case WM_ACTIVATE
'            If wParam = WA_ACTIVE Or wParam = WA_CLICKACTIVE Then
'                Select Case lParam
'                    Case m_hwndSnaggedWindow
'
'                        MDIParentProc = CallWindowProc(fMain.DefWndProc, hWnd, uMsg, wParam, lParam)
'
'                    Case fMain.hWnd
'                        Debug.Print "release a"
'                        If Not IsWindow(m_hwndSnaggedWindow) Then
'                            Debug.Print "release 1"
'                            Call ReleaseSnaggedWIndow
'                        End If
'                        MDIParentProc = CallWindowProc(fMain.DefWndProc, hWnd, uMsg, wParam, lParam)
'
'                    Case GetWindow(fMain.hWnd, GW_CHILD)
'                        Debug.Print "release b"
'                        If 0 <> m_hwndSnaggedWindow Then 'this is just a kludge to see if child window has been closed directly
'                            If Not IsWindow(m_hwndSnaggedWindow) Then
'                                Debug.Print "release 2"
'                                Call ReleaseSnaggedWIndow
'                            End If
'                        End If
'                        MDIParentProc = CallWindowProc(fMain.DefWndProc, hWnd, uMsg, wParam, lParam)
'
'                    Case Else
'                        MDIParentProc = 0
'
'                End Select
'            Else
'
'                MDIParentProc = CallWindowProc(fMain.DefWndProc, hWnd, uMsg, wParam, lParam)
'            End If
        Case WM_COMMAND ' by intercepting this we can make the menu "functional" even across processes!
            If 0 <> m_SnaggedWindowMenu Then 'child menu is hooked
                If 0 = HiWord(wParam) Then 'this command came from a menu
                    'pass it on to the child app
                    MDIParentProc = SendMessage(m_hwndSnaggedWindow, uMsg, wParam, ByVal lParam)
                    Debug.Print "Child menu command re-routed back to child"
                Else
                    'pass it on to the child app
                    MDIParentProc = SendMessage(m_hwndSnaggedWindow, uMsg, wParam, ByVal lParam)
                    Debug.Print "Child accelerator key command re-routed back to child"
                End If
            Else
                MDIParentProc = CallWindowProc(fMain.DefWndProc, hwnd, uMsg, wParam, lParam)
            End If
        Case WM_SYSCOMMAND
            If SC_CLOSE = wParam Then
                Debug.Print "WC_CLOSE"
                If 0 <> m_hwndSnaggedWindow Then
                    'ask user for input
                    UserRet = MsgBox("Do you want to close the snagged window too?", vbMsgBoxSetForeground Or _
                                                                                    vbQuestion Or vbDefaultButton2 Or _
                                                                                    vbSystemModal Or vbYesNoCancel, _
                                                                                    App.Title)
                    Select Case UserRet
                        Case vbYes
                            MDIParentProc = CallWindowProc(fMain.DefWndProc, hwnd, uMsg, wParam, lParam)
                        Case vbNo
                            Call ReleaseSnaggedWIndow
                            MDIParentProc = CallWindowProc(fMain.DefWndProc, hwnd, uMsg, wParam, lParam)
                        Case vbCancel
                            MDIParentProc = 0
                    End Select
                Else
                    MDIParentProc = CallWindowProc(fMain.DefWndProc, hwnd, uMsg, wParam, lParam)
                End If
            Else
                MDIParentProc = CallWindowProc(fMain.DefWndProc, hwnd, uMsg, wParam, lParam)
            End If
        Case WM_SETFOCUS
            If Not IsWindow(m_hwndSnaggedWindow) Then
                Call ReleaseSnaggedWIndow
            End If
            MDIParentProc = CallWindowProc(fMain.DefWndProc, hwnd, uMsg, wParam, lParam)
        Case Else

            MDIParentProc = CallWindowProc(fMain.DefWndProc, hwnd, uMsg, wParam, lParam)
           
    End Select
   
End Function

Private Function HiWord(ByVal dw As Long) As Integer
    HiWord = (dw And &HFFFF0000) \ 65536
End Function
####END CODE ######


Include all the preceding files in a single project to see the demo.
0
 
DPProAuthor Commented:
Bear with me...I hate API's. Give me a little while to incorporate it into what I need to do.

Looks good so far!
0
 
DPProAuthor Commented:
Thanks a lot. After deleting most of the code, and getting the handle a different way, I got what I needed.

This worked just fine, except on my mdi, I have a Sheridan panel with command buttons on it. The panel is covered, but I can live with that for now......

Again Thanks
0

Featured Post

Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now