imho.ws
IMHO.WS  

Вернуться   IMHO.WS > Компьютеры > Программирование
Опции темы
Старый 17.05.2007, 15:22     # 1
bart_s
Newbie
 
Регистрация: 17.05.2007
Сообщения: 14

bart_s Путь к славе только начался
C# и MAPI

Пишу програмку для работы с Outook 2003/2007
Как можно из С# используя MAPI получить объект Inspector?

Обычный метод это:
Outlook.Application oApp = new Outlook.Application();
Outlook.NameSpace oNS = oApp.GetNamespace("mapi");
Outlook.MAPIFolder oInbox = oNS.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
Microsoft.Office.Interop.Outlook.Items oItems = oInbox.Items;
Microsoft.Office.Interop.Outlook.MailItem oMsg = null;
oMsg = (Microsoft.Office.Interop.Outlook.MailItem)oItems[1];
Inspector oInsp = oMsg.GetInspector;

mshtml.IHTMLDocument2 htDoc = (mshtml.IHTMLDocument2)oInsp.HTMLEditor;
Вот на этой строке включается Outlook security.

Читал что обойти Outlook security можно, если использовать MAPI.
А как его использовать в C# незнаю
bart_s вне форума  
Старый 28.05.2007, 23:15     # 2
alexey_ma
Member
 
Регистрация: 10.03.2002
Адрес: Israel
Сообщения: 245

