Solved

Un-Drawing in VB

Posted on 2002-07-20
27
317 Views
Last Modified: 2010-08-05
I am using this subroutine to draw a red X over a picture box when a usere clicks on it.
__________________________________________________________
Private Sub Picture1_Click()
   Me.AutoRedraw = True
   Picture1.AutoRedraw = True
   
   Picture1.Line (0, 0)-(Picture1.ScaleWidth, Picture1.ScaleHeight), vbRed
   Picture1.Line (Picture1.ScaleWidth, 0)-(0, Picture1.ScaleHeight), vbRed

End Sub
__________________________________________________________
I need to have the red X go away after the user has clicked on it a second time. Is there any way to Undraw the lines?
Thank you,
Arrummzen
0
Comment
Question by:Arrummzen
  • 11
  • 8
  • 5
  • +3
27 Comments
 
LVL 17

Expert Comment

by:inthedark
ID: 7167268
The easy way to do this is use 2 line controls. You can show/hide then as you wish.

line1.x1=2
line1.y1=2
line1.x2=100
line1.y2=100

etc.
0
 
LVL 1

Expert Comment

by:Benjy
ID: 7167271
or set autoredraw to false before you draw the lines and when you want them to go away set picture1.picture = picture1.image
0
 
LVL 3

Expert Comment

by:leojl
ID: 7167283
hi arrummzen,
The standard way to undraw a line is to draw a line over it with the background color. Since your red X is over a picture that would not work. You could just reload the original picture without the X, but that is not an answer to your question. If you want to draw the line with pixels then you can capture each pixel from the picture befor you draw the red pixel. save the picture pixels in an array and then redraw the line with the picture pixels. I think that is the standard way to undraw something you have drawn over a picture...if you wish I can get you the code to capture picture pixels and then redraw them.
leo
0
 
LVL 1

Author Comment

by:Arrummzen
ID: 7167336
Ok let me explain some more. I have a form with one large picture with 32 trees on it. There are 16 on the top and 16 on the bottom. Now I am going to put an empty image box over each tree. When one of these invisible image boxes are clicked on I need a red x to appear in the box.
----------------------------------------------------------
Private Sub Picture1_Click()
   Picture1.AutoRedraw = true
      Picture1.Line (0, 0)-(Picture1.ScaleWidth, Picture1.ScaleHeight), vbRed
   Picture1.Line (Picture1.ScaleWidth, 0)-(0, Picture1.ScaleHeight), vbRed
End Sub
----------------------------------------------------------
The above code draws a line when the image box is clicked. I cant set atoredraw to false because if I do an the user goes to another window for a few seconds the x will go away. I can’t put another line across the old one because then the large picture box in the background will look bad. I don’t want to use line objects because then I have to specify the X and Y locations because I want to be able to resize the image boxes for use on other pages.
This might be hard to do. I will increase the points by 50 to 150.
Thank you for your time,
Arrummzen
0
 
LVL 17

Expert Comment

by:inthedark
ID: 7167377
Try this, it will still work however picture1 has been resized:


Form_Load()
    HideShowLines False
End Sub

Private Sub Picture1_Click()
   
    Set Line1.Container = Picture1
    Set Line2.Container = Picture1
   
    ' Do the dropping line
    Line1.X1 = 0
    Line1.X2 = Picture1.ScaleWidth
    Line1.Y1 = 0
    Line1.Y2 = Picture1.ScaleHeight
   
    ' Now the rising line
    Line2.X1 = Picture1.ScaleWidth
    Line2.X2 = 0
    Line2.Y1 = 0
    Line2.Y2 = Picture1.ScaleHeight
   
    HideShowLines True

End Sub
Sub HideShowLines(SetVisible as Boolean)
    Line1.Visible = SetVisible
    Line2.Visible = SetVisible
End Sub
0
 
LVL 17

Expert Comment

by:inthedark
ID: 7167380
I expect you are using an array of picture boxes:

