From: Webbiz on
On Tue, 2 Mar 2010 08:38:59 -0000, "Ivar"
<ivar.ekstromer000(a)ntlworld.com> wrote:

>
>
>If scrolling is involved then speed of drawing is an issue, for that reason
>I would not use bitmaps etc. Instead create yourself a sub that you can pass
>the needed arguments to, such as the HDC, the X and the Y and something to
>indentify the type of arrow to draw and call it as needed. I would look to
>CreatePolygonRgn and similar APIs for the drawing of shapes.
>With this method you can have total control of what is drawn with very fast
>speeds. Just needs a bit more coding from you.
>Have fun
>
>Ivar


Thanks Ivar.

CreatePolygonRgn. I'll check it out.

Webbiz
From: Webbiz on
On Tue, 2 Mar 2010 19:43:17 -0000, "Mike Williams"
<Mike(a)WhiskyAndCoke.com> wrote:

>"Mike Williams" <Mike(a)WhiskyAndCoke.com> wrote in message
>news:%23ubQdAfuKHA.812(a)TK2MSFTNGP06.phx.gbl...
>
>> . . if the arrow is a simple line drawing (either filled or unfilled),
>> then it would probably be faster to draw it
>> using the GDI Polygon function . .
>
>One thing I forgot to mention in my previous response is if you decide to
>use the Polygon and SetWindowOrgEx method to draw your arrows then it might
>be best to make the first data item in the array of poly points the
>coordinates of the point of the arrow (rather than the coordinates of any
>other position around its shape) and set the "point" coordinates in the data
>to the values (0, 0). In that way whenever you wish to draw an arrow you
>merely need to specify the location of its point (which is probably most
>often the part of the arrow you are interested in) and the arrow will be
>drawn with its point at the desired location. To see what I mean, try the
>following simplified example (into a Form containing a PictureBox and a
>Command Button). The outline color of the arrow is determined by the
>ForeColor of the PicBox and the fill colour is determined both by the
>FillStyle and FillColor properties, all of which you can set using either
>the standard VB PictureBox properties or their equivalent GDI methods.
>
>Mike
>
>Option Explicit
>Private Declare Function SetWindowOrgEx Lib "gdi32" _
> (ByVal hdc As Long, ByVal nX As Long, ByVal nY As Long, _
> lpPoint As POINTAPI) As Long
>Private Declare Function Polygon Lib "gdi32" _
> (ByVal hdc As Long, lpPoint As POINTAPI, _
> ByVal nCount As Long) As Long
>Private Type POINTAPI
> x As Long
> y As Long
>End Type
>Private DownData(1 To 7) As POINTAPI
>
>Private Sub Form_Load()
> DownData(1).x = 0: DownData(1).y = 0 ' the arrow point
> DownData(2).x = -8: DownData(2).y = -17
> DownData(3).x = -3: DownData(3).y = -17
> DownData(4).x = -3: DownData(4).y = -48
> DownData(5).x = 3: DownData(5).y = -48
> DownData(6).x = 3: DownData(6).y = -17
> DownData(7).x = 8: DownData(7).y = -17
>End Sub
>
>Private Sub DrawDownArrow(pic As PictureBox, x As Single, y As Single)
> Dim p1 As POINTAPI, x1 As Long, y1 As Long
> x1 = pic.ScaleX(x - pic.ScaleLeft, pic.ScaleMode, vbPixels)
> y1 = pic.ScaleY(y - pic.ScaleTop, pic.ScaleMode, vbPixels)
> SetWindowOrgEx pic.hdc, -x1, -y1, p1 ' set origin
> Polygon pic.hdc, DownData(1), 7
> SetWindowOrgEx pic.hdc, p1.x, p1.y, p1 ' restore original origin
>End Sub
>
>Private Sub Command1_Click()
>Picture1.ScaleWidth = 1000
>Picture1.ScaleHeight = 1000
>' draw a "down arrow" with its point at the centre
>DrawDownArrow Picture1, 500, 500
>End Sub


Thanks Mike.

