Forum > Beginners

<Solved> TopMargin

(1/1)

Sprek Skik:
Is there a way to make use of TopMargin in this code:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TfrmNoteBook.PrintMemo;var  I, n, Line : Integer; begin  I := 0;  n := 0;  Line := 0 ;  Printer.BeginDoc ;  Printer.Canvas.Font.Name := 'MS Sans Serif';  Printer.Canvas.Font.Size := 10;  Printer.Canvas.Font.Color := clBlack;  for I := 0 to Memo1.Lines.Count - 1 do  begin    if Line = 0 then      for n := 0 to 3 do        begin          Printer.Canvas.TextOut(500, Line, '');          Line := Line + Abs(Printer.Canvas.Font.Height);        end;    Printer.Canvas.TextOut(500, Line, Memo1.Lines[I]);     {Font.Height is calculated as -Font.Size * 72 / Font.PixelsPerInch which returns     a negative number. So Abs() is applied to the Height to make it a non-negative     value}    Line := Line + Abs(Printer.Canvas.Font.Height);    if (Line >= Printer.PageHeight) then      begin        Line := 0;        Printer.NewPage;      end;   end;  Printer.EndDoc;end;
I used a loop to make a margin but using topmargin would be more logical.
Any help would be great I am just beginning and it's difficult to find simple code. It would be better to use TRY with:

With Printer do
TRY
begin

end;
Except

end;
end;

But I don't know enough about error handing so this will do the job for now.

wp:
The first two parameters of the Canvas.TextOut method denote the x and y coordinates of the point where the top/left corner of the text given as third argument is printed. So, when you want to reserve a top margin do not begin drawing at y = 0 but at the value corresponding to the top margin. But note: the pixels on the printer are much denser than on the screen (usually). The printer has properties XDPI and YDPI (dpi = dots per inch) which you can use to convert a given distance to pixels. The following function converts millimeters to pixel count:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function mmToPx(mm: Double; PPI: Integer): Integer;var  inches: Double;begin  inches := mm/25.4;  Result := round(inches * PPI);end; Basically you can use the PageSetupDialog's MarginLeft/Top/Right/Bottom values here which are displayed as millimeters on my system; looking at it with the debugger, however, I saw that the actually returned values are millimeters multiplied by 100. And there is a property Units (pmDefault, pmMillimeters, pmInches) which suggests that there may be more complicated cases in general - I did not investigate this.

Find in the attachment a small project which prints a memo and uses the PageSetupDialog's margins. It is a bit special (and thus more complicated) because it automatically tries to wordwrap the lines of the memo, certainly not perfect in all cases, but good enough for the demo's dummy text.

Sprek Skik:

--- Quote from: wp on May 20, 2024, 06:14:45 pm ---The first two parameters of the Canvas.TextOut method denote the x and y coordinates of the point where the top/left corner of the text given as third argument is printed. So, when you want to reserve a top margin do not begin drawing at y = 0 but at the value corresponding to the top margin. But note: the pixels on the printer are much denser than on the screen (usually). The printer has properties XDPI and YDPI (dpi = dots per inch) which you can use to convert a given distance to pixels. The following function converts millimeters to pixel count:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function mmToPx(mm: Double; PPI: Integer): Integer;var  inches: Double;begin  inches := mm/25.4;  Result := round(inches * PPI);end; Basically you can use the PageSetupDialog's MarginLeft/Top/Right/Bottom values here which are displayed as millimeters on my system; looking at it with the debugger, however, I saw that the actually returned values are millimeters multiplied by 100. And there is a property Units (pmDefault, pmMillimeters, pmInches) which suggests that there may be more complicated cases in general - I did not investigate this.

Find in the attachment a small project which prints a memo and uses the PageSetupDialog's margins. It is a bit special (and thus more complicated) because it automatically tries to wordwrap the lines of the memo, certainly not perfect in all cases, but good enough for the demo's dummy text.

--- End quote ---

Wow that some example it need some study. Thanks it's a difficult subject. I thought that there were simple instructions to make TopMargin work but thank you for the function it should make it more simple....

wp:
Maybe my example is too difficult to get started... (and, btw, it contains an error in calculation of the maximum horizontal and vertical print positions). Here is a simpler project without wordbreak. It reads the names of the files in the Windows (root) directory and displays them in the memo. The names are rather short and word-break is not needed if the memo is sufficiently wide. I added lots of comments to explain what is happening.