Pset and SetPixel Bug 
Author Message
 Pset and SetPixel Bug

I've just come across what appears to be a very interesting little bug in
the VB Pset method when drawing to either a Form or PictureBox (Autoredraw =
False). At first I thought it might be just something to do with VB itself,
but the bug also appears to exists in the GDI SetPixel function, which of
course the VB Pset method uses.

I don't normally set pixels individually on bitmaps and when I do I usually
use much faster methods than SetPixel so it is probably quite some time
since I have used Pset or SetPixel and I don't therefore know how long the
bug has existed on my system. I'm sure that if it was a long time I would
have come across it before though, so I expect it is something new, perhaps
something to do with Vista or one of its updates, although it could of
course be a hardware problem on my own system that I've not noticed before.

The bug causes the pixel to fail to be drawn for certain values of X
coordinate (pixels) but not for others. A quick test seems to indicate that
it fails to be drawn whenever bit 8 of X is set. For example, X values of 0
to &HFF, &H200 to &H2FF and &H400 to &H4FF work fine but X values of &H100
to &H1FF and &H300 to &H3FF do not. For example, if I attempt to use
SetPixel (or the GDI Pset function) to draw a horizontal line on a maximized
Form I get a "dashed" line where the width of the individual lines and
spaces is 256 pixels.

The problem does not exist on an Autoredraw Form or PictureBox, and neither
does it exists for any values of the Y coordinate whether Autoredraw is on
or not. It is just non Autoredraw and X coordinates that seem to have the
problem. This is such an unusual thing that it would almost certainly have
been noticed by lots of other people had it been in existence for any length
of time, so I'm beginning to think that it might be just my own particular
combination of hardware and software and drivers that is causing the
problem. I'm currently using Vista Home Edition with Service Pack 1 and
which is regularly updated on a Intel Core2 Quad Q6600 processor and an ATI
Radeon HD 4850 graphics card. I'm using VB6 with Service Pack 6 installed.

There is some simple test code below which, on my system, produces the fault
I have described. Just paste the code into a VB Form containing a Command
Button and run the program and click the button. I really would appreciate
it if anyone here would be prepared to try it on their own system and report
the result, including details of the system and of which VB ServicePack is
in use. On my system both the blue and the red horizontal lines are "dashed
lines" with 256 pixel wide dashes and spaces, instead of the continuous
horizontal lines that I was expecting.

The code is so straight forward that I can't believe I've done something
wrong myself, although I am getting a bit long in the tooth these days and
my brain is not quite as agile as it used to be so it is always possible
that I've slipped up! If anyone notices a problem with my code then I would
appreciate it if you would let me know.

p.s. I've just tested the same code on my laptop (very different processor
and graphics subsystem than my main machine) and I get the same problem
there. The only similarities between the two machines are the OS (one uses
Vista Home and the other uses Vista Business) and the VB Service Pack (both
using SP6).

Mike

Option Explicit
Private Declare Function SetPixel Lib "gdi32" _
  (ByVal hdc As Long, _
  ByVal x As Long, ByVal y As Long, _
  ByVal crColor As Long) As Long

Private Sub Form_Load()
Me.WindowState = vbMaximized
Me.AutoRedraw = False
Me.ScaleMode = vbPixels
End Sub

Private Sub Command1_Click()
Dim x As Long
For x = 0 To Me.ScaleWidth
  Me.PSet (x, 10), vbBlue
  SetPixel Me.hdc, x, 20, vbRed
Next x
End Sub



Thu, 18 Aug 2011 21:49:07 GMT  
 Pset and SetPixel Bug


Quote:
> I've just come across what appears to be a very interesting little bug in
> the VB Pset method when drawing to either a Form or PictureBox (Autoredraw
=
> False). At first I thought it might be just something to do with VB
itself,
> but the bug also appears to exists in the GDI SetPixel function, which of
> course the VB Pset method uses.

> I don't normally set pixels individually on bitmaps and when I do I
usually
> use much faster methods than SetPixel so it is probably quite some time
> since I have used Pset or SetPixel and I don't therefore know how long the
> bug has existed on my system. I'm sure that if it was a long time I would
> have come across it before though, so I expect it is something new,
perhaps
> something to do with Vista or one of its updates, although it could of
> course be a hardware problem on my own system that I've not noticed
before.

> The bug causes the pixel to fail to be drawn for certain values of X
> coordinate (pixels) but not for others. A quick test seems to indicate
that
> it fails to be drawn whenever bit 8 of X is set. For example, X values of
0
> to &HFF, &H200 to &H2FF and &H400 to &H4FF work fine but X values of &H100
> to &H1FF and &H300 to &H3FF do not. For example, if I attempt to use
> SetPixel (or the GDI Pset function) to draw a horizontal line on a
maximized
> Form I get a "dashed" line where the width of the individual lines and
> spaces is 256 pixels.

