書小宅之C#——實現的第三方程序嵌入自己的WinForm

首先創建一個C#的窗體應用(.net框架):
在這裏插入圖片描述
在左側隱藏的工具箱中可以添加控件,對自己的窗體做初步的佈局。

這裏記錄我在做項目的過程中遇到的兩個較嚴重的問題:
問題1:用重疊的Panel實現界面切換,本來可以簡單地靠Panel.BringToFront()或Panel.Visible=true和Panel.Visible=false配合着來實現,但是因爲自己在窗體設計界面手動調整Panel的大小,導致控件層級不同,達不到自己想要的效果。
解決方法:首先在.Designer.cs中找到對應的控件,將其size和location屬性設置到相同的合適值,在左側隱藏的文檔大綱中,將這幾個重疊的控件拖拽到相同的層級。

問題2:“System.Runtime.InteropServices.COMException”
解決方法:解決方案:無法啓動服務,原因可能是已被禁用或與其相關聯的設備沒有啓動。
(1)在開始–》運行中輸入services.msc
(2)找到Windows Management Instrumentation服務
(3)鼠標右鍵打開屬性,選擇啓動類型爲【自動】,並開啓服務即可#

啓動第三方程序

方法1:

string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase);         
//string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
//string path = (Directory.GetCurrentDirectory() + "\\stats.exe");////獲得當前的目錄至debug
//string path_project = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;

Process process=new Process();
process.StartInfo.FileName = path;//明確路徑
process.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;//加上這句效果更好
process.StartInfo.UseShellExecute = true;
process.StartInfo.Arguments = null;
process.Start();

process.WaitForExit();//等待Excel退出後才能執行以後的步驟

Process.Kill();//程序結束時

方法2:

this.BeginInvoke(new Action(() => System.Diagnostics.Process.Start(path)));

方法3:

System.Diagnostics.Process.Start(path);

方法4:利用反射來啓動程序:

Type Excel = Type.GetTypeFromProgID("Excel.Application");//獲取Excel.Application的類型
ExcelObject = Activator.CreateInstance(Excel);//創建spss.Application的類型的實例
parameter[0] = true;//使用反射動態調用類成員
 // public object InvokeMember(string, BindingFlags, Binder, object, object[]);
Excel.InvokeMember("Visible", BindingFlags.Static | BindingFlags.SetProperty | BindingFlags.Public, null, ExcelObject, parameter);//執行spss.Application的類型的Visible的方法。
System.Runtime.InteropServices.Marshal.ReleaseComObject(spssObject);
GC.Collect();

如果想用COM方式來調用excel程序

添加的引用如:
在這裏插入圖片描述
在這裏插入圖片描述
在Form中添加WebBrowser控件。(對象名卻省是axWebBrowser1)

using Excel = Microsoft.Office.Interop.Excel;
using System.Reflection;
 //產生一個Excel.Application的新進程
Excel.Application app = new Excel.Application();
if (app == null)
{
	progressBar1.Text = "ERROR: EXCEL couldn't be started!";
    return;
}
app.Visible = true; //如果只想用程序控制該excel而不想讓用戶操作時候,可以設置爲false
app.UserControl = true;
Workbooks workbooks = app.Workbooks;
_Workbook workbook = workbooks.Add(XlWBATemplate.xlWBATWorksheet); //根據模板產生新的workbook,或者Add裏面加入絕對路徑
Sheets sheets = workbook.Worksheets;
_Worksheet worksheet = (_Worksheet)sheets.get_Item(1);
if (worksheet == null)
{
	progressBar1.Text = "ERROR: worksheet == null";
    return;
}

// This paragraph puts the value 5 to the cell G1
Range range1 = worksheet.get_Range("A1", Missing.Value);
if (range1 == null)
{
    progressBar1.Text = "ERROR: range == null";
    return;
}
const int nCells = 2345;
range1.Value2 = nCells;

