Home All Groups Group Topic Archive Search About
Author
10 Mar 2009 5:36 PM
Claus Centrino
I'm just playing around copying some pictures from one
picturebox into others and back where pictures are laoded by
LoadPicture() function and edited by some prints and lines.
So far so good, in most cases it works fine as expected. But
in some cases I get errors, even when the same code sequence
was executed error free in a preceding loop when nothing
changed except target coordinates for x/ to copy a picture
into 2 or mopore positions in the same target.

My code is too complex to list here so I only want to ask if
there is a good description available for PaintPicture
specifications. Please don't explain what PaintPicture
does - I know what it should do. But obviously there are
some restrictions for the underlaying pictureboxes which I
don't know so that a working sequence fails when executed
again, in most cases error 481 - invalid picture and error
5 - invalid argument, with - in my view - valid input
parameters (reasonable coordinates, picture sizes, and
bitmaps loaded from file).

I **did** google for these errors and did play around with
AutoRedraw, but nevertheless I did not get a stable
PaintPicture execution. I found something about picturebox's
picture and image properties and played around with these
but also not successful. Sometimes the image property as
source works where picture property fails, but I can't
detect when and why. So I hope to find some docu about
PaintPicture explaining restrictions for source and target
picturebox.

Author
10 Mar 2009 8:10 PM
Larry Serflaten
"Claus Centrino" <c***@sofort-mail.de> wrote

> My code is too complex to list here so I only want to ask if
> there is a good description available for PaintPicture
> specifications.

Often times it helps to isolate the problem in a new project,
so you can work on it without distracting code from a larger
project.  It also allows for posting simple test for others to try
on their own systems, to see if fails for them, or if you have
a problem unique to your own setup....


> I **did** google for these errors and did play around with
> AutoRedraw, but nevertheless I did not get a stable
> PaintPicture execution. I found something about picturebox's
> picture and image properties and played around with these
> but also not successful. Sometimes the image property as
> source works where picture property fails, but I can't
> detect when and why.

What do you mean 'fails'?  It errors, or you just don't see a
change?

A rule of thumb would be to always use the Picture property.
If you've added your own graphics (Print, Circle, Line, and
any API work. etc) then before using PaintPicture, assign the
Image property to the Picture property prior to using PaintPicture.

Set picThis.Picture = picThis.Image
picThat.PaintPicture picThis.Picture, ... ... ...

See if that helps.

LFS
Author
10 Mar 2009 8:28 PM
Mike Williams
"Claus Centrino" <c***@sofort-mail.de> wrote in message
news:gp68he$dkq$1@online.de...

> . . . and error 5 - invalid argument, with - in my view - valid input
> parameters (reasonable coordinates, picture
> sizes, and bitmaps loaded from file).

> Sometimes the image property as source works where
> picture property fails, but I can't detect when and why.

The Picture property of a PictureBox works as a source image for the
PaintPicture method only if a valid picture or image has actually been
assigned to it or loaded into it, whereas the Image property should always
work (contrary to what it says in the help files), although the contents of
the Image property will depend on what you have drawn or painted into it and
what you have loaded into the Picture property and whether or not Autoredraw
is True.

Regarding the Runtime Error 5 there are various limitations on the
parameters in the PaintPicture method. For example, the parameters Width1
and Height1 (the desired width and height of the output) cannot be of such a
value that they equate to zero pixels (although either positive or negative
pixel values are fine). This problem is easy to miss if you are using the
default ScaleMode of Twips for the destination PictureBox, because anything
in the range -7 to +7 (twips) will be the equivalent of zero pixels (on a
machine running at the standard 15 twips per pixel setting). Personally I
would advise using a ScaleMode of Pixels when manipulating bitmaps.

If you're still having problems then it really would be best if you posted
your code. If it is part of a very large program then create a separate
project containing only the PaintPicture and associated code and post it (in
fact it would be best if you did that anyway), after of course ensuring that
it actually does have the problem you describe, and at the same time post
details of the line on which the error occurs, the error description, and
the value of the various parameters at the time the error occured.

Mike
Author
11 Mar 2009 9:12 AM
Claus Centrino
Thank you for your answer.

It seems to be not a problem of a special code, I simply
want to understand the conditions under which PaintPicture
works.