Private Sub Picture1_Click(Index As Integer)
   
    ' these 2 lines next are the giant leap forward:
    Set Line1.Container = Picture1(Index)
    Set Line2.Container = Picture1(Index)
   
    ' Do the dropping line
    Line1.X1 = 0
    Line1.X2 = Picture1(Index).ScaleWidth
    Line1.Y1 = 0
    Line1.Y2 = Picture1(Index).ScaleHeight
   
    ' Now the rising line
    Line2.X1 = Picture1(Index).ScaleWidth
    Line2.X2 = 0
    Line2.Y1 = 0
    Line2.Y2 = Picture1(Index).ScaleHeight
   
    HideShowLines True

End Sub
0
 
LVL 1

Author Comment

by:Arrummzen
ID: 7167392
Hmm. Your code looks like it should work but for some reason on I receive a Object required (Error 424) on line the following lines:
    Line1.Visible = SetVisible
    Line2.Visible = SetVisible
I have tried running the subroutine in a lone module and in the forms main code block. I don’t know what to do.
When I click on the picture box I get the following error Object required (Error 424). I don’t know. I think I am putting the code in rite. This error occurs on the line Set Line1.Container = Picture1(Index)
Tell me if you need any more information.
Thank you for your help,
Arrummzen
0
 
LVL 17

Expert Comment

by:inthedark
ID: 7167407
Find the toolbox and you will see the line control.

Draw two of them on your form.

I suspect that this could be the problem.
0
 
LVL 17

Expert Comment

by:inthedark
ID: 7167409
Line controls are strange as they don't have any events.

After you have placed the line controls on the form change the properties so that color and size are set as desired.
0
 
LVL 1

Author Comment

by:Arrummzen
ID: 7167419
Ok. Now there is another problem. I want to click on one picture box and have it draw a x over the picture box and when I click on it again for the x to go away however rite now if I click on a picture box a x appears and when I click on it again nothing happens and then when I click on a different picture box the x moves to the other box. I think I can get this to work with individual boxes however I will give you a extra 10 points if you give me source code to get it to work as I explained above with a control array.
Thank you for your time,
Arrummzen
0
 
LVL 17

Expert Comment

by:inthedark
ID: 7167528
So you have to detect if the X is already on a picture.

I think I understand that you want to toggle the X on/off. Click once to turn on. Click again to remove.

You can use and indicator array or the Tag property.

In your form load you need to set:

LastIndex = -1

Private Sub Picture1_Click(Index As Integer)
   
' is the x on show on a different picture
If LastIndex >= 0 And LastIndex <> Index Then
   Picture1(LastIndex).Tag = ""
End If
If Len(Picture1(Index).Tag) = 0 Then
        Picture1(Index).Tag = "X" ' set the x on show indicator

        ' these 2 lines next are the giant leap forward:
        Set Line1.Container = Picture1(Index)
        Set Line2.Container = Picture1(Index)
       
        ' Do the dropping line
        Line1.X1 = 0
        Line1.X2 = Picture1(Index).ScaleWidth
        Line1.Y1 = 0
        Line1.Y2 = Picture1(Index).ScaleHeight
       
        ' Now the rising line
        Line2.X1 = Picture1(Index).ScaleWidth
        Line2.X2 = 0
        Line2.Y1 = 0
        Line2.Y2 = Picture1(Index).ScaleHeight
       
        HideShowLines True ' show X
Else
        Picture1(Index).Tag = "" ' clear then x on show indicator
        HideShowLines True ' hide X
End If

LastIndex = Index

End Sub


0
 
LVL 17

Expert Comment

by:inthedark
ID: 7167531
Sorry at the end:
HideShowLines False ' hide X
0
 
LVL 6

Expert Comment

by:pierrecampe
ID: 7167876
Private Sub Picture1_Click(Index As Integer)
    Dim CrossIsThere As Boolean
    Dim BakColor As Long
    Dim CrossColor As Long
    Dim TheColor As Long
    BakColor = Picture1(Index).Point(2 * Screen.TwipsPerPixelX, 0)
    CrossColor = vbRed
    CrossIsThere = Picture1(Index).Point(0, 0) = CrossColor
    If CrossIsThere Then
       TheColor = BakColor
    Else
       TheColor = CrossColor
    End If
    Picture1(Index).Line (0, 0)-(Picture1(Index).ScaleWidth, Picture1(Index).ScaleHeight), TheColor
    Picture1(Index).Line (0, Picture1(Index).ScaleHeight)-(Picture1(Index).ScaleWidth, 0), TheColor
