HTML/CSS: Printing page in letter size

PHOTO EMBED

Mon Aug 29 2022 15:57:19 GMT+0000 (Coordinated Universal Time)

Saved by @marcopinero #css #html

<html moznomarginboxes mozdisallowselectionprint>
<head>
<!--style type="text/css">

@page { size: auto;  margin: 0mm; }
@media print {  
  body { margin: 1.6cm; margin-top:0;}
}
.header, .header-space,
.footer, .footer-space {
  height: 50px;
}
.header {
  position: fixed;
  top: 0;
  padding-top:20px;
}
.footer {
  position: fixed;
  bottom: 0;
}
.content{
  width: 7.2in;
}
</style-->
<style type="text/css">
@page { margin: 0 }
body { margin: 2cm; margin-top:0; }
.sheet {
  margin: 0;
  overflow: hidden;
  position: relative;
  box-sizing: border-box;
  page-break-after: always;
}

/** Paper sizes **/
body.A3               .sheet { width: 297mm; height: 419mm }
body.A3.landscape     .sheet { width: 420mm; height: 296mm }
body.A4               .sheet { width: 210mm; height: 296mm }
body.A4.landscape     .sheet { width: 297mm; height: 209mm }
body.A5               .sheet { width: 148mm; height: 209mm }
body.A5.landscape     .sheet { width: 210mm; height: 147mm }
body.letter           .sheet { width: 216mm; height: 279mm }
body.letter.landscape .sheet { width: 280mm; height: 215mm }
body.legal            .sheet { width: 216mm; height: 356mm }
body.legal.landscape  .sheet { width: 357mm; height: 215mm }

/** Padding area **/
.sheet.padding-10mm { padding: 10mm }
.sheet.padding-15mm { padding: 15mm }
.sheet.padding-20mm { padding: 20mm }
.sheet.padding-25mm { padding: 25mm }

