Changing shape fill color on mouseover

ebeauchamp28

New Member
Joined
Feb 18, 2006
Messages
20
I have a rectangle shape (simple drawing in Excel) that is currently assigned to a macro. When you rest the cursor over, the cursor changes shape to a hand, indicating you can click and activate the macro. However, I would also like the fill color of this rectangle to change temporarily while the cursor is over it.

Any idea of the code required to do this? Would it be needed as a Private Sub?

Many thanks
Erik
 

Excel Facts

Highlight Duplicates
Home, Conditional Formatting, Highlight Cells, Duplicate records, OK to add pink formatting to any duplicates in selected range.
Private Sub CommandButton1_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)

'On mouse-over, color Button Green.
If CommandButton1.BackColor <> RGB(122, 255, 0) Then _
CommandButton1.BackColor = RGB(122, 255, 100)
End Sub


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

'On mouse-over = gone, color Button Red.
If CommandButton1.BackColor <> RGB(255, 0, 0) Then _
CommandButton1.BackColor = RGB(255, 0, 0)
End Sub


Private Sub UserForm_Activate()

'On form open color Button Bright Red.
If CommandButton1.BackColor <> RGB(255, 0, 0) Then _
CommandButton1.BackColor = RGB(255, 0, 0)
End Sub
 
Upvote 0
Thanks for the code.

The first part works, but not the second one, when the mouse moves off the button, it does not change color.

I noticed the sub is called:
Private Sub UserForm_MouseMove

Does it mean the button needs to be on a user form? In my document, the button cannot be on a form - it has to be directly on the sheet.

The following topic says that there's no way to capture the "mouse gone" event when the button is not on a form:
http://www.mrexcel.com/board2/viewtopic.php?t=170915

Hopefully there's another workaround...

I've read about using ActiveX controls, but it may add too much complexity for other user of the document.
 
Upvote 0
You are going to have to resort to some API wizardry and create a hotspot. I don't know how to do that and the following dirty solution may be good enough. Your CPU may scream but DoEvents will yield to other processes and I noticed no problem with performance on my older PC.

The example download contains a class module named, "ShapeEvents" and some code in the thisworkbook class. Sheet1 has a shape named "Rectangle1". See the example download...

ShapeEvents.zip

