Program printing resized images on different OS version - c#

I have a working code, on both the target machine, and my own machine. However, my machine is a W10, and the target is a W7. The code below should draw 5 barcodes on the right half of the page, however, when I use it on the target machine, one of two scenarios happen, depending on how I change the code. If I make the width of the barcode too big, it will go beyond the edge of the page and it will not be readable. If I make the width slightly too small, it resizes the whole barcode, and it becomes to small, again unreadable. I assume that this is a problem with the print drivers in which, they are different for both W10 and W7 (I used the same printer on both machines, same settings as well).
Is there a problem with my code and how do I change it?
private void DocumentDrucker_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
Graphics graphic = e.Graphics;
//SolidBrush brush = new SolidBrush(Color.Black);
Font font = new Font("Courier New", 80, FontStyle.Bold);
Font fontK = new Font("Courier New", 30, FontStyle.Bold);
Font fontKleinst = new Font("Courier New", 15, FontStyle.Bold);
float pageWidth = e.PageSettings.PrintableArea.Width;
float pageHeight = e.PageSettings.PrintableArea.Height;
float fontHeight = font.GetHeight();
int startX = 0;
int startY = 0;
int offsetY = 0;
float imageH = Properties.Resources.pfeilO.Height;
float imageW = Properties.Resources.pfeilO.Width;
graphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
//var imagePoint = new Point(Convert.ToInt32(pageWidth * 0.55), offsetY);
var barcodePoint = new Point(Convert.ToInt32(pageWidth * 0.66), 0);
for (; elemente < ZumDrucken.Items.Count; elemente++)
{
var currentItem = ZumDrucken.Items[elemente];
graphic.DrawString(currentItem.Text.Substring(4, 3), fontK, Brushes.Black, startX, startY +offsetY+20);
graphic.DrawString("Typ:"+currentItem.Text.Substring(0,3), fontKleinst, Brushes.Black, startX, (startY + offsetY + 30+fontK.Height));
graphic.DrawString(currentItem.Text.Substring(7), font, Brushes.Black, (startX+75), startY + offsetY);
var currentImage = Properties.Resources.pfeilU;
bool lastCharIsAOne = currentItem.Text[currentItem.Text.Length - 1] == '1';
if (currentItem.Checked == lastCharIsAOne)
{
currentImage = Properties.Resources.pfeilO;
}
graphic.DrawImage(currentImage, Convert.ToInt32((pageWidth * 0.55)), offsetY+20, imageW, imageH);
b.EncodedImage?.Dispose();
//b.Encode(TYPE.CODE128A, "SBD" + currentItem.Text.Substring(0, 3) + currentItem.Text.Substring(4), Color.Black, Color.Transparent,Convert.ToInt32(pageWidth-50), Convert.ToInt32(pageHeight * 0.151));
b.Encode(TYPE.CODE128A, "SBD" + currentItem.Text.Substring(0, 3) + currentItem.Text.Substring(4), Color.Black, Color.Transparent, 570, 135);
barcodePoint.Y = offsetY;
graphic.DrawImage(b.EncodedImage, barcodePoint);
offsetY = offsetY + 163;
if (offsetY >= pageWidth-120)
{
e.HasMorePages = true;
offsetY = 0;
elemente++;
graphic.Dispose();
b.Dispose();
font.Dispose();
fontK.Dispose();
fontKleinst.Dispose();
return;
}
else
{
e.HasMorePages = false;
}
}
graphic.Dispose();
b.Dispose();
font.Dispose();
fontK.Dispose();
fontKleinst.Dispose();
}
Here is also the code where I set all the margins to 0, and change the paper mode to landscape.
private void Drucken_Click(object sender, EventArgs e)
{
DocumentDrucker.DocumentName = "Dokument";
elemente = 0;
DruckDialog.Document = DocumentDrucker;
DocumentDrucker.DefaultPageSettings.Landscape = true;
DocumentDrucker.DefaultPageSettings.Margins.Top = 0;
DocumentDrucker.DefaultPageSettings.Margins.Left = 0;
DocumentDrucker.DefaultPageSettings.Margins.Right = 0;
DocumentDrucker.DefaultPageSettings.Margins.Bottom = 0;
if (DruckDialog.ShowDialog() == DialogResult.OK)
DocumentDrucker.Print();
}