/*
* 用WebBrowser“裝載”Excel"表,實際上仍然是在新的進程空間中運行Excel.exe
* WebBrowser控件不支持菜單合併,也就是說無法把Excel表的菜單帶入到我們的程序中
* 幸好提供了可以把工具欄添加進來的功能,通過工具欄可以進行許多Excel專有的操作。
* 可以通過WebBrowser的方法NavigateComplete提供的事件參數e來訪問Excel.Application。
*/
string strFileName = @"c:/a.xls";
Object refmissing = System.Reflection.Missing.Value;
Excel_webBrowser.Navigate(strFileName, ref refmissing, ref refmissing, ref refmissing, ref refmissing);
//下面這句可以將excel本身的工具調添加進來
Excel_webBrowser.ExecWB(SHDocVw.OLECMDID.OLECMDID_HIDETOOLBARS, SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DONTPROMPTUSER, ref refmissing, ref refmissing);

/*
* 首先需要明白,用WebBrowser“裝載”Excel"表,實際上仍然是在新的進程空間中運行Excel.exe。
* 可以用任務管理器觀察。因此,只要我們能夠獲取Excel.Application對象,就能像上文一中所說的那樣操作Excel數據。
* 幸好可以通過WebBrowser的方法NavigateComplete提供的事件參數e來訪問Excel.Application。 
*/

public void axWebBrowser1_NavigateComplete2(object sender, AxSHDocVw.DWebBrowserEvents2_NavigateComplete2Event e)
{
     Object o = e.pDisp;
     Object oDocument = o.GetType().InvokeMember("Document", BindingFlags.GetProperty, null, o, null);
      Object oApplication = o.GetType().InvokeMember("Application", BindingFlags.GetProperty, null, oDocument, null);
      //Object oName = o.GetType().InvokeMember("Name",BindingFlags.GetProperty ,null,oApplication,null); 
      //由於打開的是excel文件,所以這裏的oApplication 其實就是Excel.Application
      Excel.Application eApp = (Excel.Application)oApplication;//這樣就可以象上文中所述來操作Excel了。
}

/*
* 包含該webbrowser的form退出時候,如何確保excel進程也退出?(參見microsoft幫助中心kb317109)
* 由於WebBrowser只不過是對Excel表的瀏覽,而Excel在單獨的進程中運行。
* 所以要保證對該Excel對象eApp及其相應的所有成員變量都釋放引用,才能保證在Form退出時excel進程跟着退出。
* 這一點在一個程序需要多次打開關閉excel表時尤爲重要。 
*/
Excel.Application oApp;
Excel.Workbooks oBooks;
Excel.Workbook oBook;
Excel.Worksheet oSheet;

private void ExcelExit()
{
     NAR(oSheet);
     oBook.Close(False);
     NAR(oBook);
     NAR(oBooks);
     oApp.Quit();
     NAR(oApp);
     
     Debug.WriteLine("Sleeping...");
     System.Threading.Thread.Sleep(5000);
     Debug.WriteLine("End Excel");
}
private void NAR(Object o)
{
	try { System.Runtime.InteropServices.Marshal.ReleaseComObject(o); }
    catch { }
    finally { o = null; }
}

/*
* 經過試驗,我發現除了釋放這些變量以外,必須把該axWebBroswer1也銷燬掉,Excel進程才退出。
* 否則的話,即使讓axWebBroser1去Navigate空內容"about:blank", excel進程仍然不會退出。
* 因此應該將axWebBroser1所在的Form關閉掉,或者直接調用axWebBrowser1.Dispose();
* 如果還是其它問題導致不能正常退出,就只有調用垃圾回收了。
*/
GC.Collect();

有關桌面快捷方式的操作

