How to enable backspace key in IE extension - c#

I developed a Internet explorer extension using interfaces which are used in this project. All the things works perfectly except backspace capturing during the extension is focused. I have tried by changing IInputObject interface methods but no luck. Any suggestions for solve this.
IInputObject methods I have used are shown below. To be honest I don't know much about how this is working, If someone can explain the process it is also will be a great help.
public void UIActivateIO(int fActivate, ref NativeMethods.MSG msg)
{
if (fActivate != 0)
{
Control nextControl = base.GetNextControl(this, true);
if (Control.ModifierKeys == Keys.Back)
{
nextControl = base.GetNextControl(nextControl, false);
}
if (nextControl != null)
{
nextControl.Select();
}
base.Focus();
}
}
public int HasFocusIO()
{
if (!base.ContainsFocus)
{
return 1;
}
return 0;
}
public int TranslateAcceleratorIO(ref NativeMethods.MSG msg)
{
if ((msg.message == 256) && ((msg.wParam == 9) || (msg.wParam == 117)))
if (base.SelectNextControl(
base.ActiveControl,
Control.ModifierKeys != Keys.Back,
true,
true,
false))
{
return 0;
}
return 1;
}
Backspace is working with shift key but I wanted to make it work without modifier. I have seen that in this project they have used TranslateMessage (ref msg);DispatchMessage (ref msg); to implment that. I have tried that also but no luck. Any help to solve this will be great. (Most of the changes i have made to IInputObject methods seems like not effected eg: change of modifer key is not effected. It is an another issue that I am facing.)

Related

C# - Fallout4's Four Dragon - Bypassing Unhandled Exceptions?

Previous thread, in case y'all are curious.
Background info: Four Dragon is a C# wrapper for Fallout 4, allowing the use of C# scripts to modify the game, as well as allowing use of Papyrus (Skyrim and Fallout 4's scripting language) functions in the same C# script. The potential! THE POSSIBILITIES!
I concocted a script that runs the Papyrus functions GetPlayerGrabbedRef() and SetMotionType, which are used to make an in-game object freeze in place. Thanks to Metro Smurf, the script is much easier to read.
However, there is a rather...Blatant problem. The script registers for the F6 and F7 keys, but when F6 is pressed and the GetPlayerGrabbedRef() function is called, when the player has not grabbed a reference (a moveable in-game object), the following exception is outputted, causing the game to promptly exit:
FATAL ERROR Unhandled exception while executing FyTyTest.FreezeObject Void OnStaticTick()
Now, I've done some reading on how to handle unhandled exceptions, allowing the program (the Fallout 4 game in this case) to continue operation without closing via the try and catch functions, but I've not had any success; the exception still occurs, causing the game to exit when "OK" is clicked.
Alas, the various .log files that are outputted show no issue; it's as if everything functioned correctly.
Here is the latest incarnation of the script:
using System;
using System.Collections.Generic;
using Fallout;
public class FreezeObject : ScriptObject
{
public FreezeObject() { }
bool bGotObject = false;
ObjectReference ItemReference;
ObjectReference EmptyReference;
int itemValue;
public override void OnStaticTick()
{
base.OnStaticTick();
bool isF6 = Fallout.Keyboard.IsKeyJustUp(System.Windows.Forms.Keys.F6);
bool isF7 = Fallout.Keyboard.IsKeyJustUp(System.Windows.Forms.Keys.F7);
if(isF6)
{
try
{
ItemReference = Game.GetPlayerGrabbedRef();
itemValue = ItemReference.GetGoldValue();
if(ItemReference = EmptyReference)
{
// nothing else to do if we have a null reference
return;
}
}
catch
{
ItemReference = EmptyReference;
itemValue = -1;
return;
}
if (itemValue > -1)
{
bGotObject = true;
}
// nothing else to do; the next block is for F7
return;
}
if(isF7 && bGotObject && ItemReference != EmptyReference && itemValue > -1)
{
ItemReference.SetMotionType(2, true);
bGotObject = false;
}
}
}
So aye. How do I go about stopping an unhandled exception from crashing the game? Or is that just not possible?
Edit: As per Corey's suggestion, I put the try...catch functions around all the function-y code...No dice; the exception still appears, closing the game once the exception message is closed.
Here's the new script:
using System;
using System.Collections.Generic;
using Fallout;
public class FreezeObject : ScriptObject
{
public FreezeObject() { }
bool bGotObject = false;
ObjectReference ItemReference;
ObjectReference EmptyReference;
int itemValue;
public override void OnStaticTick()
{try
{
base.OnStaticTick();
bool isF6 = Fallout.Keyboard.IsKeyJustUp(System.Windows.Forms.Keys.F6);
bool isF7 = Fallout.Keyboard.IsKeyJustUp(System.Windows.Forms.Keys.F7);
if(isF6)
{
ItemReference = Game.GetPlayerGrabbedRef();
itemValue = ItemReference.GetGoldValue();
if(ItemReference == EmptyReference)
{
// nothing else to do if we have a null reference
return;
}
if (itemValue > -1)
{
bGotObject = true;
}
// nothing else to do; the next block is for F7
return;
}
if(isF7 && bGotObject && ItemReference != EmptyReference && itemValue > -1)
{
ItemReference.SetMotionType(2, true);
bGotObject = false;
}
}
catch
{
}
}
}
Four Dragon hosts its own AppDomain for the purpose of loading and executing user scripts. I haven't had many opportunities to work with custom hosts, so I don't know for sure, but I believe hosts have some control over the exception handling behavior. Assuming I'm right, I'd guess at that being the cause for your weird exception handling issues.
Your best best is to address the actual cause of the exceptions. In your code, you're checking for a null reference after you've already attempted to access a method on the object. You might want to try this:
if(isF6)
{
ItemReference = Game.GetPlayerGrabbedRef();
if(ItemReference != null && ItemReference.HandleExists())
{
itemValue = ItemReference.GetFormID();
if (itemValue != 0)
{
bGotObject = true;
}
}
// nothing else to do; the next block is for F7
return;
}
I changed your GetGoldValue() call to GetFormID() since you're using it to establish whether you've got a valid ObjectReference.
If you still have issues, I'd try to storing the form ID and using Game.GetForm(formid) to reacquire an object reference in the F7 block. You're relying on the assumption that the object reference remains valid between calls to OnStaticTick, which may not necessarily be the case. (still digging through Four Dragon's implementation, so I'm still unsure)
Edit: Disregard - object references apparently stay valid between events.

Validation Logic

I am trying to create some validation for a form I have. There are two text boxes and two radio buttons on the form. My logic for this validation I know is a little rusty at the moment so any suggestions would be great.
Here is the code for what I have so far:
Keep in mind that the int errors is a public variable in the class
Start Button code:
private void btnStart_Click(object sender, EventArgs e)
{
errors = validateForm();
//Here I want the user to be able to fix any errors where I am little
stuck on that logic at the moment
//validate the form
while (errors > 0)
{
validateForm();
errors = validateForm();
}
}
ValidateForm Method:
private int validateForm()
{
errors = 0;
//check the form if there are any unentered values
if (txtDest.Text == "")
{
errors++;
}
if (txtExt.Text == "")
{
errors++;
}
if (validateRadioBtns() == true)
{
errors++;
}
return errors;
}
ValidateRadioBtns Method:
private Boolean validateRadioBtns()
{
//flag - false: selected, true: none selected
Boolean blnFlag = false;
//both of the radio buttons are unchecked
if (radAll.Checked == false && radOther.Checked == false)
{
blnFlag = true;
}
//check if there is a value entered in the text box if other is checked
else if(radOther.Checked == true && txtExt.Text == "")
{
blnFlag = true;
}
return blnFlag;
}
Overall I feel like this can somehow be more stream lined which I am fairly stuck on.
Any suggestions would be greatly appreciated since I know this is such a nooby question.
Well first since you have said that you want to validate for non-entered values, did you consider white spaces as an entry? since someone can just press space and then your validation would pass.
Aside from that, you might want to indicate which textbox they did not fill out or which group they did not click, it seems like you are using web forms so here is a walkthrough http://msdn.microsoft.com/en-us/library/vstudio/a0z2h4sw(v=vs.100).aspx.
If you are using windows forms you can use this walkthrough http://msdn.microsoft.com/en-us/library/ms229603(v=vs.110).aspx.
If you need to keep the existing logic, I would suggest extracting the repeating logic into separate functions and temporary btnFlag is not necessary also as you can return true and return false at the end.
private Boolean validateRadioBtns()
{
if (radAll.Checked == false && radOther.Checked == false)
return true;
else if(radOther.Checked == true && txtExt.Text.Trim().Length == 0 ) //just a quick sample of how you can trim the spaces and check for length
return true;
return false;
}
See the documentation for the validation patterns. You have chosen the explicit validation strategy, for which you would use the ContainerControl.ValidateChildren method and either perform your "Start" action or not.
Windows Forms has dedicated events for validation that allow you to react accordingly for each of your controls. You'll use Control.Validating and Control.Validated events.
So, unless ValidateChildren returns true, you don't need to initiate your "Start" action, i.e. the logic would become trivial.
P.S. you also probably don't need the errors variable as a class member since you return it from your validation function. For showing the error, prefer the "Tell, Don't Ask" idea by separating the error visualization in a separate component.

KeyEventArgs to VirtualKeyCode

I'm trying to make use of the WindowsInputSimulator library to help me simulate keyPresses.
The software will consist of a client and a server. When a key is entered on the Client, it's KeyEventArgs are sent to the Server. The server then does the following with it:
public void SendKeyDown(Keys keyCode, Keys modifiers)
{
uint nonVK = MapVirtualKey((uint)keyCode, 2);
char mappedChar = Convert.ToChar(nonVK);
if (modifiers.Equals(Keys.None))
{
VirtualKeyCode vkc;
if (Enum.TryParse(VkKeyScan(mappedChar).ToString(), out vkc))
{
InputSimulator.SimulateKeyDown(vkc);
}
}
else
{
//Find out which modifier we're working with.
uint modVK = MapVirtualKey((uint)modifiers, 2);
char modifierChar = Convert.ToChar(modVK);
VirtualKeyCode vkc, modVkc;
if (Enum.TryParse(VkKeyScan(mappedChar).ToString(), out vkc)
&& Enum.TryParse(VkKeyScan(modifierChar).ToString(), out modVkc))
{
InputSimulator.SimulateModifiedKeyStroke(modVkc, vkc);
}
}
}
Which works for single keys. However, I'm trying to work with modifier keys as well, and I'm running in to some trouble. For example, pressing SHIFT + K produces "k2" Which leads me to believe either my transation into VirtualKeyCodes is wonky, or something else is.
Also, when sending these commands, should I catch only the KeyDown / KeyUp events? Or should I also watch for the KeyPress event? I should be able to wrok with arrow keys and non-Character keys as well, which makes me think I should just ignore the KeyPress.
EDIT: Also, how would I know when I'm working with multiple modifiers? How should I be stringing them together?
Thoughts? Thanks!
I was able to get it working with the following. Keep in mind this works for a SINGLE modifier, and a single CHARACTER. Special characters don't yet work with this code, but I figure it's a step in the right direction, and answered my immediate question.
public void SendKey(int keyValue, Keys modifiers)
{
VirtualKeyCode key;
if (modifiers.Equals(Keys.None))
{
if (Enum.TryParse(VkKeyScan(((char)keyValue)).ToString(), out key))
{
InputSimulator.SimulateKeyDown(key);
InputSimulator.SimulateKeyUp(key);
}
}
else if (modifiers.Equals(Keys.Shift) && keyValue >= (int)Keys.A && keyValue <= (int)Keys.Z)
{
if (Enum.TryParse(VkKeyScan(((char) keyValue)).ToString(), out key))
{
InputSimulator.SimulateModifiedKeyStroke(VirtualKeyCode.SHIFT, key);
}
}
else if (modifiers.Equals(Keys.Control) && keyValue >= (int)Keys.A && keyValue <= (int)Keys.Z)
{
if (Enum.TryParse(VkKeyScan(((char)keyValue)).ToString(), out key))
{
InputSimulator.SimulateModifiedKeyStroke(VirtualKeyCode.CONTROL, key);
}
}
else if (modifiers.Equals(Keys.Alt) && keyValue >= (int)Keys.A && keyValue <= (int)Keys.Z)
{
if (Enum.TryParse(VkKeyScan(((char)keyValue)).ToString(), out key))
{
//Alt is named MENU for legacy purposes.
InputSimulator.SimulateModifiedKeyStroke(VirtualKeyCode.MENU, key);
}
}
}

Save System.Windows.Forms.Keys as Setting

I'm making a program that uses hotkeys for various things.
These hotkeys will be user-settable, and thus it'd be nice if those would be saved on exit.
Since the amount of keys on a keyboard is pretty large (including the OEM keys and such), I don't feel much warmth towards a huge monstrosity of IF clausules.
I tried using the builtin settings thingamajigg (Properties.Settings.Default etc) But it doesn't seem to save the keys properly. (That or I'm doing something wrong.)
This is the code I'm using for that right now:
// (..some code ommitted)
if (comboBox_hotkeys_uploadclipboard_modifier.SelectedText != "" && comboBox_hotkeys_uploadclipboard_key.SelectedText != "")
{
if (comboBox_hotkeys_uploadclipboard_modifier.SelectedText == "None")
Properties.Settings.Default.hotkeys_uploadclipboard_modifier = 0;
else
Properties.Settings.Default.hotkeys_uploadclipboard_modifier = modifierdict[comboBox_hotkeys_uploadclipboard_modifier.SelectedText];
Properties.Settings.Default.hotkeys_uploadclipboard_key = keydict[comboBox_hotkeys_uploadclipboard_key.SelectedText];
}
Properties.Settings.Default.Save();
return true;
And at the beginning of the program i do:
Dictionary<string, uint> modifierdict = new Dictionary<string, uint>();
Dictionary<string, Keys> keydict = new Dictionary<string, Keys>();
public Form_stuff()
{
for (int i = 0; i < Enum.GetNames(typeof(ModifierKeysH)).Length; i++)
{
modifierdict.Add(Enum.GetNames(typeof(ModifierKeysH))[i], (uint)Enum.GetValues(typeof(ModifierKeysH)).GetValue(i));
}
for (int i = 0; i < Enum.GetNames(typeof(Keys)).Length; i++)
{
keydict.Add(Enum.GetNames(typeof(Keys))[i], (Keys)Enum.GetValues(typeof(Keys)).GetValue(i));
}
}
But, it doesn't seem to actually save the keys, or load them on the next program launch. (yes I have code in place for that part too)
Does anyone know a(n easy) way?
EDIT:
Here's the code i use for setting the hotkeys, without the interop parts etc, those are hosted elsewhere in the code:
public void SetKeyboardHooks()
{
if (!(kbhook == null))
kbhook.Dispose();
kbhook = new KeyboardHook();
//Set clipboard upload hotkey
kbhook.RegisterHotKey((ModifierKeysH)Properties.Settings.Default.hotkeys_uploadclipboard_modifier, Properties.Settings.Default.hotkeys_uploadclipboard_key);
kbhook.KeyPressed += new EventHandler<KeyPressedEventArgs>(kbhook_KeyPressed);
}
void kbhook_KeyPressed(object sender, KeyPressedEventArgs e)
{
if (e.Modifier == (ModifierKeysH)Properties.Settings.Default.hotkeys_uploadclipboard_modifier && e.Key == Properties.Settings.Default.hotkeys_uploadclipboard_key)
{
string url = Functions.UploadClipboard();
Clipboard.SetText(url);
hificon.ShowBalloonTip(5000, "Upload succesful!", "Uploaded to: " + url,ToolTipIcon.Info);
}
}
As you can see the code is far from finished. This is just a roadblock here i'm trying to overcome..
The main thing that doesn't seem to be working is the fact that the hotkeys don't actually get SAVED. settings doesn't seem to like System.Windows.Forms.Keys, and then also skips the ModifierkeysH part, which are saved as uint.
False alarm people, it works just like it should, except for some reason the Comboboxes didn't return a value with .SelectedValue, instead you have to use .SelectedItem for some reason.
In any case, it works flawlessly now. thanks for everyone's time and may this thread slap someone in the face in the future for not using .SelectedItem .

Is there any C# implementation or way to have a textbox that takes a key sequence as input?

I have an implementation which hooks into the keydown event, which suppresses the keypress event and does some magic. Now I want to show something more friendly than "ControlKey" etc, so there's a switch you can see in the code below. Except I've realised things like the number keys along the top end up as D1, D2, etc., and then there's things like Add showing up for the numpad +. In addition, Print Screen doesn't seem to be recognised.
Is there something I'm missing?
This is a hard question for me to describe fluently, but hopefully you get what I mean. If not I guess I'll be replying to comments and improving this as I go.
private int numKeys = 0;
private List<int> shortcutKeys = new List<int>();
private void textBoxRegionKeys_Click(object sender, EventArgs e)
{
textBoxRegionKeys.SelectAll();
}
private void textBoxRegionKeys_KeyDown(object sender, KeyEventArgs e)
{
// There are certain keys we want to ignore...
if (e.KeyCode != Keys.Delete && e.KeyCode != Keys.Back)
{
// We can handle this ourselves, thanks
e.SuppressKeyPress = true;
// Shortern what we show
string ret = e.KeyCode.ToString();
switch (ret)
{
case "ControlKey": ret = "Ctrl"; break;
case "ShiftKey": ret = "Shift"; break;
case "Menu": ret = "Alt"; break;
}
// If we haven't selected anything, we should be appending
if (textBoxRegionKeys.SelectionLength == 0)
{
if (numKeys > 0)
{
// Does our key already exist in the list?
if (shortcutKeys.Exists(x => x == e.KeyValue))
{
return;
}
textBoxRegionKeys.Text += " + ";
}
textBoxRegionKeys.Text += ret;
shortcutKeys.Add(e.KeyValue);
numKeys++;
}
else
{
textBoxRegionKeys.Text = ret;
shortcutKeys.Clear();
shortcutKeys.Add(e.KeyValue);
numKeys = 1;
}
}
}
The TextBox KeyDown/KeyPress etc will only be raised for keys that may be accepted as input in to the text box (and associated modifiers). As such, you will not see keys handled such as Print Screen etc. The best option I can think of is not ideal, but you could override the ProcessKeyPreview or some other Form level Message interceptor to get notified of ANY key press. Something like...
protected override bool ProcessKeyPreview(ref Message m)
{
var keyCode = (Keys)Enum.ToObject(typeof (Keys), m.WParam);
//Insert some logic
return base.ProcessKeyPreview(ref m);
}
Of course, this method will be invoked whenever the FORM has focus, and a key is pressed, so you would have to filter down by doing some form of check (which again is not ideal)
if(ReferenceEquals(ActiveControl, textBoxRegionKeys)) {}
Which if your dealing with things like UserControls will be very unreliable.
As for formatting in to nice friendly messages, I think you basically you will need your own map of special characters... I am not aware of any Globalized lookup for Keys. I will dig a little and update the answer if I find something.
Edit
Did a little digging and couldn't find anything obvious for nice key mappings. I would just create a map of "friendly" key names:
private static readonly Dictionary<Keys, String> KeysMap = new Dictionary<Keys, String>
{
{ Keys.D1, "1"},
{ Keys.D9, "9"}
};
And do something like:
String friendlyKeyCode;
if (!KeysMap.TryGetValue(keyCode, out friendlyKeyCode))
friendlyKeyCode = keyCode.ToString();
Personally, I find this approach better than a massive switch... but that works too.

Categories