Related

Printing long receipt

I am trying to print a receipt in my windowsforms application. I have written some test code to run and print lines from 0 to 100. My problem is that it is printing until line 45, and it is not giving any error. I have a thermal printer xPrinter xp-80c, on this printer the max length of the paper is 30cm. And when printing to pdf it is only printing on 1 page.
Can anyone please help here and tell what is wrong.
Thank you in advance.
public static void printNewMethodFromVideoDeleteMeWhenDone()
{
PrintDialog printDialog = new PrintDialog();
PrintDocument printDocument = new PrintDocument();
printDialog.Document = printDocument;
printDocument.PrintPage += printDocument3_PrintPage;
DialogResult result = printDialog.ShowDialog();
if(result == DialogResult.OK)
{
printDocument.Print();
}
}
private static void printDocument3_PrintPage(object sender, PrintPageEventArgs e)
{
try
{
Graphics graphic = e.Graphics;
Font font = new Font("Courier New", 12);
float fontHeight = font.GetHeight();
SolidBrush brush = new SolidBrush(Color.Black);
int startX = 10;
int startY = 10;
int offset = 40;
graphic.DrawString("Welcome to the shop", new Font("Courier New", 16), brush, startX, startY);
for (int i = 0; i < 100; i++)
{
string productDescription = "Some text " + i.ToString().PadRight(30);
string productTotal = string.Format("{0:c}", i.ToString());
string line = productDescription + productTotal;
graphic.DrawString(line, font, new SolidBrush(Color.Black), startX, startY + offset);
offset = offset + (int)fontHeight + 5;
}
offset = offset + 20;
graphic.DrawString("Total To Pay".PadRight(30) + string.Format("{0:c}", 100.ToString()), font, brush, startX, startY + offset);
}
catch(Exception ex)
{
// some code here.
}
}
use your C# programming in loop to build a HTML document and use the webBrowser.Print() function to print. This is much more easier.
Call webBrowser.ShowPrintPreview() to adjust the paper and margin to zero.
create a documentReady event for printing the document after the webBrowser finished rendering the document.
webBrowser.DocumentReady += webBrowser_documentReady;
Here is the sample project that demonstrate the idea: http://www.mediafire.com/file/te2lm9sbfvln7bp/WebBrowserPrinter.zip/file

Printing receipt from the listview