一、在項目中添加“Windows Script Host Object Model”的引用
在項目上單擊右鍵,選擇“添加引用”,在“添加引用”對話框中選擇“COM”組件選項卡,然後單擊選擇“Windows Script Host Object Model”,最後確定。在項目中就會出現“IWshRuntimeLibrary”,下面就可以編寫代碼了。

 //需要引入IWshRuntimeLibrary,搜索Windows Script Host Object Model

        /// <summary>
        /// 創建快捷方式
        /// </summary>
        /// <param name="directory">快捷方式所處的文件夾</param>
        /// <param name="shortcutName">快捷方式名稱</param>
        /// <param name="targetPath">目標路徑</param>
        /// <param name="description">描述</param>
        /// <param name="iconLocation">圖標路徑,格式爲"可執行文件或DLL路徑, 圖標編號",
        /// 例如System.Environment.SystemDirectory + "\\" + "shell32.dll, 165"</param>
        /// <remarks></remarks>
        public static void CreateShortcut(string directory, string shortcutName, string targetPath,string description = null, string iconLocation = null)
        {
            if (!System.IO.Directory.Exists(directory))
            {
                System.IO.Directory.CreateDirectory(directory);
            }

            string shortcutPath = Path.Combine(directory, string.Format("{0}.lnk", shortcutName));
            WshShell shell = new WshShell();
            IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(shortcutPath);//創建快捷方式對象
            Console.WriteLine("要創建的快捷方式地址:" + shortcutPath);

            shortcut.TargetPath = targetPath;//指定目標路徑
            shortcut.WorkingDirectory = Path.GetDirectoryName(targetPath);//設置起始位置
            Console.WriteLine("TargetPath:" + shortcut.TargetPath);
            Console.WriteLine("WorkingDirectory:" + shortcut.WorkingDirectory);
            //shortcut.Arguments = shortcut.WorkingDirectory;
            shortcut.WindowStyle = 1;//設置運行方式,默認爲常規窗口
            shortcut.Description = description;//靠近時的備註
            shortcut.Hotkey = "CTRL+SHIFT+E";//全局熱鍵
            shortcut.IconLocation = string.IsNullOrWhiteSpace(iconLocation) ? targetPath : iconLocation;//設置圖標路徑
            shortcut.Save();//保存快捷方式
        }

        public static void CreateShortcutOnDesktop(string shortcutName, string targetPath,string description = null, string iconLocation = null)
        {
            string desktop = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);//獲取桌面文件夾路徑
            CreateShortcut(desktop, shortcutName, targetPath, description, iconLocation);
        }
        public static string getShortCutPath(string path)
        {
            //獲取當前桌面的路徑
            string dir = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
            //string strDesktopPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory),"xx.lnk");

            string filePath = "";
            filePath = dir + path;
            Console.WriteLine("要查找的快捷方式地址:" + filePath);

            if (System.IO.File.Exists(filePath))
            {
                //聲明操作對象
                IWshRuntimeLibrary.WshShell shell = new IWshRuntimeLibrary.WshShell();
                //創建快捷方式
                IWshRuntimeLibrary.IWshShortcut quickPath = (IWshRuntimeLibrary.IWshShortcut)shell.CreateShortcut(filePath);


                //快捷方式文件指向的路徑:TargetPath;
                //快捷方式文件指向的目標目錄:WorkingDirectory;
                Console.WriteLine("目標地址:" + quickPath.WorkingDirectory);
                return quickPath.WorkingDirectory;
            }
            else
            {
                return "";
            }
        }

判斷某一路徑下的文件是否存在

if (!File.Exists(path))
{
		MessageBox.Show("文件不存在!");
}

窗體句柄

非.NET程序,一旦程序被生成,控件ID就是固定的,但在.NET程序中控件ID是動態變化的,所以想考ID號來找到對應的窗口是不現實的。

