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 và 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.
(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;
}
}
(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 }
};
}
}
(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;
}
}
}
(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 vnconv.dll: https://www.mediafire.com/file/4mf3emy5vcod4f2/vnconv.dll/file
Link tải OpenSource
---------------------------------------------------------------------------------------------
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