I ran this. Now to study it a bit to change the size and the color of
both the outline and fill (don't want it to be the forecolor of the
picbox). I believe that from studying this I can adapt the concept
into my app, where I wish to plot a filled in red or blue arrow (red
down, blue up) by specifying where the 'point' needs to be. That would
fulfill my needs.

Appreciate it again, Graphics Guru Master. :-)

Webbiz
From: Webbiz on
On Tue, 2 Mar 2010 08:26:14 -0500, "Nobody" <nobody(a)nobody.com> wrote:

>"Webbiz" <nospam(a)noway.com> wrote in message
>news:i2epo5lqmsbcf1e9smt060n61fvlg770jk(a)4ax.com...
>>I use a picturebox to draw lines and such within.
>>
>> I would like to plot some arrows on this picturebox.
>>
>> Two kinds. A small blue UP arrow, and a small red DOWN arrow, at
>> various spots on this picturebox.
>>
>> What is the best way to do this?
>>
>> Should I create my two arrow pictures and save as a bitmap or
>> something, then have them appear on the picturebox where I want them?
>>
>> Should I use drawing commands to draw point-to-point lines and fill?
>>
>> My picturebox is redrawn each time I scroll the items drawn within. So
>> the arrows will also have to follow along. Which approach would be
>> best for such an application?
>
>Some code template like Ivar suggested(The Enum helps providing Intelisis):
>
>Public Enum enumShapes
> eShapeUpArrow
> eShapeDownArrow
> eShapeCircle
>End Enum
>
>Public Sub DrawShape(ByVal Shape As enumShapes, ByVal hDC As Long, ByVal x
>As Single, ByVal y As Single, ByVal r As Single, ByVal Color As Long)
> Select Case Shape
> Case eShapeUpArrow:
> Case eShapeDownArrow:
> Case eShapeCircle:
> End Select
>End Sub
>
>


Yes. Once I learn how to actually draw the UP or DN arrow, I'll put it
into a Sub so that I can quickly draw a few of these on my picturebox
initially, and each time it is scrolled (erase and redraw arrows in
new location).

Thanks.

Webbiz
From: Mike Williams on
"Webbiz" <nospam(a)noway.com> wrote in message
news:jetqo55rd0dnip483ealsevj70o2etenom(a)4ax.com...

> I ran this. Now to study it a bit to change the size and the
> color of both the outline and fill (don't want it to be the
> forecolor of the picbox).

When you draw your arrow(s) you can set the desired line and fill colour
just before you draw them and reset them back to their original values
afterwards. These functions are reasonably fast, especially if you use the
GDI functions rather than the equivalent PictureBoxProperties, so you can do
it each time in the DrawDownArrow function itself if you wish. You can save
a tiny bit of resources (an insignificantly small amount really) by using
what are called "stock items" for these, but you are better off creating
them in code because you will then be able to set the colour / pattern etc
to whatever you wish. You could probably amend the existing DrawDownArrow
routine so that you can pass it the desired line and fill colour each time
you call it, but since you are using the same colours each time and since
you are using only a couple of colours (pens for the outline and and brushes
for the fill) then you might as well create them just once in the main Form
load event and hang onto them throughout the life of your program, rather
than creating them anew each time. Here's the same simplified example that I
posted previously, which I've amended to include the setting of the pen and
fill colour in the DrawDownArrow routine itself. The routine sets the
colours to your desired arrow colours (I've just guess your exact colour
requiremnents for the example) and it draws the arrow with its point at the
specified position and then sets the colours back to their pre-existing
values. Regarding the different arrow sizes, much depends on exactly what
you want and how many different sizes you require. It is actually possible
to set up the DC so that exactly the same set of Polygon data draws
differently sized polygons, but it is a bit of a messy thing to do in order
to get it right without affecting your other drawings so perhaps it might be
better to have more than one set of polgon data, or perhaps even to draw
your arrows using a different method altogether. Much depends on what sort
of range of sizes you require. Anyway, here's the existing code modified to
include the colour stuff.

Mike