Of course, I made a little test project to play around, and
it works all fine here, completely. I can position and
resize or stretch the soruce picture in the target picture
whatever I want to do.

The next step was a routine with these steps:
- load a background picture into a picture box
- print the content of a richtextbox using SendMessage and
EM_FOTMATRANGE into this picture box
- copy the picturebox (now background picture plus text)
into another picturebox (for page preview) using
PaintPicture
This also works very fine, and I put all code together in a
subroutine to call it multiple with different x/y
coordinates .

Executing this routine once works still fine.

Calling this routine a second time PaintPicture fails. Of
course I played around with picture and image properties,
with different pictures (bmp, jpg), AutoRedraw and much
more. Nothing helped, I cannot find any difference in the
parameters between first and second call (except x/y).
Coordinates and picture sizes are reasonable small, and
changing the source and target dimensions didn't help.

What I'm still not understanding completely is the
difference between image and picture property. I know that
picture property gets the LoadPicture() file and image
property is something like picture property plus my own
drawings, and that Cls clears only the image and not the
picture.

But what I find strange is that sometimes, when a
"picTarget.PaintPicture picSource.Picture,..." fails, it
runs with picSource.Image. But when it works with picture
property it might not work with image property, so that I
cannot always simply use the image property. Why that? At
least, how to determine if image or picture property (except
using the hard way via error detection) ?
Author
11 Mar 2009 2:09 PM
Mike Williams
Show quote Hide quote
"Claus Centrino" <c***@sofort-mail.de> wrote in message
news:gp7vb6$q90$1@online.de...

> The next step was a routine with these steps:
> - load a background picture into a picture box
> - print the content of a richtextbox using SendMessage
> and EM_FOTMATRANGE into this picture box
> - copy the picturebox (now background picture plus
> text) into another picturebox (for page preview) using PaintPicture. This
> also works very fine, and I put all
> code together in a subroutine to call it multiple with
> different x/y coordinates .
> Executing this routine once works still fine.
> Calling this routine a second time PaintPicture fails.

As I've said, there could be all sorts of reasons for the failure, depending
on exactly what your code is doing. The best thing would be for you to
create the project you have just described as a stand alone project,
preferably with all code and declarations and functions in the Form itself,
and then post your code here, after first making sure that it does in fact
exhibit the problem you have mentioned, together with details of the
Controls you have used and any changes you have made to their default
settings in the IDE. Alternativey, instead of posting the code you can post
the actual contents of the .frm file.

> But what I find strange is that sometimes, when a "picTarget.PaintPicture
> picSource.Picture,..." fails,
> it runs with picSource.Image. But when it works
> with picture property it might not work with image
> property, so that I cannot always simply use the
> image property. Why that?

The PaintPicture method should normally work with either the Picture or the
Image property of the source, although it says in the help files that it
must be the Picture property. If you want to be pedantic then you can use
PicSource.Picture = PicSource.Image and then use the Picure property (or you
can alternatively use the StretchBlt API on hDC of the Autoredraw
PictureBox, but I would suggest getting your existing PaintPicture code
working before you do that). However, you need to be aware that there can be
a difference in size between the Picture property and the Image property of
an Autoredraw PictureBox. The Picture property is the original picture that
was loaded into it and it will have a pixel size equal to the pixel size of
the original picture and it will contain only that picture, whereas the
Image property is effectively a bitmap in a separate memory DC and it will
(except under certain circumstances) be the same size as the Autoredraw
Picture Box and it will contain the picture (or part of the picture
depending on its size) with the stuff you have drawn over it (while
Autoredraw was True) superimposed.

It really would be easier to help you if you posted your code.

Mike
Author
11 Mar 2009 2:37 PM
Mike Williams
"Claus Centrino" <c***@sofort-mail.de> wrote in message
news:gp7vb6$q90$1@online.de...

> Thank you for your answer. It seems to be not a problem
> of a special code, I simply want to understand the conditions
> under which PaintPicture works.