Hi I have a form for pharmacy purchase but the print/confirm button have errors. The error occurs when it is printing. I just found this codes on a tutorial online and I want to use it.
This is the error I got when pdf is printing.
The error is from the float cash = float.Parse(txBCash.Text.Substring(1, 3));
This is the codes
private void btnConfirm_Click(object sender, EventArgs e)
{
PrintDialog printDialog = new PrintDialog();
PrintDocument printDocument = new PrintDocument();
printDialog.Document = printDocument; //add the document to the dialog box...
printDocument.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(CreateReceipt); //add an event handler that will do the printing
//on a till you will not want to ask the user where to print but this is fine for the test envoironment.
DialogResult result = printDialog.ShowDialog();
if (result == DialogResult.OK)
{
printDocument.Print();
}
}
public void CreateReceipt(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
int total = 0;
float cash = float.Parse(txBCash.Text.Substring(1, 3));
float change = 0.00f;
//this prints the reciept
Graphics graphic = e.Graphics;
Font font = new Font("Courier New", 12); //must use a mono spaced font as the spaces need to line up
float fontHeight = font.GetHeight();
int startX = 10;
int startY = 10;
int offset = 40;
graphic.DrawString(" Kwem Drugstore", new Font("Courier New", 18), new SolidBrush(Color.Black), startX, startY);
string top = "Item Name".PadRight(30) + "Price";
graphic.DrawString(top, font, new SolidBrush(Color.Black), startX, startY + offset);
offset = offset + (int)fontHeight; //make the spacing consistent
graphic.DrawString("----------------------------------", font, new SolidBrush(Color.Black), startX, startY + offset);
offset = offset + (int)fontHeight + 5; //make the spacing consistent
float totalprice = 0.00f;
foreach (string item in listViewOrders.Items)
{
//create the string to print on the reciept
string productDescription = item;
string productTotal = item.Substring(item.Length - 6, 6);
float productPrice = float.Parse(item.Substring(item.Length - 5, 5));
//MessageBox.Show(item.Substring(item.Length - 5, 5) + "PROD TOTAL: " + productTotal);
}
change = (cash - totalprice);
//when we have drawn all of the items add the total
offset = offset + 20; //make some room so that the total stands out.
graphic.DrawString("Total to pay ".PadRight(30) + String.Format("{0:c}", totalprice), new Font("Courier New", 12, FontStyle.Bold), new SolidBrush(Color.Black), startX, startY + offset);
offset = offset + 30; //make some room so that the total stands out.
graphic.DrawString("CASH ".PadRight(30) + String.Format("{0:c}", cash), font, new SolidBrush(Color.Black), startX, startY + offset);
offset = offset + 15;
graphic.DrawString("CHANGE ".PadRight(30) + String.Format("{0:c}", change), font, new SolidBrush(Color.Black), startX, startY + offset);
offset = offset + 30; //make some room so that the total stands out.
graphic.DrawString(" Thank-you for your purchase,", font, new SolidBrush(Color.Black), startX, startY + offset);
offset = offset + 15;
graphic.DrawString(" please come back soon!", font, new SolidBrush(Color.Black), startX, startY + offset);
}
}
I don't know if this is correct or if i'm doing it correctly. But please help me resolve this because for our project in our school.
Any type of response is greatly appreciated. Thank you in advance.
Array indexes in C# starts at zero, not at 1. And the second parameter of the Substring method is not the end position but the length of characters to retrieve. So your code asks for 3 characters from the txBCash textbox starting from the second character typed. If you want to get the first three characters then you should write
float cash = float.Parse(txBCash.Text.Substring(0, 3));
But a better approach is through float.TryParse that doesn't trigger an exception when the input is not a valid float. Of course you cannot be sure that your user types just 3 characters in that textbox, so I would remove also the starting and the length limits
float cash = 0.0;
if(!float.TryParse(txBCash.Text, out cash))
MessageBox.Show("Invalid value for cash");

Can rectangle be split in rows and columns?

