I want to save a TextPad window using C# code; I can find out the handle of the window but not sure how to send CTRL - S to that window. I want to use P/Invoke API to achiev
I needed to do exactly what you need to do, call a Ctrl+S in some background window, after about a day of research there seem to be many ways of achieving this.
For instance to press Alt-F then a 'S' you can call:
PostMessage(handle, 0x0112, 0xF100, 0x0046);
PostMessage(handle, 0x0102, 0x0053, 0);
The Alt-F part works on background windows, while the subsequent 'S' does not.
Another way of doing this is with WM_COMMAND and WM_MENUSELECT, MF_MOUSESELECT:
IntPtr menu = GetMenu(handle);
IntPtr subMenu = GetSubMenu(menu, 0);//0 = first menu item
uint menuItemID = GetMenuItemID(subMenu, 2);//2 = second item in submenu
SendMessage(handle, 0x0111, 0x20000000 + menuItemID, menu);
Finally and somewhat ironically the simples solution is to call WM_COMMAND with the menuItemID:
PostMessage(handle, 0x0111, 0x0003, 0x0);
The 0x0003 (save in notepad) is determined by the app and it's menu structure, you can get this code by listening to WM_COMMAND in spy++ on the window while you either use the combo key combination or press the mouse button on the menu command.
It seems it's also possible to use WM_SYSKEYUP/DOWN and WM_MENUCOMMAND, also keys like Ctrl-C, Ctrl-V have constant defined values and can be passed as one character, but only to apps that listen to these hardcoded chars...
Thanks for the starting point.
You cannot use SendMessage (or PostMessage, the correct one) to simulate the state of the modifiers keys, like CTRL. You must use SendInput().
A keystroke like Ctrl+S is not untypically translated into a WM_COMMAND message. Use the Spy++ tool to see what happens when you type Ctrl+S by hand. If you see WM_COMMAND then you're golden, you can use SendMessage() to send that message. This will of course only work on a specific process.