首先我要判断是否已经打开了参照面板.

然而cad自己没有相关的系统变量.这时我就需要利用到win32api来判断程序是否打开了参照面板了.

首先学习的是  从.NET平台调用Win32 API 这篇文章很好的说明了c#如何调用win32api,以及大家可能遇到的各种问题.

其次,我们要用到spy++这个工具来看windowns窗口的句柄,

注意这个工具若没有的话,要在控制面板上面选择vs,然后安装c++的相关内容,不然只安装net是没有的....

还有就是工具--导入和导出设置--重置所有设置--Visual C++,选择C++工程的环境!!

然后就可以利用spy++查找的拖拽来拖到cad窗口上....

然后我直接贴一下整个功能的代码:

win32api:

#if !HC2019
#else
using GrxCAD.DatabaseServices;
using GrxCAD.EditorInput;
using GrxCAD.Geometry;
using GrxCAD.ApplicationServices;
using GrxCAD.Runtime;
#endif
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Printing;
using System.Runtime.InteropServices;
using System.Text; namespace JingJingBoxDD
{
public class LocalPrinter
{
/// <summary>
/// 系统所有打印机名称(默认将在第一)
/// </summary>
public static string[] GetLocalPrinters()
{
var fPrinters = new List<string>();
try
{
PrintDocument fPrintDocument = new PrintDocument();
string s = fPrintDocument.PrinterSettings.PrinterName;//默认打印机
if (s != null)
{
//默认打印机始终出现在列表的第一项
fPrinters.Add(s);
}
foreach (string fPrinterName in PrinterSettings.InstalledPrinters)
{
if (!fPrinters.Contains(fPrinterName))
{
fPrinters.Add(fPrinterName);
}
}
}
catch
{ }
return fPrinters.ToArray();
}
} public partial class Win32api
{
/// <summary>
/// 设置默认打印机
/// </summary>
/// <param name="Name"></param>
/// <returns></returns>
[DllImport("winspool.drv")]
public static extern bool SetDefaultPrinter(string Name);
} public partial class Win32api
{
// https://blog.csdn.net/bcbobo21cn/article/details/50930221 public delegate bool WNDENUMPROC(IntPtr hwnd, int lParam); /// <summary>
/// 置前窗口
/// </summary>
/// <param name="hwnd"></param>
/// <returns></returns>
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool SetForegroundWindow(IntPtr hwnd); /// <summary>
/// 枚举窗口
/// </summary>
/// <param name="lpEnumFunc"></param>
/// <param name="lParam"></param>
/// <returns></returns>
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool EnumWindows(WNDENUMPROC lpEnumFunc, int lParam); /// <summary>
/// 获取窗口Text
/// </summary>
/// <param name="hwnd"></param>
/// <param name="lpString"></param>
/// <param name="nMaxCount"></param>
/// <returns></returns>
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int GetWindowText(IntPtr hwnd, [MarshalAs(UnmanagedType.LPWStr)]StringBuilder lpString, int nMaxCount); /// <summary>
/// 获取窗口类名
/// </summary>
/// <param name="hwnd"></param>
/// <param name="lpString"></param>
/// <param name="nMaxCount"></param>
/// <returns></returns>
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int GetClassName(IntPtr hwnd, [MarshalAs(UnmanagedType.LPWStr)]StringBuilder lpString, int nMaxCount); /// <summary>
/// 窗口隐藏
/// </summary>
/// <param name="hwnd">窗口句柄</param>
/// <returns></returns>
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool IsWindowVisible(IntPtr hwnd); /// <summary>
/// 查找子窗口
/// </summary>
/// <param name="hwnd"></param>
/// <param name="hwndChildAfter"></param>
/// <param name="lpszClass"></param>
/// <param name="lpszWindow"></param>
/// <returns></returns>
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr FindWindowEx(IntPtr hwnd, uint hwndChildAfter, string lpszClass, string lpszWindow); ///https://jingyan.baidu.com/article/c45ad29cd5fb58051653e278.html
/// <summary>
/// 发送消息
/// </summary>
/// <returns></returns>
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam); /// <summary>
/// 发送消息
/// </summary>
/// <returns></returns>
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, ref Rectangle lParam); /// <summary>
/// 关闭文件夹
/// </summary>
/// <param name="hwnd"></param>
public static void QuitToolbar(IntPtr hwnd)
{
// https://docs.microsoft.com/zh-cn/windows/desktop/winmsg/wm-close
const int WM_CLOSE = 0x0010;
SendMessage(hwnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
} //窗口样式
public struct WindowInfo
{
public IntPtr hwnd;
public string windowName;
public string className;
} /// <summary>
/// 枚举所有桌面窗口
/// </summary>
/// <returns></returns>
public static WindowInfo[] GetAllDesktopWindows()
{
//用来保存窗口对象 列表
var wndList = new List<WindowInfo>();
//枚举所有桌面窗口
EnumWindows(delegate (IntPtr hWnd, int lParam)
{
WindowInfo wnd = new WindowInfo();
StringBuilder sb = new StringBuilder();
wnd.hwnd = hWnd;//句柄
GetWindowText(hWnd, sb, sb.Capacity); //获取窗口名称
wnd.windowName = sb.ToString();
GetClassName(hWnd, sb, sb.Capacity);//获取窗口类
wnd.className = sb.ToString();
wndList.Add(wnd);//添加到列表中
return true;
}, );
return wndList.ToArray();
}
} public struct InternetExplorer
{
public IntPtr HWND { get; set; }//句柄
public string LocationURL { get; set; }//文件夹路径
public void Quit()//关闭文件夹
{
Win32api.QuitToolbar(HWND);
}
} /// <summary>
/// 遍历桌面资源管理器
/// </summary>
public class ShellWindows : IEnumerable
{
private readonly ArrayList list;
public IEnumerator GetEnumerator()
{
return (list as IEnumerable).GetEnumerator();
} /// <summary>
/// 获取桌面所有文件夹的路径
/// </summary>
/// <returns></returns>
public ShellWindows()
{
var allDesktopWindows = Win32api.GetAllDesktopWindows();
var lst = new List<InternetExplorer>();
foreach (var item in allDesktopWindows)
{
if (item.className == "CabinetWClass")
{
string a = item.windowName;
var fi = Win32api.FindWindowEx(item.hwnd, , "WorkerW", null);
if (fi != IntPtr.Zero)
{
fi = Win32api.FindWindowEx(fi, , "ReBarWindow32", null);
if (fi != IntPtr.Zero)
{
fi = Win32api.FindWindowEx(fi, , "Address Band Root", null);
if (fi != IntPtr.Zero)
{
fi = Win32api.FindWindowEx(fi, , "msctls_progress32", null);
if (fi != IntPtr.Zero)
{
fi = Win32api.FindWindowEx(fi, , "Breadcrumb Parent", null);
if (fi != IntPtr.Zero)
{
fi = Win32api.FindWindowEx(fi, , "ToolbarWindow32", null);//资源管理器
//知识:toolbar上的按钮没有handler,要用发送通知信息
if (fi != IntPtr.Zero)
{
StringBuilder sb = new StringBuilder();
//获取窗口名称-路径地址
Win32api.GetWindowText(fi, sb, sb.Capacity);
string path = sb.ToString();
path = path.Substring(, path.Length - );//4表示"地址: "长度 InternetExplorer ie = new InternetExplorer
{
HWND = item.hwnd,
LocationURL = path
};
lst.Add(ie);
}
}
}
}
} }
}
}
list = new ArrayList(lst);
}
} }

