0

アラビア語をレシートプリンターに印刷するPOSアプリケーションを構築しています。Lprinter クラスを使用して、印刷コマンドをプリンターに送信しました。私の問題は、アラビア語をプリンターに直接印刷できないことです。そのため、複数の回避策と検索の後、プリンターでアラビア語を印刷する方法を見つけました。最初に、変更した Lprinter クラスにいくつかの変更を加えました

 CharSet.Ansi

CharSet.Auto

また、印刷方法をコピーして に変更Marshal.StringToCoTaskMemAnsiしましたMarshal.StringToCoTaskMemUni。したがって、アラビア語を印刷するときは、新しいメソッドを呼び出します。

これは実際に私のために働いています。現在、プリンターに送信するために、アラビア語のテキストを 16 進数に変換しようとしています。

私は次のことを試しました:

 byte[] bytes1 = Encoding.UTF8.GetBytes("ا");
        Array.Reverse(bytes1);
        var hexString = BitConverter.ToString(bytes1);
        hexString = hexString.Replace("-", "");


        MyPrinter.PrintAr(hexString);

ただし、\x を挿入して、これがテキストではなく 16 進数であることをプリンターが識別できるようにすることができなかったため、実際の 16 進数を取得します。参考までに、私が送信するとき

MyPrinter.PrintAr("\xFEEF\xFE8F\xFEA3");

実際にアラビア語を印刷します。

アラビア語のテキストを 16 進数に正確に変換し、各 16 進数の前に \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;
    }


}
4

0 に答える 0