Suche Print-Routine für einen Texteditor
Moderatoren: crack, Krüsty, Marwin
-
Paulchen
- Member
- Beiträge: 11
- Registriert: Samstag 6. Mai 2006, 13:02
- Wohnort: 16727 Oberkrämer/Schwante
Suche Print-Routine für einen Texteditor
Hallo,
ich suche einen Experten der mir helfen kann. Für einen Texteditor aus Masm32-Paket suche ich noch eine Druckroutine. Ich habe das Programm teilweise erweitert und nach meinem Verständnis umgeschrieben. Leider habe keine Ahnung wie man Texte ausdruckt. Ich habe einen Standard-Tintendrucker (Farbe + Schwarzweiß)von HP. Hinweise auf Druckroutinen in einer höheren Programmiersprache nutzen mir nichts. Leider kann ich mit diesen Sprachen nichts anfangen. Englisch kann ich auch nicht. Meine Schulzeit liegt schon 48 Jahre zurück.
Mit freundlichen Grüßen
Paulchen
ich suche einen Experten der mir helfen kann. Für einen Texteditor aus Masm32-Paket suche ich noch eine Druckroutine. Ich habe das Programm teilweise erweitert und nach meinem Verständnis umgeschrieben. Leider habe keine Ahnung wie man Texte ausdruckt. Ich habe einen Standard-Tintendrucker (Farbe + Schwarzweiß)von HP. Hinweise auf Druckroutinen in einer höheren Programmiersprache nutzen mir nichts. Leider kann ich mit diesen Sprachen nichts anfangen. Englisch kann ich auch nicht. Meine Schulzeit liegt schon 48 Jahre zurück.
Mit freundlichen Grüßen
Paulchen
- crack
- Administrator
- Beiträge: 280
- Registriert: Dienstag 21. Dezember 2004, 15:02
- Wohnort: 53783 Eitorf
- Kontaktdaten:
Im Prinzip ist es nicht so kompliziert ... Windows behandelt die üblichen Ein- und Ausgabegeräte ja auch als 'Dateiobjekt', also könntest Du einfach das 'Fileobjekt' mit dem Namen 'LPT1' durch die API Prozedur 'CreateFile' als Writefile öffnen, und hineinschreiben, und zum Schluss wieder schliessen.... Ich werde mal einige Versuche in der Richtung anstellen, hier habe ich etwas ähnliches allerdings bezgl. der selben Problematik in C++ gefunden: drucken ...
mfg. Crack
mfg. Crack
mit freundlichen grüssen,
with best regards,
crack
with best regards,
crack
- crack
- Administrator
- Beiträge: 280
- Registriert: Dienstag 21. Dezember 2004, 15:02
- Wohnort: 53783 Eitorf
- Kontaktdaten:
Ja, ich habe es getestet, man kann es exakt so machen:
Das kannst Du so als Prozedur benutzen (natürlich müssen 'NBuffer' (der zu druckende Text) und 'Klartextgroesse' (länge des Textes) dann an dein Programm angepasst werden.
Code: Alles auswählen
PrintIt PROTO
.data
...
prn db "LPT1",0
...
.data?
hDatei dd ?
.code
...
PrintIt proc
invoke CreateFile,addr prn,GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0
mov hDatei,eax
invoke SetFilePointer, hDatei, NULL, NULL, FILE_END
invoke WriteFile, hDatei,addr NBuffer, Klartextgroesse, addr GeschriebeneBytes, NULL
invoke CloseHandle, hDatei
ret
PrintIt endp
...
...
mit freundlichen grüssen,
with best regards,
crack
with best regards,
crack
ich lege einfach mal paar Codeausschnitte bei .... Damals hatte ich das zuerst auch mit lpt &Co probiert, es musste aber auch für Netzwerkdrucker gehen, deswegen eine "allgemeinere" GDI-Basierende Lösung:
Gedruckt wird aus einem EDIT-Control heraus, ich hoffe Du kannst es weitesgehend anpassen. Die Schriftart musst Du wahrschenilch wirklich anpassen, da sie auf großgeschriebenen Asm-Quellcodeausgelegt wurde.
Man kann da sogar noch einiges kürzen, da ich damals unbediengt einen Copyrightvermerk am Anfang haben wollte :rolleyes:
zusätzlich hat man im Gegensatzt zum LPT Output den Vorteil 1.keine Probeleme mit den USB/Netzwerkdruckern
2 die Schriftart und Größe sind anpassbar - und man kann auch Seitenränder usw. einhalten.
Code: Alles auswählen
Quellcode_drucken proc
LOCAL pd:PRINTDLG
LOCAL DocInfo:DOCINFO
LOCAL LFont: TEXTMETRIC
LOCAL hFont:HANDLE
LOCAL buffer[129]:BYTE
.data
druckname db "ALI-Emulator ",169," by ***",0 ;das wird als Copyrightzeilge genutzt (gedruckt), kann eigentlich entfernt werden.
FontName db "MS Sans Serif",0
X DWORD X_MAX
Y DWORD Y_MAX
Numlines dd 0
.code
INVOKE PrintSetup, ADDR pd, hWin
invoke PrintDlg,addr pd
.if eax==0
ret
.endif
INVOKE CreateFont,80,0,0,0,FW_LIGHT,FALSE,FALSE,FALSE,ANSI_CHARSET,0,0,DEFAULT_QUALITY,0,addr FontName
mov hFont,eax
mov eax, sizeof DOCINFO
mov DocInfo.cbSize, eax
mov eax, offset druckname
mov DocInfo.lpszDocName, eax
mov DocInfo.lpszOutput, NULL
mov DocInfo.lpszDatatype, NULL
mov DocInfo.fwType, 0
INVOKE GetTextMetrics, pd.hDC, ADDR LFont
;druckstarten:
invoke StartDoc,pd.hDC,addr DocInfo
mov ecx,0 ;anzahl der Kopien
PRINT_LOOP:
push ecx
invoke StartPage,pd.hDC; Inhalt ausgeben
invoke SelectObject,pd.hDC,hFont
invoke SendDlgItemMessage,hWin,ID_PROGRAM_INPUT,EM_GETLINECOUNT,0,0
mov Numlines,eax
xor ecx,ecx
push ecx
mov X,X_MAX
mov Y,Y_MAX
invoke TextOut,pd.hDC,X,Y,addr druckname,25 ;wie erwähnt, copyrightzeile
mov eax, Y
add eax, LFont.tmHeight
add eax, LFont.tmExternalLeading
add eax, LFont.tmHeight
mov Y, eax
lea esi,buffer
mov WORD PTR [buffer],128
TEXT_LOOP:
pop ecx
push ecx
lea esi,buffer
invoke SendDlgItemMessage,hWin,ID_PROGRAM_INPUT,EM_GETLINE,ecx,esi
mov edx,eax
lea esi,buffer
add esi,2 ;da wir ein Word für Größe des Textes haben
invoke TextOut,pd.hDC,X,Y,addr buffer,edx
mov eax, Y
add eax, LFont.tmHeight
add eax, LFont.tmExternalLeading
mov Y, eax
pop ecx
inc ecx
push ecx
cmp ecx,Numlines
jng TEXT_LOOP
pop ecx
;enden
invoke EndPage,pd.hDC;
pop ecx
inc ecx
cmp cx, pd.nCopies
jg PRINT_LOOP
invoke EndDoc,pd.hDC;
invoke DeleteDC,pd.hDC
.if pd.hDevMode != NULL
invoke GlobalFree,pd.hDevMode
.endif
.if (pd.hDevNames != NULL)
invoke GlobalFree,pd.hDevNames;
.endif
ret
Quellcode_drucken endp
Code: Alles auswählen
PrintSetup PROC PSprintdlg:DWORD, hWnd:DWORD
push edi
mov edi, PSprintdlg
mov eax, sizeof PRINTDLG
mov [edi].PRINTDLG.lStructSize, eax
mov eax, hWnd
mov [edi].PRINTDLG.hWndOwner, eax
mov [edi].PRINTDLG.hDevMode, NULL
mov [edi].PRINTDLG.hDevNames, NULL
mov [edi].PRINTDLG.hDC, NULL
mov [edi].PRINTDLG.Flags, PD_RETURNDC OR PD_NOSELECTION OR PD_NOPAGENUMS
mov [edi].PRINTDLG.nFromPage, 0
mov [edi].PRINTDLG.nToPage, 0
mov [edi].PRINTDLG.nMinPage, 0
mov [edi].PRINTDLG.nMaxPage, 0
mov [edi].PRINTDLG.nCopies, 1
mov [edi].PRINTDLG.hInstance, NULL
mov [edi].PRINTDLG.lCustData, 0
mov [edi].PRINTDLG.lpfnPrintHook, NULL
mov [edi].PRINTDLG.lpfnSetupHook, NULL
mov [edi].PRINTDLG.lpPrintTemplateName, NULL
mov [edi].PRINTDLG.lpPrintSetupTemplateName, NULL
mov [edi].PRINTDLG.hPrintTemplate, NULL
mov [edi].PRINTDLG.hSetupTemplate, NULL
pop edi
ret
PrintSetup ENDP
Man kann da sogar noch einiges kürzen, da ich damals unbediengt einen Copyrightvermerk am Anfang haben wollte :rolleyes:
zusätzlich hat man im Gegensatzt zum LPT Output den Vorteil 1.keine Probeleme mit den USB/Netzwerkdruckern
2 die Schriftart und Größe sind anpassbar - und man kann auch Seitenränder usw. einhalten.
-
Paulchen
- Member
- Beiträge: 11
- Registriert: Samstag 6. Mai 2006, 13:02
- Wohnort: 16727 Oberkrämer/Schwante
Suche Print-Routine für einen Texteditor
Hallo,
vielen Dank an alle Experten die mir bisher geantwortet haben. Ein besonderes Dankeschön geht an EBFE der sich viel Mühe gemacht hat.
Wenn ich wieder meht Zeit habe werde ich Ihre Vorschläge ausprobieren.
Z.ZT. ist viel Gartenarbeit angesagt und der Computer bleibt aus.
Mit freundlichen Grüßen
Paulchen
vielen Dank an alle Experten die mir bisher geantwortet haben. Ein besonderes Dankeschön geht an EBFE der sich viel Mühe gemacht hat.
Wenn ich wieder meht Zeit habe werde ich Ihre Vorschläge ausprobieren.
Z.ZT. ist viel Gartenarbeit angesagt und der Computer bleibt aus.
Mit freundlichen Grüßen
Paulchen
-
Paulchen
- Member
- Beiträge: 11
- Registriert: Samstag 6. Mai 2006, 13:02
- Wohnort: 16727 Oberkrämer/Schwante
Suche Print-Routine für einen Texteditor
Hallo EBFE,
habe mir Ihre Druckroutine angesehen und versucht sie zu verstehen.
Einige Dinge sind mir nicht klar.
1. Das Handle hWnd ist sicher das Handle des Elternfensters und nicht das des Richedit-Steuerelementes?
2. Welche Werte muß man für X-und Y_MAX angeben und was bedeuten sie?
3. Was bedeutet ID_PROGRAMM_INPUT und was muß dafür angeben?
Ich würde mich freuen wenn Sie mir nochmals helfen könnten.
Mit freundlichen Grüßen
Paulchen
habe mir Ihre Druckroutine angesehen und versucht sie zu verstehen.
Einige Dinge sind mir nicht klar.
1. Das Handle hWnd ist sicher das Handle des Elternfensters und nicht das des Richedit-Steuerelementes?
2. Welche Werte muß man für X-und Y_MAX angeben und was bedeuten sie?
3. Was bedeutet ID_PROGRAMM_INPUT und was muß dafür angeben?
Ich würde mich freuen wenn Sie mir nochmals helfen könnten.
Mit freundlichen Grüßen
Paulchen
korrekt. In meinem Fall ist es das Handle zum Hauptdialogfenster.1. Das Handle hWnd ist sicher das Handle des Elternfensters und nicht das des Richedit-Steuerelementes?
Das sind die "Startwerte" für den Druckanfang der jeweiligen Seite: also an welcher logischer Koordinate der Text gezeichnet werden soll. "Logical" heißt eigentlich nicht pixelabhängig sondern "angepasst" an die Ausgabe. X_MAX ist bei mir 15 - damit hat man immer eine bestimmte Randbreite links. Für den Zeilenumbruch sollte der Editor sorgen und der Rand rechts ist undefiniert.2. Welche Werte muß man für X-und Y_MAX angeben und was bedeuten sie?
Wobei die Startwerte durch "Ausprobieren" ermittelt wurden (wie erwähnt,damals wollte ich unbediengt vorher ein Copyright vorher drucken).
Ansonsten wird mit Textmetric gearbetet:
(Interessant ist dabei nur der code im Textloop), so dass man unabhängig von der gewählten Schrift immer einen bestimmten Zeilenabstand hat.mov eax, Y
add eax, LFont.tmHeight
add eax, LFont.tmExternalLeading
mov Y, eax
Hier bietet sich auch an, anstatt mit dem festen Wert 15 für X tmWeight
zu verwenden.
das ist die ID meines EDIT-Controls. Da wird der Text zeilenweise "ausgelesen".richEdit sollte analog funktionieren.3. Was bedeutet ID_PROGRAMM_INPUT und was muß dafür angeben?
-
Paulchen
- Member
- Beiträge: 11
- Registriert: Samstag 6. Mai 2006, 13:02
- Wohnort: 16727 Oberkrämer/Schwante
Suche Print-Routine für Texteditor
Hallo EBFE,
habe Ihre Druckroutine für ein Richedit1-Steuerelement umgegeschrieben. Funktioniert gut. Schicke sie Ihnen mit. Bekomme sie aber nur sehr unübersichtlich in das Fenster.
Mit freundlichen Grüßen
Paulchen
name Drucken
title "Text ausdrucken"
Drucken PROTO
PrintSetup PROTO :DWORD,:DWORD
X_MAX equ 120 ;Breite linker Seitenrand
Y_MAX equ 20
.data
FontName db "MS Sans Serif",0
X DWORD X_MAX
Y DWORD Y_MAX
.code
align 4
Drucken proc
LOCAL pd:PRINTDLG ;Struktur für Printdialog
LOCAL DocInfo:DOCINFO ;Struktur für StartDoc
LOCAL LFont: TEXTMETRIC
LOCAL hFont:HANDLE ;Handle Schriftart
LOCAL buffer[130]:BYTE ;I/O für Zeile
LOCAL AnzZeilen:DWORD ;Anzahl Zeilen
LOCAL ZeilenIndex:DWORD ;Zeilennummer im Control
LOCAL LgPfad:DWORD ;L'Pfad der Datei
LOCAL AnzKopien:DWORD ;Anzahl Kopien
LOCAL ZProSeite:DWORD ;Zeilen pro Seite
mov AnzZeilen,0 ;Anzzahl Zeilen im Control löschen
mov ZeilenIndex,0 ;Zeilennummer im Control löschen
mov ZProSeite,0 ;Zeilen pro Seite löschen
invoke SendMessage,hWnd,WM_GETTEXTLENGTH,0,0 ;L'Fenstername holen
mov LgPfad,eax ;Länge sichern
invoke PrintSetup, ADDR pd,hWnd ;Struktur für Printdialog füllen
invoke PrintDlg,addr pd ;Printdialog aufrufen
cmp eax,0 ;Abbruch?
je druckende ;ja
;
;*** Schriftart 'MS Sans Serif' erzeugen
;
invoke Font,50,0,0,0,FW_LIGHT,FALSE,FALSE,FALSE,ANSI_CHARSET,0,0,\
DEFAULT_QUALITY,0,addr FontName ;Schriftart MS Sans Serif erzeugen
mov hFont,eax ;Handle Schriftart
;
;*** Struktur DOCINFO versorgen
;
mov DocInfo.cbSize, sizeof DOCINFO ;L' der Struktur DOCINFO
mov eax, offset szFileName ;Pfadname
mov DocInfo.lpszDocName, eax
mov DocInfo.lpszOutput, NULL
mov DocInfo.lpszDatatype, NULL
mov DocInfo.fwType, 0
invoke GetTextMetrics, pd.hDC, ADDR LFont ;Metrische Eigenschaften der Schriftart bestimmen
invoke SendMessage,hRichEd,EM_GETLINECOUNT,0,0 ;Anz. Zeilen im Steuerelement holen
mov AnzZeilen,eax ;Anzahl Zeilen sichern
;
;*** Druckauftrag starten
;
invoke StartDoc,pd.hDC,addr DocInfo
mov AnzKopien,0 ;Anzahl der Kopien
print_loop:
invoke StartPage,pd.hDC ;neue Seite
invoke SelectObject,pd.hDC,hFont ;selektiere Gerätekontext
mov X,X_MAX
mov Y,Y_MAX
mov eax,LgPfad
invoke TextOut,pd.hDC,X,Y,addr szFileName,eax ;Pfad der Datei
mov eax, Y
add eax, LFont.tmHeight
add eax, LFont.tmExternalLeading
add eax, LFont.tmHeight
mov Y, eax
text_loop:
mov WORD PTR [buffer],128 ;max. Zeilenlänge
invoke SendMessage,hRichEd,EM_LINELENGTH,ZeilenIndex,0 ;Zeilenlänge holen
invoke SendMessage,hRichEd,EM_GETLINE,ZeilenIndex,ADDR buffer ;Zeile lesen
sub eax,2 ;wahrscheinlich am Ende der Zeile X'OD0A'
invoke TextOut,pd.hDC,X,Y,ADDR buffer,eax ;Zeile ausgeben
mov eax, Y
add eax, LFont.tmHeight
add eax, LFont.tmExternalLeading
mov Y, eax
inc ZeilenIndex ;Index Zeilennummer + 1
inc ZProSeite ;Zeile pro Seite + 1
cmp ZProSeite,62 ;62 Zeilen pro Seite?
jne text_loop10 ;nein
invoke EndPage,pd.hDC ;Ende der Seite
mov ZProSeite,0 ;Zähler pro Seite auf 0
jmp print_loop ;neue Seite
text_loop10:
mov eax,ZeilenIndex ;ZeilenIndex
cmp eax,AnzZeilen ;alle Zeilen gedruckt?
jng text_loop ;nein
invoke EndPage,pd.hDC ;Ende der Seite
invoke EndDoc,pd.hDC ;Ende Druckauftrag
invoke DeleteDC,pd.hDC ;lösche Gerätekontext
.if pd.hDevMode != NULL
invoke GlobalFree,pd.hDevMode
.endif
.if (pd.hDevNames != NULL)
invoke GlobalFree,pd.hDevNames
.endif
druckende:
ret
Drucken endp
habe Ihre Druckroutine für ein Richedit1-Steuerelement umgegeschrieben. Funktioniert gut. Schicke sie Ihnen mit. Bekomme sie aber nur sehr unübersichtlich in das Fenster.
Mit freundlichen Grüßen
Paulchen
name Drucken
title "Text ausdrucken"
Drucken PROTO
PrintSetup PROTO :DWORD,:DWORD
X_MAX equ 120 ;Breite linker Seitenrand
Y_MAX equ 20
.data
FontName db "MS Sans Serif",0
X DWORD X_MAX
Y DWORD Y_MAX
.code
align 4
Drucken proc
LOCAL pd:PRINTDLG ;Struktur für Printdialog
LOCAL DocInfo:DOCINFO ;Struktur für StartDoc
LOCAL LFont: TEXTMETRIC
LOCAL hFont:HANDLE ;Handle Schriftart
LOCAL buffer[130]:BYTE ;I/O für Zeile
LOCAL AnzZeilen:DWORD ;Anzahl Zeilen
LOCAL ZeilenIndex:DWORD ;Zeilennummer im Control
LOCAL LgPfad:DWORD ;L'Pfad der Datei
LOCAL AnzKopien:DWORD ;Anzahl Kopien
LOCAL ZProSeite:DWORD ;Zeilen pro Seite
mov AnzZeilen,0 ;Anzzahl Zeilen im Control löschen
mov ZeilenIndex,0 ;Zeilennummer im Control löschen
mov ZProSeite,0 ;Zeilen pro Seite löschen
invoke SendMessage,hWnd,WM_GETTEXTLENGTH,0,0 ;L'Fenstername holen
mov LgPfad,eax ;Länge sichern
invoke PrintSetup, ADDR pd,hWnd ;Struktur für Printdialog füllen
invoke PrintDlg,addr pd ;Printdialog aufrufen
cmp eax,0 ;Abbruch?
je druckende ;ja
;
;*** Schriftart 'MS Sans Serif' erzeugen
;
invoke Font,50,0,0,0,FW_LIGHT,FALSE,FALSE,FALSE,ANSI_CHARSET,0,0,\
DEFAULT_QUALITY,0,addr FontName ;Schriftart MS Sans Serif erzeugen
mov hFont,eax ;Handle Schriftart
;
;*** Struktur DOCINFO versorgen
;
mov DocInfo.cbSize, sizeof DOCINFO ;L' der Struktur DOCINFO
mov eax, offset szFileName ;Pfadname
mov DocInfo.lpszDocName, eax
mov DocInfo.lpszOutput, NULL
mov DocInfo.lpszDatatype, NULL
mov DocInfo.fwType, 0
invoke GetTextMetrics, pd.hDC, ADDR LFont ;Metrische Eigenschaften der Schriftart bestimmen
invoke SendMessage,hRichEd,EM_GETLINECOUNT,0,0 ;Anz. Zeilen im Steuerelement holen
mov AnzZeilen,eax ;Anzahl Zeilen sichern
;
;*** Druckauftrag starten
;
invoke StartDoc,pd.hDC,addr DocInfo
mov AnzKopien,0 ;Anzahl der Kopien
print_loop:
invoke StartPage,pd.hDC ;neue Seite
invoke SelectObject,pd.hDC,hFont ;selektiere Gerätekontext
mov X,X_MAX
mov Y,Y_MAX
mov eax,LgPfad
invoke TextOut,pd.hDC,X,Y,addr szFileName,eax ;Pfad der Datei
mov eax, Y
add eax, LFont.tmHeight
add eax, LFont.tmExternalLeading
add eax, LFont.tmHeight
mov Y, eax
text_loop:
mov WORD PTR [buffer],128 ;max. Zeilenlänge
invoke SendMessage,hRichEd,EM_LINELENGTH,ZeilenIndex,0 ;Zeilenlänge holen
invoke SendMessage,hRichEd,EM_GETLINE,ZeilenIndex,ADDR buffer ;Zeile lesen
sub eax,2 ;wahrscheinlich am Ende der Zeile X'OD0A'
invoke TextOut,pd.hDC,X,Y,ADDR buffer,eax ;Zeile ausgeben
mov eax, Y
add eax, LFont.tmHeight
add eax, LFont.tmExternalLeading
mov Y, eax
inc ZeilenIndex ;Index Zeilennummer + 1
inc ZProSeite ;Zeile pro Seite + 1
cmp ZProSeite,62 ;62 Zeilen pro Seite?
jne text_loop10 ;nein
invoke EndPage,pd.hDC ;Ende der Seite
mov ZProSeite,0 ;Zähler pro Seite auf 0
jmp print_loop ;neue Seite
text_loop10:
mov eax,ZeilenIndex ;ZeilenIndex
cmp eax,AnzZeilen ;alle Zeilen gedruckt?
jng text_loop ;nein
invoke EndPage,pd.hDC ;Ende der Seite
invoke EndDoc,pd.hDC ;Ende Druckauftrag
invoke DeleteDC,pd.hDC ;lösche Gerätekontext
.if pd.hDevMode != NULL
invoke GlobalFree,pd.hDevMode
.endif
.if (pd.hDevNames != NULL)
invoke GlobalFree,pd.hDevNames
.endif
druckende:
ret
Drucken endp
-
Paulchen
- Member
- Beiträge: 11
- Registriert: Samstag 6. Mai 2006, 13:02
- Wohnort: 16727 Oberkrämer/Schwante
Suche Print-Routine für Texteditor
Hallo EBFE,
habe Ihre Druckroutine jetzt voll an meine Bedürfnisse angepaßt. Funktioniert auch mit einem Netzwerkdrucker. Ich möchte gerne noch wissen, wie man Fehlermeldungen vom Drucker abfangen kann.
Z.B. 'Drucker nicht eingeschaltet' oder 'Kein Papier im Druker' usw.
Wäre schön wenn Sie mir noch einmal helfen könnten.
Mit freundlichen Grüßen
Paulchen
habe Ihre Druckroutine jetzt voll an meine Bedürfnisse angepaßt. Funktioniert auch mit einem Netzwerkdrucker. Ich möchte gerne noch wissen, wie man Fehlermeldungen vom Drucker abfangen kann.
Z.B. 'Drucker nicht eingeschaltet' oder 'Kein Papier im Druker' usw.
Wäre schön wenn Sie mir noch einmal helfen könnten.
Mit freundlichen Grüßen
Paulchen