HBPrintPDF - Bitmap als Hintergrundformular
Moderator: Moderatoren
HBPrintPDF - Bitmap als Hintergrundformular
Hallo Hubert,
ich nutze Deine Klasse mit QuickPDF Version 11. Ich bin damit sehr zufrieden.
Ich habe bisher Formulare in der Weise als PDF erstellt, dass ich ein BMP als Form drucke und dann die Daten "drüber" drucke.
Das BMP ist über ARC in der EXE gelinkt.
Jetzt möchte ich das BMP in eine DLL auslagern. Ich habe es jedoch nicht geschafft, das BMP zu drucken. Ich weiß nicht, wo ich die DLL angeben muss.
Hast Du ein Beispiel oder einen Tipp, wie das funktioniert?
Viele Grüße
Heinz
ich nutze Deine Klasse mit QuickPDF Version 11. Ich bin damit sehr zufrieden.
Ich habe bisher Formulare in der Weise als PDF erstellt, dass ich ein BMP als Form drucke und dann die Daten "drüber" drucke.
Das BMP ist über ARC in der EXE gelinkt.
Jetzt möchte ich das BMP in eine DLL auslagern. Ich habe es jedoch nicht geschafft, das BMP zu drucken. Ich weiß nicht, wo ich die DLL angeben muss.
Hast Du ein Beispiel oder einen Tipp, wie das funktioniert?
Viele Grüße
Heinz
Das einzige, was ich weiß ist, dass ich nichts weiß, Sokrates
- brandelh
- Foren-Moderator
- Beiträge: 15707
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 71 Mal
- Danksagung erhalten: 38 Mal
- Kontaktdaten:
Re: HBPrintPDF - Bitmap als Hintergrundformular
Hi,
zeig doch mal die ARC und CH Dateien mit denen du die Bitmap (welche ART ?) anlegst,
sowie die PRG Auszüge mit denen du die Bitmap aus der Exe liest und an QuickPDF weiter gibst.
Beim Resourcen laden braucht man eigentlich nur die DLL angeben in der die neue Resource liegen soll.
Bei der Weitergabe an QuickPDF sollte sich nichts ändern.
zeig doch mal die ARC und CH Dateien mit denen du die Bitmap (welche ART ?) anlegst,
sowie die PRG Auszüge mit denen du die Bitmap aus der Exe liest und an QuickPDF weiter gibst.
Beim Resourcen laden braucht man eigentlich nur die DLL angeben in der die neue Resource liegen soll.
Bei der Weitergabe an QuickPDF sollte sich nichts ändern.
Gruß
Hubert
Hubert
Re: HBPrintPDF - Bitmap als Hintergrundformular
Hallo,
mache ich, brauche jedoch ein wenig Zeit...
Grüße
Heinz
mache ich, brauche jedoch ein wenig Zeit...
Grüße
Heinz
Das einzige, was ich weiß ist, dass ich nichts weiß, Sokrates
- brandelh
- Foren-Moderator
- Beiträge: 15707
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 71 Mal
- Danksagung erhalten: 38 Mal
- Kontaktdaten:
Re: HBPrintPDF - Bitmap als Hintergrundformular
die haben wir ... und lassen sie uns nicht nehmen
Gruß
Hubert
Hubert
Re: HBPrintPDF - Bitmap als Hintergrundformular
Hallo,
diesen Code benutze ich:
Die Version "Alt" funktioniert.
In der Version "Neu" werden die BMP zusammen mit einer kleinen PRG in die DLL GBR.DLL gelinkt.
In der Gb.EXE verbleiben die Icons und andere BMP (Buttons etc.), siehe Gb.Arc
Ich benutze Huberts HBPrintPDF.
Wo kann ich jetzt angeben, dass das BMP nicht mehr aus der Exe, sondern aus der GBR.DLL geladen wird?
Grüße
Heinz
diesen Code benutze ich:
Code: Alles auswählen
********************************** Alt
// GB.ARC
...
USERDEF MANIFEST
MANIFEST_RESID = FILE "gb.exe.manifest"
VERSION
"CompanyName" = "HEN"
...
ICON 101 = "ENA.ICO"
BITMAP 501 = "ena11.bmp" /
...
FUNCTION cl_PrnPdf()
...
oHBPDF := HBPrintPDF():new():create( GetQuickPDFLizenzKey() )
...
cl_PrnBMPPdf( oHBPdf, aPrnPara )
...
RETURN .T.
FUNCTION cl_PrnBMPPdf( oHBPdf, aPrnPara )
LOCAL lSuccess:=.F.
...
* nID ist 501
* Druck der Form, BMP aus Gb.exe
IF !EMPTY(cFileName)
oHBPDF:CompressImages(1)
lSuccess := oHBPDF:DrawImageFile( nX, nY, nXSize, nYSize, 0, 0, 0, cFileName )
ELSE
IF !EMPTY(nID)
oHBPDF:CompressImages(1)
lSuccess := oHBPDF:DrawImageResource( nX, nY, nXSize, nYSize, 0, 0, 0, nID )
ENDIF
ENDIF
* Druck des Textes über das BMP
RETURN lSuccess
*
********************************** Neu
// GB_Res.ARC
BITMAP 501 = "ena11.bmp"
Gb.xpj
[PROJECT]
COMPILE = xpp
COMPILE_FLAGS = /q
DEBUG = yes
GUI = no
LINKER = alink
LINK_FLAGS =
RC_COMPILE = arc
RC_FLAGS =
VERSION = 2.1
GB.XPJ
[GB.XPJ]
GB.exe
GB.dll
GBR.dll
[GB.exe]
...
[GB.dll]
...
[GBR.dll]
COMPILE = xpp
COMPILE_FLAGS = /DLL:DYNAMIC /wi /wu /q /p /w /d_GbLk /d_HEN2
DEBUG_SAVE = yes
GUI = yes
LINKER = ALINK
LINK_FLAGS = /debug /dll
RC_COMPILE = ARC
RC_FLAGS = /v
OBJ_DIR = K:\XPP2\OBJ\GB
// $START-AUTODEPEND
GB_Res.obj
.\GB.lib
GBR.def
..\..\Source\Gb\GB_Res.res
// $STOP-AUTODEPEND
..\..\Source\Gb\GB_Res.ARC
..\..\Source\Gb\GB_Res.PRG
In der Version "Neu" werden die BMP zusammen mit einer kleinen PRG in die DLL GBR.DLL gelinkt.
In der Gb.EXE verbleiben die Icons und andere BMP (Buttons etc.), siehe Gb.Arc
Ich benutze Huberts HBPrintPDF.
Wo kann ich jetzt angeben, dass das BMP nicht mehr aus der Exe, sondern aus der GBR.DLL geladen wird?
Grüße
Heinz
Das einzige, was ich weiß ist, dass ich nichts weiß, Sokrates
- brandelh
- Foren-Moderator
- Beiträge: 15707
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 71 Mal
- Danksagung erhalten: 38 Mal
- Kontaktdaten:
Re: HBPrintPDF - Bitmap als Hintergrundformular
Ich verstehe wo dein Problem ist
Normalerweise nutzt man in Xbase++ diesen Befehl um eine Resource BMP zu laden:
Wenn [<nDll|cDll>] leer ist, holt er sich z.B. die Bitmap aus der EXE, ansonsten gibt man die DLL (als Name oder ID nach dllload() ) ... oder man nutzt XbpBitmap() direkt:
Bei PDF Dateien ist es mit den Bildern etwas anders als bei normalem Drucken.
Eine PDF bindet eine BITMAP genau EINMAL in die Datei ein und vergibt Name und/oder ID.
Danach druckt man mit dieser ID, welche NICHT der im Xbase++ Programm verwendeten ResourceID entspricht, daher ist auch keine DLL Angabe in dem obigen Befehl möglich.
Je nachdem was man im Xbase++ Programm schon hat, kann man verschiedene Befehle nutzen um die Grafik in die PDF zu bekommen.
Für dich dürfte das am Besten passen (Resource wurde noch NICHT in XbpBitmap geladen):
HBPrintPDF:PrintBmp( nPosX, nPosY, nXSize, nYSize, cFileNameID, nID, nHAlign, nVAlign, nRotate, nBox, nDotsPerUnit ) - sehen wir den Quellcode an:
der letzte Teil passt wohl für dich am Besten, solange du die Bitmap aus der Resource nicht schon geladen hast (wie ganz oben erwähnt):
cFileNameID := "MeineBitmapinDLL.DLL"
nID := 501 // besser einen NAMEN per CH Datei (#define bmpHintergrund 501)
HBPrintPDF:PrintBmp( nPosX, nPosY, nXSize, nYSize, cFileNameID, nID, nHAlign, nVAlign, nRotate, nBox, nDotsPerUnit )
Intern wird der Befehl dann die Bitmap in die PDF laden und verwenden:
wie man sieht, wird eine Resource einer DLL nur einmal in die PDF eingebunden und danach einfach wieder verwendet.
Allerdings muss ich hier feststellen, dass zwei gleiche ResourceIDs in zwei verschiedenen DLL so nicht möglich sind, da immer die ID der ersten Bitmap benutzt wird. Unschön ... wohl ein Fehler.
Auf jeden Fall solltest du dir die PDF Hilfe zu QuickPDF ansehen, AddImage* DrawImage* und verschiedene Manipulationsbefehle.
Zu jedem Namen findest du eine Methode hier, wobei ich auch zusätzliche aufgenommen habe um das Leben zu erleichtern.
Wenn z.B. eine Variable schon mit XbpBitmap():load ... mit einer Grafik oder Resourcegrafik geladen wurde, kann man die direkt übergeben und die Methode kümmert sich um den BMP Header:
Ich meine diese Befehle sind alle in der 11er Version enthalten.
Normalerweise nutzt man in Xbase++ diesen Befehl um eine Resource BMP zu laden:
Code: Alles auswählen
LoadResource( <nResId>|<cResId>, [<nDll|cDll>], [<nRestype>|<cResType>], <nLanguageId|cLanguageId> ) --> xResource
Code: Alles auswählen
XbpBitmap()
Syntax
:load( [<cDLLname>], <nID> ) --> lSuccess
Eine PDF bindet eine BITMAP genau EINMAL in die Datei ein und vergibt Name und/oder ID.
Danach druckt man mit dieser ID, welche NICHT der im Xbase++ Programm verwendeten ResourceID entspricht, daher ist auch keine DLL Angabe in dem obigen Befehl möglich.
Je nachdem was man im Xbase++ Programm schon hat, kann man verschiedene Befehle nutzen um die Grafik in die PDF zu bekommen.
Für dich dürfte das am Besten passen (Resource wurde noch NICHT in XbpBitmap geladen):
HBPrintPDF:PrintBmp( nPosX, nPosY, nXSize, nYSize, cFileNameID, nID, nHAlign, nVAlign, nRotate, nBox, nDotsPerUnit ) - sehen wir den Quellcode an:
Code: Alles auswählen
*---------------------------------------------------
METHOD HBPrintPDF:PrintBmp( nPosX, nPosY, nXSize, nYSize, cFileNameID, nID, nHAlign, nVAlign, nRotate, nBox, nDotsPerUnit )
local nImageID, lFehler := .f., cErrTxt, nDLL, nOldLineWidth, nOldImage // cFileNameID = C or N ...
...
nOldImage := ::SelectedImage() // die selektierte Image-ID (Bitmap) für folgende Image Befehle
do case
case nID==NIL .and. empty(cFileNameID)
// Keine Resource, Kein Dateiname, Kein Stringpuffer => aktuell selektierte Grafik benutzen !
...
case nID==NIL .and. valtype(cFileNameID)=="C" // Datei auf Festplatte nutzen
// Dateiname !
nImageID := ::AddImageFile(cFileNameID,0)
...
case nID==NIL .and. valtype(cFileNameID)=="N"
// Image ID ! - also die ID einer schon enthaltenen Bitmap in der PDF !
if ::SelectImage(cFileNameID)
...
case nID==NIL
// ERROR
...
case nID == -1 // XbpBitmap SetBuffer() String
if valtype(cFileNameID)=="C" .and. ! empty(cFileNameID)
nImageID := ::AddImageFromXbpBMP(cFileNameID) // XbpBitmap als Bitmap hinzufügen
...
case nID > 0 // RESOURCE ID DER EXE ODER DLL
// *** das müsste für dich am Besten passen ***
if valtype(cFileNameID)=="C" .and. ! empty(cFileNameID) // IN DLL
nDLL := DllLoad(cFileNameID)
else
nDLL := NIL
endif
nImageID := ::AddImageResource(nID,0,nDLL)
if nImageID > 0
// OK
else
cErrTxt := "RESOURCE-ID NOT VALID"
lFehler := .t.
endif
otherwise
...
end
Code: Alles auswählen
case nID > 0 // RESOURCE ID DER EXE ODER DLL
// *** das müsste für dich am Besten passen ***
if valtype(cFileNameID)=="C" .and. ! empty(cFileNameID) // IN DLL
nDLL := DllLoad(cFileNameID)
else
nDLL := NIL
endif
nImageID := ::AddImageResource(nID,0,nDLL)
nID := 501 // besser einen NAMEN per CH Datei (#define bmpHintergrund 501)
HBPrintPDF:PrintBmp( nPosX, nPosY, nXSize, nYSize, cFileNameID, nID, nHAlign, nVAlign, nRotate, nBox, nDotsPerUnit )
Intern wird der Befehl dann die Bitmap in die PDF laden und verwenden:
Code: Alles auswählen
// -------------------------------------------------------------------------------------------------------------------
METHOD HBPrintPDF:AddImageResource(nResourceID,nOptions,nDLL) // ONLY / NUR BMP BITMAP RESOURCEN !!!
LOCAL nImageID, cImageName
DEFAULT nResourceID TO 0
if nResourceID > 0
cImageName := "RES_ID_"+alltrim(str(nResourceID))
// schon vorhanden ?
nImageID := ::GetImageIDByName(cImageName) // ist das Image schon enthalten / only once
if nImageID == 0
nImageID := ::AddImageFromString( ::cLoadResource(nDLL,nResourceID, 2, , .t. ) , nOptions )
if nImageID > 0 // OK !
::AddImageID(nImageID,cImageName)
endif
endif
endif
return nImageID
Allerdings muss ich hier feststellen, dass zwei gleiche ResourceIDs in zwei verschiedenen DLL so nicht möglich sind, da immer die ID der ersten Bitmap benutzt wird. Unschön ... wohl ein Fehler.
Auf jeden Fall solltest du dir die PDF Hilfe zu QuickPDF ansehen, AddImage* DrawImage* und verschiedene Manipulationsbefehle.
Zu jedem Namen findest du eine Methode hier, wobei ich auch zusätzliche aufgenommen habe um das Leben zu erleichtern.
Wenn z.B. eine Variable schon mit XbpBitmap():load ... mit einer Grafik oder Resourcegrafik geladen wurde, kann man die direkt übergeben und die Methode kümmert sich um den BMP Header:
Code: Alles auswählen
// -------------------------------------------------------------------------------------------------------------------
METHOD HBPrintPDF:AddImageFromXbpBMP(cBMP) // NUR BEI BMP für Rückgabewert von XbpBitmap():setBuffer() !!! *.BMP !!!
// ONLY with BMP and return value from XbpBitmap():setBuffer()!!! *.BMP !!!
if left(cBMP,2) # "BM"
cBMP := "BM"+U2BIN(len(cBMP)+14)+W2BIN(0)+W2BIN(0)+U2BIN(BIN2U(left(cBMP,4))+14)+cBMP
endif
return ::AddImageFromString(cBMP,0) // !!! *.BMP !!!
Gruß
Hubert
Hubert
Re: HBPrintPDF - Bitmap als Hintergrundformular
Hallo Hubert,
vielen Dank für Deinen Einsatz und die schnelle Antwort.
Ich habe es gestern Abend hinbekommen, wahrscheinlich aber auf eine abenteuerliche Weise.
Ich habe das BMP außerhalb Deiner Klasse mit XbpBitmap geladen. Das Laden der DLL mit dem BMP und die Übergabe von nDLL an AddImageResource ist mir nicht gelungen. Deshalb habe ich zuerst DrawImageResource und dann AddImageResource um den Parameter cBMP erweitert und das BMP übergeben. In AddImageResource wird dann nicht mehr ::cLoadResource ausgeführt, sondern mit AddImageFromXbpBMP der Header hinzugefügt. Dann zurück in DrawImageResource wird noch FitImage ausgeführt (unbedingt erforderlich?).
Hier mein Code (Aufruf):
und die Änderungen Deiner Klasse (in ii/Ende ii eingeschlossen):
Wie gesagt, wahrscheinlich nicht so elegant gelöst, es funktioniert aber.
Nochmals vielen Dank!
Viele Grüße
Heinz
vielen Dank für Deinen Einsatz und die schnelle Antwort.
Ich habe es gestern Abend hinbekommen, wahrscheinlich aber auf eine abenteuerliche Weise.
Ich habe das BMP außerhalb Deiner Klasse mit XbpBitmap geladen. Das Laden der DLL mit dem BMP und die Übergabe von nDLL an AddImageResource ist mir nicht gelungen. Deshalb habe ich zuerst DrawImageResource und dann AddImageResource um den Parameter cBMP erweitert und das BMP übergeben. In AddImageResource wird dann nicht mehr ::cLoadResource ausgeführt, sondern mit AddImageFromXbpBMP der Header hinzugefügt. Dann zurück in DrawImageResource wird noch FitImage ausgeführt (unbedingt erforderlich?).
Hier mein Code (Aufruf):
Code: Alles auswählen
*Laden und Rückgabe des BMP
lSuccess := cl_LRes(cFileNameID,nID,, @cBMP)
IF lSuccess
*Aufruf Deine Klasse und Übergabe des BMP
lSuccess := oHBPDF:DrawImageResource( nX, nY, nXSize, nYSize, 0, 0, 0, nID, , cBMP)
ENDIF
Code: Alles auswählen
*METHOD HBPrintPDF:AddImageResource(nResourceID,nOptions,nDLL) // ONLY / NUR BMP BITMAP RESOURCEN !!!
// ii
METHOD HBPrintPDF:AddImageResource(nResourceID,nOptions,nDLL,cBMP) // ONLY / NUR BMP BITMAP RESOURCEN !!!
// Ende ii
LOCAL nImageID, cImageName
DEFAULT nResourceID TO 0
if nResourceID > 0
cImageName := "RES_ID_"+alltrim(str(nResourceID))
// schon vorhanden ?
nImageID := ::GetImageIDByName(cImageName) // ist das Image schon enthalten / only once
if nImageID == 0
// ii
IF EMPTY(cBMP)
// Ende ii
nImageID := ::AddImageFromString( ::cLoadResource(nDLL,nResourceID, 2, , .t. ) , nOptions )
// ii
ELSE
nImageID := ::AddImageFromXbpBMP(@cBMP)
// ii
ENDIF
// Ende ii
if nImageID > 0 // OK !
::AddImageID(nImageID,cImageName)
endif
endif
endif
return nImageID
*METHOD HBPrintPDF:DrawImageResource(nLeft, nTop, nWidth, nHeight,nHAlign,nVAlign,nRotate,nResourceID,nOptions)
// ii
METHOD HBPrintPDF:DrawImageResource(nLeft, nTop, nWidth, nHeight,nHAlign,nVAlign,nRotate,nResourceID,nOptions,cBMP)
// Ende ii
local nImageID, lOK := .f.
* nImageID := ::AddImageResource(nResourceID,nOptions)
// ii
nImageID := ::AddImageResource(nResourceID,nOptions,,cBMP)
// Ende ii
if nImageID > 0
lOK := ::FitImage(nLeft, nTop, nWidth, nHeight,nHAlign,nVAlign,nRotate)
endif
return lOK
Nochmals vielen Dank!
Viele Grüße
Heinz
Das einzige, was ich weiß ist, dass ich nichts weiß, Sokrates