Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Получение нестандартных полей (телефон,факс) из Windows Contacts -диалог Select Recipients / 3 сообщений из 3, страница 1 из 1
07.01.2016, 07:56
    #39142940
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получение нестандартных полей (телефон,факс) из Windows Contacts -диалог Select Recipients
Ну, собственно задача вызвать диалог стандартной виндовой адресной книги "Выбор получателей",
вернуть набор этих получателей (в общем случае подразделяются на To,CC,BCC).
Про каждого получателя надо знать имя, e-mail, но еще надо б телефон, факс (домашний,рабочий) и т.п.
Начало рассуждений и картинки здесь:
Доступ к адресной книге (контакты Windows)

Я таки нашел как это делается:
IAddrBook::Address Method
И даже сварганил в итоге рабочий код, кот. полностью привожу ниже (на красоту кода не претендую, т.к. пишу на VB(6,.Net) но как-то так):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
#include <windows.h>
#include <Shlobj.h>

#include <wab.h>

typedef HRESULT (WINAPI *fWABOpen)(LPADRBOOK*,LPWABOBJECT*,LPWAB_PARAM,DWORD);


int main()
{
	HRESULT hRes;
	LPADRBOOK lpAdrBook;
	LPWABOBJECT lpWABObject;
	LPWAB_PARAM lpWABParam = NULL;
	DWORD Reserved2 = NULL;

	HINSTANCE hinstLib;

	TCHAR szPath[MAX_PATH];
	char buf[256];
              SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES_COMMONX86, NULL, SHGFP_TYPE_DEFAULT, szPath);
	wsprintf(buf, "%s\\System\\wab32", szPath);
	hinstLib = LoadLibrary(buf);
	//hinstLib = LoadLibrary("C:\\Program Files (x86)\\Common Files\\System\\wab32");
	fWABOpen procWABOpen;

	if (hinstLib != NULL)
	{
		procWABOpen = (fWABOpen)GetProcAddress(hinstLib, "WABOpen");
		if (procWABOpen != NULL)
		{
			hRes = (procWABOpen)(&lpAdrBook, &lpWABObject, NULL, Reserved2);
			//_ASSERTE(hRes == S_OK);
			if (hRes != S_OK) exit(1);

			ULONG lpulUIParam = 0;// (ULONG_PTR *)hWnd;
			ADRPARM lpAdrParms;
			lpAdrParms.cbABContEntryID = 0;
			lpAdrParms.lpABContEntryID = NULL;
			lpAdrParms.ulFlags = DIALOG_MODAL; //MAPI_UNICODE +
			lpAdrParms.lpReserved = NULL;
			lpAdrParms.ulHelpContext = 0;
			lpAdrParms.lpszHelpFileName = NULL;
			lpAdrParms.lpfnABSDI = NULL;
			lpAdrParms.lpfnDismiss = NULL;
			lpAdrParms.lpvDismissContext = NULL;
			lpAdrParms.lpszCaption = NULL;
			lpAdrParms.lpszNewEntryTitle = NULL;
			lpAdrParms.lpszDestWellsTitle = NULL;
			lpAdrParms.cDestFields = 3;
			lpAdrParms.nDestFieldFocus = 0;
			lpAdrParms.lppszDestTitles = NULL;
			lpAdrParms.lpulDestComps = NULL;
			lpAdrParms.lpContRestriction = NULL;
			lpAdrParms.lpHierRestriction = NULL;
			LPADRLIST lppAdrList = NULL;
			hRes = lpAdrBook->Address(&lpulUIParam, &lpAdrParms, &lppAdrList);


      for(ULONG i=0;i<lppAdrList->cEntries;i++)
			{
        wsprintf(buf, "%d", lppAdrList->aEntries[i].cValues);
        MessageBox(NULL, buf, "cValues", MB_OK);
				for(ULONG j=0;j<lppAdrList->aEntries[i].cValues;j++)//
				{
          SPropValue *lpProp = &lppAdrList->aEntries[i].rgPropVals[j];

					if (lpProp->ulPropTag == PR_DISPLAY_NAME_A){
            wsprintf(buf, "Display Name: %s", lpProp->Value.lpszA);
            MessageBox(NULL, buf, "Display Name", MB_OK);
					}
					if (lpProp->ulPropTag == PR_EMAIL_ADDRESS_A){
            wsprintf(buf, "Email Address: %s", lpProp->Value.lpszA);
            MessageBox(NULL, buf, "Email Address", MB_OK);
					}
					if (lpProp->ulPropTag == PR_RECIPIENT_TYPE){ //1-To,2-CC,3-BCC
            wsprintf(buf, "Receiptype: %d", lpProp->Value.ul);
            MessageBox(NULL, buf, "Receiptype", MB_OK);
					}
					if (lpProp->ulPropTag == PR_HOME_TELEPHONE_NUMBER_A){
            wsprintf(buf, "Home Phone: %s", lpProp->Value.lpszA);
            MessageBox(NULL, buf, "Home Phone", MB_OK);
					}
					if (lpProp->ulPropTag == PR_HOME_FAX_NUMBER_A){
            wsprintf(buf, "Home Fax: %s", lpProp->Value.lpszA);
            MessageBox(NULL, buf, "Home Fax", MB_OK);
					}
				}

			}

		}
	}
	return 0;
}



