windows form - show windows 8 keyboard when touch textbox - windows

I've create a windows form application. I'd like that when the application is installed on a pc with Windows 8 and touchscren, if I click on a textbox, the virtual keyboard is automatic showed.
I've seen something like
private void textbox_Enter(object sender, EventArgs e)
{
System.Diagnostics.Process.Start("TabTip.exe");
}
but it works also when I use the mouse. I'd like that the virtual keyboards apppear just when I use touchscreen.
Thanks

I've found a "rude" solution.
I've seen that when I touch, the "587" WM Message occurs, followed by 2 "33" WM Message (the same when you click using mouse).
So I've seen that: before than "mouseclick" or "focus enter" event on textbox:
a) if you have used mouse, there is 1 "33" Wm Message
b) if you have used touch, there is 1 "587" message followed by 2 "33" Wm Message.
So, about the code.
In MyForm.cs I have a public list of bool, that save "touch status". If i never touch (or my pc doesn't support touchscreen) the status will never fill
namespace MyForm
{
public partial class MyForm: Form
{
public List<bool> v_touch = new List<bool>();
protected override void WndProc(ref Message msg)
{
switch (msg.Msg)
{
//touch
case 587:
v_touch.Add(true);
break;
//mouse or touch (on mouse click message 33 occurs 1 time; on touch tap message 587 occurs 1 time and message 33 occurs 2 times)
case 33:
//add just if some touch event (587) has occured (never fill v_touch for not touch devices)
if (v_touch.Count > 0)
{
v_touch.Add(false);
}
break;
}
base.WndProc(ref msg);
}
}
}
In all myUserControls, I need for each textbox, add moouseclick, focus enter and focus leave events.
MouseClick or focus enter call a function that enable virtual keybooard checking "touch status". Instead, focus leave event will kill keyboard.
namespace MyForm
{
public partial class MyUserControl : UserControl
{
public void enableVirtualKeyboard(List<bool> v_touch)
{
//check if came from "touch". When I use touch, the last v_touch values are (true, false, false)
if (v_touch.Count >= 3 && v_touch[v_touch.Count - 3] == true)
{
string progFiles = #"C:\Program Files\Common Files\Microsoft Shared\ink";
string onScreenKeyboardPath = System.IO.Path.Combine(progFiles, "TabTip.exe");
Process.Start(onScreenKeyboardPath);
}
}
public void disableVirtualKeyboard()
{
Process[] oskProcessArray = Process.GetProcessesByName("TabTip");
foreach (Process onscreenProcess in oskProcessArray)
{
onscreenProcess.Kill();
}
}
private void textbox_MouseClick(object sender, MouseEventArgs e)
{
this.enableVirtualKeyboard(((MyForm)this.ParentForm).v_touch);
}
private void textbox_Enter(object sender, EventArgs e)
{
this.enableVirtualKeyboard(((MyForm)this.ParentForm).v_touch);
}
private textbox_Leave(object sender, EventArgs e)
{
this.disableVirtualKeyboard();
}
}
}
}
We can write disableVirtualKeyboard and enableVirtualKeyboard in a common class, so we can use the 2 methods in all texbbx of each control of the application. Also, it's good use disableVirtualKeyboard on Form_Closing event of MyForm

Related

How to detect backspace in an Entry control when it is empty

I am using Xamarin.Forms with Android. I have a form which has 4 Entry controls for a user to enter code. I am using TextChanged event to detect user input and automatically move focus to the next control. This part works fine, i.e. as user types a digit focus automatically jumps to the next entry. However, I need to achieve the opposite, user should be able to tap backspace button and focus should move to the previous control. The problem is that TextChanged is not triggered when entry control is empty. How can I achieve this? Is there a custom renderer I can create for android to capture text input? Maybe there is a way to use 1 entry instead but I need to make it look like distinct 4 boxes.
Finally,I've found a solution for this by implementing a renderer in android.
In shared code(PCL),Create a class like this
public class CustomEntry:Entry
{
public delegate void BackspaceEventHandler(object sender, EventArgs e);
public event BackspaceEventHandler OnBackspace;
public CustomEntry()
{
}
public void OnBackspacePressed()
{
if (OnBackspace != null)
{
OnBackspace(null, null);
}
}
}
And,Then in your android project create a renderer like this:
public class CustomEntryRenderer: EntryRenderer
{
public override bool DispatchKeyEvent(KeyEvent e)
{
if (e.Action == KeyEventActions.Down)
{
if (e.KeyCode == Keycode.Del)
{
if (string.IsNullOrWhiteSpace(Control.Text))
{
var entry = (PasswordBox)Element;
entry.OnBackspacePressed();
}
}
}
return base.DispatchKeyEvent(e);
}
protected override void
OnElementChanged(Xamarin.Forms.Platform.Android.ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
}
}
And then use it like this:
Entry1.OnBackspace += Entry1BackspaceEventHandler;
public void Entry1BackspaceEventHandler()
{
//things you want to do
}

