PDA

View Full Version : Problem with Mouse Down Event



rss
11-15-2006, 07:22 PM
Hi,

I have the following code which almost does what I want:

Private Sub Image1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, _
ByVal X As Single, ByVal Y As Single)

Range("a2").Value = Button
Range("b2").Value = Shift
Range("c2").Value = X
Range("d2").Value = Y

Image1.picture = LoadPicture("C:\Documents and Settings\My Documents\My Pictures\smiley.bmp")


If Range("c2").Value < 20 Then Image1.picture = LoadPicture("")

End Sub

The problem is that I have to move the mouse pointer off the bmp image for the LoadPicture to work. I would like to see the loadpicture work just after clicking on the image. Thanks for your help.

malik641
11-15-2006, 10:18 PM
Hi rss, welcome to VBAX :hi:

Could you please provide a workbook to help us understand better what's happening?

Just by looking at your code, I would say you should store those values in public variables in the MouseDown event and verify them in the MouseUp event so it seems like the image would load just after they let go of the mouse click.

geekgirlau
11-16-2006, 01:25 AM
Welcome to the board!

I've taken the liberty of modifying the title of your thread. You'll find that you are much more likely to get responses if the title explicitly tells people what the issue is about, rather than a generic "help" description.

rss
11-19-2006, 08:56 AM
Hi rss, welcome to VBAX :hi:

Could you please provide a workbook to help us understand better what's happening?

Just by looking at your code, I would say you should store those values in public variables in the MouseDown event and verify them in the MouseUp event so it seems like the image would load just after they let go of the mouse click.

Thanks for your response. Couple of questions: 1) How do i provide you with a workbook 2) not sure what you mean by store values in public variables - I did see a way to create a public versus private functions but then you have to use a module as oppose to just placing the code in a worksheet. and finally 3) if I also us the mouse up event do I place that inside the mouse down event or just have it listed as a subroutine, when the event occurs will the subroutine automatically get executed?

I am going to try to attach the workbook to this post

malik641
11-19-2006, 10:24 AM
Hi rss,

To answer your questions...

1.) I see you figured that out already.

2.) I thought you were attempting to do something else...so I don't believe you need public variables for this. And what I did mean was to declare your variables above all procedures in the Sheet1 module. Whether you use Dim or Public, it's only public to the Sheet1 module for all procedures within the Sheet1 module. Public variables that are public to the entire project (i.e. all modules in your workbook) must be declared public outside of any procedure in a standard module.


3.) No, you can't place a procedure inside another procedure (event or not). But you can call procedures from within a procedure. Like say you had one procedure to load or unload the image called PictureLoad and parameters must be passed to it, you could use it in the following manner:

Private Sub Image1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, _
ByVal X As Single, ByVal Y As Single)
Call PictureLoad(AnyParametersYouMayHave)
End Sub



But for this situation...I think what you want to do is the following:
Private Sub Image1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, _
ByVal X As Single, ByVal Y As Single)

Range("a2").Value = Button
Range("b2").Value = Shift
Range("c2").Value = X
Range("d2").Value = Y

If Range("c2").Value < 20 Then
Image1.picture = LoadPicture("")
Else
Image1.picture = LoadPicture("C:\Documents and Settings\Joe\My Documents\Picture\Car Pics\Dodge Viper GTS-R.jpg")
End If

Range("a20").Value = X
End Sub
But then again, I'm still not entirely sure what it is you want to accomplish :dunno Could you give us some more details?

rss
11-19-2006, 01:32 PM
Hi rss,

To answer your questions...

1.) I see you figured that out already.

2.) I thought you were attempting to do something else...so I don't believe you need public variables for this. And what I did mean was to declare your variables above all procedures in the Sheet1 module. Whether you use Dim or Public, it's only public to the Sheet1 module for all procedures within the Sheet1 module. Public variables that are public to the entire project (i.e. all modules in your workbook) must be declared public outside of any procedure in a standard module.


3.) No, you can't place a procedure inside another procedure (event or not). But you can call procedures from within a procedure. Like say you had one procedure to load or unload the image called PictureLoad and parameters must be passed to it, you could use it in the following manner:

Private Sub Image1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, _
ByVal X As Single, ByVal Y As Single)
Call PictureLoad(AnyParametersYouMayHave)
End Sub


But for this situation...I think what you want to do is the following:
Private Sub Image1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, _
ByVal X As Single, ByVal Y As Single)