End Sub

0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 6

Expert Comment

by:pierrecampe
ID: 7167883
or you could just save the crossed/not crossed state in the picture's tag property
that way you wont even have to test if point(0,0) is red
0
 
LVL 6

Expert Comment

by:pierrecampe
ID: 7167886
and now that i think of it, you probably even know the background color of the picturebox,so you dont even have to look for it
0
 
LVL 6

Expert Comment

by:pierrecampe
ID: 7167904
Private Sub Picture1_Click(Index As Integer)
    Dim TheColor As Long
    If Picture1(Index).Tag = "Cross" Then
       TheColor = &H80000005 ' the color you gave at design-time
       Picture1(Index).Tag = "NoCross"
    Else
       TheColor = vbRed
       Picture1(Index).Tag = "Cross"
    End If
    Picture1(Index).Line (0, 0)-(Picture1(Index).ScaleWidth, Picture1(Index).ScaleHeight), TheColor
    Picture1(Index).Line (0, Picture1(Index).ScaleHeight)-(Picture1(Index).ScaleWidth, 0), TheColor
End Sub
0
 
LVL 6

Expert Comment

by:pierrecampe
ID: 7167969
easier still and works even when there is a background picture:
Private Sub Picture1_Click(Index As Integer)
    If Picture1(Index).Tag = "Cross" Then
       Picture1(Index).Tag = "NoCros"
       Picture1(Index).Cls
    Else
       Picture1(Index).Tag = "Cross"
       Picture1(Index).Line (0, 0)-(Picture1(Index).ScaleWidth, Picture1(Index).ScaleHeight), vbRed
       Picture1(Index).Line (0, Picture1(Index).ScaleHeight)-(Picture1(Index).ScaleWidth, 0), vbRed
    End If
End Sub
0
 
LVL 1

Author Comment

by:Arrummzen
ID: 7168190
Ok, I need the picture boxes to be invisible but when I set visible to false the Xs stop working. I have a background and I am using these little invisible picture/image boxes (which ever works) to draw a red x ware it is and to mark a global variable that the box was selected.
I have trees on the background. I want to click on a tree and have an X appear over the tree and the global variable marked. I want to be able to click on a tree with an X on it and have the global set to false and for the X to go away. I want have one background and I am thinking of putting an invisible image/picture box over each tree so that I can tell when each tree is clicked on. I know I am asking for a lot so I am increasing the points to 250.
0
 
LVL 17

Expert Comment

by:inthedark
ID: 7168208
When you make the picture box not visible it wont handle any events. So you need to place another, empty, picture box under the picture box that is not visible.

The empty boxes should be display ordered like:

picEmpty(Index).Zorder 1 ' this will force the box

Hope this helps.
0
 
LVL 17

Expert Comment

by:inthedark
ID: 7168210
Woops, clicked to early....

picEmpty(Index).Zorder 1 ' this will force the box under the main box when it is visible.

Give picEmpty the same click event code and dimensions as picture1
0
 
LVL 6

Accepted Solution

by:
pierrecampe earned 250 total points
ID: 7168312
you did not have to up the points,upping the points will not make us reply better
what i think now is that nobody did understand what you wanted to do
as i understand it now you have 1 big picturebox with a picture in it
and you want to know when a user clicks on an element of that picture (in this case a tree,a plant)
so you want hotspots in your big picturebox
the easiest way to have hotspots is place transparent label controls over the elements you want as hotspots
so over every tree place a transparent label control
to make it easy make it an array of labels, the code:

