How do I implement a double-right-click for winforms? - c#

This question seems to point to the existence of a windows event for a double-right-click. How to implement it in a C# windows form, however, is less than clear.
What's the best way to implement double-right-click on a control such as a button?
(I'm thinking I must use MouseDown and keep track of the time between clicks. Is there a better way?)

Override the WndProc function and listen for WM_RBUTTONDBLCLK, which as can be seen on this pinvoke page is 0x0206.
That pinvoke page also has some C# sample code for how to do it.
Whenever you see something about a windows message and/or windows API and you want to use it in C#, the pinvoke site is a good place to start looking.

Override Control.WndProc, and handle the WM_RBUTTONDBLCLK message manually.

MouseEventArgs contain property 'Button' that indicate wich button was clicked. So you can simply check this:
private void MouseDoubleClickEventHandler(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
DoSomthing();
} else if (e.Button == MouseButtons.Right)
{
DoSomethingElse();
}
}

I was able to implement this by inheriting from a button and overriding WndProc as ho1 and Reed suggested. Here's the inherited button:
public class RButton : Button
{
public delegate void MouseDoubleRightClick(object sender, MouseEventArgs e);
public event MouseDoubleRightClick DoubleRightClick;
protected override void WndProc(ref Message m)
{
const Int32 WM_RBUTTONDBLCLK = 0x0206;
if (m.Msg == WM_RBUTTONDBLCLK)
DoubleRightClick(this, null);
base.WndProc(ref m);
}
}
I added the button programatically to the form and subscribed to its new DoubleRightClick event. I'm not sure how exactly to generate the appropriate MouseEventArgs but since this is just a test case, it's not important.

Related

Prevent selecting text in a TextBox

Similar questions have been already asked (e.g., here), however I've not found an answer for my specific case. I'm building a custom control based on a DevExpress control, which in turns is based on standard TextBox and I've a flickering problem that seems due to the base TextBox component, which tries to update selection.
Without explaining all the details of my custom control, to reproduce the problem you just need to place a TextBox inside a Form and then use this code:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
textBox1.MouseMove += TextBox1_MouseMove;
}
private void TextBox1_MouseMove(object sender, MouseEventArgs e) {
(sender as TextBox).Text = DateTime.Now.Ticks.ToString();
}
}
If you launch it, you click on the TextBox and then you move the cursor toward right you will notice the flickering problem (see video here). For my custom control I would need to avoid this flickering. I'm bound to use a TextBox (so no RichTextBox). Any idea?
The solution has been provided in the meantime by Reza Aghaei by overriding WndProc and intercepting WM_SETFOCUS messages. See here
Depending on what u want to do there are several solutions:
If you want to prevent the selection it would be:
private void TextBox1_MouseMove(object sender, MouseEventArgs e)
{
(sender as TextBox).Text = DateTime.Now.Ticks.ToString();
(sender as TextBox).SelectionLength = 0;
}
Or for selecting all:
private void TextBox1_MouseMove(object sender, MouseEventArgs e)
{
(sender as TextBox).Text = DateTime.Now.Ticks.ToString();
(sender as TextBox).SelectAll();
}
And besides that u also could specify the conditions for selecting, for example:
private void TextBox1_MouseMove(object sender, MouseEventArgs e)
{
(sender as TextBox).Text = DateTime.Now.Ticks.ToString();
if (MouseButtons == MouseButtons.Left) (sender as TextBox).SelectAll();
else (sender as TextBox).SelectionLength = 0;
}
But as long as you want to select the text you always will get some flickering, because a normal Textbox has not the possibility to use things like BeginEdit and EndEdit and so it will change the text first and then select it.
Looking at the video it looks like your textbox is calling WM_ERASEBKGND unnecessarily. In order to remedy this problem you can subclass the textbox class and intercept these messages. Below is sample code which should do the trick (untested) Disclaimer: I have used this technique for other WinForm controls that had the type of flicker shown in your video but not TextBox. If it does work for you, please let me know. Good luck!
// textbox no flicker
public partial class TexttBoxNF : TextBox
{
public TexttBoxNF()
{
}
public TexttBoxNF(IContainer container)
{
container.Add(this);
InitializeComponent();
//Activate double buffering
this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
//Enable the OnNotifyMessage event so we get a chance to filter out
// Windows messages before they get to the form's WndProc
this.SetStyle(ControlStyles.EnableNotifyMessage, true);
}
//http://stackoverflow.com/questions/442817/c-sharp-flickering-listview-on-update
protected override void OnNotifyMessage(Message m)
{
//Filter out the WM_ERASEBKGND message
if (m.Msg != 0x14)
{
base.OnNotifyMessage(m);
}
}
}

Add OnClick Action to Shape Objects in MS PowerPoint

