Thứ Ba, 27 tháng 8, 2024

Mã code c# chuyển mã font Tiếng Việt | Sử dụng mã nguồn từ UVConverter

Ứng dụng được phát triển bởi đội ngũ AutoLISP Thật là đơn giản
   

Thông tin thêm: 👉👉👉

Vấn đề bảng mã

Unicode trong c# có vẻ khá nhàm chán.

Tuy nhiên, chuyển bảng mã thì vẫn chưa có một công cụ nào hoàn thiện, chia sẻ rộng rãi. 

Mã nguồn UVCONVERTER C++

Link tải mã nguồn UniKey Source Code | UniKey

Trên Unikey.org có chia sẻ code converter, tuy nhiên, được viết hoàn toàn bằng c++

Vậy đâu là giải pháp hoàn chỉnh cho vấn đề Chuyển bảng mã với dotNet?!

Kết hợp C++ và C#

C++ và C# có thể liên kết với nhau bằng các giao thức DllExport DllImport. Thông tin thêm.

Từ đó, AJS đã phát triển, điều chỉnh lại một số mã code để giúp người dùng C# có thể tiếp cận, tận dụng các mã nguồn mở từ C++.

Cách sử dụng

Tạo dự án mới.

Sử dụng DllImport để nhập các hàm từ dự án.


1 Chỉnh sửa tệp tin Charset.cs để thêm các mã bảng mã

(Copy nội dung sau)
Code:
namespace AJS_VnConvert
{
    public static class Charset
    {
        //Edit by AJS Team from www.lisp.vn
        public const int CONV_CHARSET_UNICODE = 0;

        public const int CONV_CHARSET_UNIUTF8 = 1;
        public const int CONV_CHARSET_UNIREF = 2; //&#D;
        public const int CONV_CHARSET_UNIREF_HEX = 3;
        public const int CONV_CHARSET_UNIDECOMPOSED = 4;
        public const int CONV_CHARSET_WINCP1258 = 5;
        public const int CONV_CHARSET_UNI_CSTRING = 6;

        public const int CONV_CHARSET_VIQR = 10;
        public const int CONV_CHARSET_UTF8VIQR = 11;

        public const int CONV_CHARSET_TCVN3 = 20;
        public const int CONV_CHARSET_VPS = 21;
        public const int CONV_CHARSET_VISCII = 22;
        public const int CONV_CHARSET_BKHCM1 = 23;
        public const int CONV_CHARSET_VIETWAREF = 24;
        public const int CONV_CHARSET_ISC = 25;

        public const int CONV_CHARSET_VNIWIN = 40;
        public const int CONV_CHARSET_BKHCM2 = 41;
        public const int CONV_CHARSET_VIETWAREX = 42;
        public const int CONV_CHARSET_VNIMAC = 43;
    }
}

2 Chỉnh sửa tệp tin CharsetIdMap.cs 

(Copy nội dung sau)
Code:
namespace AJS_VnConvert
{
    public class CharsetNameId
    {
        public string Name { get; set; }
        public int Id { get; set; }
    }

    public static class CharsetIdMap
    {

        //Edit by AJS Team from www.lisp.vn
        public static readonly CharsetNameId[] CharsetIdMapArray = new CharsetNameId[]
        {
            new CharsetNameId { Name = "BKHCM1", Id = Charset.CONV_CHARSET_BKHCM1 },
            new CharsetNameId { Name = "BKHCM2", Id = Charset.CONV_CHARSET_BKHCM2 },
            new CharsetNameId { Name = "ISC", Id = Charset.CONV_CHARSET_ISC },
            new CharsetNameId { Name = "NCR-DEC", Id = Charset.CONV_CHARSET_UNIREF },
            new CharsetNameId { Name = "NCR-HEX", Id = Charset.CONV_CHARSET_UNIREF_HEX },
            new CharsetNameId { Name = "TCVN3", Id = Charset.CONV_CHARSET_TCVN3 },
            new CharsetNameId { Name = "UNI-COMP", Id = Charset.CONV_CHARSET_UNIDECOMPOSED },
            new CharsetNameId { Name = "UNICODE", Id = Charset.CONV_CHARSET_UNICODE },
            new CharsetNameId { Name = "UTF-8", Id = Charset.CONV_CHARSET_UNIUTF8 },
            new CharsetNameId { Name = "UTF8", Id = Charset.CONV_CHARSET_UNIUTF8 },
            new CharsetNameId { Name = "UVIQR", Id = Charset.CONV_CHARSET_UTF8VIQR },
            new CharsetNameId { Name = "VIETWARE-F", Id = Charset.CONV_CHARSET_VIETWAREF },
            new CharsetNameId { Name = "VIETWARE-X", Id = Charset.CONV_CHARSET_VIETWAREX },
            new CharsetNameId { Name = "VIQR", Id = Charset.CONV_CHARSET_VIQR },
            new CharsetNameId { Name = "VISCII", Id = Charset.CONV_CHARSET_VISCII },
            new CharsetNameId { Name = "VNI-MAC", Id = Charset.CONV_CHARSET_VNIMAC },
            new CharsetNameId { Name = "VNI-WIN", Id = Charset.CONV_CHARSET_VNIWIN },
            new CharsetNameId { Name = "VPS", Id = Charset.CONV_CHARSET_VPS },
            new CharsetNameId { Name = "WINCP-1258", Id = Charset.CONV_CHARSET_WINCP1258 }
        };
    }
}

3 Chỉnh sửa tệp tin ImportVnConvertExts.cs để sử dụng chức năng DllImport

(Copy nội dung sau)
Code:
using System.IO;
using System.Runtime.InteropServices;
using System.Text;