Вопрос в чем:
lppAdrList->aEntries[i].cValues всегда возвращает число 12 (количество возвращаемых полей в "контакте")
PR_DISPLAY_NAME_A,PR_EMAIL_ADDRESS_A,PR_RECIPIENT_TYPE(т.е.To,CC,BCC) -возвращает без проблем, на MAPI не завязано - уже неплохо
а вот PR_HOME_TELEPHONE_NUMBER_A, PR_HOME_FAX_NUMBER_A и им подобные - никак
И неудивительно - в "контакте" не 12 полей, а гораздо больше.
Так вот как мне получить "второстепенные" телефоны, факсы и прочее.

М.б. кто когда-то копал эту кухню и знает как это сделать? Примеров в сети на эту тему что-то почти нету.

Еще вопрос забегая вперед. Т.к. там интерфейсы а не API а у меня приложение VB.Net то воспроизвести это в лоб не прибегая к C/C++ видимо не смогу, поэтому придется видимо писать C-dll+API. Ну, минимальный опыт есть.
В каком виде мне возвращать массив наборов recipients (может быть один, может несколько, может сотня - что выбрал в диалоге)
{Имя;E-mail;To/CC/BCC;Телефон(?);Факс(?);...(?)}
Чтоб потом его удобно достать из .Net?
Количество элементов + массив структур неопределенной длины ByRef IntPtr?

Еще б хорошо в Юникоде все оформить, но пока не получается. Сделал пока exe в 2005VC++EE -отработано, 2013-я рантаймов на других компах требует.
...
Рейтинг: 0 / 0
07.01.2016, 19:47
    #39143107
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получение нестандартных полей (телефон,факс) из Windows Contacts -диалог Select Recipients
автора вот PR_HOME_TELEPHONE_NUMBER_A, PR_HOME_FAX_NUMBER_A и им подобные - никак
Так вот как мне получить "второстепенные" телефоны, факсы и прочее.
Накопал.
Надо брать поле PR_ENTRYID и делать lpAdrBook->OpenEntry
Вернется интерфейс IMailUser *lpMailUser
Ему надо делать lpMailUser->GetProps
Оттуда уже выкапывается PR_HOME_TELEPHONE_NUMBER, PR_HOME_FAX_NUMBER, PR_BUSINESS_TELEPHONE_NUMBER, PR_BUSINESS_FAX_NUMBER и любые другие поля (при их наличии).
Ниже рабочий код в первом приближении.

Осталось разобраться с Юникодом (Display Name в ANSI плохая идея).
Ну и наверно засунуть все это в Dll чтоб пользовать API.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
#include <windows.h>
#include <Shlobj.h>
#include <wab.h>

typedef HRESULT (WINAPI *fWABOpen)(LPADRBOOK*,LPWABOBJECT*,LPWAB_PARAM,DWORD);