主函数:

    public class 开关参照面板
{
private static bool Chongfu = false;
private const string commandname = "JJ_er";
//重复执行er可以关闭和打开参照面板
[CommandMethod(commandname, CommandFlags.Session)]//发送同步命令 CommandFlags.Modal |
public static void JJ_er()
{
if (Chongfu)
{
Chongfu = false;
return;
}
var ed = Application.DocumentManager.MdiActiveDocument.Editor;
var regexAcad = new Regex("AutoCAD");//正则
var regexGcad = new Regex("浩辰");//正则
try
{
bool sendClose = true;
const string canzhao = "外部参照";
var wndList = new List<WinApi.WindowInfo>();
WinApi.GetAllDesktopWindows(wndList);
IntPtr open = IntPtr.Zero;
#if HC2019
foreach (var item in wndList)
{
if (item.windowName.Contains("浩辰"))
{
var fi = WinApi.FindWindowEx(item.hwnd, , null, canzhao);//"外部参照"子窗口
if (fi != IntPtr.Zero)//显示
{
if (WinApi.IsWindowVisible(fi))
{
open = fi;
break;
}
}
}
}
#else
foreach (var item in wndList)
{
if (regexAcad.IsMatch(item.windowName))
{
var fi = WinApi.FindWindowEx(item.hwnd, , null, "特性");//用过ctrl+1这里会变为"特性"子窗口
if (fi == IntPtr.Zero)
{
fi = WinApi.FindWindowEx(item.hwnd, , null, canzhao);//"外部参照"子窗口
}
if (fi == IntPtr.Zero)
{
fi = WinApi.FindWindowEx(item.hwnd, , null, "块编写选项板");
}
if (fi != IntPtr.Zero)
{
fi = WinApi.FindWindowEx(fi, , null, canzhao);//找到"特性"或"外部参照"下的"外部参照"子子窗口
if (fi != IntPtr.Zero)
{
open = fi;
break;
}
}
}
else if (item.windowName == canzhao)
{
open = item.hwnd;
break;
}
}
#endif
if (open != IntPtr.Zero)//判断窗口如果打开了,显示
{
if (WinApi.IsWindowVisible(open))//可见
{
sendClose = true;
}
else
{
sendClose = false;
}
}
else
{
foreach (var item in wndList)
{
if (item.windowName.Contains(canzhao))
{
open = item.hwnd;
break;
}
}
if (open != IntPtr.Zero)
{
//当浩辰的参照面板拖拉出来,然后放回索引箭头靠边,在这里判断
if (WinApi.IsWindowVisible(open))//可见
{
sendClose = true;
}
else
{
sendClose = false;
}
}
else
{
sendClose = false;
}
}
if (sendClose)
{
SendExternalreferences("Externalreferencesclose");//关闭面板
}
else
{
SendExternalreferences("Externalreferences");//打开面板
} Chongfu = true;
//发送自己,实现空格
SendToCad.SendCommand(commandname);
}
catch (System.Exception e)
{
throw e;
}
} /// <summary>
/// 开关参照面板
/// </summary>
/// <param name="command">Externalreferences或Externalreferencesclose</param>
private static void SendExternalreferences(string command)
{
SendToCad.SendCommand(command);//先发送打开 //如果此时的状态已退出编辑参照,但是程序会提示并阻止时
//"** 编辑参照时不允许使用 EXTERNALREFERENCES 命令 **"
//可能是cad长事务出错了,这个方法可以解开这种问题
var blockName = CadSystem.Getvar("refeditname");//是否有在位编辑
if (blockName == "")
{
string last = CadSystem.Getvar("lastprompt"); //再获取最后一行命令
Regex re = new Regex("编辑参照时不允许使用");
if (re.IsMatch(last))
{
SendToCad.SendCommand("_qsave");
SendToCad.SendCommand("_u");
SendToCad.SendCommand(command);//最后再次发送打开
}
}
}
}