> The problem does not exist on an Autoredraw Form or PictureBox, and
neither
> does it exists for any values of the Y coordinate whether Autoredraw is on
> or not. It is just non Autoredraw and X coordinates that seem to have the
> problem. This is such an unusual thing that it would almost certainly have
> been noticed by lots of other people had it been in existence for any
length
> of time, so I'm beginning to think that it might be just my own particular
> combination of hardware and software and drivers that is causing the
> problem. I'm currently using Vista Home Edition with Service Pack 1 and
> which is regularly updated on a Intel Core2 Quad Q6600 processor and an
ATI
> Radeon HD 4850 graphics card. I'm using VB6 with Service Pack 6 installed.

> There is some simple test code below which, on my system, produces the
fault
> I have described. Just paste the code into a VB Form containing a Command
> Button and run the program and click the button. I really would appreciate
> it if anyone here would be prepared to try it on their own system and
report
> the result, including details of the system and of which VB ServicePack is
> in use. On my system both the blue and the red horizontal lines are
"dashed
> lines" with 256 pixel wide dashes and spaces, instead of the continuous
> horizontal lines that I was expecting.

> The code is so straight forward that I can't believe I've done something
> wrong myself, although I am getting a bit long in the tooth these days and
> my brain is not quite as agile as it used to be so it is always possible
> that I've slipped up! If anyone notices a problem with my code then I
would
> appreciate it if you would let me know.

> p.s. I've just tested the same code on my laptop (very different processor
> and graphics subsystem than my main machine) and I get the same problem
> there. The only similarities between the two machines are the OS (one uses
> Vista Home and the other uses Vista Business) and the VB Service Pack
(both
> using SP6).

> Mike

> Option Explicit
> Private Declare Function SetPixel Lib "gdi32" _
>   (ByVal hdc As Long, _
>   ByVal x As Long, ByVal y As Long, _
>   ByVal crColor As Long) As Long

> Private Sub Form_Load()
> Me.WindowState = vbMaximized
> Me.AutoRedraw = False
> Me.ScaleMode = vbPixels
> End Sub

> Private Sub Command1_Click()
> Dim x As Long
> For x = 0 To Me.ScaleWidth
>   Me.PSet (x, 10), vbBlue
>   SetPixel Me.hdc, x, 20, vbRed
> Next x
> End Sub

Windows2000 SP4
VB6 SP5
Matrox G450/Athlon3200+/Abit AN7

Solid lines - no dashing'

Michael



Thu, 18 Aug 2011 22:06:35 GMT  
 Pset and SetPixel Bug


(Top-posted for brevity....)

I just see one solid red line and one solid blue line....no gaps.

At first I thought I saw one area that didn't look solid...but that
turned out to be a spot of something on my monitor.

Quote:
> I've just come across what appears to be a very interesting little bug
> in the VB Pset method when drawing to either a Form or PictureBox
> (Autoredraw = False). At first I thought it might be just something to
> do with VB itself, but the bug also appears to exists in the GDI
> SetPixel function, which of course the VB Pset method uses.

> I don't normally set pixels individually on bitmaps and when I do I
> usually use much faster methods than SetPixel so it is probably quite
> some time since I have used Pset or SetPixel and I don't therefore
> know how long the bug has existed on my system. I'm sure that if it
> was a long time I would have come across it before though, so I expect
> it is something new, perhaps something to do with Vista or one of its
> updates, although it could of course be a hardware problem on my own
> system that I've not noticed before.

> The bug causes the pixel to fail to be drawn for certain values of X
> coordinate (pixels) but not for others. A quick test seems to indicate
> that it fails to be drawn whenever bit 8 of X is set. For example, X
> values of 0 to &HFF, &H200 to &H2FF and &H400 to &H4FF work fine but X
> values of &H100 to &H1FF and &H300 to &H3FF do not. For example, if I
> attempt to use SetPixel (or the GDI Pset function) to draw a
> horizontal line on a maximized Form I get a "dashed" line where the
> width of the individual lines and spaces is 256 pixels.

> The problem does not exist on an Autoredraw Form or PictureBox, and
> neither does it exists for any values of the Y coordinate whether
> Autoredraw is on or not. It is just non Autoredraw and X coordinates
> that seem to have the problem. This is such an unusual thing that it
> would almost certainly have been noticed by lots of other people had
> it been in existence for any length of time, so I'm beginning to think
> that it might be just my own particular combination of hardware and
> software and drivers that is causing the problem. I'm currently using
> Vista Home Edition with Service Pack 1 and which is regularly updated
> on a Intel Core2 Quad Q6600 processor and an ATI Radeon HD 4850
> graphics card. I'm using VB6 with Service Pack 6 installed.

> There is some simple test code below which, on my system, produces the
> fault I have described. Just paste the code into a VB Form containing
> a Command Button and run the program and click the button. I really
> would appreciate it if anyone here would be prepared to try it on
> their own system and report the result, including details of the
> system and of which VB ServicePack is in use. On my system both the
> blue and the red horizontal lines are "dashed lines" with 256 pixel
> wide dashes and spaces, instead of the continuous horizontal lines
> that I was expecting.

> The code is so straight forward that I can't believe I've done
> something wrong myself, although I am getting a bit long in the tooth
> these days and my brain is not quite as agile as it used to be so it
> is always possible that I've slipped up! If anyone notices a problem
> with my code then I would appreciate it if you would let me know.