Class ShapeEvents code:
<table border="1" bgcolor="White"><caption ALIGN=left><font size="2" face=Courier New>Example VBA Code:</FONT></caption><tr><td><font size="2" face=Courier New>  <font color="#0000A0">Option</font> <font color="#0000A0">Explicit</font>
  
  <font color="#0000A0">Private</font> <font color="#0000A0">Declare</font> <font color="#0000A0">Function</font> GetCursorPos <font color="#0000A0">Lib</font> "user32" _
  (lpPoint <font color="#0000A0">As</font> POINTAPI) <font color="#0000A0">As</font> <font color="#0000A0">Long</font> ' <font color="#0000A0">Declare</font> API
  
  <font color="#0000A0">Private</font> <font color="#0000A0">Type</font> POINTAPI ' <font color="#0000A0">Declare</font> types
       x <font color="#0000A0">As</font> <font color="#0000A0">Long</font>
       y <font color="#0000A0">As</font> <font color="#0000A0">Long</font>
  <font color="#0000A0">End</font> <font color="#0000A0">Type</font>
  
  <font color="#0000A0">Public</font> <font color="#0000A0">Event</font> ShapeEnter(Sh <font color="#0000A0">As</font> Shape)
  <font color="#0000A0">Public</font> <font color="#0000A0">Event</font> ShapeExit(Sh <font color="#0000A0">As</font> Shape)
  
  <font color="#0000A0">Private</font> pEnableEvents <font color="#0000A0">As</font> <font color="#0000A0">Boolean</font>
  <font color="#0000A0">Private</font> pPreviousObjectsName <font color="#0000A0">As</font> <font color="#0000A0">String</font>
  <font color="#0000A0">Private</font> pInHover <font color="#0000A0">As</font> <font color="#0000A0">Boolean</font>
  <font color="#0000A0">Private</font> pInHoverShape <font color="#0000A0">As</font> Shape
  <font color="#0000A0">Private</font> ws <font color="#0000A0">As</font> Worksheet
  
  <font color="#0000A0">Public</font> <font color="#0000A0">Property</font> <font color="#0000A0">Let</font> EnableEvents(Value <font color="#0000A0">As</font> Boolean)
       pEnableEvents = Value
       <font color="#0000A0">If</font> pEnableEvents <font color="#0000A0">Then</font> Tracking
  <font color="#0000A0">End</font> <font color="#0000A0">Property</font>
  
  <font color="#0000A0">Public</font> <font color="#0000A0">Property</font> <font color="#0000A0">Get</font> EnableEvents() <font color="#0000A0">As</font> <font color="#0000A0">Boolean</font>
       EnableEvents = pEnableEvents
  <font color="#0000A0">End</font> <font color="#0000A0">Property</font>
  
  
  <font color="#0000A0">Private</font> <font color="#0000A0">Sub</font> Tracking()
       <font color="#0000A0">Dim</font> pt <font color="#0000A0">As</font> POINTAPI
       <font color="#0000A0">Dim</font> o <font color="#0000A0">As</font> <font color="#0000A0">Object</font>
       <font color="#0000A0">Dim</font> CurrentObjectsName <font color="#0000A0">As</font> <font color="#0000A0">String</font>
      <font color="#008000"> 'On Error Resume Next</font>
       <font color="#0000A0">Do</font> <font color="#0000A0">Until</font> <font color="#0000A0">Not</font> pEnableEvents
           DoEvents
          
           GetCursorPos pt
           <font color="#0000A0">Set</font> o = ActiveWindow.RangeFromPoint(pt.x, pt.y)
          
          
           <font color="#0000A0">Select</font> <font color="#0000A0">Case</font> TypeName(o)
          
               <font color="#0000A0">Case</font> "Range", "Nothing"
                   pPreviousObjectsName = ""
                   <font color="#0000A0">If</font> pInHover <font color="#0000A0">Then</font>
                       <font color="#0000A0">RaiseEvent</font> ShapeExit(pInHoverShape)
                       pInHover = False
                   <font color="#0000A0">End</font> <font color="#0000A0">If</font>
              
               <font color="#0000A0">Case</font> <font color="#0000A0">Else</font>
                   CurrentObjectsName = o.Name
                   <font color="#0000A0">If</font> CurrentObjectsName <> pPreviousObjectsName <font color="#0000A0">Then</font>
                       <font color="#0000A0">If</font> pInHover <font color="#0000A0">Then</font> <font color="#0000A0">RaiseEvent</font> ShapeExit(ws.Shapes(pPreviousObjectsName))
                       pPreviousObjectsName = CurrentObjectsName
                       <font color="#0000A0">Set</font> pInHoverShape = ws.Shapes(CurrentObjectsName)
                       <font color="#0000A0">RaiseEvent</font> ShapeEnter(pInHoverShape)
                       pInHover = True
                   <font color="#0000A0">End</font> <font color="#0000A0">If</font>
                  
           <font color="#0000A0">End</font> <font color="#0000A0">Select</font>
          
       <font color="#0000A0">Loop</font>
      
  <font color="#0000A0">End</font> <font color="#0000A0">Sub</font>
  
  <font color="#0000A0">Private</font> <font color="#0000A0">Sub</font> Class_Initialize()
       <font color="#0000A0">Set</font> ws = ActiveSheet
  <font color="#0000A0">End</font> <font color="#0000A0">Sub</font>
  
  <font color="#0000A0">Private</font> <font color="#0000A0">Sub</font> Class_Terminate()
       pEnableEvents = False
  <font color="#0000A0">End</font> <font color="#0000A0">Sub</font>
  
</FONT></td></tr></table>