Range("a2").Value = Button
Range("b2").Value = Shift
Range("c2").Value = X
Range("d2").Value = Y

If Range("c2").Value < 20 Then
Image1.picture = LoadPicture("")
Else
Image1.picture = LoadPicture("C:\Documents and Settings\Joe\My Documents\Picture\Car Pics\Dodge Viper GTS-R.jpg")
End If

Range("a20").Value = X
End Sub But then again, I'm still not entirely sure what it is you want to accomplish :dunno Could you give us some more details?



Thanks a lot for trying to make this work. I tried your code and it does the same thing as my current code. Go ahead and try it out on your computer. When you click on the image you have to move the pointer off the image for the mouse down load to take effect. I wanted to be able to get the image to load and unload without having to move the pointer. So, if the image was loaded and you clicked on the left hand side of the image it would disapear and if you clicked in the middle of the image or (null image) if would load. Let me know if that explains the problem. Maybe a mouse up routine on the same image will do the trick

rss
11-19-2006, 01:41 PM
The problem is the pictureload command doesn't work went you click down or release up the mouse button. Those events have to ake place but in addition you have to move the mouse pointer off the image. Is there anyway you can force the pictureload command to load without having to move the pointer?

malik641
11-19-2006, 02:07 PM
Ok. I see what's going on. For me, the image will load instantly when it is not loaded (i.e. null image is loaded) but for the null image to load, I have to move the mouse pointer off the image...strange.

...After some more testing the opposite happens (which is what was happening to you).


...Let me see what I can figure out.

malik641
11-19-2006, 03:56 PM
Ok. After some long testing I've noticed that once you click the image, the MouseMove event hurls itself in an infinite loop, even if you are not moving the mouse.

Now while this infinite loop goes on, you can still activate the Click, MouseDown and MouseUp events, but once those are done, the MouseMove event just loops itself over and over.

I'm not sure if that's where the problem lies...but I'm not sure if it isn't.

But what's really weird is that even with the following code being executed...the MouseMove event is STILL triggered!!!

sheet1.Image1.Enabled = False
sheet1.Image1.Locked = True
Application.EnableEvents = False

And this is straight from the help files:


ENABLED PROPERTY:
Use the Enabled property to enable and disable controls. A disabled control appears dimmed, while an enabled control does not. Also, if a control displays a bitmap, the bitmap is dimmed whenever the control is dimmed. If Enabled is False for an Image, the control does not initiate events but does not appear dimmed.

:dunno

rss
11-19-2006, 07:52 PM
Ok. After some long testing I've noticed that once you click the image, the MouseMove event hurls itself in an infinite loop, even if you are not moving the mouse.

Now while this infinite loop goes on, you can still activate the Click, MouseDown and MouseUp events, but once those are done, the MouseMove event just loops itself over and over.

I'm not sure if that's where the problem lies...but I'm not sure if it isn't.

But what's really weird is that even with the following code being executed...the MouseMove event is STILL triggered!!!

sheet1.Image1.Enabled = False
sheet1.Image1.Locked = True
Application.EnableEvents = False
And this is straight from the help files:



:dunno
I really appreciate your help. Maybe we should start at the beginning. If you had a picture that you wanted to be able to click on different parts of it and load a different picture depending on where you clicked how would you set it up? If I'm in an infinite loop, it seems to do something when I move the cursor off the picture and then back onto to it. I tried to move the cursor but the stuff I did didn't work properly:

I created a module and inserted:

Declare Function SetCursorPos Lib "user32" (ByVal x1 As Long, _
ByVal y1 As Long) As Long

and then I called the function. I was able to move the cursor off the picture but I can't get it to come back onto the picture. Seems the coordinates are different depending on the size of the excel sheet. When I do get it off and on it(the cursor) doesn't load the picture.

rss
11-19-2006, 07:53 PM
How are you able to determine that it's in an infinite loop? what happens to the loop when you mover the cursor off the page? Is there another way to stop the loop?

rss
11-19-2006, 07:58 PM
How are you able to determine that it's in an infinite loop? what happens to the loop when you mover the cursor off the page? Is there another way to stop the loop?Oh, and you said it was the mousemove that was in an infinite loop but I don't have a mousemove in my code just a mousedown. What's up with that?