> p.s. I've just tested the same code on my laptop (very different
> processor and graphics subsystem than my main machine) and I get the
> same problem there. The only similarities between the two machines are
> the OS (one uses Vista Home and the other uses Vista Business) and the
> VB Service Pack (both using SP6).

> Mike

> Option Explicit
> Private Declare Function SetPixel Lib "gdi32" _
>   (ByVal hdc As Long, _
>   ByVal x As Long, ByVal y As Long, _
>   ByVal crColor As Long) As Long

> Private Sub Form_Load()
> Me.WindowState = vbMaximized
> Me.AutoRedraw = False
> Me.ScaleMode = vbPixels
> End Sub

> Private Sub Command1_Click()
> Dim x As Long
> For x = 0 To Me.ScaleWidth
>   Me.PSet (x, 10), vbBlue
>   SetPixel Me.hdc, x, 20, vbRed
> Next x
> End Sub



Thu, 18 Aug 2011 22:43:08 GMT  
 Pset and SetPixel Bug
  I get 2 solid lines.

Win98SE
Athlon 1660 (KT-Pro2-A MSI board)
3dfx Voodoo3 graphics
VS SP3



Thu, 18 Aug 2011 23:00:03 GMT  
 Pset and SetPixel Bug
XP Pro SP2
VB6 SP5
AMD 4800 DualCore
MSI MB

Two solid lines.

/Henning



Quote:



>> I've just come across what appears to be a very interesting little bug in
>> the VB Pset method when drawing to either a Form or PictureBox
>> (Autoredraw
> =
>> False). At first I thought it might be just something to do with VB
> itself,
>> but the bug also appears to exists in the GDI SetPixel function, which of
>> course the VB Pset method uses.

>> I don't normally set pixels individually on bitmaps and when I do I
> usually
>> use much faster methods than SetPixel so it is probably quite some time
>> since I have used Pset or SetPixel and I don't therefore know how long
>> the
>> bug has existed on my system. I'm sure that if it was a long time I would
>> have come across it before though, so I expect it is something new,
> perhaps
>> something to do with Vista or one of its updates, although it could of
>> course be a hardware problem on my own system that I've not noticed
> before.

>> The bug causes the pixel to fail to be drawn for certain values of X
>> coordinate (pixels) but not for others. A quick test seems to indicate
> that
>> it fails to be drawn whenever bit 8 of X is set. For example, X values of
> 0
>> to &HFF, &H200 to &H2FF and &H400 to &H4FF work fine but X values of
>> &H100
>> to &H1FF and &H300 to &H3FF do not. For example, if I attempt to use
>> SetPixel (or the GDI Pset function) to draw a horizontal line on a
> maximized
>> Form I get a "dashed" line where the width of the individual lines and
>> spaces is 256 pixels.

>> The problem does not exist on an Autoredraw Form or PictureBox, and
> neither
>> does it exists for any values of the Y coordinate whether Autoredraw is
>> on
>> or not. It is just non Autoredraw and X coordinates that seem to have the
>> problem. This is such an unusual thing that it would almost certainly
>> have
>> been noticed by lots of other people had it been in existence for any
> length
>> of time, so I'm beginning to think that it might be just my own
>> particular
>> combination of hardware and software and drivers that is causing the
>> problem. I'm currently using Vista Home Edition with Service Pack 1 and
>> which is regularly updated on a Intel Core2 Quad Q6600 processor and an
> ATI
>> Radeon HD 4850 graphics card. I'm using VB6 with Service Pack 6
>> installed.

>> There is some simple test code below which, on my system, produces the
> fault
>> I have described. Just paste the code into a VB Form containing a Command
>> Button and run the program and click the button. I really would
>> appreciate
>> it if anyone here would be prepared to try it on their own system and
> report
>> the result, including details of the system and of which VB ServicePack
>> is
>> in use. On my system both the blue and the red horizontal lines are
> "dashed
>> lines" with 256 pixel wide dashes and spaces, instead of the continuous
>> horizontal lines that I was expecting.

>> The code is so straight forward that I can't believe I've done something
>> wrong myself, although I am getting a bit long in the tooth these days
>> and
>> my brain is not quite as agile as it used to be so it is always possible
>> that I've slipped up! If anyone notices a problem with my code then I
> would
>> appreciate it if you would let me know.

>> p.s. I've just tested the same code on my laptop (very different
>> processor
>> and graphics subsystem than my main machine) and I get the same problem
>> there. The only similarities between the two machines are the OS (one
>> uses
>> Vista Home and the other uses Vista Business) and the VB Service Pack
> (both
>> using SP6).

>> Mike

>> Option Explicit
>> Private Declare Function SetPixel Lib "gdi32" _
>>   (ByVal hdc As Long, _
>>   ByVal x As Long, ByVal y As Long, _
>>   ByVal crColor As Long) As Long

>> Private Sub Form_Load()
>> Me.WindowState = vbMaximized
>> Me.AutoRedraw = False
>> Me.ScaleMode = vbPixels
>> End Sub

