Printing problem

Hi there,

I'm currently working on a small project for filling in some forms on the computer and then printing the data into the forms blank fields.
Understood Good! ;-)

Well,
I had a hell of a time to align all fields to the right possition. I printed, adjusted, printed, adjusted...
It works now - at least when I print from my computer.

Copying the program to a friends machine, starting it, filling in the fields and then printing results in a total mess.
Not one feeld as where it is, when I print from my computer.

What the hell am I doing wrong

Here my code:

public void ChoosePrinterAndPrint()
{
PrintDocument doc = new PrintDocument();
PrintDialog pDialog = new PrintDialog();
doc.PrintPage +=
new PrintPageEventHandler(doc_PrintPage);

pDialog.Document = doc;
if (pDialog.ShowDialog() == DialogResult.OK)
{
doc.Print();
}
//if
}//ChoosePrinterAndPrint

private void doc_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
Graphics g = e.Graphics;
g.PageUnit =
GraphicsUnit.Millimeter;
string fontName = "Courier New";
int fontSize = 18;
FontStyle fontStyle = FontStyle.Bold;
Font font;
Brush brush = Brushes.Black;

int x = 0;
int y = 0;

StringFormat stringFormat = new StringFormat(StringFormatFlags.DirectionVertical);

int posOfDelimiter;
int wholeLength;

foreach (string key in ControlsXY.Keys)
{
x = Convert.ToInt32(ControlsXY[key].ToString().Substring(0, posOfDelimiter));
y =
Convert.ToInt32(ControlsXY[key].ToString().Substring(++posOfDelimiter));

//Print
g.DrawString(
allControls[key].ToString().ToUpper(),
font,
brush,
x,
y,
stringFormat);

}//foreach

}//doc_PrintPage




Answer this question

