如果要將功能建立在別人主程式中,
除了將功能程式碼建立在對方程式碼內,
還可以使用以下這種將功能外掛的方式來達成目標
以下提供簡單範例
外部主程式
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;
namespace UI_Reflash
{
public partial class Form1 : Form
{
/* 參數初始化 */
public Process exe = null;
public IntPtr MWH = IntPtr.Zero; /* exe hwnd number */
public Form1()
{
InitializeComponent();
}
/* 按鈕觸發啟動 */
private void button1_Click(object sender, EventArgs e)
{
/* 按鈕功能觸發MessageBox */
MessageBox.Show("UI合併觸發成功");
}
private void Form1_Load(object sender, EventArgs e)
{
/* 隱藏UI */
Hide();
/* 執行主要框架的程式 */
RunMainWindows();
/* 獲得需連結的hwnd物件 */
IntPtr mainHandle = UI.find_windows_use_process_name("ICOS_Simuation.exe");//主程式名稱
if(mainHandle != IntPtr.Zero)
{
/* 獲得連結物件的hwnd */
int mainHandle_ID_List = UI.find_Process_PID_use_process_name("ICOS_Simuation.exe");
/* 設定視窗格式 */
/* Form Border Style = 設定為 None */
FormBorderStyle = FormBorderStyle.None;
/* 設定按鈕顯示位置與大小 */
SetBounds(0,110,40,40, BoundsSpecified.Location);
/* 刷新UI介面 */
Thread CT = new Thread(() =>
{
this.Invoke((MethodInvoker)delegate
{
/* Set_UI_Interface(本體UI hwnd , 連結物件UI hwnd) */
UI.Set_UI_Interface(this.Handle, mainHandle);
Show(); //刷新顯示原本隱藏的視窗
});
MWH = mainHandle;
Thread.Sleep(100);
GC.Collect(); //強迫釋放資源
});
CT.Start();
}
}
/* 使用process的方式 Run 主程式 ,並獲取需連結物件whnd */
public void RunMainWindows()
{
System.Diagnostics.ProcessStartInfo Info = new System.Diagnostics.ProcessStartInfo();
Info.FileName = @".ICOS_Simuation.exe"; //主程式檔名
//Info.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; // 隱藏視窗
exe = Process.Start(Info);
MWH = exe.MainWindowHandle;
Thread.Sleep(200);
}
}
}
UI.cs 檔案
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
/* point use */
using System.Drawing;
/* use Dll & ini */
using System.Runtime.InteropServices;
using System.Reflection;
using System.Management;
using System.IO;
using System.Diagnostics;
using System.Threading;
/* Array list */
using System.Collections;
using System.Threading;
namespace UI_Reflash
{
class UI
{
/* 重設UI介面參數使用 */
public static int GWL_STYLE = -16;
public static int WS_CHILD = 0x40000000;
/* 使用執行程式名稱尋找視窗物件 EX: process name = Mmi.exe*/
public static IntPtr find_windows_use_process_name(string process_name)
{
Dictionary<int, Handler> getHandler = GetHandler();
IntPtr hwnd = IntPtr.Zero;
foreach (var p in getHandler)
{
String name = getHandler[p.Key].xInfo.Name;
if (name == process_name)
{
hwnd = getHandler[p.Key].hwnd;
}
}
return hwnd;
}
/* 使用執行程式名稱尋找視窗物件 EX: process name = Mmi.exe return PID */
public static int find_Process_PID_use_process_name(string process_name)
{
Dictionary<int, Handler> getHandler = GetHandler();
int pid_number = -1;
foreach (var p in getHandler)
{
String name = getHandler[p.Key].xInfo.Name;
if (name == process_name)
{
pid_number = getHandler[p.Key].id.Id;
}
}
return pid_number;
}
/// <summary>
/// 列出目前全部使用中程式的 Handler 資訊
/// </summary>
public static Dictionary<int, Handler> GetHandler()
{
Dictionary<int, Handler> dic = new Dictionary<int, Handler>();
foreach (Process proc in Process.GetProcesses())
{
try
{
Handler tm = new Handler();
tm.id = proc;
tm.hwnd = proc.MainWindowHandle;
tm.xInfo = new FileInfo(proc.MainModule.FileName);
if (!dic.ContainsKey(proc.Id)) dic.Add(proc.Id, tm);
}
catch { }
}
return dic;
}
/* IntPtr guestHandle -> 要嵌入的元件 */
/* IntPtr hostHandle -> 被嵌入的主程式 */
public static void Set_UI_Interface(IntPtr guestHandle, IntPtr hostHandle)
{
//調用windows·Api SetWindowLong 強制修改mdi的窗口屬性。
Win32APi.SetWindowLong(guestHandle, GWL_STYLE, Win32APi.GetWindowLong(guestHandle, GWL_STYLE) | WS_CHILD);
Win32APi.SetParent(guestHandle, hostHandle); //窗體崁入
}
}
}