How do I listen to UWP Xaml Slider manipulation start/end events?

What events should I listen to on a UWP Xaml Slider to determine when the user begins and ends manipulation.
This functionality is important when you have a slider that represents some continuously changing app state (say, an animation time) and you want to pause the update when the user interacts with the slider.
This question has been answered for WPF and Windows Phone, but not UWP. The other solutions do not work, or are incomplete, for UWP.
You need to listen to interaction events from a couple of the elements of the Slider template: the Thumb, and the Container. This is because the user can manipulate the thumb directly by clicking and dragging it, but also they can click anywhere on the slider and the thumb will jump to that location (even though it looks like you are then manipulating the Thumb, actually the thumb is just being relocated every time the mouse moves - you are still interacting with the container).
There are a couple caveats:
the thumb and container both process their input events and do not pass them on, so you need to use the AddHandler method of attaching RoutedEvent handlers so that you get events which have already been processed.
you need to attach the event handlers after the control template has been applied, which means you need to subclass the Slider to override a protected method.
The RoutedEvent handler information is covered here: https://learn.microsoft.com/en-us/windows/uwp/xaml-platform/events-and-routed-events-overview#registering-handlers-for-already-handled-routed-events
The following SliderEx class adds some events which can be used to detect when the user begins/ends interacting with the slider:
public class SliderEx : Slider
{
public event EventHandler SliderManipulationStarted;
public event EventHandler SliderManipulationCompleted;
public event EventHandler SliderManipulationMoved;
private bool IsSliderBeingManpulated
{
get
{
return this.isContainerHeld || this.isThumbHeld;
}
}
private bool isThumbHeld = false;
private bool isContainerHeld = false;
protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
var thumb = base.GetTemplateChild("HorizontalThumb") as Thumb;
if (thumb == null)
{
thumb = base.GetTemplateChild("VerticalThumb") as Thumb;
}
if (thumb != null)
{
thumb.DragStarted += this.Thumb_DragStarted;
thumb.DragCompleted += this.Thumb_DragCompleted;
thumb.DragDelta += this.Thumb_DragDelta;
}
var sliderContainer = base.GetTemplateChild("SliderContainer") as Grid;
if (sliderContainer != null)
{
sliderContainer.AddHandler(PointerPressedEvent,
new PointerEventHandler(this.SliderContainer_PointerPressed), true);
sliderContainer.AddHandler(PointerReleasedEvent,
new PointerEventHandler(this.SliderContainer_PointerReleased), true);
sliderContainer.AddHandler(PointerMovedEvent,
new PointerEventHandler(this.SliderContainer_PointerMoved), true);
}
}
private void SliderContainer_PointerMoved(object sender,
Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
this.InvokeMove();
}
private void SliderContainer_PointerReleased(object sender,
Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
this.SetContainerHeld(false);
}
private void SliderContainer_PointerPressed(object sender,
Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
this.SetContainerHeld(true);
}
private void Thumb_DragDelta(object sender, DragDeltaEventArgs e)
{
this.InvokeMove();
}
private void Thumb_DragCompleted(object sender, DragCompletedEventArgs e)
{
this.SetThumbHeld(false);
}
private void Thumb_DragStarted(object sender, DragStartedEventArgs e)
{
this.SetThumbHeld(true);
}
private void SetThumbHeld(bool held)
{
bool wasManipulated = this.IsSliderBeingManpulated;
this.isThumbHeld = held;
this.InvokeStateChange(wasManipulated);
}
private void SetContainerHeld(bool held)
{
bool wasManipulated = this.IsSliderBeingManpulated;
this.isContainerHeld = held;
this.InvokeStateChange(wasManipulated);
}
private void InvokeMove()
{
this.SliderManipulationMoved?.Invoke(this, EventArgs.Empty);
}
private void InvokeStateChange(bool wasBeingManipulated)
{
if (wasBeingManipulated != this.IsSliderBeingManpulated)
{
if (this.IsSliderBeingManpulated)
{
this.SliderManipulationStarted?.Invoke(this, EventArgs.Empty);
}
else
{
this.SliderManipulationCompleted?.Invoke(this, EventArgs.Empty);
}
}
}
}

