How to send CTRL+S to MS Word? - c#

I am working on a program that auto saves a Microsoft Office document after specific time (loop).
On a click of a button it will activate timer and after a given time delay it should send CTRL+S to Word and save the document.
Here is my code:
private void button1_Click(object sender, EventArgs e)
{
startTimer.Enabled = true;
stratTimer.Start();
}
private void startTimer_Tick(object sender, EventArgs e)
{
SendKeys.SendWait("^{s}");
MessageBox.Show("doc auto saved");
}
The problem is that SendKeys.Send("^{s}"); does not work.
How can I accomplish that?

SendKeys.SendWait sends keystrokes to the currently active window, so the keystrokes can be received by other window, like browser (if you are viewing this answer while the automation exe is running in the background). It is not a wise idea to send key strokes to arbitrary window.
This can partially explain why your code does not work in some cases. And it has other issues.
Just as MickyD's comment, don't use this "SendKeys" solution for automation nowadays. For auto save, VSTO is the right way to go.
See How to: Programmatically save documents.

Related

Revit API External Command freezing after WinForms Close() event

I am trying to create an external command for Revit that pops up a windows forms that has a single text box for the user to enter a description. After the user clicks Ok, the form closes but Revit gets stuck in a loading motion. It doesn't freeze, it just is constantly loading something. When I pause debugging, the code only made it to the line form.ShowDialog(). If I take out the showdialog and just run it without the form, it runs fine.
I'll post my relevant code snippets below. The form is in its own .cs, separate from the external command .cs but still under the same namespace.
Form click events code:
private void CancelForm(object sender, EventArgs e)
{
isReport = false;
this.DialogResult = DialogResult.Cancel;
Close();
}
private void SubmitForm(object sender, EventArgs e)
{
isReport = true;
reportDesc = descriptionBox.Text;
this.DialogResult = DialogResult.OK;
Close();
}
Execute command:
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
//Get application and document objects
UIApplication uiapp = commandData.Application;
Document doc = uiapp.ActiveUIDocument.Document;
ReportForm ticket = new ReportForm();
ticket.ShowDialog();
The code stops processing after showdialog. From what I could read on it, I thought it might have to do with focus on Revit after the form closing or the form not closing properly but couldn't figure out how to fix it.
Any help would be greatly appreciated!
Here is an old sample that creates a minimal Windows form on the fly, displays it as a modal form and closes successfully afterwards: The Schedule API and Access to Schedule Data. Maybe that will help. Maybe the debugger is interfering with the form closing somehow?
I ended up remaking the entire addin, made sure I was using Jeremy Tammik's Revit Addin Wizard to initiate it, and it started working. Not exactly sure what fixed it but guessing it was some error in the set up or such.

C# about sending simulated keyboard events to another APP

private void button3_Click(object sender, EventArgs e)
{
SetForegroundWindow(wndHandle);
SendKeys.SendWait("123");
}
I use WIN32 API ,use the Sendkey to achieve my target,but using the Sendkey has a disadvantage that "I have to SetForegroundWindow() before I use sendkey",it doesn't match my wish.
I want to click a button in the GUI which C# created, and then it will simulate the keyboard event to another app, and most important of all, I wish I don't have to set the window of app to be the ground window.
Does anyone have idea how to do it? I appreciate your help very much.
Does the target application must be currently active?

WebBrowser upload file - choose file dialog issue

I have a win forms app and I'm opening a webBrowser inside the app. I have to use the browser, since I'm automating the actual browser UI flow of the site. I hit a snag trying to upload a file. The input element type is "file" and, as I've discovered, the only way to populate it programatically is to hit the browse button and select the actual file from the "Choose File to Upload" dialog.
I found useful answers on the topic like:
Uploading Files Not Working - Need Assistance
I tried using the above solution, but my code doesn't move beyond file.InvokeMember("Click");. So basically, once the "Choose File to Upload" dialog opens, the code pauses and waits for the dialog to close. I'm not sure how to proceed from here. Would really appreciate help on this and maybe a better suggestion on dealing with <input type="file"..." elements.
I hope the following answer will help you. Add timer control to your form.
Before you invoke the click event to the upload file dialog, start the timer.
timer1.Interval = 3000;
timer1.Start();
file.InvokeMember("Click");
In the timer tick event add the following coding
private void timer1_Tick(object sender, EventArgs e)
{
try
{
timer1.Stop();
SendKeys.SendWait("D:\\testing.txt"); // enter the file path, which suppose to upload.
SendKeys.SendWait("{TAB 2}");
SendKeys.SendWait("{ENTER}");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}

how to auto focus an .Net winform application running in background

I have a weird problem, my .net win form application triggers a third party CRM application. When the customer is working with CRM application and clicks some button in my application, on first click the button does not trigger the event, only on the second click it responds.
The reason I suspect is that my application is not in focus.
I tried with the following code
private void XXXXX_MouseHover(object sender, EventArgs e)
{
this.BringToFront();
this.Focus();
}
But then its not working. I am new to .Net can any one point me how to fix this issue?
Any help is highly appreciated.
update: my toolstrip button.
btnbutton.Click += delegate(object sender, EventArgs e)
{
//some code to execute on button click.
};
Thanks
The .NET tool strip ignores clicks when the application doesn't have focus. This is just like how Words work. The idea here is that the user can click "anywhere" in the window without having to worry that he actually performs an action. Only when the window has focus will the click "count".
The post at http://blogs.msdn.com/b/rickbrew/archive/2006/01/09/511003.aspx describes how you can work around this. Basically, you inherit from ToolStrip and override the WndProc, and change the WM_MOUSEACTIVATE with the MA_ACTIVATEANDEAT result to the MA_ACTIVATE result.

How to persist from build programmatically?

I want to be able to load some information programmatically into Properties.Settings.Default before I publish it, but it doesn't persist. How do I overcome that?
I have (as a test):
private void button1_Click(object sender, EventArgs e)
{
Properties.Settings.Default.Setting1 = "abc";
Properties.Settings.Default.Save();
}
private void button2_Click(object sender, EventArgs e)
{
Text = Properties.Settings.Default.Setting1;
}
I clicked on button1, then published (with clickonce) and then run the published application and clicked on button2. The Text was empty.
If don't publish the application, rather just close it and reopen it and click on button2 – I get "abc".
See the following post http://www.codeproject.com/Articles/17659/How-To-Use-the-Settings-Class-in-C
publishing won't click the button for you.
You need to detect the setting isn't initialised correctly (compare with an application setting perhaps) and then set and save it yourself.
Blank / doesn't exist / = somesettingToUpgrade
and a little routine to find a setting by name, set and save then you could put that in the button click handler as well as say FormLoad.
It seems that the problem was that the scope was "user". But if the scope is "application" – it can't be changed programmatically.
So there seems not to be a way to do it. Persist from build programmatically, that is.

Categories