>> Private Sub Command1_Click()
>> Dim x As Long
>> For x = 0 To Me.ScaleWidth
>>   Me.PSet (x, 10), vbBlue
>>   SetPixel Me.hdc, x, 20, vbRed
>> Next x
>> End Sub

> Windows2000 SP4
> VB6 SP5
> Matrox G450/Athlon3200+/Abit AN7

> Solid lines - no dashing'

> Michael



Thu, 18 Aug 2011 23:50:42 GMT  
 Pset and SetPixel Bug
I get 2 solid lines, No Breaks

WinXP
ATI Radeon 9550 / X1050 Series
VS SP5

Does the same thing happen if you use SetPixel1V?

What is faster the SetPixel for setting a pixel?

Ivar



Fri, 19 Aug 2011 03:24:40 GMT  
 Pset and SetPixel Bug

Quote:
> I get 2 solid lines, No Breaks
> WinXP
> ATI Radeon 9550 / X1050 Series
> VS SP5

So far all of the respondents have said they are getting complete solid
lines and none of them have said they are using Vista or VB Service Pack 6,
so I suspect it might be one of those that is causing the problem.

Quote:
> Does the same thing happen if you use SetPixelV?

Yes.

Quote:
> What is faster the SetPixel for setting a pixel?

Actually there isn't usually a great deal of difference between the speed of
the native VB functions and the speed of the equivalent API function when
doing things like drawing lines and plotting points (especially when you are
doing so directly to the display), because they are what I personally call
"top heavy" functions, by which I mean the time taken for VB to do its
stuff, even if it is running in the IDE, is a small proportion of the
overall execution time because the underlying GDI function (which is
eventually used in both cases) takes a significant amount of time when
performing graphic operations. Things are a bit different when drawing to an
Autoredraw bitmap though, because VB methods individually effectively
trigger a refresh of the display from the Autoredraw bitmap, which I think
actually causes refreshes in the OS at the current display refresh rate or
thereabouts, whereas the GDI drawing and plotting methods do not trigger
such an Autoredraw refresh.

For example, on my machine when run as a native code compiled exe and
drawing to a non Autoredraw Form the VB Pset method takes about 2.6
microseconds per pixel whereas SetPixel takes about 2.4 microseconds and
SetPixelV takes about the same (2.4 microseconds). This is running in Vista
though, which effectively disables all of your graphics card's accelerated
2D hardware and so the functions are performed in software in Vista, so you
can expect faster speeds from the same system running XP in most cases.

Quote:
> What is faster the SetPixel for setting a pixel?

Actually, despite my previous long answer to the very same question, I've
just realised what you actually meant by that. At first I though you were
asking how fast SetPixel was compared to Pset, but I now realise that you
are asking what is faster than SetpPixel because of what I said in my
previous post when, referring to both Pset and SetPixel, I said, "I usually
use much faster methods". In fact what I meant is that whenever the need
arises to analyse and / or read and write lots of (or all of) the individual
pixels of a bitmap I usually point a Byte array to the existing location of
the bitmap data (or sometimes transfer a copy of the data into a Byte array)
and then address the three or four bytes (or whatever) of each pixel by
reading and writing the bytes of the array, which is very fast.

Mike



Fri, 19 Aug 2011 05:16:14 GMT  
 Pset and SetPixel Bug
Hi Mike Williams
I have just tried your code and I get 2 complete solid lines 1 red 1 blue.

XP SP3 VB6 SP6

Hope this helps.

Ron

Quote:

> I've just come across what appears to be a very interesting little bug in
> the VB Pset method when drawing to either a Form or PictureBox (Autoredraw =
> False). At first I thought it might be just something to do with VB itself,
> but the bug also appears to exists in the GDI SetPixel function, which of
> course the VB Pset method uses.

> I don't normally set pixels individually on bitmaps and when I do I usually
> use much faster methods than SetPixel so it is probably quite some time
> since I have used Pset or SetPixel and I don't therefore know how long the
> bug has existed on my system. I'm sure that if it was a long time I would
> have come across it before though, so I expect it is something new, perhaps
> something to do with Vista or one of its updates, although it could of
> course be a hardware problem on my own system that I've not noticed before.

> The bug causes the pixel to fail to be drawn for certain values of X
> coordinate (pixels) but not for others. A quick test seems to indicate that
> it fails to be drawn whenever bit 8 of X is set. For example, X values of 0
> to &HFF, &H200 to &H2FF and &H400 to &H4FF work fine but X values of &H100
> to &H1FF and &H300 to &H3FF do not. For example, if I attempt to use
> SetPixel (or the GDI Pset function) to draw a horizontal line on a maximized
> Form I get a "dashed" line where the width of the individual lines and
> spaces is 256 pixels.

