15. januar 2000 - 15:39Der er
24 kommentarer og 1 løsning
Udskriv ren tekst
Jeg skal skrive tekst ud på en gammel matrix-printer (IBM Proprinter XL24) Jeg prøvede først printer.canvas.textout, det virker også fint, men det går meget langsomt, da printeren jo tror at det er grafik den skriver. Hvis skriver AssignPrn(F); Rewrite(F); Writeln(F,'Linje 1'); CloseFile(F); skriver den fint ud, men hvis jeg vil skrive flere linjer, fx. AssignPrn(F); Rewrite(F); Writeln(F,'Linje 1'); Writeln(F,'Linje 2'); CloseFile(F); går prn helt amok efter første linje!! Hvad gør jeg forkert (printeren virker normalt fint, wp51 har intet problem og skriver hurtigt ud)
I dette særtema ser vi på, hvordan cloud og AI bliver fundamentet for virksomhedernes digitale forretning, og hvordan de nye muligheder for automatisering og forretningsværdi kan udnyttes uden at miste overblik, sikkerhed og menneskelig kontrol.
Hvis det kører gennem widows - hvad delphi jo gør, så "plejer" jeg at lave en hvid form, med de tekster jeg vil udskrive, det giver brugeren mulighed for at få en "preview" samtidig er det så bare at kode en frmPreview.Print (hvis du kalder formen det), og så klarer winddows resten ;)
Lad mig lige forstå det rigtigt. Du laver en (evt skjult) form, lader som om formen er papiret. dvs skriver til form.canvas og til sidst skriver form.print. Har du også gjort det med er matrix printer?
Her er et eks på hvordan jeg gjorde før i tiden. I dag bruger jeg ReportPrinter Pro:
procedure Tudskform.skriv_print; var antal_udskrevet : integer; skru : integer; zt : integer; begin antal_udskrevet := 0; printer.printerindex := find_printer(udsk_dev); // Udsk_Dev indeholder navnet på den printer jeg vil skrive på repeat skru := 0; try assignprn(filu); // filu er def. som textfile og 'printers' er tilføjet usesclause rewrite(filu); printer.title := 'W-MINI '+listtype+' liste.'; printer.canvas.font.name := font_navn; printer.canvas.font.size := 12; try for zt := 0 to sortrec.items.count -1 do begin if sortrec.items[zt] = '[SIDE SKIFT]' then begin writeln(filu,#12); {printer.newpage;} end else begin writeln(filu,sortrec.items[zt]); end; skru := skru + 1; label1.caption := 'Skriver liste nr: '+inttostr(antal_udskrevet+1)+' -linie nr: '+inttostr(skru); application.processmessages; if afbrudt then begin printer.abort; break; end; end; finally closefile(filu); antal_udskrevet := antal_udskrevet + 1; end; except on EInOutError do begin showmessage('Fejl: Kan ikke åbne til printeren !'); afbrudt := true; break; end; end; until (antal_udskrevet = udsk_ant) or afbrudt; if afbrudt then begin liste_ok := false; end else begin liste_ok := true; end; end;
Dette skriver fint på alle matrixprintere. Mon ikke at det er fordi du ikke vælger font og størrelse. Tænk på at printeren måske ikke kan skrive den fonttype der er valgt (times new roman ?) fordi den er proportional. Vælg en 10-12 cpi font a la Currier New og se om ikke det hjælper.
Kim Ja lidt i den stil, jeg laver dog ikke formen skjult, men giver brugeren mulighed for at se den - en slags preview. På siden har jeg et string array, som jeg putter de varible ind i som jeg skal have skrevet ud.
Nej jeg har ikke prøvet til en matrix printer, men hvis den er i widows printer liste - så vil jeg tro det fungerer.
Koonz>Nej, ikke når man bruger en form. Den bliver udskrivet grafisk på en matrixprinter.
Kim>Jeg laver udskriften som linier i en listbox som brugeren så kan se som preview. Derefter udskriver hver enkelt linie fra den med writeln, som du kan se i mit eks. Det virker som sagt fint hos mig.
Hov SJensen> Jeg har prøvet din code, (selvfølgelig efter jeg tilføjede diverse vars og printers i uses) men det virkede ikke. Jeg kunne ikke regne ud hvad "listtype" var, så jeg fjernede den, var den vigtig? Det er stadigt det samme: Printeren skriver fint den første linje ud, kommer med et error-bip (det tror jeg det er) og skriver derefter volapyk ud. Jeg har ingen andelse om hvor det går galt, og det irritere mig. Jeg har prøvet at skrive en lille txt fil ud fra dos via cmd: "type lille.txt > prn" og det virker fint. Kan man kalde dos cmd. fra Delphi?
Det lille bip efter første linie kunne tyde på at den linie du vil skrive er for lang. Prøv engang med mindre tekst pr. linie og se om det er det samme.
Nej, listtype var ikke vigtig. Det er blot en streng der indeholdt info om hvilken af de mulige udskrifter der var valgt, og som man kunne se sammen med navnet W-Mini i printerens dokumentliste, mens udskriften foregår.
Dos Cmd fra Delphi: Ja, brug CreateProcess med "filnavn.cmd" som programnavn.
Du kan bruge både CreateProcess der blot igangsætter et program, og eller går videre med det samme, og CreateProcessAndWait, der igangsætter et program og venter på at det bliver færdigt inden det bliver færdigt.
Hvis du ikke har koden til disse så sig til, så smider jeg dem op.
Lad os forestille os at jeg skrev det der skal printes ud ned i en txt-fil (som var formateret udelukkende med "space" og "return") og kaldte denne fil "print.txt" (liggende i prg. dir) hvordan skal jeg så få windows til at udføre cmd. "type print.txt > prn"
med andre ord: ja, du må gerne lægge lidt (mere) kode op
Path er sti og programnavn til det program du vil igangsætte. For at bruge kommandoer (doskommandoer!) skal path pege enten på Command.com eller cmd.exe Dette vil skabe et DOS vindue
Param er så den kommando du vil have udført i vinduet, på samme måde som du ville skrive den ud for promptet:
Type xxx > prn
MEN...
Type en-eller-anden-tekstfil til prn virker ikke (under NT i hvertfald, men måske under Win95/98).
Syntaxen for dette tilfælde (hvor xxx er filnavnet på den fil du vil udskrive) er:
WinExecAndWait('c:\winnt\system32\cmd.exe','/C type xxx > prn');
/C betyder at vinduet skal lukke efter udførelsen.
NB! Som kommando kan du også bruge 'copy xxx prn' eller 'copy xxx LTP1:'
Under NT er det lidt mere tricky. Der skal man type eller copy til den pågældende printer. For at dette kan virke SKAL printeren være delt ud, og man skal sende udskriften til "\\maskinnavn\printernavn". Min maskine hedder DG5LSI14 og min printer hedder HP1100, så for mig vil det være:
WinExecAndWait('c:\winnt\system32\cmd.exe','/C type xxx > \\DG5LSI14\HP1100');
og når du så har filnavnet i en var ser linierne således ud:
Win95/98:
WinExecAndWait('c:\winnt\system32\cmd.exe','/C type '+filnavn+' > prn');
NT: WinExecAndWait('c:\winnt\system32\cmd.exe','/C type '+filnavn+' > \\DG5LSI14\HP1100');
NB1! Jeg er ikke sikker på hvordan systemet reagerer hvis der er mellemrum i printernavnet, ligesom jeg ikke er sikker på at en kommando vil blive udført rigtigt hvis der er mellemrum i et af dirnavnene i enten Path eller Param værdierne. Du skal formentligt i dette tilfælde sætte anførselstegn rundt om.
NB2! Fordi min printer er en laserprinter, laver hhv. 'Type >' og 'copy ' ikke en formfeed når filen er overført, og det problem har du også på en matrixprinter, men hvor den sidste side bliver inde i laserprinteren indtil man manuelt trykker formfeed (eller sender næste fil) vil den på matrixprinteren blive udskrevet til og med sidste linie. Printhovedet vil så bare stå på næste linie, så du skal selv trykke en formfeed.
Du kan selvfølgeligt også proppe tegnet for ascii 12 (formfeed) ned i en lille fil du kalder ff.dat og så type den til printeren bagefter. Så laver den en formfeed.
NB3! Du laver filen på denne måde:
Åben en dosboks og skift til det dir hvor du vil have filen. skriv copy con ff.dat og tryk enter tryk på ALT og 12 på det numeriske tastatur. (du burde også kunne trykke Ctrl+L) Skærmen viser nu ^L. Tryk på enter. Tryk på Ctrl+Z og enter. Filen er nu skabt og ligger i det dir du valgte. Lad os sige det er C:\. Så vil du lave følgende for at få printeren til at udføre en formfeed:
Win95/98:
WinExecAndWait('c:\winnt\system32\cmd.exe','/C type c:\ff.dat > prn');
NT: WinExecAndWait('c:\winnt\system32\cmd.exe','/C type c:\ff.dat > \\DG5LSI14\HP1100');
Jeg håber at det lykkes dig at få det til at virke ordentligt.
desværre det virker ikke efter hensigten. Hvis jeg skriver:
WinExecNoWait('c:\Windows\Notepad.exe','');
er der ikke noget i vejen, notepad starter og alt er i den skøneste orden, men skriver jeg:
WinExecNoWait('c:\Windows\Command.com','');
for jeg fejlmeddelsen: "Project sjensen.exe reised exception class EExecuteError with message 'Kunne ikke starte program. Fejl kode: 2'. Process stopped Use Step or Run to continue."
nb: jeg har win98
Kan det tænkes at CreateProcess kun kan køre windows programmer, for command.com er vel et dos prg.
nb: jeg har prøvet flere andre win og dos prg, alle win prg starter mens alle dos prg ikke gør.
Kim
ps: jeg har accepteret dit/dine svar, fordi 1: det jo delvist virker og burde virke (det virker jo hos dig) 2: du har gjort dei fortjent til de 100 point. Jeg vil selvfølgelig gerne have hvis du kan hjælpe mig ydreliger, så kan vi senere tale om hvormange flere point du skal have.
Det betyder i win98 at command.com skal etablere en dos miljø. I øvrigt tror jeg ikke at command.com ligger i c:\windows, men bare i C:\ (eller måske c:\command)
En anden ting jeg vil råde dig til mens du tester er at udskifte NoWait med AndWait således at du kan se hvad der foregår. En ande mulighed er at lave en batfil der tager et argument og sender dette til printeren:
prnt.bat: type %1 > prn
og i linie skrive:
WinExecNoWait('{drive-sti}\prnt.bat','{drive-sti}\filnavn-der-skal-printes.txt'); hvis du forstår hvad jeg mener.
Hvis det er helt galt skal jeg prøve at lave et lille program på min W95 maskine (delphi2) og se hvordan det ter sig. Det kan jeg evt. gøre i løbet af eftermiddagen.
NB! Lige en ekstra ting: Fejl 2: kunne ikke starte program er ensbetydende med at 1. den kunne ikke finde programmet eller 2. programmet er ikke en exe, com eller bat fil.
udskriv? Jeg har kørt step-run mange gange og hver gang opstår fejl 2 i CreateProcess, hvis det er et dos-prg, mens det ikke er nogen fejl hvis det er et win prg.
prnt.bat: (som test) type c:\print.txt > prn; denne bat virker fint, hvis jeg dobbelt-klikker, men igen en fejl2 i D5.
Jeg venter spænt på at høre hvordan din W95 opføre sig
Jeg har nu testet det på win95 og du har ret. Det virker ikke. Det er fordi CreateProcess er skabt til 32bit prorammer (som windows) og en dosboks er 16bit
Men løsningen er så følgende:
1. Glem createprocess og brug winexec i stedet. Selvom MS siger den er "fased out" så gælder det jo kun for nyere versioner af windows, ikke Win95.
2. Brug en batfil der udfører selve kopieringen. (type xxx > lpt1:)
Sådan:
i programmet skriver du:
winexec(pchar('c:\prnt.bat '+edit1.text),sw_show); // edit1.text indeholder filnavn på fil der skal udskrives
og du opretter en batfil (i dette tilfælde i c-root) der hedder prnt.bat med følgende indhold:
type %1 > lpt1:
Det virker på min Win95. Testprogrammet er lavet i D2, men er gældende både for D3, og D4. D5 har jeg ikke prøvet med.
NB! %1 i batfilen betyder "første parameter" og det er filnavnet.
Jeg håber at du får det til at virke. God fornøjelse,
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.