使用spy++工具,可以方便地找到每一個窗口對應的窗體信息,如“名稱”、“類”、“句柄”等。
在開發過程中遇到一個很大的坑,一開始對這些概念不是很清楚,瘋狂想通過直接調用Win32 API來獲取窗體和窗體子控件的句柄,從而進行操作。
查閱資料有說法說一些窗體是畫出來的,沒用標準的菜單欄和按鈕等,這些空間找不到句柄,自然FindWindEx函數也就不管用了,不管怎麼遍歷都無法得到子控件的句柄,在此衷心提示在想要找句柄時,不妨先用spy++,看看你想要的句柄是否存在。

首先對對API函數實行託管:

using System.Runtime.InteropServices;
[DllImport("User32.dll", EntryPoint = "SendMessage")]
public static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);

[DllImport("user32.dll")]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

[DllImport("user32.dll")]
public static extern int GetWindowLong(IntPtr hWnd, int nIndex);

[DllImport("user32.dll")]
public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

[DllImport("user32.dll", CharSet = CharSet.Auto)]
public extern static IntPtr SetParent(IntPtr hChild, IntPtr hParent);

[DllImport("user32.dll")]
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndlnsertAfter, int X, int Y, int cx, int cy, uint Flags);

[DllImport("user32.dll", EntryPoint = "ShowWindow")]
public static extern int ShowWindow(IntPtr hwnd, int nCmdShow);

[DllImport("user32.dll", SetLastError = true)]
public static extern bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint);

//當一個窗口或應用程序要關閉時發送一個信號   
public const int WM_CLOSE = 0x10;
//按下某鍵,並已發出WM_KEYDOWN, WM_KEYUP消息   
const int WM_CHAR = 0x102;
//得到窗口風格
public static int GWL_STYLE = -16;
public static int WS_THICKFRAME = 262144;
public static int WS_BORDER = 8388608;
public static int SW_SHOWNORMAL = 1;
public static int SW_RESTORE = 9;
public static int SW_SHOWNOACTIVATE = 4;
IntPtr Wnd=new IntPtr(0);
do
{
	try
    {
    	Thread.Sleep(100);
        Wnd = FindWindow(null, "工作簿1 - Excel");
    }
    catch (Exception ex)
    {
         System.GC.Collect();
    }
} while (Wnd == IntPtr.Zero);

//在panel上顯示句柄
Int32 wndStyle = GetWindowLong(Wnd, GWL_STYLE);
wndStyle &= ~WS_BORDER;
wndStyle &= ~WS_THICKFRAME;
SetWindowLong(Wnd, GWL_STYLE, wndStyle);
SetParent(Wnd, this.Panel1.Handle);
SetWindowPos(Wnd, new IntPtr(0), 0, 0, this.Panel1.Width, this.Panel1, 1);
//ShowWindow(Wnd, SW_RESTORE);
ShowWindow(Wnd, (int)ProcessWindowStyle.Maximized);