I Have a requirement to add a OnClick action to Shape object in Micro Soft Power Point Addin for Office 2010 and above which is built using C# language. There are events like
SlideSelectionChanged
WindowBeforeRightClick
Which doesn't work as needed, Right Click Event doesn't even work on the Shape Objects.
Is there a way to subscribe to such type of events, I would not prefer to use MACRO however if that is inevitable I will use it.
This solution would work.
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
this.Application.WindowSelectionChange += OnWindowSelectionChanged;
}
void OnWindowSelectionChanged(PowerPoint.Selection Sel)
{
if (Sel.Type == PowerPoint.PpSelectionType.ppSelectionShapes)
{
PowerPoint.ShapeRange shapeRange = Sel.ShapeRange;
//Do some work
}
}
private void ThisAddIn_ShutDown(object sender, System.EventArgs e)
{
this.Application.WindowSelectionChange -= OnWindowSelectionChanged;
}
It's Good to have some flag to make sure you are doing the needful only on desired Shape Objects by setting some flag by using AltText like
if (Sel.ShapeRange.AlternativeText.Contains("SomeFlag"))
{
//Do some thing
}

How do I create keyboard input in a wpf application?

I want to make a wpf application in c# that displays some text on screen, and where the user is supposed to write a response and press enter to submit the response. I don't want to use a textbox, since there is only one line for the text input in the window, and I don't want the user to have to click to select the textbox. I want the application to be mouse-free.
My question is: How do I make it so that when the user has written their answer, they can submit the response simply by pressing enter?
I have tried the following snippet of code which I found on a microsoft help website:
private void OnKeyDownHandler(object sender, KeyEventArgs e)
{
if (e.Key == Key.Return)
{
doSomething();
}
}
I suppose I have to add some code elsewhere, but I'm not sure where or what I need to add.
If you want to make sure your window process every Enter key press without care what control is focused you can use PreviewKeyDown event:
private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
//Process user input
e.Handled = true;
}
}
Of course if you are doing mvvm you can create a behavior to encapsulate the event handler:
public class WindowBehavior : Behavior<Window>
{
protected override void OnAttached()
{
AssociatedObject.PreviewKeyDown += AssociatedObject_PreviewKeyDown;
}
private void AssociatedObject_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
MessageBox.Show("Enter from Window");
e.Handled = true;
}
}
protected override void OnDetaching()
{
AssociatedObject.PreviewKeyDown -= AssociatedObject_PreviewKeyDown;
}
I suggest you to read this article about bubble, tunneling and direct events basic for WPF events.
If you have a button that you're using for submit, you can easily set it as the default by using the IsDefault=true (wrote a tip about doing this and the cancel for the escape here.)
Other than that, you'll have to have somewhere to write it (yet you don't want a textbox? you can select it by default, or tab into it if you don't have the focus there), and you can handle the keydown to "catch" the Enter otherwise.

Windows Phone 8 back button event (OnBackKeyPress) handling?

Is it possible to make Windows Phone 8 back button event (OnBackKeyPress) by another method? I have been trying to call that event from outside button click or page initializer. but it gives an error?
OnBackKeyPress += new EventHandler<System.ComponentModel.CancelEventArgs>(OnBackKeyPress);
No overload for 'OnBackKeyPress' matches delegate
'System.EventHandler'
Just override the back key press event like below,
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
//Do your work here
base.OnBackKeyPress(e);
}
You can try this one
public Page()
{
InitializeComponent();
BackKeyPress +=PageBackKeyPress;
}
void PageBackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
{
// code
}
Just type "override" (without quotes) and then press space, all the overridden methods will appear, select the onBackKeyPress method.
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
base.OnBackKeyPress(e);
}
this method will appear, now u can write ur chunk of code inside.

Give focus to textBox on key press

I want to give a textbox focus when the user starts typing anywhere in my app.
My page inherits from LayoutAwarePage.
Can this be achieved ?
Edit:
I got this code:
// In constructor
Window.Current.CoreWindow.KeyDown += CoreWindow_KeyDown;
// Somewhere else in class
void CoreWindow_KeyDown(Windows.UI.Core.CoreWindow sender, Windows.UI.Core.KeyEventArgs args)
{
this.setSearchboxFocus((int)args.VirtualKey);
}
private void setSearchboxFocus(int keyCode)
{
if (keyCode == 38)
return;
if (keyCode == 40)
return;
if (this.searchBox.FocusState == Windows.UI.Xaml.FocusState.Unfocused)
{
this.searchBox.Text = "";
this.searchBox.Focus(Windows.UI.Xaml.FocusState.Keyboard);
}
}
For anyone reading this thread in the future, it is because of the webview. I asked a similar question on the msdn forum here. As of Windows 8.1, the webview is implemented as a separate window and completely steals all keyboard input when it has focus without passing any of it up to the controlling application. If you are able to change the HTML in the website being called it may be possible to use javascript listeners to pass events between the application and webview, but I did not test this myself. Unfortunately there does not seem to be any other workaround at this time.
You can handle the KeyDown/KeyUp event for the whole page by subscribing to these events
Window.Current.CoreWindow.KeyDown += CoreWindow_KeyDown;
Window.Current.CoreWindow.KeyUp += CoreWindow_KeyUp
This might help
private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
textBox1.Focus();//sets focus to textBox1 when user presses a key on form
}
How about something like this?
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (!textBox1.Focused)
{
textBox1.Focus();
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
How about, on the Windows.UI.Xaml.Controls.Page:
protected override void OnKeyDown(KeyRoutedEventArgs e)
{
textBox1.Focus(Windows.UI.Xaml.FocusState.Keyboard);
base.OnKeyDown(e);
}

Categories

Resources