本文主要是介绍通过进程ID获取中望CAD窗体并向其发送命令,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
需求:
通过自启动多个CAD应用程序,对其进行管理,针对不同CAD程序发送不同命令。
核心功能
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;namespace StartAndSendMessageCAD
{public class WindowsHandleAndProcess{//SendMessage参数private const int WM_KEYDOWN = 0X100;private const int WM_KEYUP = 0X101;private const int WM_SYSCHAR = 0X106;private const int WM_SYSKEYUP = 0X105;private const int WM_SYSKEYDOWN = 0X104;private const int WM_CHAR = 0X102;public int ProcessId = 0;public IntPtr WindowHandle = IntPtr.Zero;const int MW_CLOSE = 0x0010;[DllImport("User32.dll", EntryPoint = "SendMessage")]private static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]public static extern bool EnumWindows(EnumThreadWindowsCallback callback, IntPtr extraData);public delegate bool EnumThreadWindowsCallback(IntPtr hWnd, IntPtr lParam);[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int processId);[DllImport("user32.dll")]public static extern int GetWindowTextLength(IntPtr hWnd);[DllImport("User32.dll", CharSet = CharSet.Auto)]public static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int nMaxCount);[DllImport("user32.dll", EntryPoint = "FindWindowEx", SetLastError = true)]public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);/// <summary>/// 获取所有指定进程下的应用程序窗口句柄/// </summary>/// <param name="processId">进程ID</param>/// <returns></returns>public Dictionary<string, IntPtr> GetWindowHandle(int processId){var windowHandles = new Dictionary<string, IntPtr>();EnumThreadWindowsCallback windowsCallback = new EnumThreadWindowsCallback(FindMainWindow2);EnumWindows(windowsCallback, IntPtr.Zero);//保持循环GC.KeepAlive(windowsCallback);// 遍历所有顶层窗体bool FindMainWindow2(IntPtr handle, IntPtr extraParameter){string windowName = GetWindowText(handle);int num;GetWindowThreadProcessId(handle, out num);if (num == processId){string windowText = windowName;if (!windowHandles.ContainsKey(windowText)){windowHandles.Add(windowText, handle);}}return true;}return windowHandles;}/// <summary>/// 通过窗体句柄获取窗体Text/// </summary>/// <param name="handle"></param>/// <returns></returns>public string GetWindowText(IntPtr handle){int length = GetWindowTextLength(handle);StringBuilder windowName = new StringBuilder(length + 1);GetWindowText(handle, windowName, windowName.Capacity);return windowName.ToString();}/// <summary>/// 获取应用程序窗口句柄/// </summary>/// <param name="processId">进程ID</param>/// <param name="keyWindowText">CAD窗体Text标识</param>/// <param name="keySecondWindowText">命令栏名称</param>/// <returns></returns>public IntPtr GetWindowHandle(int processId, string keyWindowText, string keySecondWindowText){var windowHandles = GetWindowHandle(processId);foreach (var windowHandle in windowHandles){var name = windowHandle.Key;var intPtr = windowHandle.Value;if (name.Contains(keyWindowText)){var allChildHandle = GetAllChildWindows(intPtr); //获得按钮的句柄foreach (var childWindowHandle in allChildHandle){if (childWindowHandle.Key.Contains(keySecondWindowText)){if (childWindowHandle.Value != IntPtr.Zero){return childWindowHandle.Value;}}}}}return IntPtr.Zero;}/// <summary>/// 通过某个窗体Handle获取其下所有子窗体名称及其handle/// </summary>/// <param name="handle"></param>/// <returns></returns>public Dictionary<string, IntPtr> GetAllChildWindows(IntPtr handle){var windowHandles = new Dictionary<string, IntPtr>();IntPtr childHwnd = FindWindowEx(handle, IntPtr.Zero, null, null);while (childHwnd != IntPtr.Zero){string windowsText = GetWindowText(childHwnd);if (!windowHandles.ContainsKey(windowsText)){windowHandles.Add(windowsText, childHwnd);}var windowHandlesTemp = GetAllChildWindows(childHwnd);foreach (var item in windowHandlesTemp){if (!windowHandles.ContainsKey(item.Key)){windowHandles.Add(item.Key, item.Value);}}childHwnd = FindWindowEx(handle, childHwnd, null, null);}return windowHandles;}/// <summary>/// 发送一个字符串/// </summary>/// <param name="myIntPtr">窗口句柄</param>/// <param name="Input">字符串</param>public void InputStr(IntPtr myIntPtr, string Input){byte[] ch = (ASCIIEncoding.ASCII.GetBytes(Input));for (int i = 0; i < ch.Length; i++){SendMessage(myIntPtr, WM_CHAR, ch[i], 0);}}}
}
如何调用:
static void Main(string[] args){string exePath = @"C:\Program Files\ZWSOFT\ZWCAD 2023\ZWCAD.EXE";Process process = new Process();process.StartInfo.FileName = exePath;process.StartInfo.CreateNoWindow = true;process.Start();Console.WriteLine("CAD ProcessId is : " + process.Id);Thread.Sleep(10 * 1000);var handleAndProcess = new WindowsHandleAndProcess();var intPtr = handleAndProcess.GetWindowHandle(process.Id,"ZWCAD 20","CommandLine");if (intPtr != IntPtr.Zero){handleAndProcess.InputStr(intPtr, "some\n");}Console.ReadKey();}
示意图:
这篇关于通过进程ID获取中望CAD窗体并向其发送命令的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!