print1985 发表于 2021-2-24 20:28:27

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

本帖最后由 print1985 于 2021-3-2 16:06 编辑


开图不停的替换字体,囧 囧 囧受够了,干掉这个讨厌的对话框,自动替换未知字体
http://bbs.xdcad.net/data/attachment/forum/202102/24/201030ztsz5brsccvlpiis.png.thumb.jpg

1、Lisp文件这里要修改为你想要的字体。
http://bbs.xdcad.net/data/attachment/forum/202102/24/201015r66617sdl1k1vkfk.png.thumb.jpg

2、CAD菜单-工具-选项-系统-隐藏消息设置
http://bbs.xdcad.net/data/attachment/forum/202102/24/201121dmgh9j9eemeh9973.png.thumb.jpg

3、勾选如下图
http://bbs.xdcad.net/data/attachment/forum/202102/24/201525siselx2e7lqi7ebs.png.thumb.jpg

4、打开缺少字体的图纸,如图勾选“始终执行……”,后点击“忽略缺少的……”
http://bbs.xdcad.net/data/attachment/forum/202102/24/201138izvkhe87e8iu0ryr.png.thumb.jpg

搞定,以后开图不会出现选择字体对话框了,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

http://bbs.xdcad.net/data/attachment/forum/202103/02/160132d33112hbgpovhthg.gif

修改后的C#源码如下
using System.Text;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using System.Runtime.InteropServices;
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("自动替换字体结束");
      }
      public void addEvents()
      {
            //把事件处理函数与相应的事件进行连接
            CreatNew.DocumentCreateStarted += new DocumentCollectionEventHandler(documentCreateStarted);
            CreatNew.DocumentCreated += new DocumentCollectionEventHandler(documentCreated);
      }
      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声明
      
      public static extern int EnumWindows(CallBack x, int y);

      //枚举子窗体
      public static extern bool EnumChildWindows(int hwndParent, CallBack EnumFunc, int lParam);

      //找指定窗体
      private static extern int FindWindow(string lpClassName, string lpWindowName);

      
      public static extern int GetWindowText(int hwnd, StringBuilder lptrString, int nMaxCount);

      
      public static extern int IsWindowVisible(int hwnd);
      
      public static extern void GetClassName(int hwnd, StringBuilder s, int nMaxCount);


      
      public static extern int SendMessage(int hwnd, int msg, int wParam, int lParam);

      
      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(60);//用来存放窗口标题 原版为20 现改为用60个字符-CAD高版本要多一些内存才行
            for (int i = 0; i <= ListCount - 1; i++)
            {
                //设定某项来比较
                SendMessage(hwnd, LB_SETCURSEL, i, 0);
                SendMessage(hwnd, WM_GETTEXT, strshx.Capacity, strshx);
                //if (strshx.ToString() == "hztxt.shx|1|0000000") //原版代码
                if (strshx.ToString().Substring(0, 9) == "hztxt.shx")
                {
                  //MessageBox.Show(strshx.ToString());
                  //得到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();
            }
      }

    }
}


afrgrgfdgdgt111 发表于 2021-3-2 08:57:48

本帖最后由 afrgrgfdgdgt111 于 2021-3-2 09:04 编辑

print1985 发表于 2021-3-1 18:43
论坛代码高亮有问题
你把第一句:
删掉就可以了
好了谢谢大佬

999999 发表于 2021-4-25 07:08:24

感谢楼主分享

paulpipi 发表于 2021-2-24 23:12:32



学习学习了,谢谢分享

xj6019 发表于 2021-2-24 20:37:03


学习学习了,谢谢分享

-Yang- 发表于 2021-2-24 20:43:04

棒棒棒棒!

nijiea123 发表于 2021-2-28 12:02:37

可以的,很不错

海盗曹 发表于 2021-3-1 09:05:26

赞,学习一下

afrgrgfdgdgt111 发表于 2021-3-1 09:37:09

感谢大佬分享

Yruz 发表于 2021-3-1 11:29:29

感谢分享,非常有帮助

ljfzx 发表于 2021-3-1 16:08:56

这样会修改文字样式,不太好

afrgrgfdgdgt111 发表于 2021-3-1 17:17:27

大佬可以上传个lsp文件吗,我复制的代码加载错误
页: [1] 2 3 4 5 6 7
查看完整版本: 干掉选择字体对话框,开图自动替换字体(2021.3.2增加c#版本)