I am building a Word VSTO Add-in. There I have a side drawer with some buttons on it. Now when I click on a button it inserts a predefined text in a document selection position. When it inserts the text I would like to bring back focus to the document itself.
How to do that?
My best try so far:
Word.Selection currentSelection = Application.Selection;
currentSelection.Text = ((Button)sender).Tag.ToString();
Application.ActiveWindow.SetFocus();
Application.ActiveWindow.Activate();
It makes sense to call the Activate method prior calling the SetFocus one:
Word.Selection currentSelection = Application.Selection;
currentSelection.Text = ((Button)sender).Tag.ToString();
Application.ActiveWindow.Activate();
Application.ActiveWindow.SetFocus();
Also you may find Windows API functions helpful for such scenarios. For example, the SetForegroundWindow function which brings the thread that created the specified window into the foreground and activates the window. Keyboard input is directed to the window, and various visual cues are changed for the user. You may find the Win32: Bring a window to top thread helpful.
Try Application.ActiveDocument.Activate.
Related
Currently I used this snip code as a result from googling.
var eventArgs = new TextCompositionEventArgs(Keyboard.PrimaryDevice,
new TextComposition(InputManager.Current, Keyboard.FocusedElement, "A"));
eventArgs.RoutedEvent = TextInputEvent;
var flag = InputManager.Current.ProcessInput(eventArgs);
It was working if I used Keyboard.Focus(TxtBox); and the TxtBox will be filled with the Keystroke.
But what I want really achieved is:
1.Drawing a box (for example, I draw box on one of the excel cell)
2.Click on the box coordinate (to change Keyboard Focus)
3.Send Keystroke to clicked excel cell
I have done step 1 and 2.
But I can't find a way to do the third step.
Somehow, the click event (using mouse event) maybe not changing Keyboard Focus automatically.
So, how do I change Keyboard focus, if possible using coordinate ?
Or maybe can I get IInputElement from a coordinate ? and then set keyboard focus to it.
Of course, all of it outside from the main application window of the WPF.
Found it !
At:
Installed InputSimulator via NuGet, no members accessible
It is working in most cases.
I said in most cases, because it is able to type in other window like excel application, but on other custom app window. There might be a case it won't work.
Hope it help for other people, looking for the same thing.
I have made a custom MessageBox for my application and it launches as a UserControl. I have two buttons inside it and I would like to allow users to press Tab to switch between Buttons. However, since it's a UserControl overlaying the content, Pressing tab more than twice makes the focus go in the background on elements that aren't supposed to be tabbed at.
I can't figure out a good idea how to prevent this, I've thought of making a method that will select all elements and make their IsTabStop values to false and then restore them later, but I think that would be more of a problem then a solution.
Is there a way around this to limit tabbing only to the UserControl?
I would also appreciate advice on working with the message box.. the whole messagebox is an async function that has an infinitive loop until the answer is given. Is there another way to stop the application until one of the message box options was selected?
Crowcoder's reference has lead to correct MSDN page where I found my solution:
dialog = new UCMessageBox("Are you sure you want to exit the application?", MBType.YesNo);
AppMessageBox.Children.Add(dialog);
KeyboardNavigation.SetTabNavigation(dialog, KeyboardNavigationMode.Cycle);
The key was to call .SetTabNavigation function and direct it to my dialog (custom UserControl for the message box) and setting the KeyboardNavigationMode to Cycle.
After closing the UC rest of the application continued normally regarding navigation.
I haven't been able to find an example containing this functionality, and either i missed it in the documentation or it's not there.
I have a fullscreen GUI program, and when a user is required to type in a number, a calculator window popup has to appear in the center of the screen. The user types a number and clicks on enter, or hits cancel to continue past the window.
The problem is clicking on the fullscreen window behind the calculator brings that window to the front and hides the calculator without the intended entry being completed, which could get annoying for the user.
I guess the functionality I'm trying to create is what happens in most text editors/IDE's when you press the Open File button. Let me know if you want to see code, it's just two separate Window classes at the moment.
The Present() function of the Window object brings that particular window to the front. So adding a FocusOutEvent listener on the window you wish to keep in front like:
windowObj.FocusOutEvent += (obj, args) => windowObj.Present();
will work.
The alternative to this (and the better way) is to set the Modal property of the window to true.
If you've stumbled across this and you were looking for a popup window that suspends whatever called it to wait for input, see this question:
gtk# thread for window
You basically use the Dialog class instead of Window and add your elements to the ActionArea of the Dialog.
Hope this helps.
i want to get the handle of the textbox where the caret is in, in another program. all i can find is how to get the list of the controls in a window with "EnumChildWindows", and then to search for "edit" control.. (and it doesn't work for all the program that have textbox).
i have no idea how to find the one that the caret is in and the user is writing in.
i really got stuck with it.. :(
thanx alot,
Shiran.
You'll need to jump through several pinvoke hoops. Start with GetForegroundWindow() to get the handle of the active toplevel window. Then GetThreadWindowProcessId() to obtain the ID of the thread that owns that window. Then finally GetGUIThreadInfo(), it returns a bunch of into about the windows owned by the thread. The GUITHREADINFO.hwndCaret member gives you the handle to the window that owns the caret. It doesn't have to be a text box btw.
Visit pinvoke.net for the declarations you'll need.
I have textbox inside a usercontrol and I add the usercontrol to the MainWindow with the following XAML:
<Views:MyUserControl />
I have one TextBox in MyUserControl, the problem is that the TextBox doesn't take any input. Backspace och space works, but if I press the letter och numbers no text is added to the TextBox.
I have made sure that the text is not just hidden in the TextBox.
I have also tried to add a RichTextBox to MyUserControl with the same result, it doens't take any input (beside space och backspace).
I have also tried to add a TextBox to the MainWindow with the same result; it doens't take any input (beside space och backspace).
Also MyUserControl is added in a TabControl and TabItem.
Any clues?
Edit: Additional information
Forgot to write that I'm opening/creating the WPF Window from a WinForm application.
When I set my startup project in VS10 to be my WPF-project it work great with the keyboard input to the TextBox.
How come?
Im opening/creating my WPF windows with the following code:
MyWpfProject.MainWindow mw = new MyWpfProject.MainWindow();
mw.Show();
Edit: Solution
So I guess my real problem was that is was opening the WPf project from a WinForms application.
I added the following code:
MyWpfProject.MainWindow mw = new MyWpfProject.MainWindow();
ElementHost.EnableModelessKeyboardInterop(mw);
mw.Show();
"The EnableModelessKeyboardInterop() call is necessary to handle keyboard input in the WPF window if loaded from a non-WPF host like WinForms."
http://weblogs.asp.net/jdanforth/archive/2008/07/29/open-a-wpf-window-from-winforms.aspx
Answer to my own question (if someone else run into the same problem):
If you open a WPF-form from a WinForms application you have to do the following to get keyboard input:
MyWpfProject.MainWindow mw = new MyWpfProject.MainWindow();
ElementHost.EnableModelessKeyboardInterop(mw);
mw.Show();
"The EnableModelessKeyboardInterop() call is necessary to handle keyboard input in the WPF window if loaded from a non-WPF host like WinForms." http://weblogs.asp.net/jdanforth/archive/2008/07/29/open-a-wpf-window-from-winforms.aspx
maybe your user control is getting the keyboard event instead of your textbox? try to search in this way, it happens with mouse buttons.
I had the same problem but my Environment was built such that I could not apply the solution above. As it turned out that wasn't the problem. It was much more easier than expected.
I host a WPF User Control inside WinForms. My WinForms MainView (Startup form) did override the "ProcessCmdKey". Because of logical errors it returned nothing.
Nevertheless I received all key events in code behind in my XAML file but this events never updated the "Text" of my text box. Only space and backwards did so and this were the key events I didn't receive in code behind.
So in case you don't think of the simplest solution here it is for VB.NET.
STRG+F "ProcessCmdKey" and make sure that you Return the correct value of you may completely uncomment it just to verify that it isn't causing you the same trouble as it did to me.
I would like to add my own answer just on the off chance it can help anyone else with the same or similar problems. My particular use case was a .Net windows form created by an addin. The addin was running out of Autodesk Inventor which I think may be WPF (but don't take my word for it.) The addin had several windows forms some docked within the application and with some acting as popups or a separate secondary window. The solution was to set the windows forms owner to one of the docked forms. Doing this allowed text to be edited and entered into its textboxes. Very niche solution to a niche problem but hopefully it may help someone at some point in the future.
private void CreatePanels(DockableWindows DockableWindows)
{
//Create the dockable window that the panel form will live on.
DockableWindow SideWindow =
DockableWindows.Add(SidePanelNames.GUID, SidePanelNames.InternalWindowName, SidePanelNames.Title);
//Configure the windows settings.
SideWindow.ShowTitleBar = true;
SideWindow.ShowVisibilityCheckBox = true;
SideWindow.DisableCloseButton = false;
SideWindow.Visible = true;
SideWindow.AddChild(SidePanel.Handle); //Add the forms as children and then display to the user.
SidePanel.Show(); //Display the panel to the user.
}
/// <summary>
/// Creates the Display window were order and patient information is displayed to the user.
/// This method makes the adjust device form the owner of the display window. Because of this
/// dependecency it should be run after the panels have been created.
/// </summary>
private void CreateDisplayWindow()
{
DisplayForm = new DisplayForm //Create the display form.
{
Owner = SidePanel //Doing this allows text boxes to have values entered into them.
};
DisplayForm.Show(); //Show the display form to the user.
}
//Adding the side side panel as the owner of the display form was effectively the only change I needed to make.
I will add a few words of warning for anyone attempting this solution. Simply put I've since found out it's not great. It prevents the form or any of its controls from detecting certain key presses (enter and tab) which matters a lot for my usage. You'll find a much better and solution here https://forums.autodesk.com/t5/inventor-forum/dockable-window-with-wpf-controls-don-t-receive-keyboard-input/td-p/9115997