private void panel1_Paint(object sender, PaintEventArgs e)
{
Pen mypen = default(Pen);
mypen = new Pen(System.Drawing.Color.Red, 3);
mypen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
//For Dash Line in Rectangle
Pen mypen1 = default(Pen);
mypen1 = new Pen(System.Drawing.Color.Blue, 1);
mypen1.DashStyle![enter image description here][2] = System.Drawing.Drawing2D.DashStyle.Dash;
//Pen mypen2 =default(Pen);
//mypen2 = new Pen(System.Drawing.Color.Yellow, 3);
//mypen2.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
//Pen mypen3 = default(Pen);
//mypen3 = new Pen(System.Drawing.Color.Violet, 1);
//mypen3.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
L1 = Rect1LT.X + 5;
T1 = Rect1LT.Y + 5;
W1 = Rect1RB.X - Rect1LT.X;
H1 = Rect1RB.Y - Rect1LT.Y;
e.Graphics.DrawRectangle(mypen, new System.Drawing.Rectangle(L1, T1, W1, H1));
e.Graphics.DrawRectangle(mypen1, new System.Drawing.Rectangle(L1, T1, W1, H1));
e.Graphics.DrawRectangle(Pens.Blue, new System.Drawing.Rectangle(Rect1LT.X, Rect1LT.Y, 10, 10));
e.Graphics.DrawRectangle(Pens.Blue, new System.Drawing.Rectangle(Rect1RT.X, Rect1RT.Y, 10, 10));
e.Graphics.DrawRectangle(Pens.Blue, new System.Drawing.Rectangle(Rect1LB.X, Rect1LB.Y, 10, 10));
e.Graphics.DrawRectangle(Pens.Blue, new System.Drawing.Rectangle(Rect1RB.X, Rect1RB.Y, 10, 10));
e.Graphics.FillRectangle(Brushes.Blue, Rect1LT);
e.Graphics.FillRectangle(Brushes.Blue, Rect1RT);
e.Graphics.FillRectangle(Brushes.Blue, Rect1LB);
e.Graphics.FillRectangle(Brushes.Blue, Rect1RB);
e.Graphics.DrawRectangle(Pens.Blue, new System.Drawing.Rectangle(Rect1T.X, Rect1T.Y, 10, 10));
e.Graphics.DrawRectangle(Pens.Blue, new System.Drawing.Rectangle(Rect1R.X, Rect1R.Y, 10, 10));
e.Graphics.DrawRectangle(Pens.Blue, new System.Drawing.Rectangle(Rect1B.X, Rect1B.Y, 10, 10));
e.Graphics.DrawRectangle(Pens.Blue, new System.Drawing.Rectangle(Rect1L.X, Rect1L.Y, 10, 10));
e.Graphics.FillRectangle(Brushes.Blue, Rect1T);
e.Graphics.FillRectangle(Brushes.Blue, Rect1R);
e.Graphics.FillRectangle(Brushes.Blue, Rect1B);
e.Graphics.FillRectangle(Brushes.Blue, Rect1L);
DataGridView dg1 = new DataGridView();
//while (!exit)
//{
// var time = GetTime();
// Update(time);
// Render(time);
//}
}
I want to Divide Rectangle in Rows and Columns and Size of Rows and Column can be changeable at runtime? and No of Rows and Columns also can be changeable? I don't want to split whole rectangle I just want to divide them in rectangle.
Here is a simplfied example:
int cols = 7; int rows = 11;
private void panel1_Paint(object sender, PaintEventArgs e)
{
Rectangle Rect = // your Rectangle!
Rectangle pRect = Rect; // panel2.ClientRectangle;
float width = 1f * pRect.Width / cols;
float height = 1f * pRect.Height / rows;
using (Pen pen = new Pen(System.Drawing.Color.Blue, 1))
{
pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
for (int c = 0; c < cols; c++)
for (int r = 0; r < rows; r++)
{
RectangleF rect = new RectangleF(pRect.X + c * width, pRect.Y + r * height,
width, height);
e.Graphics.FillRectangle(Brushes.Coral, rect);
// e.Graphics.DrawRectangle(pen, rect.X, rect.Y, rect.Width, rect.Height);
}
for (int c = 0; c < cols; c++) e.Graphics.DrawLine(pen,
pRect.X + c * width, pRect.Y, pRect.X + c * width, pRect.Y + pRect.Height);
for (int r = 0; r < rows; r++) e.Graphics.DrawLine(pen,
pRect.X, pRect.Y + r * height, pRect.X + pRect.Width, pRect.Y + r * height);
e.Graphics.DrawRectangle(Pens.Red,
pRect.X, pRect.Y, pRect.Width - 1, pRect.Height - 1);
}
}
Note a few changes:
The border color and the fill color must not be the same.
The fill must come first or it will overwrite the border
I work with floats to fill the panel completely; if the cols and rows don't divide into the panel/rectangle size evenly, the recangles will not all have the same sizes ..
At first I have ignored your DashStyle. If you want to have a DashStyle you must completely change your plan! The reason is that if you draw Rectangles in a grid you..
..either have them overlapping and then the dashes will get in each others way. There is a DashOffset parameter but I don't think it can be twisted to make it work over any grid.
..or you need to draw the rectangles inside the grid cells but then they will be twice a thick and the patterns still will disturb each other.
Instead you simply draw only a few lines as shown!
Here is my example with Dashes:

Printing all controls in a winform c# using PrintDocument