//關閉窗口
SendMessage(Wnd, WM_CLOSE, 0, 0);
//獲取測試程序的窗體句柄
IntPtr mainWnd = FindWindow(null, "EXCEL");//返回0
List<IntPtr> listWnd = new List<IntPtr>();
//獲取窗體上OK按鈕的句柄 
IntPtr hwnd_button = FindWindowEx(mainWnd, new IntPtr(0), null, "OK");
//獲取窗體上所有控件的句柄
//EnumChildWindows可以枚舉一個父窗口的所有子窗口:
EnumChildWindows(mainWnd, new CallBack(delegate (IntPtr hwnd, int lParam)
{
	listWnd.Add(hwnd);
	return true;
}), 0);
foreach (IntPtr item in listWnd)
{
	if (item != hwnd_button)
    {
    	char[] UserChar = "luminji".ToCharArray();
        foreach (char ch in UserChar)
        {
        	SendChar(item, ch, 100);
        }
    }
}
SendMessage(hwnd_button, WM_CLICK, mainWnd, "0");
public void SendChar(IntPtr hand, char ch, int SleepTime)
{
	PostMessage(hand, WM_CHAR, ch, 0);//在文本輸入的控件上寫入內容
	System.Threading.Thread.Sleep(SleepTime);
}
/// <summary>
        /// 查找窗體上控件句柄
        /// </summary>
        /// <param name="hwnd">父窗體句柄</param>
        /// <param name="lpszWindow">控件標題(Text)</param>
        /// <param name="bChild">設定是否在子窗體中查找</param>
        /// <returns>控件句柄,沒找到返回IntPtr.Zero</returns>
        private IntPtr FindWindowEx(IntPtr hwnd, string lpszWindow, string classWindow, bool bChild)
        {
            IntPtr iResult = IntPtr.Zero;
            // 首先在父窗體上查找控件
            iResult = OperateHandle.FindWindowEx(hwnd, 0, classWindow, lpszWindow);
            // 如果找到直接返回控件句柄
            if (iResult != IntPtr.Zero) return iResult;

            // 如果設定了不在子窗體中查找
            if (!bChild) return iResult;

            // 枚舉子窗體,查找控件句柄
            int i = OperateHandle.EnumChildWindows(
            hwnd,
            (h, l) =>
            {
                Console.WriteLine("找幾次");
                IntPtr f1 = OperateHandle.FindWindowEx(h, 0, classWindow, lpszWindow);
                if (f1 == IntPtr.Zero)
                    return true;
                else
                {
                    iResult = f1;
                    return false;
                }
            },
            0);
            // 返回查找結果
            return iResult;
        }
private void excelShow_panel_SizeChanged(object sender, EventArgs e)
{
     if (this.Process == null)
     {
          return;
     }
     if (this.Process.MainWindowHandle != IntPtr.Zero)
     {
      	MoveWindow(this.Process.MainWindowHandle, 0, 0, this.Panel.Width, this.Panel.Height, true);
     }
}

另一種Excel嵌入的方法

