I am working on a C# application which consists of some context menus that have an ability to communicate with my website via WebClient(). The options work when they are clicked.
Once my app is opened, it stays open in the tray and it doesn't show in the taskbar/toolbar (the bar in the bottom where open programs stay). It's basically a background application that runs continuously.
There is a section in the context menu named Upload which includes Upload from Computer and Window screenshot. These are the two items that I want to be accessed via keyboard shortcuts. It shouldn't matter where the user is, once he clicks the set keyboard keys, he will trigger the application's _Click event for a certain context menu.
Final question: How do I make global keyboard shortcuts to trigger some context menus item _Click event?
It would be good is someone could explain a bit more broadly how to achieve this. I'm into C# for a short time (1 month learning it, 2 weeks using it) and I am having trouble understanding code just pasted here.
This is one of the click events I want to associate with a keyboard shortcut:
private void menu_upload_file_Click(object sender, EventArgs e)
{
DialogResult dialogOpened = openFileDialog1.ShowDialog();
if (dialogOpened == DialogResult.OK)
{
string filename = openFileDialog1.FileName;
this.sendToIMGit(filename);
}
}
Thanks.
You will need to use a 'keyboard hook' to create a global hotkey.
See this question.
Related
I am attempting to create my own context menu that shows when Word is in a custom 'mode'. To do this I want to disable all default context menus in favour of mine. This works perfectly when right-clicking text but not when right-clicking images or text boxes (seems to be objects in general). It looks like the event's Cancel parameter gets ignored when images are right-clicked, therefore it doesn't stop Word's context menu from showing.
Am I doing something wrong, or is this a bug in Word?
Does anyone have a solution for globally adding context menu items and hiding the rest?
Alternatives to my goal might also be the solution.
I have tried to use ribbon.xml but there are many different context menus with many different buttons, galleries etc which I would have to actively hide. Plus, I would have to duplicate a lot of XML to add my buttons to all these menus. In this pursuit, I have found the documentation for listing these context menu items lacking a complete list which has left me hunting for button idMso's. Also, if Microsoft were to add a new item, I would then have to release an update to actively remove the new item. The whole ribbon.xml way of dealing with context menus is a very difficult way of achieving what should be a simple request (in my opinion).
public partial class ThisAddIn
{
internal bool CustomContextMenuMode = true;
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
ThisAddIn.WordApplication.WindowBeforeRightClick += new Word.ApplicationEvents4_WindowBeforeRightClickEventHandler(Application_WindowBeforeRightClick);
}
private static void Application_WindowBeforeRightClick(Word.Selection Sel, ref bool Cancel)
{
if (CustomContextMenuMode == true)
{
MessageBox.Show("Context menu shows here!");
Cancel = true;
return;
}
Cancel = false;
}
}
If you right-click text (with or without a selection range), a table, or many other things, you will see that the message box shows. And when dismissed, the Cancel parameter prevents the default context menu from showing.
However, when an image is right-clicked, it shows the message box (like before) but when dismissed it still shows Word's image context menu.
Here is my Word version:
Office 365 Business,
Word version 1903 (build 11425.20204) or v16.0.11425.20200
Thank you in advance!
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 am currently working on updating a C# project that makes use of WinForms. One of the minor changes I want to make is as follows.
The project has a Form that currently allows the user to click a Button, which then opens a Folder Browser window where they can select a folder for the project to retrieve information from. The selected directory is entered into a TextBox after being selected. However, clicking on the TextBox also opens up a Folder Browser window. You are also currently unable to manually enter text into the TextBox.
What I want to do is (hopefully) pretty simple: I want the user to be able to enter a directory manually into the TextBox and for the project to accept that text input, and for the TextBox to not open a Folder Browser form upon being clicked.
Some other things to keep in mind:
I am not familiar with all the ins and outs of WinForms, so I could very well be missing something simple that I could do.
I am also in the process of completely restructuring the project, so if this is not possible in WinForms, but is possible in, say, WPF, that would not be a major obstacle for me in this case.
Here is the code for the Button, or at least the pertinent part, as a reference. txtProjectDir is the TextBox in question. Not much else is done with the TextBox in the code except for this part.
private void btnBrowse_Click(object sender, EventArgs e)
{
if (chooseProjectFolderDialog.ShowDialog() == DialogResult.OK)
{
clbConvertProjects.Items.Clear();
clbProjects.Items.Clear();
txtProjectDir.Text = chooseProjectFolderDialog.SelectedPath;
cur_projDir = txtProjectDir.Text;
Update: I have made some changes based on the input of several users (thanks to all of you, by the way). This is what the pertinent part of the code looks like now:
private void btnBrowse_Click(object sender, EventArgs e)
{
if (chooseProjectFolderDialog.ShowDialog() == DialogResult.OK)
{
clbConvertProjects.Items.Clear();
clbProjects.Items.Clear();
cur_projDir = txtProjectDir.Text;
I also had to change the TextBox to not be read-only, as well as remove a reference to the above method from its Event properties. Now it is able to accept user input, and doesn't open a Folder Browser when clicked into.
The only problem is this: if I only enter text directly into the TextBox, instead of selecting a folder via the browser popup, the program doesn't seem to properly accept the input (i.e., no information is being collected from the directory). Obviously, I still need to make the program accept user input, as it currently doesn't.
Update 2: After more suggestions (again, thanks guys) and good old trial-and-error, I have re-inserted the line txtProjectDir.Text = chooseProjectFolderDialog.SelectedPath; as removing it from the method had undesired effects on the program's functionality. I am still having an issue with the program accepting the user's manual input into the TextBox, though.
Update 3: As per #blaze_125's recommendation, I am going to have to create a new event for the TextBox when the user Leaves it. Thank you all for the help, I appreciate it!
However, clicking on the TextBox also opens up a Folder Browser window.
The only event for the TextBox is Action -> Click, which is set to btnBrowse_Click
What I want to do is (hopefully) pretty simple: I want the user to be able to enter a directory manually into the TextBox and for the project to accept that text input, and for the TextBox to not open a Folder Browser form upon being clicked.
If you don't want that event(aka action->click) to happen, then you must remove the text btnBrowse_Click from that textbox and leave it blank. That will remove the event you currently have linked to your textbox click.
There will be an even linked to the text box txtProjectDir to check this select the text box and in the properties select the lightning bolt.
I would assume that the even is a click into the textbox however.
If this is the case you probably want to remove this.
Now in terms of how to accept what is in the text box as the value you just want to reference the text and that is in the textbox whitch would be txtProjectDir.Text
private void btnBrowse_Click(object sender, EventArgs e)
{
if (chooseProjectFolderDialog.ShowDialog() == DialogResult.OK)
{
clbConvertProjects.Items.Clear();
clbProjects.Items.Clear();
cur_projDir = txtProjectDir.Text;
I am an Amateur Visual C# Programmer.
I want to implement the concept of I18N in my project.
(Similar to strings.xml in Android)
I have added 2 String Resources in my Resource File.
And I have added 2 Buttons in my form.
Now, I want the text of the Button to be the string value from the Resource file.
Please help.
Adhish
If you are using windows form, you can use this procedure.
Open the properties menu of the form in the design. Select the option "Language" and choose the language that you want.
Selecting a different language will create automatically a new file resource with the label for the language selected.
The file .resx will the same name of the form plus the initial of the language used.
It really depends on your UI framework. The following solution is for WinForms, but you can implement it (without MVVM) in WPF as well.
Create a button in the designer.
Register to the Load event of the form by double clicking it. (Right click on the form => properties => click the events button => search for the Load event)
In the load event, initialize the text of the button with the string from the resources.
Your code should look something like this:
private void Form1_Load(object sender, EventArgs e)
{
button1.Text = MyResources.ButtonText;
}
I'm trying to implement my own combobox like a lot of folks before me. What I want to accomplish is a combobox that filters and highlights items in the dropdown list while the user is typing in the combo textbox. The behaviour of a regular combobox after you click the arrow button is that the dropdown pops up and the focus stays in the textbox. This way you can start typing right away.
In order to customize the dropdown control you have to implement something from scratch. Most of the implementations that I've come across use either a Form or a ToolStripDropDown to host the custom control. Both are toplevel controls which means that you have to somehow close it yourself if the user clicks somewhere outside the dropdown. ToolStripDropDown does this automatically if AutoClose is true, but also somehow steals the combo textbox the focus on show if it is activated. A Form must be shown using ShowWithoutActivation() in order to prevent it from stealing the focus.
The problem is that the dropdown does never close unless I click somewhere within the dropdown and therefore activate it.
Another twist is that the combobox control is supposted to be hosted in an MFC application instead of a pure WinForms app.
The dropdown never being activated (gaining focus) is the main complication here. Otherwise you could just use the forms Deactivate event to hide it. The way to go here is to add an IMessageFilter to the WinForms application and catch mouse click messages. The message filter then determines whether the click took place outisde of the dropdown and closes it. If you are creating a WinForms application you are done.
Some extra work is necessary if you are for example in a MFC application hosting the control in a MFC window. In that case your IMessageFilter is useless. The reason is that the WinForms Application is never being run and therefore the event pump is never being invoked. Instead the MFC message pump does all the message handling. To solve this issue I've come accross a neat trick to activate the Application message pump in MFC applications.
In MFC applications there is usually an equivalent to the WinForms Application which is CWinApp (or CWinAppEx). The trick is to tap into the PreTranslateMessage method and serve the WinForms Application message pump before (or after) the MFC message pump:
BOOL CWinApp::PreTranslateMessage(MSG* pMsg)
{
if (FilterWindowsFormsMessages(pMsg))
{
return TRUE;
}
return CWinApp::PreTranslateMessage(pMsg);
}
BOOL CWinApp::FilterWindowsFormsMessages(MSG* pMsg)
{
Message message = Message::Create(IntPtr(pMsg->hwnd),
int(pMsg->message),
IntPtr((void*)pMsg->wParam),
IntPtr((void*)pMsg->wParam));
if (Application::FilterMessage(message))
{
return TRUE;
}
return FALSE;
}
This way the registered IMessageFilters are being served and everything works fine.