[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

microsoft.public.vb.general.discussion

mimic the Printer and PictureBox interface, but Print, Circle, PSet?

mm

6/17/2012 6:50:00 PM

I'm thinking of writing a class that could work with the same interface for
graphics methods like the Printer object or a PictureBox, so it would be
possible to reuse the already written code for these objects.

But... It's not possible to declare:

Public Sub Print (sText as String)

End Sub

in a class, neither Circle nor PSet.

Any idea?


70 Answers

Mike Williams

6/17/2012 7:49:00 PM

0

"Eduardo" <mm@mm.com> wrote in message
news:jrl8sa$ttt$1@speranza.aioe.org...
> I'm thinking of writing a class that could work with the same interface
> for graphics methods like the Printer object or a PictureBox, so it would
> be possible to reuse the already written code for these objects. But...
> It's not possible to declare:
> Public Sub Print (sText as String)
> End Sub
> in a class, neither Circle nor PSet. Any idea?

Print is a keyword and I don't think you can use it as the name of a
function? If you use a different name then it should be okay (pPrint for
example), but of course you would need to pass the Object as well as the
sText string.

Regardless of that, I'm not sure exactly what you are trying to do there,
but in the general case you cannot guarantee that the printout will be the
same on one device as on another, and you cannot therefore guarantee that it
will take the same number of pages (and other things), at least not unless
you take special care to do so. For example, taking just one specific case,
you cannot guarantee that you will get the same Font.Size on a PictureBox as
you will on a Printer Object. In fact in most cases you will not, due to the
large differences in the dpi they provide. That means you cannot guarantee,
for example, that a string of text will be the same width (or even the same
height) one one object as on another, which of course will play havoc with
wrapped blocks of text (paragraphs for example) which are likely to wrap at
completely different places on one object than they do on the other.

I'm sure there are all sorts of ways to overcome such problems. One way
would be to write your code in such a way that it referenced the same
specific object when determining the available TextWidth (etc) but which
used the actual desired output object when printing the stuff (much like you
can do when printing the contents of a RichtextBox for example), but that
would complicate your code rather than simplifying it.

I think the method I would prefer myself (although it is not really general
purpose) would be to write your code in such a way that it draws all its
output for each page of the document into a Windows enhanced metafile
(CreateEnhMetaFile). You could set up the metafile so that it was the same
size as (say) an A4 page (or a US Letter page, it makes no real difference)
minus the margins and then draw all your output into the metafile. That
metafile could then be "printed" either to the VB Printer Object or to a VB
PictureBox object using the standard VB Paintpicture method, which allows
you to draw it at any size you want. In that way the output would look the
same on all objects, and all the text wrapping points etc would be the same.

Mike







Mike Williams

6/17/2012 8:12:00 PM

0

"Mike Williams" <Mike@WhiskyAndCoke.com> wrote in message
news:jrlcag$bfl$1@dont-email.me...
>
> That metafile could then be "printed" either to the VB Printer Object
> or to a VB PictureBox object using the standard VB Paintpicture
> method, which allows you to draw it at any size you want. In that
> way the output would look the same on all objects, and all the text
> wrapping points etc would be the same.

I forgot to mention that VB Paintpicture was just an example. If you want to
stick with a memory metafile rather than saving the metafile to disk then
you can instead "print" it using PlayEnhMetafile, although there are some
subtle differences between the two.

Mike


mm

6/17/2012 9:29:00 PM

0

"Mike Williams" <Mike@WhiskyAndCoke.com> escribió en el mensaje
news:jrlcag$bfl$1@dont-email.me...
> "Eduardo" <mm@mm.com> wrote in message
> news:jrl8sa$ttt$1@speranza.aioe.org...
>> I'm thinking of writing a class that could work with the same interface
>> for graphics methods like the Printer object or a PictureBox, so it would
>> be possible to reuse the already written code for these objects. But...
>> It's not possible to declare:
>> Public Sub Print (sText as String)
>> End Sub
>> in a class, neither Circle nor PSet. Any idea?
>
> Print is a keyword and I don't think you can use it as the name of a
> function? If you use a different name then it should be okay (pPrint for
> example), but of course you would need to pass the Object as well as the
> sText string.
>
> Regardless of that, I'm not sure exactly what you are trying to do there,
> but in the general case you cannot guarantee that the printout will be the
> same on one device as on another, and you cannot therefore guarantee that
> it will take the same number of pages (and other things), at least not
> unless you take special care to do so. For example, taking just one
> specific case, you cannot guarantee that you will get the same Font.Size
> on a PictureBox as you will on a Printer Object. In fact in most cases you
> will not, due to the large differences in the dpi they provide. That means
> you cannot guarantee, for example, that a string of text will be the same
> width (or even the same height) one one object as on another, which of
> course will play havoc with wrapped blocks of text (paragraphs for
> example) which are likely to wrap at completely different places on one
> object than they do on the other.
>
> I'm sure there are all sorts of ways to overcome such problems. One way
> would be to write your code in such a way that it referenced the same
> specific object when determining the available TextWidth (etc) but which
> used the actual desired output object when printing the stuff (much like
> you can do when printing the contents of a RichtextBox for example), but
> that would complicate your code rather than simplifying it.
>
> I think the method I would prefer myself (although it is not really
> general purpose) would be to write your code in such a way that it draws
> all its output for each page of the document into a Windows enhanced
> metafile (CreateEnhMetaFile). You could set up the metafile so that it was
> the same size as (say) an A4 page (or a US Letter page, it makes no real
> difference) minus the margins and then draw all your output into the
> metafile. That metafile could then be "printed" either to the VB Printer
> Object or to a VB PictureBox object using the standard VB Paintpicture
> method, which allows you to draw it at any size you want. In that way the
> output would look the same on all objects, and all the text wrapping
> points etc would be the same.

OK, I'll explain what I'm thinking of (perhaps) doing.

Forget about the PictureBox, it just mentioned it because it also has Print,
Circle and PSet methods, but I'm interested just in the Printer object.

I have a couple of programs where I use the Printer object for making
reports. I have all the procedures already written and working fine.
But... now I would like to make available for the user to save them as PDF
files, as an option.

I made some research and so far I found that the way to go should be to
install a virtual printer that can save the PDF.
One of the problems is that almost all PDF writers that I found install some
sort of Ad-ware like the Ask toolbar, MSN emoticons, RealPlayer, Yahoo
toolbar, etc.
Another problem is that I want to save the files without user interaction
(sometimes), so I need to set the file path to save the PDF from the
program. I was able to manage to do that with "WinPdf Writer" (writing some
values on the registry), but this one installs MSN emoticons (and needs to
download the installation from internet).
Of course, I don't like it.
And I don't like the idea of having to install a printer driver on the
system, but I could accept it (may be) if it was all transparent for the
user and without any "problem" like installing some Ad-ware.

Then, I was thinking of writing the PDF from code, myself.
I found some code here:
http://www.vb6.us/tutorials/visual-basic-tu...
It didn't work OK really.

I tried to find an ActiveX component that was able to save PDF files, and I
didn't find something (but I didn't test some expensive components - $ 500
or more) and I wouldn't like to install a full suite of components or full
reporting program.