/** For screen preview **/
@media screen {
  body { background: #e0e0e0 }
  .sheet {
    background: white;
    box-shadow: 0 .5mm 2mm rgba(0,0,0,.3);
    margin: 5mm auto;
  }
}

/** Fix for Chrome issue #273306 **/
@media print {
           body.A3.landscape { width: 420mm }
  body.A3, body.A4.landscape { width: 297mm }
  body.A4, body.A5.landscape { width: 210mm }
  body.A5                    { width: 148mm }
  body.letter, body.legal    { width: 216mm }
  body.letter.landscape      { width: 280mm }
  body.legal.landscape       { width: 357mm }
}

@page { size: letter }




.header, .header-space,
.footer, .footer-space {
  height: 50px;
}
.header {
  position: fixed;
  top: 0;
  padding-top:20px;
}
.footer {
  position: fixed;
  bottom: 0;
}
.content{
  width: 7.5in;
}

</style>

</head>
<body class="letter">
<table>
  <thead><tr><td>
    <div class="header-space"> </div>
  </td></tr></thead>
  <tbody><tr><td>
    <div class="content">
      
      BorderStyle := bsnone;
WindowState := wsMaximized;
I set these properties to make both of them full screen. In the main form there is a button and when I click I want to show the second form as full screen with slide animation so I used this code:

AnimateWindow(form2.Handle, 500, AW_ACTIVATE OR AW_SLIDE OR AW_HOR_NEGATIVE);
Form2 is in auto create and visible property is set to false.

The problem when I tried this I saw odd results, the animation play but the form2 appear without any controls and not covering the full screen.

How to fix that so I can display form2 as full screen with slide animation ?

I am using XE5

delphi
shareimprove this question
edited Feb 24 '15 at 2:40
asked Feb 24 '15 at 2:23

Wel
1,52663378
add a comment
3 Answers
active oldest votes
¿No encuentras la respuesta? Pregunta en Stack Overflow en español.

✕
 
2

Based on MSN
https://msdn.microsoft.com/en-us/library/windows/desktop/ms632669(v=vs.85).aspx
there are lots of problems reported of using this function. So I recomend you go and implement the animation yourself.

Since you are interested only in sliding information do next:

Fist change your form size to fit into the monitor size.

MyForm.Width := Screen.Width;
MyForm.Height := Screen.Height;
Then move your form to the edge of the screen you want the animation to start from. When doing so keep atleast one pixel of the form inside the visible area of the monitor.

//Strating animation from left border
MyForm.Left := 1 - MyForm.Width;
MyForm.Top := 0;

//Starting from right border
MyForm.Left := MyForm.Width - 1;
MyForm.Top := 0;

//Starting from top border
MyForm.Left := 0;
MyForm.Top := 1 - MyForm.Height;

//Starting from bottom border
MyForm.Left := 0;
MyForm.Top := MyForm.Height - 1;
Once your have positioned your form in starting possition make it visible and enable timer that will beused to update forms position multiple times (animate) until it gets into desired position

MyForm.Show;
AniTimer.Enabled;
And start animation which is basically just updating your form position by using a simple timer

//Left to right animation
procedure MyForm.AniTimerOnTimer(Sender: TObject);
//Constant used to define by how many pixels will the form be moved
//on each timer interval
const MoveStep: Integer = 5;
begin
  if MyForm.Left < MoveStep then
  begin
    MyForm.Left := MyForm.Left + MoveStep;
  end;
  else
  begin
    MyForm.Left := 0;
    AniTimer.Enabled := False;
  end;
end;
Use similar approach for other directions if needed.

Instead of defining MoveStep as constant you can make it as a variable and then dynamically calculate its value so that animation is finished in N steps.

MoveStep := Screen.Width div N;
If you would like to have diagonal animation you would need two MoveStep variables. One for horizontal and one for vertical axis. And you need to make sure that both are being calculated in order to finish animation in specific number of steps

MoveStepX := Screen.Width div N;
MoveStepY := Screen.Height div N;
So now you can controll your animation speed by changing MoveStep and timer interval.

Note I don't recomend setting timer interval to small. Why?

As ypu probably know TTimer component isn't known for its acruacy so it could lead to noticable speed variation of of your animation.

Also changing form position multiple times woulrd require part of it being rerendered hwen it comes into visual rage so it could generate significant load to the CPU.

Moving fomr a few less times and with larger increments could greatly reduce the CPU load whle still performing adequate aniamtion smothness.

So do some testing to find the best combination of timer interval and move step.

shareimprove this answer
answered Feb 24 '15 at 8:09

SilverWarior
4,43321016
add a comment

 
2

Your problem is, before Form2 is first shown, the VCL does not create API windows of the windowed controls. Because it doesn't need to. Remember 'visible' is still set to false when you call AnimateWindow.

Below is a not very elegant workaround which sets 'visible' while the form has 0 width and height. It also addresses an additional problem which I don't know why you are not having. It is that I cannot animate a maximized window at all, which seems logical to me - a maximized window does not move. Anyway, to test it I suggest setting 'wsNormal' as WindowState at design time.

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  if Form2.Visible then begin
    Form2.WindowState := wsNormal;
    AnimateWindow(Form2.Handle, 500, AW_HIDE OR AW_SLIDE OR AW_HOR_NEGATIVE);
    Form2.Close;
  end else begin
    Form2.Width := 0;
    Form2.Height := 0;
    Form2.Visible := True;
    ShowWindow(Form2.Handle, SW_HIDE);

    Form2.WindowState := wsNormal;
    Form2.Width := Form2.Monitor.Width;
    Form2.Height := Form2.Monitor.Height;
    AnimateWindow(form2.Handle, 500, AW_ACTIVATE or AW_SLIDE OR AW_HOR_NEGATIVE);
    Form2.WindowState := wsMaximized;
  end;
end;
shareimprove this answer
answered Feb 24 '15 at 17:21

Sertac Akyuz
49k375133
@Wel - did you try this? – Sertac Akyuz Feb 27 '15 at 10:26
add a comment

1

AnimateWindow is a bit of a loner. It doesn't play nicely with the rest of the team in Delphi. Even though the MSDN doc for it says that it shows the form it actually doesn't do it properly. It only does the animation. I suppose it would do it nicely if you went all out Windows API and knew all that is required.

A few things to keep in mind:

I suppose you noticed that the slide effect doesn't show properly with the borders enabled.
It doesn't know about the WindowState property of the form so it will not Maximize the form if you wanted it to.
It doesn't show controls after the call, only graphic controls
It knows nothing of Delphi and how Delphi handles the showing and hiding of its forms
So the trick is:

Take away borders like you have done.
Before showing the form for the first time you must specify its size. Seeing that you want it maximized, just set it to the screen size where it will display and set its position to the four corners of that screen. This can be done on Form2's OnCreate.
So upon clicking the button you first call the AnimateWindow then call normal Form2.Show
There might be other fixes but this is the one I know of.

    </div>
  </td></tr></tbody>
  <tfoot><tr><td>
    <div class="footer-space"> </div>
  </td></tr></tfoot>
</table>
<div class="header">Prueba Encabezado</div>
<div class="footer">Pie de pagina</div>
</body>
</html>
content_copyCOPY