cad.net 利用win32api实现一个命令开关参照面板的更多相关文章

  1. CAD向控件注册一个命令

    _DMxDrawX::RegistUserCustomCommand 向控件注册一个命令,用户在命令行输入命令名这个字符串,就会触发执行命令事件 命令事件的id就是该注册时的id值,成功返回true. ...

  2. CAD向控件注册一个命令(com接口VB语言)

    主要用到函数说明: MxDrawXCustomFunction::Mx_RegistUserCustomCommand 向控件注册一个命令,用户在命令行输入命令名这个字符串,就会触发执行命令事件 命令 ...

  3. cad.net 利用win32api实现不重复打开dwg路径的文件夹(资源管理器)

    这里地址的方法也是可用的,但是net3.5不能使用 为此我选择使用win32api的方式来遍历当前桌面所有资源管理器 /// <summary> /// 不重复打开dwg路径的资源管理器 ...

  4. 利用Node.js的Net模块实现一个命令行多人聊天室

    1.net模块基本API 要使用Node.js的net模块实现一个命令行聊天室,就必须先了解NET模块的API使用.NET模块API分为两大类:Server和Socket类.工厂方法. Server类 ...

  5. CAD把一个命令当着一个函数调用,不执行(com接口VB语言)

    主要用到函数说明: MxDrawXCustomFunction::Mx_SendStringToExecuteFun 把一个命令当着一个函数调用,不执行,详细说明如下: 参数 说明 CString s ...

  6. 利用windows系统ftp命令编写的BAT文件上传[转]

    利用windows系统ftp命令编写的BAT文件上传[转] 利用windows系统ftp命令编写的BAT文件上传[转] 在开发中往往需要将本地的程序上传到服务器,而且用惯了linux命令的人来说.在w ...

  7. 学了C语言,如何利用CURL写一个下载程序?—用nmake编译CURL并安装

    在这一系列的前一篇文章学了C语言,如何为下载狂人写一个磁盘剩余容量监控程序?中,我们为下载狂人写了一个程序来监视磁盘的剩余容量,防止下载的东西撑爆了硬盘.可是,这两天,他又抱怨他的下载程序不好用,让我 ...

  8. 利用 bat 批量处理命令实现手动控制mysql /Oracle 服务的开启和关闭

    利用 bat 批量处理命令实现手动控制mysql /Oracle 服务的开启和关闭 因为最近在学习数据库的知识,主要学习的是oracle 数据库,然而好巧啊,java也是在学习,我们老师现在要我们做一 ...

  9. 利用 vue-cli 构建一个 Vue 项目

    一.项目初始构建 现在如果要构建一个 Vue 的项目,最方便的方式,莫过于使用官方的 vue-cli . 首先,咱们先来全局安装 vue-cli ,打开命令行工具,输入以下命令: $ npm inst ...