> The problem does not exist on an Autoredraw Form or PictureBox, and neither
> does it exists for any values of the Y coordinate whether Autoredraw is on
> or not. It is just non Autoredraw and X coordinates that seem to have the
> problem. This is such an unusual thing that it would almost certainly have
> been noticed by lots of other people had it been in existence for any length
> of time, so I'm beginning to think that it might be just my own particular
> combination of hardware and software and drivers that is causing the
> problem. I'm currently using Vista Home Edition with Service Pack 1 and
> which is regularly updated on a Intel Core2 Quad Q6600 processor and an ATI
> Radeon HD 4850 graphics card. I'm using VB6 with Service Pack 6 installed.

> There is some simple test code below which, on my system, produces the fault
> I have described. Just paste the code into a VB Form containing a Command
> Button and run the program and click the button. I really would appreciate
> it if anyone here would be prepared to try it on their own system and report
> the result, including details of the system and of which VB ServicePack is
> in use. On my system both the blue and the red horizontal lines are "dashed
> lines" with 256 pixel wide dashes and spaces, instead of the continuous
> horizontal lines that I was expecting.

> The code is so straight forward that I can't believe I've done something
> wrong myself, although I am getting a bit long in the tooth these days and
> my brain is not quite as agile as it used to be so it is always possible
> that I've slipped up! If anyone notices a problem with my code then I would
> appreciate it if you would let me know.

> p.s. I've just tested the same code on my laptop (very different processor
> and graphics subsystem than my main machine) and I get the same problem
> there. The only similarities between the two machines are the OS (one uses
> Vista Home and the other uses Vista Business) and the VB Service Pack (both
> using SP6).

> Mike

> Option Explicit
> Private Declare Function SetPixel Lib "gdi32" _
>   (ByVal hdc As Long, _
>   ByVal x As Long, ByVal y As Long, _
>   ByVal crColor As Long) As Long

> Private Sub Form_Load()
> Me.WindowState = vbMaximized
> Me.AutoRedraw = False
> Me.ScaleMode = vbPixels
> End Sub

> Private Sub Command1_Click()
> Dim x As Long
> For x = 0 To Me.ScaleWidth
>   Me.PSet (x, 10), vbBlue
>   SetPixel Me.hdc, x, 20, vbRed
> Next x
> End Sub



Thu, 18 Aug 2011 23:04:04 GMT  
 Pset and SetPixel Bug

Quote:

> So far all of the respondents have said they are getting complete solid
> lines and none of them have said they are using Vista or VB Service Pack
> 6, so I suspect it might be one of those that is causing the problem.

I don't have vb6 installed on my Vista Home Premium laptop. An exe compiled
on XP vb6sp6 didn't experience the problem when ran on the Vista laptop


Fri, 19 Aug 2011 07:19:06 GMT  
 Pset and SetPixel Bug
Windows Vista SP1
VB6 SP6
GeForce 8800GTX/Core2Duo E6850/Nvidia MB

Dashed lines, both PSet and SetPixel

It has to be related to the video drivers.  I am sure I would have seen this
before.

Randy
ms mvp, Visual Basic
http://vbnet.mvps.org/


Quote:
> XP Pro SP2
> VB6 SP5
> AMD 4800 DualCore
> MSI MB

> Two solid lines.

> /Henning





>>> I've just come across what appears to be a very interesting little bug
>>> in
>>> the VB Pset method when drawing to either a Form or PictureBox
>>> (Autoredraw
>> =
>>> False). At first I thought it might be just something to do with VB
>> itself,
>>> but the bug also appears to exists in the GDI SetPixel function, which
>>> of
>>> course the VB Pset method uses.

>>> I don't normally set pixels individually on bitmaps and when I do I
>> usually
>>> use much faster methods than SetPixel so it is probably quite some time
>>> since I have used Pset or SetPixel and I don't therefore know how long
>>> the
>>> bug has existed on my system. I'm sure that if it was a long time I
>>> would
>>> have come across it before though, so I expect it is something new,
>> perhaps
>>> something to do with Vista or one of its updates, although it could of
>>> course be a hardware problem on my own system that I've not noticed
>> before.

>>> The bug causes the pixel to fail to be drawn for certain values of X
>>> coordinate (pixels) but not for others. A quick test seems to indicate
>> that
>>> it fails to be drawn whenever bit 8 of X is set. For example, X values
>>> of
>> 0
>>> to &HFF, &H200 to &H2FF and &H400 to &H4FF work fine but X values of
>>> &H100
>>> to &H1FF and &H300 to &H3FF do not. For example, if I attempt to use
>>> SetPixel (or the GDI Pset function) to draw a horizontal line on a
>> maximized
>>> Form I get a "dashed" line where the width of the individual lines and
>>> spaces is 256 pixels.

>>> The problem does not exist on an Autoredraw Form or PictureBox, and
>> neither
>>> does it exists for any values of the Y coordinate whether Autoredraw is
>>> on
>>> or not. It is just non Autoredraw and X coordinates that seem to have
>>> the
>>> problem. This is such an unusual thing that it would almost certainly
>>> have
>>> been noticed by lots of other people had it been in existence for any
>> length
>>> of time, so I'm beginning to think that it might be just my own
>>> particular
>>> combination of hardware and software and drivers that is causing the
>>> problem. I'm currently using Vista Home Edition with Service Pack 1 and
>>> which is regularly updated on a Intel Core2 Quad Q6600 processor and an
>> ATI
>>> Radeon HD 4850 graphics card. I'm using VB6 with Service Pack 6
>>> installed.