malik641
11-19-2006, 10:00 PM
What I did was I put all the events in the module, and placed Debug.Print "This Event" in each of them...so I can watch what occured while I was on the sheet. I noticed that once I click the image (whether in the correct spot to turn it on/off) I didn't move the mouse anymore. So when I returned to the VBE (by Alt+Tab), I noticed that after I clicked the image, that it repeatedly went through the MouseMove event, but if I clicked again and again without moving the mouse, I saw that it was noted in the immediate window...so I can activate the other events....but the MouseMove event just kept on looping itself. The weirdest part was that I locked the image and I disabled it (Image1.Enabled = False) and it still showed the MouseMove event happening...but it wouldn't loop then because I had disabled every other event (by the way, Appication.EnableEvents = False has no effects on OLE embedded objects ...meaning Image1).

Here's the file, of course you'll have to change the LoadPicture file location.

And for your API call, I would call it by giving it the X and Y variables from the MouseDown event and adding the picture width to X and picture hieight to Y, then immediately calling it back with the X and Y that was originally taken from the MouseDown event.


Oh yeah, and even though you don't have the MouseDown event in your code, the event will happen regardless...I just put it there to see the order of events...and I was kinda hoping I could do something with it, but I don't see anything useful.

malik641
11-19-2006, 10:06 PM
When I do get it off and on it(the cursor) doesn't load the picture.Didn't notice this at first...disregard what I said about the API call then...

And no problem, I enjoy a good challenge...no matter how frustrating :thumb (except for this ridiculous FireFox 2 :motz2:)

Jan Karel Pieterse
11-20-2006, 03:34 AM
To prevent event looping, check out this page:

http://www.jkp-ads.com/Articles/NoEvents00.htm

rss
11-22-2006, 04:39 PM
To prevent event looping, check out this page:

http://www.jkp-ads.com/Articles/NoEvents00.htm


Jan,

Thanks for the reference but that's way out of my league for now. What's weird is that when I push down the mouse button commands are executed but the actual picture will not load until I move the cursor off the image and then back onto it. There must be a way to stop this from happening, or in other words get the image to load on the mouse down event without having to move the cursor back and forth. Can you help?

Jan Karel Pieterse
11-22-2006, 10:44 PM
Thanks for the reference but that's way out of my league for now. What's weird is that when I push down the mouse button commands are executed but the actual picture will not load until I move the cursor off the image and then back onto it. There must be a way to stop this from happening, or in other words get the image to load on the mouse down event without having to move the cursor back and forth. Can you help?

Out of your league or not, it is the way to go to prevent that mousemove event from looping. Have you tried including a me.repaint command after the new pic has been loaded?

rss
11-23-2006, 08:34 AM
Out of your league or not, it is the way to go to prevent that mousemove event from looping. Have you tried including a me.repaint command after the new pic has been loaded?
Hi Jan,

I looked up repaint and got the following:

boolean=object.repaint

I tried inserting true=image1.repaint but that didn't work. I'm still looking for an example of how to use the command.

Here's a copy of the current code:

Private Sub Image1_GotFocus()

End Sub

Private Sub Image1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, _
ByVal x As Single, ByVal y As Single)


Range("a2").Value = Button
Range("b2").Value = Shift
Range("c2").Value = x
Range("d2").Value = y

x1 = 0
y1 = 0


If Range("c2").Value < 20 Then
Image1.Picture = LoadPicture("")

Else
Image1.Picture = LoadPicture("C:\Documents and Settings\Bob Slotpole\My Documents\My Pictures\smiley.bmp")


End If


End Sub

Jan Karel Pieterse
11-23-2006, 11:40 AM
It is a method of the userform itself:

Me.Repaint

rss
11-23-2006, 03:44 PM
It is a method of the userform itself:

Me.Repaint

Thanks Jan, all of that means absolutely nothing. As you can see from the code there's no reference of a "userform".

While I've read about 100 pages of VBA Excel, I still have about 300 more pages to go. I've done a pretty exhaustive search on this site to try to get the program to work without any luck.

Could you possibly be a little more descriptive? I'm able to get the picture to load but the mouse cursor has to be moved off and then back onto the actual picture. It's interesting because other things will continue to be processed by the VBA code when the mouse button is just pushed down without the cursor being moved. I suspect it has something to do with the basic structure of my program. It works, but there's an error in it so it doesn't work correctly although there's no error message. Come on, do you really expect a newbe to figure this out?

