procedure TCmdForm.DisplayPages(Sender: TObject);
var
fr: TFormatRange;
dc: THandle;
ox, oy, w, h: LongInt;
cpMin: LRESULT;
x: Integer;
PgWide, PgHigh, PgLft, PgRht, PgTop, PgBtm, InchW, InchH, ViewScale: double;
PixHigh, PixWide, ViewChg, BegChar, PgCnt, PgSum: integer;
MorePages: boolean;
BackPages, xstr, PgStr: string;
begin
// define paper size... these 7 can be global for paper size and display
PgWide:= 8.5; PgHigh:= 11.0;
PgLft:= 1.0; PgRht:= 1.0;
PgTop:= 1.0; PgBtm:= 1.0;
ViewScale:= 2; // display size: 10.5=double, 1.0=full, 2.0=half
// setup the PaperArea metrics
PaperArea.top:= 0; // 40 fits my layout
PaperArea.height:= Round(PgHigh * Screen.PixelsPerInch / ViewScale);
PaperArea.width:= Round(PgWide * Screen.PixelsPerInch / ViewScale);
PaperArea.left:= Round((PageMemo.width - PaperArea.width) / 2); // centering view page
// setup the TextArea metrics
InchH:= PgHigh - PgTop - PgBtm;
InchW:= PgWide - PgLft - PgRht;
PixHigh:= Round(InchH * Screen.PixelsPerInch / ViewScale);
PixWide:= Round(InchW * Screen.PixelsPerInch / ViewScale);
// setup the TextArea position
TextArea.Top:= Round((Screen.PixelsPerInch * PgTop) / ViewScale);
TextArea.height:= PixHigh;
TextArea.width:= PixWide;
TextArea.left:= Round((Screen.PixelsPerInch * PgLft) / ViewScale);
TextArea.Picture.Bitmap.SetSize(Round(PixWide * ViewScale), Round(PixHigh * ViewScale));
// clear the image canvas
TextArea.Canvas.Brush.Color:= clWindow;
TextArea.Canvas.FillRect(0, 0, TextArea.Canvas.ClipRect.Right, TextArea.Canvas.ClipRect.Bottom);
TextArea.Canvas.MoveTo(0, 0);
cpMin:= 0;
PaperArea.visible:= true;
ScrollView.visible:= true;
// set the printing metrics
dc:= TextArea.Canvas.Handle;
ox:= 0; //GetDeviceCaps(dc, PHYSICALOFFSETX);
oy:= 0; //GetDeviceCaps(dc, PHYSICALOFFSETY);
w:= XPixToTwips(Round(PixWide * ViewScale)); //GetDeviceCaps(dc, PHYSICALWIDTH);
h:= YPixToTwips(Round(PixHigh * ViewScale)); //GetDeviceCaps(dc, PHYSICALHEIGHT);
FillChar(fr, SizeOf(TFormatRange), 0);
fr.hdc:= dc; // fr._hdc := dc; **on another system**
fr.hdcTarget:= dc;
fr.rc.Left:= ox;
fr.rc.Right:= ox+w;
fr.rc.Top:= oy;
fr.rc.Bottom:= oy+h; //
fr.chrg.cpMin:= cpMin;
SendMessage(PageMemo.Handle, EM_FORMATRANGE, 0, 0); // clear EM_FORMATRANGE
SendMessage(PageMemo.Handle, EM_HIDESELECTION, 1, 0); // hide selection
SendMessage(PageMemo.Handle, EM_SETSEL, cpMin, -1); // select to end of document
SendMessage(PageMemo.Handle, EM_EXGETSEL, 0, LParam(@fr.chrg)); // copy selection
SendMessage(PageMemo.Handle, EM_SETSEL, 0, 0); // reset to no selection
SendMessage(PageMemo.Handle, EM_HIDESELECTION, 0, 0); // show selection
// get the page count
cpMin:= 0; PgSum:= 0; MorePages:= true;
while (fr.chrg.cpMin<=fr.chrg.cpMax) and (MorePages) do // track through document
begin
// clear the image canvas
TextArea.Canvas.Brush.Color:= clWindow;
TextArea.Canvas.FillRect(0, 0, TextArea.Canvas.ClipRect.Right, TextArea.Canvas.ClipRect.Bottom);
TextArea.Canvas.MoveTo(0, 0);
// set the printing metrics
dc:= TextArea.Canvas.Handle;
ox:= 0; //GetDeviceCaps(dc, PHYSICALOFFSETX);
oy:= 0; //GetDeviceCaps(dc, PHYSICALOFFSETY);
w:= XPixToTwips(Round(PixWide * ViewScale)); //GetDeviceCaps(dc, PHYSICALWIDTH);
h:= YPixToTwips(Round(PixHigh * ViewScale)); //GetDeviceCaps(dc, PHYSICALHEIGHT);
FillChar(fr, SizeOf(TFormatRange), 0);
fr.hdc:= dc; // fr._hdc := dc; **on another system**
fr.hdcTarget:= dc;
fr.rc.Left:= ox;
fr.rc.Right:= ox+w;
fr.rc.Top:= oy;
fr.rc.Bottom:= oy+h; //
fr.chrg.cpMin:= cpMin;
SendMessage(PageMemo.Handle, EM_FORMATRANGE, 0, 0); // clear EM_FORMATRANGE
SendMessage(PageMemo.Handle, EM_HIDESELECTION, 1, 0); // hide selection
SendMessage(PageMemo.Handle, EM_SETSEL, cpMin, -1); // select to end of document
SendMessage(PageMemo.Handle, EM_EXGETSEL, 0, LParam(@fr.chrg)); // copy selection
SendMessage(PageMemo.Handle, EM_SETSEL, 0, 0); // reset to no selection
SendMessage(PageMemo.Handle, EM_HIDESELECTION, 0, 0); // show selection
cpMin:= SendMessage(PageMemo.Handle, EM_FORMATRANGE, 1, LPARAM(@fr));
SendMessage(PageMemo.Handle, EM_FORMATRANGE, 0, 0); // clear EM_FORMATRANGE
if (fr.chrg.cpMin=fr.chrg.cpMax)
then MorePages:= false
else PgSum:= PgSum + 1;
end;
// print each page
MorePages:= true; ViewChg:= 0; PgCnt:= 0;
cpMin:= 0; BackPages:=''; BegChar:= 0;
// clear the image canvas
TextArea.Canvas.Brush.Color:= clWindow;
TextArea.Canvas.FillRect(0, 0, TextArea.Canvas.ClipRect.Right, TextArea.Canvas.ClipRect.Bottom);
TextArea.Canvas.MoveTo(0, 0);
// set the printing metrics
dc:= TextArea.Canvas.Handle;
ox:= 0; //GetDeviceCaps(dc, PHYSICALOFFSETX);
oy:= 0; //GetDeviceCaps(dc, PHYSICALOFFSETY);
w:= XPixToTwips(Round(PixWide * ViewScale)); //GetDeviceCaps(dc, PHYSICALWIDTH);
h:= YPixToTwips(Round(PixHigh * ViewScale)); //GetDeviceCaps(dc, PHYSICALHEIGHT);
FillChar(fr, SizeOf(TFormatRange), 0);
fr.hdc:= dc; // fr._hdc := dc; **on another system**
fr.hdcTarget:= dc;
fr.rc.Left:= ox;
fr.rc.Right:= ox+w;
fr.rc.Top:= oy;
fr.rc.Bottom:= oy+h; //
fr.chrg.cpMin:= cpMin;
SendMessage(PageMemo.Handle, EM_FORMATRANGE, 0, 0); // clear EM_FORMATRANGE
SendMessage(PageMemo.Handle, EM_HIDESELECTION, 1, 0); // hide selection
SendMessage(PageMemo.Handle, EM_SETSEL, cpMin, -1); // select to end of document
SendMessage(PageMemo.Handle, EM_EXGETSEL, 0, LParam(@fr.chrg)); // copy selection
SendMessage(PageMemo.Handle, EM_SETSEL, 0, 0); // reset to no selection
SendMessage(PageMemo.Handle, EM_HIDESELECTION, 0, 0); // show selection
while (fr.chrg.cpMin<=fr.chrg.cpMax) and (MorePages) do // track through document
begin
if (ViewChg<0) then
begin
x:= pos(',',BackPages);
if x>0 then delete(BackPages,1,x);
x:= pos(',',BackPages);
if x>0 then
begin
xstr:= copy(BackPages,1,x-1);
delete(BackPages,1,x);
cpMin:= StrToInt(xstr);
PgCnt:= PgCnt - 2;
if cpMin<0 then
begin
cpMin:= 0; BackPages:='';
PgCnt:= 0;
end;
end else begin
cpMin:= 0; BackPages:='';
PgCnt:= 0;
end;
end;
BackPages:= IntToStr(cpMin)+','+BackPages; //showmessage(BackPages);
ViewChg:= 0;
BegChar:= cpMin; //showmessage(IntToStr(BegChar));
// clear the image canvas
TextArea.Canvas.Brush.Color:= clWindow;
TextArea.Canvas.FillRect(0, 0, TextArea.Canvas.ClipRect.Right, TextArea.Canvas.ClipRect.Bottom);
TextArea.Canvas.MoveTo(0, 0);
// set the printing metrics
dc:= TextArea.Canvas.Handle;
ox:= 0; //GetDeviceCaps(dc, PHYSICALOFFSETX);
oy:= 0; //GetDeviceCaps(dc, PHYSICALOFFSETY);
w:= XPixToTwips(Round(PixWide * ViewScale)); //GetDeviceCaps(dc, PHYSICALWIDTH);
h:= YPixToTwips(Round(PixHigh * ViewScale)); //GetDeviceCaps(dc, PHYSICALHEIGHT);
FillChar(fr, SizeOf(TFormatRange), 0);
fr.hdc:= dc; // fr._hdc := dc; **on another system**
fr.hdcTarget:= dc;
fr.rc.Left:= ox;
fr.rc.Right:= ox+w;
fr.rc.Top:= oy;
fr.rc.Bottom:= oy+h; //
fr.chrg.cpMin:= cpMin;
SendMessage(PageMemo.Handle, EM_FORMATRANGE, 0, 0); // clear EM_FORMATRANGE
SendMessage(PageMemo.Handle, EM_HIDESELECTION, 1, 0); // hide selection
SendMessage(PageMemo.Handle, EM_SETSEL, cpMin, -1); // select to end of document
SendMessage(PageMemo.Handle, EM_EXGETSEL, 0, LParam(@fr.chrg)); // copy selection
SendMessage(PageMemo.Handle, EM_SETSEL, 0, 0); // reset to no selection
SendMessage(PageMemo.Handle, EM_HIDESELECTION, 0, 0); // show selection
cpMin:= SendMessage(PageMemo.Handle, EM_FORMATRANGE, 1, LPARAM(@fr));
SendMessage(PageMemo.Handle, EM_FORMATRANGE, 0, 0); // clear EM_FORMATRANGE
if (cpMin<=fr.chrg.cpMin) then
begin
MorePages:= false; // document has no content
break;
end;
fr.chrg.cpMin:= cpMin; // set to start of next page
PgCnt:= PgCnt + 1;
// begin modal dialogs
if (PgSum>1) then
begin
PgStr:= 'Page '+IntToStr(PgCnt)+' of ';
PgStr:= PgStr+IntToStr(PgSum)+' Pages';
end else PgStr:= 'Single Page';
if (PgSum=1) then // pause at only-page
begin
case QuestionDlg (PgStr,'No Navigation',mtCustom,
[mrCancel, 'Quit'],'') of
mrCancel: MorePages:= false;
end;
end;
if (BegChar=0) and (PgSum>1) then // pause at first-page
begin
case QuestionDlg (PgStr,'Navigation at Home',mtCustom,
[mrCancel, 'Quit', mrYes, 'Next'],'') of
mrCancel: MorePages:= false;
mrYes: ViewChg:= 1;
end;
end else if (fr.chrg.cpMin<fr.chrg.cpMax) then // pause at each-page
begin
case QuestionDlg (PgStr,'Page Navigation',mtCustom,
[mrNo,'Back', mrCancel, 'Quit', mrYes, 'Next'],'') of
mrNo: ViewChg:= -1;
mrCancel: MorePages:= false;
mrYes: ViewChg:= 1;
end;
end;
if (fr.chrg.cpMin=fr.chrg.cpMax) and (PgSum>1) then // pause at last-page
begin
case QuestionDlg (PgStr,'Navigation at End',mtCustom,
[mrNo,'Back', mrCancel, 'Quit'],'') of
mrNo: ViewChg:= -1;
mrCancel: MorePages:= false;
end;
end;
// end of modal dialogs
end;
// clean up
SendMessage(PageMemo.Handle, EM_FORMATRANGE, 0, 0); // clear EM_FORMATRANGE
if MorePages
then EndDoc(fr.hdc) // close EM_FORMATRANGE
else AbortDoc(fr.hdc);
TextArea.Picture.Bitmap.Canvas.Changed; // reset image event
PaperArea.visible:= false;
ScrollView.visible:= false;
end;