@byku_guzio: dzięki za odpowiedź, jednak oczywiście tak robiłem na początku i mam inne wyniki w sensie wyglądu wydruku do pdfa niż generowane są dla tego samego pliku przez przykładowy plugin. Oczywiście pomijając fakt, że plugin autora dodaje numer linii na przykład dla plików typu *.c, *.cpp lub *.pas, natomiast mój na prośbę osoby z forum totalcmd.pl ma dodawać przed właściwą treścią pliku wczytanego do Listera podawać ilośc linijek w pliku, bez względu na rozszerzenie takowego. Z tym, że oczywiście ma być używany raczej dla plików tekstowych, ale ze znakami typowaymi osiągalnymi z klawiatury, bo na domyślnym foncie dla RichEdita na prztkład ascii logosy z plików *.nfo się prawidłowo nie pokażą, nie wspominając już o zawartości plików typu *.exe lub innych binarnych. Dlatego jak ktoś jeszcze znalazł czas i mógł zobaczyć w źrodle pluginu, do którego podałem link co jest nie tak to prosił bym o pomoć. Może wkleje jak teraz wygląda kod u mnie i w C++, co niestety nie działa. Pomijam nieco inne nazewnictwo typów i pewnych zmiennych, bo na przykład w Delphi nie możemy użyć zmiennej o nazwie Hdc typu HDC. Pomijam też fakt, że nie lubię raczej dawać po then pojedyńczej instrukcji, wolę w razie przyszłych zmian poprzedzić je beginem oraz endem. Oto kod w C++:
int __stdcall ListPrint(HWND ListWin,char* FileToPrint,char* DefPrinter,int PrintFlags,RECT* Margins)
{
PRINTDLG PrintDlgRec;
memset(&PrintDlgRec,0,sizeof(PRINTDLG));
PrintDlgRec.lStructSize=sizeof(PRINTDLG);
PrintDlgRec.Flags= PD_ALLPAGES | PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC;
PrintDlgRec.nFromPage = 0xFFFF;
PrintDlgRec.nToPage = 0xFFFF;
PrintDlgRec.nMinPage = 1;
PrintDlgRec.nMaxPage = 0xFFFF;
PrintDlgRec.nCopies = 1;
PrintDlgRec.hwndOwner = ListWin;// MUST be Zero, otherwise crash!
if (PrintDlg(&PrintDlgRec))
{
HDC hdc=PrintDlgRec.hDC;
DOCINFO DocInfo;
POINT offset,physsize,start,avail,printable;
int LogX,LogY;
RECT rcsaved;
// Warning: PD_ALLPAGES is zero!
BOOL PrintSel=(PrintDlgRec.Flags & PD_SELECTION);
BOOL PrintPages=(PrintDlgRec.Flags & PD_PAGENUMS);
int PageFrom=1;
int PageTo=0x7FFF;
if (PrintPages) {
PageFrom=PrintDlgRec.nFromPage;
PageTo=PrintDlgRec.nToPage;
if (PageTo<=0) PageTo=0x7FFF;
}
memset(&DocInfo,0,sizeof(DOCINFO));
DocInfo.cbSize=sizeof(DOCINFO);
DocInfo.lpszDocName=FileToPrint;
if (StartDoc(hdc,&DocInfo)) {
SetMapMode(hdc,MM_LOMETRIC);
offset.x=GetDeviceCaps(hdc,PHYSICALOFFSETX);
offset.y=GetDeviceCaps(hdc,PHYSICALOFFSETY);
DPtoLP(hdc,&offset,1);
physsize.x=GetDeviceCaps(hdc,PHYSICALWIDTH);
physsize.y=GetDeviceCaps(hdc,PHYSICALHEIGHT);
DPtoLP(hdc,&physsize,1);
start.x=Margins->left-offset.x;
start.y=-Margins->top-offset.y;
if (start.x<0)
start.x=0;
if (start.y>0)
start.y=0;
avail.x=GetDeviceCaps(hdc,HORZRES);
avail.y=GetDeviceCaps(hdc,VERTRES);
DPtoLP(hdc,&avail,1);
printable.x=min(physsize.x-(Margins->right+Margins->left),avail.x-start.x);
printable.y=max(physsize.y+(Margins->top+Margins->bottom),avail.y-start.y);
LogX=GetDeviceCaps(hdc, LOGPIXELSX);
LogY=GetDeviceCaps(hdc, LOGPIXELSY);
SendMessage(ListWin, EM_FORMATRANGE, 0, 0);
FORMATRANGE Range;
memset(&Range,0,sizeof(FORMATRANGE));
Range.hdc=hdc;
Range.hdcTarget=hdc;
LPtoDP(hdc,&start,1);
LPtoDP(hdc,&printable,1);
Range.rc.left = start.x * 1440 / LogX;
Range.rc.top = start.y * 1440 / LogY;
Range.rc.right = (start.x+printable.x) * 1440 / LogX;
Range.rc.bottom = (start.y+printable.y) * 1440 / LogY;
SetMapMode(hdc,MM_TEXT);
BOOL PrintAborted=false;
Range.rcPage = Range.rc;
rcsaved = Range.rc;
int CurrentPage = 1;
int LastChar = 0;
int LastChar2= 0;
int MaxLen = SendMessage(ListWin,WM_GETTEXTLENGTH,0,0);
Range.chrg.cpMax = -1;
if (PrintPages) {
do {
Range.chrg.cpMin = LastChar;
if (CurrentPage<PageFrom) {
LastChar = SendMessage(ListWin, EM_FORMATRANGE, 0, (LPARAM)&Range);
} else {
//waitform.ProgressLabel.Caption:=spage+inttostr(CurrentPage);
//application.processmessages;
LastChar = SendMessage(ListWin, EM_FORMATRANGE, 1, (LPARAM)&Range);
}
// Warning: At end of document, LastChar may be<MaxLen!!!
if (LastChar!=-1 && LastChar < MaxLen) {
Range.rc=rcsaved; // Check whether another page comes
Range.rcPage = Range.rc;
Range.chrg.cpMin = LastChar;
LastChar2= SendMessage(ListWin, EM_FORMATRANGE, 0, (LPARAM)&Range);
if (LastChar<LastChar2 && LastChar < MaxLen && LastChar != -1 &&
CurrentPage>=PageFrom && CurrentPage<PageTo) {
EndPage(hdc);
}
}
CurrentPage++;
Range.rc=rcsaved;
Range.rcPage = Range.rc;
} while (LastChar < MaxLen && LastChar != -1 && LastChar<LastChar2 &&
(PrintPages && CurrentPage<=PageTo) && !PrintAborted);
} else {
if (PrintSel) {
SendMessage(ListWin,EM_GETSEL,(WPARAM)&LastChar,(LPARAM)&MaxLen);
Range.chrg.cpMax = MaxLen;
}
do {
Range.chrg.cpMin = LastChar;
//waitform.ProgressLabel.Caption:=spage+inttostr(CurrentPage);
//waitform.ProgressLabel.update;
//application.processmessages;
LastChar = SendMessage(ListWin, EM_FORMATRANGE, 1, (LPARAM)&Range);
// Warning: At end of document, LastChar may be<MaxLen!!!
if (LastChar!=-1 && LastChar < MaxLen) {
Range.rc=rcsaved; // Check whether another page comes
Range.rcPage = Range.rc;
Range.chrg.cpMin = LastChar;
LastChar2= SendMessage(ListWin, EM_FORMATRANGE, 0, (LPARAM)&Range);
if (LastChar<LastChar2 && LastChar < MaxLen && LastChar != -1) {
EndPage(hdc);
}
}
CurrentPage++;
Range.rc=rcsaved;
Range.rcPage = Range.rc;
} while (LastChar<LastChar2 && LastChar < MaxLen && LastChar != -1 && !PrintAborted);
}
if (PrintAborted)
AbortDoc(hdc);
else
EndDoc(hdc);
} //StartDoc
SendMessage(ListWin, EM_FORMATRANGE, 0, 0);
DeleteDC(PrintDlgRec.hDC);
}
if (PrintDlgRec.hDevNames)
GlobalFree(PrintDlgRec.hDevNames);
return 0;
}
I to samo według mnie w Delphi (LISTPLUGIN_OK to 0). Niestety przy odkomentowanych warnkach dla pętli while ... do - plik *.pdf z wydrukiem nie jest generowany, a po ich obkomentowaniu nie generuje się w całości:
function ListPrint(PluginWin : THandle; FileToPrint, DefPrinter : PChar;
PrintFlags : integer; var Margins : TRect) : integer; stdcall;
var
AHdc : HDC;
RCSaved : TRect;
DocInfo : TDocInfo;
Range : TFormatRange;
PrintDlgRec : TPrintDlg;
PrintAborted, PrintSel, PrintPages : boolean;
Avail, Offset, Printable, PhysSize, Start : TPoint;
CurrentPage, LastChar, LastChar2, LogX, LogY, MaxLen, PageFrom, PageTo : integer;
begin
FillChar(PrintDlgRec, SizeOf(TPrintDlg), #0);
PrintDlgRec.lStructSize := SizeOf(TPRINTDLG);
PrintDlgRec.Flags := PD_ALLPAGES or PD_USEDEVMODECOPIESANDCOLLATE or PD_RETURNDC;
PrintDlgRec.nFromPage := 1;
PrintDlgRec.nToPage := $FFFF;
PrintDlgRec.nMinPage := 1;
PrintDlgRec.nMaxPage := $FFFF;
PrintDlgRec.nCopies := 1;
PrintDlgRec.hwndOwner := PluginWin;
if PrintDlg(PrintDlgRec) then
begin
AHdc := PrintDlgRec.hDC;
PrintSel := (PrintDlgRec.Flags and PD_SELECTION) = PD_SELECTION;
PrintPages := (PrintDlgRec.Flags and PD_PAGENUMS) = PD_PAGENUMS;
PageFrom := 1;
PageTo := $7FFF;
if PrintPages then
begin
PageFrom := PrintDlgRec.nFromPage;
PageTo := PrintDlgRec.nToPage;
if (PageTo <= 0) then
begin
PageTo := $7FFF;
end;
end;
FillChar(DocInfo, SizeOf(TDocInfo), #0);
DocInfo.cbSize := SizeOf(TDocInfo);
DocInfo.lpszDocName := FileToPrint;
if StartDoc(AHdc, DocInfo) = 0 then
StartDoc(AHdc, DocInfo);
begin
SetMapMode(AHdc, MM_LOMETRIC);
Offset.X := GetDeviceCaps(AHdc, PHYSICALOFFSETX);
Offset.Y := GetDeviceCaps(AHdc, PHYSICALOFFSETY);
DPtoLP(AHdc, Offset, 1);
PhysSize.X := GetDeviceCaps(AHdc, PHYSICALWIDTH);
PhysSize.Y := GetDeviceCaps(AHdc, PHYSICALHEIGHT);
DPtoLP(AHdc, PhysSize, 1);
Start.X := Margins.Left - Offset.X;
Start.Y := Start.Y - Margins.Top - Offset.Y;
if (Start.X < 0) then
begin
Start.X := 0;
end;
if (Start.Y > 0) then
begin
Start.Y := 0;
end;
Avail.X := GetDeviceCaps(AHdc, HORZRES);
Avail.Y := GetDeviceCaps(AHdc, VERTRES);
DPtoLP(AHdc, Avail, 1);
Printable.X := Min(PhysSize.X - (Margins.Right + Margins.Left), Avail.X - start.X);
Printable.Y := Max(PhysSize.Y + (Margins.Top + Margins.Bottom), Avail.Y - start.Y);
LogX := GetDeviceCaps(AHdc, LOGPIXELSX);
LogY := GetDeviceCaps(AHdc, LOGPIXELSY);
SendMessage(PluginWin, EM_FORMATRANGE, 0, 0);
FillChar(Range, SizeOf(TFormatRange), #0);
Range.hdc := AHdc;
Range.hdcTarget := AHdc;
LPtoDP(AHdc, Start, 1);
LPtoDP(AHdc, Printable, 1);
Range.rc.Left := Start.X * 1440 div LogX;
Range.rc.Top := Start.Y * 1440 div LogY;
Range.rc.Right := (Start.X + Printable.X) * 1440 div LogX;
Range.rc.Bottom := (Start.Y + Printable.Y) * 1440 div LogY;
SetMapMode(AHdc, MM_TEXT);
PrintAborted := False;
Range.rcPage := Range.rc;
RCSaved := Range.rc;
CurrentPage := 1;
LastChar := 0;
LastChar2 := 0;
MaxLen := SendMessage(PluginWin, WM_GETTEXTLENGTH, 0, 0);
Range.chrg.cpMax := -1;
if (PrintPages) then
begin
while (LastChar < MaxLen) and (LastChar <> -1) and (LastChar < LastChar2)
and (PrintPages) and (CurrentPage <= PageTo) and (not PrintAborted) do
begin
Range.chrg.cpMin := LastChar;
if (CurrentPage < PageFrom) then
begin
LastChar := SendMessage(PluginWIn, EM_FORMATRANGE, 0, LongInt(@Range));
end
else
begin
LastChar := SendMessage(PluginWIn, EM_FORMATRANGE, 1, LongInt(@Range));
end;
if (LastChar <> -1) and (LastChar < MaxLen) then
begin
Range.rc := RCSaved;
Range.rcPage := Range.rc;
Range.chrg.cpMin := LastChar;
LastChar2 := SendMessage(PluginWIn, EM_FORMATRANGE, 0, LongInt(@Range));
if (LastChar < LastChar2) and (LastChar < MaxLen) and (LastChar <> -1)
and (CurrentPage >= PageFrom) and (CurrentPage < PageTo) then
begin
EndPage(AHdc);
end;
end;
CurrentPage := CurrentPage + 1;
Range.rc := RCSaved;
Range.rcPage := Range.rc;
end;
end
else
begin
if PrintSel then
begin
SendMessage(PluginWIn, EM_GETSEL, LastChar, MaxLen);
Range.chrg.cpMax := MaxLen;
end;
while (LastChar < LastChar2) and (LastChar < MaxLen) and (LastChar <> -1)
and (not PrintAborted) do
begin
Range.chrg.cpMin := LastChar;
LastChar := SendMessage(PluginWIn, EM_FORMATRANGE, 1, LongInt(@Range));
if (LastChar <> -1) and (LastChar < MaxLen) then
begin
Range.rc := RCSaved;
Range.rcPage := Range.rc;
Range.chrg.cpMin := LastChar;
LastChar2 := SendMessage(PluginWIn, EM_FORMATRANGE, 0, LongInt(@Range));
if (LastChar < LastChar2) and (LastChar < MaxLen) and (LastChar <> -1) then
begin
EndPage(AHdc);
end;
end;
CurrentPage := CurrentPage + 1;
Range.rc := RCSaved;
Range.rcPage := Range.rc;
end;
end;
if PrintAborted then
begin
AbortDoc(AHdc);
end
else
begin
EndDoc(AHdc);
end;
end;
SendMessage(PluginWIn, EM_FORMATRANGE, 0, 0);
DeleteDC(PrintDlgRec.hDC);
end;
if PrintDlgRec.hDevNames > 0 then
begin
GlobalFree(PrintDlgRec.hDevNames);
end;
Result := LISTPLUGIN_OK;
end;