Using System;
Using System. Collections. Generic;
Using System. ComponentModel;
Using System. Drawing;
Using System. Data;
Using System. Text;
Using System. Windows. Forms;
Using System. Diagnostics;
Using System. Runtime. InteropServices;
Using System. IO;
Using System. Drawing. Design;
Namespace HCDL
{
Public class ShowForm
{
//-------------------
// Action <object, EventArgs> appIdleAction = null;
EventHandler appIdleEvent = null;
Control ParentCon = null;
String strGUID = "";
Public ShowForm (Control C, string Titlestr)
{
AppIdleEvent = new EventHandler (Application_Idle );
ParentCon = C;
StrGUID = Titlestr;
}
/// <Summary>
/// Open and embed the application to which the property <code> AppFilename </code> directs
/// </Summary>
Public IntPtr Start (string FileNameStr)
{
If (m_AppProcess! = Null)
{
Stop ();
}
Try
{
ProcessStartInfo info = new ProcessStartInfo (FileNameStr );
Info. UseShellExecute = true;
Info. WindowStyle = ProcessWindowStyle. Minimized;
M_AppProcess = System. Diagnostics. Process. Start (info );
M_AppProcess.WaitForInputIdle ();
Application. Idle + = appIdleEvent;
}
Catch
{
If (m_AppProcess! = Null)
{
If (! M_AppProcess.HasExited)
M_AppProcess.Kill ();
M_AppProcess = null;
}
}
Return m_AppProcess.Handle;
}
/// <Summary>
/// Ensure that the application is embedded in this container
/// </Summary>
/// <Param name = "sender"> </param>
/// <Param name = "e"> </param>
Void Application_Idle (object sender, EventArgs e)
{
If (this. m_AppProcess = null | this. m_AppProcess.HasExited)
{
This. m_AppProcess = null;
Application. Idle-= appIdleEvent;
Return;
}
If (m_appprocess.main?whandle = IntPtr. Zero) return;
Application. Idle-= appIdleEvent;
EmbedProcess (m_AppProcess, ParentCon );
}
/// <Summary>
/// Clear the identifier here when the application ends running
/// </Summary>
/// <Param name = "sender"> </param>
/// <Param name = "e"> </param>
Void m_AppProcess_Exited (object sender, EventArgs e)
{
M_AppProcess = null;
}
/// <Summary>
/// Close the application to which the property <code> AppFilename </code> points
/// </Summary>
Public void Stop ()
{
If (m_AppProcess! = Null) // & m_appprocess.main?whandle! = IntPtr. Zero)
{
Try
{
If (! M_AppProcess.HasExited)
M_AppProcess.Kill ();
}
Catch (Exception)
{
}
M_AppProcess = null;
}
}
# Region attributes
/// <Summary>
/// Application process
/// </Summary>
Process m_AppProcess = null;
/// <Summary>
/// Identify whether the embedded program has been started
/// </Summary>
Public bool IsStarted {get {return (this. m_AppProcess! = Null );}}
# Endregion attributes
# Region Win32 API
[DllImport ("user32.dll", EntryPoint = "GetWindowThreadProcessId", SetLastError = true,
CharSet = CharSet. Unicode, ExactSpelling = true,
CallingConvention = CallingConvention. StdCall)]
Private static extern long GetWindowThreadProcessId (long hWnd, long lpdwProcessId );
[DllImport ("user32.dll", SetLastError = true)]
Private static extern IntPtr FindWindow (string lpClassName, string lpWindowName );
[DllImport ("user32.dll", SetLastError = true)]
Private static extern long SetParent (IntPtr hWndChild, IntPtr hWndNewParent );
[DllImport ("user32.dll", EntryPoint = "GetWindowLongA", SetLastError = true)]
Private static extern long GetWindowLong (IntPtr hwnd, int nIndex );
Public static IntPtr SetWindowLong (HandleRef hWnd, int nIndex, int dwNewLong)
{
If (IntPtr. Size = 4)
{
Return SetWindowLongPtr32 (hWnd, nIndex, dwNewLong );
}
Return SetWindowLongPtr64 (hWnd, nIndex, dwNewLong );
}
[DllImport ("user32.dll", EntryPoint = "SetWindowLong", CharSet = CharSet. Auto)]
Public static extern IntPtr SetWindowLongPtr32 (HandleRef hWnd, int nIndex, int dwNewLong );
[DllImport ("user32.dll", EntryPoint = "SetWindowLongPtr", CharSet = CharSet. Auto)]
Public static extern IntPtr SetWindowLongPtr64 (HandleRef hWnd, int nIndex, int dwNewLong );
[DllImport ("user32.dll", SetLastError = true)]
Private static extern long SetWindowPos (IntPtr hwnd, long hWndInsertAfter, long x, long y, long cx, long cy, long wFlags );
[DllImport ("user32.dll", SetLastError = true)]
Private static extern bool MoveWindow (IntPtr hwnd, int x, int y, int cx, int cy, bool repaint );
[DllImport ("user32.dll", EntryPoint = "PostMessageA", SetLastError = true)]
Private static extern bool PostMessage (IntPtr hwnd, uint Msg, uint wParam, uint lParam );
[DllImport ("user32.dll", SetLastError = true)]
Private static extern IntPtr GetParent (IntPtr hwnd );
[DllImport ("user32.dll", EntryPoint = "ShowWindow", SetLastError = true)]
Static extern bool ShowWindow (IntPtr hWnd, int nCmdShow );
Private const int SWP_NOOWNERZORDER = 0x200;
Private const int SWP_NOREDRAW = 0x8;
Private const int SWP_NOZORDER = 0x4;
Private const int SWP_SHOWWINDOW = 0x0040;
Private const int WS_EX_MDICHILD = 0x40;
Private const int SWP_FRAMECHANGED = 0x20;
Private const int SWP_NOACTIVATE = 0x10;
Private const int SWP_ASYNCWINDOWPOS = 0x4000;
Private const int SWP_NOMOVE = 0x2;
Private const int SWP_NOSIZE = 0x1;
Private const int GWL_STYLE = (-16 );
Private const int WS_VISIBLE = 0x10000000;
Private const int WM_CLOSE = 0x10;
Private const int WS_CHILD = 0x40000000;
Private const int SW_HIDE = 0; // {hide, and the taskbar is not minimized}
Private const int SW_SHOWNORMAL = 1; // {display with the nearest size and position, activate}
Private const int SW_NORMAL = 1; // {same as SW_SHOWNORMAL}
Private const int SW_SHOWMINIMIZED = 2; // {minimize, activate}
Private const int SW_SHOWMAXIMIZED = 3; // {maximize, activate}
Private const int SW_MAXIMIZE = 3; // {same as SW_SHOWMAXIMIZED}
Private const int SW_SHOWNOACTIVATE = 4; // {display with the nearest size and position, not activated}
Private const int SW_SHOW = 5; // {same as SW_SHOWNORMAL}
Private const int SW_MINIMIZE = 6; // {minimized, not activated}
Private const int SW_SHOWMINNOACTIVE = 7; // {same as SW_MINIMIZE}
Private const int SW_SHOWNA = 8; // {same as SW_SHOWNOACTIVATE}
Private const int SW_RESTORE = 9; // {same as SW_SHOWNORMAL}
Private const int SW_SHOWDEFAULT = 10; // {same as SW_SHOWNORMAL}
Private const int SW_MAX = 10; // {same as SW_SHOWNORMAL}
# Endregion Win32 API
/// <Summary>
/// Embed the specified program into the specified control
/// </Summary>
Private void EmbedProcess (Process app, Control control)
{
// Get the main handle
If (app = null | app. main1_whandle = IntPtr. Zero | control = null) return;
Try
{
// Put it into this form
SetParent (app. maindomainwhandle, control. Handle );
}
Catch (Exception)
{}
Try
{
// Remove border and whatnot
SetWindowLong (new HandleRef (this, app. MainWindowHandle), GWL_STYLE, WS_VISIBLE );
SendMessage (app. main1_whandle, WM_SETTEXT, IntPtr. Zero, strGUID );
}
Catch (Exception)
{}
Try
{
// Move the window to overlay it on this window
MoveWindow (app. main1_whandle,-20,-20, control. Width, control. Height-10, true );
}
Catch (Exception)
{}
}
[DllImport ("User32.dll", EntryPoint = "SendMessage")]
Private static extern int SendMessage (IntPtr hWnd, int Msg, IntPtr wParam, string lParam );
Const int WM_SETTEXT = 0x000C;
}
}
Usage
C # code?
12 |
ShowForm Sf = new ShowForm( this , "For internal use only" + System.Guid.NewGuid().ToString()); ProxHandle= Sf.Start(Application.StartupPath + "\\ProxyThorn.exe" ); |
/// <summary>
/// Ensure that the application is embedded in this container
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void
Application_Idle(
object
sender, EventArgs e)
{
if
(
this
.m_AppProcess ==
null
||
this
.m_AppProcess.HasExited)
{
this
.m_AppProcess =
null
;
Application.Idle -= appIdleEvent;
return
;
}
while
(m_AppProcess.MainWindowHandle == IntPtr.Zero)
{
Thread.Sleep(100);
m_AppProcess.Refresh();
}
Application.Idle -= appIdleEvent;
EmbedProcess(m_AppProcess, ParentCon);
}
Latency between some software-triggered events
Change the above method
MoveWindow (app. main1_whandle,-20,-20, control. Width, control. Height-10, true );