Sending CTRL-S message to a window

前端 未结 2 1795
挽巷
挽巷 2020-12-03 19:17

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

相关标签:
2条回答
  • 2020-12-03 19:50

    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.

    0 讨论(0)
  • 2020-12-03 19:53

    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.

    0 讨论(0)
提交回复
热议问题