>>> There is some simple test code below which, on my system, produces the
>> fault
>>> I have described. Just paste the code into a VB Form containing a
>>> Command
>>> Button and run the program and click the button. I really would
>>> appreciate
>>> it if anyone here would be prepared to try it on their own system and
>> report
>>> the result, including details of the system and of which VB ServicePack
>>> is
>>> in use. On my system both the blue and the red horizontal lines are
>> "dashed
>>> lines" with 256 pixel wide dashes and spaces, instead of the continuous
>>> horizontal lines that I was expecting.

>>> The code is so straight forward that I can't believe I've done something
>>> wrong myself, although I am getting a bit long in the tooth these days
>>> and
>>> my brain is not quite as agile as it used to be so it is always possible
>>> that I've slipped up! If anyone notices a problem with my code then I
>> would
>>> appreciate it if you would let me know.

>>> p.s. I've just tested the same code on my laptop (very different
>>> processor
>>> and graphics subsystem than my main machine) and I get the same problem
>>> there. The only similarities between the two machines are the OS (one
>>> uses
>>> Vista Home and the other uses Vista Business) and the VB Service Pack
>> (both
>>> using SP6).

>>> Mike

>>> Option Explicit
>>> Private Declare Function SetPixel Lib "gdi32" _
>>>   (ByVal hdc As Long, _
>>>   ByVal x As Long, ByVal y As Long, _
>>>   ByVal crColor As Long) As Long

>>> Private Sub Form_Load()
>>> Me.WindowState = vbMaximized
>>> Me.AutoRedraw = False
>>> Me.ScaleMode = vbPixels
>>> End Sub

>>> Private Sub Command1_Click()
>>> Dim x As Long
>>> For x = 0 To Me.ScaleWidth
>>>   Me.PSet (x, 10), vbBlue
>>>   SetPixel Me.hdc, x, 20, vbRed
>>> Next x
>>> End Sub

>> Windows2000 SP4
>> VB6 SP5
>> Matrox G450/Athlon3200+/Abit AN7

>> Solid lines - no dashing'

>> Michael



Fri, 19 Aug 2011 11:54:16 GMT  
 Pset and SetPixel Bug
Hi Mike,

Quote:
> Actually, despite my previous long answer to the very same question,
> I've just realised what you actually meant by that. At first I though
> you were asking how fast SetPixel was compared to Pset, but I now
> realise that you are asking what is faster than SetpPixel because of
> what I said in my previous post when, referring to both Pset and
> SetPixel, I said, "I usually use much faster methods". In fact what I
> meant is that whenever the need arises to analyse and / or read and
> write lots of (or all of) the individual pixels of a bitmap I usually
> point a Byte array to the existing location of the bitmap data (or
> sometimes transfer a copy of the data into a Byte array) and then
> address the three or four bytes (or whatever) of each pixel by reading
> and writing the bytes of the array, which is very fast.

this is a very intresting idea, could you please provide some code on
how to point a byte array to a bitmap?

Thanks



Fri, 19 Aug 2011 18:59:45 GMT  
 Pset and SetPixel Bug



Quote:
> I've just come across what appears to be a very interesting little bug in
> the VB Pset method when drawing to either a Form or PictureBox (Autoredraw
> = False). At first I thought it might be just something to do with VB
> itself, but the bug also appears to exists in the GDI SetPixel function,
> which of course the VB Pset method uses.
[HUGE SNIP]
> The code is so straight forward that I can't believe I've done something
> wrong myself, although I am getting a bit long in the tooth these days and
> my brain is not quite as agile as it used to be so it is always possible
> that I've slipped up! If anyone notices a problem with my code then I
> would appreciate it if you would let me know.

"my brain is not quite as agile as it used to be "
Maybe your eyes too? Certainly so in my case.
Have you by any chance changed the character and icon sizes in Vista?
I found that the VB6 interface was greatly perturbed when I set Vista to use
larger fonts (120ppp instead of 96).
That said, I have tested your proggy on Vista/VB6/SP6 in both "normal" and
"blind old codger" modes and got solid lines both times.
I alos tried with screen resolutions other than the native maximum, still no
problems.


Fri, 19 Aug 2011 23:36:32 GMT  
 Pset and SetPixel Bug

Quote:
> this is a very intresting idea, could you please provide some
> code on how to point a byte array to a bitmap?

