-
Dec 6th, 2014, 04:22 PM
#1
VB6 Render PDF-Files directly (and generate a Preview from the same DrawingRoutine)
Since the PDF-Printing-Topic comes up occasionally - sometimes with recommendations and links to
VB-Modules which try to write a PDF-file directly - the PDF-support of the cairo-lib (wrapped conveniently
in vbRichClient5.dll) is "miles ahead" of all these approaches in terms of functionality (the supported
Drawing-Commands) - and reliability (correctness of the generated PDF-Output).
So here's a small VB6-Demo which shows how to use a vbRichClient5.cCairoSurface instance, which
can also be created as "being of cairo-SurfaceType PDF" instead of the usual "ImgSurface-Type" which
is pixelbased and used for OnScreen-Output (BTW, another true VectorSurface-type is e.g. SVG,
which other than PDF can not only be written directly, but also read).
Anyways, in the end we are able to perform the very same Drawing-Commands against a CairoSurface
of type PDF, the same way as we are wont, when we take a CairoSurface of Type "Image" (which then
just renders antialiased against a Pixel-area to bring out the results of the VectorDrawing-Commands).
That transparently usable multi-surface-support of Cairo is one of the greatest advantages of this library IMO.
The demo will print two Pages (only the first one is currently rendered and shown as an OnScreen-Preview) -
but in the PDF-Document we will end up with a Portrait-Page - followed by a Landscape-Page with somewhat
different (simpler) content ( just wanted to show how to handle the swapping of Page-Orientations "on the go",
so that's the purpose of the simpler Landscape-Page).
Ok, here's the Demo-Code (which references the vbRichClient5 dependency, you will
have to download and install first, to be able to run the Example... from vbRichClient.com).
SimplePDF.zip
And here's a ScreenShot of the VB-OnScreen-Preview of the first Page - accompanied to the right
with the Preview of the PDF-Viewer (adjusted to show the two contained PDF-Document-Pages).
Edit: added a missing info to the RichClient-Library, this PDF-Demo depends on.
Olaf
Last edited by Schmidt; Dec 7th, 2014 at 08:40 AM.
-
Dec 7th, 2014, 03:00 AM
#2
Addicted Member
Re: VB6 Render PDF-Files directly (and generate a Preview from the same DrawingRoutin
-
Dec 7th, 2014, 08:45 AM
#3
Re: VB6 Render PDF-Files directly (and generate a Preview from the same DrawingRoutin
Originally Posted by jedifuk
this for vb6 ?? right ??
Yes it's for VB5/VB6, sorry - corrected the Opener-Post now about the missing dependency-info...
The Source-Project references the vbRichClient5 library, one will have to download and install first,
to be able to run the Example...
(The RC5-framework is a free contribution to the VBClassic-Community - and can be downloaded
from vbRichClient.com).
Olaf
-
Feb 1st, 2015, 04:46 AM
#4
Re: VB6 Render PDF-Files directly (and generate a Preview from the same DrawingRoutin
Hi,
I am getting error
ActiveX component can't create object
on this line -
Cairo.ImageList.AddImage "MyLogo", App.Path & "\2010_FIFA_World_Cup_logo.svg", 320, 320, True
And if I comment that out, I get same error on this line -
Set Srf = Cairo.CreateSurface(PgWidthPoints * OverScanFac, PgHeightPoints * OverScanFac) 'create a Pixel-Surface (with some Overscan)
I initially just placed vbRichClient5.dll into the app folder
That appeared to keep VB Reference dialog happy, but I get the error when Form is loading
I moved the dll into System32 folder (XP Pro)
and pointed the References dialog to that.
(I did not 'Install' Is that a problem ?)
Still get the errors
Help,
Rob
Last edited by Bobbles; Feb 1st, 2015 at 04:56 AM.
Reason: specified the DLL name
-
Feb 1st, 2015, 10:58 AM
#5
Re: VB6 Render PDF-Files directly (and generate a Preview from the same DrawingRoutin
Originally Posted by Bobbles
I initially just placed vbRichClient5.dll into the app folder...
That's not enough (not the right way to "go about it").
The vbRichClient5.dll is an ActiveX- (a COM-) Dll - and as such it needs to
be *registered* on a Developer-machine first.
On the Download-Site is statet:
Out of the contained dlls you'd have only:
- vbRichClient5.dll <-- this one here to register (either per regsvr32 in Admin-Mode - or per incl. Script: RegisterRC5inPlace.vbs)
- vb_cairo_sqlite.dll
- DirectCOM.dll
In addition, please keep those Dlls always together in their Folder - also when you deploy them with your App.
So (also taking into account the last sentence in the quote above),
it's a good idea to unzip the *complete* content of the downloaded Zip
into its own Folder on your Developer-machine - e.g. into C:\RC5\...
and then DoubleClick the small VBScript-File there (RegisterRC5inPlace.vbs).
After that you will be able to run most of the RC5-Demos without placing any
RC5-Binaries within the App- or Demo-Folders of the Code-examples you find.
Placing the RC5-Binaries in your App-Folder (or better, in a \Bin\-Folder below
your App-Folder) is only of importance, when it comes to "shipping your App".
That's possible with the RC5-package in a regfree manner - I've covered that in
a separate article, which you can find here:
http://www.vbforums.com/showthread.p...rectCOM-Helper
Take note, that the RC5-package will add about 2.3MB to your App-Deployment,
when you ship it compressed in *.zip-Format - or 1.6MB when you ship it in *.7z-format.
Olaf
-
Feb 2nd, 2015, 01:00 AM
#6
Re: VB6 Render PDF-Files directly (and generate a Preview from the same DrawingRoutin
Thanks Olaf,
For taking the trouble to explain it to me.
I followed your instructions and the program now previews and creates a PDF file.
I never deploy my programs.
I just give the user an exe, and they place it into a folder such as C:\ClipBuddy
And it can run without installation.
I avoid dependencies like the plague.
There are a couple that I use in one program.
What I do is create a VB6 project, with those dependencies, and no code.
I use the P&D Wizard to create an installer.
The user runs that once, every 100 years.
(They ignore the entry in the Start Menu.)
From that point on I can create EXEs and just give them to the user, and they will run, without installation.
I probably won't build your stuff into my 'once in a 100 years installer'
Can I remote in to their PC, and repeat the instructions you gave me ? <===
Thanks,
Rob
PS I wonder if it would be possible to enhance your program, to reduce the necessity to design every line of the PDF output.
For example, I (cough! Rod Stephens) have done a similar exercise with printing VB6 forms.
The VB6 Form print method, gives a blurry print (with some mis-alignment)
Rod Stephens has an example on his web site, which illustrates how to do a high definition print. And one can also send it to a picturebox, instead of the physical printer, to provide a Print Preview
http://www.vb-helper.com/howto_print...textboxes.html
This allows one to loop through any Form's controls, and replicate them to the printer (or Picturebox). Thus avoiding every new project, being a tedious coding task
Let me know if you think something similar could be done for your excellent PDF creation.
If you are curious, there is a much more comprehensive example that came with one of Rod's Graphics books. That is the one that I use.
I have been in touch with Rod over the years, and in fact was communicating with him a week ago (about a suggested improvement I made to one of his other examples).
I surely should be able to convince him to allow me to send you a copy of the very comprehensive HiRes project.
PPS I would like to share the comprehensive printing example with our members. I might raise that possibility with Rod. But I will hold back so as to increase the chances he will let me share it with you (for your PDF creation consideration)
-
Feb 3rd, 2015, 07:10 PM
#7
Re: VB6 Render PDF-Files directly (and generate a Preview from the same DrawingRoutin
Originally Posted by Bobbles
I just give the user an exe, and they place it into a folder such as C:\ClipBuddy
And it can run without installation.
I avoid dependencies like the plague.
As said above (and described in the article about regfree deployment) -
You can compile your new Executable with the RC5-dependency in a way,
which would allow you, to "ship your Exe" (along with an accompanying
\RC5Bin\ folder that simply needs to be placed beside your new Exe)...
(no setup required).
Originally Posted by Bobbles
I probably won't build your stuff into my 'once in a 100 years installer'
Can I remote in to their PC, and repeat the instructions you gave me ? <===
That would be one way to do it - but as just described - when you follow the
instructions given in the article here:
http://www.vbforums.com/showthread.p...rectCOM-Helper
... including the *.bas-HelperModule which was described there in the Article into your Exe-Project,
then you could ship the 3 RC5-Binaries in a SubFolder of a Zip, and let the User place this
SubFolder beside your new compiled Executable.
That would be it already... (though if you're not sure - then registering the RC5-
Dlls in the same way as you did yourself on your Dev-machine, would be Ok too).
Originally Posted by Bobbles
PS I wonder if it would be possible to enhance your program, to reduce the necessity to design every line of the PDF output.
For example, I (cough! Rod Stephens) have done a similar exercise with printing VB6 forms.
The VB6 Form print method, gives a blurry print (with some mis-alignment)
Rod Stephens has an example on his web site, which illustrates how to do a high definition print.
And one can also send it to a picturebox, instead of the physical printer, to provide a Print Preview
http://www.vb-helper.com/howto_print...textboxes.html
This allows one to loop through any Form's controls, and replicate them to the printer (or Picturebox).
Thus avoiding every new project, being a tedious coding task
Let me know if you think something similar could be done for your excellent PDF creation.
Yes, there's a relative easy way to marry old VB-Drawing-Code (with basically no changes)
with the Cairo-Drawing I've used here - the RC5 already contains a Class (cVBDraw), which
was written as a translator between old VB-Drawing-Commands and Cairo-Drawing.
This Class was so far only experimental (though the interfaces were already complete) -
and I've just implemented the still missing pieces of internal stuff, to be usable in a decent way.
So the following will require you to download the latest Version (5.0.23) of the RC5, which I've
just uploaded - so that the new internal enhancments on the cVBDraw-Class can do their work.
See the Explanations for a small VB-DemoProject further below.
Originally Posted by Bobbles
If you are curious, there is a much more comprehensive example that came with one of Rod's Graphics books. That is the one that I use.
I have been in touch with Rod over the years, and in fact was communicating with him a week ago (about a suggested improvement I made to one of his other examples).
I surely should be able to convince him to allow me to send you a copy of the very comprehensive HiRes project.
PPS I would like to share the comprehensive printing example with our members. I might raise that possibility with Rod. But I will hold back so as to increase the chances he will let me share it with you (for your PDF creation consideration)
More complex VB-Drawing-Code would be a really nice TestCase for the stuff which the following
Demo already includes and supports... So, feel free to direct your VB-Printing-Guru to this thread
here, to try out the example below - maybe the community gets a nice "donation"...
What I did was downloading the small routines of the VB-Form-Printing (and Preview-) Code you
provided a link to above - placing them in a modVBPrinting.bas module - and leaving them there -
basically unchanged (aside from small enhancements with regards to enabling a few more Font-Props -
and allowing also VB.ImageControls on the VB-Form (for the small Logo you see in the following ScreenShot):
Here's the slightly adapted Code I've taken over from your Link, as it is now included in the Demo-Zip here:
CairoVBPrinting.zip
Code:
Public Sub PrintFormFields(Prt As Printer, Frm As Form, Optional ByVal draw_box As Boolean)
Dim Ctl As Control, wid As Single, hgt As Single
Prt.DrawWidth = 15
Prt.ScaleMode = vbTwips
For Each Ctl In Frm.Controls
If TypeOf Ctl Is Label Then
PrintText Prt, Frm, Ctl, Ctl.Caption, False
ElseIf TypeOf Ctl Is TextBox Then
PrintText Prt, Frm, Ctl, Ctl.Text, True
ElseIf TypeOf Ctl Is Image Then
PrintImage Prt, Frm, Ctl, Ctl.Picture
End If
Next Ctl
If draw_box Then
wid = Frm.ScaleX(Frm.ScaleWidth, Frm.ScaleMode, vbTwips)
hgt = Frm.ScaleY(Frm.ScaleHeight, Frm.ScaleMode, vbTwips)
Prt.Line (0, 0)-Step(wid, hgt), , B
End If
End Sub
' Print text where the control belongs.
Private Sub PrintText(Prt As Printer, Frm As Form, Ctl As Control, Txt$, ByVal draw_box As Boolean)
Dim l As Single, t As Single, wid As Single, hgt As Single
l = Frm.ScaleX(Ctl.Left, Frm.ScaleMode, vbTwips)
t = Frm.ScaleY(Ctl.Top, Frm.ScaleMode, vbTwips)
If draw_box Then
Prt.CurrentX = l + Frm.ScaleX(0.2 * Ctl.Font.Size, vbPoints, vbTwips)
Prt.CurrentY = t + Frm.ScaleY(0.2 * Ctl.Font.Size, vbPoints, vbTwips)
Else
Prt.CurrentX = l
Prt.CurrentY = t
End If
' Select the printer font.
Prt.Font.Name = Ctl.Font.Name
Prt.Font.Size = Ctl.Font.Size
Prt.Font.Bold = Ctl.Font.Bold
Prt.Font.Italic = Ctl.Font.Italic
Prt.Font.Strikethrough = Ctl.Font.Strikethrough
Prt.Font.Underline = Ctl.Font.Underline
Prt.ForeColor = Ctl.ForeColor
If TypeOf Prt Is cVBDraw Then 'this Printer-Interface-implementing class, is the Cairo-cVBDraw-Class of the RichClient...
Dim oVBDraw As cVBDraw: Set oVBDraw = Prt '...so we have to perform a small cast from the Printer-Interface to cVBDraw...
oVBDraw.PrintText Txt '... and print the Text with this alternative method (which respects CurrentX and CurrentY in the same way)
Else 'it's the normal VB-Printer-Object...
Prt.Print Txt '... so we use the normal VB-Print-method against it
End If
If draw_box Then
wid = Frm.ScaleX(Ctl.Width, Frm.ScaleMode, vbTwips)
hgt = Frm.ScaleY(Ctl.Height, Frm.ScaleMode, vbTwips)
Prt.Line (l, t)-Step(wid, hgt), , B
End If
End Sub
Private Sub PrintImage(Prt As Printer, Frm As Form, Ctl As Control, Img As StdPicture)
Dim l As Single, t As Single, wid As Single, hgt As Single
l = Frm.ScaleX(Ctl.Left, Frm.ScaleMode, vbTwips)
t = Frm.ScaleY(Ctl.Top, Frm.ScaleMode, vbTwips)
wid = Frm.ScaleX(Ctl.Width, Frm.ScaleMode, vbTwips)
hgt = Frm.ScaleY(Ctl.Height, Frm.ScaleMode, vbTwips)
Prt.PaintPicture Img, l, t, wid, hgt
End Sub
The code which is marked brown describes the parts I've enhanced (in a true VB.Printer-compatible manner),
and the Code which is marked magenta, describes the only necessary compromise one has to make in his
old VB-Drawing-Code - as you can see, it is related to VBs Printer.Print statement, which is not really a part
of the VB.Printer-COM-Interface (instead Extra-Instructions for it are generated directly by the compiler) -
so I had no chance other, than implement a compatible PrintText-method on the Main-Interface of my
cVBDraw-Class.
Olaf
Last edited by Schmidt; Feb 3rd, 2015 at 08:12 PM.
-
Dec 14th, 2016, 01:54 PM
#8
Lively Member
Re: VB6 Render PDF-Files directly (and generate a Preview from the same DrawingRoutin
Hi Olaf Schimidt,
is possible put all necessary code of original DLL (classes, bas, etc) into Excel workbook (vbe editor) to generate this PDF file and the preview without use the external DLL file?
thanks!
-
Dec 14th, 2016, 03:16 PM
#9
Re: VB6 Render PDF-Files directly (and generate a Preview from the same DrawingRoutin
Originally Posted by xman2000
...is possible put all necessary code of original DLL (classes, bas, etc) into Excel workbook (vbe editor) to generate this PDF file and the preview without use the external DLL file?
No, because:
- the volume of the needed Class-Code would be much larger than you think
- the vbRichClient5.dll's sourcecode is planned to be opened along with a VB6-successor, not earlier
- and also because the whole thing would depend on vb_cairo_sqlite.dll anyways
.. (it's the compiled C-Code of the cairo-lib, which does the main-work with the PDF-rendering).
You can use the vbRichClient5.dll regfree with your Excel-Solution (no need to regsvr32 or anything) -
did you try that already?
If it is only a problem with a "64Bit-version of Excel", this can be worked around as well with relative ease.
Olaf
-
Dec 14th, 2016, 05:23 PM
#10
Lively Member
Re: VB6 Render PDF-Files directly (and generate a Preview from the same DrawingRoutin
Hi Schimidt,
i am start now using DLL into Excel, i am not kow make a sample file with DLL, at this moment.
you have a demo code for Office for vbRichClient5.dll?
thanks!
''=============================================
And i am here:
'"https://groups.google.com/forum/#!searchin/comp.lang.basic.visual.misc/svg$20excel%7Csort:relevance/comp.lang.basic.visual.misc/rtJ8uEo0l3o/qbQtAAn3DwAJ"
Hi Olaf,
thank you very mutch, you clear mor the problem.
but i am not able to convert StdPicture to vector image object embed into Excel like i am want.
i want 2 things:
1a. thing: import and export a file in EPS and SVG format.
2a thing: convert a biptmap picture embed into Excel to IPCT or Stdppicute and render to picture object pure Vector format (EPS, EMF or Autoshape).
i am not able to step StdPIcture To IMage-Object vector format.
i want pure VB Or VBA Code into Excel, not external ressources.
thank you.
===================================================
you have a code form convert a biptmap picture embed into Excel to IPCT or Stdppicute and render to picture object pure Vector format (EPS, EMF or Autoshape) into (embed) worksheet ???
maybe using this code ??
Code:
Private Sub PrintImage(Prt As Printer, Frm As Form, Ctl As Control, Img As StdPicture)
Dim l As Single, t As Single, wid As Single, hgt As Single
l = Frm.ScaleX(Ctl.Left, Frm.ScaleMode, vbTwips)
t = Frm.ScaleY(Ctl.Top, Frm.ScaleMode, vbTwips)
wid = Frm.ScaleX(Ctl.Width, Frm.ScaleMode, vbTwips)
hgt = Frm.ScaleY(Ctl.Height, Frm.ScaleMode, vbTwips)
Prt.PaintPicture Img, l, t, wid, hgt
End Sub
edit:
i am think i need change this line:
i can use a canvas of MsChart to receive the object of StdPicture or Ipict?
Last edited by xman2000; Dec 14th, 2016 at 05:47 PM.
-
Oct 16th, 2020, 11:39 PM
#11
Re: VB6 Render PDF-Files directly (and generate a Preview from the same DrawingRoutin
Since it was asked in a normal Forum-Thread,
I've now adapted the original Demo of the Opener-Thread, so that it can now render a passed Recordset-Object over several Pages.
Here is the Source-Project:
RecordsetToPDF.zip
HTH
Olaf
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|