ThisWorkbook Class Code:
<table border="1" bgcolor="White"><caption ALIGN=left><font size="2" face=Courier New>Example VBA Code:</FONT></caption><tr><td><font size="2" face=Courier New>  <font color="#0000A0">Option</font> <font color="#0000A0">Explicit</font>
  
  <font color="#0000A0">Private</font> <font color="#0000A0">WithEvents</font> MyShapeEvents <font color="#0000A0">As</font> ShapeEvents
  
  <font color="#0000A0">Private</font> <font color="#0000A0">Sub</font> MyShapeEvents_ShapeEnter(Sh <font color="#0000A0">As</font> Shape)
       <font color="#0000A0">Select</font> <font color="#0000A0">Case</font> Sh.Name
           <font color="#0000A0">Case</font> "Rectangle 1"
               Sh.Fill.ForeColor.SchemeColor = 10
               Sh.TextFrame.Characters.Text = "Click Me!"
               Sh.TextFrame.HorizontalAlignment = xlCenter
               Sh.TextFrame.VerticalAlignment = xlCenter
               <font color="#0000A0">With</font> Sh.TextFrame.Characters(Start:=1, Length:=9).Font
                   .FontStyle = "Bold"
                   .Size = 16
                   .Underline = xlUnderlineStyleSingle
                   .ColorIndex = 6
               <font color="#0000A0">End</font> <font color="#0000A0">With</font>
               Sh.Line.Weight = 6#
               Sh.Line.ForeColor.SchemeColor = 40
              
          <font color="#008000"> 'Case "Some Other shape here"</font>
          
       <font color="#0000A0">End</font> <font color="#0000A0">Select</font>
  <font color="#0000A0">End</font> <font color="#0000A0">Sub</font>
  
  <font color="#0000A0">Private</font> <font color="#0000A0">Sub</font> MyShapeEvents_ShapeExit(Sh <font color="#0000A0">As</font> Shape)
       <font color="#0000A0">Select</font> <font color="#0000A0">Case</font> Sh.Name
           <font color="#0000A0">Case</font> "Rectangle 1"
               Sh.Fill.ForeColor.SchemeColor = 64
               Sh.TextFrame.Characters.Text = ""
               Sh.Line.Weight = 1#
               Sh.Line.ForeColor.SchemeColor = 64
       <font color="#0000A0">End</font> <font color="#0000A0">Select</font>
  <font color="#0000A0">End</font> <font color="#0000A0">Sub</font>
  
  <font color="#0000A0">Sub</font> Rectangle1_Click()
       MsgBox "Your macros code here..."
  <font color="#0000A0">End</font> <font color="#0000A0">Sub</font>
  
  <font color="#0000A0">Private</font> <font color="#0000A0">Sub</font> Workbook_Open()
       <font color="#0000A0">Set</font> MyShapeEvents = <font color="#0000A0">New</font> ShapeEvents
       MyShapeEvents.EnableEvents = True
  <font color="#0000A0">End</font> <font color="#0000A0">Sub</font>
  
  <font color="#0000A0">Private</font> <font color="#0000A0">Sub</font> Workbook_SheetActivate(ByVal Sh <font color="#0000A0">As</font> Object)
       <font color="#0000A0">Set</font> MyShapeEvents = <font color="#0000A0">New</font> ShapeEvents
       MyShapeEvents.EnableEvents = True
  <font color="#0000A0">End</font> <font color="#0000A0">Sub</font>
  
  <font color="#0000A0">Private</font> <font color="#0000A0">Sub</font> Workbook_SheetDeactivate(ByVal Sh <font color="#0000A0">As</font> Object)
       <font color="#0000A0">On</font> <font color="#0000A0">Error</font> <font color="#0000A0">Resume</font> <font color="#0000A0">Next</font>
       MyShapeEvents.EnableEvents = False
       <font color="#0000A0">Set</font> MyShapeEvents = <font color="#0000A0">Nothing</font>
  <font color="#0000A0">End</font> <font color="#0000A0">Sub</font>
  
</FONT></td></tr></table>
 
Upvote 0
Edit the class to disable cell drag and drop or Excel will crash... The downloadable example has these changes reflected within. Also, the code needs some work and may or may not be worth it, but it was fun anyway. :)

Perhaps this might be more stable using a timer??? Whatdoyu think?

<table border="1" bgcolor="White"><caption ALIGN=left><font size="2" face=Courier New>Example VBA Code:</FONT></caption><tr><td><font size="2" face=Courier New>  <font color="#0000A0">Private</font> <font color="#0000A0">Sub</font> Class_Initialize()
       Application.CellDragAndDrop = False
       <font color="#0000A0">Set</font> ws = ActiveSheet
  <font color="#0000A0">End</font> <font color="#0000A0">Sub</font>
  
  <font color="#0000A0">Private</font> <font color="#0000A0">Sub</font> Class_Terminate()
       pEnableEvents = False
       Application.CellDragAndDrop = True
  <font color="#0000A0">End</font> <font color="#0000A0">Sub</font>
</FONT></td></tr></table>
 
Upvote 0
Yes, my code only works on a user form!
Only the UserForm has a Mouse Over Event!
There is no Mouse-Over" Event for a Sheet or ThisWorkbook!

Excel [VBA] has poor Mouse control.
 
Upvote 0
Thanks all for your help. Tom, I tried your download and it works nicely, but takes too much CPU. My template sheet has 6 rectangles used as section headers; when you click on them, it automatically expands the grouped subsection. There can be hundreds of sheets based on this template in the same workbook.

I've been able to put a label control under each rectangle, and the mousemove event sets the current rectangle with an orange background, and resets all others to regular blue background. Kind of doing the same effect as the shortcut bar in Outlook. Works okay, but the mouse control is not very accurate. If you move quickly, the mousemove event is not trapped.

I am seriously considering using an activeX control instead, which probably has better mouse control, including a normal "mouse gone" event. Don't know where to start though.

What are the basic steps for this?
Is it a control (shape) I can create myself, then define as ActiveX?
Maybe this area is too technical for me...

If anyone has an Excel sample with such an ActiveX control (mouseover events), thanks in advance for sharing it.
 
Upvote 0
There is no Mouse_Exit event with the active x controls that come with excel. There is too much overhead involved. I would just use hyperlinks as headers and then respond to user clicks in the Follow_Hyperlink event. There are workarounds using multiple controls but it's not worth it. Especially if you have that many sheets.
 
Upvote 0

Forum statistics

Threads
1,216,113
Messages
6,128,905
Members
449,478
Latest member
Davenil

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top