2

A process is identified by filtering parent process ID numbers, when the correct process is found that should receive a keystroke. This application is an Excel workbook. A macro is run inside this application that requires the keystroke. The provider of the macro cannot change this behaviour.

This user form showing up when the macro finishes inhibits automation due to its manual input requirement.

I have tried a couple of different approaches to send the return key, but they failed. The most promising is below:

[DllImport("User32.dll")]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("User32.dll")]
static extern int SetForegroundWindow(IntPtr hWnd);

//...then at the bottom of my script

//p is the Excel process selected from a bunch of Excel workbooks
IntPtr ptrFF = p.Handle;
SetForegroundWindow(ptrFF);
SendKeys.Send("{w 3}");          //<- it falls over at this stage            

The error message is:

"SendKeys cannot run inside this application because the application is not handling Windows messages. Either change the application to handle messages, or use the SendKeys.SendWait method."

If I use the

SendKeys.SendWait("{w 3}"); 

command then it seems all right, but the keystroke does not get to its desired destination somehow.

Do you have any idea how to find a workaround of this issue with the Excel macro either by sendkeys or other ways?

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Pydan
  • 57
  • 10
  • 4
    Possible duplicate of [Simulating Key Press c#](https://stackoverflow.com/questions/3047375/simulating-key-press-c-sharp) – Deniz Jun 15 '18 at 09:25
  • This may not be duplicate as suggested as the OP is asking to send a keypress to Excel, not their own C# application, so they do not have control of the Excel executable therefore unable to tell it to handle Windows messages. I could be wrong but wanted to heads-up on this. – Rich Bianco Jun 15 '18 at 18:49

2 Answers2

1

Works for nearly every window (beside some Java windows) + the window has not to be in focus:

Also here a usefull list of Virtual Key Codes

        [DllImport("user32.dll")]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll")]
        static extern bool PostMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam);

        private void button1_Click(object sender, EventArgs e)
        {
            const int WM_SYSKEYDOWN = 0x0104;
            const int VK_SPACE = 0x20;

            IntPtr WindowToFind = FindWindow(null, "WINDOW NAME");

            PostMessage(WindowToFind, WM_SYSKEYDOWN, VK_SPACE, 0);
        }
Deniz
  • 429
  • 1
  • 4
  • 19
0

The only flaw of this solution that it does not send keystrokes to Excel User Form. And that is the ultimate goal of the venture.

It turned out that the solution is fairly simple. This

IntPtr ptrFF = p.Handle;

had to be changed to

IntPtr ptrFF = p.MainWindowHandle

Although I am not quite sure why this solved my problem, but it work apparently with notepad and Excel, so it seems to be a solution.

Pydan
  • 57
  • 10