我正在构建POS应用程序,该应用程序将阿拉伯语单词打印到收据打印机中。我使用Lprinter类将打印命令发送到打印机。我的问题是我无法直接在打印机上打印阿拉伯语,因此经过多种解决方法和搜索后,我找到了一种在打印机上打印阿拉伯语的方法。首先,我对我更改的Lprinter类进行了一些修改
CharSet.Ansi
到
CharSet.Auto
我也复制了打印方法,并将Marshal.StringToCoTaskMemAnsi
更改为Marshal.StringToCoTaskMemUni
。所以当我打印阿拉伯语时,我会调用新方法。
这实际上对我有用。现在,我正在尝试将阿拉伯文本转换为十六进制,以便将其发送到打印机。
我尝试了以下操作:
byte[] bytes1 = Encoding.UTF8.GetBytes("ا");
Array.Reverse(bytes1);
var hexString = BitConverter.ToString(bytes1);
hexString = hexString.Replace("-", "");
MyPrinter.PrintAr(hexString);
但是,我得到了实际的十六进制,因为我无法插入\ x来允许打印机识别出它是十六进制而不是文本。 仅供参考,当我发送
MyPrinter.PrintAr("\xFEEF\xFE8F\xFEA3");
它实际上打印阿拉伯语。
对于您如何将阿拉伯文字准确地转换为十六进制然后在每个十六进制之前添加\ x或\ u的帮助,我深表感谢。
下面是修改后的LPrinter类:
class LPrinter
{
// Structure and API declarions:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public class DOCINFOA
{
[MarshalAs(UnmanagedType.LPWStr)] public string pDocName;
[MarshalAs(UnmanagedType.LPWStr)] public string pOutputFile;
[MarshalAs(UnmanagedType.LPWStr)] public string pDataType;
}
[DllImport("winspool.Drv", EntryPoint = "OpenPrinterW", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPWStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd);
[DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool ClosePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "StartDocPrinterW", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di);
[DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool EndDocPrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool StartPagePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool EndPagePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten);
/*=================================================*/
private IntPtr HandlePrinter;
private PrinterSettings ps;
public LPrinter()
{
HandlePrinter = IntPtr.Zero;
ps = new PrinterSettings();
}
public string PrinterName
{
get
{
return ps.PrinterName;
}
set
{
ps.PrinterName = value;
}
}
public bool ChoosePrinter()
{
PrintDialog pd = new PrintDialog();
pd.PrinterSettings = ps;
if (pd.ShowDialog() == DialogResult.OK)
{
ps = pd.PrinterSettings;
return true;
}
else return false;
}
public bool Open(string DocName)
{
// see if printer is already open
if (HandlePrinter != IntPtr.Zero) return false;
// opens the printer
bool risp = OpenPrinter(ps.PrinterName, out HandlePrinter, IntPtr.Zero);
if (risp == false) return false;
// starts a print job
DOCINFOA MyDocInfo = new DOCINFOA();
MyDocInfo.pDocName = DocName;
MyDocInfo.pOutputFile = null;
MyDocInfo.pDataType = "RAW";
if (StartDocPrinter(HandlePrinter, 1, MyDocInfo))
{
StartPagePrinter(HandlePrinter); //starts a page
return true;
}
else return false;
}
public bool Close()
{
if (HandlePrinter == IntPtr.Zero) return false;
if (!EndPagePrinter(HandlePrinter)) return false;
if (!EndDocPrinter(HandlePrinter)) return false;
if (!ClosePrinter(HandlePrinter)) return false;
HandlePrinter = IntPtr.Zero;
return true;
}
public bool Print(string outputstring)
{
if (HandlePrinter == IntPtr.Zero) return false;
//IntPtr buf = Marshal.StringToCoTaskMemAnsi(outputstring);
IntPtr buf = Marshal.StringToCoTaskMemUni(outputstring);
Int32 done = 0;
bool ok = WritePrinter(HandlePrinter, buf, outputstring.Length, out done);
Marshal.FreeCoTaskMem(buf);
if (!ok) return false;
else return true;
}
public bool PrintAr(string outputstring)
{
if (HandlePrinter == IntPtr.Zero) return false;
// IntPtr buf = Marshal.StringToCoTaskMemAnsi(outputstring);
IntPtr buf = Marshal.StringToCoTaskMemUni(outputstring);
Int32 done = 0;
bool ok = WritePrinter(HandlePrinter, buf, outputstring.Length, out done);
Marshal.FreeCoTaskMem(buf);
if (!ok) return false;
else return true;
}
}