明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 21042|回复: 74

[源码] 干掉选择字体对话框,开图自动替换字体(2021.3.2增加c#版本)

    [复制链接]
发表于 2021-2-24 20:28:27 | 显示全部楼层 |阅读模式
本帖最后由 print1985 于 2021-3-2 16:06 编辑

开图不停的替换字体,囧 囧 囧  受够了,干掉这个讨厌的对话框,自动替换未知字体


1、Lisp文件这里要修改为你想要的字体。


2、CAD菜单-工具-选项-系统-隐藏消息设置


3、勾选如下图


4、打开缺少字体的图纸,如图勾选“始终执行……”,后点击“忽略缺少的……”


搞定,以后开图不会出现选择字体对话框了,lisp程序会在开图后会自动替换未知字体。

主要源码来自http://bbs.mjtd.com/forum.php?mod=viewthread&tid=181963&extra=&highlight=%D7%D6%CC%E5%2B%CC%E6%BB%BB&page=1
我只作了简单修改,感谢gaics、sctw、wudechao等各位大侠


如果复制下面的代码如果有问题 请到晓东下载lsp
http://bbs.xdcad.net/thread-727707-1-1.html


;手动替换字体,命令tzt
(defun c:tzt() (GL:changefont))

;替换字体
(defun GL:changefont ( / *error* a b c d date1 e err font_chn font_eng font_lst_chn font_lst_eng font_lst_tru font_tru textstyles x)
(setq font_eng "tssdeng.shx"  ;tssdeng.shx英文字体,自行修改
      font_chn "tssdchn.shx"  ;tssdchn.shx中文字体,自行修改
      font_tru "宋体"         ;windows系统字体,自行修改
      font_lst_eng '()
      font_lst_chn '()
      font_lst_tru '()
)

(defun *error* (msg) ;错误处理
  (setvar "regenmode" 1)
  (command "undo" "e")
  (setvar "cmdecho" 1)
  (princ msg)
)

(vl-load-com)
(setvar "cmdecho" 0)
(command "undo" "be")
(setvar "regenmode" 0)
(setq date1 (getvar "millisecs"))
(setq textstyles (vla-get-textstyles (vla-get-activedocument (vlax-get-acad-object))))
(vlax-for x textstyles (vla-getfont x 'a 'b 'c 'd 'e) (if (= a "")
                                                        (progn
                                                         (if (and
                                                              (not (findfile (vla-get-fontfile x)))
                                                              (not (findfile (strcat (vla-get-fontfile x) ".shx")))
                                                             )
                                                         (progn
                                                          (vla-put-fontfile x font_eng)
                                                          (setq font_lst_eng (cons (vla-get-name x) font_lst_eng))
                                                         )
                                                         )
                                                         (if (and
                                                              (/= (vla-get-bigfontfile x) "")
                                                              (not (findfile (vla-get-bigfontfile x)))
                                                              (not (findfile (strcat (vla-get-bigfontfile x) ".shx")))
                                                             )
                                                         (progn
                                                          (vla-put-bigfontfile x font_chn)
                                                          (setq font_lst_chn (cons (vla-get-name x) font_lst_chn))
                                                         )
                                                         )
                                                        )
                                                        (progn
                                                         (setq err (vl-catch-all-apply 'vla-setfont (list x a b c d e)))
                                                         (if (vl-catch-all-error-p err)
                                                         (progn
                                                          (vla-setfont x font_tru b c d e)
                                                          (setq font_lst_tru (cons (vla-get-name x) font_lst_tru))
                                                         )
                                                         )
                                                        )
                                                       )
)
(setvar "regenmode" 1)
(command "regen")
(princ "\n")
(if (or font_lst_eng font_lst_chn font_lst_tru)
(progn
  (princ (strcat "字体替换完成,共耗时" (rtos (/ (- (getvar "millisecs") date1)1000.000) 2 3) "秒。  "))
  (if font_lst_eng (progn (princ "文字样式:")(princ font_lst_eng)(princ (strcat "的英文字体已替换为" font_eng "。  "))))
  (if font_lst_chn (progn (princ "文字样式:")(princ font_lst_chn)(princ (strcat "的中文字体已替换为" font_chn "。  "))))
  (if font_lst_tru (progn (princ "文字样式:")(princ font_lst_tru)(princ (strcat "的字体已替换为" font_tru "。  "))))
)
(princ "\n所有字体均存在,未替换")
)
(command "undo" "e")
(setvar "cmdecho" 1)
(princ)
)

;开图自动替换字体
(GL:changefont)


----------------------------------c#版本-------------------------------------------
2021.3.2增加c#版本

源码来自 http://blog.sina.com.cn/s/blog_69e8fdf00100nc58.html  版权归原作者所有,感谢!
本人修改了几处代码并重新编译以适应高版本CAD

使用方法:
1、将DLL文件设为自动加载(不会设的设置的可以参看我发的lisp+c#混合编程帖子的lisp代码)。
2、开图使用Hztxt.shx自动替换未知字体,所以你的CAD至少得有Hztxt.shx字体。
3、DLL可以单独使用,也可以和上面的lisp代码组合使用,当然如果要用DLL就不能干掉字体替换对话框了(干掉C#程序就没法自动选择字体了),不干掉字体选择对话框lisp也是可以自动替换的。

原理:开图出现字体选择对话框时,自动选择Hztxt.shx字体替换未知字体(可以理解为模拟按键,代替手动选择)
明经现在上传不了附件 请到晓东下载DLL文件
http://bbs.xdcad.net/thread-727707-1-1.html



修改后的C#源码如下
  1. using System.Text;
  2. using Autodesk.AutoCAD.ApplicationServices;
  3. using Autodesk.AutoCAD.EditorInput;
  4. using Autodesk.AutoCAD.Runtime;
  5. using System.Runtime.InteropServices;
  6. using System.Threading;

  7. namespace ChangeFonts
  8. {
  9.     class PublicTxtIndex
  10.     {
  11.         public static Thread TxtIndex;//声明一个静态变量

  12.         public static Thread PublicTxtIndexN
  13.         {
  14.             get
  15.             {
  16.                 return TxtIndex;
  17.             }
  18.             set
  19.             {
  20.                 TxtIndex = value;
  21.             }
  22.         }

  23.     }

  24.     public class Init : IExtensionApplication
  25.     {
  26.         public void Initialize()
  27.         {
  28.             Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  29.             ed.WriteMessage("MOKACAD插件初始化完成。");
  30.             //启动事件
  31.             ChangeFontEvent GoChange = new ChangeFontEvent();
  32.             GoChange.addEvents();
  33.         }
  34.         public void Terminate()
  35.         {
  36.             //程序结束,在里做一些程序的清理工作
  37.         }
  38.     }
  39.     public class ChangeFontEvent
  40.     {
  41.         DocumentCollection CreatNew = Application.DocumentManager;
  42.         DLLChange.GOON dochange = new DLLChange.GOON();

  43.         void documentCreateStarted(object sender, DocumentCollectionEventArgs e)
  44.         {
  45.             try
  46.             {
  47.                 //如果这个时候还没有文档(原一个文档都没有,那到这里就要CAD致命错误)
  48.                 Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  49.                 ed.WriteMessage("开始自动替换字体");
  50.             }
  51.             catch
  52.             {
  53.             }

  54.             Thread thread1 = new Thread(new ThreadStart(dochange.Reportfont));
  55.             PublicTxtIndex.PublicTxtIndexN = thread1;
  56.             StartOrAbort(true);
  57.         }

  58.         //打开或关闭
  59.         void StartOrAbort(bool flag)
  60.         {

  61.             if (flag == true)//如果需要开启
  62.             {
  63.                 PublicTxtIndex.PublicTxtIndexN.Start();
  64.             }
  65.             else
  66.             {
  67.                 PublicTxtIndex.PublicTxtIndexN.Abort(); //终止线程

  68.             }
  69.         }

  70.         void documentCreated(object sender, DocumentCollectionEventArgs e)
  71.         {
  72.             StartOrAbort(false);
  73.             Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  74.             ed.WriteMessage("自动替换字体结束");
  75.         }
  76.         public void addEvents()
  77.         {
  78.             //把事件处理函数与相应的事件进行连接
  79.             CreatNew.DocumentCreateStarted += new DocumentCollectionEventHandler(documentCreateStarted);
  80.             CreatNew.DocumentCreated += new DocumentCollectionEventHandler(documentCreated);
  81.         }
  82.         public void removeEvents()
  83.         {
  84.             //断开所有的事件处理函数
  85.             CreatNew.DocumentCreateStarted -= new DocumentCollectionEventHandler(documentCreateStarted);
  86.             CreatNew.DocumentCreated -= new DocumentCollectionEventHandler(documentCreated);
  87.         }
  88.     }
  89. }

  90. namespace DLLChange
  91. {
  92.     public delegate bool CallBack(int hwnd, int y);

  93.     public class GOON
  94.     {

  95.         #region API声明
  96.         [DllImport("user32.dll")]
  97.         public static extern int EnumWindows(CallBack x, int y);

  98.         [DllImport("user32.dll", EntryPoint = "EnumChildWindows")]//枚举子窗体
  99.         public static extern bool EnumChildWindows(int hwndParent, CallBack EnumFunc, int lParam);

  100.         [DllImport("User32.dll", EntryPoint = "FindWindow")]//找指定窗体
  101.         private static extern int FindWindow(string lpClassName, string lpWindowName);

  102.         [DllImport("user32")]
  103.         public static extern int GetWindowText(int hwnd, StringBuilder lptrString, int nMaxCount);

  104.         [DllImport("user32")]
  105.         public static extern int IsWindowVisible(int hwnd);
  106.         [DllImport("User32.Dll")]
  107.         public static extern void GetClassName(int hwnd, StringBuilder s, int nMaxCount);


  108.         [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Ansi)]
  109.         public static extern int SendMessage(int hwnd, int msg, int wParam, int lParam);

  110.         [DllImport("User32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Ansi)]
  111.         public static extern int SendMessage(int hWnd, int uMsg, int wParam, StringBuilder lParam);

  112.         const int LB_SETTOPINDEX = 0x0197;
  113.         const int LB_SETCURSEL = 0x0186;
  114.         const int LB_GETCOUNT = 0x18B;

  115.         const int WM_GETTEXT = 0x000D;
  116.         const int BM_CLICK = 0x00F5;

  117.         const int VK_UP = 0x26;//方向键
  118.         const int VK_DOWN = 0x28;
  119.         const int WM_CHAR = 0x102;
  120.         const int WM_KEYDOWN = 0x100;
  121.         #endregion

  122.         #region 相当于public变量
  123.         class ClassSqlString
  124.         {
  125.             public static int SqlString;//声明一个静态变量

  126.             public static int GlobalUserName
  127.             {
  128.                 get
  129.                 {
  130.                     return SqlString;
  131.                 }
  132.                 set
  133.                 {
  134.                     SqlString = value;
  135.                 }
  136.             }

  137.         }
  138.         class PublicButtonHwnd
  139.         {
  140.             public static int ButtonHwnd;//声明一个静态变量

  141.             public static int YButtonHwnd
  142.             {
  143.                 get
  144.                 {
  145.                     return ButtonHwnd;
  146.                 }
  147.                 set
  148.                 {
  149.                     ButtonHwnd = value;
  150.                 }
  151.             }

  152.         }
  153.         class PublicTxtIndex
  154.         {
  155.             public static int TxtIndex;//声明一个静态变量

  156.             public static int PublicTxtIndexN
  157.             {
  158.                 get
  159.                 {
  160.                     return TxtIndex;
  161.                 }
  162.                 set
  163.                 {
  164.                     TxtIndex = value;
  165.                 }
  166.             }

  167.         }
  168.         #endregion

  169.         #region 查找AutoCAD替换字体的窗口,返回得到这个窗口的句柄
  170.         public bool Report(int hwnd, int lParam)
  171.         {


  172.             if (IsWindowVisible(hwnd) == 1)
  173.             //if (pHwnd == 0 && IsWindowVisible(hwnd) == 1)
  174.             {
  175.                 StringBuilder sb = new StringBuilder(512);

  176.                 GetWindowText(hwnd, sb, sb.Capacity);
  177.                 string CadString;
  178.                 CadString = sb.ToString();
  179.                 if (CadString.Length > 7 && CadString.Substring(0, 7) == "指定字体给样式")
  180.                 {//找到字体窗口
  181.                     ClassSqlString.GlobalUserName = hwnd;
  182.                     return false;
  183.                 }
  184.             }
  185.             return true;
  186.         }
  187.         #endregion

  188.         #region 在这个替换字体的主窗口内查找子窗口
  189.         public bool Reportfa(int hwnd, int lParam)//循环查找替换listbox
  190.         {
  191.             string lpszParentClass = "ListBox"; //整个窗口的类名
  192.             StringBuilder sbClassName = new StringBuilder(255);
  193.             GetClassName(hwnd, sbClassName, 255);
  194.             //由于现查找到这个确定按钮,所以先设置这个值
  195.             if (sbClassName.ToString() == "Button")
  196.             {
  197.                 StringBuilder strButton = new StringBuilder(10);//用来存放窗口标题
  198.                 GetWindowText(hwnd, strButton, strButton.Capacity);
  199.                 if (strButton.ToString() == "确定")
  200.                 {
  201.                     PublicButtonHwnd.YButtonHwnd = hwnd;//得到确定的按钮
  202.                 }
  203.             }

  204.             if (lpszParentClass == sbClassName.ToString())
  205.             {
  206.                 //找到一个listbox,就看他的标题是不是空,空的舍弃
  207.                 StringBuilder str = new StringBuilder(512);//用来存放窗口标题
  208.                 GetWindowText(hwnd, str, str.Capacity);
  209.                 string strEnd = string.Empty;
  210.                 strEnd = str.ToString();//转换为字符串

  211.                 if (strEnd.Length > 0)//如果长度大于0,就找到这个啦
  212.                 {
  213.                     if (PublicTxtIndex.PublicTxtIndexN == 0)
  214.                     {
  215.                         GetfontIndex(hwnd);
  216.                     }
  217.                     //设置listbox值
  218.                     SendMessage(hwnd, LB_SETCURSEL, PublicTxtIndex.PublicTxtIndexN, 0);
  219.                     //下移一行      
  220.                     SendMessage(hwnd, WM_KEYDOWN, VK_DOWN, 0);
  221.                     //发送确定按钮
  222.                     SendMessage(PublicButtonHwnd.YButtonHwnd, BM_CLICK, 0, 0);

  223.                     return false;
  224.                 }

  225.             }
  226.             return true;

  227.         }
  228.         #endregion

  229.         #region 得到hztxt.shx的位置,设置PublicTxtIndexN
  230.         public void GetfontIndex(int hwnd)
  231.         {
  232.             //先查找一共有多少项
  233.             int ListCount;
  234.             ListCount = SendMessage(hwnd, LB_GETCOUNT, 0, 0);
  235.             StringBuilder strshx = new StringBuilder(60);//用来存放窗口标题 原版为20 现改为用60个字符-CAD高版本要多一些内存才行
  236.             for (int i = 0; i <= ListCount - 1; i++)
  237.             {
  238.                 //设定某项来比较
  239.                 SendMessage(hwnd, LB_SETCURSEL, i, 0);
  240.                 SendMessage(hwnd, WM_GETTEXT, strshx.Capacity, strshx);
  241.                 //if (strshx.ToString() == "hztxt.shx|1|0000000") //原版代码
  242.                 if (strshx.ToString().Substring(0, 9) == "hztxt.shx")
  243.                 {
  244.                     //MessageBox.Show(strshx.ToString());
  245.                     //得到hztxt前一个值
  246.                     PublicTxtIndex.PublicTxtIndexN = i - 1;
  247.                     break;
  248.                 }
  249.             }
  250.         }
  251.         #endregion

  252.         //循环查找替换
  253.         public void Reportfont()
  254.         {
  255.             // Process[] ProcArray = Process.GetProcesses();
  256.             int Nub = 1;
  257.             while (Nub > 0)
  258.             {
  259.                 EnumWindows(this.Report, 0);//这里会得到下面的kaka的值
  260.                 int kaka;
  261.                 kaka = ClassSqlString.GlobalUserName;//替换字体的对话框的句柄
  262.                 EnumChildWindows(kaka, this.Reportfa, 0);
  263.                 //this.DoEvents();
  264.             }
  265.         }

  266.     }
  267. }



点评

当图纸第一次打开后,手动替换后,不关闭CAD再打开这个图纸时,就不会出现替换框,原理就是CAD有内部暂存的映射表 ,我的发现就是利用这个原理,找到CAD内置函数,主动添加映射,实现与fontalt西文映射的雷同效果...  发表于 2023-3-23 22:13
我这个全球首发大字体映射,采用的CAD内置未公布函数,其他与你类似https://www.douyin.com/video/7098569390710443302  发表于 2023-3-23 22:07
隐藏字体替对话框换貌似是cad2011才开始具备的,cad2010没找到这个选项。  发表于 2021-6-22 23:47

评分

参与人数 4明经币 +4 收起 理由
222808 + 1
yyz639 + 1
tigcat + 1 很给力!
1028695446 + 1 很给力!

查看全部评分

"觉得好,就打赏"
还没有人打赏,支持一下
发表于 2021-3-2 08:57:48 | 显示全部楼层
本帖最后由 afrgrgfdgdgt111 于 2021-3-2 09:04 编辑
print1985 发表于 2021-3-1 18:43
论坛代码高亮有问题
你把第一句:
删掉就可以了

好了  谢谢大佬

评分

参与人数 1明经币 +1 收起 理由
天凉好个秋 + 1

查看全部评分

回复 支持 1 反对 0

使用道具 举报

发表于 2021-4-25 07:08:24 | 显示全部楼层
感谢楼主分享
回复 支持 1 反对 0

使用道具 举报

发表于 2021-2-24 23:12:32 | 显示全部楼层


学习学习了,谢谢分享
回复 支持 0 反对 1

使用道具 举报

发表于 2021-2-24 20:37:03 | 显示全部楼层

学习学习了,谢谢分享
发表于 2021-2-28 12:02:37 | 显示全部楼层
可以的,很不错
发表于 2021-3-1 09:05:26 | 显示全部楼层
赞,学习一下
发表于 2021-3-1 09:37:09 | 显示全部楼层
感谢大佬分享
发表于 2021-3-1 11:29:29 | 显示全部楼层
感谢分享,非常有帮助
发表于 2021-3-1 16:08:56 | 显示全部楼层
这样会修改文字样式,不太好
发表于 2021-3-1 17:17:27 | 显示全部楼层
大佬可以上传个lsp文件吗,我复制的代码加载错误
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2025-1-8 15:08 , Processed in 0.291802 second(s), 34 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表