Adding event handlers to object - vba

Is there a way to add keydown and keyleft event handler to image object in a user form? I can only see mouseup/down/move,error,dragover,dropandpaste.
I notice with an option button, the event keydown/keyleft is available but not for image.
Thanks in advance

You can't add event handlers that don't exist for that control type (other than by subclassing, but the image control doesn't receive focus anyway), but an image control can't receive the focus, and therefore can't receive keystrokes anyway.
You talk about KeyDown and KeyLeft events. While some controls have KeyDown, KeyPress and KeyUp events, there aren't any controls that have a KeyLeft event. Do you perhaps mean to capture the KeyDown event, and then detect whether the Down arrow or Left arrow was the key that pressed down?
However, there are a few options:
Wire up the KeyDown or KeyPress event (depending upon which type of key information you require) for the UserForm, and then act upon the image control. This is probably only of use if you're happy for keypresses to be handled by the form, regardless of which other control might be selected.
Add a proxy control, say a TextBox that does receive KeyDown and KeyPress events, and place it behind the image control. That way, when the user tabs to the textbox, you can add a border to the image to make it look like it is selected, and then have the textbox key events act upon the image. If a user clicks on the image, instead of tabbing between controls, you can set the image's click event to give the textbox the focus, and again, handle the key events for the textbox as a proxy for the image control.

It depends on what are you trying to achieve which you didn't specify.
Image obviously doesn't have Key-events so it can't be used directly.
One possible solution could be to use Frame control which has a Picture property and has KeyDown event, so you can catch key-downs when the frame has focus. Example:
Private Sub FrameWithPicture_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
' Compare KeyCode with predefined vbKey-Constansts, e.g. for key-left:
If KeyCode = vbKeyLeft Then
' left arrow key was pressed, do somthing
Else
' all other keys were pressed, do something else
End If
End Sub
Or you could add Image control to this frame and when key-down event occurs on the frame, then perform some action on this image like this: FrameWithImage.Controls.Item(0).BackColor = vbRed etc. HTH

Related

How can I get mouse location on a button?

VB.NET
Visual Studio
I have several buttons that I add at runtime, and I have a MouseDown event handler for the click event. Left click works just fine, but the right click event fires, but doesn't do what I need it to.
If e.Button = Windows.Forms.MouseButtons.Right Then
If sender.Bounds.Contains(e.Location) = True Then
ContextMenuStrip.Show(Cursor.Position)
End If
End If
I shortened this to make it easier to read.
When I look at e.Location, it shows the mouse location in relation to the button.
So if my button is at 400, 600, the location of the mouse should be in that area, but the mouse location comes back with 20, 30 because it is at 20,30 inside the button.
How can I do this right click event properly?
MouseDown event raises when the mouse is down on your control, so the mouse is surely in your control bounds and you don't need to check if the button contains e.Location.
To show the context menu strip, if you assign the context menu strip to ContextMenuStrip property of your control, then you don't need to do anything and the menu will show automatically. But if for any reason you want to handle MouseDown event, you can use either of these options:
ContextMenuStrip1.Show(DirectCast(sender, Control), e.Location)
ContextMenuStrip1.Show(MousePosition)
Note: Just for learning purpose if you want to check if e.Location is in your button, you can use either of these options:
Button1.ClientRectangle.Contains(e.Location)
Button1.Bounds.Contains(Button1.Parent.PointToClient(Button1.PointToScreen(e.Location)))
Or some other combinations using PointToClient, PointToScreen, RectangleToClient, RectangleToScreen methods of controls.

Detect MouseUp after Leaving MouseDown Control

Using VB.NET, Short of adding a mouseup event to every control in my form, does anybody know a way to trigger a mouseup event regardless of where the cursor is located or what control the cursor is in?
Or is there a way to see if the mouse left button is up, that way I can do on enter, if mouseup then...
Or is there a way to see if the mouse left button is up, that way I can do on enter, if mouseup then...
There is a static property on the Control class - Control.MouseButtons which returns, in the form of a flag based enum, which buttons on the mouse are currently pressed.
var pressedButtons = Control.MouseButtons;
if (!pressedButtons.HasFlag(MouseButtons.Left))
{
// Left mouse button is not down, so do stuff
}

How can I prevent key presses from changing the value of a scrollbar control?

I have a form with a user control that has a vscrollbar control. I would like to handle the user control's keypress event, but when I press the 'down arrow' key (for example), the keypress event isn't handled, and the vscrollbar's value increases instead. Other navigational keys behave this way as well.
I would like to have the vscrollbar stop 'overriding' my intention to raise the keypress event. I was thinking I could set the user control's keypreview property to true, but then I noticed it doesn't have one.
You need to look at using the KeyDown or PreviewKeyDown event instead.

Slow label and picturebox event firing which are child of Button

i have developed custom control which inherits Button control, actually i`m creating button with one picturebox and label on Button(picturebox and label are child controls). I created same method and wired child controls to behave as clicking on parent(Button), it works but its slow no mather what i do(tried with InvokeOnClick, me.performclick, Me.OnClick(New EventArgs()), tried with same method for all events), but clicking on label or picture box is slow, i need it to be fast as clicking directly on button cause in my application is very important to be able to click on button twice in second for example, if you click on label or picturebox twice at second it will fire just one time not 2.
What i have been thinking of is to make label and picturebox invisible for event is it possible or anyother idea ?
Thanks in forward
You are doing battle with ControlStyles.StandardDoubleClick. Which is turned on for the PictureBox and Label controls but turned off for Button.
So when you are clicking rapidly on either the picturebox or the label then they'll generate the DoubleClick event instead of the Click event. You'll interpret that as "slow" since you probably didn't write a handler for that event. Subscribing the event and calling Me.OnClick is a workaround.
Just don't do this. PictureBox and Label are point-and-click convenience controls but they are extraordinarily wasteful. It takes just two lines of code in the button's OnPaint() method override to get the exact same outcome, minus the overhead and the event problems. Use e.Graphics.DrawImage() to draw the pb's image and TextRenderer.DrawText() to draw the label's text.
Using MouseDown event ensures the event is triggered once per click, regardless of click/doubleclick.

Using mouse to increment and decrement value of the NumericUpDown control in VB.net

I have a NumericUpDown control in my VB.Net 2.0 project. When the user clicks the mouse inside the control and drags left or right, I want the value of the control to increment or decrement accordingly.
The problem I am having is that I am not able to capture the mouse-move event once the mouse pointer is inside the boundaries of the control and the mouse button is pressed. I've tried overriding the onMouseMove() event, but this event only fires once when the mouse is moved over the text-box part of the NumericUpDown control. However, the event fires continuously when moved over the Up/Down buttons of the same control.
I still want to preserve the normal operation of the control: be able to type in a value, use the up and down button to change the value etc...
Anyone have any suggestions what to try? Thanks!
The mouse event goes to the TextBox that's inside the NUD. You can get a reference to it from Controls property, index 1 is the textbox:
Public Sub New()
InitializeComponent()
AddHandler NumericUpDown1.Controls(1).MouseDown, AddressOf NudMouseDown
AddHandler NumericUpDown1.Controls(1).MouseMove, AddressOf NudMouseMove
End Sub
This kinda breaks the rules but its okay, that control is never going to change anymore.