int main()
{
  HRESULT hRes;
  LPADRBOOK lpAdrBook;
  LPWABOBJECT lpWABObject;
  LPWAB_PARAM lpWABParam = NULL;
  DWORD Reserved2 = NULL;

  HINSTANCE hinstLib;

  TCHAR szPath[MAX_PATH];
  char buf[1024];
  SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES_COMMONX86, NULL, SHGFP_TYPE_DEFAULT, szPath);
  wsprintf(buf, "%s\\System\\wab32", szPath);
  hinstLib = LoadLibrary(buf); //"C:\\Program Files (x86)\\Common Files\\System\\wab32"
  fWABOpen procWABOpen;

  if (hinstLib != NULL)
  {
    procWABOpen = (fWABOpen)GetProcAddress(hinstLib, "WABOpen");
    if (procWABOpen != NULL)
    {
      hRes = (procWABOpen)(&lpAdrBook, &lpWABObject, NULL, Reserved2);
      if (hRes != S_OK) exit(1);

      ULONG lpulUIParam = 0;// (ULONG_PTR *)hWnd;
      ADRPARM lpAdrParms;
      lpAdrParms.cbABContEntryID = 0;
      lpAdrParms.lpABContEntryID = NULL;
      lpAdrParms.ulFlags = DIALOG_MODAL; //MAPI_UNICODE +
      lpAdrParms.lpReserved = NULL;
      lpAdrParms.ulHelpContext = 0;
      lpAdrParms.lpszHelpFileName = NULL;
      lpAdrParms.lpfnABSDI = NULL;
      lpAdrParms.lpfnDismiss = NULL;
      lpAdrParms.lpvDismissContext = NULL;
      lpAdrParms.lpszCaption = NULL;
      lpAdrParms.lpszNewEntryTitle = NULL;
      lpAdrParms.lpszDestWellsTitle = NULL;
      lpAdrParms.cDestFields = 3;
      lpAdrParms.nDestFieldFocus = 0;
      lpAdrParms.lppszDestTitles = NULL;
      lpAdrParms.lpulDestComps = NULL;
      lpAdrParms.lpContRestriction = NULL;
      lpAdrParms.lpHierRestriction = NULL;
      LPADRLIST lppAdrList = NULL;
      hRes = lpAdrBook->Address(&lpulUIParam, &lpAdrParms, &lppAdrList);
      if (hRes != S_OK) return 0;
      if (lppAdrList==NULL)return 0;
      for(ULONG i=0;i<lppAdrList->cEntries;i++)
      {
        LPSTR m_DisplayName = "";
        LPSTR m_EmailAddress = "";
        ULONG m_ReceipType=0; //1-To,2-CC,3-BCC
        LPSTR m_HomeTelephoneNumber = "";
        LPSTR m_HomeFaxNumber = "";
        LPSTR m_BusinessTelephoneNumber = "";
        LPSTR m_BusinessFaxNumber = "";
        ULONG cProps = 0;
        LPSPropValue lpProps = NULL;
        for(ULONG j=0;j<lppAdrList->aEntries[i].cValues;j++)//
        {
          SPropValue *lpProp = &lppAdrList->aEntries[i].rgPropVals[j];

          if (lpProp->ulPropTag == PR_DISPLAY_NAME_A)
            m_DisplayName=lpProp->Value.lpszA;
          if (lpProp->ulPropTag == PR_EMAIL_ADDRESS_A)
            m_EmailAddress=lpProp->Value.lpszA;
          if (lpProp->ulPropTag == PR_RECIPIENT_TYPE) //1-To,2-CC,3-BCC
            m_ReceipType=lpProp->Value.ul;
          if (lpProp->ulPropTag == PR_ENTRYID){
            ULONG ulFlags = 0;//MAPI_BEST_ACCESS;
            ULONG ulObjType = NULL;
            LPUNKNOWN lpUnk = NULL;
            hRes = lpAdrBook->OpenEntry(lpProp->Value.bin.cb,(LPENTRYID)(lpProp->Value.bin.lpb),NULL,ulFlags,&ulObjType,&lpUnk);
            if (hRes == S_OK){
              ulFlags = NULL;
              if (ulObjType == MAPI_MAILUSER){
                IMailUser *lpMailUser = static_cast <IMailUser *>(lpUnk);
                hRes = lpMailUser->GetProps(NULL,0,&cProps,&lpProps);
                if (hRes == S_OK){
                  for(ULONG k=0;k<cProps;k++)//
                  {
                    if (lpProps[k].ulPropTag == PR_HOME_TELEPHONE_NUMBER_A)
                     m_HomeTelephoneNumber=lpProps[k].Value.lpszA;
                    if (lpProps[k].ulPropTag == PR_HOME_FAX_NUMBER_A)
                      m_HomeFaxNumber=lpProps[k].Value.lpszA;
                    if (lpProps[k].ulPropTag == PR_BUSINESS_TELEPHONE_NUMBER_A)
                      m_BusinessTelephoneNumber=lpProps[k].Value.lpszA;
                    if (lpProps[k].ulPropTag == PR_BUSINESS_FAX_NUMBER_A)
                      m_BusinessFaxNumber=lpProps[k].Value.lpszA;
                  }
                }
              }
            }
          }
        }
        wsprintf(buf, "Display Name: %s\nEmail Address: %s\nReceiptype: %d\nHome Phone: %s\nHome Fax: %s\n\
Office Phone: %s\nOffice Fax: %s",
          m_DisplayName,m_EmailAddress,m_ReceipType,m_HomeTelephoneNumber,m_HomeFaxNumber,
          m_BusinessTelephoneNumber,m_BusinessFaxNumber);
        MessageBox(NULL, buf, "Recipient info", MB_OK);
        lpWABObject->FreeBuffer(lpProps);
      }
    }
  }
  FreeLibrary(hinstLib);
  return 0;
}
...
Рейтинг: 0 / 0
07.01.2016, 21:09
    #39143124
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получение нестандартных полей (телефон,факс) из Windows Contacts -диалог Select Recipients
Дмитрий77Осталось разобраться с Юникодом
а в чём проблема?
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Получение нестандартных полей (телефон,факс) из Windows Contacts -диалог Select Recipients / 3 сообщений из 3, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]