So... I was thinking about, perhaps writing such a component.

But, I should use the same interface that the VB Printer object uses, so the
user should just change "Printer" to "mPrinter" and declare mPrinter as
object, and set that variable to an instance of my Class.

But, I found that I can declare a Sub Line, but not a sub Print, Circle or
PSet.

Besides that, I'm thinking now that I would run into trouble if the code of
the program uses the hDc of the Printer to write or paint with APIs. That's
another issue.


Schmidt

6/18/2012 1:23:00 AM

0

Am 17.06.2012 23:29, schrieb Eduardo:

[PDF-Rendering]
> So... I was thinking about, perhaps writing such a component.

A huge task (regarding implementation of correct PDF-Output),
....and already done in a decent way by the cairo-developers.
(and again, as for your DB-FullText-Search - contained in RC4).

So in case you are intereseted, I could come up with
(simple) examples, to get you going.

Cairo is nice for that, because you can work against
always the same CairoContext-Interface (something like a
hDC in the Windows-GDI). You can use the very same drawing
methods for an OnScreen-Preview ("PixelSurface-Rendering") -
as when rendering with your unchanged Routines (using the
same coordinates!) against a PDF-based CairoContext.

In case the CairoContext came from a normal PixelSurface,
you can render this Surface later on (after all your
Drawing-Output-Routines did their work) to your VB-Form.hdc
in a single call:
PxlSurface.DrawTo Form.hDC, xOffs, yOffs

And in case the CairoContext came from a PDF-Surface, your
same Drawing-Routines will not "change Pixels on it" of course,
but write (under the hood) the appropriately translated PDF-
Commands directly into a File instead.


> But, I should use the same interface that the VB Printer object uses,
> so the user should just change "Printer" to "mPrinter" and declare
> mPrinter as object, and set that variable to an instance of my Class.
>
> But, I found that I can declare a Sub Line, but not a sub Print,
> Circle or PSet.

The one Problem is the Naming (you would need to use a
TypeLib-Defintion, to allow Names as Class-Methods, which
are already "reserved" by VB).

On Top of that (even when VB would allow to define such
names as Class-methods in an easy way directly) ... how would
you solve the weird syntax-problem these "oldfashioned" methods
(or perhaps: "statements") expect with regards to their Parameters?

e.g. Line:
Line (0, 200) - (ScaleWidth, 200), vbBlack

Not really a "normal" Function-Call, is it?
Your own Line-Method would be defined with 5 Params instead
(or an Optional six'th, for the "BF" Option-stuff, which is
also there).