using Office = Microsoft.Office.Core;
using Excel = Microsoft.Office.Interop.Excel;
//聲明變量
		Office.CommandBarButton oButton;
	 	Office.CommandBarComboBox oEdit;
		Office.CommandBarComboBox oDrop;
		Office.CommandBarComboBox oCombo;
		Office.CommandBarButton oPopupButton;

		Excel.Application oExcel;
		Office.CommandBar oCommandBar;
		Office.CommandBarPopup oPopup;
		Object oMissing = System.Reflection.Missing.Value;

		// Start Excel.
		oExcel = new Excel.Application();
		// Show Excel and set UserControl
		//oExcel.Width = this.Width;
		//oExcel.Height = this.Height;
		//oExcel.Left = this.Left;
		//oExcel.Top = this.Top;

		oExcel.Visible = true;
		oExcel.UserControl = true;
            
		// Add a new workbook
		oExcel.Workbooks.Add(oMissing);

		// Create a new command bar.
		oCommandBar = oExcel.CommandBars.Add("Billiards Sample", oMissing, oMissing);

		// Add a button to the command bar.
		oButton = (Office.CommandBarButton)oCommandBar.Controls.Add(
		Office.MsoControlType.msoControlButton, oMissing, oMissing, oMissing, oMissing);

		// Set the caption and face ID.
		oButton.Caption = "New game";
		oButton.FaceId = 1845;
	// Set up a delegate for the Click event.
		Office._CommandBarButtonEvents_ClickEventHandler oButtonHandler =new Office._CommandBarButtonEvents_ClickEventHandler(oButton_Click);
		oButton.Click += oButtonHandler;

		// Add an edit box to the command bar.
		oEdit = (Office.CommandBarComboBox)oCommandBar.Controls.Add(
		Office.MsoControlType.msoControlEdit, oMissing, oMissing, oMissing, oMissing);
		// Show a vertical separator.
		oEdit.BeginGroup = true;
		// Clear the text and show a caption.
    	oEdit.Text = "";
    	oEdit.Caption = "Enter your name:";
    	oEdit.Style = Office.MsoComboStyle.msoComboLabel;
    	// Set up a delegate for the Change event.
    	Office._CommandBarComboBoxEvents_ChangeEventHandler oEditHandler = new Office._CommandBarComboBoxEvents_ChangeEventHandler(oEdit_Change);
    	oEdit.Change += oEditHandler;

    	// Add a combo box to the command bar.
     	oCombo = (Office.CommandBarComboBox)oCommandBar.Controls.Add(
     	Office.MsoControlType.msoControlComboBox, oMissing, oMissing, oMissing, oMissing);
            // Add items to the combo box.
            oCombo.AddItem("Sharky", oMissing);
            oCombo.AddItem("Cash", oMissing);
            oCombo.AddItem("Lucky", oMissing);
            // Set the caption and style.
            oCombo.Caption = "Choose your opponent:";
            oCombo.Style = Office.MsoComboStyle.msoComboLabel;
            // Set up a delegate for the Change event.

            Office._CommandBarComboBoxEvents_ChangeEventHandler oComboHandler =
                    new Office._CommandBarComboBoxEvents_ChangeEventHandler(oCombo_Change);
            oCombo.Change += oComboHandler;

            // Add a drop-down list box to the command bar.
            oDrop = (Office.CommandBarComboBox)oCommandBar.Controls.Add(
                    Office.MsoControlType.msoControlDropdown, oMissing, oMissing, oMissing, oMissing);
            // Add items to the list box.
            oDrop.AddItem("8 Ball", oMissing);
            oDrop.AddItem("9 Ball", oMissing);
            oDrop.AddItem("Straight Pool", oMissing);
            oDrop.AddItem("Bowlliards", oMissing);
            oDrop.AddItem("Snooker", oMissing);
            // Set the value to the first in the list.
            oDrop.ListIndex = 1;
            // Set the caption and style.
            oDrop.Caption = "Choose your game:";
            oDrop.Style = Office.MsoComboStyle.msoComboLabel;
            // Set up a delegate for the Change event.
            Office._CommandBarComboBoxEvents_ChangeEventHandler oDropHandler =
                    new Office._CommandBarComboBoxEvents_ChangeEventHandler(oDrop_Change);
            oDrop.Change += oDropHandler;

            // Add a pop-up menu to the command bar.
            oPopup = (Office.CommandBarPopup)oCommandBar.Controls.Add(
                    Office.MsoControlType.msoControlPopup, oMissing, oMissing, oMissing, oMissing);
            // Add a separator before the pop-up button.
            oPopup.BeginGroup = true;
            // Set the caption.
            oPopup.Caption = "Rack 'em Up!";
            // Add a button to the pop-up.
            oPopupButton = (Office.CommandBarButton)oPopup.CommandBar.Controls.Add(
                    Office.MsoControlType.msoControlButton, oMissing, oMissing, oMissing, oMissing);
            // Change the face ID and caption for the button.
            oPopupButton.FaceId = 643;
            oPopupButton.Caption = "Break!";
            // Set up a delegate for the Click event.
            Office._CommandBarButtonEvents_ClickEventHandler oPopupButtonHandler =
                    new Office._CommandBarButtonEvents_ClickEventHandler(oPopupButton_Click);
            oPopupButton.Click += oPopupButtonHandler;

            // Show the command bar to the user.
            oCommandBar.Visible = true;
        }
        private void oButton_Click(Office.CommandBarButton Ctrl, ref bool Cancel)
        {
            // Reset all values.
            oEdit.Text = "";
            oDrop.ListIndex = 1;
            oCombo.Text = "";
            Console.WriteLine("New game button clicked");
        }

        private void oEdit_Change(Office.CommandBarComboBox Ctrl)
        {
            Console.WriteLine("oEdit_Change event fired -- Player's name = " + Ctrl.Text);
        }

        private void oCombo_Change(Office.CommandBarComboBox Ctrl)
        {
            Console.WriteLine("oCombo_Change event fired -- New opponent = " + Ctrl.Text);
        }

        private void oDrop_Change(Office.CommandBarComboBox Ctrl)
        {
            Console.WriteLine("oDrop_Change event fired -- Game type = " + Ctrl.Text);
        }

        private void oPopupButton_Click(Office.CommandBarButton Ctrl, ref bool Cancel)
        {
            System.Random oRand;

            Console.WriteLine("oPopupButton_Click event fired");
            // Create a new random number class.
            oRand = new System.Random();
            String sWinner;
            // Get a random number and check its range.
            if (oRand.NextDouble() > 0.5)
                sWinner = oEdit.Text;
            else
                sWinner = oCombo.Text;
            // Show a message box to the user.
            MessageBox.Show("Game: " + oDrop.Text + "\r\n\r\nName: " + oEdit.Text +
                "\r\nOpponent: " + oCombo.Text + "\r\n\r\nWinner: " + sWinner, "Game Results");
        }

