|
|
|
The General Winforms Interview Questions consists the most frequently
asked questions in Winforms. This list of 100+ questions guage your familiarity
with the Winforms platform. The q&a have been collected over a period
of time from various blogs, forums and other similar Winforms sites
|
10.Windows Forms Mouse Handling
|
| 10.1 How do I
add a context menu to a control?
|
| 10.2 When using
the ContextMenu on multiple Controls, how do I know on which Control the right
click was performed?
|
| 10.3 How do
menu shortcuts work?
|
| 10.4 How do I
make the context menu appear only when clicked at certain portions of the
Control?
|
| 10.5 How do I
prevent the context menu from showing up on certain keyboard keys (like
Keys.Apps)?
|
| 10.6 How do I
know when a menu is closed/started so that I can refresh my status bar?
|
| 10.7 Is there
an Idle event which will get fired from which I could update my menu item's
enabled state?
|
10.1 How do I get a mouse cursor position in my control's client coordinates?
|
|
Use the Position property of the Cursor class found in the System.Windows.Forms
namespace. Here is code that will flag whether the mouse is over button1.
|
Point ptCursor = Cursor.Position;
ptCursor = PointToClient(ptCursor);
if( button1.Bounds.Contains(ptCursor) )
{
//mouse over button1
//....
}
else
{
//mouse not over button1
//....
}
|
10.2 How can I catch the mouse being over a control?
|
|
Add a handler for the control's MouseMove event. This will be hit as the mouse
moves over the control's Bounds rectangle.
|
10.3 How do I set the mouse cursor position?
|
|
The Cursor.Position property is a static property with both get and set methods
available. Remember that the Point object used by the property is in screen
coordinates. Here is code that move the mouse position down 20 points.
|
Point pt = Cursor.Position;
pt.Y += 20;
Cursor.Position = pt;
|
|
10.4 I How can I reset the OnMouseHover timer so that it will fire again
without the mouse having to leave the client area of a control?
|
|
In the microsoft.public.dotnet.framework.windowsforms newsgroup, T. H. in den
Bosch posted the following suggestion with a potential warning: I found out
that calling Control.ResetMouseEventArgs() does the trick. This is an
undocumented internal method, so I don't know if calling it has adverse side
effects.
|
10.5 How can I drag a window if it doesn't have a title bar or border?
|
|
You can drag such a window by using Win32 APIs to switch the mouse hit to
WM_NCLBUTTONDOWN. The code below will allow you to drag by mousing down
anywhere in the form's clientarea as long as you don't hit a child control on
the form.
|
using System.Runtime.InteropServices;
............
public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HTCAPTION = 0x2;
[DllImportAttribute ("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int
lParam);
[DllImportAttribute ("user32.dll")]
public static extern bool ReleaseCapture();
private void Form2_MouseDown(object sender, System.Windows.Forms.MouseEventArgs
e)
{
ReleaseCapture();
SendMessage(Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0);
}
|
|
Here is a solution posed by Jacob Grass (Abiliti Solutions) that does not rely
on InteropServices.
|
Private blnMoving As Boolean = False
Private MouseDownX As Integer
Private MouseDownY As Integer
Private Sub Form1_MouseDown(ByVal sender As Object, _
ByVal e As System.Windows.Forms.MouseEventArgs) Handles Form1.MouseDown
If e.Button = MouseButtons.Left Then
blnMoving = True
MouseDownX = e.X
MouseDownY = e.Y
End If
End Sub
Private Sub Form1_MouseUp(ByVal sender As Object, _
ByVal e As System.Windows.Forms.MouseEventArgs) Handles Form1.MouseUp
If e.Button = MouseButtons.Left Then
blnMoving = False
End If
End Sub
Private Sub Form1_MouseMove(ByVal sender As Object, _
ByVal e As System.Windows.Forms.MouseEventArgs) Handles Form1.MouseMove
If blnMoving Then
Dim temp As Point = New Point()
temp.X = Form1.Location.X + (e.X - MouseDownX)
temp.Y = Form1.Location.Y + (e.Y - MouseDownY)
Form1.Location = temp
End If
End Sub
|
10.6 How can I determine if a mouse button is pressed and moving over my form?
|
|
Catch the form's MouseMove event which is called when the mouse moves over the
form. To determine if a button is pressed during the move, check the event
arg's Button property. The code below draw's a line on the form as the mouse
moves over it. The line is red when the left button is pressed, white when the
right button is pressed and blue when no button is pressed.
|
.... private void InitializeComponent()
{
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 273);
this.Name = "Form1";
this.Text = "Form1";
this.MouseMove += new
System.Windows.Forms.MouseEventHandler(this.Form1_MouseMove);
}
....
private void Form1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs
e)
{
if(_point.X == -1)
_point = new Point(e.X, e.Y);
Color c;
if(e.Button == MouseButtons.Left)
c = Color.Red;
else if(e.Button == MouseButtons.Right)
c = Color.White;
else if(e.Button == MouseButtons.None)
c = Color.Blue;
else
c = this.BackColor;
Point p = new Point(e.X,e.Y);
Graphics g = Graphics.FromHwnd(this.Handle);
Pen pen = new Pen(c,1);
g.DrawLine(pen,_point,p);
_point = p;
pen.Dispose();
}
|
10.7 Why am I not receiving MouseLeave messages in a Control in my Form?
|
|
This usually happens when a Control doesn't know that the mouse has left its
bounds following a mouse enter. This results in the Control not throwing a
MouseLeave event for subsequent mouse moves over it.
This is possible if you performed some operation when the mouse was within a
Control that made it lose its mouse capture, for example, opening a top-level
window over the Control such that the mouse is now over this new window.
To work around this problem send a WM_MOUSELEAVE manually to the original
Control before the offending operation.
|
class NativeMethods
{
[DllImport("user32.dll", CharSet=CharSet.Auto)]
extern public static IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam,
IntPtr lParam) ;
}
// Send a WM_MOUSELEAVE manually to a window.
NativeMethods.SendMessage(control.Handle, NativeMethods.WM_MOUSELEAVE,
IntPtr.Zero, IntPtr.Zero);
|
|