e.g. (simplified) this way:
Public Sub Line(x1, y1, x2, y2, Color, Optional Mode)

which would require a change in your drawing-routines
from:
Printer.Line (0, 200) - (ScaleWidth, 200), vbBlack
to:
mPrinter.Line 0, 200, ScaleWidth, 200, vbBlack

So, it would by no means be that easy, to reuse existing
drawing-code, which has its Line-Drawing "expressed" in
the old (backward-compatible) "Basic-Syntax", when putting
a new (redefined with "real" Params) Line-Method behind a
new Class (even when the Name-Definition-Problem for "Line"
wouldn't exist).

You would perhaps use the VB-IDE-Replace-Dialog, to solve that
in a sequence of "well-thought" commands as e.g.:
Replace all occurences of:
'.Line ('
with the term:
'.Line '

or:
') - ('
with the term:
', '

and so on...
(although the last example is already ambigous, because you could
replace such a sequence accidentally also in a subtraction-Op,
which has sub-terms enclosed in parentheses as well).

So, due to the "old-syntax" - you would need to run replacement-
Ops on your old code in either way, so why not redefine at this
occasion also the Naming?

Replace all occurences of:
'.Line ('
with the term:
'.DrawLine '

...and your Naming-Problem is already done (for the Line-Call).
(I'm aware, that the Line-Call does not have that Naming-problem,
but the same Problem with the weird Param-Definitions also
exists for the Circle-Call and for PSet).

> Besides that, I'm thinking now that I would run into trouble if the code of
> the program uses the hDc of the Printer to write or paint with APIs. That's
> another issue.

When you work with a CairoContext, this is not a Handle,
but (when working over the COM-Wrapper), is already a
"Device-abstracting" Class-Encapsulation - and so IMO
basically the thing you want to write on your own.

A context can generate output in a PixelSurface
(a PixelSurface is memory-wise similar to a GDI-DIB
with 32Bit-per-Pixel - but doesn't consume a hDIB-Handle,
it's just a plain mem-alloc)

Dim PxlSrf As cCairoSurface
Set PxlSrf = Cairo.CreateSurface(PxlWidth, PxlHeight, ImageSurface)

or when creating a PDF-Surface:
Dim PDFSrf As cCairoSurface
Set PDFSrf = Cairo.CreateSurface(PdfPgWidth, PdfPgHeight, PDFSurface)

In both cases of Surface-Types (which are hosted in the same
Class-Type cCairoSurface) you can derive a CairoContext
(the thing you will use for drawing), with a simple call:

Dim CC as cCairoContext
Set CC = PxlSrf.CreateContext
'or alternatively
'Set CC = PdfSrf.CreateContext

This CC-Class-Variable (although representing something
like a hDC) is of course a Class - and as such you don't
need to initiate drawings over it, by giving a Handle
into a "C-style API-Function" as e.g.:
TextOut hDC, ..., ...
Rectangle hDC, ..., ...

But you do:
CC.TextOut ..., ...
CC.Rectangle ..., ...
CC.DrawLine ..., ...
'etc for loads of additional drawing-functionality

So, as said, your abstraction-Helper-Class (for both, Screen-
and PDF-Output) is already there, in case you want to use
the RC4-lib anyways (in its function as wrapper for SQLite).

Maybe write a small additional wrapper around it, to allow
also for the Color-Parameters the VB-Drawing-stuff offers
directly in its old statements - and to support Properties
as .Scalemode, .CurrentX, .CurrentY, in case you made heavy
use of those in your drawing-routines as well.

Olaf





mm

6/18/2012 2:34:00 AM

0


"Schmidt" <sss@online.de> escribió en el mensaje
news:jrlvu0$pac$1@dont-email.me...
> Am 17.06.2012 23:29, schrieb Eduardo:
>
> [PDF-Rendering]
>> So... I was thinking about, perhaps writing such a component.
>
> A huge task (regarding implementation of correct PDF-Output),

Yes, I know, that's why I said "perhaps" (I would write it).


> ...and already done in a decent way by the cairo-developers.

I didn't know.


> (and again, as for your DB-FullText-Search - contained in RC4).
>
> So in case you are intereseted, I could come up with
> (simple) examples, to get you going.

OK, great.

I have routines for printing that use code like:

Printer.FontName...
Printer.Orientation...
Printer.CurrentX...
Printer.Print...
Printer.Line...

>
> Cairo is nice for that, because you can work against
> always the same CairoContext-Interface (something like a
> hDC in the Windows-GDI). You can use the very same drawing

I think that in some parts I have used API calls also, TextOut or DrawText
over the printer's hDC


> methods for an OnScreen-Preview ("PixelSurface-Rendering") -
> as when rendering with your unchanged Routines (using the
> same coordinates!) against a PDF-based CairoContext.
>
> In case the CairoContext came from a normal PixelSurface,
> you can render this Surface later on (after all your
> Drawing-Output-Routines did their work) to your VB-Form.hdc
> in a single call:
> PxlSurface.DrawTo Form.hDC, xOffs, yOffs

Could this be useful to make a print preview in a PictureBox?

>
> And in case the CairoContext came from a PDF-Surface, your
> same Drawing-Routines will not "change Pixels on it" of course,
> but write (under the hood) the appropriately translated PDF-
> Commands directly into a File instead.

So far I just would like to use the code that I have for the printer object.

>
>
>> But, I should use the same interface that the VB Printer object uses,
>> so the user should just change "Printer" to "mPrinter" and declare
>> mPrinter as object, and set that variable to an instance of my Class.
>>
>> But, I found that I can declare a Sub Line, but not a sub Print,
>> Circle or PSet.
>
> The one Problem is the Naming (you would need to use a
> TypeLib-Defintion, to allow Names as Class-Methods, which
> are already "reserved" by VB).
>
> On Top of that (even when VB would allow to define such
> names as Class-methods in an easy way directly) ... how would
> you solve the weird syntax-problem these "oldfashioned" methods
> (or perhaps: "statements") expect with regards to their Parameters?
>
> e.g. Line:
> Line (0, 200) - (ScaleWidth, 200), vbBlack

I already found how to solve that:

Public Sub Line(ParamArray nParams())


Try this:

New project, add a class module
In the class module:

Public Sub Line(ParamArray nParams())
Dim c As Long

For c = 0 To UBound(nParams)
Debug.Print "Parameter " & c & ": " & nParams(c)
Next c
End Sub


In the form:

Private Sub Form_Load()
Dim a As New Class1

a.Line (2, 3)-(4, 5), vbRed, BF
End Sub


The parameter BF comes in the first parameter ( index 0).

The object browser shows the definition:

Sub Line(Flags As Integer, X1 As Single, Y1 As Single, X2 As Single, Y2 As
Single, Color As Long)


>
> Not really a "normal" Function-Call, is it?
> Your own Line-Method would be defined with 5 Params instead
> (or an Optional six'th, for the "BF" Option-stuff, which is
> also there).
>
> e.g. (simplified) this way:
> Public Sub Line(x1, y1, x2, y2, Color, Optional Mode)
>
> which would require a change in your drawing-routines
> from:
> Printer.Line (0, 200) - (ScaleWidth, 200), vbBlack
> to:
> mPrinter.Line 0, 200, ScaleWidth, 200, vbBlack
>
> So, it would by no means be that easy, to reuse existing
> drawing-code, which has its Line-Drawing "expressed" in
> the old (backward-compatible) "Basic-Syntax", when putting
> a new (redefined with "real" Params) Line-Method behind a
> new Class (even when the Name-Definition-Problem for "Line"
> wouldn't exist).
>
> You would perhaps use the VB-IDE-Replace-Dialog, to solve that
> in a sequence of "well-thought" commands as e.g.:
> Replace all occurences of:
> '.Line ('
> with the term:
> '.Line '
>
> or:
> ') - ('
> with the term:
> ', '
>
> and so on...
> (although the last example is already ambigous, because you could
> replace such a sequence accidentally also in a subtraction-Op,
> which has sub-terms enclosed in parentheses as well).
>
> So, due to the "old-syntax" - you would need to run replacement-
> Ops on your old code in either way, so why not redefine at this
> occasion also the Naming?
>
> Replace all occurences of:
> '.Line ('
> with the term:
> '.DrawLine '
>
> ..and your Naming-Problem is already done (for the Line-Call).
> (I'm aware, that the Line-Call does not have that Naming-problem,
> but the same Problem with the weird Param-Definitions also
> exists for the Circle-Call and for PSet).
>
>> Besides that, I'm thinking now that I would run into trouble if the code
>> of
>> the program uses the hDc of the Printer to write or paint with APIs.
>> That's
>> another issue.
>
> When you work with a CairoContext, this is not a Handle,
> but (when working over the COM-Wrapper), is already a
> "Device-abstracting" Class-Encapsulation - and so IMO
> basically the thing you want to write on your own.
>
> A context can generate output in a PixelSurface
> (a PixelSurface is memory-wise similar to a GDI-DIB
> with 32Bit-per-Pixel - but doesn't consume a hDIB-Handle,
> it's just a plain mem-alloc)
>
> Dim PxlSrf As cCairoSurface
> Set PxlSrf = Cairo.CreateSurface(PxlWidth, PxlHeight, ImageSurface)
>
> or when creating a PDF-Surface:
> Dim PDFSrf As cCairoSurface
> Set PDFSrf = Cairo.CreateSurface(PdfPgWidth, PdfPgHeight, PDFSurface)
>
> In both cases of Surface-Types (which are hosted in the same
> Class-Type cCairoSurface) you can derive a CairoContext
> (the thing you will use for drawing), with a simple call:
>
> Dim CC as cCairoContext
> Set CC = PxlSrf.CreateContext
> 'or alternatively
> 'Set CC = PdfSrf.CreateContext
>
> This CC-Class-Variable (although representing something
> like a hDC) is of course a Class - and as such you don't
> need to initiate drawings over it, by giving a Handle
> into a "C-style API-Function" as e.g.:
> TextOut hDC, ..., ...
> Rectangle hDC, ..., ...
>
> But you do:
> CC.TextOut ..., ...
> CC.Rectangle ..., ...
> CC.DrawLine ..., ...
> 'etc for loads of additional drawing-functionality
>
> So, as said, your abstraction-Helper-Class (for both, Screen-
> and PDF-Output) is already there, in case you want to use
> the RC4-lib anyways (in its function as wrapper for SQLite).
>
> Maybe write a small additional wrapper around it, to allow
> also for the Color-Parameters the VB-Drawing-stuff offers
> directly in its old statements - and to support Properties
> as .Scalemode, .CurrentX, .CurrentY, in case you made heavy
> use of those in your drawing-routines as well.

I could write a class to make the conversion from the VB Printer syntax to
the Cairo syntax...


mm

6/18/2012 3:56:00 AM

0


"Schmidt" <sss@online.de> escribió en el mensaje
news:jrlvu0$pac$1@dont-email.me...
> Am 17.06.2012 23:29, schrieb Eduardo:
>
> [PDF-Rendering]
>> So... I was thinking about, perhaps writing such a component.
>
> A huge task (regarding implementation of correct PDF-Output),

BTW, the PDF file specification is here:
http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/PDF3200...

And the Microsoft Word file specification is here:
http://download.microsoft.com/download/2/4/8/24862317-78F0-4C4B-B355-C7B2C1D997DB/%5BMS-...

(it would be also nice to be able to save as *.Doc, without having to have
Word installed).

The VB Printer object is quite simple, it only has a few methods. The
problem is to find on these huge and complex documents how to do it.


Another thought:

what about "hacking" the VB Printer object, to be able to do something like:

Dim oPrinter as New MyPrinterClass

Set Printer = oPrinter

VB won't allow that (error 13 is raised), but what about hacking in some way
VB to make that when the code references the Printer, it actually goes to my
object?
Perhaps with CopyMemory, VirtualProtect, ObjPtr...

Still, I would need to be able to declare a Sub Print, a Sub Circle and a
Sub PSet

....or it would be even better if I was able to have a general interface,
something like:

Private Sub MethodCalled (MethodName as String, ParamArray nParams())
Select Case MethodName
Case Line
' code for line...
Case Print
' code for Print
Case...

Case Else
Err.Raise x, "Object does not support this method"
End Select
End Sub



Schmidt

6/18/2012 2:56:00 PM

0

Am 18.06.2012 04:34, schrieb Eduardo:
> "Schmidt" <sss@online.de> escribi� en el mensaje
> news:jrlvu0$pac$1@dont-email.me...
>> Am 17.06.2012 23:29, schrieb Eduardo:
>>
>> [PDF-Rendering]
>>> So... I was thinking about, perhaps writing such a component.
>>
>> A huge task (regarding implementation of correct PDF-Output),
>
> Yes, I know, that's why I said "perhaps" (I would write it).

I think, there's already VB6-SourceCode out there, which
implements (basic) PDF-rendering already - Mike-Williams
has done a little research recently and posted a few links.

Haven't tested it, and don't know how stable and fast
these implementation are - but I think they are nowhere
near as *complete* as the cairo-PDF-rendering - and
what they lack is IMO the "Duality" cairo supports with
regards to PixelOutput, when calling the same (vectorgraphics)-
drawing-methods against these different "Device-Surfaces".


[Naming, and "weird syntax"-problem]
> I already found how to solve that:
>
> Public Sub Line(ParamArray nParams())

Now that's funny... - didn't know that.

But it gives an idea, how VB deals under the hood with
these older drawing-commands.

But the Line-call is the single exception which allows
this ParamArray-Trickery.
Neither PSet nor Circle work this way (already choking
at the reserved Name).

But also unambigous names as:
Public Sub DrawLine(ParamArray nParams())

will not work, because in these cases the compiler does
*not* translate and assist with the older Param-Syntax.
(in case of the Line-command it does that only, because
it somehow "slipped through").

But as said earlier, when you define a TypeLib for
this Drawing-Class' interface (I've just tested this
with PSet), then you can implement this Typelib in your
new Wrapper-Class (using Implements) and then the VB-Compiler
supports the Translation of the old Param-Syntax for your new
Typelib-defined (and implemented) PSet-Method as well.


> I could write a class to make the conversion from the VB Printer
> syntax to the Cairo syntax...

Although what I've written above sounds encouraging, I'm still
not that sure, if it is worth the effort, to wrap the old
VB-Drawing-Commands, which are not the most powerful, when
it comes to modern graphics- and Text-Output.

I understand, that there's a lot of old drawing-code, which
tries to do "amazing things" with VBs few drawing-commands.

And because these commands are not that powerful, one ends up
with pretty large routines, to e.g. accomplish the rendering
of a Recordset in a nice layouted table (perhaps adding
additional GDI-API-routines into the mix, to do all the
additional, fancy things VB has no builtin graphics-command for).

And because these routines are that large and complex, one then
wants an identically behaving (and interfaced) "Alternative-Object",
to avoid changing "these monsters"... ;-)

Therefore I would tackle that the other way around, to achieve
smaller and better maintainable BaseRoutines (the ones which
make up your Reports).

E.g. when you end up with a generic Report-Class with Methods as:

SetPageDimensionAndOrientation
DrawHeaderLines
DrawLogo (or DrawImageToRectangle)
DrawRectangle (as well as Circle, Ellipse, RoundedRect)
DrawLineWithDifferentEndings
DrawTextInRectangle
DrawTableFromRs
DrawFooterLines

And implement these few generic Reporting-Routines with
the help of a modern graphics-engine *directly*, then
(maybe) you will have even fun, to replace your older
ReportPage-Drawing-Functions with the help of these few,
but powerful generic Helper-Methods.

This way you could end up with far less lines of "user-code
per page" I think, code more clear and easier to maintain.

If the implementation of a generic and modern ReportClass and
the rewrite of the PageDrawing-Routines is in the end less time-
consuming than the implementation and testing of a compatible
Class for VBs old Drawing-stuff (using a TypeLib), depends on
the amount of the differently implemented Page-Render-Routines
you currently have, and what those routines do internally with
regards to complexity (and how many GDI-APIs are in the mix -
and what you plan to do with these Calls in the end).

You can use cairo in either case (it offers powerful alternatives
for all the GDI-APIs too).
In either case, be it a generic cReport-Class or a cVBDrawings-
Class, you can abstract from the Devices (Pixel-/Screen-Output
and PDF-Output).
The cReport-Class would need no fiddeling with TypeLibs,
and would offer a higher-level abstraction, optimized for
PageDrawings in a Reporting-Scenario, but you would need
to rewrite your PageOutput-Routines entirely, though in
perhaps (much) less lines of code.

The cVBDrawings-Class could act as a replacement for VBs
Printer- or PictureBox Drawing-Calls - it would allow,
to (more or less) leave your existing routines intact,
but testing the cVBDrawings-Helper against each PageOutput-
routine you currently have, would be necessary anyway
(+ the CodeAdaptions for the involved GDI-Routines, to map
them against additional Methods in cVBDrawings, which
replace GDI-APIs with cCairoContext-Methods)


Olaf






Schmidt

6/18/2012 3:20:00 PM

0

Am 18.06.2012 05:56, schrieb Eduardo:
> "Schmidt" <sss@online.de> escribi� en el mensaje
> news:jrlvu0$pac$1@dont-email.me...
>> Am 17.06.2012 23:29, schrieb Eduardo:
>>
>> [PDF-Rendering]
>>> So... I was thinking about, perhaps writing such a component.
>>
>> A huge task (regarding implementation of correct PDF-Output),
>
> BTW, the PDF file specification is here:
> http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/PDF3200...

Yes, that's what the guys who already attempted a PDF-Rendering
Implementation in VBClassic have read too.

> And the Microsoft Word file specification is here:
> http://download.microsoft.com/download/2/4/8/24862317-78F0-4C4B-B355-C7B2C1D997DB/%5BMS-...
>
> (it would be also nice to be able to save as *.Doc, without having to
> have Word installed).

Not sure, if that's a good idea to implement on your own too.
It's at least as complex as the PDF-Implementation (considering
the different *.doc and the recent *.docx Formats).

And at least the Adobe-PDF-Reader supports a service wich
allows such a conversion directly from PDFs.


> The VB Printer object is quite simple, it only has a few methods. The
> problem is to find on these huge and complex documents how to do it.
>
>
> Another thought:
>
> what about "hacking" the VB Printer object, to be able to do something like:
>
> Dim oPrinter as New MyPrinterClass
>
> Set Printer = oPrinter
>
> VB won't allow that (error 13 is raised), but what about hacking in some way
> VB to make that when the code references the Printer, it actually goes to my
> object?
> Perhaps with CopyMemory, VirtualProtect, ObjPtr...

I don't see the need for that - and also thought, that it would
be PDF you want to create, and the cairo-PDF-rendering does not
involve a "virtual Printer-Driver" ... it does this directly
InMemory (or "InFile") - without any Printer involved.

> Still, I would need to be able to declare a Sub Print, a Sub Circle
> and a Sub PSet

As just said (and tested), this will work (including the translation
of the old Param-Syntax), when you define a dedicated "external *.tlb"
for that - and implement the Methods and Properties in this *.tlb
in your VB6-Wrapper-Class (using Implements).

>
> ...or it would be even better if I was able to have a general interface,
> something like:
>
> Private Sub MethodCalled (MethodName as String, ParamArray nParams())
> Select Case MethodName
> Case Line
> ' code for line...
> Case Print
> ' code for Print
> Case...
>
> Case Else
> Err.Raise x, "Object does not support this method"
> End Select
> End Sub
>

Wouldn't do that, you would have to touch each line of your
existing Drawing-Calls, to map to this new calling-scheme
(and Intellisense is completely out of the question then).

I think I've outlined the only two viable choices (IMO)
already in my other posting - either a modern cReport-Class,
with powerful high-level-calls, which makes rewriting your
exisiting PageDrawings much easier with less lines of code -
or alternatively the TypeLib-based approach, which tries
to stay compatible to VBs old Drawing-Commands in the
implementing Class, to keep as much of your old PageDrawing-
Code.

Olaf


mm

6/18/2012 3:41:00 PM

0


"Schmidt" <sss@online.de> escribió en el mensaje
news:jrnfhb$c7u$1@dont-email.me...

> I think, there's already VB6-SourceCode out there, which
> implements (basic) PDF-rendering already - Mike-Williams
> has done a little research recently and posted a few links.

Before posting the OP message, I searched the group with Google, and didn't
find it. I just foud a question from Rick Raisley made in 2008 (or 2005) and
some other from 1999.
Now I added the keywords "Mike Williams" and many new messages appeared
(I'll read them now).
Google feature of searching in groups is not working right any more.

>
> Haven't tested it, and don't know how stable and fast
> these implementation are - but I think they are nowhere
> near as *complete* as the cairo-PDF-rendering - and
> what they lack is IMO the "Duality" cairo supports with
> regards to PixelOutput, when calling the same (vectorgraphics)-
> drawing-methods against these different "Device-Surfaces".
>
>
> [Naming, and "weird syntax"-problem]
>> I already found how to solve that:
>>
>> Public Sub Line(ParamArray nParams())
>
> Now that's funny... - didn't know that.
>
> But it gives an idea, how VB deals under the hood with
> these older drawing-commands.

Yes.

> But the Line-call is the single exception which allows
> this ParamArray-Trickery.
> Neither PSet nor Circle work this way (already choking
> at the reserved Name).

I think they are handled in the same way as Line.

The definition in the Object Browser are:

Sub PSet(Step As Integer, X As Single, Y As Single, Color As Long)

Sub Circle(Step As Integer, X As Single, Y As Single, Radius As Single,
Color As Long, Start As Single, End As Single, Aspect As Single)

The Print command does not appear, but it should be:

Sub Print(Text as String)

The only problem that I see is that they are reserved words.

>
> But also unambigous names as:
> Public Sub DrawLine(ParamArray nParams())
> will not work, because in these cases the compiler does
> *not* translate and assist with the older Param-Syntax.

That's another reason why I want to keep the original names.


> (in case of the Line-command it does that only, because
> it somehow "slipped through").
>
> But as said earlier, when you define a TypeLib for
> this Drawing-Class' interface (I've just tested this
> with PSet), then you can implement this Typelib in your
> new Wrapper-Class (using Implements) and then the VB-Compiler
> supports the Translation of the old Param-Syntax for your new
> Typelib-defined (and implemented) PSet-Method as well.

I have no experience with Typelibs.
Should this typelib be also present (and loaded) in the developer's machine
of the client program?

Or it's just to allow me to compile it with the reserved words (in the
component's developer machine)?

>
>> I could write a class to make the conversion from the VB Printer
>> syntax to the Cairo syntax...
>
> Although what I've written above sounds encouraging, I'm still
> not that sure, if it is worth the effort, to wrap the old
> VB-Drawing-Commands, which are not the most powerful, when
> it comes to modern graphics- and Text-Output.
>
> I understand, that there's a lot of old drawing-code, which
> tries to do "amazing things" with VBs few drawing-commands.
>
> And because these commands are not that powerful, one ends up
> with pretty large routines, to e.g. accomplish the rendering
> of a Recordset in a nice layouted table (perhaps adding
> additional GDI-API-routines into the mix, to do all the
> additional, fancy things VB has no builtin graphics-command for).
>
> And because these routines are that large and complex, one then
> wants an identically behaving (and interfaced) "Alternative-Object",
> to avoid changing "these monsters"... ;-)
>
> Therefore I would tackle that the other way around, to achieve
> smaller and better maintainable BaseRoutines (the ones which
> make up your Reports).
>
> E.g. when you end up with a generic Report-Class with Methods as:
>
> SetPageDimensionAndOrientation
> DrawHeaderLines
> DrawLogo (or DrawImageToRectangle)
> DrawRectangle (as well as Circle, Ellipse, RoundedRect)
> DrawLineWithDifferentEndings
> DrawTextInRectangle
> DrawTableFromRs
> DrawFooterLines
>
> And implement these few generic Reporting-Routines with
> the help of a modern graphics-engine *directly*, then
> (maybe) you will have even fun, to replace your older
> ReportPage-Drawing-Functions with the help of these few,
> but powerful generic Helper-Methods.
>
> This way you could end up with far less lines of "user-code
> per page" I think, code more clear and easier to maintain.
>
> If the implementation of a generic and modern ReportClass and
> the rewrite of the PageDrawing-Routines is in the end less time-
> consuming than the implementation and testing of a compatible
> Class for VBs old Drawing-stuff (using a TypeLib), depends on
> the amount of the differently implemented Page-Render-Routines
> you currently have, and what those routines do internally with
> regards to complexity (and how many GDI-APIs are in the mix -
> and what you plan to do with these Calls in the end).
>
> You can use cairo in either case (it offers powerful alternatives
> for all the GDI-APIs too).
> In either case, be it a generic cReport-Class or a cVBDrawings-
> Class, you can abstract from the Devices (Pixel-/Screen-Output
> and PDF-Output).
> The cReport-Class would need no fiddeling with TypeLibs,
> and would offer a higher-level abstraction, optimized for
> PageDrawings in a Reporting-Scenario, but you would need
> to rewrite your PageOutput-Routines entirely, though in
> perhaps (much) less lines of code.