namespace AJS_VnConvert
{
    internal static class ImportVnConvertExts
    {
        public const string vnconv = "vnconv.dll";

        [DllImport(vnconv, CallingConvention = CallingConvention.Cdecl)]
        [return: MarshalAs(UnmanagedType.BStr)]
        private static extern string VnConvertString(int inCharset, int outCharset, byte[] input, int inlen);

        public static string ConvertString(this string input, int inCharset, int outCharset)
        {
            byte[] bytes = (inCharset <= 1 ? Encoding.UTF8 : Encoding.Default).GetBytes(input);
            var ret = VnConvertString(inCharset, outCharset, bytes, bytes.Length);
            return ret;
        }

        [DllImport(vnconv, CallingConvention = CallingConvention.Cdecl)]
        public static extern int VnFileConvert(int inCharset, int outCharset, string input, string output);

        public static string ConvertStringUsingFile(this string clipboard, int inCharset, int outCharset)
        {
            var inf = Path.GetTempFileName();
            var outf = Path.GetTempFileName();

            if (inCharset > 1)
                File.WriteAllText(inf, clipboard, Encoding.Default);
            else
                File.WriteAllText(inf, clipboard);

            string str = clipboard;

            VnFileConvert(inCharset, outCharset, inf, outf);

            File.Delete(inf);
            if (File.Exists(outf))
            {
                str = File.ReadAllText(outf, outCharset <= 1 ? Encoding.UTF8 : System.Text.Encoding.Default);
                File.Delete(outf);
            }

            return str;
        }
    }
}


4 Chỉnh sửa tệp tin myCommands.cs có sẵn trong Project (nếu tạo bằng Wizards)

(Copy nội dung sau)
Code:
// (C) Copyright 2024 by
//
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using System.Linq;

// This line is not mandatory, but improves loading performances
[assembly: CommandClass(typeof(AJS_VnConvert.MyCommands))]

namespace AJS_VnConvert
{
    // This class is instantiated by AutoCAD for each document when
    // a command is called by the user the first time in the context
    // of a given document. In other words, non static data in this class
    // is implicitly per-document!
    public class MyCommands
    {
        // Modal Command with localized name
        [CommandMethod("AJSVnConvert", CommandFlags.Modal)]
        public void MyCommand() // This method can have any name
        {
            // Put your command code here
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed;
            if (doc != null)
            {
                ed = doc.Editor;
                ed.WriteMessage("AJS-VNCONVERT from www.lisp.vn");

                foreach (var id in CharsetIdMap.CharsetIdMapArray)
                    ed.WriteMessage("\n" + id.Name + " " + id.Id);

                PromptIntegerOptions pio = new PromptIntegerOptions("\nChọn bảng mã nguồn");
                pio.DefaultValue = 20;
                pio.LowerLimit = CharsetIdMap.CharsetIdMapArray.Min(x => x.Id);
                pio.UpperLimit = CharsetIdMap.CharsetIdMapArray.Max(x => x.Id);
                PromptIntegerResult spir = ed.GetInteger(pio);
                if (spir.Status != PromptStatus.OK || !CharsetIdMap.CharsetIdMapArray.Any(x => x.Id == spir.Value)) return;

                pio = new PromptIntegerOptions("\nChọn bảng mã đích");
                pio.DefaultValue = 1;
                pio.LowerLimit = CharsetIdMap.CharsetIdMapArray.Min(x => x.Id);
                pio.UpperLimit = CharsetIdMap.CharsetIdMapArray.Max(x => x.Id);
                PromptIntegerResult dpir = ed.GetInteger(pio);
                if (dpir.Status != PromptStatus.OK || !CharsetIdMap.CharsetIdMapArray.Any(x => x.Id == dpir.Value)) return;

                if (spir.Value == dpir.Value) return;

                SelectionFilter sf = new SelectionFilter(new TypedValue[] { new TypedValue(0, "*TEXT") });
                PromptSelectionResult psr = ed.GetSelection(sf);
                if (psr.Status != PromptStatus.OK) return;

                using (Transaction tr = doc.Database.TransactionManager.StartTransaction())
                {
                    foreach (SelectedObject so in psr.Value)
                    {
                        DBObject d = tr.GetObject(so.ObjectId, OpenMode.ForWrite);
                        if (d == null) continue;

                        if (d is DBText txt)
                        {
                            string content = txt.TextString;
                            string converted = content.ConvertString(spir.Value, dpir.Value);
                            txt.TextString = converted;
                        }
                        else if (d is MText mtxt)
                        {
                            string content = mtxt.Contents;
                            string converted = content.ConvertString(spir.Value, dpir.Value);
                            mtxt.Contents = converted;
                        }
                    }

                    tr.Commit();
                }

                ed.WriteMessage("AJS-VNCONVERT from www.lisp.vn");
            }
        }
    }
}


Không bắt buộc phải thêm Projects vnconv. Mà ta chỉ cần chép tệp tin vnconv.dll đã được build sẵn.



Link tải OpenSource


---------------------------------------------------------------------------------------------
Ứng dụng được phát triển bởi đội ngũ AutoLISP Thật là đơn giản - Tác giả ứng dụng in D2P

    

Mọi thông tin xin liên hệ Fanpage AutoLISP Thật là đơn giản!
Cảm ơn bạn đã theo dõi!

Không có nhận xét nào:

Đăng nhận xét

Rải block theo Polyline trong AutoCAD | Dim block theo Polyline | Insert block along selected polylines

Ứng dụng được phát triển bởi đội ngũ AutoLISP Thật là đơn giản      Thông tin thêm: 👉👉👉