File Output and Parallel Printer(LPT1) output is different

  • Thread starter Thread starter Jeff0803
  • Start date Start date
J

Jeff0803

Guest
I made a some sample program to send texts to the LPT1.

1486340.png

I open port and send text using Win32 API.

If open a file and write text, result is OK(written text is exactly the same as I input in the textbox of the sample program).

1486341.png

However, if open LPT1 and send text, result is NG.(As you see below, After "28G", "GRAHAM / DAVID MR" is printed one more time.

1486342.png

Can anybody give me some advice about what is the problem in the code?

Here is the code.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;

namespace ParallelPortTest
{
public partial class Form1 : Form
{

ParallelOutput po;
IntPtr porthandle;
FileStream filestream;
// 1 2 3 4
// 12345678901234567890123456789012345678901
string strTicket = "GRAHAM / DAVID MR " + Environment.NewLine +
" " + Environment.NewLine +
"HEATHROW - LONDON XS 1794 C 25MAR 21:00" + Environment.NewLine +
"FRANKFURT " + Environment.NewLine +
" 28G";
[DllImport("kernel32.dll", SetLastError = true)]
static extern SafeFileHandle CreateFile(string lpFileName, FileAccess dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, FileMode dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile);

public Form1()
{
InitializeComponent();
}

private void bttnSend_Click(object sender, EventArgs e)
{
SendProcAPI();
}
private void SendProcAPI()
{
Encoding mode;

if (string.IsNullOrEmpty(cbParallelPort.Text))
{
MessageBox.Show("Port name is null string!");
return;
}
if (cbEncoding.SelectedIndex == 0)
{
mode = Encoding.ASCII;
}
else if (cbEncoding.SelectedIndex == 1)
{
mode = Encoding.Unicode;
}
else if (cbEncoding.SelectedIndex == 2)
{
mode = Encoding.UTF8;
}
else
{
mode = Encoding.ASCII;
}

if (po.PrintText(this.cbParallelPort.Text, strTicket, Convert.ToInt16(this.tbSendText.Text.Length), mode) == -1)
{
MessageBox.Show("Failed to open parallel port!");
return;
}
}
private void Form1_Load(object sender, EventArgs e)
{
this.tbSendText.Text = strTicket;

}

private void bttn_GetPortName_Click(object sender, EventArgs e)
{
List<string> portnames;
po = new ParallelOutput();
cbParallelPort.Items.Clear();
portnames = po.GetPortNames();
if (portnames == null)
{
MessageBox.Show("Cannot get port names.");
return;
}

foreach (string item in portnames)
{
this.cbParallelPort.Items.Add(item);
}
if (portnames.Count > 0)
{
cbParallelPort.SelectedIndex = 0;
}
}

private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show(this.tbSendText.Text.Length.ToString());
}
}
}

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
using System.ComponentModel;
using System.Windows.Forms;
namespace ParallelPortTest
{
public class ParallelOutput
{
#region Declaration - Enumerate Parallel Ports
//PortType enum
//struct for PORT_INFO_2
[StructLayout(LayoutKind.Sequential)]
public struct PORT_INFO_2
{
public string pPortName;
public string pMonitorName;
public string pDescription;
public PortType fPortType;
internal int Reserved;
}


[Flags]
public enum PortType : int
{
write = 0x1,
read = 0x2,
redirected = 0x4,
net_attached = 0x8
}

//Win32 API
[DllImport("winspool.drv", EntryPoint = "EnumPortsA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
public static extern int EnumPorts(string pName, int Level, IntPtr lpbPorts, int cbBuf, ref int pcbNeeded, ref int pcReturned);
#endregion

#region Declaration - Parallel Port Open/Send/Close
public const short FILE_ATTRIBUTE_NORMAL = 0x80;
public const short INVALID_HANDLE_VALUE = -1;
public const uint GENERIC_READ = 0x80000000;
public const uint GENERIC_WRITE = 0x40000000;
public const uint CREATE_NEW = 1;
public const uint CREATE_ALWAYS = 2;
public const uint OPEN_EXISTING = 3;

[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr CreateFile(string lpFileName, uint dwDesiredAccess,
uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition,
uint dwFlagsAndAttributes, IntPtr hTemplateFile);
#endregion



public ParallelOutput()
{
}
public IntPtr OpenPort(string parallelport)
{
IntPtr ptr = CreateFile(parallelport, GENERIC_WRITE, 0,
IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);

/* Is bad handle? INVALID_HANDLE_VALUE */
if (ptr.ToInt32() == -1)
{
/* ask the framework to marshall the win32 error code to an exception */
// Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
return (IntPtr.Zero);
}
return (ptr);
}
//Port name will be LPT1
public FileStream SendText(IntPtr ptr, String receiptText, Encoding encoding)
{
FileStream lpt = new FileStream(ptr, FileAccess.ReadWrite);
Byte[] buffer = new Byte[2048];
//Check to see if your printer support ASCII encoding or Unicode.
//If unicode is supported, use the following:
if (encoding == Encoding.Unicode)
{
buffer = System.Text.Encoding.Unicode.GetBytes(receiptText);
}
else if (encoding == Encoding.ASCII)
{
buffer = System.Text.Encoding.ASCII.GetBytes(receiptText);
}
lpt.Write(buffer, 0, buffer.Length);
return (lpt);
}
public int PrintText(string parallelport, string receiptText, Int16 nLen, Encoding encoding)
{
int i = 0;
int dy = 0;

//To LPT1
// IntPtr ptr = CreateFile(parallelport, GENERIC_WRITE, 0,
// IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
//To File
IntPtr ptr = CreateFile(@"C:\CSharpSample\ParallelPortTest\bin\Release\result.txt", GENERIC_WRITE, 0,
IntPtr.Zero, CREATE_NEW, 0, IntPtr.Zero);
/* Is bad handle? INVALID_HANDLE_VALUE */
if (ptr.ToInt32() == -1)
{
/* ask the framework to marshall the win32 error code to an exception */
// Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
return (-1);
}

FileStream lpt = new FileStream(ptr, FileAccess.ReadWrite);
Byte[] buffer = new Byte[2048];
Byte[] outbuffer = new Byte[2048];
// Byte[] buffer = new Byte[nLen];
// Byte[] outbuffer = new Byte[nLen];

//Check to see if your printer support ASCII encoding or Unicode.
//If unicode is supported, use the following:
if (encoding == Encoding.Unicode)
{
buffer = System.Text.Encoding.Unicode.GetBytes(receiptText);
}
else if (encoding == Encoding.ASCII)
{
buffer = System.Text.Encoding.ASCII.GetBytes(receiptText);
}
else if (encoding == Encoding.UTF8)
{
buffer = System.Text.Encoding.UTF8.GetBytes(receiptText);
}

for (i = 0; i < buffer.Length/*nLen*/; i++)
{
outbuffer = 0x00;
}
for (i = dy = 0; i < buffer.Length/*nLen*/; i++)
{
if (buffer < 6)
continue;
if (buffer > 31 || buffer == 10 || buffer == 12 || buffer == 13)
outbuffer[dy++] = buffer;
else
outbuffer[dy++] = 0x20;
}
// lpt.Write(buffer, 0, buffer.Length);
lpt.Write(outbuffer, 0, dy);
lpt.Close();
return (0);
}
public void ClosePort(FileStream lpt)
{
lpt.Close();
}

public List<string> GetPortNames()
{
//variables needed for Win32 API calls
int result; int needed = 0; int cnt = 0; IntPtr buffer = IntPtr.Zero; IntPtr port = IntPtr.Zero;

//list to hold the returned port names
List<string> ports = new List<string>();

//new PORT_INFO_2 for holding the ports
PORT_INFO_2[] portInfo = null;

//enumerate through to get the size of the memory we need
result = EnumPorts("", 2, buffer, 0, ref needed, ref cnt);
try
{
//allocate memory
buffer = Marshal.AllocHGlobal(Convert.ToInt32(needed + 1));

//get list of port names
result = EnumPorts("", 2, buffer, needed, ref needed, ref cnt);

//check results, if 0 (zero) then we got an error
if (result != 0)
{
//set port value
port = buffer;

//instantiate struct
portInfo = new PORT_INFO_2[cnt];

//now loop through the returned count populating our array of PORT_INFO_2 objects
for (int i = 0; i < cnt; i++)
{
portInfo = (PORT_INFO_2)Marshal.PtrToStructure(port, typeof(PORT_INFO_2));
port = (IntPtr)(port.ToInt32() + Marshal.SizeOf(typeof(PORT_INFO_2)));
}
port = IntPtr.Zero;
}
else
throw new Win32Exception(Marshal.GetLastWin32Error());

//now get what we want. Loop through al the
//items in the PORT_INFO_2 Array and populate our generic list
for (int i = 0; i < cnt; i++)
{
if (portInfo.pPortName.Length > 3 && portInfo.pPortName.Contains("LPT"))
{
ports.Add(portInfo.pPortName.Replace(":", ""));
}
}

//sort the list
ports.Sort();

return ports;
}
catch (Exception ex)
{
return null;
}
finally
{
if (buffer != IntPtr.Zero)
{
Marshal.FreeHGlobal(buffer);
buffer = IntPtr.Zero;
port = IntPtr.Zero;
}
}

}
}
}

Continue reading...
 
Back
Top