Introduction
I was given so many tasks of automation. That I was really fed up with them. Once my manager asked me to automate IE as in our application, so that user feels that it's the application's IE browser. One other day, I was asked to add Word control and make a Window in the application with Word look and feel and same Toolbars. So then I thought there must be a way in Dotnet to add the applications "as is" and some kind of communication with them as well.
Note: Of course, the kind of flexibility you achieve with automation can not be achieved via this way. But "according to the requirements", it can reduce time to market and prevent adding heavy automation code and DLLs.
Using the code
I have shown how different applications can be added easily in a control or Form. If you add it in a Form, user will feel that it will become kind of MDI application holding other application. First demo application shows how to add Command Prompt, Internet Explorer, Windows Media Player and WinWord. Second application shows how to interact with them.
Add Applications Demo
Main functions which are used in this case are from user32. That are SetParent
, ShowWindow
and SetForegroundWindow
. Rest of the help is provided by managed Process
, ProcessInfo
and SendKeys
classes.
Declare Function ShowWindow Lib "user32" (ByVal hWnd As System.IntPtr,
ByVal nCmdShow As Integer) As Boolean
Declare Function SetParent Lib "user32" (ByVal hWndChild As System.IntPtr,
ByVal hWndNewParent As System.IntPtr)
As System.IntPtr
Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As System.IntPtr)
As Integer
Following code is written on "Open -> Command Prompt-> Open as Normal and Add as Min" menu. It opens the command window using Process.Start()
as normal and then adds it to parent window (which is a .NET window) as a sub window using ShowWindow
function and makes its state minimized.
Dim pinfo As New ProcessStartInfo("cmd")
Dim p As Process = System.Diagnostics.Process.Start(pinfo)
SetParent(p.MainWindowHandle, Me.Handle)
ShowWindow(p.MainWindowHandle, SW_MINIMIZE)
Second menu is Open ->Get Running Browser and make it full screen. You have to have at least one IE window open for this functionality. It captures it and adds it in the main form as maximized. Closing the application will also close this window.
Dim p As Process() = System.Diagnostics.Process.GetProcessesByName("iexplore")
Try
SetParent(p(0).MainWindowHandle, Me.Handle)
ShowWindow(p(0).MainWindowHandle, SW_MAXIMIZE)
Catch ex As Exception
MessageBox.Show("No IE window open - Please open one")
End Try
Third menu is opening a Media Player and adding it to a button and play a file present in XP Media directory. Open -> Media Player - in a Button - Max. Another interesting point is, Media folder is not listed in Enviornment.SpecialFolders
. So you have to get it like the way I have used below:
Dim p As Process = System.Diagnostics.Process.Start("mplayer2",
Environment.GetEnvironmentVariable("WINDIR") + "\\Media\\Windows XP Startup.wav")
p.WaitForInputIdle()
SetParent(p.MainWindowHandle, Me.Button1.Handle)
ShowWindow(p.MainWindowHandle, SW_MAXIMIZE)
Fourth and last menu is adding WinWord and add it in a Label. Open -> WinWord - In a Label. WaitForInputIdle
helps in getting the Winword to an idle state.
Dim pinfo As New ProcessStartInfo("WINWORD")
Dim p As Process = System.Diagnostics.Process.Start(pinfo)
p.WaitForInputIdle()
SetParent(p.MainWindowHandle, Me.Label1.Handle)
Interact with Application (Calc.exe and IE)
Run the demo. Open any website using IE window external from the demo. Click "Get Running IE Window". It will get the running IE window instance and add it to the control and get its HTMLDocument and display all the source in the TextBox. It will also display its title on the label next to the button. Click on the "Open Calc" button. It will open the calc in user Window. Do all the calculations and close the calculator. The result will come back to the TextBox next to "Open Calc" button.
IE demo important points
IE demo uses IEDom
class to retrieve the DOM of IE window. IsIEServerWindow
function looks for Internet Explorer_Server
class. WM_HTML_GETOBJECT
message is send to Windows handle using RegisterWindowMessage
Win32 call. Then ObjectFromLresult
function to get IHTMLDocument
object.
If Not IsIEServerWindow(hWnd) Then
win32.EnumChildWindows(hWnd, AddressOf EnumChild, hWnd)
End If
If Not hWnd.Equals(0) Then
lMsg = win32.RegisterWindowMessage("WM_HTML_GETOBJECT")
Call win32.SendMessageTimeout(hWnd, lMsg, 0, 0, _
win32.SMTO_ABORTIFHUNG, 1000, lRes)
If lRes Then
hr = ObjectFromLresult(lRes, IID_IHTMLDocument, 0, IEDOMFromhWnd)
If hr Then Throw New COMException(hr)
End If
End If
End If
Also used RemoveMenuBar
function to remove IE Rebar.
If ClassName.ToString() = "ReBarWindow32" Then
win32.ShowWindow(hWnd, 0)
Return 0
Else
Return 1
End If
Calc demo important points
ExteranlCalc
form opens calc.exe on load and adds it to itself. removeTitleBarAndRescale
function is used to remove the titlebar, stop resizing. SetWindowPos
function is used to set the position of the Window and place it in a way to hide menubar of calc.
win32.SetParent(p.MainWindowHandle, Me.Handle)
win32.removeTitleBarAndRescale(p.MainWindowHandle)
win32.SetWindowPos(p.MainWindowHandle, Me.Handle, -LEFT_CONST,
-TOP_CONST, Me.Width + LEFT_CONST + RIGHT_CONST,
Me.Height + TOP_CONST + BOTTOM_CONST,
win32.SWP_FRAMECHANGED Or win32.SWP_NOZORDER)
Note: I have tested with standard calculator. If you want to show scientific calc, adjust the size of
ExternalCalc
form. You may also use
SendKeys
to show the calc in any form. Error checking in all scenarios has not been done on the demos.
Points of Interest
It's very easy way to add applications in your .NET based application. Thanks to Microsoft for making such things :)
Revision History
12-29-2004:
- Added a Picture with calc and IE Control and their interaction.
- Added the source code for calc and IE demo.
11-29-2004: