Spell checking library for Windows Mobile 6.x - c#

We are looking into how we can check the spelling of text entered by the user in an app we have developed.
Is there any standard APIs and libraries/dictionaries included in the Windows Mobile 6.x OS that can be used for this? Please point me in the rigth direction if there is.
Thank you in advance!

Windows Mobile 6 has Auto Correction and Auto Suggestion built in. You can enable and disable these from your app with the following PInvoke call.
public static class InputContext
{
private enum SHIC_FEATURE : uint
{
RESTOREDEFAULT = 0,
AUTOCORRECT = 1,
AUTOSUGGEST = 2,
HAVETRAILER = 3,
CLASS = 4
}
[DllImport("aygshell.dll")]
private static extern int SHSetInputContext(IntPtr hwnd, SHIC_FEATURE dwFeature, ref bool lpValue);
public static void SetAutoSuggestion(IntPtr handle, bool enable)
{
SHSetInputContext(handle, SHIC_FEATURE.AUTOSUGGEST, ref enable);
SHSetInputContext(handle, SHIC_FEATURE.AUTOCORRECT, ref enable);
}
}

Related

C# force register/overwrite hotkeys

I want to force register/overwrite hotkeys...so this code is working fine but it fail's when that hotkey already register for the other application...
so I want to overwrite hotkey is it possible?
[DllImport("user32", SetLastError=true)]
private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
[DllImport("user32", SetLastError = true)]
private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
enum KeyModifier
{
None = 0,
Alt = 1,
Control = 2,
Shift = 4,
WinKey = 8
}
public ExampleForm()
{
InitializeComponent();
int id = 0; // The id of the hotkey.
RegisterHotKey(this.Handle, id, (int)KeyModifier.Shift, Keys.A.GetHashCode()); // Register Shift + A as global hotkey.
}
I agree with IInspectable (and obviously Raymond). You should avoid this. But if you absolutely must do this, I believe Windows Hooks using SetWindowHookEx is the way to go.
System level hooks are serious stuff, and care should be taken when implementing them, since they affect system's performance..
For details and working code look here and here.
Do note again: Its an overkill, and its like using a sledgehammer (or I would say Demolition hammer) to crack a nut. But sometimes you gotta do what you gotta do!

Determine if Windows 10 Touch Keyboard is Visible or Hidden

I am trying to find out if the windows 10 virtual touch keyboard is visible or not to know whether to open it or not from my application. THe following code has worked fine up until the latest Windows 10 update 15063 or possible the one right before it. Seems like Microsoft changed something with the window styles possibly but I can't figure it out.
public static bool IsKeyboardVisible()
{
IntPtr keyboardHandle = GetKeyboardWindowHandle();
// Specifies we wish to retrieve window styles.
int GWL_STYLE = -16;
//The window is disabled. See http://msdn.microsoft.com/en-gb/library/windows/desktop/ms632600(v=vs.85).aspx.
UInt32 WS_VISIBLE = 0x10000000;
UInt32 WS_DISABLED = 0x08000000;
UInt32 WS_POPUP = 0x80000000;
bool visible = false;
bool disabled = false;
if (keyboardHandle != IntPtr.Zero)
{
UInt32 style = GetWindowLong(keyboardHandle, GWL_STYLE);
visible = ((style & WS_VISIBLE) == WS_VISIBLE);
disabled = ((style & WS_DISABLED) == WS_DISABLED); // ref https://stackoverflow.com/questions/11065026/get-window-state-of-another-process
log.InfoFormat("style:{0:X4} visible:{1} disabled:{2}", style, visible, disabled);
}
return visible && !disabled ;
}
This is related to: Show touch keyboard (TabTip.exe) in Windows 10 Anniversary edition
I've done some research with Spy++ . Looks like the new keyboard in Fall Creators Update (ver. 1709) is hosted by another window. This window has Windows.UI.Core.CoreWindow class and Microsoft Text Input Application as its title.
The following code works for all Windows 10 versions including the new 1803 and older Windows versions as well (starting with Windows 8, I believe).
static class TouchKeyboard
{
public static bool GetIsOpen()
{
return GetIsOpen1709() ?? GetIsOpenLegacy();
}
private static bool? GetIsOpen1709()
{
var parent = IntPtr.Zero;
for (;;)
{
parent = FindWindowEx(IntPtr.Zero, parent, WindowParentClass1709);
if (parent == IntPtr.Zero)
return null; // no more windows, keyboard state is unknown
// if it's a child of a WindowParentClass1709 window - the keyboard is open
var wnd = FindWindowEx(parent, IntPtr.Zero, WindowClass1709, WindowCaption1709);
if (wnd != IntPtr.Zero)
return true;
}
}
private static bool GetIsOpenLegacy()
{
var wnd = FindWindowEx(IntPtr.Zero, IntPtr.Zero, WindowClass);
if (wnd == IntPtr.Zero)
return false;
var style = GetWindowStyle(wnd);
return style.HasFlag(WindowStyle.Visible)
&& !style.HasFlag(WindowStyle.Disabled);
}
private const string WindowClass = "IPTip_Main_Window";
private const string WindowParentClass1709 = "ApplicationFrameWindow";
private const string WindowClass1709 = "Windows.UI.Core.CoreWindow";
private const string WindowCaption1709 = "Microsoft Text Input Application";
private enum WindowStyle : uint
{
Disabled = 0x08000000,
Visible = 0x10000000,
}
private static WindowStyle GetWindowStyle(IntPtr wnd)
{
return (WindowStyle)GetWindowLong(wnd, -16);
}
[DllImport("user32.dll", SetLastError = false)]
private static extern IntPtr FindWindowEx(IntPtr parent, IntPtr after, string className, string title = null);
[DllImport("user32.dll", SetLastError = false)]
private static extern uint GetWindowLong(IntPtr wnd, int index);
}
Update: I updated the answer and the code to be compatible with Redstone 4 (v1803) as well.
I'm using this solution, and it is working on Windows 1607, 1709 and 1803 (check the Main method below on the code):
using System;
using System.Drawing;
using System.Runtime.InteropServices;
namespace ConsoleApp1
{
class Program
{
[ComImport, Guid("D5120AA3-46BA-44C5-822D-CA8092C1FC72")]
public class FrameworkInputPane
{
}
[ComImport, System.Security.SuppressUnmanagedCodeSecurity,
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid("5752238B-24F0-495A-82F1-2FD593056796")]
public interface IFrameworkInputPane
{
[PreserveSig]
int Advise(
[MarshalAs(UnmanagedType.IUnknown)] object pWindow,
[MarshalAs(UnmanagedType.IUnknown)] object pHandler,
out int pdwCookie
);
[PreserveSig]
int AdviseWithHWND(
IntPtr hwnd,
[MarshalAs(UnmanagedType.IUnknown)] object pHandler,
out int pdwCookie
);
[PreserveSig]
int Unadvise(
int pdwCookie
);
[PreserveSig]
int Location(
out Rectangle prcInputPaneScreenLocation
);
}
static void Main(string[] args)
{
var inputPane = (IFrameworkInputPane)new FrameworkInputPane();
inputPane.Location(out var rect);
Console.WriteLine((rect.Width == 0 && rect.Height == 0) ? "Keyboard not visible" : "Keyboard visible");
}
}
}
It uses the IFrameworkInputPane interface (https://learn.microsoft.com/en-us/windows/desktop/api/shobjidl_core/nn-shobjidl_core-iframeworkinputpane)
I discovered yet another undocumented COM API that returns the position of the touch keyboard. It returns the bounds of the keyboard window or zeroes if the keyboard is hidden. I tested it in Windows 8.1, Windows 10 and Windows 10 Fall Creators Update and it works fine.
Now some bad news: in all versions prior to Fall Creators Update it only reports accurate results if the active window and the touch keyboard are located on the same monitor. If this is not the case - the API just returns the previous cached value. I'm guessing it has something to do with the fact that this API was meant to be used to calculate occlusion of the touch keyboard and your app's window. (It's called inside Windows::UI::ViewManagement::InputPane.get_OccludedRect() UWP API).
So if you don't care about supporting older versions or multi-monitor scenarios - use it. Otherwise I would suggest checking the Windows version and falling back to the previous method (GetIsOpenLegacy() from my other answer).
The API:
[ComImport, Guid("228826af-02e1-4226-a9e0-99a855e455a6")]
class ImmersiveShellBroker
{
}
[ComImport, Guid("9767060c-9476-42e2-8f7b-2f10fd13765c")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IImmersiveShellBroker
{
void Dummy();
IInputHostManagerBroker GetInputHostManagerBroker();
}
[ComImport, Guid("2166ee67-71df-4476-8394-0ced2ed05274")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IInputHostManagerBroker
{
void GetIhmLocation(out Rect rect, out DisplayMode mode);
}
[StructLayout(LayoutKind.Sequential)]
struct Rect
{
public int Left, Top, Right, Bottom;
}
enum DisplayMode
{
NotSupported = 0,
Floating = 2,
Docked = 3,
}
Usage example:
// do this once:
var brokerClass = new ImmersiveShellBroker();
var broker = (IImmersiveShellBroker)brokerClass;
var ihm = broker.GetInputHostManagerBroker();
Marshal.ReleaseComObject(broker);
// now ihm reference can be cached and used later:
Rect rect;
DisplayMode mode;
ihm.GetIhmLocation(out rect, out mode);
Note: looks like GetIhmLocation() always returns DisplayMode.NotSupported instead of the actual mode prior to Windows 10.

C# Screen size without references in interactive

I want to get the screen size of the primary screen, without adding any references (e.g. WinForms or Presentation). I found a similar question here, however there is no solution which doesn't include downloading or something like that.
But I want to make a method, which can be executed in the C# interactive on any other pc. Therefore I need a solution that doesn't reference other stuff than the standard (E.g. System, System.Core, ... is allowed).
I do know this is possible with
System.Windows.Forms.Screen.PrimaryScreen.Bounds;
but as this requires the System.Windows.Forms reference, it's not suitable for me. But basically the result of this snippet is what I want to get without references.
Here's an example I came up with.
I have noticed that it does not work correctly on High-DPI Screens. It will report the apparent resolution, not the actual resolution.
static void Main(string[] args)
{
var size = GetScreenSize();
Console.WriteLine(size.Length + " x " + size.Width);
Console.ReadLine();
}
static Size GetScreenSize()
{
return new Size(GetSystemMetrics(0), GetSystemMetrics(1));
}
struct Size
{
public Size(int l, int w)
{
Length = l;
Width = w;
}
public int Length { get; set; }
public int Width { get; set; }
}
[DllImport("User32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
public static extern int GetSystemMetrics(int nIndex);
If you don't want to use those libraries, You'll probably need to use native methods. I can't think of a way around this, as you'll need to communicate with the system any way you go.
A good place to start would be the source of System.Windows.Forms.Screen
Here's a link to the source. I bet you could strip down their code, and get the bare minimum.
I actually found a solution to this:
using System;
using System.Runtime.InteropServices;
static void Main()
{
EnumWindows(E, IntPtr.Zero);
Console.Write($"{_.Item1}x{_.Item2}");
}
struct R
{
int l;
int t;
public int r;
public int b;
public override string ToString() => $"{l},{t},{r},{b}";
public bool i() => l == 0 && r != 00;
}
static (int, int) _;
static bool E(IntPtr w, IntPtr l)
{
var r = new R();
GetWindowRect(w, ref r);
if (r.i() && _.Item1 == 0)
_ = (r.r, r.b);
return true;
}
delegate bool P(IntPtr w, IntPtr l);
[DllImport("user32.dll")]
static extern bool EnumWindows(P e, IntPtr l);
[DllImport("user32.dll")]
static extern bool GetWindowRect(IntPtr w, ref R r);
Main()
Paste this into your interactive and it should output the screen resolution - at least it does for me.
Don't ask me how it works, it's stumped together from different tutorials and pressed into the interactive. Therefore I can't guarantee this will work on every pc.
Could somebody else please test this?

Disable touch visual feedback on windows 8.1 (programmatically) [Desktop App]

I have a C# WPF application intended specifically for Win8.1 (a desktop app, NOT metro).
I want users to be able to use touch injections but I'm trying to disable the visualization feedback that windows creates for a Tap gesture Press Hold and Drag (like selecting multiple files on desktop) and other gestures (zooming scrolling etc).
After Searching the web for a long time I've found this post:
How do I disable Windows 8 touch contact visualizations for my application?
So I tried to do the same...
I tried this (Will put my Win32 class at the end)
public void DisableGestureVisualization()
{
const int SPI_SETCONTACTVISUALIZATION = 0x2019;
const int SPI_SETGESTUREVISUALIZATION = 0x201B;
ulong gv = 0;
Logger.Debug(!Win32.SystemParametersInfo(SPI_SETGESTUREVISUALIZATION, 0, ref gv, 0)
? #"Failed SystemParametersInfo SPI_SETGESTUREVISUALIZATION"
: #"Successfuly returned from SystemParametersInfo SPI_SETGESTUREVISUALIZATION");
Logger.Debug(!Win32.SystemParametersInfo(SPI_SETCONTACTVISUALIZATION, 0, ref gv, 0)
? #"Failed SystemParametersInfo SPI_SETCONTACTVISUALIZATION"
: #"Successfuly returned from SystemParametersInfo SPI_SETCONTACTVISUALIZATION");
}
And also this:
public void TryDisableWindowsVisualFeedback(IntPtr hWnd)
{
bool enable = false;
foreach (Win32.FEEDBACK_TYPE type in Enum.GetValues(typeof(Win32.FEEDBACK_TYPE)))
{
if (type == Win32.FEEDBACK_TYPE.FEEDBACK_MAX)
{
continue;
}
Logger.Debug(!Win32.SetWindowFeedbackSetting(hWnd, type, 0, 4, ref enable)
? #"Failed to SetWindowFeedbackSetting for " + type
: #"Successfuly returned from SetWindowFeedbackSetting for " + type);
}
}
And I call this from my WPF app like this:
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
Window window = Window.GetWindow(this);
var wih = new WindowInteropHelper(window);
IntPtr hWnd = wih.Handle;
TryDisableWindowsVisualFeedback(hWnd);
}
This is my auxiliary Win32 class:
internal class Win32
{
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SystemParametersInfo(
uint uiAction,
uint uiParam,
ref ulong pvParam,
uint fWinIni
);
public enum FEEDBACK_TYPE : uint
{
FEEDBACK_TOUCH_CONTACTVISUALIZATION = 1,
FEEDBACK_PEN_BARRELVISUALIZATION = 2,
FEEDBACK_PEN_TAP = 3,
FEEDBACK_PEN_DOUBLETAP = 4,
FEEDBACK_PEN_PRESSANDHOLD = 5,
FEEDBACK_PEN_RIGHTTAP = 6,
FEEDBACK_TOUCH_TAP = 7,
FEEDBACK_TOUCH_DOUBLETAP = 8,
FEEDBACK_TOUCH_PRESSANDHOLD = 9,
FEEDBACK_TOUCH_RIGHTTAP = 10,
FEEDBACK_GESTURE_PRESSANDTAP = 11,
FEEDBACK_MAX = 0xFFFFFFFF
}
[DllImport("user32.dll")]
public static extern bool SetWindowFeedbackSetting(
IntPtr hwnd,
FEEDBACK_TYPE feedback,
uint dwFlags,
uint size,
[In] ref bool configuration
);
}
Non of the above disabled the round gray tap visual feedback nor did it disable the small white circle that appears when holding and dragging.
I even tried using the C# example in the blog:
Windows.UI.Input.PointerVisualizationSettings.
GetForCurrentView().
IsContactFeedbackEnabled = false;
This code works for a metro app, so I tried This SO post and got the Windows namespace but when running the code I get
"An unhandled exception of type 'System.Exception' occurred in MyProg.exe
WinRT information: Element not found.
Additional information: Element not found."
From what I could figure out, the PointerVisualizationSettings is not supported from a desktop application so this way is doomed...
If anyone can help me with this issue, please do.
Thanks
I had a similar problem and I was able to remove my tap gesture feedback by adding
Stylus.IsTapFeedbackEnabled = "False" to my root window.
Your TryDisableWindowsVisualFeedback method looks like it has the wrong pinvoke signature so you may be setting the visual feedback instead of clearing it. The configuration argument is a BOOL* not a bool*, and BOOL is a 4 byte integer. You can fix this with the MarshalAs attribute:
[In , MarshalAs(UnmanagedType.Bool)] ref bool configuration
You can call GetWindowFeedbackSetting to confirm that it was set correctly.
With the right pinvoke and hWnd, SetWindowFeedbackSetting should work. I confirmed that it does for me in a native app. WPF handles touch a bit oddly. I wouldn't expect it to affect this, but I haven't looked at WPF in depth for several years.
For your other methods, the Windows.UI.Input classes are documented to work only in Windows Store apps, so errors calling them from a desktop app are expected. Under the covers they'll make the same changes as SetWindowFeedbackSetting.
Using SystemParametersInfo to affect global UI is overkill: you don't want to solve a local problem by causing a global one. That said, it would probably work if you fire change notifications. Using SetWindowFeedbackSetting to target just your window is a much better solution though.
I don't know if this would resolve the OP's original issue (or even makes a difference), but I can confirm that I have successfully disabled all touch related visual feedback for my own Control-derived class selectively with the following method (almost like the one suggested by the OP) - at least on my Windows 10 machine:
public class MyTouchControl: Control
{
// ...a lot of other touch related stuff going on...
enum FEEDBACK_TYPE
{
TOUCH_CONTACTVISUALIZATION = 1,
PEN_BARRELVISUALIZATION = 2,
PEN_TAP = 3,
PEN_DOUBLETAP = 4,
PEN_PRESSANDHOLD = 5,
PEN_RIGHTTAP = 6,
TOUCH_TAP = 7,
TOUCH_DOUBLETAP = 8,
TOUCH_PRESSANDHOLD = 9,
TOUCH_RIGHTTAP = 10,
GESTURE_PRESSANDTAP = 11
}
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetWindowFeedbackSetting(IntPtr hWnd, FEEDBACK_TYPE feedback, int dwFlags, int size, ref int config);
void disableAllTouchVisualFeedback()
{
int enable = 0;
foreach (FEEDBACK_TYPE type in Enum.GetValues(typeof(FEEDBACK_TYPE)))
{
SetWindowFeedbackSetting(Handle, type, 0, 4, ref enable);
}
}
protected override void OnHandleCreated(EventArgs e)
{
disableAllTouchVisualFeedback();
base.OnHandleCreated(e);
}
}

Controlling volume in C# using WMPLib in Windows

The story:
I'm writing a music player controlled by voice. Previously the project used winamp for music -- which I'd like to do away with. I'd like to integrate the voice control with music player. The problem is, when changing the volume property of my media player object (mplayer.settings.volume = 5;), it changes the MASTER volume. Meaning any voice feedback will be completely inaudible while music is playing. Not cool when you're driving. If I fire up windows media player, I can change the volume of the music without affecting the master volume.. so there has to be a way.
I've thought of maybe finding out if there's an equalizer control buried in there, but the documentation on that is pathetic. -- either that or my google-fu is weak.
So does anyone know how I would go about separating master and music volume with windows media player control?
Particulars:
Target machine is XP(sp3), with .NET 4.0 I believe. Also, this is a console app.
Thanks in advance for any help
I have tested this in Windows Media Player VER 12, so I guess for most people there is a much easier way than using "user32.dll":
private static WMPLib.WindowsMediaPlayer Player;
public static void VolumeUp()
{
if (Player.settings.volume < 90)
{
Player.settings.volume = (Player.settings.volume + 10);
}
}
public static void VolumeDown()
{
if (Player.settings.volume > 1)
{
Player.settings.volume = (Player.settings.volume - (Player.settings.volume / 2));
}
}
No doubt this has been supported for some time now. It does not change the Master Volume and only the Media Player Volume is changed. The Windows Master Volume is left alone.
Hope this helps others out there that are not limited to XP SP3.
The only way I found of doing this was using Interop and WM_APPCOMMAND windows message:
private const int APPCOMMAND_VOLUME_MUTE = 0x80000;
private const int WM_APPCOMMAND = 0x319;
private const int APPCOMMAND_MICROPHONE_VOLUME_UP = 26 * 65536;
private const int APPCOMMAND_MICROPHONE_VOLUME_DOWN = 25 * 65536;
[DllImport("user32.dll")]
public static extern IntPtr SendMessageW(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
private void SetMicVolume()
{
SendMessageW(new WindowInteropHelper(this).Handle, WM_APPCOMMAND, new (IntPtr)APPCOMMAND_MICROPHONE_VOLUME_UP);//or _DOWN
}

Categories