Printing problem

  • Musafir

    Thanks for your help,

    I checked those properties before, but since they are read-only, I didn't know how to use them - and still don't.
    Some further help and maybe code would be awesome.

    Btw, I would like to stick to millimeters for the PageUnit, since calucating is the excact position is much easier...

    Thanks,

    Finch.


  • JIM.H.

    Hi,
    Can you give me a detailed description of what you are trying to print , any scanned copy of printout will be extremely helpful. I think I can help you but need to to know the exact problem.



  • LasseJ

    I'm not sure about this, but the problem could be because the use of pixels. I believe that pixels are relative to the viewing device. E.g. your form will also display differently on differend monitors with differend resolutions. You could try to play around with some g.PageUnit settings perhaps

    What you also might want to double check is the page size of the print document. the one system might default it on a4 and the other on letter format perhaps


  • Craig Throne

    You say it is totally messed up on the other computers, but what is messed up, how and what is the difference, can you see a pattern in it

    Can you please provide us more information so we can help you solving this problem.



  • evdberg

    Ok so here is the code snippet that may help you (you'll have to modify it) -

    [DllImport("gdi32")]

    private static extern Int32 GetDeviceCaps(IntPtr hdc, Int32 capindex);

    //Constant margin for left side set it according to your need (in Pixels)

    private const int PHYSICALOFFSETX = 112; 

    //Constant margin for top side set it according to your need (in Pixels)

     private const int PHYSICALOFFSETY = 113;                             

     Now place the following code to your doc_PrintPage() method  -

    //this will provide you with a handle to printer, p is PrintPageEventArgs 

    IntPtr hDC = p.Graphics.GetHdc();            

    dblHardMarginLeft = GetDeviceCaps(hDC , PHYSICALOFFSETX);

    dblHardMarginTop = GetDeviceCaps(hDC , PHYSICALOFFSETY);

     // be 100% sure to release this handle

    p.Graphics.ReleaseHdc(hDC);                

    dblHardMarginLeft = (dblHardMarginLeft*96/p.Graphics.DpiX);           //left margin in inches

    dblHardMarginTop = (dblHardMarginTop*96/p.Graphics.DpiY);          //right margin in inches

    // your paper width and height will be calculated by following code

    dblPaperWidth = (float)((p.PageBounds.Width)-(dblHardMarginLeft*2));

    dblPaperHeight = (float)((p.PageBounds.Height)-(dblHardMarginTop*2));

    furthermore you'll have to subtract these margins (dblHardMarginLeft ,dblHardMarginTop) from your x and y coordinates respectively to get the exact location to start printing.

    Hope this'll be helpful.

    For more help provide me with source code (if possible).

    Sudeep Kaul.

     


  • M j P

    Hi Mark,

    Sorry for delayed reply - it was Diwali weekend here in India. I'll try to make adjustments in your code but I am not sure about the time I may be able to upload it for you. As far as the things you have asked are concerned - i'll soon give you a detailed explanation.


  • sabha

    Mark, I think you should try the DeviceCaps code above. The problem related to inconsistent margin can be solved with that.

    Regarding the use of millimeters - well you can use pixels as specified in the code.  

    :)

    Sudeep

      


  • alwayscnfsd

    You have to the following information for calculation:

    1. PrintPageEventArgs.Graphics.PageUnit, set this to the page unit you want to use (normally pixels).
    2. PrintPageEventArgs.PageBounds, area that represents the total area of the page.
    3. PrintPageEventArgs.MarginBounds, area within the page margins.
    4. PrintPageEventArgs.PageSettings.PrintableArea, the printable area on the page.
    5. PrintPageEventArgs.PageSettings.PrinterResolution, the print resolution for the page.

    It can be a great help to set the PageUnit to GraphicsUnit.Document (1/300 inch) or GraphicsUnit.Point (1/72 inch), because this is resolution independed.



  • larz

    Hi Kaul,

    thanks for your help. I really appreciate it!!!
    Well,
    seems like I'm losing my face over this threat:
    I implemented your code (win32.dll) and could compile. But I'm not quite sure what you mean by "finding the exact x/y locations" and "subtract these margins (dblHardMarginLeft ,dblHardMarginTop) from your x and y coordinates respectively".
    If possible, could you make just one of those adjustments in the downloaded code and upload/send it That would be awesome.

    Greetz,
    Mark.


  • monchhib

    I just downloaded your code and in first site it seems that you just need to find the exact x and y locations - try out what I had suggested it should work.

    Sudeep.


  • JeffS23

    Hi everybody,

    here is some more information...
    The whole project can be downloaded here: [PainReliever.zip]

    First of all about the printouts:
    I don't know why, but it's "not that bad anymore". I tried printing on 3 different computers with 3 different resolutions. 2 were fine, one seems to have bigger top and right margin.
    But it's still not correct, I need it to be correct on EVERY computer... of course.

    I should be able to use Win32 API. At least I can't think of any reason why I shouldn't.

    Hashtable allControls:
    All textbox controls are located on a groupBox. So I use a foreach loop to get all names of the controls and their text.
    string key: Name of the control
    string value: Text typed into the textbox
    Code:
    foreach(Control c in groupBox_TextBoxes.Controls)
    {
    allControls[c.Name] = c.Text;
    }

    Hashtable ControlsXY:
    The x/y coordinates where the text of any textbox is supposed to be printed is saved here.
    string key: Name of the control
    string value: "x/y" (eg: "39/0")

    int posOfDelimiter:
    As you can see, the x/y coordinates are seperated by a slash "/". So I look for this slash and save its positon to this variable.

    int wholeLength:
    I used this previously... but not anymore...
    It's not used anymore, I just forgot to delete it.

    Why I use millimeters:
    Since I'm aligning around 20 fields manually it's easier to measure the distances between each field with a ruler and than keying the x/y coordinates into the code...
    It's one option and since it's easier for me, I just use this.

    Any more information needed
    Since the "error" occures ONLY on other machines with different resolution, I really thing, my dear, I'm not so far off! ;-)
    But what you say make much sense to me...
    But when my colleague changes his resolution to 1024 x 768, the printout is looking fine...

    Thanks,
    Mark.


  • KKaps

    Hi there,

    thanks for helping me. So here it goes:
    That's a scanned copy of the form I'm trying to print in. As you might recognize, it's the arrival/departure card form for Malaysia.
    [ArrivalCard]

    And here a copy of the GUI of my program:
     [GUI]

    And now the description of the problem:
    When I print from my computer, everything is fine. I tried my best to align every
    single field according to its position on the actual card... well, it works good enough.
    When porting the program to other computers, everything is is messed up. Not ONE
    is where it is supposed to be.
    Can I see a pattern
    Well, sort of. Seems like there is a pretty big top-margin.
    Different resolution on the other computers
    Yes!
    But since I'm really aligning EVERY single field, how can this still be a problem

    I hope this is enough for you to be able to support me.
    If not, I can scan in some print-outs, to show you how it looks. Just let me know...

    Greetz,
    Finch82

     

    EDIT: I found the root problem:
    It's the resolution of the computer the program is running on. Mine is 1024 x 768... and the alignment ONLY works on for this resolution.
    Well,
    this is not sufficient at all. Does it mean I have to align everything according to the resolution or is there any other way I can ship around this cliff
    I mean, I've never seen an application which print outcome depends on the resolution on your computer...


  • Ljhopkins

    You are wrong dear, the monitor resolution has nothing to do with the printouts as long as you are not capturing the screen. I think settings recommended by PJ. van de Sande will help you, but it would be better if you can attach the distorted /misaligned printout's scan.

    Actually I am interested in -

    1) What are you printing - meaning are you also printing the tabular format on the page or it's(the tabular format) pre-printed and you are just filling into the squares.

    2)Can you use Win32 APIs

    Also give me details about -

    1) allControls[]

    2) ControlsXYKeys

    3) posOfDelimiter

    4) wholeLength

    Why are you using Millimeters as PageUnit


  • MarkWHarrison

    Nobody!
  • Printing problem