|
14.04.2015, 12:43 | #1 |
Участник
|
Поддержка unicode при печати на принтер
Вот здесь есть код, который позволяет напечатать какой-то текст на выбранный принтер (Zebra printer - это для чего мы используем этот код)
http://read.pudn.com/downloads153/so...elper.cs__.htm По этой ссылке кто-то обновил код, чтобы название принтера поддерживало unicode, но сам текст для печати - ANSI Кто из наших WinAPI экспертов может помочь сделать, чтобы все поддерживало unicode? Моя первая попытка успехом не увенчалась, потому что (это я так думаю) dwCount = szString.Length; pBytes = Marshal.StringToCoTaskMemUni(szString); размер dwCount меньше чем надо (не для юникода, возможно), поэтому в напечатанном меньше символов чем посылалось на печать |
|
14.04.2015, 13:21 | #2 |
Участник
|
У вас же код пишет в принтер байты. В этом случае, мне кажется, имеет смысл использовать что-нить вроде System.Text.UnicodeEncoding.GetByteCount(String) для подсчета байтов плюс GetBytes() оттуда же для получения массива байтов для строки.
Последний раз редактировалось gl00mie; 14.04.2015 в 13:23. |
|
14.04.2015, 15:23 | #3 |
Участник
|
Сюда запощу код на всякий случай, а то говорят с той ссылкой что-то не так
X++: using System; using System.IO; using System.Drawing.Printing; using System.Runtime.InteropServices; using System.Windows.Forms; namespace Printer { public class RawPrinterHelper { [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct DOCINFOW { [MarshalAs(UnmanagedType.LPWStr)] public string pDocName; [MarshalAs(UnmanagedType.LPWStr)] public string pOutputFile; [MarshalAs(UnmanagedType.LPWStr)] public string pDataType; } [DllImport("winspool.Drv", EntryPoint = "OpenPrinterW", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)] public static extern bool OpenPrinter(string src, ref IntPtr hPrinter, int pd); [DllImport("winspool.Drv", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)] public static extern bool ClosePrinter(IntPtr hPrinter); [DllImport("winspool.Drv", EntryPoint = "StartDocPrinterW", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)] public static extern bool StartDocPrinter(IntPtr hPrinter, int level, ref RawPrinterHelper.DOCINFOW pDI); [DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern bool EndDocPrinter(IntPtr hPrinter); [DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern bool StartPagePrinter(IntPtr hPrinter); [DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern bool EndPagePrinter(IntPtr hPrinter); [DllImport("winspool.Drv", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)] public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, int dwCount, ref int dwWritten); public static bool SendBytesToPrinter(string szPrinterName, IntPtr pBytes, Int32 dwCount) { IntPtr hPrinter = System.IntPtr.Zero; Int32 dwError; DOCINFOW di = new DOCINFOW(); Int32 dwWritten = 0; bool bSuccess; di.pDocName = "My Document"; di.pDataType = "RAW"; bSuccess = false; if (OpenPrinter(szPrinterName, ref hPrinter, (int)0)) { if (StartDocPrinter(hPrinter, 1, ref di)) { if (StartPagePrinter(hPrinter)) { bSuccess = WritePrinter(hPrinter, pBytes, dwCount, ref dwWritten); EndPagePrinter(hPrinter); } EndDocPrinter(hPrinter); } ClosePrinter(hPrinter); } if (bSuccess == false) { dwError = Marshal.GetLastWin32Error(); } return bSuccess; } public static bool SendFileToPrinter(string szPrinterName, string szFileName) { FileStream stream1 = new FileStream(szFileName, FileMode.Open); BinaryReader reader1 = new BinaryReader(stream1); byte[] buffer1 = new byte[((int)stream1.Length) + 1]; buffer1 = reader1.ReadBytes((int)stream1.Length); IntPtr ptr1 = Marshal.AllocCoTaskMem((int)stream1.Length); Marshal.Copy(buffer1, 0, ptr1, (int)stream1.Length); bool flag1 = RawPrinterHelper.SendBytesToPrinter(szPrinterName, ptr1, (int)stream1.Length); Marshal.FreeCoTaskMem(ptr1); return flag1; } public static void SendStringToPrinter(string szPrinterName, string szString) { IntPtr pBytes; Int32 dwCount; dwCount = szString.Length; pBytes = Marshal.StringToCoTaskMemAnsi(szString); MessageBox.Show(pBytes.ToString()); SendBytesToPrinter(szPrinterName, pBytes, dwCount); Marshal.FreeCoTaskMem(pBytes); } } } |
|
13.03.2018, 11:50 | #4 |
Участник
|
Может кто нибудь уже делал это в аксапте, с использованием только X++ и DllFunction (без использования сторонних библиотек) и может поделится кодом ?
Стоит задача прямой печати в принтер Zebra через usb командами EPL/ZPL... Код C# - работает, но не хотелось бы использовать библиотеки dll которые придется копировать на каждого клиента... |
|
13.03.2018, 12:30 | #5 |
Участник
|
Цитата:
|
|
|
За это сообщение автора поблагодарили: Logger (1). |
13.06.2018, 15:09 | #6 |
Участник
|
Написал в итоге скрипт (без использования сторонних библиотек, только WinApi) который позволяет из кода Ax печатать командами ZPL/EPL напрямую в принтер этикеток (ZEBRA например) через драйвер принтера без использования COM порта (через порт USB например)
X++: static void Job364(Args _args) { int g; Binary DOC_INFO_1; Binary bytes; Binary hPrinter = new Binary(260); Binary printerNamePtr = new Binary(260); Binary pcWritten; int i; int v; DLL winSpool = new DLL('WINSPOOL.DRV'); DLLFunction openPrinter = new DLLFunction(winSpool,'OpenPrinterA'); DLLFunction closePrinter = new DLLFunction(winSpool,'ClosePrinter'); DLLFunction startDocPrinter = new DLLFunction(winSpool,'StartDocPrinterA'); DLLFunction endDocPrinter = new DLLFunction(winSpool,'EndDocPrinter'); DLLFunction startPagePrinter = new DLLFunction(winSpool,'StartPagePrinter'); DLLFunction endPagePrinter = new DLLFunction(winSpool,'EndPagePrinter'); DLLFunction writePrinter = new DLLFunction(winSpool,'WritePrinter'); int handle; str printerName = "\\\\itdev2\\ZDesigner ZD410-203dpi ZPL"; // str printerName = "Microsoft XPS Document Writer"; int ok; str txt2print; str err; ; openPrinter.returns(ExtTypes::DWORD); // BOOL OpenPrinter( openPrinter.arg(ExtTypes::Pointer); // LPTSTR pPrinterName, // printer or server name openPrinter.arg(ExtTypes::Pointer); // LPHANDLE phPrinter, // printer or server handle openPrinter.arg(ExtTypes::Pointer); // LPPRINTER_DEFAULTS pDefault) // printer defaults closePrinter.returns(ExtTypes::DWORD); closePrinter.arg(ExtTypes::DWORD); // hPrinter startDocPrinter.returns(ExtTypes::DWORD); startDocPrinter.arg(ExtTypes::DWORD); // hPrinter startDocPrinter.arg(ExtTypes::DWORD); // Level startDocPrinter.arg(ExtTypes::Pointer); // LPBYTE pDocInfo endDocPrinter.returns(ExtTypes::DWORD); endDocPrinter.arg(ExtTypes::DWORD); // hPrinter startPagePrinter.returns(ExtTypes::DWORD); startPagePrinter.arg(ExtTypes::DWORD); // hPrinter endPagePrinter.returns(ExtTypes::DWORD); endPagePrinter.arg(ExtTypes::DWORD); // hPrinter writePrinter.returns(ExtTypes::DWORD); writePrinter.arg(ExtTypes::DWORD); // _In_ HANDLE hPrinter, writePrinter.arg(ExtTypes::Pointer); // _In_ LPVOID pBuf, writePrinter.arg(ExtTypes::DWORD); // _In_ cbBuf, writePrinter.arg(ExtTypes::Pointer); // _Out_ LPDWORD pcWritten DOC_INFO_1 = new Binary(16); txt2print = @' N US D10 ZT Q240,24 q456 R08,08 TDdd.mn.y4 A10,0,0,a,1,1,N,"Name Название" A10,27,0,a,1,1,N,"Name2 Товара" A10,50,0,b,1,1,N,"TransRefId ссылка" A200,50,0,b,1,1,N,"Кол-во " A235,140,0,c,1,1,N,"ManufacId-Тра" B10,110,0,1,2,4,75,B,"12121212" P1 ' ; printerNamePtr.string(0, printerName); ok = openPrinter.call(printerNamePtr, hPrinter, 0); if (ok != 1) { throw error(strFmt("Can not open printer '%1'", printerName)); } handle = hPrinter.dWord(0); for (g = 1; g <= 3; g++) { ok = startDocPrinter.call(handle, 1, DOC_INFO_1); if (ok == 0) { err = WinApi::formatMessage(winapi::getLastError()); closePrinter.call(handle); throw error(err); } ok = startPagePrinter.call(handle); if (ok == 0) { err = WinApi::formatMessage(winapi::getLastError()); endDocPrinter.call(handle); closePrinter.call(handle); throw error(err); } pcWritten = new Binary(8); bytes = new Binary(strLen(txt2print) + 2); bytes.string(0, txt2print); ok = writePrinter.call(handle, bytes, strLen(txt2print), pcWritten); if (ok == 0) { err = WinApi::formatMessage(winapi::getLastError()); endPagePrinter.call(handle); endDocPrinter.call(handle); closePrinter.call(handle); throw error(err); } ok = endPagePrinter.call(handle); ok = endDocPrinter.call(Handle); } closePrinter.call(handle); } |
|
|
Похожие темы | ||||
Тема | Ответов | |||
Основной принтер . Ах 2009 | 3 | |||
Infolog при печати отчета | 9 | |||
Активность пиктограммы печати | 2 | |||
Очередь печати документов | 3 | |||
Откуда фактура_RU берет количество для печати | 2 |
|