I think you don't take into account the benefits of an easy implementation.
Something like:

ReplacePrinter = True
PrinterDocumentPath = "D:\Folder\FileName.pdf"

And that's all, happy printing.
Of course there would be some "advanced configurations" available.

And you don't lose the other Cairo's enhanced features, you could reach them
from a object variable referencing the Cairo object directly, and add all
the new code specifically for Cairo if you want.
Or may be you want to keep your code just "VB Printer frienly", for the case
if in the future you want to remove Cairo from the system.

>
> The cVBDrawings-Class could act as a replacement for VBs
> Printer- or PictureBox Drawing-Calls - it would allow,
> to (more or less) leave your existing routines intact,
> but testing the cVBDrawings-Helper against each PageOutput-
> routine you currently have, would be necessary anyway
> (+ the CodeAdaptions for the involved GDI-Routines, to map
> them against additional Methods in cVBDrawings, which
> replace GDI-APIs with cCairoContext-Methods)

We could leave APIs as not supported if it's not possible to support.


mm

6/18/2012 4:09:00 PM

0


"Schmidt" <sss@online.de> escribió en el mensaje
news:jrngv6$lm8$1@dont-email.me...

> Yes, that's what the guys who already attempted a PDF-Rendering
> Implementation in VBClassic have read too.