I got a windows form which has more than one page of mainly labels and textboxes, I'm trying to keep the font that i have in the winform already, so far I'm able to print the first page, but when i try to add the rest of the controls it does all sort of weird stuff this is the part of my code where i'm putting everything to print but not all the controls in the panel show in the print preview. So i found out that the controls in the panel are not in order and what i need to do is create the number of printing pages first then put the controls in those printing pages. any help on trying to create the print pages first to add the controls to it. it will always be 4 print pages.
int mainCount = 0;
public void printStuff(System.Drawing.Printing.PrintPageEventArgs e)
{
Font printFont = new Font("Arial", 9);
int dgX = dataGridView1.Left;
int dgY = dataGridView1.Top += 22;
double linesPerPage = 0;
float yPos = 0;
int count = 0;
float leftMargin = e.MarginBounds.Left;
float topMargin = e.MarginBounds.Top;
float bottomMargin = e.MarginBounds.Bottom;
StringFormat str = new StringFormat();
linesPerPage = e.MarginBounds.Height / printFont.GetHeight(e.Graphics);
Control ctrl;
while ((count < linesPerPage) && (panel1.Controls.Count != mainCount))
{
ctrl = panel1.Controls[mainCount];
yPos = topMargin + (count * printFont.GetHeight(e.Graphics));
mainCount++;
count++;
if (ctrl is Label)
{
e.Graphics.DrawString(ctrl.Text, printFont, Brushes.Black, ctrl.Left + 5, ctrl.Top + 40);
}
else if (ctrl is TextBox)
{
e.Graphics.DrawString(ctrl.Text, printFont, Brushes.Black, ctrl.Left + 5, ctrl.Top + 40);
e.Graphics.DrawRectangle(Pens.Black, ctrl.Left, ctrl.Top + 40, ctrl.Width, ctrl.Height);
}
}
if (count > linesPerPage)
{
e.HasMorePages = true;
}
else
{
e.HasMorePages = false;
}
}
//Print
private void exportFileToolStripMenuItem_Click(object sender, EventArgs e)
{
printPreviewDialog1.Document = printDocument1;
printPreviewDialog1.ShowDialog();
}
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
printStuff(e);
}
It seems to me that the problem is that on subsequent pages you are not subtracting the "page offset" form the control Top positions when printing. You are essentially trying to use the screen coordinates of the controls when placing them on the printed page which obviously only works correctly for the first page. On subsequent pages you need to map the screen coordinates by subtracting a quantity which is the equivalent of the "total-printed-surface-so-far"..
You will want to modify this line for instance:
e.Graphics.DrawString(ctrl.Text, printFont, Brushes.Black, ctrl.Left + 5, ctrl.Top + 40);
to something like this:
e.Graphics.DrawString(ctrl.Text, printFont, Brushes.Black, ctrl.Left + 5, ctrl.Top + 40 - pageOffset);
where the pageOffset is a variable that should be computed for each page, based on the Height of the printable area: pageOffset = currentPageNumber * heightOfPrintableArea so you will also need to maintain a variable for the number of pages printed, similar to the mainCount
Of course, the same would apply to the other branch of your if statement:
e.Graphics.DrawString(ctrl.Text, printFont, Brushes.Black, ctrl.Left + 5, ctrl.Top + 40 - pageOffset);
e.Graphics.DrawRectangle(Pens.Black, ctrl.Left, ctrl.Top + 40 - pageOffset, ctrl.Width, ctrl.Height);

Datagridview painting and Scroll effect on it

Hey frenz, In my project I merged rows with cell painting. It works fine. but when i use scroll bar it gives random output. i.e. Data on that merged cell goes to header of the datagrid view. so any solution . The code is as follows:
private void Daywisegrid_Paint(object sender, PaintEventArgs e)
{
for (int k = 0; k < BranchIndex.Count; k++)
{
Font fnt = new Font("Arial", 10, FontStyle.Bold, GraphicsUnit.Point);
Rectangle rct1 = new Rectangle((Daywisegrid.GetColumnDisplayRectangle(0, true).X),
(Daywisegrid.GetColumnDisplayRectangle(0, true).Y),
Daywisegrid.GetColumnDisplayRectangle(0, true).Width - 1,
(Daywisegrid.GetRowDisplayRectangle((Daywisegrid.Rows.Count - 1), true).Top -
Daywisegrid.GetRowDisplayRectangle((Daywisegrid.Rows.Count - 1), true).Height));
Rectangle rct = Daywisegrid.GetRowDisplayRectangle(Convert.ToInt32(BranchIndex[k]), true);
rct.Height -= 1;
SizeF s = e.Graphics.MeasureString("Branch", Daywisegrid.Font);
float lefts = (rct.Width / 2) - (s.Width / 2);
float tops = rct.Top+((rct.Height/2)-(s.Height / 2));
e.Graphics.FillRectangle(Brushes.White, rct);
e.Graphics.DrawString(BranchName[k].ToString(), fnt, Brushes.Black,0, tops);
}
}

Categories