书小宅之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);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章