VSTO How to hide FormRegion in Reply email [in InlineResponse also]?

So, as the subject says...what is the easiest way to hide FormRegion if email is in Reply mode whether its in a new window or with InlineResponse?
Just set the FormRegion.Visible property which returns a Boolean value that indicates whether the form region is visible or hidden.
Went back to test the approach in my answer after the question from #EugeneAstafiev and -- of course -- this was more complicated than I first thought... but I did get it working with some additional code.
The issue is that when the user clicks "Reply", it opens a new inspector window with a new instance of the FormRegion. So setting the Visible property to false in the event handler sets it only on the current "Read" mode inspector window -- rather than the new "Compose" mode inspector window that gets opened. So, instead the code samples below set up a bool flag property in ThisAddIn called LoadFormRegion that can be toggled to "false" when the Reply or ReplyAll event is fired.
Also, I noticed that setting Visible to false on the FormRegion still draws the area of the FormRegion on the inspector window, just with nothing in it. To completely prevent the FormRegion from loading, you can test for "Compose" mode and then the ThisAddin.LoadFormRegion flag in the FormRegionInitializing event handler located inside of the "Form Region Factory" at the top of the code page -- which is usually folded away from view. In that code block, setting "e.Cancel = true" will prevent the FormRegion from loading at all.
Here is the revised code for the FormRegion, which now subscribes to all three email button click events (Reply, ReplyAll, Forward), and sets the ThisAddIn.LoadFormRegion flag accordingly:
namespace TESTINGOutlookAddInVSTO
{
partial class FormRegion1
{
#region Form Region Factory
[Microsoft.Office.Tools.Outlook.FormRegionMessageClass(Microsoft.Office.Tools.Outlook.FormRegionMessageClassAttribute.Note)]
[Microsoft.Office.Tools.Outlook.FormRegionName("TESTINGOutlookAddInVSTO.FormRegion1")]
public partial class FormRegion1Factory
{
// Occurs before the form region is initialized.
// To prevent the form region from appearing, set e.Cancel to true.
// Use e.OutlookItem to get a reference to the current Outlook item.
private void FormRegion1Factory_FormRegionInitializing(object sender, Microsoft.Office.Tools.Outlook.FormRegionInitializingEventArgs e)
{
if (e.FormRegionMode == Outlook.OlFormRegionMode.olFormRegionCompose)
{
var myAddIn = Globals.ThisAddIn;
if (myAddIn.LoadFormRegion == false)
{
e.Cancel = true;
}
}
}
}
#endregion
// Occurs before the form region is displayed.
// Use this.OutlookItem to get a reference to the current Outlook item.
// Use this.OutlookFormRegion to get a reference to the form region.
private void FormRegion1_FormRegionShowing(object sender, System.EventArgs e)
{
// Reset ThisAddIn.LoadFormRegion flag to true (in case user starts
// composing email from scratch without clicking Reply, ReplyAll or Forward)
var myAddin = Globals.ThisAddIn;
myAddin.LoadFormRegion = true;
var myMailItem = this.OutlookItem as Outlook.MailItem;
// Track these events to set the ThisAddIn.FormRegionShowing flag
((Outlook.ItemEvents_10_Event)myMailItem).Reply += myMailItem_Reply;
((Outlook.ItemEvents_10_Event)myMailItem).ReplyAll += myMailItem_ReplyAll;
((Outlook.ItemEvents_10_Event)myMailItem).Forward += myMailItem_Forward;
}
// Sets FormRegionShowing flag on ThisAddin
private void SetFormRegionShowing(bool show)
{
var myAddIn = Globals.ThisAddIn;
myAddIn.LoadFormRegion = show;
}
private void myMailItem_Forward(object Forward, ref bool Cancel)
{
SetFormRegionShowing(true);
}
private void myMailItem_ReplyAll(object Response, ref bool Cancel)
{
SetFormRegionShowing(false);
}
private void myMailItem_Reply(object Response, ref bool Cancel)
{
SetFormRegionShowing(false);
}
// Occurs when the form region is closed.
// Use this.OutlookItem to get a reference to the current Outlook item.
// Use this.OutlookFormRegion to get a reference to the form region.
private void FormRegion1_FormRegionClosed(object sender, System.EventArgs e)
{
}
}
}
And here's the new code for ThisAddIn to setup the LoadFormRegion property flag:
namespace TESTINGOutlookAddInVSTO
{
public partial class ThisAddIn
{
private bool loadFormRegion;
public bool LoadFormRegion { get => loadFormRegion; set => loadFormRegion = value; }
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
LoadFormRegion = true;
}
private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
{
// Note: Outlook no longer raises this event. If you have code that
// must run when Outlook shuts down, see https://go.microsoft.com/fwlink/?LinkId=506785
}
#region VSTO generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InternalStartup()
{
this.Startup += new System.EventHandler(ThisAddIn_Startup);
this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
}
#endregion
}
}
Tested the above and works nearly perfectly... I noticed that if there is a "Draft" reply in the user's Inbox created before the add-in was loaded, clicking on that email to continue editing in the Preview window or a new inspector window will cause some wonky display issues with the FormRegion. However, once I closed out that draft, then everything seemed to return to normal.

