Таким образом, существует прекрасный метод для получения перекрестного процесса с указателем 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