控件的Location.X、Location.Y、Left、Top是相對於控件的父控件而言的

句柄

//使用方法
        //控件函數.窗口拖動(this.button1,this);
        //控件函數.控件拖動(this.button2);
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, uint wParam, uint lParam);
        [DllImport("user32.dll")]
        private static extern IntPtr WindowFromPoint(Point p);   //根據座標點獲取句柄
        [DllImport("user32.dll")]
        private static extern int GetWindowText(IntPtr hwnd, StringBuilder lpString, int nMaxCount);  //獲取窗口標題
        [DllImport("user32.dll")]
        private static extern void GetClassName(IntPtr hwnd, StringBuilder s, int nMaxCount);   //獲取句柄類名
        [DllImport("user32.dll")]
        private static extern IntPtr GetParent(IntPtr hwnd);   //獲取句柄父句柄
        [DllImport("user32.dll")]
        private static extern IntPtr SetParent(IntPtr hwnd, IntPtr cwnd);  //設置父句柄
        [DllImport("user32.dll")]
        private static extern bool GetWindowRect(IntPtr hwnd, ref RECT lpRECT);   //獲取句柄矩形位置信息

        [StructLayout(LayoutKind.Sequential)]
        public struct handleInfoStructor
        {
            public Rectangle location;
            public string showPassw;
            public string className;
            public List<IntPtr> fatherFormHandle;
            public List<string> fatherFormTitle;
            public List<string> fatherFormClassName;
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
        }
        public static handleInfoStructor getHandleInfo(IntPtr hd)
        {
            handleInfoStructor xinxi = new handleInfoStructor();
            xinxi.fatherFormHandle = new List<IntPtr>();
            xinxi.fatherFormTitle = new List<string>();
            xinxi.fatherFormClassName = new List<string>();
            RECT weizhi = new RECT();
            GetWindowRect(hd, ref weizhi);
            xinxi.location.X = weizhi.Left;
            xinxi.location.Y = weizhi.Top;
            xinxi.location.Width = weizhi.Right - weizhi.Left;
            xinxi.location.Height = weizhi.Bottom - weizhi.Top;
            StringBuilder s = new StringBuilder(512);
            GetWindowText(hd, s, s.Capacity);
            xinxi.showPassw = s.ToString();
            GetClassName(hd, s, s.Capacity);
            xinxi.className = s.ToString();

            IntPtr f1 = GetParent(hd);
            IntPtr h;
            while (f1 != IntPtr.Zero)
            {
                xinxi.fatherFormHandle.Add(f1);
                StringBuilder s1 = new StringBuilder(512);
                GetWindowText(f1, s1, s1.Capacity);
                xinxi.fatherFormTitle.Add(s1.ToString());
                GetClassName(f1, s1, s1.Capacity);
                xinxi.fatherFormClassName.Add(s1.ToString());
                h = f1;
                f1 = GetParent(h);
            }
            return xinxi;
        }

        [DllImport("user32.dll")]
        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        //hwndparent爲0表示桌面爲父,hwndchildafter爲null表示從第一個開始,lpwindowname爲null表示步匹配該項
        [DllImport("user32.dll")]
        private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpClassName, string lpWindowName);
        //查找控件句柄
        public static IntPtr findview(IntPtr parent, string classname, string text)
        {
            IntPtr hwndtemp = FindWindowEx(parent, IntPtr.Zero, classname, text);
            if (hwndtemp == IntPtr.Zero)
            {
                List<IntPtr> allchild = findallchild(parent);
                for (int i = 0; i < allchild.Count; i++)
                {
                    handleInfoStructor ju = getHandleInfo(allchild[i]);
                    if (ju.className == classname && ju.showPassw == text)
                    {
                        return allchild[i];
                    }
                }
            }
            return hwndtemp;
        }

        //查找一級子控件hd
        public static List<IntPtr> findchild(IntPtr parent)
        {
            List<IntPtr> allchild = new List<IntPtr>();
            IntPtr hwnd = FindWindowEx(parent, IntPtr.Zero, null, null);
            while (hwnd != IntPtr.Zero)
            {
                allchild.Add(hwnd);
                hwnd = FindWindowEx(parent, hwnd, null, null);
            }
            return allchild;
        }
        //查找所有子控件-廣度遍歷
        public static List<IntPtr> findallchild(IntPtr parent)
        {
            List<IntPtr> allchild = new List<IntPtr>();
            allchild.Add(parent);   //第一個添加父句柄,最後再刪除
            for (int i = 0; i < allchild.Count; i++)
            {
                IntPtr patenttemp = allchild[i];
                IntPtr hwnd = FindWindowEx(patenttemp, IntPtr.Zero, null, null);
                while (hwnd != IntPtr.Zero)
                {
                    allchild.Add(hwnd);
                    hwnd = FindWindowEx(patenttemp, hwnd, null, null);
                }
            }
            allchild.RemoveAt(0);
            return allchild;
        }

        //查找窗口
        public static IntPtr findform(string classname, string windowname)
        {
            IntPtr hwnd = FindWindow(classname, windowname);
            return hwnd;
        }