The method varies slightly depending on what kind of bitmap you are dealing
with (screen compatible bitmap or device independent bitmap) and also where
you are getting it from. If for example it is a device independent bitmap
that you have created in code using CreateDIBSection then the
CreateDIBSection function will return a pointer in the ppbits parameter
telling you where in memory the bitmap bits are located, or if you have
loaded a bmp file from disk using LoadImage then the LoadImage function is
capable of telling you where the bitmap data is located in memory. Once you
know the address you can then point a SAFEARRAY structure at that data and
access it from the array. Perhaps a more flexible, albeit it slightly
slower, method is to use GetDIBits to transfer the pixel data of an existing
bitmap to an area of memory (an standard VB array of Bytes or perhaps Longs)
in DIB format because this is easier to set up and will allow you to more
easily deal with bitmaps that you commonly come across in VB6 (the Image
bitmap of an Autoredraw PictureBox for example, the format of which varies
depending on the colour depth of your display). This is slower than the
previous method of pointing a SAFEARRAY structure at an existing block of
bitmap data because it involves creating a new block of memory (the standard
VB array of Bytes or Longs) and transferring the data of an existing bitmap
into it, with the conversion that is required to convert the pixel data from
screen compatible format to DIB format, but GetDIBits is surprisingly fast
at converting and shifting such data so it is still a very useful technique.

As an example, the following code loads a jpg image and stretches it into a
screen sized Autoredraw VB PictureBox so that it exactly fits (in this
simple example I have not taken account of the original aspect ratio).
However, if you wish, you can easily change the code so that the PictureBox
sizes itself to the full original image size. When you run the code and
click the displayed picture the GetDIBits function copies the pixel data in
DIB format into a suitably sized VB array of UDTs, where each UDT contains 4
individual Bytes (I could have instead used an array of Longs, but in this
case I wanted easy access to the individual rgb bytes of each pixel). The
code then, just for test purposes, runs through the VB array setting the red
component of each "pixel" to zero. Finally the SetDIBitstoDevice function is
used to transfer the VB array data back to the PictureBox in the appropriate
format. Note that it would have been possible to transfer the data as a
"three bytes per pixel" DIB into a Byte array, but using four bytes per
pixel (even though it uses a little more memory) is sometimes more
appropriate.

Anyway, to try the code paste it into a VB Form containing a PictureBox and
change the hard coded "c:\temp\jan1.jpg" to a picture that exists on your
own system. When you run the project and click the displayed picture you
will see the effect of the removal of the red element and the time taken
will be displayed in a message box, showing separately the time taken by
GetDIBits, the time to run through and modify the VB array data, the time
taken by SetDIBitsToDevice and the overall total time. This time to deal
with the array will be a lot quicker of course when run as a native code
compiled exe than it will be when run in the IDE. Even though this
particular method takes longer than the alternative of pointing an array at
the existing image data (because it needs to actually copy blocks of memory
data) it is still very quick when compared to SetPixel, typically hundreds
of times faster.

Mike

Option Explicit
Private Declare Function timeBeginPeriod _
  Lib "winmm.dll" (ByVal uPeriod As Long) As Long
Private Declare Function timeEndPeriod _
  Lib "winmm.dll" (ByVal uPeriod As Long) As Long
Private Declare Function timeGetTime _
  Lib "winmm.dll" () As Long
Private Type BITMAPINFOHEADER
  biSize As Long
  biWidth As Long
  biHeight As Long
  biPlanes As Integer
  biBitCount As Integer
  biCompression As Long
  biSizeImage As Long
  biXPel{*filter*}eter As Long
  biYPel{*filter*}eter As Long
  biClrUsed As Long
  biClrImportant As Long
End Type
Private Type RGBQUAD
  rgbBlue As Byte
  rgbGreen As Byte
  rgbRed As Byte
  rgbReserved As Byte
End Type
Private Type BITMAPINFO
  bmiHeader As BITMAPINFOHEADER
End Type
Private Declare Function GetDIBits Lib "gdi32" _
  (ByVal hdc As Long, ByVal hBitmap As Long, _
  ByVal nStartScan As Long, ByVal nNumScans As Long, _
  lpBits As Any, lpBI As BITMAPINFO, _
  ByVal wUsage As Long) As Long
Private Declare Function SetDIBitsToDevice Lib "gdi32" _
  (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, _
  ByVal dx As Long, ByVal dy As Long, ByVal SrcX As Long, _
  ByVal SrcY As Long, ByVal Scan As Long, _
  ByVal NumScans As Long, Bits As Any, _
  BitsInfo As BITMAPINFO, ByVal wUsage As Long) As Long
Private Const DIB_RGB_COLORS = 0
Private Const BI_RGB = 0

Private Sub Form_Load()
timeBeginPeriod 1
Me.WindowState = vbMaximized
Me.Show
Picture1.Move 0, 0, Me.ScaleWidth, Me.ScaleHeight
Picture1.ScaleMode = vbPixels
Picture1.AutoRedraw = True
Picture1.PaintPicture LoadPicture("c:\temp\jan1.jpg"), _
  0, 0, Picture1.ScaleWidth, Picture1.ScaleHeight
End Sub

Private Sub Form_Unload(Cancel As Integer)
timeEndPeriod 1
End Sub

Private Sub Picture1_MouseDown(Button As Integer, _
  Shift As Integer, x As Single, y As Single)