随机推荐

  1. leetcode105

    /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode ...

  2. 使用Nexus2搭建Maven本地仓库

    由于OS为WindowsXP,而Nexus3forWindows为x64版本,只能选择安装nexus2了. Windows(x86)平台,Nexus Repository Manager OSS 2. ...

  3. BUILDING WITH BOOTSTRAP

    BUILDING WITH BOOTSTRAP Bootstrap Generalizations You just built an impressive webpage using the Boo ...

  4. Mac 系统下 mysql 的安装与配置

    1.mysql 的安装 1)官网下载 mysql 安装包:http://www.mysql.com/downloads/ 2)下载后解压打开安装包,点击 pkg 文件进行安装 3)注意:最后一步弹窗会 ...

  5. tensorflow/pytorch/mxnet的pip安装,非源代码编译,基于cuda10/cudnn7.4.1/ubuntu18.04.md

    os安装 目前对tensorflow和cuda支持最好的是ubuntu的18.04 ,16.04这种lts,推荐使用18.04版本.非lts的版本一般不推荐. Windows倒是也能用来装深度GPU环 ...

  6. SqlServer中的UNION操作符在合并数据时去重的原理以及UNION运算符查询结果默认排序的问题

    本文出处:http://www.cnblogs.com/wy123/p/7884986.html 周围又有人在讨论UNION和UNION ALL,对于UNION和UNION ALL,网上说的最多的就是 ...

  7. window、location、location.href、self、top简单介绍

    1.self:当前窗口对象(如果是在iframe里,则为该框架的窗口对象) 2.top:父窗口对象 3.window:典型情况下,浏览器会为每一个打开的html创建对应的window对象,如果这个文档 ...

  8. 1. Go安装

    和任何语言一样,开始使用之前都要先安装好他的开发/编译环境. Go是由谷歌开发的一个开源的编译型的静态语言,编译型语言最大的优点就是效率高运行速度快. Go语言支持Linux,Windows,Mac等 ...

  9. 微信小程序和微信公众号的id是一个吗

    首先,简单说下我遇到的问题是我们的程序调用微信小程序得到openid,然后通过openID得到用户的唯一标识,用户得以登录,然而,当我们调用微信公众号也同样的到openid,同一以用户两个不同的ope ...

  10. 169. Majority Element (Array)

    Given an array of size n, find the majority element. The majority element is the element that appear ...