В C # можно получить доступ и изменить насос сообщений Windows, чтобы ответить на WM_GETOBJECT? - PullRequest
0 голосов
/ 30 октября 2018

Таким образом, существует прекрасный метод для получения перекрестного процесса с указателем COM (той же машины) из сеанса Excel.exe, если вы знаете его Hwnd с помощью API-интерфейса Accessibility. Специальная функция Windows API - AccessibleObjectFromWindow ; если вызывается с параметром OBJID_NATIVEOM, то Excel.exe отправляет COM-указатель на объект Excel.Window. Очень круто.

Так что мне было интересно, могут ли разработчики реализовать такую ​​же технику для своих приложений. Ответ - да, они отвечают на определенное сообщение WM_GETOBJECT в своем коде сообщения. Хотя это выполнимо для приложения C ++, я озадачен тем, как это сделать для приложения C #.

Я предполагаю, что ответ - сделать что-то, чтобы получить доступ к коду обработки сообщений и изменить его. Это может быть случай, когда какой-то магический атрибут может быть использован Я открыт для любой техники, пока она работает.

Вот код, который получает указатель COM из Excel

    [DllImport("user32.dll", SetLastError = true)]
    static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);


    [DllImport("oleacc.dll", SetLastError = true)]
    internal static extern int AccessibleObjectFromWindow(IntPtr hwnd, uint id, ref Guid iid,
                                                [In, Out, MarshalAs(UnmanagedType.IUnknown)] ref object ppvObject);

    bool IXlMoniker.GetExcelByHwnd(int lhwndApp2, ref object appRetVal)
    {
        bool bRetVal = false;

        IntPtr lhwndApp = (IntPtr)lhwndApp2;

        IntPtr lHwndDesk = FindWindowEx(lhwndApp, IntPtr.Zero, "XLDESK", "");
        if (lHwndDesk != IntPtr.Zero)
        {

            IntPtr lHwndExcel7 = FindWindowEx(lHwndDesk, IntPtr.Zero, "EXCEL7", null);
            if (lHwndExcel7 != IntPtr.Zero)
            {
                Guid IID_IDispatch = new Guid("{00020400-0000-0000-C000-000000000046}");
                const uint OBJID_NATIVEOM = 0xFFFFFFF0;
                object app = null;
                if (AccessibleObjectFromWindow(lHwndExcel7, OBJID_NATIVEOM, ref IID_IDispatch, ref app) == 0)
                {
                    dynamic appWindow = app;
                    appRetVal = appWindow.Application;
                    return true;
                }
            }
        }
        return bRetVal;
    }

Это выглядит многообещающе Вернуть IOleCommandTarget из обработки WM_GETOBJECT в NativeWindow

...