Sending CTRL-S message to a window

前端 未结 2 1810
挽巷
挽巷 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.

提交回复
热议问题