And who are them?

> Not sure, if that's a good idea to implement on your own too.
> It's at least as complex as the PDF-Implementation (considering
> the different *.doc and the recent *.docx Formats).
>
> And at least the Adobe-PDF-Reader supports a service wich
> allows such a conversion directly from PDFs.

I see that you don't understand simplicity, easiness.
People don't want to save files in one format, go and open another program,
and convert it to the desired format.

One of the task of being a programmer is to make complex things easy.

Of course they don't need to save reports as PDF either. They can print the
reports in paper, then scan them with a scanner, pass an OCR to recover the
text, and then make the PDF.

Or.. to manually type the printed reports into Word.


>> ...or it would be even better if I was able to have a general interface,
>> something like:
>>
>> Private Sub MethodCalled (MethodName as String, ParamArray nParams())
>> Select Case MethodName
>> Case Line
>> ' code for line...
>> Case Print
>> ' code for Print
>> Case...
>>
>> Case Else
>> Err.Raise x, "Object does not support this method"
>> End Select
>> End Sub
>>
>
> Wouldn't do that, you would have to touch each line of your
> existing Drawing-Calls, to map to this new calling-scheme
> (and Intellisense is completely out of the question then).

I think you didn't understand.

"do that"?

I can't do that, or at least I don't know if it would be somehow possible.

What I was saying is that I would like that VB could give me the calls to
the Printer (or other object) for me to handle in that way, with that
interface, in a "late bound" way.

About all the other comments, I realize that not everybody is aware of the
benefits of making complex things simple.
Realize, Olaf, that most of the people are a bit impatient (I'm), they don't
want to study Cairo, they want to solve a problem, and if they can solve it
with a couple of lines, the better.
You could sell it, I could say that even when VB is quite old, it could be
sold well.
But it should be a direct replacement.

If I do the research and study the problem in deep, it will be one time, in
order to be able to make something that allows to use the old printing code
and not having to rewrite it.
I can be patient to do something that will be done once and will be useful
many times.