Option Explicit
Private Declare Function SetWindowOrgEx Lib "gdi32" _
(ByVal hdc As Long, ByVal nX As Long, ByVal nY As Long, _
lpPoint As POINTAPI) As Long
Private Declare Function Polygon Lib "gdi32" _
(ByVal hdc As Long, lpPoint As POINTAPI, _
ByVal nCount As Long) As Long
Private Declare Function CreatePen Lib "gdi32" _
(ByVal nPenStyle As Long, ByVal nWidth As Long, _
ByVal crColor As Long) As Long
Private Declare Function CreateSolidBrush Lib "gdi32" _
(ByVal crColor As Long) As Long
Private Declare Function SelectObject Lib "gdi32" _
(ByVal hdc As Long, ByVal hObject As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" _
(ByVal hObject As Long) As Long
Private Const PS_SOLID = 0
Private Type POINTAPI
x As Long
y As Long
End Type
Private DownData(1 To 7) As POINTAPI
Private pen1 As Long
Private Brush1 As Long

Private Sub Form_Load()
DownData(1).x = 0: DownData(1).y = 0 ' the arrow point
DownData(2).x = -8: DownData(2).y = -17
DownData(3).x = -3: DownData(3).y = -17
DownData(4).x = -3: DownData(4).y = -48
DownData(5).x = 3: DownData(5).y = -48
DownData(6).x = 3: DownData(6).y = -17
DownData(7).x = 8: DownData(7).y = -17
pen1 = CreatePen(PS_SOLID, 1, RGB(160, 0, 0))
Brush1 = CreateSolidBrush(RGB(250, 80, 80))
End Sub

Private Sub Form_Unload(Cancel As Integer)
DeleteObject pen1
DeleteObject Brush1
End Sub

Private Sub DrawDownArrow(pic As PictureBox, x As Single, y As Single)
Dim p1 As POINTAPI, x1 As Long, y1 As Long
Dim oldPen As Long, oldBrush As Long
x1 = pic.ScaleX(x - pic.ScaleLeft, pic.ScaleMode, vbPixels)
y1 = pic.ScaleY(y - pic.ScaleTop, pic.ScaleMode, vbPixels)
SetWindowOrgEx pic.hdc, -x1, -y1, p1 ' set origin
oldPen = SelectObject(pic.hdc, pen1)
oldBrush = SelectObject(pic.hdc, Brush1)
Polygon pic.hdc, DownData(1), 7
SetWindowOrgEx pic.hdc, p1.x, p1.y, p1 ' restore original origin
SelectObject pic.hdc, oldPen
SelectObject pic.hdc, oldBrush
End Sub

Private Sub Command1_Click()
Picture1.ScaleWidth = 1000
Picture1.ScaleHeight = 1000
' draw a "down arrow" with its point at the centre
DrawDownArrow Picture1, 500, 500
End Sub




From: Webbiz on
On Tue, 2 Mar 2010 21:54:07 -0000, "Mike Williams"
<Mike(a)WhiskyAndCoke.com> wrote:

>"Webbiz" <nospam(a)noway.com> wrote in message
>news:jetqo55rd0dnip483ealsevj70o2etenom(a)4ax.com...
>
>> I ran this. Now to study it a bit to change the size and the
>> color of both the outline and fill (don't want it to be the
>> forecolor of the picbox).
>
>When you draw your arrow(s) you can set the desired line and fill colour
>just before you draw them and reset them back to their original values
>afterwards. These functions are reasonably fast, especially if you use the
>GDI functions rather than the equivalent PictureBoxProperties, so you can do
>it each time in the DrawDownArrow function itself if you wish. You can save
>a tiny bit of resources (an insignificantly small amount really) by using
>what are called "stock items" for these, but you are better off creating
>them in code because you will then be able to set the colour / pattern etc
>to whatever you wish. You could probably amend the existing DrawDownArrow
>routine so that you can pass it the desired line and fill colour each time
>you call it, but since you are using the same colours each time and since
>you are using only a couple of colours (pens for the outline and and brushes
>for the fill) then you might as well create them just once in the main Form
>load event and hang onto them throughout the life of your program, rather
>than creating them anew each time. Here's the same simplified example that I
>posted previously, which I've amended to include the setting of the pen and
>fill colour in the DrawDownArrow routine itself. The routine sets the
>colours to your desired arrow colours (I've just guess your exact colour
>requiremnents for the example) and it draws the arrow with its point at the
>specified position and then sets the colours back to their pre-existing
>values. Regarding the different arrow sizes, much depends on exactly what
>you want and how many different sizes you require. It is actually possible
>to set up the DC so that exactly the same set of Polygon data draws
>differently sized polygons, but it is a bit of a messy thing to do in order
>to get it right without affecting your other drawings so perhaps it might be
>better to have more than one set of polgon data, or perhaps even to draw
>your arrows using a different method altogether. Much depends on what sort
>of range of sizes you require. Anyway, here's the existing code modified to
>include the colour stuff.
>
>Mike
>
>Option Explicit
>Private Declare Function SetWindowOrgEx Lib "gdi32" _
> (ByVal hdc As Long, ByVal nX As Long, ByVal nY As Long, _
> lpPoint As POINTAPI) As Long
>Private Declare Function Polygon Lib "gdi32" _
> (ByVal hdc As Long, lpPoint As POINTAPI, _
> ByVal nCount As Long) As Long
>Private Declare Function CreatePen Lib "gdi32" _
> (ByVal nPenStyle As Long, ByVal nWidth As Long, _
> ByVal crColor As Long) As Long
>Private Declare Function CreateSolidBrush Lib "gdi32" _
> (ByVal crColor As Long) As Long
>Private Declare Function SelectObject Lib "gdi32" _
> (ByVal hdc As Long, ByVal hObject As Long) As Long
>Private Declare Function DeleteObject Lib "gdi32" _
> (ByVal hObject As Long) As Long
>Private Const PS_SOLID = 0
>Private Type POINTAPI
> x As Long
> y As Long
>End Type
>Private DownData(1 To 7) As POINTAPI
>Private pen1 As Long
>Private Brush1 As Long
>
>Private Sub Form_Load()
> DownData(1).x = 0: DownData(1).y = 0 ' the arrow point
> DownData(2).x = -8: DownData(2).y = -17
> DownData(3).x = -3: DownData(3).y = -17
> DownData(4).x = -3: DownData(4).y = -48
> DownData(5).x = 3: DownData(5).y = -48
> DownData(6).x = 3: DownData(6).y = -17
> DownData(7).x = 8: DownData(7).y = -17
> pen1 = CreatePen(PS_SOLID, 1, RGB(160, 0, 0))
> Brush1 = CreateSolidBrush(RGB(250, 80, 80))
>End Sub
>
>Private Sub Form_Unload(Cancel As Integer)
> DeleteObject pen1
> DeleteObject Brush1
>End Sub
>
>Private Sub DrawDownArrow(pic As PictureBox, x As Single, y As Single)
> Dim p1 As POINTAPI, x1 As Long, y1 As Long
> Dim oldPen As Long, oldBrush As Long
> x1 = pic.ScaleX(x - pic.ScaleLeft, pic.ScaleMode, vbPixels)
> y1 = pic.ScaleY(y - pic.ScaleTop, pic.ScaleMode, vbPixels)
> SetWindowOrgEx pic.hdc, -x1, -y1, p1 ' set origin
> oldPen = SelectObject(pic.hdc, pen1)
> oldBrush = SelectObject(pic.hdc, Brush1)
> Polygon pic.hdc, DownData(1), 7
> SetWindowOrgEx pic.hdc, p1.x, p1.y, p1 ' restore original origin
> SelectObject pic.hdc, oldPen
> SelectObject pic.hdc, oldBrush
>End Sub
>
>Private Sub Command1_Click()
> Picture1.ScaleWidth = 1000
> Picture1.ScaleHeight = 1000
> ' draw a "down arrow" with its point at the centre
> DrawDownArrow Picture1, 500, 500
>End Sub
>
>
>


I created a DrawUpArrow as well and redimensioned the size of the
arrows. Changed where they appear and tested, okay.

Looking over the functions, I got a bit confused with SetWindowOrgEx.
I know it's used to change the coordinates of 0,0 or something like
that, but it's the part of restoring that puzzled me.

Anyway, I've a copy of VB Programmer's Guide to the Win32 API and
decided to read all of chapter 7 and 8. Enlightening. Shortly I should
come to understand what all is going on here.

Thanks Mike.

Webbiz