Reputation: 13755
I'm trying to do the following in C#:
Here's what I got
Process p = new Process();
p.StartInfo.Filename = "notepad.exe";
p.Start();
// use the user32.dll SetForegroundWindow method
SetForegroundWindow( p.MainWindowHandle ); // make sure notepad has focus
SendKeys.SendWait( "some text" );
SendKeys.SendWait( "%f" ); // send ALT+f
SendKeys.SendWait( "x" ); // send x = exit
// a confirmation dialog appears
All this works just as expected, but now after I've sent ALT+f+x I get a "Do you want to save changed to Untitled" dialog and I would like to close it from within my applications by "pressing" 'n' for "Don't Save". However
SendKeys.SendWait( "n" );
works only if my application has not lost focus (after ALT+f+x). If it did and I try to go back using
SetForegroundWindow( p.MainWindowHandle );
this sets the focus to the main notepad window instead of the confirmation dialog. I used the GetForegroundWindow
method from user32.dll and found out that the dialog handle is different than the notepad handle (which kinda makes sence) but SetForegroundWindow
doesn't work with even with the dialog window handle
Any idea how I can give the focus back to the dialog so that I can successfully use SendKeys
?
here's the full code
[DllImport("user32.dll")]
static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
[DllImport("User32.DLL")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
public const int SW_RESTORE = 9;
...
Process p = new Process();
p.StartInfo.FileName = "notepad.exe";
p.Start();
Thread.Sleep( 1000 );
SendKeys.SendWait( "some text" );
SendKeys.SendWait( "%f" ); // send ALT+F
SendKeys.SendWait( "x" ); // send x = exit
IntPtr dialogHandle = GetForegroundWindow();
System.Diagnostics.Trace.WriteLine( "notepad handle: " + p.MainWindowHandle );
System.Diagnostics.Trace.WriteLine( "dialog handle: " + dialogHandle );
Thread.Sleep( 5000 ); // switch to a different application to lose focus
SetForegroundWindow( p.MainWindowHandle );
ShowWindow( dialogHandle, SW_RESTORE );
Thread.Sleep( 1000 );
SendKeys.SendWait( "n" );
Thank you
Upvotes: 2
Views: 6703
Reputation: 16464
You can't give what you don't have - SetForegroundWindow()
only works if your application currently has the focus.
Modern Windows versions prevent applications from stealing focus, as that was a major annoyance back in the Windows 9x days.
Also, 'Alt+F, x' only refers to exit on English Windows versions, it won't work on most other languages. Avoid using SendKeys()
, it's impossible to use in a reliable way.
Upvotes: 2