I'm certainly not against trying something on my own, just at this stage I have not a clue as to what could be wrong as I don't get any kind of error message and knowone has suggested there was in fact anything wrong with the code.

Thanks again for your help. Happy Thanksgiving.

malik641
11-23-2006, 07:15 PM
To prevent event looping, check out this page:

http://www.jkp-ads.com/Articles/NoEvents00.htm

I'm not sure this is what we want for what we're trying to accomplish. There's no code in the MouseMove event besides Debug.Print "mousemove" just to see the order of events. If I add:
If ThisWorkbook.NoMouseMoveEvent = False Then Exit Sub
All it's going to do is repeatedly 'exit sub', the same thing as if I had no code in it at all. I don't even want it to execute.


This thing has me stumped. :think:

Ivan F Moala
11-23-2006, 10:31 PM
rss

Because the control is on your sheet you need to initiate some sort of refresh.

Try this work around



Private Sub Image1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, _
ByVal X As Single, ByVal Y As Single)

Range("a2").Value = Button
Range("b2").Value = Shift
Range("c2").Value = X
Range("d2").Value = Y

With Image1
.picture = LoadPicture("C:\Documents and Settings\Bob Slotpole\My Documents\My Pictures\smiley.bmp")
.Visible = False

If Range("c2").Value < 20 Then .picture = LoadPicture("")
Range("a20").Value = X

.Visible = True
End With

End Sub

rbrhodes
11-23-2006, 11:13 PM
rss,


this worked for me:



Private Sub Image1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, _
ByVal X As Single, ByVal Y As Single)


'Added by dr
Application.ScreenUpdating = False



Range("a2").Value = Button
Range("b2").Value = Shift
Range("c2").Value = X
Range("d2").Value = Y


Image1.picture = LoadPicture("C:\Documents and Settings\My Documents\My Pictures\smiley.bmp")



If Range("c2").Value < 20 Then Image1.picture = LoadPicture("")


'Added by dr
Application.ScreenUpdating = true


End Sub



Cheers,


dr

Andy Pope
11-24-2006, 02:54 AM
Could you use a label instead of an image control?
The label does not appear to suffer the same refresh problems.

rss
11-24-2006, 04:50 PM
rss

Because the control is on your sheet you need to initiate some sort of refresh.

Try this work around



Private Sub Image1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, _
ByVal X As Single, ByVal Y As Single)

Range("a2").Value = Button
Range("b2").Value = Shift
Range("c2").Value = X
Range("d2").Value = Y

With Image1
.picture = LoadPicture("C:\Documents and Settings\Bob Slotpole\My Documents\My Pictures\smiley.bmp")
.Visible = False

If Range("c2").Value < 20 Then .picture = LoadPicture("")
Range("a20").Value = X

.Visible = True
End With

End Sub



Hi,

Thanks for the above solution. I tried the following:

If Range("c2").Value < 20 Then
Image1.Picture = LoadPicture("")
Image1.Visible = False
Else
Image1.Picture = LoadPicture("C:\Documents and Settings\My Documents\My Pictures\smiley.bmp")
Image1.Visible = True
End If

and the picture just disappears as visible get sets to false. How come it works with the "with" statement and not without it? It seems odd that you make the condition false after you load the picture? How come it doesn't disaapear? Trying to understand why it works, thanks.

malik641
11-24-2006, 07:57 PM
Thanks Ivan and rbrhodes for the help :thumb


Hey rss, why don't you use exactly Ivan's code? Isn't that exactly what you needed?

As for your code, it could work, just place the Image1.Visible = False before the if statement, and Image1.Visible = True before the end of the procedure.

rss
11-24-2006, 09:10 PM
Thanks Ivan and rbrhodes for the help :thumb


Hey rss, why don't you use exactly Ivan's code? Isn't that exactly what you needed?

As for your code, it could work, just place the Image1.Visible = False before the if statement, and Image1.Visible = True before the end of the procedure.
Thanks for the suggestion. I tried it and yes Ivan's code works fine. I'm just trying to understand what's going on so I don't make the same mistake. How come when I place the .visible lines before and after the if block it works but it doesn't work when they are loacted inside the if block? Also, it seems backwards that I'm setting the image to false first and then to true - what's up with that?


I'm not sure but looking at the code I think the false statement closes the image then the if block executes and the true statement redraws the image. It happens so fast that you don't see the image going blank. Is that correct?