Dim bmapinfo As BITMAPINFO
Dim SourceArray() As RGBQUAD
Dim SourceWidth As Long, SourceHeight As Long
Dim x1 As Long, y1 As Long
Dim t1 As Long, t2 As Long
Dim t3 As Long, t4 As Long
SourceWidth = Picture1.ScaleWidth
SourceHeight = Picture1.ScaleHeight
With bmapinfo.bmiHeader
  .biSize = Len(bmapinfo)
  .biWidth = SourceWidth
  .biHeight = SourceHeight
  .biPlanes = 1
  .biBitCount = 32
  .biCompression = BI_RGB
End With
t1 = timeGetTime
ReDim SourceArray(1 To SourceWidth, 1 To SourceHeight)
GetDIBits Picture1.hdc, Picture1.Image, _
    0, SourceHeight, SourceArray(1, 1), bmapinfo, _
    DIB_RGB_COLORS
t2 = timeGetTime
' just some test code to set the red
' component of each pixel to zero
For y1 = 1 To SourceHeight
  For x1 = 1 To SourceWidth
    SourceArray(x1, y1).rgbRed = 0
  Next x1
Next y1
'
t3 = timeGetTime
SetDIBitsToDevice Picture1.hdc, 0, 0, SourceWidth, _
  SourceHeight, 0, 0, 0, SourceHeight, SourceArray(1, 1), _
  bmapinfo, DIB_RGB_COLORS
t4 = timeGetTime
Picture1.Refresh
MsgBox t2 - t1 & " milliseconds to create array and GetDIBits." _
  & vbCrLf & t3 - t2 & " milliseconds to modify pixels " _
  & vbCrLf & t4 - t3 & " milliseconds to SetBits back to Image." _
  & vbCrLf & vbCrLf & "total time is " & t4 - t1 & " milliseconds."
End Sub



Fri, 19 Aug 2011 23:52:01 GMT  
 Pset and SetPixel Bug

Quote:
> I've just come across what appears to be a very interesting little bug in
> the VB Pset method when drawing to either a Form or PictureBox (Autoredraw
> = False). At first I thought it might be just something to do with VB
> itself, but the bug also appears to exists in the GDI SetPixel function,
> which of course the VB Pset method uses.

I get lines with huge gaps in them on my laptop

Vista Ultimate SP1; no 'aero', no font smoothing effects
Mobile Intel 945GM Express Chipset Family
Intel Video BIOS
VB6 SP5

If I set the Form's DrawWidth property to 2 or more I get a solid line from
the PSet method.  I also get a solid line using the Me.Line method rather
than setting individal pixels:
Me.Line (0, 30)-(Me.ScaleWidth, 30), vbGreen ' no breaks

I modfied the code as follow to confirm where the transitions took place

Dim x As Long
For x = 0 To Me.ScaleWidth
  Me.PSet (x, 10), vbBlue
  SetPixel Me.hdc, x, 50, vbRed
  If x > 0 Then
    If Me.Point(x, 10) <> Me.Point(x - 1, 10) Then
      Me.CurrentX = x
      Me.CurrentY = 25
      Me.Print x
    End If
    If Me.Point(x, 50) <> Me.Point(x - 1, 50) Then
      Me.CurrentX = x
      Me.CurrentY = 65
      Me.Print x
    End If
  End If
Next x
Me.Line (0, 100)-(Me.ScaleWidth, 100), vbGreen

The gaps are from 256-511 and 768-1023 so it's only a poblem when that one
bit is set in the x value



Sat, 20 Aug 2011 00:10:36 GMT  
 Pset and SetPixel Bug

Quote:
> Windows Vista SP1
> VB6 SP6
> GeForce 8800GTX/Core2Duo E6850/Nvidia MB
> Dashed lines, both PSet and SetPixel
> It has to be related to the video drivers.  I am sure
> I would have seen this before.

That's exactly what I thought at first, a possible video card driver problem
which is usually the first thing I suspect when I come across such problems.
That is why I tested it on my laptop (which is also Vista using VB6 SP6)
fully expecting it to work correctly and produce a solid line on my laptop,
which uses completely different hardware. However, I was extremely surprised
to find that it performed exactly the same on my laptop as it did on my
desktop, producing a line with wide breaks! I suppose it could be the case
that both my laptop and my desktop have similar driver problems (something
which I haven't yet looked into), but I wasn't expecting it because the
hardware is so different. My main machine uses a modern Intel Quad Core
processor and a fairly high end 512MB ATI Radeon 4850 graphics card whereas
my laptop uses a cheap single core Intel Celeron 1.6 processor with a cheap
"built into the motherboard" Intel GMA950 graphics chip set.

Mike



Sat, 20 Aug 2011 01:04:34 GMT  
 
 [ 25 post ]  Go to page: [1] [2]

 Relevant Pages 

1. setPixel doesn't work

2. Modifying an image using setpixel...

3. weird error with setpixels

4. using SetPixel

5. SetPixel and "Connect the dots"

6. Get/SetPixel API - Need help on ways to speed up a loop

7. setpixel

8. MASKBIT or SETPIXEL

9. Using SetPixel and Actually gettting the right color?

10. GetPixel doesn't get what SetPixel set

11. HELP: GetPixel and SetPixel ??

12. SetBkColor & SetPixel

 

 
Powered by phpBB® Forum Software