.. . . just one more point I think I should mention, you said in your
original post that you were transferring images from one PictureBox into
others and then back again (and I assume that you are using Autoredraw
PictureBoxes) but perhaps you haven't realised that PaintPicture will only
accept the Picture property of a PictureBox as the source if a picture
actually has been loaded into that PictureBox (typically either by setting
its Picture property to a valid picture in code or in the IDE or by using
the LoadPicture method in code). If its Picture property does not contain an
actual picture (loaded into it as described) then it does not have a valid
Picture property and you therefore cannot use its Picture property as the
source in any PaintPicture code. If all you have done is draw something into
it or copied something into it from another PictureBox using PaintPicture or
whatever (and if its Autoredraw property was True at the time) then that
"drawing or painting" will have gone into its Image property, and you must
use its Image property as the source in any PaintPicture code or you will
get an 'Invalid Picture' error. Alternatively, if you really do want to use
its Picture property, then you must assign its Image property to it
(Picture1.Picture = Picture1.Image). Personally I would just use its Image
property and leave its Picture property alone.

Mike
Author
13 Mar 2009 10:47 AM
Claus Centrino
"Claus Centrino" <c***@sofort-mail.de> schrieb im
Newsbeitrag news:gp68he$dkq$1@online.de...

As a said in my opening posting I didn't want to discuss my
(complex) code (because pasting hundreds of code lines
wouldn't make a big sense) but would like to get more
technical info about PaintPicture. Now as some of you
consist in having code I stripped off the complete sub
levels and put the basic code into a new form to demonstrate
the effect.

Take a form with 3 pictureboxes
- picTMP
- picRTBG to hold the background image for a richtextbox
- picOUT  showing the final sheet of paper as preview
and a small picture file, in my case a .jpg file.
Adjust the pictures' sizes so that picTMP is a little bit
greater than the jpg file would need, to show the stretch
effect, and picRTBG larger than picTMP to show how multiple
picTMPs can be placed in it, but keep it smaller than
picOUT.

Add a command button to start this sequence:

    Dim xS as Single
    Dim yS as Single
    Dim wS as Single
    Dim hS as Single

    Dim xT as Single
    Dim yT as Single
    Dim wTs Single
    Dim hT as Single

   'initiate pictureboxes
    Wih picTMP
        .Appearance
        .AutoRedraw = True
        .AutoSize = True
        .BorderStyle = 0
        .ScaleMode = vbTwips
    End With

    '... same for picRTBG and picOUT  except that their
AutoSize is set to FALSE
    '...

    'step 1 - load picture into picTMP
    picTMP.Picture = LoadPicture("C:\XY.jpg")

    'step 2 - fill picRTBG with picTMP
    'in my case I have a sub which fills up picRTBG with
several copies of picTMP using PaintPicture
    'but here I do only one to demonstrate streching and how
picRTBG is filled (the point is that no
    'LoadPicture() takes place
    xS = 0
    yS = 0
    wS = picTMP.Width
    hS = picTMP.Height
    xT = 0
    yT = 0
    wT = wS
    hT = hS
    picRTBG.PaintPicture picTMP.Picture, xT, yT, wT, hT, xS,
yS, wS, hS

    'step 3 - place picRTBG to desited position in picOUT
    xS = 0
    yS = 0
    wS = picRTBG.Width
    hS = picRTBG.Height
    xT = 100
    yT = 100
    wT = wS
    hT = hS
    picOUT.PaintPicture picRTBG.Picture, xT, yT, wT, hT, xS,
yS, wS, hS

This last PaintPicture fail with error 481 - invalid
picture.
To make it work in this case it helps to assign the .Image
to the .Picture property before running PaintPicture:

    picRTBG.Picture = picRTBH.Image
    picOUT.PaintPicture picRTBG.Picture, xT, yT, wT, hT, xS,
yS, wS, hS

then it works.

So far, so good.

Now, as my application is much more complex than this small
piece of code I have encapsulated PaintPicture in an own Sub
PicPaintPicture(picT, picS, xs, yS,..) routine which is
called whenever I want to transform a picture or part of it
into another picture. And these 'whenever' calls are again
part of nested subrotines having general parameters.

Therefore my simply Question is how can I detect in my
private PicPaintSub routine if the source picturebox
contains a valid picture?

Because assigning image to picture property just before
calling PaintPicture does NOT work in all cases and could
generate error 5 - invalid procedure call or invalid
argument.

And there a situations where neither PaintPicture without
copying image property nor with copying raises errors in
both cases.

I suppose different scale modes could be a reason (don't
know if so and if yes, if it is the only one), and maybe
there are more such circumstances, but in a complex call
environment it is hard to test lots of parameter
combinations without knowing where to dig. A better way
would be knowing exactly the conditions under which
PaintPicture works as expected. And again, that's what I
asked for.
Author
13 Mar 2009 12:55 PM
Larry Serflaten
"Claus Centrino" <c***@sofort-mail.de> wrote

<snipped for brievity>

> Therefore my simply Question is how can I detect in my
> private PicPaintSub routine if the source picturebox
> contains a valid picture?

The short answer would be to check the Picture.Type property

If Source.Picture.Type <> 0 Then
   ... copy picture ...
End if

But your example had a few other problems.  You are asking
about PaintPicture, when its the Picture property that you are
actually having trouble with.  It pretty much all stems from the
AutoRedraw settings you used.

With AutoRedraw set to False, the things you send to the
Picturebox land on the screen (Line, Circle, PaintPicture, etc)
If you minimize the form, and restore, they're gone!  They are
not a part of the Picturebox.

Even when you say  picRTGB.PaintPicture  ... ...   you are not
adding anything to the picturebox, you are only drawing to the
screen, at that location.  You can verify this by watching the
Picture.Handle, or Picture.Type properties. When they are 0
you don't have a picture associated with the Picture property.
If they are something else, you do.

In a nutshell, if your picRTGB.Picture.Handle is 0, and you
paint to it, you simply paint to the screen.  If you try to
copy a picture whose Handle property is 0, you'll get
the error you saw.

If you are going to be working with pictures and pictureboxes,
set their AutoRedraw properties to True, that gives them all
memory to work with, and that memory is their Image property.

Yes, its a bit confusing to the uninitiated, and someone may
come along with a better explaination, but the simple answer
is to set all their AutoRedraw properties to True so PaintPicture
will work.  You may not see the results (you see the Picture
property, not the Image property), but the function will work
as expected.

LFS
Author
13 Mar 2009 5:38 PM
Claus Centrino
> If you are going to be working with pictures and
> pictureboxes,
> set their AutoRedraw properties to True, that gives them
> all
> memory to work with, and that memory is their Image
> property.

Hmm, I have it already set to True, but nevertheless, your
message also contains valuable info for me, thank you also
and have a good weekend.
Author
13 Mar 2009 8:46 PM
Larry Serflaten
"Claus Centrino" <c***@sofort-mail.de> wrote
> > If you are going to be working with pictures and
> > pictureboxes,
> > set their AutoRedraw properties to True, that gives them
> > all
> > memory to work with, and that memory is their Image
> > property.
>
> Hmm, I have it already set to True, but nevertheless, your
> message also contains valuable info for me, thank you also
> and have a good weekend.

Oops.  I see I misread this line:

    '... same for picRTBG and picOUT  except that their AutoSize is set to FALSE

I set their AutoRedraw to FALSE....

Still, testing the Picture.Type (or handle) should tell you if you have
a valid picture....

Good luck!
LFS
Author
13 Mar 2009 1:26 PM
Michael Williams
"Claus Centrino" <c***@sofort-mail.de> wrote in message
news:gpddm5$g01$1@online.de...

> Now as some of you consist in having code I stripped
> off the complete sub levels and put the basic code into
> a new form to demonstrate the effect.

You sound as though we are asking you to do something rather nasty and that
people who are prepared to help you have no right to ask you to post an
example of the code you are having problems with? A rather strange attitude
if you ask me. Also, since you have at last condescended to provide us with
some example code, I would have hoped that it would actually be tested and
working code that you had actually entered and ran in the IDE, rather than
"air code", which it very definitely is judging by the fact that there are
errors on lines like 'Dim wTs Single' and '.Appearance' (with no
assignment). Still, at least it's a start ;-)

> assigning image to picture property just before
> calling PaintPicture does NOT work in all
> cases

Yes it does. It works both on Autoredraw and on Non Autoredraw Picture
Boxes. If you get an error in PaintPicture after assigning its Image
property to its Picture property then it will not be an Invalid Picture
(Error 481). If you do get an error after doing that then it will probably
be an Error 5 and it will usually be because there is something wrong with
the positional or size parameters you have used with it.

> and could generate error 5 - invalid
> procedure call or invalid argument.

Error 5 is NOT the error you would get if the Picture property did not
contain a valid picture. Error 5 is an Invalid Procedure Call or Argument
error and has nothing whatsoever to do with whether or not the PictureBox
contains a valid Picture property. Error 5 is usually generated when there
is something wrong with the PaintPicture position or size arguments, for
example if you specify an output size of zero pixels (or anything between -7
and +7 on standard 96 dpi machines since you are using twips and since the
value will be converted to whole pixels by PaintPicture). I suspect that if
you are getting such errors then it is because you have problems with the
x1, y1, Width1, Height1, x2, y2, Width2 or Height2 parameters, possibly
because of a ScaleMode problem.

For example, I notice that you are using twips as the ScaleMode for your
three PictureBoxes but that you are using picTMP.Width and picTMP.Height to
assign values to some of the PaintPicture arguments. This can cause problems
because the Width and Height are in the ScaleMode units of the PictureBox's
container (usually the Form) and if the Form's ScaleMode is not also set to
Twips then you will get problems unless you take account of the differences
in ScaleModes. You really should use picTMP.ScaleWidth and
picTMP.ScaleHeight, because they are in the scale units of the PictureBox
and you can then avoid such problems. For example, if the width of your Twip
ScaleMode borderless picTMP PictureBox is 3000 Twips and if your Form also
has a ScaleMode of twips and if you assign the Width value of the PictureBox
to the appropriate one of the PaintPicture arguments (in an attempt to draw
an output at a size of 300 twips) then it will work fine. But if something
somewhere in your code (you said it is a large project) ever changes the
ScaleMode of the Form (for example to vbCentimeters) then the picTMP.Width
will be just 5.292. which will result in PaintPicture attempting to draw the
output at a size of 5.292 twips, which is less than one pixel. This will
result in an Error 5 (Invalid Procedure Call or Argument). Changing to using
ScaleWidth and ScaleHeight in your code (instead of Height and Width as you
are currently using) should solve such problems.

> Therefore my simply Question is how can I detect in
> my  private PicPaintSub routine if the source picturebox contains a valid
> picture? . . . would be knowing exactly
> the conditions under which PaintPicture works as
> expected. And again, that's what I asked for.

Again, it sounds as though you are chastising us for failing to comply with
your every wish, almost as though you have a RIGHT to our help, although
perhaps that's just me being a bit 'edgy' and perhaps it is simply a
language problem? Anyway, my own viiew is that it would be far better to
first fix the problems in your code that are causing the various errors you
seem to be getting, perhaps by tackling the ScaleMode and .Width versus
..ScaleWidth things I've mentioned. Anmd, although this is just a personal
choice really, I would advise you to use pixels when delaing with bitmaps
rather than twips. However, that being said, you can very easily test
whether a PictureBox contrains a valid Picture property or not with the
following code:

If Picture1.Picture.Width = 0 Then
  MsgBox "No Picture assigned to PicBox"
End If

Mike
Author
13 Mar 2009 5:35 PM
Claus Centrino
> You sound as though we are asking you to do something
> rather nasty and that people who are prepared to help you
> have no right to ask you to post an example of the code
> you are having problems with? A rather strange attitude if
> you ask me.

Sorry if it sounds nasty for you, this might come from my
translation from German, but as I said in my opening message
I didn't want to have discussed my specific complex code, I
only wanted to get more info about PaintPicture parameters.

>  Also, since you have at last condescended to provide us
> with some example code, I would have hoped that it would
> actually be tested and working code that you had actually
> entered and ran in the IDE, rather than "air code", which
> it very definitely is judging by the fact that there are
> errors on lines like 'Dim wTs Single' and '.Appearance'
> (with no assignment). Still, at least it's a start ;-)

Sorry again, I didn't copy & paste the code from my
development machine which is not connected to internet,
although I have reread the code there came up still the two
errors you mentioned.

> Again, it sounds as though you are chastising us for
> failing to comply with your every wish, almost as though
> you have a RIGHT to our help, although perhaps that's just
> me being a bit 'edgy' and perhaps it is simply a language
> problem?

I fear it obviously is one.

Anyway, I got valuable information from your message, and
I'll try to change my code according to your hints.

Thank you, and have a good weekend.