alexey_ma Нимб уже пробиваетсяalexey_ma Нимб уже пробивается
Не совсем понимаю что вы называете "объект Inspector".
Если вам , судя по приведенному коду, нужно получить IHTMLDocument2 то это можно сделать и без MAPI, достаточно иметь хендл окна ActiveX-а (его СlassName - ""Internet Explorer_Server").
Код примерно такой :
Код:
BOOL CWebConnectivity::GetHTMLDocFromWnd(HWND hWnd, MSHTML::IHTMLDocument2Ptr& spOutDoc2) const
{
	if(!hWnd) 
		return FALSE;

	spOutDoc2=NULL;
	static UINT MSG = RegisterWindowMessage(TEXT("WM_HTML_GETOBJECT"));
	wstring ClassName("");
	TCHAR buf[MAX_LEN];
	::GetClassName(hWnd,buf,sizeof(buf)/sizeof(TCHAR)-2);

	ClassName=buf;
	if(ClassName != TEXT("Internet Explorer_Server"))
	{
		if (ClassName == TEXT("Internet Explorer_TridentCmboBx") || 
			ClassName == TEXT("Internet Explorer_TridentLstBox"))
		{
			hWnd = ::GetParent(hWnd);
			::GetClassName(hWnd,buf,sizeof(buf)-2);
			ClassName=buf;
			if(ClassName != TEXT("Internet Explorer_Server") )
				return FALSE;
		}
	}
	DWORD lRes = 0;
	LRESULT res = ::SendMessageTimeout(hWnd, MSG, 0, 0, SMTO_ABORTIFHUNG, 1000, &lRes);
	if (!res)
		return FALSE;
	if(::ObjectFromLresult(lRes,MSHTML::IID_IHTMLDocument2,0,(void**)&spOutDoc2) == S_OK)
	{
		
		return TRUE;
	
	}
	return FALSE;
}
Код С++, в шарп сами завернете при необходимости. Работает без проблем для "Internet Explorer_Server" -ов в любых аппликациях, в том числе и для Outlook .
Есть некоторые тонкости. Например IHTMLDocument-ы могут быть вложенными, придеться делать энумирацию доков чтоб-бы добраться до нужного, и т.д. Если будет интересно - спрашивайте.
__________________
Best Regards
alexey_ma вне форума  
Старый 31.05.2007, 10:22     # 3
bart_s
Newbie
 
Регистрация: 17.05.2007
Сообщения: 14

bart_s Путь к славе только начался
Спасибо.
Microsoft.Office.Interop.Outlook.Inspector - это окно просмотра email сообщения (которое, в зависимости от формата письма, содержит вложенное окно одного из ActiveX-ов :
Microsoft.Office.Interop.Outlook.OlEditorType.olEditorHTML
Microsoft.Office.Interop.Outlook.OlEditorType.olEditorRTF
Microsoft.Office.Interop.Outlook.OlEditorType.olEditorWord
Microsoft.Office.Interop.Outlook.OlEditorType.olEditorText
)

Аналогичную функцию GetHTMLDocFromWnd я использую. Но этот код работает только в том случае если у нас письмо в HTML формате. А во если в формате Word то получить WordDocument через hWnd не получается. Поэтому получаю его через Microsoft.Office.Interop.Outlook.Inspector (в данном случае WordEditor).
На что выскакивает окно security.

Для обхода security ищу информацию по использованию oMsg.MAPIOBJECT
из C#?
bart_s вне форума  
Старый 31.05.2007, 12:17     # 4
alexey_ma
Member
 
Регистрация: 10.03.2002
Адрес: Israel
Сообщения: 245

alexey_ma Нимб уже пробиваетсяalexey_ma Нимб уже пробивается
Можно попытаться и Word получить через AccessibleObject. Я правда никогда не пробовал, но есть большая вероятность что будет работать.
Порядок действий должен быть следующий :
Получить AccessibleObject из окна или точки (функция AccessibleObjectFromPoint).
Потом из AccessibleObject-а получить IServiceProvider, примерно так :
Код:
IServiceProviderPtr pSP;
IAccessiblePtr pAcc;
if(AccessibleObjectFromPoint(pt, &pAcc, &varId)==S_OK)
	{
		if(pAcc->QueryInterface(IID_IServiceProvider, (void **)&pSP)==S_OK)
		{
			//Тут сделать QueryService на соответствущий СОМ интерфейс Ворда
			Word::_DocumentPtr spDoc;;
			if(pSP->QueryService(Word::IID_Document,Word::IID_Document, (void **)&spDoc)==S_OK)
			{
				....
			}
		}
Не уверен что правильно написал интерфейсы Ворда, нужно пробовать.
Но сам принцип должен работать. Я в своих прогах таким образом получаю HTML елементы из экранной точки.
__________________
Best Regards
alexey_ma вне форума  
Старый 04.06.2007, 14:31     # 5
bart_s
Newbie
 
Регистрация: 17.05.2007
Сообщения: 14

bart_s Путь к славе только начался
Инересный метод. Попробую обязательно.

И еще один впрос касательно Outlook 2007.
В 2007 окно просмотра email сообщения не содержит "Internet Explorer_Server", при любых форматах принимаемых писем они выводятся в Word (activex-е). Допустим я обошел проблему получения этого Word-ctrl.
Мне необходимо скопировать содержание этого Word окна в BMP.
C IHTMLDocument проблем не было там делал Scroll и PrintWindow.

А с Word-ом не удается получить размеры всего она сообщения, следовательно scroll не получается нормально делать. Кроме того не получилось скопировать содержимое окна через PrintWindow. Пробовал использовать BitBlt - но это самый худший вариант

Может есть методы работы с Word-ctrl?
bart_s вне форума  
Старый 04.06.2007, 18:04     # 6
alexey_ma
Member
 
Регистрация: 10.03.2002
Адрес: Israel
Сообщения: 245

alexey_ma Нимб уже пробиваетсяalexey_ma Нимб уже пробивается
Я, к сожалению, не очень хорошо знаком с офисным COM. Но он хорошо задокументирован в MSDN.
Думаю что последовательность действий примерно такая :
Сначала надо добраться до поинтера на _Application (Наверное будет работать GetActiveObject c соответствующим class id). Потом получить указатель на интерфейс Window ( скорее всего так app->GetActiveWindow()). А у Window есть методы GetVerticalPercentScrolled и PutVerticalPercentScrolled.

Более точно нужно спрашивать у людей которые пишут на VBA для Word, они обычно хорошо знают все эти замороки.

P.S.
Typelibrary ворда можно просмотреть с помощью утилитки оleview ( она помоему входит в поставку VS и Platform SDK).
Typelibrary ворда находится в файле MSWORD.OLB. ( У меня на компьютере C:\Program Files\Microsoft Office\Office12\MSWORD.OLB).
__________________
Best Regards
alexey_ma вне форума  
Старый 06.06.2007, 12:41     # 7
bart_s
Newbie
 
Регистрация: 17.05.2007
Сообщения: 14

bart_s Путь к славе только начался
Пробовал GetActiveWindow(), GetVerticalPercentScrolled и PutVerticalPercentScrolled. И они не совсем подходят для определения реальных размеров документа. А в версии Outlook 2007 функция GetActiveWindow() запрещена. (видимо для повышения секретности)
Словом каждая новая версия хуже предыдущей.

Попробую напрямую посылать WM_KEYDOWN (VK_DOWN) на hWnd Word окна. Может и получится.
bart_s вне форума  
Старый 11.06.2007, 12:57     # 8
bart_s
Newbie
 
Регистрация: 17.05.2007
Сообщения: 14

bart_s Путь к славе только начался
Решение найдено!

У Word Typelibrary
есть понятие Range и Slection, которые имеют замечательную функцию Copy() и CopyAsPicture(). Кроме того можно получить данные текущего Range в формате Enhanced Meta File используя member variable EnhMetaFileBits.

bart_s вне форума  


Ваши права в разделе
Вы НЕ можете создавать новые темы
Вы не можете отвечать в темах.
Вы НЕ можете прикреплять вложения
Вы НЕ можете редактировать свои сообщения

BB код Вкл.
Смайлы Вкл.
[IMG] код Выкл.
HTML код Выкл.

Быстрый переход


Часовой пояс GMT +4, время: 16:29.




Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.