TextBox Leave Event suppresses Button Click

I have a simple Windows Form: 'Message' TextBox has Enter and Leave events to allow user to enter text in another language only on that field. 'Send' button sends the form content. After the user fills the Message and clicks Send, Textbox's Leave event prevent button's Click event from firing. I need both handlers to run.
Here's the relevant code:
private void Message_Enter(object sender, EventArgs e)
{
inputLang = InputLanguage.CurrentInputLanguage;
foreach (InputLanguage lang in InputLanguage.InstalledInputLanguages)
{
if (lang.LayoutName == "United States-International")
{
InputLanguage.CurrentInputLanguage = lang;
break;
}
}
}
private void Message_Leave(object sender, EventArgs e)
{
InputLanguage.CurrentInputLanguage = inputLang;
}
private void Send_Click(object sender, EventArgs e)
{
string dest = ServerList.Text;
string msg = Message.Text;
if (dest.Length == 0 || msg.Length == 0 )
{
Log("Fill the destination server and the message");
return;
}
if (context.SendMessage(dest, msg))
{
if (!ServerList.Items.Contains(dest))
{
ServerList.Items.Add(dest);
}
}
else
{
if (ServerList.Items.Contains(dest))
{
ServerList.Items.Remove(dest);
}
}
}
The problem is now solved. The problem is caused by the change of input language. If the enter and leave handlers did other stuff then the click event will fire normally. Since I need to change the input language I solved it by monitoring the MouseDown, MouseClick and MouseUp events and generating a click if it was not automatically generated.
I've got same problem. When I changed the input language and then on leave event set it back to default one. When i click on other component it wont fire click event. I had to click twice then.
I thing it has something to do with focus.
I solved it by setting the focus back to form, after changing back the input language.
Here is the handler:
void textBoxSearch_LostFocus(object sender, EventArgs e)
{
InputLanguage.CurrentInputLanguage = InputLanguage.DefaultInputLanguage;
this.Focus();
}
Hope it helps...

catch touch event on blackberry api5

I want to catch the touch event in OS5. I use this method protected boolean touchEvent(TouchEvent message) in ListFieldRich. But this method didn't run it. I press all keys nothing happens. Even if I debug my code, this method didn't run when press keys.
How can I know the touch event in OS5?
Thanks
Touchevent will be called if you have a touch screen phone, and you touch the screen. It will not be called if you press the keys or buttons. Did you touch the screen?
I resolved my problem. I used this method protected boolean trackwheelClick(int status, int time)
setChangeListener() on your RichTextField and override these method in your Screen class
protected boolean navigationClick(int status, int time) {
if(Touchscreen.isSupported()) {
return false;
}
fieldChangeNotify(1);
return true;
}
//for touch
protected boolean touchEvent(TouchEvent message) {
if (TouchEvent.CLICK == message.getEvent()) {
FieldChangeListener listener = getChangeListener();
if (null != listener)
listener.fieldChanged(this, 1);
}
return super.touchEvent(message);
}
and in fieldChanged() method
public void fieldChanged(Field field, int context) {
if (field == yourRichTextField) {
Dialog.inform("RichtextField Clicked Button Pressed");
}

Resources