- UID
- 658062
- 积分
- 2147
- 精华
- 贡献
-
- 威望
-
- 活跃度
-
- D豆
-
- 在线时间
- 小时
- 注册时间
- 2008-10-22
- 最后登录
- 1970-1-1
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
转自 http://hi.baidu.com/kakanimo/item/e36168dcd0cb764bddf9be5f
(原创)C#实现打开CAD文件时自动替换缺失字体
经过N多天的研究,终于代码出来了;本着分享的精神,现在把代码都贴出来。ps:此程序算是本人的第一个完整的C#程序,必定存在拖沓冗余的代码。随着C#学习的深入,会不断优化。现在就将就看看过程思路吧。
VB实现可以见http://hi.baidu.com/kakanimo/blog/item/4a69fe1e617a4f69f624e4ca.html,不过代码要自己修改下,VB中是进了CAD图再替换字体。完全根据我之前的那篇CAD替换字体框的研究写成打开图之前替换。
此程序涉及的东西比较多。如调用API、CAD替换字体框的研究(http://hi.baidu.com/kakanimo/blog/item/83e1cffc04dc0049d7887d78.html)、CAD事件(看了几天C#的委托事件,也算看懂了,谁知CAD中事件太简单了,只需要连接下写下事件处理代码就可以了。囧,完全可以依样画瓢。)、多线程==,由于都是首次使用,基本上是依样画瓢。废话不说,上代码
using System;
using System.Text;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Threading;
namespace ChangeFonts
{
class PublicTxtIndex
{
public static Thread TxtIndex;//声明一个静态变量
public static Thread PublicTxtIndexN
{
get
{
return TxtIndex;
}
set
{
TxtIndex = value;
}
}
}
public class Init : IExtensionApplication
{
public void Initialize()
{
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
ed.WriteMessage("MOKACAD插件初始化完成。");
//启动事件
ChangeFontEvent GoChange=new ChangeFontEvent();
GoChange.addEvents();
}
public void Terminate()
{
//程序结束,在里做一些程序的清理工作
}
}
public class ChangeFontEvent
{
DocumentCollection CreatNew = Application.DocumentManager;
DLLChange.GOON dochange = new DLLChange.GOON();
void documentCreateStarted(object sender, DocumentCollectionEventArgs e)
{
try
{
//如果这个时候还没有文档(原一个文档都没有,那到这里就要CAD致命错误)
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
ed.WriteMessage("开始自动替换字体");
}
catch
{
}
Thread thread1 = new Thread(new ThreadStart(dochange.Reportfont));
PublicTxtIndex.PublicTxtIndexN = thread1;
StartOrAbort(true);
}
//打开或关闭
void StartOrAbort(bool flag)
{
if (flag == true)//如果需要开启
{
PublicTxtIndex.PublicTxtIndexN.Start();
}
else
{
PublicTxtIndex.PublicTxtIndexN.Abort(); //终止线程
}
}
void documentCreated(object sender, DocumentCollectionEventArgs e)
{
StartOrAbort(false);
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
ed.WriteMessage("自动替换字体结束");
}
[CommandMethod("AddEvents")]
public void addEvents()
{
//把事件处理函数与相应的事件进行连接
CreatNew.DocumentCreateStarted += new DocumentCollectionEventHandler(documentCreateStarted);
CreatNew.DocumentCreated += new DocumentCollectionEventHandler(documentCreated);
}
[CommandMethod("RemoveEvents")]
public void removeEvents()
{
//断开所有的事件处理函数
CreatNew.DocumentCreateStarted -= new DocumentCollectionEventHandler(documentCreateStarted);
CreatNew.DocumentCreated -= new DocumentCollectionEventHandler(documentCreated);
}
}
}
namespace DLLChange
{
public delegate bool CallBack(int hwnd, int y);
public class GOON
{
#region API声明
[DllImport("user32.dll")]
public static extern int EnumWindows(CallBack x, int y);
[DllImport("user32.dll", EntryPoint = "EnumChildWindows")]//枚举子窗体
public static extern bool EnumChildWindows(int hwndParent, CallBack EnumFunc, int lParam);
[DllImport("User32.dll", EntryPoint = "FindWindow")]//找指定窗体
private static extern int FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32")]
public static extern int GetWindowText(int hwnd, StringBuilder lptrString, int nMaxCount);
[DllImport("user32")]
public static extern int IsWindowVisible(int hwnd);
[DllImport("User32.Dll")]
public static extern void GetClassName(int hwnd, StringBuilder s, int nMaxCount);
[DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Ansi)]
public static extern int SendMessage(int hwnd, int msg, int wParam, int lParam);
[DllImport("User32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Ansi)]
public static extern int SendMessage(int hWnd, int uMsg, int wParam, StringBuilder lParam);
const int LB_SETTOPINDEX = 0x0197;
const int LB_SETCURSEL = 0x0186;
const int LB_GETCOUNT = 0x18B;
const int WM_GETTEXT = 0x000D;
const int BM_CLICK = 0x00F5;
const int VK_UP = 0x26;//方向键
const int VK_DOWN = 0x28;
const int WM_CHAR = 0x102;
const int WM_KEYDOWN = 0x100;
#endregion
#region 相当于public变量
class ClassSqlString
{
public static int SqlString;//声明一个静态变量
public static int GlobalUserName
{
get
{
return SqlString;
}
set
{
SqlString = value;
}
}
}
class PublicButtonHwnd
{
public static int ButtonHwnd;//声明一个静态变量
public static int YButtonHwnd
{
get
{
return ButtonHwnd;
}
set
{
ButtonHwnd = value;
}
}
}
class PublicTxtIndex
{
public static int TxtIndex;//声明一个静态变量
public static int PublicTxtIndexN
{
get
{
return TxtIndex;
}
set
{
TxtIndex = value;
}
}
}
#endregion
#region 查找AutoCAD替换字体的窗口,返回得到这个窗口的句柄
public bool Report(int hwnd, int lParam)
{
if (IsWindowVisible(hwnd) == 1)
//if (pHwnd == 0 && IsWindowVisible(hwnd) == 1)
{
StringBuilder sb = new StringBuilder(512);
GetWindowText(hwnd, sb, sb.Capacity);
string CadString;
CadString = sb.ToString();
if (CadString.Length > 7 && CadString.Substring(0, 7) == "指定字体给样式")
{//找到字体窗口
ClassSqlString.GlobalUserName = hwnd;
return false;
}
}
return true;
}
#endregion
#region 在这个替换字体的主窗口内查找子窗口
public bool Reportfa(int hwnd, int lParam)//循环查找替换listbox
{
string lpszParentClass = "ListBox"; //整个窗口的类名
StringBuilder sbClassName = new StringBuilder(255);
GetClassName(hwnd, sbClassName, 255);
//由于现查找到这个确定按钮,所以先设置这个值
if (sbClassName.ToString() == "Button")
{
StringBuilder strButton = new StringBuilder(10);//用来存放窗口标题
GetWindowText(hwnd, strButton, strButton.Capacity);
if (strButton.ToString() == "确定")
{
PublicButtonHwnd.YButtonHwnd = hwnd;//得到确定的按钮
}
}
if (lpszParentClass == sbClassName.ToString())
{
//找到一个listbox,就看他的标题是不是空,空的舍弃
StringBuilder str = new StringBuilder(512);//用来存放窗口标题
GetWindowText(hwnd, str, str.Capacity);
string strEnd = string.Empty;
strEnd = str.ToString();//转换为字符串
if (strEnd.Length > 0)//如果长度大于0,就找到这个啦
{
if (PublicTxtIndex.PublicTxtIndexN == 0)
{
GetfontIndex(hwnd);
}
//设置listbox值
SendMessage(hwnd, LB_SETCURSEL, PublicTxtIndex.PublicTxtIndexN, 0);
//下移一行
SendMessage(hwnd, WM_KEYDOWN, VK_DOWN, 0);
//发送确定按钮
SendMessage(PublicButtonHwnd.YButtonHwnd, BM_CLICK, 0, 0);
return false;
}
}
return true;
}
#endregion
#region 得到hztxt.shx的位置,设置PublicTxtIndexN
public void GetfontIndex(int hwnd)
{
//先查找一共有多少项
int ListCount;
ListCount = SendMessage(hwnd, LB_GETCOUNT, 0, 0);
StringBuilder strshx = new StringBuilder(20);//用来存放窗口标题
for (int i = 0; i <= ListCount - 1; i++)
{
//设定某项来比较
SendMessage(hwnd, LB_SETCURSEL, i, 0);
//SendMessage(hwnd, LB_SETTOPINDEX, i, 0);//
SendMessage(hwnd, WM_GETTEXT, strshx.Capacity, strshx);
if (strshx.ToString() == "hztxt.shx|1|0000000")
{
//得到hztxt前一个值
PublicTxtIndex.PublicTxtIndexN = i - 1;
break;
}
}
}
#endregion
//循环查找替换
public void Reportfont()
{
// Process[] ProcArray = Process.GetProcesses();
int Nub = 1;
while (Nub > 0)
{
EnumWindows(this.Report, 0);//这里会得到下面的kaka的值
int kaka;
kaka = ClassSqlString.GlobalUserName;//替换字体的对话框的句柄
EnumChildWindows(kaka, this.Reportfa, 0);
//this.DoEvents();
}
}
}
}
|
|