獲得當前窗口的大小

獲取窗口大小及位置:需要調用方法GetWindowRect(IntPtr hWnd, ref RECT lpRect)

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);

        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int Left;                             //最左座標
            public int Top;                             //最上座標
            public int Right;                           //最右座標
            public int Bottom;                        //最下座標
        }

示例:

                    InPtr awin = GetForegroundWindow();    //獲取當前窗口句柄
                    RECT rect = new RECT();
                    GetWindowRect(awin, ref rect);
                   int width = rc.Right - rc.Left;                        //窗口的寬度
                   int height = rc.Bottom - rc.Top;                   //窗口的高度
                    int x = rc.Left;                                             
                    int y = rc.Top;

Excel嵌入

	Microsoft.Office.Interop.Excel.Application excel_H = new Microsoft.Office.Interop.Excel.Application();

    excel_H.CommandBars[1].Enabled = false;
    excel_H.CommandBars["Standard"].Visible = false;
    excel_H.CommandBars["Formatting"].Visible = false;
    excel_H.DisplayFormulaBar = false;
    IntPtr hwnd = (IntPtr)excel_H.Hwnd;
    try
    {
    	excel_H.Width = this.Width;
        excel_H.Height = this.Height;

        excel_H.Left = 0;
        excel_H.Top = 0;
     }
     catch (COMException ex) { }

     excel_H.WindowState = Microsoft.Office.Interop.Excel.XlWindowState.xlNormal;
     SetParent(hwnd, this.show_panel.Handle);
     excel_H.Visible = true;
     excel_H.Workbooks.Close();
     excel_H.Quit();
     System.Runtime.InteropServices.Marshal.ReleaseComObject(excel_H);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章