Private Sub Label1_Click(Index As Integer)
    If Label1(Index).Tag = "Cross" Then
       Label1(Index).Tag = "NoCross"
       Picture1.PaintPicture Picture1.Image, Label1(Index).Left, Label1(Index).Top, Label1(Index).Width, Label1(Index).Height, Label1(Index).Left, Label1(Index).Top, Label1(Index).Width, Label1(Index).Height
    Else
       Label1(Index).Tag = "Cross"
       Picture1.Line (Label1(Index).Left, Label1(Index).Top)-(Label1(Index).Left + Label1(Index).Width, Label1(Index).Top + Label1(Index).Height)
       Picture1.Line (Label1(Index).Left, Label1(Index).Top + Label1(Index).Height)-(Label1(Index).Left + Label1(Index).Width, Label1(Index).Top)
    End If
End Sub

0
 
LVL 6

Expert Comment

by:pierrecampe
ID: 7168315
oh yes place the labels ON the picturebox, do NOT place them on the form and then move them over the picturebox
0
 
LVL 17

Expert Comment

by:inthedark
ID: 7168344
That's a good point pierrecampe, label boxes could be usefull in the case of one picture with hot spots.

If you wish to use line controls, place them on your picture.

Here are some other tips:

At design time give the labels a border and send all label elements in form load like:

Sub Form_load()
  dim c as long
  For C=0 to MaxLabelElements
      Label1(c).BorderStyle = 0
  next c
End Sub


Private Sub Label1_Click(Index As Integer)
 

If Len(Label1(Index).Tag) = 0 Then
       Label1(Index).Tag = "X" ' set the x on show indicator
       
       ' Do the dropping line
       Line1.X1 = Label1(Index).Left
       Line1.X2 = Label1(Index).Left + Label1(Index).Width
       Line1.Y1 = Label1(Index).Top
       Line1.Y2 = Label1(Index).Top + Label1(Index).Height
       
       ' Now the rising line
       Line2.X1 = Label1(Index).Left + Label1(Index).Width
       Line2.X2 = Label1(Index).Left
       Line2.Y1 = Label1(Index).Top
       Line2.Y2 = Label1(Index).Top + Label1(Index).Height
       
       HideShowLines True ' show X
Else
       Label1(Index).Tag = "" ' clear then x on show indicator
       HideShowLines False ' hide X
End If

End Sub
0
 
LVL 6

Expert Comment

by:pierrecampe
ID: 7168376
yes i think the method with line controls is probably better, because the paintpicture method is dependant of the kind of picture thats in the picturebox and of the autoredraw property
if autoredraw is true picture1.image will not work you will have to use picture1.picture
picture1.image will work independant of what kind of picture (bitmap,metafile etc...)but only if autoredraw is false
picture1.picture will probably not work with metafiles
for picture1.picture to work, the visual picture in the picturebox has to have exactly the same dimensions as the real picture,what is seldom the case with metafiles
if using the line control system i would suggest making them array's to, also i suggest not using global variables,you can always check if a tree is crossed by looping trouch their tag property's
0
 
LVL 17

Expert Comment

by:inthedark
ID: 7168388
Yes and, if you need to have more then one item X'ed at the same time you will have to use an array of line controls. Like: line1(Index) and Line2(Index)....
0
 
LVL 27

Expert Comment

by:Ark
ID: 7168545
Hi
Dim pic As StdPicture
'........
'Before drawing cross:
Set pic = Picture1.Picture
'Draw cross

'To restore:
Picture1.Picture = pic
Picture1.refresh

Cheers
0
 
LVL 1

Author Comment

by:Arrummzen
ID: 7168688
Thank you very much every one for your help. By the way I know it was because I didn’t explain my question well. I don’t know if points mean anything to any of you. I just wanted to try to make up for my bad explanation. Anyhow thanks a lot.
Thank you for your time,
Arrummzen
0

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

Introduction I needed to skip over some file processing within a For...Next loop in some old production code and wished that VB (classic) had a statement that would drop down to the end of the current iteration, bypassing the statements that were c…
The debugging module of the VB 6 IDE can be accessed by way of the Debug menu item. That menu item can normally be found in the IDE's main menu line as shown in this picture.   There is also a companion Debug Toolbar that looks like the followin…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

8 Experts available now in Live!

Get 1:1 Help Now