Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

8745 lines
310 KiB

  1. /**********************************************************************************
  2. *
  3. *
  4. * Details.C - contains functions for the Details dialog
  5. *
  6. *
  7. *
  8. *
  9. *
  10. *
  11. *
  12. **********************************************************************************/
  13. #include "_apipch.h"
  14. #define _CRYPTDLG_
  15. #define EDIT_LEN MAX_UI_STR*2
  16. #define MAX_EDIT_LEN MAX_BUF_STR*2
  17. #define IDC_TRIDENT_WINDOW 9903
  18. extern BOOL bDNisByLN;
  19. extern HINSTANCE ghCommCtrlDLLInst;
  20. // extern LPPROPERTYSHEET gpfnPropertySheet;
  21. // extern LPIMAGELIST_LOADIMAGE gpfnImageList_LoadImage;
  22. // extern LP_CREATEPROPERTYSHEETPAGE gpfnCreatePropertySheetPage;
  23. extern LPPROPERTYSHEET_A gpfnPropertySheetA;
  24. extern LPPROPERTYSHEET_W gpfnPropertySheetW;
  25. extern LPIMAGELIST_LOADIMAGE_A gpfnImageList_LoadImageA;
  26. extern LPIMAGELIST_LOADIMAGE_W gpfnImageList_LoadImageW;
  27. extern LP_CREATEPROPERTYSHEETPAGE_A gpfnCreatePropertySheetPageA;
  28. extern LP_CREATEPROPERTYSHEETPAGE_W gpfnCreatePropertySheetPageW;
  29. extern HRESULT HandleSaveChangedInsufficientDiskSpace(HWND hWnd, LPMAILUSER lpMailUser);
  30. extern BOOL GetOpenFileName(LPOPENFILENAME pof);
  31. extern BOOL GetSaveFileName(LPOPENFILENAME pof);
  32. extern BOOL bIsIE401OrGreater();
  33. extern void ChangeLocaleBasedTabOrder(HWND hWnd, int nPropSheet);
  34. const LPTSTR szInternetCallKey = TEXT("Software\\Clients\\Internet Call");
  35. const LPTSTR szCallto = TEXT("callto://");
  36. const LPTSTR szHTTP = TEXT("http://");
  37. /* Context-Sensitive Help IDs
  38. The following is a giant list of Control IDs and corresponding Help IDs for
  39. all the controls on all the property sheets .. when adding new prop sheets
  40. just append your controls to the bottom of the list
  41. */
  42. static DWORD rgDetlsHelpIDs[] =
  43. {
  44. IDC_DETAILS_PERSONAL_FRAME_NAME, IDH_WAB_COMM_GROUPBOX,
  45. IDC_DETAILS_PERSONAL_FRAME_EMAIL, IDH_WAB_ADD_EMAIL_NAME,
  46. IDC_DETAILS_PERSONAL_STATIC_FIRSTNAME, IDH_WAB_CONTACT_PROPS_FIRST,
  47. IDC_DETAILS_PERSONAL_EDIT_FIRSTNAME, IDH_WAB_CONTACT_PROPS_FIRST,
  48. IDC_DETAILS_PERSONAL_STATIC_LASTNAME, IDH_WAB_CONTACT_PROPS_LAST,
  49. IDC_DETAILS_PERSONAL_EDIT_LASTNAME, IDH_WAB_CONTACT_PROPS_LAST,
  50. IDC_DETAILS_PERSONAL_STATIC_MIDDLENAME, IDH_WAB_MIDDLE_NAME,
  51. IDC_DETAILS_PERSONAL_EDIT_MIDDLENAME, IDH_WAB_MIDDLE_NAME,
  52. IDC_DETAILS_PERSONAL_STATIC_NICKNAME, IDH_WAB_NICKNAME,
  53. IDC_DETAILS_PERSONAL_EDIT_NICKNAME, IDH_WAB_NICKNAME,
  54. IDC_DETAILS_PERSONAL_STATIC_DISPLAYNAME,IDH_WAB_PERSONAL_NAME_DISPLAY,
  55. IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME, IDH_WAB_PERSONAL_NAME_DISPLAY,
  56. IDC_DETAILS_PERSONAL_STATIC_TITLE, IDH_WAB_CONTACT_PROPS_TITLE,
  57. IDC_DETAILS_PERSONAL_EDIT_TITLE, IDH_WAB_CONTACT_PROPS_TITLE,
  58. IDC_DETAILS_PERSONAL_STATIC_CAPTION3, IDH_WAB_ADD_EMAIL_NAME,
  59. IDC_DETAILS_PERSONAL_EDIT_ADDEMAIL, IDH_WAB_ADD_EMAIL_NAME,
  60. IDC_DETAILS_PERSONAL_BUTTON_ADDEMAIL, IDH_WAB_ADD_EMAIL_NAME,
  61. IDC_DETAILS_PERSONAL_LIST, IDH_WAB_EMAIL_NAME_LIST,
  62. IDC_DETAILS_PERSONAL_BUTTON_REMOVE, IDH_WAB_DELETE_EMAIL_NAME,
  63. IDC_DETAILS_PERSONAL_BUTTON_SETDEFAULT, IDH_WAB_DEFAULT_EMAIL_NAME,
  64. IDC_DETAILS_PERSONAL_BUTTON_EDIT, IDH_WAB_EDIT_EMAIL_NAME,
  65. IDC_DETAILS_PERSONAL_BUTTON_ADDTOWAB, IDH_WAB_DIRSERV_ADDADDRESS,
  66. IDC_DETAILS_PERSONAL_CHECK_RICHINFO, IDH_WAB_PROPERTIES_SEND_USING_PLAIN_TEXT,
  67. IDC_DETAILS_HOME_STATIC_ADDRESS, IDH_WAB_HOME_ADDRESS,
  68. IDC_DETAILS_HOME_EDIT_ADDRESS, IDH_WAB_HOME_ADDRESS,
  69. IDC_DETAILS_HOME_STATIC_CITY, IDH_WAB_HOME_CITY,
  70. IDC_DETAILS_HOME_EDIT_CITY, IDH_WAB_HOME_CITY,
  71. IDC_DETAILS_HOME_STATIC_STATE, IDH_WAB_HOME_STATE,
  72. IDC_DETAILS_HOME_EDIT_STATE, IDH_WAB_HOME_STATE,
  73. IDC_DETAILS_HOME_STATIC_ZIP, IDH_WAB_HOME_ZIP,
  74. IDC_DETAILS_HOME_EDIT_ZIP, IDH_WAB_HOME_ZIP,
  75. IDC_DETAILS_HOME_STATIC_COUNTRY, IDH_WAB_HOME_COUNTRY,
  76. IDC_DETAILS_HOME_EDIT_COUNTRY, IDH_WAB_HOME_COUNTRY,
  77. IDC_DETAILS_HOME_CHECK_DEFAULTADDRESS, IDH_WAB_BUSINESS_DEFAULTBOX,
  78. IDC_DETAILS_HOME_BUTTON_MAP, IDH_WAB_BUSINESS_VIEWMAP,
  79. IDC_DETAILS_HOME_STATIC_WEB, IDH_WAB_HOMEPAGE,
  80. IDC_DETAILS_HOME_EDIT_URL, IDH_WAB_HOMEPAGE,
  81. IDC_DETAILS_HOME_BUTTON_URL, IDH_WAB_HOMEPAGE_BUTTON,
  82. IDC_DETAILS_HOME_STATIC_PHONE, IDH_WAB_BUS_PHONE,
  83. IDC_DETAILS_HOME_EDIT_PHONE, IDH_WAB_BUS_PHONE,
  84. IDC_DETAILS_HOME_STATIC_FAX, IDH_WAB_BUS_FAX,
  85. IDC_DETAILS_HOME_EDIT_FAX, IDH_WAB_BUS_FAX,
  86. IDC_DETAILS_HOME_STATIC_CELLULAR, IDH_WAB_BUS_CELLULAR,
  87. IDC_DETAILS_HOME_EDIT_CELLULAR, IDH_WAB_BUS_CELLULAR,
  88. IDC_DETAILS_HOME_COMBO_GENDER, IDH_WAB_HOME_GENDER,
  89. IDC_DETAILS_BUSINESS_STATIC_COMPANY, IDH_WAB_BUS_COMPANY,
  90. IDC_DETAILS_BUSINESS_EDIT_COMPANY, IDH_WAB_BUS_COMPANY,
  91. IDC_DETAILS_BUSINESS_STATIC_ADDRESS, IDH_WAB_BUS_ADDRESS,
  92. IDC_DETAILS_BUSINESS_EDIT_ADDRESS, IDH_WAB_BUS_ADDRESS,
  93. IDC_DETAILS_BUSINESS_STATIC_CITY, IDH_WAB_BUS_CITY,
  94. IDC_DETAILS_BUSINESS_EDIT_CITY, IDH_WAB_BUS_CITY,
  95. IDC_DETAILS_BUSINESS_STATIC_STATE, IDH_WAB_BUS_STATE,
  96. IDC_DETAILS_BUSINESS_EDIT_STATE, IDH_WAB_BUS_STATE,
  97. IDC_DETAILS_BUSINESS_STATIC_ZIP, IDH_WAB_BUS_ZIP,
  98. IDC_DETAILS_BUSINESS_EDIT_ZIP, IDH_WAB_BUS_ZIP,
  99. IDC_DETAILS_BUSINESS_STATIC_COUNTRY, IDH_WAB_BUS_COUNTRY,
  100. IDC_DETAILS_BUSINESS_EDIT_COUNTRY, IDH_WAB_BUS_COUNTRY,
  101. IDC_DETAILS_BUSINESS_CHECK_DEFAULTADDRESS, IDH_WAB_BUSINESS_DEFAULTBOX,
  102. IDC_DETAILS_BUSINESS_BUTTON_MAP, IDH_WAB_BUSINESS_VIEWMAP,
  103. IDC_DETAILS_BUSINESS_STATIC_JOBTITLE, IDH_WAB_BUS_TITLE,
  104. IDC_DETAILS_BUSINESS_EDIT_JOBTITLE, IDH_WAB_BUS_TITLE,
  105. IDC_DETAILS_BUSINESS_STATIC_DEPARTMENT, IDH_WAB_BUS_DEPT,
  106. IDC_DETAILS_BUSINESS_EDIT_DEPARTMENT, IDH_WAB_BUS_DEPT,
  107. IDC_DETAILS_BUSINESS_STATIC_OFFICE, IDH_WAB_BUS_OFFICE,
  108. IDC_DETAILS_BUSINESS_EDIT_OFFICE, IDH_WAB_BUS_OFFICE,
  109. IDC_DETAILS_BUSINESS_STATIC_PHONE, IDH_WAB_BUS_PHONE,
  110. IDC_DETAILS_BUSINESS_EDIT_PHONE, IDH_WAB_BUS_PHONE,
  111. IDC_DETAILS_BUSINESS_STATIC_FAX, IDH_WAB_BUS_FAX,
  112. IDC_DETAILS_BUSINESS_EDIT_FAX, IDH_WAB_BUS_FAX,
  113. IDC_DETAILS_BUSINESS_STATIC_PAGER, IDH_WAB_BUS_PAGER,
  114. IDC_DETAILS_BUSINESS_EDIT_PAGER, IDH_WAB_BUS_PAGER,
  115. IDC_DETAILS_BUSINESS_STATIC_IPPHONE, IDH_WAB_BUSINESS_IPPHONE,
  116. IDC_DETAILS_BUSINESS_EDIT_IPPHONE, IDH_WAB_BUSINESS_IPPHONE,
  117. IDC_DETAILS_BUSINESS_STATIC_WEB, IDH_WAB_HOMEPAGE,
  118. IDC_DETAILS_BUSINESS_EDIT_URL, IDH_WAB_HOMEPAGE,
  119. IDC_DETAILS_BUSINESS_BUTTON_URL, IDH_WAB_HOMEPAGE_BUTTON,
  120. IDC_DETAILS_NOTES_STATIC_NOTES, IDH_WAB_NOTES,
  121. IDC_DETAILS_NOTES_EDIT_NOTES, IDH_WAB_NOTES,
  122. IDC_DETAILS_NOTES_STATIC_NOTES_GROUP, IDH_WAB_OTHER_GROUP_MEMBERSHIP,
  123. IDC_DETAILS_NOTES_EDIT_GROUPS, IDH_WAB_OTHER_GROUP_MEMBERSHIP,
  124. IDC_DETAILS_NOTES_FRAME_FOLDER, IDH_WAB_OTHER_FOLDER,
  125. IDC_DETAILS_NOTES_STATIC_FOLDER, IDH_WAB_OTHER_FOLDER,
  126. IDC_DETAILS_CERT_FRAME, IDH_WAB_COMM_GROUPBOX,
  127. IDC_DETAILS_CERT_LIST, IDH_WAB_PROPERTIES_CERTIFICATES,
  128. IDC_DETAILS_CERT_BUTTON_PROPERTIES, IDH_WAB_PROPERTIES_PROPERTIES,
  129. IDC_DETAILS_CERT_BUTTON_REMOVE, IDH_WAB_PROPERTIES_REMOVE,
  130. IDC_DETAILS_CERT_BUTTON_SETDEFAULT, IDH_WAB_PROPERTIES_SETASDEFAULT,
  131. IDC_DETAILS_CERT_BUTTON_IMPORT, IDH_WAB_PROPERTIES_IMPORT,
  132. IDC_DETAILS_CERT_BUTTON_EXPORT, IDH_WAB_PROPERTIES_EXPORT,
  133. IDC_DETAILS_CERT_COMBO, IDH_WAB_CERTIFICATES_SELECT_EMAIL_ADDRESS,
  134. IDC_DETAILS_CERT_STATIC2, IDH_WAB_CERTIFICATES_SELECT_EMAIL_ADDRESS,
  135. IDC_DETAILS_NTMTG_FRAME_SERVERS, IDH_WAB_COMM_GROUPBOX,
  136. IDC_DETAILS_NTMTG_FRAME_SERVERS2, IDH_WAB_COMM_GROUPBOX,
  137. IDC_DETAILS_NTMTG_STATIC_CAPTION2, IDH_WAB_CONFERENCE_SELECT_ADDRESS,
  138. IDC_DETAILS_NTMTG_COMBO_EMAIL, IDH_WAB_CONFERENCE_SELECT_ADDRESS,
  139. IDC_DETAILS_NTMTG_BUTTON_CALL, IDH_WAB_CONFERENCE_CALL_NOW,
  140. IDC_DETAILS_NTMTG_STATIC_CAPTION3, IDH_WAB_CONFERENCE_SERVER_NAME,
  141. IDC_DETAILS_NTMTG_EDIT_ADDSERVER, IDH_WAB_CONFERENCE_SERVER_NAME,
  142. IDC_DETAILS_NTMTG_BUTTON_ADDSERVER, IDH_WAB_CONFERENCE_ADD_SERVER,
  143. IDC_DETAILS_NTMTG_BUTTON_EDIT, IDH_WAB_CONFERENCE_EDIT_SERVER,
  144. IDC_DETAILS_NTMTG_BUTTON_REMOVE, IDH_WAB_CONFERENCE_REMOVE_SERVER,
  145. IDC_DETAILS_NTMTG_BUTTON_SETDEFAULT, IDH_WAB_CONFERENCE_SET_DEFAULT,
  146. IDC_DETAILS_NTMTG_BUTTON_SETBACKUP, IDH_WAB_CONFERENCE_SET_BACKUP,
  147. IDC_DETAILS_NTMTG_LIST_SERVERS, IDH_WAB_CONFERENCE_SERVER_LIST,
  148. IDC_DETAILS_TRIDENT_BUTTON_ADDTOWAB, IDH_WAB_DIRSERV_ADDADDRESS,
  149. IDC_DETAILS_SUMMARY_STATIC_NAME, IDH_WAB_SUMMARY,
  150. IDC_DETAILS_SUMMARY_STATIC_EMAIL, IDH_WAB_SUMMARY,
  151. IDC_DETAILS_SUMMARY_STATIC_HOMEPHONE, IDH_WAB_SUMMARY,
  152. IDC_DETAILS_SUMMARY_STATIC_PAGER, IDH_WAB_SUMMARY,
  153. IDC_DETAILS_SUMMARY_STATIC_CELLULAR, IDH_WAB_SUMMARY,
  154. IDC_DETAILS_SUMMARY_STATIC_PERSONALWEB, IDH_WAB_SUMMARY,
  155. IDC_DETAILS_SUMMARY_STATIC_BUSINESSPHONE, IDH_WAB_SUMMARY,
  156. IDC_DETAILS_SUMMARY_STATIC_BUSINESSFAX, IDH_WAB_SUMMARY,
  157. IDC_DETAILS_SUMMARY_STATIC_JOBTITLE, IDH_WAB_SUMMARY,
  158. IDC_DETAILS_SUMMARY_STATIC_DEPARTMENT, IDH_WAB_SUMMARY,
  159. IDC_DETAILS_SUMMARY_STATIC_OFFICE, IDH_WAB_SUMMARY,
  160. IDC_DETAILS_SUMMARY_STATIC_COMPANYNAME, IDH_WAB_SUMMARY,
  161. IDC_DETAILS_SUMMARY_STATIC_BUSINESSWEB, IDH_WAB_SUMMARY,
  162. IDC_DETAILS_ORG_STATIC_MANAGER, IDH_WAB_ORGANIZATION_MANAGER,
  163. IDC_DETAILS_ORG_LIST_MANAGER, IDH_WAB_ORGANIZATION_MANAGER,
  164. IDC_DETAILS_ORG_STATIC_REPORTS, IDH_WAB_ORGANIZATION_REPORTS,
  165. IDC_DETAILS_ORG_LIST_REPORTS, IDH_WAB_ORGANIZATION_REPORTS,
  166. IDC_DETAILS_FAMILY_STATIC_SPOUSE, IDH_WAB_PERSONAL_SPOUSE,
  167. IDC_DETAILS_FAMILY_EDIT_SPOUSE, IDH_WAB_PERSONAL_SPOUSE,
  168. IDC_DETAILS_FAMILY_STATIC_CHILDREN, IDH_WAB_PERSONAL_CHILDREN,
  169. IDC_DETAILS_FAMILY_LIST_CHILDREN, IDH_WAB_PERSONAL_CHILDREN,
  170. IDC_DETAILS_FAMILY_BUTTON_ADDCHILD, IDH_WAB_PERSONAL_ADD,
  171. IDC_DETAILS_FAMILY_BUTTON_EDITCHILD, IDH_WAB_PERSONAL_EDIT,
  172. IDC_DETAILS_FAMILY_BUTTON_REMOVECHILD, IDH_WAB_PERSONAL_REMOVE,
  173. IDC_DETAILS_FAMILY_STATIC_BIRTHDAY, IDH_WAB_PERSONAL_BIRTHDAY,
  174. IDC_DETAILS_FAMILY_STATIC_ANNIVERSARY, IDH_WAB_PERSONAL_ANNIVERSARY,
  175. IDC_DETAILS_FAMILY_DATE_BIRTHDAY, IDH_WAB_PERSONAL_BIRTHDAY,
  176. IDC_DETAILS_FAMILY_DATE_ANNIVERSARY, IDH_WAB_PERSONAL_ANNIVERSARY,
  177. 0,0
  178. };
  179. /*
  180. Structs for Filling in data in the PropSheets
  181. When filling in IDs into each property sheet, we do a GetProps on the displayed
  182. object for the specific Props needed for each page .. we then use the returned
  183. data to fill in the current prop sheet ..
  184. Named properties need some special handling since we can't pre-allocate them into the structs -
  185. the named properties need to be added prior to using them
  186. Non-string properties may also need special handling
  187. */
  188. /* -- Summary TAB info --*/
  189. #define MAX_SUMMARY_ID 13
  190. int rgSummaryIDs[] =
  191. {
  192. IDC_DETAILS_SUMMARY_STATIC_NAME,
  193. IDC_DETAILS_SUMMARY_STATIC_EMAIL,
  194. IDC_DETAILS_SUMMARY_STATIC_BUSINESSPHONE,
  195. IDC_DETAILS_SUMMARY_STATIC_BUSINESSFAX,
  196. IDC_DETAILS_SUMMARY_STATIC_HOMEPHONE,
  197. IDC_DETAILS_SUMMARY_STATIC_PAGER,
  198. IDC_DETAILS_SUMMARY_STATIC_CELLULAR,
  199. IDC_DETAILS_SUMMARY_STATIC_JOBTITLE,
  200. IDC_DETAILS_SUMMARY_STATIC_DEPARTMENT,
  201. IDC_DETAILS_SUMMARY_STATIC_OFFICE,
  202. IDC_DETAILS_SUMMARY_STATIC_COMPANYNAME,
  203. IDC_DETAILS_SUMMARY_STATIC_BUSINESSWEB,
  204. IDC_DETAILS_SUMMARY_STATIC_PERSONALWEB,
  205. };
  206. static const SizedSPropTagArray(MAX_SUMMARY_ID + 2, ptaUIDetlsPropsSummary) =
  207. {
  208. MAX_SUMMARY_ID + 2,
  209. {
  210. PR_DISPLAY_NAME,
  211. PR_EMAIL_ADDRESS,
  212. PR_BUSINESS_TELEPHONE_NUMBER,
  213. PR_BUSINESS_FAX_NUMBER,
  214. PR_HOME_TELEPHONE_NUMBER,
  215. PR_PAGER_TELEPHONE_NUMBER,
  216. PR_CELLULAR_TELEPHONE_NUMBER,
  217. PR_TITLE,
  218. PR_DEPARTMENT_NAME,
  219. PR_OFFICE_LOCATION,
  220. PR_COMPANY_NAME,
  221. PR_BUSINESS_HOME_PAGE,
  222. PR_PERSONAL_HOME_PAGE,
  223. PR_CONTACT_EMAIL_ADDRESSES,
  224. PR_CONTACT_DEFAULT_ADDRESS_INDEX,
  225. }
  226. };
  227. /* -- Personal/Name TAB info --*/
  228. /*
  229. * [PaulHi] 4/8/99 Since the personal property sheet contains global properties
  230. * (i.e., the Ruby properties ... PR_WAB_YOMI_LASTNAME, PR_WAB_YOMI_FIRSTNAME),
  231. * this tag array cannot be static.
  232. static const SizedSPropTagArray(12, ptaUIDetlsPropsPersonal)=
  233. {
  234. 12,
  235. {
  236. PR_DISPLAY_NAME,
  237. PR_EMAIL_ADDRESS,
  238. PR_ADDRTYPE,
  239. PR_CONTACT_EMAIL_ADDRESSES,
  240. PR_CONTACT_ADDRTYPES,
  241. PR_CONTACT_DEFAULT_ADDRESS_INDEX,
  242. PR_GIVEN_NAME,
  243. PR_SURNAME,
  244. PR_MIDDLE_NAME,
  245. PR_NICKNAME,
  246. PR_SEND_INTERNET_ENCODING,
  247. PR_DISPLAY_NAME_PREFIX
  248. }
  249. };
  250. */
  251. /* -- Home TAB info --*/
  252. static SizedSPropTagArray(10, ptaUIDetlsPropsHome)=
  253. {
  254. 10,
  255. {
  256. PR_HOME_ADDRESS_STREET,
  257. PR_HOME_ADDRESS_CITY,
  258. PR_HOME_ADDRESS_POSTAL_CODE,
  259. PR_HOME_ADDRESS_STATE_OR_PROVINCE,
  260. PR_HOME_ADDRESS_COUNTRY,
  261. PR_PERSONAL_HOME_PAGE,
  262. PR_HOME_TELEPHONE_NUMBER,
  263. PR_HOME_FAX_NUMBER,
  264. PR_CELLULAR_TELEPHONE_NUMBER,
  265. PR_NULL, /*PR_WAB_POSTALID*/
  266. }
  267. };
  268. /* -- Business TAB info --*/
  269. static SizedSPropTagArray(15, ptaUIDetlsPropsBusiness)=
  270. {
  271. 15,
  272. {
  273. PR_BUSINESS_ADDRESS_STREET,
  274. PR_BUSINESS_ADDRESS_CITY,
  275. PR_BUSINESS_ADDRESS_POSTAL_CODE,
  276. PR_BUSINESS_ADDRESS_STATE_OR_PROVINCE,
  277. PR_BUSINESS_ADDRESS_COUNTRY,
  278. PR_BUSINESS_HOME_PAGE,
  279. PR_BUSINESS_TELEPHONE_NUMBER,
  280. PR_BUSINESS_FAX_NUMBER,
  281. PR_PAGER_TELEPHONE_NUMBER,
  282. PR_COMPANY_NAME,
  283. PR_TITLE,
  284. PR_DEPARTMENT_NAME,
  285. PR_OFFICE_LOCATION,
  286. PR_NULL, /*PR_WAB_IPPHONE*/
  287. PR_NULL, /*PR_WAB_POSTALID*/
  288. }
  289. };
  290. /* -- Notes TAB info --*/
  291. static const SizedSPropTagArray(1, ptaUIDetlsPropsNotes)=
  292. {
  293. 1,
  294. {
  295. PR_COMMENT,
  296. }
  297. };
  298. /* -- Digital ID TAB info --*/
  299. static const SizedSPropTagArray(1, ptaUIDetlsPropsCert)=
  300. {
  301. 1,
  302. {
  303. PR_USER_X509_CERTIFICATE,
  304. }
  305. };
  306. /* -- Family TAB info --*/
  307. static const SizedSPropTagArray(5, ptaUIDetlsPropsFamily)=
  308. {
  309. 5,
  310. {
  311. PR_SPOUSE_NAME,
  312. PR_CHILDRENS_NAMES,
  313. PR_GENDER,
  314. PR_BIRTHDAY,
  315. PR_WEDDING_ANNIVERSARY,
  316. }
  317. };
  318. enum _ImgEmail
  319. {
  320. imgNotDefaultEmail=0,
  321. imgDefaultEmail,
  322. imgChild
  323. };
  324. typedef struct _EmailItem
  325. {
  326. TCHAR szDisplayText[EDIT_LEN*2];
  327. TCHAR szEmailAddress[EDIT_LEN];
  328. TCHAR szAddrType[EDIT_LEN];
  329. BOOL bIsDefault;
  330. } EMAIL_ITEM, * LPEMAIL_ITEM;
  331. typedef struct _ServerItem
  332. {
  333. LPTSTR lpServer;
  334. LPTSTR lpEmail;
  335. } SERVER_ITEM, * LPSERVER_ITEM;
  336. enum _CertValidity
  337. {
  338. imgCertValid=0,
  339. imgCertInvalid
  340. };
  341. enum _ListViewType
  342. {
  343. LV_EMAIL=0,
  344. LV_CERT,
  345. LV_SERVER,
  346. LV_KIDS
  347. };
  348. // forward declarations
  349. LRESULT CALLBACK RubySubClassedProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  350. int CreateDetailsPropertySheet(HWND hwndOwner,LPPROP_ARRAY_INFO lpPropArrayInfo);
  351. INT_PTR CALLBACK fnSummaryProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam);
  352. INT_PTR CALLBACK fnPersonalProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam);
  353. INT_PTR CALLBACK fnHomeProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam);
  354. INT_PTR CALLBACK fnBusinessProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam);
  355. INT_PTR CALLBACK fnNotesProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam);
  356. INT_PTR CALLBACK fnCertProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam);
  357. INT_PTR CALLBACK fnTridentProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam);
  358. INT_PTR CALLBACK fnConferencingProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam);
  359. INT_PTR CALLBACK fnOrgProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam);
  360. INT_PTR CALLBACK fnFamilyProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam);
  361. void FillComboWithEmailAddresses(LPPROP_ARRAY_INFO lpPai, HWND hWndCombo, int * lpnDefault);
  362. void SetBackupServer(HWND hDlg, LPPROP_ARRAY_INFO lpPai, int iSelectedItem, BOOL bForce);
  363. void SetDefaultServer(HWND hDlg, LPPROP_ARRAY_INFO lpPai, int iSelectedItem, BOOL bForce);
  364. BOOL FillPersonalDetails(HWND hDlg, LPPROP_ARRAY_INFO lpPai, int nPropSheet, BOOL * lpbChangesMade);
  365. BOOL FillHomeBusinessNotesDetailsUI(HWND hDlg, LPPROP_ARRAY_INFO lpPai, int nPropSheet, BOOL * lpbChangesMade);
  366. BOOL FillCertTridentConfDetailsUI(HWND hDlg, LPPROP_ARRAY_INFO lpPai, int nPropSheet, BOOL * lpbChangesMade);
  367. BOOL FillFamilyDetailsUI(HWND hDlg, LPPROP_ARRAY_INFO lpPai, int nPropSheet, BOOL * lpbChangesMade);
  368. BOOL GetDetailsFromUI(HWND hDlg, LPPROP_ARRAY_INFO lpPai , BOOL bSomethingChanged, int nPropSheet, LPSPropValue * lppPropArray, LPULONG lpulcPropCount);
  369. BOOL SetDetailsUI(HWND hDlg, LPPROP_ARRAY_INFO lpPai, ULONG ulOperationType,int nPropSheet);
  370. void CreateDateTimeControl(HWND hDlg, int idFrame, int idControl);
  371. void AddLVNewChild(HWND hDlg, LPTSTR lpName);
  372. void ShowExpediaMAP(HWND hDlg, LPMAPIPROP lpPropObj, BOOL bHome);
  373. // [PaulHi] 4/5/99 Raid 57504 Enable the View Map button(s) for all locales.
  374. // [PaulHi] 6/17/99 Raid 80805 Disable the View Map button again for various locales.
  375. void ShowHideMapButton(HWND hWndButton);
  376. HRESULT HrInitDetlsListView(HWND hWndLV, DWORD dwStyle, int nLVType);
  377. void FreeLVParams(HWND hWndLV, int LVType);
  378. void SetLVDefaultEmail( HWND hWndLV, int iItemIndex);
  379. void AddLVEmailItem(HWND hWndLV, LPTSTR lpszEmailAddress, LPTSTR lpszAddrType);
  380. BOOL DeleteLVEmailItem(HWND hWndLV, int iItemIndex);
  381. void ShowURL(HWND hWnd, int id, LPTSTR lpURL);
  382. void SetHTTPPrefix(HWND hDlg, int id);
  383. int AddNewEmailEntry(HWND hDlg, BOOL bShowCancelButton);
  384. void SetDetailsWindowTitle(HWND hDlg, BOOL bModifyDisplayNameField);
  385. void ShowRubyNameEntryDlg(HWND hDlg, LPPROP_ARRAY_INFO lpPai);
  386. void SetComboDNText(HWND hDlg, LPPROP_ARRAY_INFO lpPAI, BOOL bAddAll, LPTSTR szTxt);
  387. void FreeCertList(LPCERT_ITEM * lppCItem);
  388. HRESULT HrSetCertInfoInUI(HWND hDlg, LPSPropValue lpPropMVCert, LPPROP_ARRAY_INFO lpPai);
  389. BOOL AddLVCertItem(HWND hWndLV, LPCERT_ITEM lpCItem, BOOL bCheckForDups);
  390. void SetLVDefaultCert( HWND hWndLV,int iItemIndex);
  391. BOOL DeleteLVCertItem(HWND hWndLV, int iItemIndex, LPPROP_ARRAY_INFO lpPAI);
  392. void ShowCertProps(HWND hDlg, HWND hWndLV, BOOL * lpBool);
  393. BOOL ImportCert(HWND hDlg, LPPROP_ARRAY_INFO lpPai);
  394. BOOL ExportCert(HWND hDlg);
  395. void UpdateCertListView(HWND hDlg, LPPROP_ARRAY_INFO lpPai);
  396. //HRESULT KillTrustInSleazyFashion(HWND hWndLV, int iItem);
  397. void LocalFreeServerItem(LPSERVER_ITEM lpSI);
  398. HRESULT HrAddEmailToObj(LPPROP_ARRAY_INFO lpPai, LPTSTR szEmail, LPTSTR szAddrType);
  399. //$$/////////////////////////////////////////////////////////////////
  400. //
  401. // Ensure lower case character
  402. //
  403. /////////////////////////////////////////////////////////////////////
  404. TCHAR lowercase(TCHAR ch) {
  405. if (ch >= 'A' && ch <= 'Z') {
  406. ch = ch + ('a' - 'A');
  407. }
  408. return(ch);
  409. }
  410. //$$///////////////////////////////////////////////////////////////////
  411. //
  412. // bIsHttpPrefix(LPTSTR szBuf) - verify that the URL is http: not file://fdisk.exe
  413. //
  414. //$$///////////////////////////////////////////////////////////////////
  415. BOOL bIsHttpPrefix(LPTSTR szBuf)
  416. {
  417. // SECURITY: make sure it's http:
  418. if (lstrlen(szBuf) > 5)
  419. {
  420. if (lowercase(szBuf[0]) == 'h' &&
  421. lowercase(szBuf[1]) == 't' &&
  422. lowercase(szBuf[2]) == 't' &&
  423. lowercase(szBuf[3]) == 'p' &&
  424. lowercase(szBuf[4]) == ':')
  425. {
  426. return TRUE;
  427. }
  428. else
  429. {
  430. // BUGBUG: Susan Higgs wants a dialog here, but BruceK thinks
  431. // it's superfluous. If people are nice to each other, we should
  432. // not ever get here. I regard this as a last ditch line of
  433. // security to keep ruthless people from exploiting our use
  434. // of ShellExecute.
  435. DebugTrace( TEXT("Whoa! Somebody's put something other than a web page in the web page slot! %sf\n"), szBuf);
  436. }
  437. }
  438. return FALSE;
  439. }
  440. // TBD - merge these two functions HrShowDetails and HrShowOneOffDetails
  441. //$$///////////////////////////////////////////////////////////////////
  442. //
  443. // HrShowOneOffDetails - shows read-onlydetails for one-off addresses
  444. //
  445. //
  446. // We either pass in a cbEntryID-lpEntryID combination or
  447. // we pass in a ulcValues-lpPropArray combination or
  448. // we pass in a lpPropObj to display
  449. //
  450. // If we are displaying one-off props on a LDAP URL result, the LDAP
  451. // URL is also added so that it can be piped into extension prop sheets
  452. // that need the LDAP URL information
  453. //
  454. //////////////////////////////////////////////////////////////////////
  455. HRESULT HrShowOneOffDetails( LPADRBOOK lpAdrBook,
  456. HWND hWndParent,
  457. ULONG cbEntryID,
  458. LPENTRYID lpEntryID,
  459. ULONG ulObjectType,
  460. LPMAPIPROP lpPropObj,
  461. LPTSTR szLDAPURL,
  462. ULONG ulFlags)
  463. {
  464. HRESULT hr = hrSuccess;
  465. SCODE sc = SUCCESS_SUCCESS;
  466. ULONG cValues = 0;
  467. LPSPropValue lpPropArray = NULL;
  468. ULONG i=0;
  469. PROP_ARRAY_INFO PropArrayInfo = {0};
  470. // if no common control, exit
  471. if (NULL == ghCommCtrlDLLInst) {
  472. hr = ResultFromScode(MAPI_E_UNCONFIGURED);
  473. goto out;
  474. }
  475. if(ulFlags & WAB_ONEOFF_NOADDBUTTON)
  476. {
  477. ulFlags &= ~WAB_ONEOFF_NOADDBUTTON;
  478. PropArrayInfo.ulFlags |= DETAILS_HideAddToWABButton;
  479. }
  480. if ( ((!lpEntryID) && (!lpPropObj)) ||
  481. (ulFlags != SHOW_ONE_OFF))
  482. {
  483. hr = MAPI_E_INVALID_PARAMETER;
  484. goto out;
  485. }
  486. if(cbEntryID && lpEntryID)
  487. {
  488. // if this is a one-off address, do an open entry and then a get props to
  489. // get an lpPropArray from this guy ...
  490. if (HR_FAILED(hr = lpAdrBook->lpVtbl->OpenEntry(lpAdrBook,
  491. cbEntryID, // cbEntryID
  492. lpEntryID, // entryid
  493. NULL, // interface
  494. 0, // ulFlags
  495. &(PropArrayInfo.ulObjectType),
  496. (LPUNKNOWN *)&(PropArrayInfo.lpPropObj) )))
  497. {
  498. // Failed! Hmmm.
  499. if((HR_FAILED(hr)) && (MAPI_E_USER_CANCEL != hr))
  500. {
  501. int ids;
  502. UINT flags = MB_OK | MB_ICONEXCLAMATION;
  503. switch(hr)
  504. {
  505. case MAPI_E_UNABLE_TO_COMPLETE:
  506. case MAPI_E_AMBIGUOUS_RECIP:
  507. ids = idsLDAPAmbiguousRecip;
  508. break;
  509. case MAPI_E_NOT_FOUND:
  510. ids = idsLDAPSearchNoResults;
  511. break;
  512. case MAPI_E_NO_ACCESS:
  513. ids = idsLDAPAccessDenied;
  514. break;
  515. case MAPI_E_TIMEOUT:
  516. ids = idsLDAPSearchTimedOut;
  517. break;
  518. case MAPI_E_NETWORK_ERROR:
  519. ids = idsLDAPCouldNotFindServer;
  520. break;
  521. default:
  522. ids = idsEntryNotFound;
  523. break;
  524. }
  525. ShowMessageBox( hWndParent, ids, flags);
  526. }
  527. goto out;
  528. }
  529. }
  530. else
  531. {
  532. PropArrayInfo.ulObjectType = ulObjectType;
  533. PropArrayInfo.lpPropObj = lpPropObj;
  534. }
  535. if (HR_FAILED(hr = PropArrayInfo.lpPropObj->lpVtbl->GetProps(PropArrayInfo.lpPropObj,
  536. NULL, MAPI_UNICODE,
  537. &cValues, // how many properties were there?
  538. &lpPropArray)))
  539. {
  540. goto out;
  541. }
  542. if (cValues == 0)
  543. {
  544. // nothing to show
  545. hr = E_FAIL;
  546. goto out;
  547. }
  548. else
  549. PropArrayInfo.ulFlags |= DETAILS_ShowSummary;
  550. PropArrayInfo.lpIAB = lpAdrBook;
  551. //Now we can call the property sheets ...
  552. PropArrayInfo.cbEntryID = 0; //this will be ignored for one-offs
  553. PropArrayInfo.lpEntryID = NULL;
  554. PropArrayInfo.bSomethingChanged = FALSE;
  555. for(i=0;i<TOTAL_PROP_SHEETS;i++)
  556. PropArrayInfo.bPropSheetOpened[i] = FALSE;
  557. PropArrayInfo.ulOperationType = SHOW_ONE_OFF;
  558. PropArrayInfo.nRetVal = DETAILS_RESET;
  559. if(InitCryptoLib())
  560. PropArrayInfo.ulFlags |= DETAILS_ShowCerts;
  561. // Do we show the org tab ?
  562. for(i=0;i<cValues;i++)
  563. {
  564. if( lpPropArray[i].ulPropTag == PR_WAB_MANAGER ||
  565. lpPropArray[i].ulPropTag == PR_WAB_REPORTS )
  566. {
  567. PropArrayInfo.ulFlags |= DETAILS_ShowOrg;
  568. break;
  569. }
  570. }
  571. // Check if we need to show the Trident Pane
  572. #ifndef WIN16 // WIN16FF
  573. for(i=0;i<cValues;i++)
  574. {
  575. if(lpPropArray[i].ulPropTag == PR_WAB_LDAP_LABELEDURI)
  576. {
  577. if(lstrlen(lpPropArray[i].Value.LPSZ) &&
  578. bIsHttpPrefix((LPTSTR)lpPropArray[i].Value.LPSZ) )
  579. {
  580. // We have the correct property, now check - do we have Trident installed
  581. // on this machine ???
  582. hr = HrNewWABDocHostObject(&(PropArrayInfo.lpIWABDocHost));
  583. if(!HR_FAILED(hr) && PropArrayInfo.lpIWABDocHost)
  584. {
  585. // Check to see if we can load IE4 and whether its the right
  586. // version of IE4 .. <TBD> this should actually be a global so we
  587. // dont do this for each entry ...
  588. // <TBD> dont hardcode these strings ..
  589. LPDLLGETVERSIONPROCOE lpfnDllGetVersionProc = NULL;
  590. HINSTANCE hTrident = LoadLibrary( TEXT("shdocvw.dll"));
  591. if(hTrident)
  592. {
  593. lpfnDllGetVersionProc = (LPDLLGETVERSIONPROCOE) GetProcAddress(hTrident, "DllGetVersion");
  594. if(lpfnDllGetVersionProc)
  595. {
  596. // Check the version number
  597. DLLVERSIONINFO dvi = {0};
  598. dvi.cbSize = sizeof(dvi);
  599. lpfnDllGetVersionProc(&dvi);
  600. // we are looking for IE4 version 4.71.0544.1 or more
  601. if( dvi.dwMajorVersion > 4 ||
  602. (dvi.dwMajorVersion == 4 && dvi.dwMinorVersion >= 71 && dvi.dwBuildNumber >= 544))
  603. {
  604. PropArrayInfo.ulFlags |= DETAILS_ShowTrident;
  605. }
  606. }
  607. FreeLibrary(hTrident);
  608. }
  609. }
  610. }
  611. break;
  612. }
  613. }
  614. #endif
  615. // if this is an ldap entry, turn the ldap entryid into an ldapurl and pass that
  616. // to the extension prop sheets .. this enables the NTDS prop sheets to appropriately
  617. // display themselves ..
  618. if( cbEntryID && lpEntryID )
  619. {
  620. LPTSTR lpURL = NULL;
  621. CreateLDAPURLFromEntryID(cbEntryID, lpEntryID, &lpURL, &PropArrayInfo.bIsNTDSURL);
  622. PropArrayInfo.lpLDAPURL = lpURL;
  623. }
  624. else
  625. PropArrayInfo.lpLDAPURL = szLDAPURL;
  626. GetExtDisplayInfo((LPIAB)lpAdrBook, &PropArrayInfo, TRUE, TRUE);
  627. if (CreateDetailsPropertySheet(hWndParent,&PropArrayInfo) == -1)
  628. {
  629. // Something failed ...
  630. hr = E_FAIL;
  631. goto out;
  632. }
  633. // This was a read only operation so we dont care for the results ...
  634. // so nothing more to do ....
  635. if(PropArrayInfo.nRetVal == DETAILS_ADDTOWAB)
  636. {
  637. ULONG cbEID = 0, cbPABEID = 0;
  638. LPENTRYID lpEID = NULL, lpPABEID = NULL;
  639. // We need to strip out the PR_WAB_LDAP_LABELEDURI prop and the
  640. // old entryid if it exists
  641. for(i=0;i<cValues;i++)
  642. {
  643. switch(lpPropArray[i].ulPropTag)
  644. {
  645. case PR_WAB_LDAP_LABELEDURI:
  646. // remove the ldap url from this object
  647. case PR_ENTRYID:
  648. lpPropArray[i].ulPropTag = PR_NULL;
  649. break;
  650. }
  651. if(lpPropArray[i].ulPropTag == PR_WAB_MANAGER ||
  652. lpPropArray[i].ulPropTag == PR_WAB_REPORTS )
  653. lpPropArray[i].ulPropTag = PR_NULL;
  654. }
  655. if(!HR_FAILED(hr = lpAdrBook->lpVtbl->GetPAB(lpAdrBook, &cbPABEID, &lpPABEID)))
  656. {
  657. hr = HrCreateNewEntry( lpAdrBook,
  658. hWndParent,
  659. MAPI_MAILUSER, //MAILUSER or DISTLIST
  660. cbPABEID, lpPABEID,
  661. MAPI_ABCONT,//container entryid
  662. CREATE_CHECK_DUP_STRICT,
  663. TRUE,
  664. cValues,
  665. lpPropArray,
  666. &cbEID,
  667. &lpEID);
  668. }
  669. if(lpPABEID)
  670. MAPIFreeBuffer(lpPABEID);
  671. if(lpEID)
  672. MAPIFreeBuffer(lpEID);
  673. }
  674. out:
  675. if(PropArrayInfo.lpLDAPURL && PropArrayInfo.lpLDAPURL!=szLDAPURL)
  676. LocalFree(PropArrayInfo.lpLDAPURL);
  677. LocalFreeAndNull(&PropArrayInfo.lpszOldName);
  678. FreeExtDisplayInfo(&PropArrayInfo);
  679. if(PropArrayInfo.szDefaultServerName)
  680. LocalFree(PropArrayInfo.szDefaultServerName);
  681. if(PropArrayInfo.szBackupServerName)
  682. LocalFree(PropArrayInfo.szBackupServerName);
  683. if(PropArrayInfo.lpIWABDocHost)
  684. (PropArrayInfo.lpIWABDocHost)->lpVtbl->Release(PropArrayInfo.lpIWABDocHost);
  685. if(PropArrayInfo.lpPropObj && !lpPropObj)
  686. PropArrayInfo.lpPropObj->lpVtbl->Release(PropArrayInfo.lpPropObj);
  687. if(lpPropArray)
  688. MAPIFreeBuffer(lpPropArray);
  689. return hr;
  690. }
  691. //$$/////////////////////////////////////////////////////////////////
  692. //
  693. // HrShowDetails - shows details/new entry UI
  694. //
  695. // lpIAB - lpAdrBook object
  696. // hWndParent - hWnd of parent
  697. // hPropertyStore - Handle to property store (can be retrieved from lpIAB)
  698. // cbEIDContainer - EntryID of container in which to create the entry
  699. // lpEIDContainer - EntryID of container in which to create the entry
  700. // lppEntryID - entry id of object to display .. if a new object,
  701. // contains the lpentryid of the created object
  702. // lpPropObj - sometimes used in lieu of the entryid .. useful for
  703. // adding objects like vCards and LDAP entries which have
  704. // an object but dont currently exist in the WAB
  705. // ulFlags - unused
  706. // lpbChangesMade - Indicates if object was modified or not
  707. //
  708. ///////////////////////////////////////////////////////////////////
  709. HRESULT HrShowDetails( LPADRBOOK lpIAB,
  710. HWND hWndParent,
  711. HANDLE hPropertyStore,
  712. ULONG cbEIDContainer,
  713. LPENTRYID lpEIDContainer,
  714. ULONG *lpcbEntryID,
  715. LPENTRYID *lppEntryID,
  716. LPMAPIPROP lpPropObj, // [optional] IN:IMAPIProp object
  717. ULONG ulFlags,
  718. ULONG ulObjectType,
  719. BOOL * lpbChangesMade)
  720. {
  721. HRESULT hr = hrSuccess;
  722. SCODE sc = SUCCESS_SUCCESS;
  723. ULONG cbpta = 0;
  724. ULONG ulNumOldProps = 0;
  725. ULONG cbEntryID = 0;
  726. LPENTRYID lpEntryID = NULL;
  727. int nRet = 0, nRetVal = 0;
  728. ULONG i = 0, j = 0, k = 0;
  729. PROP_ARRAY_INFO PropArrayInfo = {0};
  730. BOOL bChanges = FALSE;
  731. ULONG nMaxSheets = 0;
  732. DebugPrintTrace(( TEXT("----------\nHrShowDetails Entry\n")));
  733. // if no common control, exit
  734. if (NULL == ghCommCtrlDLLInst) {
  735. hr = ResultFromScode(MAPI_E_UNCONFIGURED);
  736. goto out;
  737. }
  738. if(lppEntryID)
  739. lpEntryID = *lppEntryID;
  740. if (lpcbEntryID)
  741. cbEntryID = *lpcbEntryID;
  742. if ( (!(ulFlags & SHOW_OBJECT) && hPropertyStore == NULL) ||
  743. ( (ulFlags & SHOW_DETAILS) && (lpEntryID == NULL)) ||
  744. ( (ulFlags & SHOW_OBJECT) && (lpPropObj == NULL)))
  745. {
  746. hr = MAPI_E_INVALID_PARAMETER;
  747. goto out;
  748. }
  749. if(cbEntryID && lpEntryID)
  750. {
  751. PropArrayInfo.cbEntryID = cbEntryID;
  752. PropArrayInfo.lpEntryID = LocalAlloc(LMEM_ZEROINIT, cbEntryID);
  753. CopyMemory(PropArrayInfo.lpEntryID, lpEntryID, cbEntryID);
  754. PropArrayInfo.ulFlags |= DETAILS_ShowSummary;
  755. }
  756. else if (ulFlags & SHOW_DETAILS)
  757. {
  758. // cant show details without a valid entryid
  759. hr = MAPI_E_INVALID_PARAMETER;
  760. goto out;
  761. }
  762. *lpbChangesMade = FALSE;
  763. if (ulFlags & SHOW_DETAILS)
  764. {
  765. if (HR_FAILED(hr = lpIAB->lpVtbl->OpenEntry(lpIAB,
  766. cbEntryID, // cbEntryID
  767. lpEntryID, // entryid
  768. NULL, // interface
  769. MAPI_BEST_ACCESS, // ulFlags
  770. &(PropArrayInfo.ulObjectType),
  771. (LPUNKNOWN *)&(PropArrayInfo.lpPropObj) )))
  772. {
  773. // Failed! Hmmm.
  774. goto out;
  775. }
  776. }
  777. else if (ulFlags & SHOW_OBJECT)
  778. {
  779. Assert(lpPropObj);
  780. PropArrayInfo.lpPropObj = lpPropObj;
  781. PropArrayInfo.ulObjectType = ulObjectType;
  782. }
  783. else
  784. {
  785. SBinary sb = {0};
  786. sb.cb = cbEIDContainer;
  787. sb.lpb = (LPBYTE) lpEIDContainer;
  788. if(HR_FAILED(hr = HrCreateNewObject( lpIAB,
  789. &sb,
  790. ulObjectType,
  791. 0,
  792. &(PropArrayInfo.lpPropObj))))
  793. {
  794. goto out;
  795. }
  796. PropArrayInfo.ulObjectType = ulObjectType;
  797. PropArrayInfo.cbEntryID = 0;
  798. PropArrayInfo.lpEntryID = NULL;
  799. PropArrayInfo.ulFlags |= DETAILS_DNisFMLName;
  800. }
  801. PropArrayInfo.lpIAB = lpIAB;
  802. nMaxSheets = (ulObjectType == MAPI_DISTLIST) ? propDLMax : TOTAL_PROP_SHEETS;
  803. for(i=0;i<nMaxSheets;i++)
  804. PropArrayInfo.bPropSheetOpened[i] = FALSE;
  805. PropArrayInfo.ulOperationType = ulFlags;
  806. PropArrayInfo.nRetVal = DETAILS_RESET;
  807. PropArrayInfo.bSomethingChanged = FALSE;
  808. if(InitCryptoLib())
  809. PropArrayInfo.ulFlags |= DETAILS_ShowCerts;
  810. // Never show trident for regular people - only for LDAP contacts
  811. // PropArrayInfo.bShowTrident = FALSE;
  812. GetExtDisplayInfo((LPIAB) lpIAB, &PropArrayInfo, FALSE, (ulObjectType == MAPI_MAILUSER));
  813. if(ulObjectType == MAPI_MAILUSER)
  814. {
  815. if (CreateDetailsPropertySheet(hWndParent,&PropArrayInfo) == -1)
  816. {
  817. // Something failed ...
  818. hr = E_FAIL;
  819. goto out;
  820. }
  821. }
  822. else
  823. {
  824. if (CreateDLPropertySheet(hWndParent,&PropArrayInfo) == -1)
  825. {
  826. // Something failed ...
  827. hr = E_FAIL;
  828. goto out;
  829. }
  830. }
  831. if (PropArrayInfo.nRetVal == DETAILS_CANCEL)
  832. {
  833. hr = MAPI_E_USER_CANCEL;
  834. goto out;
  835. }
  836. bChanges = PropArrayInfo.bSomethingChanged;
  837. /*
  838. if(!bChanges)
  839. {
  840. for(i=0;i<nMaxSheets;i++)
  841. {
  842. if(PropArrayInfo.bPropSheetOpened[i])
  843. {
  844. // The returned prop array is not null
  845. // or the sheet was opened (which should return something) but
  846. // the returned array is null (which means every thing on that
  847. // particular sheet has been deleted).
  848. bChanges = TRUE;
  849. break;
  850. }
  851. }
  852. }
  853. */
  854. if(!bChanges && PropArrayInfo.lpWED)
  855. {
  856. if(PropArrayInfo.lpWED->fDataChanged)
  857. {
  858. bChanges = TRUE;
  859. }
  860. }
  861. if (!bChanges) goto out;
  862. // if its an object, dont save changes yet
  863. if(!(ulFlags & SHOW_OBJECT))
  864. {
  865. // Bug: 56220 - a retail-only bug in which for some reason the ObjAccess flag on
  866. // Groups gets reset to IPROP_READONLY which causes a write failure. I can't figure out
  867. // the cause for the problem but as a temporary solution, I'm forcing the access flag to
  868. // say READWRITE and everythng works fine then. Note that if we're at this code point, then
  869. // the object flag will ALWAYS be READWRITE anyway
  870. ((LPMailUser)PropArrayInfo.lpPropObj)->ulObjAccess = IPROP_READWRITE;
  871. hr = (PropArrayInfo.lpPropObj)->lpVtbl->SaveChanges( (PropArrayInfo.lpPropObj), // this
  872. KEEP_OPEN_READWRITE);
  873. if(hr == MAPI_E_NOT_ENOUGH_DISK)
  874. hr = HandleSaveChangedInsufficientDiskSpace( hWndParent,
  875. (LPMAILUSER) PropArrayInfo.lpPropObj);
  876. *lpbChangesMade = TRUE;
  877. }
  878. // if we want entryids back, make sure we get them
  879. {
  880. if(lppEntryID && lpcbEntryID && !*lppEntryID && !*lpcbEntryID)
  881. {
  882. LPSPropValue lpSPV = NULL;
  883. ULONG ulSPV = 0;
  884. if(!HR_FAILED(hr = (PropArrayInfo.lpPropObj)->lpVtbl->GetProps(PropArrayInfo.lpPropObj,
  885. (LPSPropTagArray)&ptaEid, MAPI_UNICODE,
  886. &ulSPV, &lpSPV)))
  887. {
  888. if(lpSPV[ieidPR_ENTRYID].ulPropTag == PR_ENTRYID)
  889. {
  890. sc = MAPIAllocateBuffer(lpSPV[ieidPR_ENTRYID].Value.bin.cb, lppEntryID);
  891. if(!sc)
  892. {
  893. *lpcbEntryID = lpSPV[ieidPR_ENTRYID].Value.bin.cb;
  894. CopyMemory(*lppEntryID, lpSPV[ieidPR_ENTRYID].Value.bin.lpb, *lpcbEntryID);
  895. }
  896. }
  897. MAPIFreeBuffer(lpSPV);
  898. }
  899. }
  900. }
  901. hr = S_OK;
  902. out:
  903. FreeExtDisplayInfo(&PropArrayInfo);
  904. LocalFreeAndNull(&PropArrayInfo.lpszOldName);
  905. if(PropArrayInfo.szDefaultServerName)
  906. LocalFree(PropArrayInfo.szDefaultServerName);
  907. if(PropArrayInfo.szBackupServerName)
  908. LocalFree(PropArrayInfo.szBackupServerName);
  909. if(PropArrayInfo.lpEntryID)
  910. LocalFree(PropArrayInfo.lpEntryID);
  911. if(PropArrayInfo.lpPropObj && !lpPropObj)
  912. PropArrayInfo.lpPropObj->lpVtbl->Release(PropArrayInfo.lpPropObj);
  913. return hr;
  914. }
  915. /*//$$***************************************************************************
  916. * FUNCTION: CreateDetailsPropertySheet(HWND)
  917. *
  918. * PURPOSE: Creates the Details property sheet
  919. *
  920. ****************************************************************************/
  921. int CreateDetailsPropertySheet(HWND hwndOwner,
  922. LPPROP_ARRAY_INFO lpPropArrayInfo)
  923. {
  924. PROPSHEETPAGE psp[TOTAL_PROP_SHEETS];
  925. PROPSHEETHEADER psh;
  926. //TCHAR szBuf[TOTAL_PROP_SHEETS][MAX_UI_STR];
  927. LPTSTR * szBuf = NULL;
  928. TCHAR szBuf2[MAX_UI_STR];
  929. ULONG ulProp = 0;
  930. ULONG ulTotal = 0;
  931. HPROPSHEETPAGE * lph = NULL;
  932. ULONG ulCount = 0;
  933. int i = 0;
  934. int nRet = 0;
  935. BOOL bRet = FALSE;
  936. // If it's an NTDS entry and we have the requisite prop sheets, then we are going to hide the
  937. // WAB's version of the prop sheets and show the NTDS ones upfront instead
  938. //
  939. // NTDS folks want us to hide the following: personal, home, business and other
  940. //
  941. BOOL bShowNTDSProps = ( lpPropArrayInfo->nNTDSPropSheetPages &&
  942. lpPropArrayInfo->lphNTDSpages &&
  943. lpPropArrayInfo->bIsNTDSURL);
  944. ulTotal = TOTAL_PROP_SHEETS // Predefined ones +
  945. + lpPropArrayInfo->nPropSheetPages
  946. + lpPropArrayInfo->nNTDSPropSheetPages;
  947. if(!(szBuf = LocalAlloc(LMEM_ZEROINIT, sizeof(LPTSTR)*TOTAL_PROP_SHEETS)))
  948. goto out;
  949. for(i=0;i<TOTAL_PROP_SHEETS;i++)
  950. {
  951. if(!(szBuf[i] = LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*MAX_UI_STR)))
  952. goto out;
  953. }
  954. lph = LocalAlloc(LMEM_ZEROINIT, sizeof(HPROPSHEETPAGE) * ulTotal);
  955. if(!lph)
  956. goto out;
  957. psh.nStartPage = 0;
  958. //
  959. // Initialize info for the various property sheets
  960. //
  961. if( (lpPropArrayInfo->ulFlags & DETAILS_ShowSummary) && !bShowNTDSProps )
  962. {
  963. // Personal
  964. psp[propSummary].dwSize = sizeof(PROPSHEETPAGE);
  965. psp[propSummary].dwFlags = PSP_USETITLE;
  966. psp[propSummary].hInstance = hinstMapiX;
  967. psp[propSummary].pszTemplate = MAKEINTRESOURCE(IDD_DETAILS_SUMMARY);
  968. psp[propSummary].pszIcon = NULL;
  969. psp[propSummary].pfnDlgProc = fnSummaryProc;
  970. LoadString(hinstMapiX, idsDetailsSummaryTitle, szBuf[propSummary], MAX_UI_STR);
  971. psp[propSummary].pszTitle = szBuf[propSummary];
  972. psp[propSummary].lParam = (LPARAM) lpPropArrayInfo;
  973. lph[ulCount] = gpfnCreatePropertySheetPage(&(psp[propSummary]));
  974. if(lph[ulCount])
  975. ulCount++;
  976. // Start page is personal page
  977. psh.nStartPage = propSummary;
  978. }
  979. if(!bShowNTDSProps)
  980. {
  981. // Personal
  982. // Check if this is Japan/China/Korea and use the RUBY personal prop sheet instead
  983. if(bIsRubyLocale())
  984. lpPropArrayInfo->ulFlags |= DETAILS_UseRubyPersonal;
  985. psp[propPersonal].dwSize = sizeof(PROPSHEETPAGE);
  986. psp[propPersonal].dwFlags = PSP_USETITLE;
  987. psp[propPersonal].hInstance = hinstMapiX;
  988. psp[propPersonal].pszTemplate = MAKEINTRESOURCE((lpPropArrayInfo->ulFlags & DETAILS_UseRubyPersonal) ? IDD_DETAILS_PERSONAL_RUBY : IDD_DETAILS_PERSONAL);
  989. psp[propPersonal].pszIcon = NULL;
  990. psp[propPersonal].pfnDlgProc = fnPersonalProc;
  991. LoadString(hinstMapiX, idsName, szBuf[propPersonal], MAX_UI_STR);
  992. psp[propPersonal].pszTitle = szBuf[propPersonal];
  993. psp[propPersonal].lParam = (LPARAM) lpPropArrayInfo;
  994. lph[ulCount] = gpfnCreatePropertySheetPage(&(psp[propPersonal]));
  995. if(lph[ulCount])
  996. ulCount++;
  997. }
  998. if(!bShowNTDSProps)
  999. {
  1000. // Home
  1001. psp[propHome].dwSize = sizeof(PROPSHEETPAGE);
  1002. psp[propHome].dwFlags = PSP_USETITLE;
  1003. psp[propHome].hInstance = hinstMapiX;
  1004. psp[propHome].pszTemplate = MAKEINTRESOURCE(IDD_DETAILS_HOME);
  1005. psp[propHome].pszIcon = NULL;
  1006. psp[propHome].pfnDlgProc = fnHomeProc;
  1007. LoadString(hinstMapiX, idsDetailsHomeTitle, szBuf[propHome], MAX_UI_STR);
  1008. psp[propHome].pszTitle = szBuf[propHome];
  1009. psp[propHome].lParam = (LPARAM) lpPropArrayInfo;
  1010. lph[ulCount] = gpfnCreatePropertySheetPage(&(psp[propHome]));
  1011. if(lph[ulCount])
  1012. ulCount++;
  1013. }
  1014. if(!bShowNTDSProps)
  1015. {
  1016. // Business
  1017. psp[propBusiness].dwSize = sizeof(PROPSHEETPAGE);
  1018. psp[propBusiness].dwFlags = PSP_USETITLE;
  1019. psp[propBusiness].hInstance = hinstMapiX;
  1020. psp[propBusiness].pszTemplate = MAKEINTRESOURCE(IDD_DETAILS_BUSINESS);
  1021. psp[propBusiness].pszIcon = NULL;
  1022. psp[propBusiness].pfnDlgProc = fnBusinessProc;
  1023. LoadString(hinstMapiX, idsDetailsBusinessTitle, szBuf[propBusiness], MAX_UI_STR);
  1024. psp[propBusiness].pszTitle = szBuf[propBusiness];
  1025. psp[propBusiness].lParam = (LPARAM) lpPropArrayInfo;
  1026. lph[ulCount] = gpfnCreatePropertySheetPage(&(psp[propBusiness]));
  1027. if(lph[ulCount])
  1028. ulCount++;
  1029. }
  1030. if(!bShowNTDSProps)
  1031. {
  1032. psp[propFamily].dwSize = sizeof(PROPSHEETPAGE);
  1033. psp[propFamily].dwFlags = PSP_USETITLE;
  1034. psp[propFamily].hInstance = hinstMapiX;
  1035. psp[propFamily].pszTemplate = MAKEINTRESOURCE(IDD_DETAILS_FAMILY);
  1036. psp[propFamily].pszIcon = NULL;
  1037. psp[propFamily].pfnDlgProc = fnFamilyProc;
  1038. LoadString(hinstMapiX, idsDetailsPersonalTitle, szBuf[propFamily], MAX_UI_STR);
  1039. psp[propFamily].pszTitle = szBuf[propFamily];
  1040. psp[propFamily].lParam = (LPARAM) lpPropArrayInfo;
  1041. lph[ulCount] = gpfnCreatePropertySheetPage(&(psp[propFamily]));
  1042. if(lph[ulCount])
  1043. ulCount++;
  1044. }
  1045. if(!bShowNTDSProps)
  1046. {
  1047. // Notes
  1048. psp[propNotes].dwSize = sizeof(PROPSHEETPAGE);
  1049. psp[propNotes].dwFlags = PSP_USETITLE;
  1050. psp[propNotes].hInstance = hinstMapiX;
  1051. psp[propNotes].pszTemplate = MAKEINTRESOURCE(IDD_DETAILS_NOTES);
  1052. psp[propNotes].pszIcon = NULL;
  1053. psp[propNotes].pfnDlgProc = fnNotesProc;
  1054. LoadString(hinstMapiX, idsDetailsNotesTitle, szBuf[propNotes], MAX_UI_STR);
  1055. psp[propNotes].pszTitle = szBuf[propNotes];
  1056. psp[propNotes].lParam = (LPARAM) lpPropArrayInfo;
  1057. lph[ulCount] = gpfnCreatePropertySheetPage(&(psp[propNotes]));
  1058. if(lph[ulCount])
  1059. ulCount++;
  1060. }
  1061. if(bShowNTDSProps) //now insert the NTDS props at this point instead of the above lot..
  1062. {
  1063. // Now do the extended props if any
  1064. for(i=0;i<lpPropArrayInfo->nNTDSPropSheetPages;i++)
  1065. {
  1066. if(lpPropArrayInfo->lphNTDSpages)
  1067. {
  1068. lph[ulCount] = lpPropArrayInfo->lphNTDSpages[i];
  1069. ulCount++;
  1070. }
  1071. }
  1072. }
  1073. // Conferencing
  1074. psp[propConferencing].dwSize = sizeof(PROPSHEETPAGE);
  1075. psp[propConferencing].dwFlags = PSP_USETITLE;
  1076. psp[propConferencing].hInstance = hinstMapiX;
  1077. psp[propConferencing].pszTemplate = MAKEINTRESOURCE(IDD_DETAILS_NTMTG);
  1078. psp[propConferencing].pszIcon = NULL;
  1079. psp[propConferencing].pfnDlgProc = fnConferencingProc;
  1080. {
  1081. TCHAR sz[MAX_PATH];
  1082. LONG cbSize = CharSizeOf(sz);
  1083. *sz='\0';
  1084. if(RegQueryValue(HKEY_LOCAL_MACHINE, szInternetCallKey, sz, &cbSize) == ERROR_SUCCESS
  1085. && lstrlen(sz)
  1086. && !lstrcmpi(sz,TEXT("Microsoft NetMeeting")))
  1087. {
  1088. StrCpyN(szBuf[propConferencing], TEXT("NetMeeting"), MAX_UI_STR);
  1089. }
  1090. else
  1091. LoadString(hinstMapiX, idsDetailsConferencingTitle, szBuf[propConferencing], MAX_UI_STR);
  1092. }
  1093. psp[propConferencing].pszTitle = szBuf[propConferencing];
  1094. psp[propConferencing].lParam = (LPARAM) lpPropArrayInfo;
  1095. lph[ulCount] = gpfnCreatePropertySheetPage(&(psp[propConferencing]));
  1096. if(lph[ulCount])
  1097. ulCount++;
  1098. ulProp = propConferencing + 1;
  1099. if(lpPropArrayInfo->ulFlags & DETAILS_ShowCerts)
  1100. {
  1101. // Certificates
  1102. psp[ulProp].dwSize = sizeof(PROPSHEETPAGE);
  1103. psp[ulProp].dwFlags = PSP_USETITLE;
  1104. psp[ulProp].hInstance = hinstMapiX;
  1105. psp[ulProp].pszTemplate = MAKEINTRESOURCE(IDD_DETAILS_CERT);
  1106. psp[ulProp].pszIcon = NULL;
  1107. psp[ulProp].pfnDlgProc = fnCertProc;
  1108. LoadString(hinstMapiX, idsDetailsCertTitle, szBuf[propCert], MAX_UI_STR);
  1109. psp[ulProp].pszTitle = szBuf[propCert];
  1110. psp[ulProp].lParam = (LPARAM) lpPropArrayInfo;
  1111. lph[ulCount] = gpfnCreatePropertySheetPage(&(psp[ulProp]));
  1112. if(lph[ulCount])
  1113. ulCount++;
  1114. ulProp++;
  1115. }
  1116. if( !bShowNTDSProps &&
  1117. (lpPropArrayInfo->ulFlags & DETAILS_ShowOrg) )
  1118. {
  1119. // Organization
  1120. psp[ulProp].dwSize = sizeof(PROPSHEETPAGE);
  1121. psp[ulProp].dwFlags = PSP_USETITLE;
  1122. psp[ulProp].hInstance = hinstMapiX;
  1123. psp[ulProp].pszTemplate = MAKEINTRESOURCE(IDD_DETAILS_ORG);
  1124. psp[ulProp].pszIcon = NULL;
  1125. psp[ulProp].pfnDlgProc = fnOrgProc;
  1126. LoadString(hinstMapiX, idsDetailsOrgTitle, szBuf[propOrg], MAX_UI_STR);
  1127. psp[ulProp].pszTitle = szBuf[propOrg];
  1128. psp[ulProp].lParam = (LPARAM) lpPropArrayInfo;
  1129. lph[ulCount] = gpfnCreatePropertySheetPage(&(psp[ulProp]));
  1130. if(lph[ulCount])
  1131. ulCount++;
  1132. ulProp++;
  1133. }
  1134. if(lpPropArrayInfo->ulFlags & DETAILS_ShowTrident)
  1135. {
  1136. // Trident sheet
  1137. psp[ulProp].dwSize = sizeof(PROPSHEETPAGE);
  1138. psp[ulProp].dwFlags = PSP_USETITLE;
  1139. psp[ulProp].hInstance = hinstMapiX;
  1140. psp[ulProp].pszTemplate = MAKEINTRESOURCE(IDD_DETAILS_TRIDENT);
  1141. psp[ulProp].pszIcon = NULL;
  1142. psp[ulProp].pfnDlgProc = fnTridentProc;
  1143. LoadString(hinstMapiX, idsDetailsTridentTitle, szBuf[propTrident], MAX_UI_STR);
  1144. psp[ulProp].pszTitle = szBuf[propTrident];
  1145. psp[ulProp].lParam = (LPARAM) lpPropArrayInfo;
  1146. lph[ulCount] = gpfnCreatePropertySheetPage(&(psp[ulProp]));
  1147. if(lph[ulCount])
  1148. {
  1149. // Start page is trident page
  1150. psh.nStartPage = ulCount;
  1151. ulCount++;
  1152. }
  1153. lpPropArrayInfo->ulTridentPageIndex = ulProp;
  1154. ulProp++;
  1155. }
  1156. // Now do the extended props if any
  1157. for(i=0;i<lpPropArrayInfo->nPropSheetPages;i++)
  1158. {
  1159. if(lpPropArrayInfo->lphpages)
  1160. {
  1161. lph[ulCount] = lpPropArrayInfo->lphpages[i];
  1162. ulCount++;
  1163. }
  1164. }
  1165. /*** US dialogs get truncated on FE OSes .. we want the comctl to fix the truncation
  1166. but this is only implemented in IE4.01 and beyond .. the problem with this being
  1167. that wab is specifically compiled with the IE = 0x0300 so we're not pulling in the
  1168. correct flag from the commctrl header .. so we will define the flag here and pray
  1169. that commctrl never changes it ***/
  1170. #define PSH_USEPAGELANG 0x00200000 // use frame dialog template matched to page
  1171. /*** ***/
  1172. psh.dwSize = sizeof(PROPSHEETHEADER);
  1173. psh.dwFlags = PSH_NOAPPLYNOW;
  1174. if(bIsIE401OrGreater())
  1175. psh.dwFlags |= PSH_USEPAGELANG;
  1176. psh.hwndParent = hwndOwner;
  1177. psh.hInstance = hinstMapiX;
  1178. psh.pszIcon = NULL;
  1179. LoadString(hinstMapiX, IDS_DETAILS_CAPTION, szBuf2, CharSizeOf(szBuf2));
  1180. psh.pszCaption = szBuf2;
  1181. psh.nPages = ulCount; // ulProp //sizeof(psp) / sizeof(PROPSHEETPAGE);
  1182. psh.phpage = lph;
  1183. nRet = (int) gpfnPropertySheet(&psh);
  1184. bRet = TRUE;
  1185. out:
  1186. LocalFreeAndNull((LPVOID*)&lph);
  1187. if(szBuf)
  1188. {
  1189. for(i=0;i<TOTAL_PROP_SHEETS;i++)
  1190. LocalFreeAndNull(&(szBuf[i]));
  1191. LocalFreeAndNull((LPVOID*)&szBuf);
  1192. }
  1193. return nRet;
  1194. }
  1195. /* Filling in the Data in a Prop Sheet
  1196. Since most props handled in the UI are string props, and it's just a
  1197. matter of doing SetText/GetText with the data on the appropriate edit
  1198. control, we create control-property pairs of edit-controls and string props
  1199. and use them to fill in props in a simple loop
  1200. Non string props and named props end up needing special handling
  1201. */
  1202. typedef struct _tagIDProp
  1203. {
  1204. ULONG ulPropTag;
  1205. int idCtl;
  1206. } ID_PROP;
  1207. // Control IDs corresponding to the Personal property sheet
  1208. ID_PROP idPropPersonal[]=
  1209. {
  1210. {PR_DISPLAY_NAME, IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME},
  1211. {PR_GIVEN_NAME, IDC_DETAILS_PERSONAL_EDIT_FIRSTNAME},
  1212. {PR_SURNAME, IDC_DETAILS_PERSONAL_EDIT_LASTNAME},
  1213. {PR_MIDDLE_NAME, IDC_DETAILS_PERSONAL_EDIT_MIDDLENAME},
  1214. {PR_NICKNAME, IDC_DETAILS_PERSONAL_EDIT_NICKNAME},
  1215. {PR_DISPLAY_NAME_PREFIX, IDC_DETAILS_PERSONAL_EDIT_TITLE},
  1216. {0, IDC_DETAILS_PERSONAL_EDIT_ADDEMAIL},
  1217. {PR_NULL/*YOMI_LAST*/,IDC_DETAILS_PERSONAL_STATIC_RUBYLAST},
  1218. {PR_NULL/*YOMI_FIRST*/,IDC_DETAILS_PERSONAL_STATIC_RUBYFIRST}
  1219. };
  1220. const ULONG idPropPersonalCount = 9;
  1221. // Control IDs corresponding to the Home property sheet
  1222. ID_PROP idPropHome[]=
  1223. {
  1224. {PR_HOME_ADDRESS_STREET, IDC_DETAILS_HOME_EDIT_ADDRESS},
  1225. {PR_HOME_ADDRESS_CITY, IDC_DETAILS_HOME_EDIT_CITY},
  1226. {PR_HOME_ADDRESS_POSTAL_CODE, IDC_DETAILS_HOME_EDIT_ZIP},
  1227. {PR_HOME_ADDRESS_STATE_OR_PROVINCE, IDC_DETAILS_HOME_EDIT_STATE},
  1228. {PR_HOME_ADDRESS_COUNTRY, IDC_DETAILS_HOME_EDIT_COUNTRY},
  1229. {PR_PERSONAL_HOME_PAGE, IDC_DETAILS_HOME_EDIT_URL},
  1230. {PR_HOME_TELEPHONE_NUMBER, IDC_DETAILS_HOME_EDIT_PHONE},
  1231. {PR_HOME_FAX_NUMBER, IDC_DETAILS_HOME_EDIT_FAX},
  1232. {PR_CELLULAR_TELEPHONE_NUMBER, IDC_DETAILS_HOME_EDIT_CELLULAR},
  1233. {PR_NULL/*PR_WAB_POSTALID*/, IDC_DETAILS_HOME_CHECK_DEFAULTADDRESS},
  1234. };
  1235. #define idPropHomePostalID 9 // since POSTALID is dynamically generated prop, it needs to be reset anytime the array is used
  1236. const ULONG idPropHomeCount = 10;
  1237. // Control IDs corresponding to the Business property sheet
  1238. ID_PROP idPropBusiness[]=
  1239. {
  1240. {PR_BUSINESS_ADDRESS_STREET, IDC_DETAILS_BUSINESS_EDIT_ADDRESS},
  1241. {PR_BUSINESS_ADDRESS_CITY, IDC_DETAILS_BUSINESS_EDIT_CITY},
  1242. {PR_BUSINESS_ADDRESS_POSTAL_CODE, IDC_DETAILS_BUSINESS_EDIT_ZIP},
  1243. {PR_BUSINESS_ADDRESS_STATE_OR_PROVINCE, IDC_DETAILS_BUSINESS_EDIT_STATE},
  1244. {PR_BUSINESS_ADDRESS_COUNTRY, IDC_DETAILS_BUSINESS_EDIT_COUNTRY},
  1245. {PR_BUSINESS_HOME_PAGE, IDC_DETAILS_BUSINESS_EDIT_URL},
  1246. {PR_BUSINESS_TELEPHONE_NUMBER, IDC_DETAILS_BUSINESS_EDIT_PHONE},
  1247. {PR_BUSINESS_FAX_NUMBER, IDC_DETAILS_BUSINESS_EDIT_FAX},
  1248. {PR_PAGER_TELEPHONE_NUMBER, IDC_DETAILS_BUSINESS_EDIT_PAGER},
  1249. {PR_COMPANY_NAME, IDC_DETAILS_BUSINESS_EDIT_COMPANY},
  1250. {PR_TITLE, IDC_DETAILS_BUSINESS_EDIT_JOBTITLE},
  1251. {PR_DEPARTMENT_NAME, IDC_DETAILS_BUSINESS_EDIT_DEPARTMENT},
  1252. {PR_OFFICE_LOCATION, IDC_DETAILS_BUSINESS_EDIT_OFFICE},
  1253. {PR_NULL/*PR_WAB_IPPHONE*/, IDC_DETAILS_BUSINESS_EDIT_IPPHONE},
  1254. {PR_NULL/*PR_WAB_POSTALID*/, IDC_DETAILS_BUSINESS_CHECK_DEFAULTADDRESS},
  1255. };
  1256. #define idPropBusIPPhone 13 // since PR_WAB_IPPHONE is dynamically generated prop, it needs to be reset anytime the array is used
  1257. #define idPropBusPostalID 14 // since POSTALID is dynamically generated prop, it needs to be reset anytime the array is used
  1258. const ULONG idPropBusinessCount = 15;
  1259. // Control IDs corresponding to the Notes property sheet
  1260. ID_PROP idPropNotes[] =
  1261. {
  1262. {PR_COMMENT, IDC_DETAILS_NOTES_EDIT_NOTES} //PR_COMMENT
  1263. };
  1264. const ULONG idPropNotesCount = 1;
  1265. // Control IDs corresponding to the Family property sheet
  1266. ID_PROP idPropFamily[] =
  1267. {
  1268. {PR_SPOUSE_NAME, IDC_DETAILS_FAMILY_EDIT_SPOUSE},
  1269. {PR_GENDER, IDC_DETAILS_HOME_COMBO_GENDER},
  1270. {PR_BIRTHDAY, IDC_DETAILS_FAMILY_DATE_BIRTHDAY},
  1271. {PR_WEDDING_ANNIVERSARY, IDC_DETAILS_FAMILY_DATE_ANNIVERSARY},
  1272. {PR_CHILDRENS_NAMES, IDC_DETAILS_FAMILY_LIST_CHILDREN}
  1273. };
  1274. const ULONG idPropFamilyCount = 5;
  1275. /*
  1276. A list of all the buttons on all the propsheets .. this is mostly used to render the buttons
  1277. disabled when reading read-only data (such as vCards and LDAP)
  1278. */
  1279. ULONG idSetReadOnlyControls[] = {
  1280. IDC_DETAILS_PERSONAL_BUTTON_ADDEMAIL,
  1281. IDC_DETAILS_PERSONAL_BUTTON_REMOVE,
  1282. IDC_DETAILS_PERSONAL_BUTTON_SETDEFAULT,
  1283. IDC_DETAILS_PERSONAL_BUTTON_EDIT,
  1284. IDC_DETAILS_HOME_BUTTON_URL,
  1285. IDC_DETAILS_BUSINESS_BUTTON_URL,
  1286. IDC_DETAILS_CERT_BUTTON_PROPERTIES,
  1287. IDC_DETAILS_CERT_BUTTON_REMOVE,
  1288. IDC_DETAILS_CERT_BUTTON_SETDEFAULT,
  1289. IDC_DETAILS_CERT_BUTTON_IMPORT,
  1290. IDC_DETAILS_CERT_BUTTON_EXPORT,
  1291. IDC_DETAILS_NTMTG_BUTTON_ADDSERVER,
  1292. IDC_DETAILS_NTMTG_BUTTON_EDIT,
  1293. IDC_DETAILS_NTMTG_BUTTON_REMOVE,
  1294. IDC_DETAILS_NTMTG_BUTTON_SETDEFAULT,
  1295. IDC_DETAILS_NTMTG_BUTTON_SETBACKUP,
  1296. IDC_DETAILS_NTMTG_COMBO_EMAIL,
  1297. IDC_DETAILS_NTMTG_LIST_SERVERS,
  1298. IDC_DETAILS_NTMTG_EDIT_ADDSERVER,
  1299. IDC_DETAILS_FAMILY_EDIT_SPOUSE,
  1300. IDC_DETAILS_FAMILY_LIST_CHILDREN,
  1301. IDC_DETAILS_FAMILY_BUTTON_ADDCHILD,
  1302. IDC_DETAILS_FAMILY_BUTTON_EDITCHILD,
  1303. IDC_DETAILS_FAMILY_BUTTON_REMOVECHILD,
  1304. IDC_DETAILS_FAMILY_DATE_BIRTHDAY,
  1305. IDC_DETAILS_FAMILY_DATE_ANNIVERSARY,
  1306. IDC_DETAILS_HOME_COMBO_GENDER,
  1307. IDC_DETAILS_HOME_CHECK_DEFAULTADDRESS,
  1308. IDC_DETAILS_BUSINESS_CHECK_DEFAULTADDRESS,
  1309. IDC_DETAILS_PERSONAL_LIST,
  1310. IDC_DETAILS_PERSONAL_CHECK_RICHINFO,
  1311. IDC_DETAILS_CERT_LIST,
  1312. IDC_DETAILS_CERT_COMBO,
  1313. };
  1314. const ULONG idSetReadOnlyCount = 33;
  1315. /*//$$***************************************************************************
  1316. * FUNCTION: SetDetailsUI
  1317. *
  1318. * PURPOSE: Generic function that is used for doing the legwork for preparing
  1319. * the prop sheet to receive the data. This will include setting the text limits
  1320. * rendering controls read-only etc. Most of the propsheets call this same
  1321. * function since there is a lot of common work for each property sheet.
  1322. * To add future prop sheets, you can extend this function or you can just
  1323. * write your own...
  1324. *
  1325. ****************************************************************************/
  1326. BOOL SetDetailsUI(HWND hDlg, LPPROP_ARRAY_INFO lpPai, ULONG ulOperationType, int nPropSheet)
  1327. {
  1328. ULONG i =0;
  1329. ID_PROP * lpidProp = NULL;
  1330. ULONG idCount = 0;
  1331. switch(nPropSheet)
  1332. {
  1333. case propPersonal:
  1334. //Check the send-plain text check box on the UI off by default
  1335. CheckDlgButton(hDlg, IDC_DETAILS_PERSONAL_CHECK_RICHINFO, BST_UNCHECKED);
  1336. // Initialize the list view
  1337. lpPai->hWndDisplayNameField = GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME);
  1338. HrInitDetlsListView(GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_LIST), LVS_REPORT, LV_EMAIL);
  1339. if (ulOperationType == SHOW_ONE_OFF)
  1340. {
  1341. EnableWindow(lpPai->hWndDisplayNameField , FALSE);
  1342. EnableWindow(GetDlgItem(GetParent(hDlg), IDOK), FALSE);
  1343. }
  1344. lpidProp = idPropPersonal;
  1345. idCount = idPropPersonalCount;
  1346. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_ADDEMAIL),FALSE);
  1347. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_REMOVE),FALSE);
  1348. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_SETDEFAULT),FALSE);
  1349. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_EDIT),FALSE);
  1350. SendMessage(GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME),
  1351. CB_LIMITTEXT, (WPARAM) EDIT_LEN, 0);
  1352. if(lpPai->ulFlags & DETAILS_UseRubyPersonal)
  1353. {
  1354. SetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_STATIC_RUBYFIRST, szEmpty);
  1355. SetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_STATIC_RUBYLAST, szEmpty);
  1356. // [PaulHi] 3/29/99 Subclass the first and last name edit boxes. The
  1357. // static Ruby fields will be updated automatically.
  1358. // Only do this for Japanese locales.
  1359. if (GetUserDefaultLCID() == 0x0411)
  1360. {
  1361. HWND hWndEdit;
  1362. WNDPROC OldWndProc = NULL;
  1363. hWndEdit = GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_EDIT_FIRSTNAME);
  1364. Assert(hWndEdit);
  1365. OldWndProc = (WNDPROC)SetWindowLongPtr(hWndEdit, GWLP_WNDPROC, (LONG_PTR)RubySubClassedProc);
  1366. Assert(GetWindowLongPtr(hWndEdit, GWLP_USERDATA) == 0);
  1367. SetWindowLongPtr(hWndEdit, GWLP_USERDATA, (LONG_PTR)OldWndProc);
  1368. hWndEdit = GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_EDIT_LASTNAME);
  1369. Assert(hWndEdit);
  1370. OldWndProc = (WNDPROC)SetWindowLongPtr(hWndEdit, GWLP_WNDPROC, (LONG_PTR)RubySubClassedProc);
  1371. Assert(GetWindowLongPtr(hWndEdit, GWLP_USERDATA) == 0);
  1372. SetWindowLongPtr(hWndEdit, GWLP_USERDATA, (LONG_PTR)OldWndProc);
  1373. }
  1374. }
  1375. break;
  1376. case propHome:
  1377. lpidProp = idPropHome;
  1378. idCount = idPropHomeCount;
  1379. lpidProp[idPropHomePostalID].ulPropTag = PR_WAB_POSTALID;
  1380. ShowHideMapButton(GetDlgItem(hDlg, IDC_DETAILS_HOME_BUTTON_MAP));
  1381. ImmAssociateContext(GetDlgItem(hDlg, IDC_DETAILS_HOME_EDIT_PHONE), (HIMC) NULL);
  1382. ImmAssociateContext(GetDlgItem(hDlg, IDC_DETAILS_HOME_EDIT_FAX), (HIMC) NULL);
  1383. ImmAssociateContext(GetDlgItem(hDlg, IDC_DETAILS_HOME_EDIT_CELLULAR), (HIMC) NULL);
  1384. break;
  1385. case propBusiness:
  1386. lpidProp = idPropBusiness;
  1387. idCount = idPropBusinessCount;
  1388. lpidProp[idPropBusIPPhone].ulPropTag = PR_WAB_IPPHONE;
  1389. lpidProp[idPropBusPostalID].ulPropTag = PR_WAB_POSTALID;
  1390. ShowHideMapButton(GetDlgItem(hDlg, IDC_DETAILS_BUSINESS_BUTTON_MAP));
  1391. ImmAssociateContext(GetDlgItem(hDlg, IDC_DETAILS_BUSINESS_EDIT_PHONE), (HIMC) NULL);
  1392. ImmAssociateContext(GetDlgItem(hDlg, IDC_DETAILS_BUSINESS_EDIT_FAX), (HIMC) NULL);
  1393. ImmAssociateContext(GetDlgItem(hDlg, IDC_DETAILS_BUSINESS_EDIT_PAGER), (HIMC) NULL);
  1394. ImmAssociateContext(GetDlgItem(hDlg, IDC_DETAILS_BUSINESS_EDIT_IPPHONE), (HIMC) NULL);
  1395. break;
  1396. case propNotes:
  1397. lpidProp = idPropNotes;
  1398. idCount = idPropNotesCount;
  1399. break;
  1400. case propFamily:
  1401. lpidProp = idPropFamily;
  1402. idCount = idPropFamilyCount;
  1403. { // Gender Combo stuff
  1404. TCHAR szBuf[MAX_PATH];
  1405. HWND hWndCombo = GetDlgItem(hDlg, IDC_DETAILS_HOME_COMBO_GENDER);
  1406. SendMessage(hWndCombo, CB_RESETCONTENT, 0, 0);
  1407. for(i=0;i<3;i++)
  1408. {
  1409. LoadString(hinstMapiX, idsGender+i, szBuf, CharSizeOf(szBuf));
  1410. SendMessage(hWndCombo, CB_ADDSTRING, 0, (LPARAM) szBuf);
  1411. }
  1412. SendMessage(hWndCombo, CB_SETCURSEL, 0, 0); //default is unspecified gender
  1413. }
  1414. //Need to create the month date controls for this dialog
  1415. CreateDateTimeControl(hDlg, IDC_STATIC_BIRTHDAY, IDC_DETAILS_FAMILY_DATE_BIRTHDAY);
  1416. CreateDateTimeControl(hDlg, IDC_STATIC_ANNIVERSARY, IDC_DETAILS_FAMILY_DATE_ANNIVERSARY);
  1417. //Setup the ListView for the children's names
  1418. HrInitDetlsListView(GetDlgItem(hDlg, IDC_DETAILS_FAMILY_LIST_CHILDREN), LVS_REPORT, LV_KIDS);
  1419. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_FAMILY_BUTTON_REMOVECHILD),FALSE);
  1420. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_FAMILY_BUTTON_EDITCHILD),FALSE);
  1421. break;
  1422. case propCert:
  1423. HrInitDetlsListView(GetDlgItem(hDlg, IDC_DETAILS_CERT_LIST), LVS_REPORT, LV_CERT);
  1424. lpidProp = NULL;
  1425. idCount = 0;
  1426. break;
  1427. case propTrident:
  1428. if (ulOperationType != SHOW_ONE_OFF)
  1429. {
  1430. HWND hwnd = GetDlgItem(hDlg, IDC_DETAILS_TRIDENT_BUTTON_ADDTOWAB);
  1431. EnableWindow(hwnd, FALSE);
  1432. ShowWindow(hwnd, SW_HIDE);
  1433. }
  1434. lpidProp = NULL;
  1435. idCount = 0;
  1436. break;
  1437. case propConferencing:
  1438. // If there is a Internet Call client installed, enable CallNow
  1439. // else disable it
  1440. {
  1441. LONG cbSize = 0;
  1442. if(RegQueryValue(HKEY_LOCAL_MACHINE, szInternetCallKey, NULL, &cbSize) == ERROR_SUCCESS && cbSize >= 1)
  1443. EnableWindow(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_BUTTON_CALL), TRUE);
  1444. else
  1445. EnableWindow(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_BUTTON_CALL), FALSE);
  1446. HrInitDetlsListView(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_LIST_SERVERS), LVS_REPORT, LV_SERVER);
  1447. lpPai->hWndComboConf = GetDlgItem(hDlg, IDC_DETAILS_NTMTG_COMBO_EMAIL);
  1448. lpPai->nDefaultServerIndex = -1;
  1449. lpPai->nBackupServerIndex = -1;
  1450. lpPai->cchDefaultServerName = MAX_UI_STR;
  1451. lpPai->szDefaultServerName = LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*(lpPai->cchDefaultServerName));
  1452. lpPai->cchBackupServerName = MAX_UI_STR;
  1453. lpPai->szBackupServerName = LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*(lpPai->cchBackupServerName));
  1454. EnableWindow(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_BUTTON_ADDSERVER), FALSE);
  1455. EnableWindow(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_BUTTON_EDIT), FALSE);
  1456. EnableWindow(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_BUTTON_REMOVE), FALSE);
  1457. EnableWindow(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_BUTTON_SETDEFAULT), FALSE);
  1458. EnableWindow(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_BUTTON_SETBACKUP), FALSE);
  1459. }
  1460. break;
  1461. }
  1462. if(lpidProp && idCount)
  1463. {
  1464. //Set max input limits on the edit fields
  1465. for(i=0;i<idCount;i++)
  1466. {
  1467. ULONG ulLen = EDIT_LEN; //512
  1468. HWND hWndC= GetDlgItem(hDlg,lpidProp[i].idCtl);
  1469. if(!hWndC)
  1470. continue;
  1471. // Some fields need to be longer than others ...
  1472. switch(lpidProp[i].idCtl)
  1473. {
  1474. case IDC_DETAILS_HOME_EDIT_URL:
  1475. case IDC_DETAILS_BUSINESS_EDIT_URL:
  1476. case IDC_DETAILS_NOTES_EDIT_NOTES:
  1477. ulLen = MAX_EDIT_LEN-MAX_DISPLAY_NAME_LENGTH; // ~2K
  1478. break;
  1479. case IDC_DETAILS_HOME_CHECK_DEFAULTADDRESS: //make exceptions for non-string props
  1480. case IDC_DETAILS_BUSINESS_CHECK_DEFAULTADDRESS:
  1481. case IDC_DETAILS_HOME_COMBO_GENDER:
  1482. continue;
  1483. break;
  1484. }
  1485. SendMessage(hWndC,EM_SETLIMITTEXT,(WPARAM) ulLen,0);
  1486. if (ulOperationType == SHOW_ONE_OFF) // Make all the controls readonly
  1487. SendMessage(hWndC,EM_SETREADONLY,(WPARAM) TRUE,0);
  1488. }
  1489. }
  1490. if(nPropSheet == propHome)
  1491. SetHTTPPrefix(hDlg, IDC_DETAILS_HOME_EDIT_URL);
  1492. else if(nPropSheet == propBusiness)
  1493. SetHTTPPrefix(hDlg, IDC_DETAILS_BUSINESS_EDIT_URL);
  1494. if (ulOperationType == SHOW_ONE_OFF)
  1495. {
  1496. // Make all the readonlyable controls readonly
  1497. for(i=0;i<idSetReadOnlyCount;i++)
  1498. {
  1499. switch(idSetReadOnlyControls[i])
  1500. {
  1501. case IDC_DETAILS_HOME_BUTTON_URL:
  1502. case IDC_DETAILS_BUSINESS_BUTTON_URL:
  1503. break;
  1504. default:
  1505. {
  1506. HWND hWnd = GetDlgItem(hDlg,idSetReadOnlyControls[i]);
  1507. if(hWnd)
  1508. EnableWindow(hWnd,FALSE);
  1509. }
  1510. break;
  1511. }
  1512. }
  1513. }
  1514. // Set the font of all the children to the default GUI font
  1515. EnumChildWindows( hDlg, SetChildDefaultGUIFont, (LPARAM) 0);
  1516. return TRUE;
  1517. }
  1518. ///////////////////////////////////////////////////////////////////////////////
  1519. // RubySubClassedProc
  1520. //
  1521. // Subclassed window proc for the Ruby static edit fields. Used to provide
  1522. // IME support.
  1523. ///////////////////////////////////////////////////////////////////////////////
  1524. #define CCHMAX_RUBYSIZE 1024
  1525. LRESULT CALLBACK RubySubClassedProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1526. {
  1527. WNDPROC OldWndProc = (WNDPROC)GetWindowLongPtr(hWnd, GWLP_USERDATA);
  1528. HIMC hIMC;
  1529. WCHAR wszTemp[CCHMAX_RUBYSIZE];
  1530. WCHAR wszRuby[CCHMAX_RUBYSIZE];
  1531. HWND hWndParent;
  1532. LONG lId;
  1533. HWND hWndRuby = NULL;
  1534. Assert(OldWndProc);
  1535. switch (uMsg)
  1536. {
  1537. case WM_IME_COMPOSITION:
  1538. if ( (hIMC = ImmGetContext(hWnd)) )
  1539. {
  1540. // IME does not include zero terminating character
  1541. ZeroMemory(wszTemp, sizeof(wszTemp));
  1542. ZeroMemory(wszRuby, sizeof(wszRuby));
  1543. ImmGetCompositionStringW(hIMC, GCS_RESULTREADSTR, wszTemp, (sizeof(WCHAR) * (CCHMAX_RUBYSIZE-1)));
  1544. // This subclassing only takes place for Japanese systems (lcid = 0x0411).
  1545. LCMapString(0x0411, LCMAP_FULLWIDTH | LCMAP_HIRAGANA, wszTemp, lstrlen(wszTemp), wszRuby, CCHMAX_RUBYSIZE-1);
  1546. ImmReleaseContext(hWnd, hIMC);
  1547. // Set either the first or last name ruby field, depending on which edit control
  1548. // this is.
  1549. hWndParent = GetParent(hWnd);
  1550. Assert(hWndParent);
  1551. lId = (LONG)GetWindowLongPtr(hWnd, GWL_ID);
  1552. switch (lId)
  1553. {
  1554. case IDC_DETAILS_PERSONAL_EDIT_FIRSTNAME:
  1555. hWndRuby = GetDlgItem(hWndParent, IDC_DETAILS_PERSONAL_STATIC_RUBYFIRST);
  1556. break;
  1557. case IDC_DETAILS_PERSONAL_EDIT_LASTNAME:
  1558. hWndRuby = GetDlgItem(hWndParent, IDC_DETAILS_PERSONAL_STATIC_RUBYLAST);
  1559. break;
  1560. default:
  1561. Assert(0); // What the heck did we subclass if not the two Ruby fields above?
  1562. break;
  1563. }
  1564. if (hWndRuby)
  1565. {
  1566. BOOL bDoConcat = TRUE;
  1567. DWORD dwStartSel = 0;
  1568. DWORD dwEndSel = 0;
  1569. // If we have selected text in the edit field or it is empty then
  1570. // start over in Ruby field
  1571. SendMessage(hWnd, EM_GETSEL, (WPARAM)&dwStartSel, (LPARAM)&dwEndSel);
  1572. GetWindowText(hWnd, wszTemp, (CCHMAX_RUBYSIZE-1));
  1573. if ( (dwEndSel > dwStartSel) || ((*wszTemp) == '\0') )
  1574. bDoConcat = FALSE;
  1575. // Concatenate the text to what already exists in the Ruby field
  1576. if (bDoConcat)
  1577. {
  1578. GetWindowText(hWndRuby, wszTemp, (CCHMAX_RUBYSIZE-1));
  1579. if ( (lstrlen(wszTemp) + lstrlen(wszRuby) + 1) < CCHMAX_RUBYSIZE )
  1580. {
  1581. StrCatBuff(wszTemp, wszRuby, ARRAYSIZE(wszTemp));
  1582. SetWindowText(hWndRuby, wszTemp);
  1583. break;
  1584. }
  1585. }
  1586. // Default
  1587. SetWindowText(hWndRuby, wszRuby);
  1588. }
  1589. }
  1590. break;
  1591. } // end switch(uMsg)
  1592. return CallWindowProc(OldWndProc, hWnd, uMsg, wParam, lParam);
  1593. }
  1594. /*//$$***************************************************************************
  1595. * FUNCTION: FillCertComboWithEmailAddresses(hDlg, lpPai);
  1596. *
  1597. *
  1598. * PURPOSE: Fills in the dialog items on the property sheet
  1599. *
  1600. * szEmail - if an email address is specified that exists in the
  1601. * combo, that email address is selected
  1602. *
  1603. ****************************************************************************/
  1604. void FillCertComboWithEmailAddresses(HWND hDlg, LPPROP_ARRAY_INFO lpPai, LPTSTR szEmail)
  1605. {
  1606. HWND hWndCombo = GetDlgItem(hDlg, IDC_DETAILS_CERT_COMBO);
  1607. TCHAR sz[MAX_UI_STR];
  1608. int nDefault = 0;
  1609. FillComboWithEmailAddresses(lpPai, hWndCombo, &nDefault);
  1610. if( lpPai->ulOperationType != SHOW_ONE_OFF &&
  1611. SendMessage(hWndCombo, CB_GETCOUNT, 0, 0) > 0 &&
  1612. SendMessage(hWndCombo, CB_GETCOUNT, 0, 0) != CB_ERR )
  1613. EnableWindow(hWndCombo, TRUE);
  1614. // Append the item [None - certificates without e-mail addresses]
  1615. // to this list
  1616. *sz = '\0';
  1617. LoadString(hinstMapiX, idsCertsWithoutEmails, sz, CharSizeOf(sz));
  1618. // *** NOTE ***
  1619. // This item should always be the last item in the combo - several
  1620. // places in this file work on that assumption
  1621. //
  1622. if(lstrlen(sz))
  1623. SendMessage(hWndCombo, CB_ADDSTRING, 0, (LPARAM) sz);
  1624. if(szEmail)
  1625. {
  1626. // Set focus to a specific email address
  1627. int nCount = (int) SendMessage(hWndCombo, CB_GETCOUNT, 0, 0);
  1628. if(lstrlen(szEmail))
  1629. {
  1630. int i;
  1631. for(i=0;i<nCount-1;i++)
  1632. {
  1633. int nLen = (int)SendMessage(hWndCombo, CB_GETLBTEXTLEN, (WPARAM)i, 0);
  1634. if (nLen != CB_ERR)
  1635. {
  1636. LPTSTR psz = (LPTSTR)LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*(nLen + 1));
  1637. if (psz)
  1638. {
  1639. psz[0] = 0;
  1640. SendMessage(hWndCombo, CB_GETLBTEXT, (WPARAM) i, (LPARAM) psz);
  1641. if( lstrlen(psz) &&
  1642. !lstrcmpi(psz, szEmail))
  1643. {
  1644. LocalFreeAndNull(&psz);
  1645. SendMessage(hWndCombo, CB_SETCURSEL, (WPARAM) i, 0);
  1646. break;
  1647. }
  1648. LocalFreeAndNull(&psz);
  1649. }
  1650. }
  1651. }
  1652. }
  1653. else
  1654. {
  1655. // passed in an empty email string which means we have just imported
  1656. // a cert without an email address which means set the focus to the
  1657. // last item in the combo
  1658. SendMessage(hWndCombo, CB_SETCURSEL, (WPARAM) nCount-1, 0);
  1659. }
  1660. }
  1661. else
  1662. SendMessage(hWndCombo, CB_SETCURSEL, (WPARAM) nDefault, 0);
  1663. }
  1664. //$$//////////////////////////////////////////////////////////////////////////////
  1665. //
  1666. // bVerifyRequiredData
  1667. //
  1668. // Checks that all the required data for a given prop sheet is filled in,
  1669. // If not, returns FALSE and ID of control to set focus on
  1670. //
  1671. //////////////////////////////////////////////////////////////////////////////////
  1672. BOOL bVerifyRequiredData(HWND hDlg,
  1673. LPPROP_ARRAY_INFO lpPai,
  1674. int nPropSheet,
  1675. int * lpCtlID)
  1676. {
  1677. TCHAR szBuf[2 * MAX_UI_STR];
  1678. ULONG ulSzBuf = CharSizeOf(szBuf);
  1679. //
  1680. // First check the required property (which is the GroupName)
  1681. //
  1682. *lpCtlID = 0;
  1683. szBuf[0]='\0';
  1684. switch (nPropSheet)
  1685. {
  1686. case propPersonal:
  1687. // We need to check that all the required properties are filled in ...
  1688. // For now all we really want a display Name
  1689. szBuf[0] = '\0';
  1690. GetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME, szBuf, ulSzBuf);
  1691. TrimSpaces(szBuf);
  1692. if (lstrlen(szBuf) == 0)
  1693. {
  1694. // Nothing in the display name field ..
  1695. // Try to populate the field with the various info.
  1696. // If we are successful in populating the field, we'll pick the first
  1697. // entry as the default display name
  1698. // If we are unsuccessful in picking something, we will stop and warn the
  1699. // user
  1700. HWND hWndCombo = GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME);
  1701. int nItemCount = 0;
  1702. SetComboDNText(hDlg, lpPai, TRUE, NULL);
  1703. nItemCount = (int) SendMessage(hWndCombo, CB_GETCOUNT, 0, 0);
  1704. if(nItemCount == 0)
  1705. {
  1706. //still nothing , warn and abort
  1707. ShowMessageBox(GetParent(hDlg), IDS_DETAILS_MESSAGE_FIRST_LAST_REQUIRED, MB_ICONEXCLAMATION | MB_OK);
  1708. *lpCtlID = IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME;
  1709. return FALSE;
  1710. }
  1711. else
  1712. {
  1713. //Get the combo current selection which will be item 0
  1714. SendMessage(hWndCombo, CB_GETLBTEXT, (WPARAM) 0, (LPARAM) szBuf);
  1715. }
  1716. }
  1717. break;
  1718. }
  1719. return TRUE;
  1720. }
  1721. //$$//////////////////////////////////////////////////////////////////////////////
  1722. //
  1723. // bUpdateOldPropTagArray
  1724. //
  1725. // For each prop sheet that is accessed, we will update the list of old prop tags
  1726. // for that sheet so that the old props can be knocked out of existing mailuser objects
  1727. //
  1728. //////////////////////////////////////////////////////////////////////////////////
  1729. BOOL bUpdateOldPropTagArray(LPPROP_ARRAY_INFO lpPai, int nIndex)
  1730. {
  1731. LPSPropTagArray lpta = NULL;
  1732. SizedSPropTagArray(14, ptaUIDetlsPropsPersonal)=
  1733. {
  1734. 14,
  1735. {
  1736. PR_DISPLAY_NAME,
  1737. PR_EMAIL_ADDRESS,
  1738. PR_ADDRTYPE,
  1739. PR_CONTACT_EMAIL_ADDRESSES,
  1740. PR_CONTACT_ADDRTYPES,
  1741. PR_CONTACT_DEFAULT_ADDRESS_INDEX,
  1742. PR_GIVEN_NAME,
  1743. PR_SURNAME,
  1744. PR_MIDDLE_NAME,
  1745. PR_NICKNAME,
  1746. PR_SEND_INTERNET_ENCODING,
  1747. PR_DISPLAY_NAME_PREFIX,
  1748. PR_WAB_YOMI_FIRSTNAME,
  1749. PR_WAB_YOMI_LASTNAME
  1750. }
  1751. };
  1752. switch(nIndex)
  1753. {
  1754. case propPersonal:
  1755. lpta = (LPSPropTagArray) &ptaUIDetlsPropsPersonal;
  1756. break;
  1757. case propHome:
  1758. ptaUIDetlsPropsHome.aulPropTag[idPropHomePostalID] = PR_WAB_POSTALID;
  1759. lpta = (LPSPropTagArray) &ptaUIDetlsPropsHome;
  1760. break;
  1761. case propBusiness:
  1762. ptaUIDetlsPropsBusiness.aulPropTag[idPropBusIPPhone] = PR_WAB_IPPHONE;
  1763. ptaUIDetlsPropsBusiness.aulPropTag[idPropBusPostalID] = PR_WAB_POSTALID;
  1764. lpta = (LPSPropTagArray) &ptaUIDetlsPropsBusiness;
  1765. break;
  1766. case propNotes:
  1767. lpta = (LPSPropTagArray) &ptaUIDetlsPropsNotes;
  1768. break;
  1769. case propCert:
  1770. lpta = (LPSPropTagArray) &ptaUIDetlsPropsCert;
  1771. break;
  1772. case propConferencing:
  1773. lpta = (LPSPropTagArray) &ptaUIDetlsPropsConferencing;
  1774. break;
  1775. case propFamily:
  1776. lpta = (LPSPropTagArray) &ptaUIDetlsPropsFamily;
  1777. break;
  1778. }
  1779. if(!lpta)
  1780. return TRUE;
  1781. if(lpPai->lpPropObj && lpPai->bSomethingChanged)
  1782. {
  1783. // Knock out these old props from the PropObject
  1784. if( (lpPai->lpPropObj)->lpVtbl->DeleteProps( (lpPai->lpPropObj),lpta,NULL))
  1785. return FALSE;
  1786. }
  1787. return TRUE;
  1788. }
  1789. /*
  1790. -
  1791. - bGetHomeBusNotesInfo - Gets data from the Home/Business/Notes fields
  1792. -
  1793. */
  1794. BOOL bGetHomeBusNotesInfo(HWND hDlg, LPPROP_ARRAY_INFO lpPai,
  1795. int nPropSheet, ID_PROP * lpidProp, ULONG idPropCount,
  1796. LPSPropValue * lppPropArray, LPULONG lpulcPropCount)
  1797. {
  1798. ULONG ulSzBuf = 4*MAX_BUF_STR;
  1799. LPTSTR szBuf = LocalAlloc(LMEM_ZEROINIT, ulSzBuf*sizeof(TCHAR));
  1800. // The idea is to first count all the properties that have non-zero values
  1801. // Then create a lpPropArray of that size and fill in the text from the props ..
  1802. //
  1803. BOOL bRet = FALSE;
  1804. ULONG ulNotEmptyCount = 0;
  1805. SCODE sc = S_OK;
  1806. ULONG i = 0;
  1807. LPSPropValue lpPropArray = NULL;
  1808. ULONG ulcPropCount = 0,ulIndex=0;
  1809. //The biggest field in the UI is about 2K length - just to be safe we want about 4K
  1810. // in this buffer so we need to allocate it dynamically
  1811. if(!szBuf)
  1812. {
  1813. DebugTrace(( TEXT("LocalAlloc failed to allocate memory\n")));
  1814. return FALSE;
  1815. }
  1816. for(i=0;i<idPropCount;i++)
  1817. {
  1818. switch(lpidProp[i].idCtl)
  1819. {
  1820. case IDC_DETAILS_HOME_CHECK_DEFAULTADDRESS:
  1821. if(lpPai->ulFlags & DETAILS_DefHomeChanged)
  1822. ulNotEmptyCount++;
  1823. continue;
  1824. break;
  1825. case IDC_DETAILS_BUSINESS_CHECK_DEFAULTADDRESS:
  1826. if(lpPai->ulFlags & DETAILS_DefBusChanged)
  1827. ulNotEmptyCount++;
  1828. continue;
  1829. break;
  1830. }
  1831. szBuf[0]='\0'; //reset
  1832. GetDlgItemText(hDlg, lpidProp[i].idCtl, szBuf, ulSzBuf);
  1833. TrimSpaces(szBuf);
  1834. if(lstrlen(szBuf) && lpidProp[i].ulPropTag) //some text
  1835. ulNotEmptyCount++;
  1836. // if its just the default prefix, ignore
  1837. if( ((lpidProp[i].idCtl == IDC_DETAILS_HOME_EDIT_URL) ||
  1838. (lpidProp[i].idCtl == IDC_DETAILS_BUSINESS_EDIT_URL)) &&
  1839. (lstrcmpi(szHTTP, szBuf)==0))
  1840. ulNotEmptyCount--;
  1841. }
  1842. if (ulNotEmptyCount == 0)
  1843. {
  1844. bRet = TRUE;
  1845. goto out;
  1846. }
  1847. ulcPropCount = ulNotEmptyCount;
  1848. sc = MAPIAllocateBuffer(sizeof(SPropValue) * ulcPropCount, &lpPropArray);
  1849. if (sc!=S_OK)
  1850. {
  1851. DebugTrace(( TEXT("Error allocating memory\n")));
  1852. goto out;
  1853. }
  1854. ulIndex = 0; //now we reuse this variable as an index
  1855. // Now read the props again and fill in the lpPropArray
  1856. for(i=0;i<idPropCount;i++)
  1857. {
  1858. switch(lpidProp[i].idCtl)
  1859. {
  1860. case IDC_DETAILS_HOME_CHECK_DEFAULTADDRESS:
  1861. case IDC_DETAILS_BUSINESS_CHECK_DEFAULTADDRESS:
  1862. continue;
  1863. break;
  1864. }
  1865. szBuf[0]='\0'; //reset
  1866. GetDlgItemText(hDlg, lpidProp[i].idCtl, szBuf, ulSzBuf);
  1867. TrimSpaces(szBuf);
  1868. if( ((lpidProp[i].idCtl == IDC_DETAILS_HOME_EDIT_URL) ||
  1869. (lpidProp[i].idCtl == IDC_DETAILS_BUSINESS_EDIT_URL)) &&
  1870. (lstrcmpi(szHTTP, szBuf)==0))
  1871. continue;
  1872. if(lstrlen(szBuf) && lpidProp[i].ulPropTag) //some text
  1873. {
  1874. ULONG nLen = sizeof(TCHAR)*(lstrlen(szBuf)+1);
  1875. lpPropArray[ulIndex].ulPropTag = lpidProp[i].ulPropTag;
  1876. sc = MAPIAllocateMore(nLen, lpPropArray, (LPVOID *) (&(lpPropArray[ulIndex].Value.LPSZ)));
  1877. if (sc!=S_OK)
  1878. {
  1879. DebugPrintError(( TEXT("Error allocating memory\n")));
  1880. goto out;
  1881. }
  1882. StrCpyN(lpPropArray[ulIndex].Value.LPSZ,szBuf,nLen/sizeof(TCHAR));
  1883. ulIndex++;
  1884. }
  1885. }
  1886. if(nPropSheet == propHome)
  1887. {
  1888. if(lpPai->ulFlags & DETAILS_DefHomeChanged)
  1889. {
  1890. lpPropArray[ulIndex].ulPropTag = PR_WAB_POSTALID;
  1891. lpPropArray[ulIndex].Value.l = (IsDlgButtonChecked(hDlg, IDC_DETAILS_HOME_CHECK_DEFAULTADDRESS)) ?
  1892. ADDRESS_HOME : ADDRESS_NONE;
  1893. ulIndex++;
  1894. }
  1895. }
  1896. else if(nPropSheet == propBusiness)
  1897. {
  1898. if(lpPai->ulFlags & DETAILS_DefBusChanged)
  1899. {
  1900. lpPropArray[ulIndex].ulPropTag = PR_WAB_POSTALID;
  1901. lpPropArray[ulIndex].Value.l = (IsDlgButtonChecked(hDlg, IDC_DETAILS_BUSINESS_CHECK_DEFAULTADDRESS)) ?
  1902. ADDRESS_WORK : ADDRESS_NONE;
  1903. ulIndex++;
  1904. }
  1905. }
  1906. *lppPropArray = lpPropArray;
  1907. *lpulcPropCount = ulIndex;
  1908. bRet = TRUE;
  1909. out:
  1910. if (!bRet)
  1911. {
  1912. if ((lpPropArray) && (ulcPropCount > 0))
  1913. {
  1914. MAPIFreeBuffer(lpPropArray);
  1915. ulcPropCount = 0;
  1916. }
  1917. }
  1918. LocalFreeAndNull(&szBuf);
  1919. return bRet;
  1920. }
  1921. /*
  1922. - bGetPersonalInfo
  1923. - Get Data from Personal Prop sheet
  1924. *
  1925. */
  1926. BOOL bGetPersonalInfo( HWND hDlg, LPPROP_ARRAY_INFO lpPai,
  1927. ID_PROP * lpidProp, ULONG idPropCount,
  1928. LPSPropValue * lppPropArray, LPULONG lpulcPropCount)
  1929. {
  1930. ULONG ulSzBuf = 4*MAX_BUF_STR;
  1931. LPTSTR szBuf = LocalAlloc(LMEM_ZEROINIT, ulSzBuf*sizeof(TCHAR));
  1932. BOOL bRet = FALSE;
  1933. ULONG ulNotEmptyCount = 0;
  1934. SCODE sc = S_OK;
  1935. HRESULT hr = S_OK;
  1936. ULONG i = 0;
  1937. LPSPropValue lpPropArray = NULL;
  1938. ULONG ulcPropCount = 0,ulIndex=0;
  1939. ULONG ulcProps = 0;
  1940. LPSPropValue rgProps = NULL;
  1941. HWND hWndLV = NULL;
  1942. TCHAR szConf[MAX_UI_STR];
  1943. SizedSPropTagArray(1, ptaIC) = {1, PR_SEND_INTERNET_ENCODING};
  1944. //The biggest field in the UI is about 2K length - just to be safe we want about 4K
  1945. // in this buffer so we need to allocate it dynamically
  1946. if(!szBuf)
  1947. {
  1948. DebugTrace(( TEXT("LocalAlloc failed to allocate memory\n")));
  1949. return FALSE;
  1950. }
  1951. if(HR_FAILED(lpPai->lpPropObj->lpVtbl->GetProps(lpPai->lpPropObj, (LPSPropTagArray)&ptaIC,
  1952. MAPI_UNICODE, &ulcProps, &rgProps)))
  1953. goto out;
  1954. szBuf[0] = '\0';
  1955. hWndLV = GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_LIST);
  1956. GetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME, (LPTSTR)szBuf, ulSzBuf);
  1957. TrimSpaces(szBuf);
  1958. if (lstrlen(szBuf) == 0)
  1959. {
  1960. // Nothing in the display name field ..
  1961. // Try to populate the field with the various info.
  1962. // If we are successful in populating the field, we'll pick the first
  1963. // entry as the default display name
  1964. // If we are unsuccessful in picking something, we will stop and warn the
  1965. // user
  1966. HWND hWndCombo = GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME);
  1967. int nItemCount = 0;
  1968. SetComboDNText(hDlg, lpPai, TRUE, NULL);
  1969. nItemCount = (int) SendMessage(hWndCombo, CB_GETCOUNT, 0, 0);
  1970. if(nItemCount && nItemCount != CB_ERR)
  1971. {
  1972. //Get the combo current selection which will be item 0
  1973. SendMessage(hWndCombo, CB_GETLBTEXT, (WPARAM) 0, (LPARAM) szBuf);
  1974. }
  1975. }
  1976. ulNotEmptyCount = 0;
  1977. for(i=0;i<idPropCount;i++)
  1978. {
  1979. HWND hWndC = GetDlgItem(hDlg, lpidProp[i].idCtl);
  1980. if(!hWndC)
  1981. continue;
  1982. szBuf[0]='\0'; //reset
  1983. if(GetWindowText(hWndC, szBuf, ulSzBuf))
  1984. {
  1985. TrimSpaces(szBuf);
  1986. if(lstrlen(szBuf) && lpidProp[i].ulPropTag) //some text
  1987. ulNotEmptyCount++;
  1988. }
  1989. }
  1990. if ((ulNotEmptyCount == 0) &&
  1991. (ListView_GetItemCount(hWndLV) <= 0)) // Bug 14274 - werent looking for an email address before bailing out ..
  1992. {
  1993. // This prop sheet is empty ... ignore it
  1994. bRet = TRUE;
  1995. goto out;
  1996. }
  1997. ulcPropCount = ulNotEmptyCount;
  1998. ulcPropCount++; // We create an entryid
  1999. if(ListView_GetItemCount(hWndLV) > 0)
  2000. ulcPropCount += 5; // +1 for email1_address,
  2001. // +1 for addrtype,
  2002. // +1 for contact_email_addresses,
  2003. // +1 for contact_addrtypes
  2004. // +1 for contact_default_index,
  2005. ulcPropCount++; //Add one for the PR_SEND_INTERNET_ENCODING property
  2006. sc = MAPIAllocateBuffer(sizeof(SPropValue) * ulcPropCount, &lpPropArray);
  2007. if (sc!=S_OK)
  2008. {
  2009. DebugPrintError(( TEXT("Error allocating memory\n")));
  2010. goto out;
  2011. }
  2012. ulIndex = 0;
  2013. // Now read the props again and fill in the lpPropArray
  2014. for(i=0;i<idPropCount;i++)
  2015. {
  2016. HWND hWndC = GetDlgItem(hDlg, lpidProp[i].idCtl);
  2017. if(!hWndC)
  2018. continue;
  2019. szBuf[0]='\0'; //reset
  2020. GetWindowText(hWndC, szBuf, ulSzBuf);
  2021. TrimSpaces(szBuf);
  2022. if(lstrlen(szBuf))
  2023. {
  2024. if(lpidProp[i].idCtl == IDC_DETAILS_PERSONAL_STATIC_RUBYFIRST)
  2025. lpidProp[i].ulPropTag = PR_WAB_YOMI_FIRSTNAME;
  2026. else if(lpidProp[i].idCtl == IDC_DETAILS_PERSONAL_STATIC_RUBYLAST)
  2027. lpidProp[i].ulPropTag = PR_WAB_YOMI_LASTNAME;
  2028. if(lpidProp[i].ulPropTag) //some text
  2029. {
  2030. ULONG nLen = sizeof(TCHAR)*(lstrlen(szBuf)+1);
  2031. lpPropArray[ulIndex].ulPropTag = lpidProp[i].ulPropTag;
  2032. sc = MAPIAllocateMore(nLen, lpPropArray, (LPVOID *) (&(lpPropArray[ulIndex].Value.LPSZ)));
  2033. if (sc!=S_OK)
  2034. {
  2035. DebugPrintError(( TEXT("Error allocating memory\n")));
  2036. goto out;
  2037. }
  2038. StrCpyN(lpPropArray[ulIndex].Value.LPSZ,szBuf,nLen/sizeof(TCHAR));
  2039. ulIndex++;
  2040. }
  2041. }
  2042. }
  2043. // TBD - write code for getting all the other props
  2044. // if this is a new entry, we want to give it a blank PR_ENTRYID property
  2045. // else we want to set its PR_ENTRYID property
  2046. lpPropArray[ulIndex].ulPropTag = PR_ENTRYID;
  2047. if (lpPai->cbEntryID == 0)
  2048. {
  2049. lpPropArray[ulIndex].Value.bin.cb = 0;
  2050. lpPropArray[ulIndex].Value.bin.lpb = NULL;
  2051. }
  2052. else
  2053. {
  2054. lpPropArray[ulIndex].Value.bin.cb = lpPai->cbEntryID;
  2055. sc = MAPIAllocateMore(lpPai->cbEntryID, lpPropArray, (LPVOID *) (&(lpPropArray[ulIndex].Value.bin.lpb)));
  2056. if (sc!=S_OK)
  2057. {
  2058. DebugPrintError(( TEXT("Error allocating memory\n")));
  2059. goto out;
  2060. }
  2061. CopyMemory(lpPropArray[ulIndex].Value.bin.lpb,lpPai->lpEntryID,lpPai->cbEntryID);
  2062. }
  2063. ulIndex++;
  2064. szConf[0] = TEXT('\0');
  2065. // Check if we need to change the COnf_server_email_index prop
  2066. if(lpPai->hWndComboConf)
  2067. {
  2068. GetWindowText(lpPai->hWndComboConf, szConf, CharSizeOf(szConf));
  2069. TrimSpaces(szConf);
  2070. }
  2071. if(ListView_GetItemCount(hWndLV) > 0)
  2072. {
  2073. // Find out how many elements we need to add
  2074. ULONG nEmailCount = ListView_GetItemCount(hWndLV);
  2075. // we'll use the following as indexes for lpPropArray
  2076. ULONG nMVEmailAddress = ulIndex++;//ulIndex+0;
  2077. ULONG nMVAddrTypes = ulIndex++;//ulIndex+1;
  2078. ULONG nEmailAddress = ulIndex++;//ulIndex+2;
  2079. ULONG nAddrType = ulIndex++;//ulIndex+3;
  2080. ULONG nDefaultIndex = ulIndex++;//ulIndex+4;
  2081. lpPropArray[nEmailAddress].ulPropTag = PR_EMAIL_ADDRESS;
  2082. lpPropArray[nAddrType].ulPropTag = PR_ADDRTYPE;
  2083. lpPropArray[nDefaultIndex].ulPropTag = PR_CONTACT_DEFAULT_ADDRESS_INDEX;
  2084. lpPropArray[nMVEmailAddress].ulPropTag = PR_CONTACT_EMAIL_ADDRESSES;
  2085. lpPropArray[nMVAddrTypes].ulPropTag = PR_CONTACT_ADDRTYPES;
  2086. // initialize before using ...
  2087. lpPropArray[nMVEmailAddress].Value.MVSZ.cValues = 0;
  2088. lpPropArray[nMVEmailAddress].Value.MVSZ.LPPSZ = NULL;
  2089. lpPropArray[nMVAddrTypes].Value.MVSZ.cValues = 0;
  2090. lpPropArray[nMVAddrTypes].Value.MVSZ.LPPSZ = NULL;
  2091. // For thetime being just null them all
  2092. for(i=0;i<nEmailCount;i++)
  2093. {
  2094. LV_ITEM lvi = {0};
  2095. lvi.mask = LVIF_PARAM;
  2096. lvi.iItem = i;
  2097. lvi.iSubItem = 0;
  2098. if (ListView_GetItem(hWndLV, &lvi))
  2099. {
  2100. LPEMAIL_ITEM lpEItem = (LPEMAIL_ITEM) lvi.lParam;
  2101. if(HR_FAILED(hr = AddPropToMVPString(
  2102. lpPropArray,
  2103. ulcPropCount,
  2104. nMVEmailAddress,
  2105. lpEItem->szEmailAddress)))
  2106. {
  2107. DebugPrintError(( TEXT("AddPropToMVString Email failed: %x"),hr));
  2108. goto out;
  2109. }
  2110. if(HR_FAILED(hr = AddPropToMVPString(
  2111. lpPropArray,
  2112. ulcPropCount,
  2113. nMVAddrTypes,
  2114. lpEItem->szAddrType)))
  2115. {
  2116. DebugPrintError(( TEXT("AddPropToMVString AddrType failed: %x"),hr));
  2117. goto out;
  2118. }
  2119. if(lpEItem->bIsDefault)
  2120. {
  2121. ULONG cchSize;
  2122. // For the default e-mail ... set all the other props
  2123. lpPropArray[nDefaultIndex].Value.l = i;
  2124. cchSize = lstrlen(lpEItem->szEmailAddress)+1;
  2125. sc = MAPIAllocateMore( sizeof(TCHAR)*cchSize,
  2126. lpPropArray,
  2127. (LPVOID *) (&(lpPropArray[nEmailAddress].Value.LPSZ)));
  2128. if(FAILED(sc))
  2129. {
  2130. DebugPrintError(( TEXT("MApiAllocateMore failed\n")));
  2131. hr = ResultFromScode(sc);
  2132. goto out;
  2133. }
  2134. StrCpyN(lpPropArray[nEmailAddress].Value.LPSZ,lpEItem->szEmailAddress,cchSize);
  2135. cchSize = lstrlen(lpEItem->szAddrType)+1;
  2136. sc = MAPIAllocateMore( sizeof(TCHAR)*cchSize,
  2137. lpPropArray,
  2138. (LPVOID *) (&(lpPropArray[nAddrType].Value.LPSZ)));
  2139. if(FAILED(sc))
  2140. {
  2141. DebugPrintError(( TEXT("MApiAllocateMore failed\n")));
  2142. hr = ResultFromScode(sc);
  2143. goto out;
  2144. }
  2145. StrCpyN(lpPropArray[nAddrType].Value.LPSZ,lpEItem->szAddrType,cchSize);
  2146. } // if bIsDefault...
  2147. } // if LV_GetItem ...
  2148. } // for i = ...
  2149. } // if LV_GetItemCount ...
  2150. // Add the PR_SEND_INTERNET_ENCODING property
  2151. lpPropArray[ulIndex].ulPropTag = PR_SEND_INTERNET_ENCODING;
  2152. lpPropArray[ulIndex].Value.l = 0;
  2153. // The PR_SEND_INTERNET_ECODING is a bit mask of several flags and we dont want
  2154. // to loose any information that was in the original set of bits so we get it again
  2155. if(rgProps[0].ulPropTag == PR_SEND_INTERNET_ENCODING)
  2156. {
  2157. //Check the check box on the UI
  2158. lpPropArray[ulIndex].Value.l = rgProps[0].Value.l;
  2159. }
  2160. lpPropArray[ulIndex].Value.l &= ~BODY_ENCODING_MASK; //BODY_ENCODING_HTML;
  2161. if(IsDlgButtonChecked(hDlg, IDC_DETAILS_PERSONAL_CHECK_RICHINFO) != BST_CHECKED)
  2162. lpPropArray[ulIndex].Value.l |= BODY_ENCODING_TEXT_AND_HTML; //BODY_ENCODING_HTML;
  2163. ulIndex++;
  2164. *lppPropArray = lpPropArray;
  2165. *lpulcPropCount = ulIndex;
  2166. bRet = TRUE;
  2167. out:
  2168. if (!bRet)
  2169. {
  2170. if ((lpPropArray) && (ulcPropCount > 0))
  2171. {
  2172. MAPIFreeBuffer(lpPropArray);
  2173. ulcPropCount = 0;
  2174. }
  2175. }
  2176. LocalFreeAndNull(&szBuf);
  2177. FreeBufferAndNull(&rgProps);
  2178. return bRet;
  2179. }
  2180. /*
  2181. - bGetConferencingInfo
  2182. - Get Data from Conferencing Prop sheet
  2183. *
  2184. */
  2185. BOOL bGetConferencingInfo( HWND hDlg, LPPROP_ARRAY_INFO lpPai,
  2186. LPSPropValue * lppPropArray, LPULONG lpulcPropCount)
  2187. {
  2188. ULONG ulSzBuf = 4*MAX_BUF_STR;
  2189. LPTSTR szBuf = LocalAlloc(LMEM_ZEROINIT, ulSzBuf*sizeof(TCHAR));
  2190. BOOL bRet = FALSE;
  2191. ULONG ulNotEmptyCount = 0;
  2192. SCODE sc = S_OK;
  2193. HRESULT hr = S_OK;
  2194. ULONG i = 0;
  2195. LPSPropValue lpPropArray = NULL;
  2196. ULONG ulcPropCount = 0,ulIndex=0;
  2197. HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_NTMTG_LIST_SERVERS);
  2198. int nItemCount = ListView_GetItemCount(hWndLV);
  2199. TCHAR szEmail[MAX_UI_STR];
  2200. ULONG ulcProps = 0;
  2201. LPSPropValue rgProps = NULL;
  2202. SizedSPropTagArray(1, ptaCf) = {1, PR_WAB_CONF_SERVERS};
  2203. //The biggest field in the UI is about 2K length - just to be safe we want about 4K
  2204. // in this buffer so we need to allocate it dynamically
  2205. if(!szBuf)
  2206. {
  2207. DebugTrace(( TEXT("LocalAlloc failed to allocate memory\n")));
  2208. return FALSE;
  2209. }
  2210. if(HR_FAILED(lpPai->lpPropObj->lpVtbl->GetProps(lpPai->lpPropObj, (LPSPropTagArray)&ptaCf,
  2211. MAPI_UNICODE, &ulcProps, &rgProps)))
  2212. goto out;
  2213. // For the conferencing tab, we need to save 4 properties
  2214. // Conferencing Server Names
  2215. // Default Index
  2216. // Backup Index
  2217. // Email Address Index
  2218. //
  2219. ulNotEmptyCount = 0;
  2220. if(nItemCount > 0)
  2221. {
  2222. ulNotEmptyCount += 2; // CONF_SERVERS and DEFAULT_INDEX
  2223. if(lpPai->nBackupServerIndex != -1)
  2224. ulNotEmptyCount++;
  2225. }
  2226. if (ulNotEmptyCount == 0)
  2227. {
  2228. // This prop sheet is empty ... ignore it
  2229. bRet = TRUE;
  2230. goto out;
  2231. }
  2232. ulcPropCount = ulNotEmptyCount;
  2233. sc = MAPIAllocateBuffer(sizeof(SPropValue) * ulcPropCount, &lpPropArray);
  2234. if (sc!=S_OK)
  2235. goto out;
  2236. ulIndex = 0; //now we reuse this variable as an index
  2237. if(nItemCount > 0)
  2238. {
  2239. TCHAR * szCalltoStr = NULL; //szCalltoStr[MAX_UI_STR * 3];
  2240. ULONG cchCalltoStr = MAX_UI_STR*3;
  2241. ULONG i,j;
  2242. if (szCalltoStr = LocalAlloc(LMEM_ZEROINIT, cchCalltoStr*sizeof(TCHAR)))
  2243. {
  2244. lpPropArray[ulIndex].ulPropTag = PR_WAB_CONF_SERVERS;
  2245. lpPropArray[ulIndex].Value.MVSZ.cValues = 0;
  2246. lpPropArray[ulIndex].Value.MVSZ.LPPSZ = NULL;
  2247. // first scan the original prop array for any PR_SERVERS props that
  2248. // we didnt touch - retain those props witout losing them
  2249. {
  2250. j = 0; //index of PR_WAB_CONF_SERVERS prop
  2251. if(rgProps[j].ulPropTag == PR_WAB_CONF_SERVERS)
  2252. {
  2253. LPSPropValue lpProp = &(rgProps[j]);
  2254. for(i=0;i<lpProp->Value.MVSZ.cValues; i++)
  2255. {
  2256. LPTSTR lp = lpProp->Value.MVSZ.LPPSZ[i];
  2257. TCHAR sz[32];
  2258. int iLenCallto = lstrlen(szCallto);
  2259. if(!SubstringSearch(lp, TEXT("://")))
  2260. continue;
  2261. if(lstrlen(lp) < iLenCallto)
  2262. continue;
  2263. if (StrCmpNI(lp, szCallto, iLenCallto))
  2264. {
  2265. // Not a callto string .. retain it
  2266. if(HR_FAILED(hr = AddPropToMVPString( lpPropArray, ulcPropCount, ulIndex, lp)))
  2267. {
  2268. DebugPrintError(( TEXT("AddPropToMVString Conf server %s failed: %x"),lp, hr));
  2269. goto out;
  2270. }
  2271. }
  2272. }
  2273. }
  2274. }
  2275. for(i=0;i< (ULONG) nItemCount; i++)
  2276. {
  2277. szBuf[0]='\0';
  2278. szEmail[0] = '\0';
  2279. {
  2280. LV_ITEM lvi = {0};
  2281. lvi.mask = LVIF_PARAM;
  2282. lvi.iItem = i; lvi.iSubItem = 0;
  2283. ListView_GetItem(hWndLV, &lvi);
  2284. if(lvi.lParam)
  2285. {
  2286. LPSERVER_ITEM lpSI = (LPSERVER_ITEM) lvi.lParam;
  2287. if(lpSI->lpServer)
  2288. StrCpyN(szBuf, lpSI->lpServer, ulSzBuf);
  2289. if(lpSI->lpEmail)
  2290. StrCpyN(szEmail, lpSI->lpEmail, ARRAYSIZE(szEmail));
  2291. }
  2292. }
  2293. if(lstrlen(szBuf) && lstrlen(szEmail))
  2294. {
  2295. StrCpyN(szCalltoStr, szCallto, cchCalltoStr);
  2296. StrCatBuff(szCalltoStr, szBuf, cchCalltoStr);
  2297. StrCatBuff(szCalltoStr, TEXT("/"), cchCalltoStr);
  2298. StrCatBuff(szCalltoStr, szEmail, cchCalltoStr);
  2299. if(HR_FAILED(hr = AddPropToMVPString( lpPropArray, ulcPropCount, ulIndex, szCalltoStr)))
  2300. {
  2301. DebugPrintError(( TEXT("AddPropToMVString Conf server %s failed: %x"),szCalltoStr, hr));
  2302. goto out;
  2303. }
  2304. }
  2305. }
  2306. LocalFreeAndNull(&szCalltoStr);
  2307. }
  2308. ulIndex++;
  2309. lpPropArray[ulIndex].ulPropTag = PR_WAB_CONF_DEFAULT_INDEX;
  2310. lpPropArray[ulIndex].Value.l = (ULONG) lpPai->nDefaultServerIndex;
  2311. ulIndex++;
  2312. if(lpPai->nBackupServerIndex != -1)
  2313. {
  2314. lpPropArray[ulIndex].ulPropTag = PR_WAB_CONF_BACKUP_INDEX;
  2315. lpPropArray[ulIndex].Value.l = (ULONG) lpPai->nBackupServerIndex;
  2316. ulIndex++;
  2317. }
  2318. }
  2319. *lppPropArray = lpPropArray;
  2320. *lpulcPropCount = ulIndex;
  2321. bRet = TRUE;
  2322. out:
  2323. if (!bRet)
  2324. {
  2325. if ((lpPropArray) && (ulcPropCount > 0))
  2326. {
  2327. MAPIFreeBuffer(lpPropArray);
  2328. ulcPropCount = 0;
  2329. }
  2330. }
  2331. LocalFreeAndNull(&szBuf);
  2332. FreeBufferAndNull(&rgProps);
  2333. return bRet;
  2334. }
  2335. /*
  2336. - bGetFamilyInfo - get's info back from the Family Prop
  2337. -
  2338. */
  2339. BOOL bGetFamilyInfo(HWND hDlg, LPPROP_ARRAY_INFO lpPai,
  2340. ID_PROP * lpidProp, ULONG idPropCount,
  2341. LPSPropValue * lppPropArray, ULONG * lpulcPropCount)
  2342. {
  2343. ULONG ulSzBuf = 4*MAX_BUF_STR;
  2344. LPTSTR szBuf = LocalAlloc(LMEM_ZEROINIT, ulSzBuf*sizeof(TCHAR));
  2345. BOOL bRet = FALSE;
  2346. ULONG ulNotEmptyCount = 0;
  2347. SCODE sc = S_OK;
  2348. ULONG i = 0;
  2349. LPSPropValue lpPropArray = NULL;
  2350. ULONG ulcPropCount = 0,ulIndex=0;
  2351. HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_FAMILY_LIST_CHILDREN);
  2352. SYSTEMTIME st = {0};
  2353. short int nSel = 0;
  2354. int nCount = 0;
  2355. //The biggest field in the UI is about 2K length - just to be safe we want about 4K
  2356. // in this buffer so we need to allocate it dynamically
  2357. if(!szBuf)
  2358. {
  2359. DebugTrace(( TEXT("LocalAlloc failed to allocate memory\n")));
  2360. return FALSE;
  2361. }
  2362. for(i=0;i<idPropCount;i++)
  2363. {
  2364. switch(lpidProp[i].idCtl)
  2365. {
  2366. case IDC_DETAILS_FAMILY_LIST_CHILDREN:
  2367. if( lpPai->ulFlags & DETAILS_ChildrenChanged ||
  2368. ListView_GetItemCount(hWndLV) > 0)
  2369. ulNotEmptyCount++;
  2370. continue;
  2371. break;
  2372. case IDC_DETAILS_FAMILY_DATE_BIRTHDAY:
  2373. case IDC_DETAILS_FAMILY_DATE_ANNIVERSARY:
  2374. {
  2375. SYSTEMTIME st = {0};
  2376. if( lpPai->ulFlags & DETAILS_DateChanged ||
  2377. GDT_VALID == SendDlgItemMessage(hDlg, lpidProp[i].idCtl, DTM_GETSYSTEMTIME, 0, (LPARAM) &st))
  2378. ulNotEmptyCount++;
  2379. }
  2380. continue;
  2381. case IDC_DETAILS_HOME_COMBO_GENDER:
  2382. if( lpPai->ulFlags & DETAILS_GenderChanged ||
  2383. SendDlgItemMessage(hDlg, IDC_DETAILS_HOME_COMBO_GENDER, CB_GETCURSEL, 0, 0)>0 )
  2384. ulNotEmptyCount++;
  2385. continue;
  2386. break;
  2387. }
  2388. szBuf[0]='\0'; //reset
  2389. GetDlgItemText(hDlg, lpidProp[i].idCtl, szBuf, ulSzBuf);
  2390. TrimSpaces(szBuf);
  2391. if(lstrlen(szBuf) && lpidProp[i].ulPropTag) //some text
  2392. ulNotEmptyCount++;
  2393. }
  2394. if (ulNotEmptyCount == 0)
  2395. {
  2396. bRet = TRUE;
  2397. goto out;
  2398. }
  2399. ulcPropCount = ulNotEmptyCount;
  2400. sc = MAPIAllocateBuffer(sizeof(SPropValue) * ulcPropCount, &lpPropArray);
  2401. if (sc!=S_OK)
  2402. {
  2403. DebugTrace(( TEXT("Error allocating memory\n")));
  2404. goto out;
  2405. }
  2406. ulIndex = 0; //now we reuse this variable as an index
  2407. // Now read the props again and fill in the lpPropArray
  2408. for(i=0;i<idPropCount;i++)
  2409. {
  2410. switch(lpidProp[i].idCtl)
  2411. {
  2412. case IDC_DETAILS_FAMILY_DATE_BIRTHDAY:
  2413. case IDC_DETAILS_FAMILY_DATE_ANNIVERSARY:
  2414. case IDC_DETAILS_HOME_COMBO_GENDER:
  2415. case IDC_DETAILS_FAMILY_LIST_CHILDREN:
  2416. continue;
  2417. break;
  2418. }
  2419. szBuf[0]='\0'; //reset
  2420. GetDlgItemText(hDlg, lpidProp[i].idCtl, szBuf, ulSzBuf);
  2421. TrimSpaces(szBuf);
  2422. if(lstrlen(szBuf) && lpidProp[i].ulPropTag) //some text
  2423. {
  2424. ULONG nLen = sizeof(TCHAR)*(lstrlen(szBuf)+1);
  2425. lpPropArray[ulIndex].ulPropTag = lpidProp[i].ulPropTag;
  2426. sc = MAPIAllocateMore(nLen, lpPropArray, (LPVOID *) (&(lpPropArray[ulIndex].Value.LPSZ)));
  2427. if (sc!=S_OK)
  2428. {
  2429. DebugTrace( TEXT("Error allocating memory\n"));
  2430. goto out;
  2431. }
  2432. StrCpyN(lpPropArray[ulIndex].Value.LPSZ,szBuf,nLen/sizeof(TCHAR));
  2433. ulIndex++;
  2434. }
  2435. }
  2436. // Get the Gender data
  2437. //
  2438. nCount = ListView_GetItemCount(hWndLV);
  2439. if(lpPai->ulFlags & DETAILS_ChildrenChanged || nCount>0)
  2440. {
  2441. ULONG ulCount = 0;
  2442. if(nCount > 0)
  2443. {
  2444. lpPropArray[ulIndex].ulPropTag = PR_CHILDRENS_NAMES;
  2445. sc = MAPIAllocateMore(nCount * sizeof(LPTSTR), lpPropArray, (LPVOID *)&(lpPropArray[ulIndex].Value.MVSZ.LPPSZ));
  2446. if (sc!=S_OK)
  2447. {
  2448. DebugTrace( TEXT("Error allocating memory\n"));
  2449. goto out;
  2450. }
  2451. for(i=0;i<(ULONG)nCount;i++)
  2452. {
  2453. *szBuf = '\0';
  2454. ListView_GetItemText(hWndLV, i, 0, szBuf, ulSzBuf);
  2455. if(szBuf && lstrlen(szBuf))
  2456. {
  2457. ULONG cchSize=lstrlen(szBuf)+1;
  2458. sc = MAPIAllocateMore(sizeof(TCHAR)*cchSize, lpPropArray, (LPVOID *) (&(lpPropArray[ulIndex].Value.MVSZ.LPPSZ[ulCount])));
  2459. if (sc!=S_OK)
  2460. {
  2461. DebugTrace( TEXT("Error allocating memory\n"));
  2462. goto out;
  2463. }
  2464. StrCpyN(lpPropArray[ulIndex].Value.MVSZ.LPPSZ[ulCount], szBuf, cchSize);
  2465. ulCount++;
  2466. }
  2467. }
  2468. lpPropArray[ulIndex].Value.MVSZ.cValues = ulCount;
  2469. ulIndex++;
  2470. }
  2471. }
  2472. nSel = (short int) SendDlgItemMessage(hDlg, IDC_DETAILS_HOME_COMBO_GENDER, CB_GETCURSEL, 0, 0);
  2473. if(nSel == CB_ERR)
  2474. nSel = 0;
  2475. if(lpPai->ulFlags & DETAILS_GenderChanged || nSel>0)
  2476. {
  2477. lpPropArray[ulIndex].ulPropTag = PR_GENDER;
  2478. lpPropArray[ulIndex].Value.i = nSel;
  2479. ulIndex++;
  2480. }
  2481. if(GDT_VALID == SendDlgItemMessage(hDlg, IDC_DETAILS_FAMILY_DATE_BIRTHDAY, DTM_GETSYSTEMTIME, 0, (LPARAM) &st))
  2482. {
  2483. lpPropArray[ulIndex].ulPropTag = PR_BIRTHDAY;
  2484. SystemTimeToFileTime(&st, (FILETIME *) (&lpPropArray[ulIndex].Value.ft));
  2485. ulIndex++;
  2486. }
  2487. if(GDT_VALID == SendDlgItemMessage(hDlg, IDC_DETAILS_FAMILY_DATE_ANNIVERSARY, DTM_GETSYSTEMTIME, 0, (LPARAM) &st))
  2488. {
  2489. lpPropArray[ulIndex].ulPropTag = PR_WEDDING_ANNIVERSARY;
  2490. SystemTimeToFileTime(&st, (FILETIME *) (&lpPropArray[ulIndex].Value.ft));
  2491. ulIndex++;
  2492. }
  2493. *lppPropArray = lpPropArray;
  2494. *lpulcPropCount = ulIndex;
  2495. bRet = TRUE;
  2496. out:
  2497. if (!bRet)
  2498. {
  2499. if ((lpPropArray) && (ulcPropCount > 0))
  2500. {
  2501. MAPIFreeBuffer(lpPropArray);
  2502. ulcPropCount = 0;
  2503. }
  2504. }
  2505. LocalFreeAndNull(&szBuf);
  2506. return bRet;
  2507. }
  2508. //$$//////////////////////////////////////////////////////////////////////////////
  2509. //
  2510. // GetDetails from UI - reads the UI for its parameters and verifies that
  2511. // all required fields are set.
  2512. //
  2513. //////////////////////////////////////////////////////////////////////////////////
  2514. BOOL GetDetailsFromUI( HWND hDlg, LPPROP_ARRAY_INFO lpPai ,
  2515. BOOL bSomethingChanged, int nPropSheet,
  2516. LPSPropValue * lppPropArray, LPULONG lpulcPropCount)
  2517. {
  2518. BOOL bRet = TRUE;
  2519. ULONG i = 0;
  2520. LPSPropValue lpPropArray = NULL;
  2521. ULONG ulcPropCount = 0,ulIndex=0;
  2522. ID_PROP * lpidProp = NULL;
  2523. ULONG idPropCount = 0;
  2524. ULONG ulNotEmptyCount = 0;
  2525. SCODE sc = S_OK;
  2526. HRESULT hr = hrSuccess;
  2527. if (!bSomethingChanged)
  2528. {
  2529. bRet = TRUE;
  2530. goto out;
  2531. }
  2532. *lppPropArray = NULL;
  2533. *lpulcPropCount = 0;
  2534. DebugTrace( TEXT("GetDetailsFromUI: %d\n"),nPropSheet);
  2535. switch(nPropSheet)
  2536. {
  2537. case propHome:
  2538. idPropCount = idPropHomeCount;
  2539. lpidProp = idPropHome;
  2540. lpidProp[idPropHomePostalID].ulPropTag = PR_WAB_POSTALID;
  2541. goto GetProp;
  2542. case propBusiness:
  2543. idPropCount = idPropBusinessCount;
  2544. lpidProp = idPropBusiness;
  2545. lpidProp[idPropBusIPPhone].ulPropTag = PR_WAB_IPPHONE;
  2546. lpidProp[idPropBusPostalID].ulPropTag = PR_WAB_POSTALID;
  2547. goto GetProp;
  2548. case propNotes:
  2549. idPropCount = idPropNotesCount;
  2550. lpidProp = idPropNotes;
  2551. GetProp:
  2552. bRet = bGetHomeBusNotesInfo(hDlg, lpPai, nPropSheet,
  2553. lpidProp, idPropCount,lppPropArray, lpulcPropCount);
  2554. break;
  2555. /***********/
  2556. case propPersonal:
  2557. bRet = bGetPersonalInfo(hDlg, lpPai, idPropPersonal, idPropPersonalCount, lppPropArray, lpulcPropCount);
  2558. break; // case propPersonal
  2559. /***********/
  2560. case propCert:
  2561. // There is only 1 property, PR_USER_X509_CERTIFICATE
  2562. if(lpPai->lpCItem)
  2563. {
  2564. if(HR_FAILED(HrSetCertsFromDisplayInfo( lpPai->lpCItem, lpulcPropCount, lppPropArray)))
  2565. bRet = FALSE;
  2566. }
  2567. break;
  2568. /***********/
  2569. case propConferencing:
  2570. bRet = bGetConferencingInfo(hDlg, lpPai,lppPropArray, lpulcPropCount);
  2571. break;
  2572. /***********/
  2573. case propFamily:
  2574. bRet = bGetFamilyInfo(hDlg, lpPai, idPropFamily, idPropFamilyCount, lppPropArray, lpulcPropCount);
  2575. break;
  2576. }
  2577. out:
  2578. if (!bRet)
  2579. {
  2580. if ((lpPropArray) && (ulcPropCount > 0))
  2581. {
  2582. MAPIFreeBuffer(lpPropArray);
  2583. ulcPropCount = 0;
  2584. }
  2585. }
  2586. return bRet;
  2587. }
  2588. //$$//////////////////////////////////////////////////////////////////////////
  2589. //
  2590. // bUpdatePropArray
  2591. //
  2592. // Updates the prop array info for each sheet that is stored in the globaly accessible
  2593. // pointer
  2594. //
  2595. //////////////////////////////////////////////////////////////////////////////
  2596. BOOL bUpdatePropArray(HWND hDlg, LPPROP_ARRAY_INFO lpPai, int nPropSheet)
  2597. {
  2598. BOOL bRet = TRUE;
  2599. ULONG cValues = 0;
  2600. LPSPropValue rgPropVals = NULL;
  2601. if (lpPai->ulOperationType != SHOW_ONE_OFF)
  2602. {
  2603. bUpdateOldPropTagArray(lpPai, nPropSheet);
  2604. lpPai->bSomethingChanged = ChangedExtDisplayInfo(lpPai, lpPai->bSomethingChanged);
  2605. if(lpPai->bSomethingChanged)
  2606. {
  2607. bRet = GetDetailsFromUI( hDlg, lpPai, lpPai->bSomethingChanged, nPropSheet, &rgPropVals, &cValues);
  2608. if(cValues && rgPropVals)
  2609. {
  2610. #ifdef DEBUG
  2611. _DebugProperties(rgPropVals, cValues, TEXT("GetDetails from UI\n"));
  2612. #endif
  2613. lpPai->lpPropObj->lpVtbl->SetProps(lpPai->lpPropObj, cValues, rgPropVals, NULL);
  2614. }
  2615. }
  2616. }
  2617. FreeBufferAndNull(&rgPropVals);
  2618. return bRet;
  2619. }
  2620. #define lpPAI ((LPPROP_ARRAY_INFO) pps->lParam)
  2621. #define lpbSomethingChanged (&(lpPAI->bSomethingChanged))
  2622. /*//$$***********************************************************************
  2623. * FUNCTION: fnPersonalProc
  2624. *
  2625. * PURPOSE: Callback function for handling the PERSONAL property sheet ...
  2626. *
  2627. ****************************************************************************/
  2628. INT_PTR CALLBACK fnPersonalProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)
  2629. {
  2630. PROPSHEETPAGE * pps;
  2631. BOOL bRet = FALSE;
  2632. pps = (PROPSHEETPAGE *) GetWindowLongPtr(hDlg, DWLP_USER);
  2633. switch(message)
  2634. {
  2635. case WM_INITDIALOG:
  2636. SetWindowLongPtr(hDlg,DWLP_USER,lParam);
  2637. pps = (PROPSHEETPAGE *) lParam;
  2638. lpPAI->ulFlags |= DETAILS_Initializing;
  2639. ChangeLocaleBasedTabOrder(hDlg, contactPersonal);
  2640. SetDetailsUI(hDlg,lpPAI, lpPAI->ulOperationType,propPersonal);
  2641. lpPAI->ulFlags &= ~DETAILS_Initializing;
  2642. return TRUE;
  2643. case WM_DESTROY:
  2644. bRet = TRUE;
  2645. break;
  2646. case WM_SYSCOLORCHANGE:
  2647. //Forward any system changes to the list view
  2648. SendMessage(GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_LIST), message, wParam, lParam);
  2649. break;
  2650. case WM_HELP:
  2651. WABWinHelp(((LPHELPINFO)lParam)->hItemHandle,
  2652. g_szWABHelpFileName,
  2653. HELP_WM_HELP,
  2654. (DWORD_PTR)(LPSTR) rgDetlsHelpIDs );
  2655. break;
  2656. case WM_CONTEXTMENU:
  2657. WABWinHelp((HWND) wParam,
  2658. g_szWABHelpFileName,
  2659. HELP_CONTEXTMENU,
  2660. (DWORD_PTR)(LPVOID) rgDetlsHelpIDs );
  2661. break;
  2662. case WM_COMMAND:
  2663. switch(GET_WM_COMMAND_CMD(wParam,lParam)) //check the notification code
  2664. {
  2665. case CBN_DROPDOWN:
  2666. switch(LOWORD(wParam))
  2667. {
  2668. case IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME:
  2669. SetComboDNText(hDlg, lpPAI, TRUE, NULL);
  2670. break;
  2671. }
  2672. break;
  2673. case CBN_SELCHANGE:
  2674. switch(LOWORD(wParam))
  2675. {
  2676. case IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME:
  2677. {
  2678. int nSel = (int) SendDlgItemMessage(hDlg, IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME, CB_GETCURSEL, 0, 0);
  2679. if(nSel != CB_ERR)
  2680. {
  2681. int nLen = (int) SendDlgItemMessage(hDlg, IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME, CB_GETLBTEXTLEN, (WPARAM)nSel, 0);
  2682. if(nLen != CB_ERR)
  2683. {
  2684. LPTSTR lpsz = LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*(nLen + 1));
  2685. if(lpsz)
  2686. {
  2687. SendDlgItemMessage(hDlg, IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME, CB_GETLBTEXT, (WPARAM)nSel, (LPARAM)lpsz);
  2688. SetWindowPropertiesTitle(GetParent(hDlg), lpsz);
  2689. if (lpbSomethingChanged) //some edit box changed - dont care which
  2690. (*lpbSomethingChanged) = TRUE;
  2691. LocalFreeAndNull(&lpsz);
  2692. }
  2693. }
  2694. }
  2695. }
  2696. break;
  2697. }
  2698. break;
  2699. case CBN_EDITCHANGE:
  2700. switch(LOWORD(wParam))
  2701. {
  2702. case IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME:
  2703. if(!(lpPAI->ulFlags & DETAILS_ProgChange) )
  2704. {
  2705. lpPAI->ulFlags &= ~DETAILS_DNisFMLName;
  2706. lpPAI->ulFlags &= ~DETAILS_DNisNickName;
  2707. lpPAI->ulFlags &= ~DETAILS_DNisCompanyName;
  2708. }
  2709. {
  2710. TCHAR szBuf[MAX_UI_STR];
  2711. szBuf[0]='\0';
  2712. GetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME, szBuf, CharSizeOf(szBuf));
  2713. SetWindowPropertiesTitle(GetParent(hDlg), szBuf);
  2714. if (lpbSomethingChanged) //some edit box changed - dont care which
  2715. (*lpbSomethingChanged) = TRUE;
  2716. }
  2717. break;
  2718. }
  2719. break;
  2720. case EN_CHANGE:
  2721. if(lpPAI->ulFlags & DETAILS_Initializing)
  2722. break;
  2723. if (lpbSomethingChanged) //some edit box changed - dont care which
  2724. (*lpbSomethingChanged) = TRUE;
  2725. switch(LOWORD(wParam))
  2726. {
  2727. case IDC_DETAILS_PERSONAL_EDIT_ADDEMAIL:
  2728. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_ADDEMAIL),TRUE);
  2729. SendMessage(hDlg, DM_SETDEFID, IDC_DETAILS_PERSONAL_BUTTON_ADDEMAIL, 0);
  2730. return 0;
  2731. break;
  2732. case IDC_DETAILS_PERSONAL_EDIT_FIRSTNAME:
  2733. case IDC_DETAILS_PERSONAL_EDIT_LASTNAME:
  2734. case IDC_DETAILS_PERSONAL_EDIT_MIDDLENAME:
  2735. // if there is nothing in the display name field (new contact)
  2736. // and we are typing here, update the display name
  2737. //TCHAR szBuf[2];
  2738. //int nText = GetWindowText(lpPAI->hWndDisplayNameField, szBuf, CharSizeOf(szBuf));
  2739. if(lpPAI->ulFlags & DETAILS_DNisFMLName)// || !nText)
  2740. {
  2741. lpPAI->ulFlags |= DETAILS_ProgChange;
  2742. SetDetailsWindowTitle(hDlg, TRUE);
  2743. lpPAI->ulFlags &= ~DETAILS_ProgChange;
  2744. }
  2745. // [PaulHi] 4/8/99
  2746. // If the text in the edit box was deleted then also delete the corresponding
  2747. // Ruby field text
  2748. if(lpPAI->ulFlags & DETAILS_UseRubyPersonal)
  2749. {
  2750. HWND hWndEdit = GetDlgItem(hDlg, LOWORD(wParam));
  2751. HWND hWndRuby = NULL;
  2752. WCHAR wszTemp[EDIT_LEN];
  2753. Assert(hWndEdit);
  2754. GetWindowText(hWndEdit, wszTemp, EDIT_LEN);
  2755. if (*wszTemp == '\0')
  2756. {
  2757. // Clear either the first or last name ruby field, depending on which
  2758. // edit control this is.
  2759. switch (LOWORD(wParam))
  2760. {
  2761. case IDC_DETAILS_PERSONAL_EDIT_FIRSTNAME:
  2762. hWndRuby = GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_STATIC_RUBYFIRST);
  2763. break;
  2764. case IDC_DETAILS_PERSONAL_EDIT_LASTNAME:
  2765. hWndRuby = GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_STATIC_RUBYLAST);
  2766. break;
  2767. default:
  2768. break;
  2769. }
  2770. if (hWndRuby)
  2771. SetWindowText(hWndRuby, szEmpty);
  2772. }
  2773. }
  2774. break;
  2775. case IDC_DETAILS_PERSONAL_EDIT_NICKNAME:
  2776. {
  2777. if(lpPAI->ulFlags & DETAILS_DNisNickName)
  2778. {
  2779. TCHAR szBuf[MAX_UI_STR];
  2780. szBuf[0]='\0';
  2781. GetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_EDIT_NICKNAME, szBuf, CharSizeOf(szBuf));
  2782. lpPAI->ulFlags |= DETAILS_ProgChange;
  2783. SetComboDNText(hDlg, lpPAI, FALSE, szBuf);
  2784. lpPAI->ulFlags &= ~DETAILS_ProgChange;
  2785. }
  2786. else
  2787. SetComboDNText(hDlg, lpPAI, TRUE, NULL);
  2788. }
  2789. break;
  2790. default:
  2791. break;
  2792. }
  2793. break;
  2794. }
  2795. switch(GET_WM_COMMAND_ID(wParam, lParam))
  2796. {
  2797. case IDC_DETAILS_PERSONAL_BUTTON_RUBY:
  2798. ShowRubyNameEntryDlg(hDlg, lpPAI);
  2799. break;
  2800. case IDC_DETAILS_PERSONAL_CHECK_RICHINFO:
  2801. if (lpbSomethingChanged)
  2802. (*lpbSomethingChanged) = TRUE;
  2803. break;
  2804. case IDC_DETAILS_PERSONAL_BUTTON_SETDEFAULT:
  2805. {
  2806. HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_LIST);
  2807. if(ListView_GetSelectedCount(hWndLV)==1)
  2808. {
  2809. SetLVDefaultEmail( hWndLV, ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED));
  2810. if (lpbSomethingChanged)
  2811. (*lpbSomethingChanged) = TRUE;
  2812. }
  2813. }
  2814. break;
  2815. case IDC_DETAILS_PERSONAL_BUTTON_EDIT:
  2816. {
  2817. HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_LIST);
  2818. if(ListView_GetSelectedCount(hWndLV)==1)
  2819. {
  2820. HWND hWndEditLabel;
  2821. int index = ListView_GetNextItem(hWndLV,-1,LVNI_SELECTED);
  2822. SetFocus(hWndLV);
  2823. hWndEditLabel = ListView_EditLabel(hWndLV, index);
  2824. // Set Text Limit on this Edit Box
  2825. SendMessage(hWndEditLabel, EM_LIMITTEXT, EDIT_LEN, 0);
  2826. }
  2827. }
  2828. break;
  2829. case IDC_DETAILS_PERSONAL_BUTTON_REMOVE:
  2830. {
  2831. HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_LIST);
  2832. if(ListView_GetSelectedCount(hWndLV)>=1)
  2833. {
  2834. BOOL bSetNewDefault = FALSE;
  2835. int iItemIndex = ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED);
  2836. while(iItemIndex != -1)
  2837. {
  2838. BOOL bRet = FALSE;
  2839. bRet = DeleteLVEmailItem(hWndLV,iItemIndex);
  2840. if (!bSetNewDefault)
  2841. bSetNewDefault = bRet;
  2842. iItemIndex = ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED);
  2843. }
  2844. if (bSetNewDefault && (ListView_GetItemCount(hWndLV) > 0))
  2845. SetLVDefaultEmail(hWndLV, 0);
  2846. if (lpbSomethingChanged)
  2847. (*lpbSomethingChanged) = TRUE;
  2848. if (ListView_GetItemCount(hWndLV) <= 0)
  2849. {
  2850. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_REMOVE),FALSE);
  2851. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_SETDEFAULT),FALSE);
  2852. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_EDIT),FALSE);
  2853. SetFocus(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_EDIT_ADDEMAIL));
  2854. return FALSE;
  2855. }
  2856. else
  2857. {
  2858. //make sure something is selected
  2859. if(ListView_GetSelectedCount(hWndLV) <= 0)
  2860. LVSelectItem(hWndLV,0);
  2861. }
  2862. }
  2863. }
  2864. break;
  2865. case IDC_DETAILS_PERSONAL_BUTTON_ADDEMAIL:
  2866. AddNewEmailEntry(hDlg,FALSE);
  2867. return FALSE;
  2868. break;
  2869. }
  2870. break;
  2871. case WM_NOTIFY:
  2872. switch(((NMHDR FAR *)lParam)->code)
  2873. {
  2874. case PSN_SETACTIVE: //initialize
  2875. FillPersonalDetails(hDlg, lpPAI, propPersonal, lpbSomethingChanged);
  2876. if(lpPAI->ulOperationType != SHOW_ONE_OFF)
  2877. {
  2878. // Since items to this list view can be added from certs and conf panes,
  2879. // update this everytime the focus somes back to us
  2880. if(ListView_GetItemCount(GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_LIST)) > 0)
  2881. {
  2882. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_REMOVE),TRUE);
  2883. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_SETDEFAULT),TRUE);
  2884. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_EDIT),TRUE);
  2885. }
  2886. }
  2887. break;
  2888. case PSN_KILLACTIVE: //Losing activation to another page
  2889. if (lpPAI->ulOperationType != SHOW_ONE_OFF)
  2890. {
  2891. // check if there is some pending email entry
  2892. if(IDCANCEL == AddNewEmailEntry(hDlg,TRUE))
  2893. {
  2894. //abort this ok
  2895. SetFocus(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_EDIT_ADDEMAIL));
  2896. SetWindowLongPtr(hDlg,DWLP_MSGRESULT, TRUE);
  2897. return TRUE;
  2898. }
  2899. }
  2900. bUpdatePropArray(hDlg, lpPAI, propPersonal);
  2901. FreeLVParams(GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_LIST),LV_EMAIL);
  2902. break;
  2903. case PSN_APPLY: //ok
  2904. if (lpPAI->ulOperationType != SHOW_ONE_OFF)
  2905. {
  2906. int CtlID = 0; //used to determine which required field in the UI has not been set
  2907. ULONG ulcPropCount = 0;
  2908. if(!bVerifyRequiredData(hDlg, lpPAI, propPersonal, &CtlID))
  2909. {
  2910. SetFocus(GetDlgItem(hDlg,CtlID));
  2911. SetWindowLongPtr(hDlg,DWLP_MSGRESULT, TRUE);
  2912. return TRUE;
  2913. }
  2914. }
  2915. //bUpdatePropArray(hDlg, lpPAI, propPersonal);
  2916. //FreeLVParams(GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_LIST),LV_EMAIL);
  2917. if (lpPAI->nRetVal == DETAILS_RESET)
  2918. lpPAI->nRetVal = DETAILS_OK;
  2919. break;
  2920. case PSN_RESET: //cancel
  2921. if(lpPAI->ulFlags & DETAILS_EditingEmail) //cancel any email editing else it faults #30235
  2922. {
  2923. ListView_EditLabel(GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_LIST), -1);
  2924. lpPAI->ulFlags &= ~DETAILS_EditingEmail;
  2925. }
  2926. FreeLVParams(GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_LIST),LV_EMAIL);
  2927. if (lpPAI->nRetVal == DETAILS_RESET)
  2928. lpPAI->nRetVal = DETAILS_CANCEL;
  2929. break;
  2930. case LVN_BEGINLABELEDITA:
  2931. case LVN_BEGINLABELEDITW:
  2932. {
  2933. // We are editing a email address in teh list box
  2934. // We need to get:
  2935. // item index number
  2936. // item lParam
  2937. // edit box hWnd
  2938. // and replace the text with the actual email address
  2939. HWND hWndLV = ((NMHDR FAR *)lParam)->hwndFrom;
  2940. LV_ITEM lvi = ((LV_DISPINFO FAR *) lParam)->item;
  2941. if (lvi.iItem >= 0)
  2942. {
  2943. HWND hWndLVEdit = NULL;
  2944. LPEMAIL_ITEM lpEItem = NULL;
  2945. if (lvi.mask & LVIF_PARAM)
  2946. {
  2947. lpEItem = (LPEMAIL_ITEM) lvi.lParam;
  2948. }
  2949. else
  2950. {
  2951. lvi.mask |= LVIF_PARAM;
  2952. if (ListView_GetItem(hWndLV, &lvi))
  2953. lpEItem = (LPEMAIL_ITEM) lvi.lParam;
  2954. }
  2955. if (!lpEItem)
  2956. return TRUE; //prevents editing
  2957. hWndLVEdit = ListView_GetEditControl(hWndLV);
  2958. if (!hWndLVEdit)
  2959. return TRUE;
  2960. lpPAI->ulFlags |= DETAILS_EditingEmail;
  2961. SendMessage(hWndLVEdit, WM_SETTEXT, 0, (LPARAM) lpEItem->szEmailAddress);//lpText);
  2962. return FALSE;
  2963. }
  2964. }
  2965. return TRUE;
  2966. break;
  2967. case LVN_ENDLABELEDITA:
  2968. case LVN_ENDLABELEDITW:
  2969. {
  2970. // We get the text from the edit box and put it in the item data
  2971. BOOL bRet = FALSE;
  2972. HWND hWndLV = ((NMHDR FAR *)lParam)->hwndFrom;
  2973. LV_ITEM lvi = ((LV_DISPINFO FAR *) lParam)->item;
  2974. LPWSTR lpW = NULL;
  2975. LPSTR lpA = NULL;
  2976. if(!g_bRunningOnNT) //on Win9x we will get an LV_ITEMA, not a LV_ITEMW
  2977. {
  2978. lpA = (LPSTR)lvi.pszText;
  2979. lpW = ConvertAtoW(lpA);
  2980. lvi.pszText = lpW;
  2981. }
  2982. if ((lvi.iItem >= 0) && lvi.pszText && (lstrlen(lvi.pszText)))
  2983. {
  2984. LV_ITEM lviActual = {0};
  2985. LPEMAIL_ITEM lpEItem = NULL;
  2986. BOOL bSetDefault = FALSE;
  2987. LPTSTR lpText = lvi.pszText;
  2988. LPTSTR lpszEmailAddress = NULL;
  2989. if(!IsInternetAddress(lpText, &lpszEmailAddress))
  2990. {
  2991. if(IDNO == ShowMessageBox(GetParent(hDlg), idsInvalidInternetAddress, MB_ICONEXCLAMATION | MB_YESNO))
  2992. {
  2993. bRet = TRUE;
  2994. goto endN;
  2995. }
  2996. }
  2997. // bobn, Raid 87496, IsInternetAddress can correctly leave lpszEmailAddress NULL
  2998. // if it returns false. If the user said to use it, we need to set it accordingly.
  2999. if(!lpszEmailAddress)
  3000. lpszEmailAddress = lpText;
  3001. lviActual.mask = LVIF_PARAM | LVIF_TEXT;
  3002. lviActual.iItem = lvi.iItem;
  3003. if (ListView_GetItem(hWndLV, &lviActual))
  3004. lpEItem = (LPEMAIL_ITEM) lviActual.lParam;
  3005. if (!lpEItem)
  3006. {
  3007. bRet = TRUE;
  3008. goto endN;
  3009. }
  3010. StrCpyN(lpEItem->szEmailAddress, lpszEmailAddress, ARRAYSIZE(lpEItem->szEmailAddress));
  3011. StrCpyN(lpEItem->szDisplayText, lpszEmailAddress, ARRAYSIZE(lpEItem->szDisplayText));
  3012. lviActual.pszText = lpszEmailAddress;
  3013. // Throw away any display name that may have been entered here.
  3014. bSetDefault = lpEItem->bIsDefault;
  3015. lpEItem->bIsDefault = FALSE; //this will be set again in SetLVDefaultEmail function
  3016. ListView_SetItem(hWndLV, &lviActual);
  3017. if (bSetDefault)
  3018. SetLVDefaultEmail(hWndLV, lvi.iItem);
  3019. lpPAI->ulFlags &= ~DETAILS_EditingEmail;
  3020. bRet = FALSE;
  3021. }
  3022. endN:
  3023. LocalFreeAndNull(&lpW);
  3024. if(!g_bRunningOnNT)
  3025. ((LV_DISPINFO FAR *) lParam)->item.pszText = (LPWSTR)lpA; // reset it as we found it
  3026. return bRet;
  3027. }
  3028. return TRUE;
  3029. break;
  3030. case NM_DBLCLK:
  3031. switch(wParam)
  3032. {
  3033. case IDC_DETAILS_PERSONAL_LIST:
  3034. {
  3035. NM_LISTVIEW * pNm = (NM_LISTVIEW *)lParam;
  3036. if (ListView_GetSelectedCount(pNm->hdr.hwndFrom) == 1)
  3037. {
  3038. int iItemIndex = ListView_GetNextItem(pNm->hdr.hwndFrom,-1,LVNI_SELECTED);
  3039. SetLVDefaultEmail(pNm->hdr.hwndFrom, iItemIndex);
  3040. if (lpbSomethingChanged)
  3041. (*lpbSomethingChanged) = TRUE;
  3042. }
  3043. }
  3044. break;
  3045. }
  3046. break;
  3047. case NM_CUSTOMDRAW:
  3048. switch(wParam)
  3049. {
  3050. case IDC_DETAILS_PERSONAL_LIST:
  3051. {
  3052. NMCUSTOMDRAW *pnmcd=(NMCUSTOMDRAW*)lParam;
  3053. NM_LISTVIEW * pNm = (NM_LISTVIEW *)lParam;
  3054. if(pnmcd->dwDrawStage==CDDS_PREPAINT)
  3055. {
  3056. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, CDRF_NOTIFYITEMDRAW | CDRF_DODEFAULT);
  3057. return TRUE;
  3058. }
  3059. else if(pnmcd->dwDrawStage==CDDS_ITEMPREPAINT)
  3060. {
  3061. LPEMAIL_ITEM lpEItem = (LPEMAIL_ITEM) pnmcd->lItemlParam;
  3062. if (lpEItem)
  3063. {
  3064. if(lpEItem->bIsDefault)
  3065. {
  3066. SelectObject(((NMLVCUSTOMDRAW*)lParam)->nmcd.hdc, GetFont(fntsSysIconBold));
  3067. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, CDRF_NEWFONT);
  3068. return TRUE;
  3069. }
  3070. #ifdef WIN16 // Set font
  3071. else
  3072. {
  3073. SelectObject(((NMLVCUSTOMDRAW*)lParam)->nmcd.hdc, GetFont(fntsSysIcon));
  3074. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, CDRF_NEWFONT);
  3075. return TRUE;
  3076. }
  3077. #endif
  3078. }
  3079. }
  3080. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, CDRF_DODEFAULT);
  3081. return TRUE;
  3082. }
  3083. break;
  3084. }
  3085. break;
  3086. }
  3087. break; //WM_NOTIFY
  3088. default:
  3089. #ifndef WIN16 // WIN16 doesn't support MSWheel.
  3090. if((g_msgMSWheel && message == g_msgMSWheel)
  3091. // || message == WM_MOUSEWHEEL
  3092. )
  3093. {
  3094. SendMessage(GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_LIST), message, wParam, lParam);
  3095. }
  3096. #endif
  3097. break;
  3098. } //switch
  3099. return bRet;
  3100. }
  3101. /*//$$***********************************************************************
  3102. * FUNCTION: fnHomeProc
  3103. *
  3104. * PURPOSE: Callback function for handling the HOME property sheet ...
  3105. *
  3106. ****************************************************************************/
  3107. INT_PTR CALLBACK fnHomeProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)
  3108. {
  3109. PROPSHEETPAGE * pps;
  3110. BOOL bRet = FALSE;
  3111. pps = (PROPSHEETPAGE *) GetWindowLongPtr(hDlg, DWLP_USER);
  3112. switch(message)
  3113. {
  3114. case WM_INITDIALOG:
  3115. SetWindowLongPtr(hDlg,DWLP_USER,lParam);
  3116. pps = (PROPSHEETPAGE *) lParam;
  3117. lpPAI->ulFlags |= DETAILS_Initializing;
  3118. SetDetailsUI(hDlg, lpPAI, lpPAI->ulOperationType,propHome);
  3119. ChangeLocaleBasedTabOrder(hDlg, contactHome);
  3120. lpPAI->ulFlags &= ~DETAILS_Initializing;
  3121. return TRUE;
  3122. case WM_HELP:
  3123. WABWinHelp(((LPHELPINFO)lParam)->hItemHandle,
  3124. g_szWABHelpFileName,
  3125. HELP_WM_HELP,
  3126. (DWORD_PTR)(LPSTR) rgDetlsHelpIDs );
  3127. break;
  3128. case WM_CONTEXTMENU:
  3129. WABWinHelp((HWND)wParam,
  3130. g_szWABHelpFileName,
  3131. HELP_CONTEXTMENU,
  3132. (DWORD_PTR)(LPVOID) rgDetlsHelpIDs );
  3133. break;
  3134. case WM_COMMAND:
  3135. switch(GET_WM_COMMAND_CMD(wParam,lParam)) //check the notification code
  3136. {
  3137. case EN_CHANGE: //some edit box changed - dont care which
  3138. if(lpPAI->ulFlags & DETAILS_Initializing)
  3139. break;
  3140. if (lpbSomethingChanged)
  3141. (*lpbSomethingChanged) = TRUE;
  3142. break;
  3143. }
  3144. {
  3145. int nCmd = GET_WM_COMMAND_ID(wParam, lParam);
  3146. switch(nCmd)
  3147. {
  3148. case IDC_DETAILS_HOME_CHECK_DEFAULTADDRESS:
  3149. if (lpbSomethingChanged)
  3150. (*lpbSomethingChanged) = TRUE;
  3151. lpPAI->ulFlags |= DETAILS_DefHomeChanged;
  3152. break;
  3153. case IDCANCEL:
  3154. // This is a windows bug that prevents ESC canceling prop sheets
  3155. // which have MultiLine Edit boxes KB: Q130765
  3156. SendMessage(GetParent(hDlg),message,wParam,lParam);
  3157. break;
  3158. case IDC_DETAILS_HOME_BUTTON_MAP:
  3159. bUpdatePropArray(hDlg, lpPAI, propHome); // update the props from the fields onto the prop-object
  3160. ShowExpediaMAP(hDlg, lpPAI->lpPropObj, TRUE);
  3161. break;
  3162. case IDC_DETAILS_HOME_BUTTON_URL:
  3163. ShowURL(hDlg, IDC_DETAILS_HOME_EDIT_URL,NULL);
  3164. break;
  3165. }
  3166. }
  3167. break;
  3168. case WM_NOTIFY:
  3169. switch(((NMHDR FAR *)lParam)->code)
  3170. {
  3171. case PSN_SETACTIVE: //initialize
  3172. FillHomeBusinessNotesDetailsUI(hDlg, lpPAI, propHome, lpbSomethingChanged);
  3173. break;
  3174. case PSN_KILLACTIVE: //Losing activation to another page
  3175. bUpdatePropArray(hDlg, lpPAI, propHome);
  3176. lpPAI->ulFlags &= ~DETAILS_DefHomeChanged; //reset flag
  3177. break;
  3178. case PSN_APPLY: //ok
  3179. //bUpdatePropArray(hDlg, lpPAI, propHome);
  3180. // in case any of the extended props changed, we need to mark this flag so we wont lose data
  3181. if (lpPAI->nRetVal == DETAILS_RESET)
  3182. lpPAI->nRetVal = DETAILS_OK;
  3183. break;
  3184. case PSN_RESET: //cancel
  3185. if (lpPAI->nRetVal == DETAILS_RESET)
  3186. lpPAI->nRetVal = DETAILS_CANCEL;
  3187. break;
  3188. }
  3189. return TRUE;
  3190. }
  3191. return bRet;
  3192. }
  3193. /*//$$***********************************************************************
  3194. * FUNCTION: fnBusinessProc
  3195. *
  3196. * PURPOSE: Callback function for handling the BUSINESS property sheet ...
  3197. *
  3198. ****************************************************************************/
  3199. INT_PTR CALLBACK fnBusinessProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)
  3200. {
  3201. PROPSHEETPAGE * pps;
  3202. BOOL bRet = FALSE;
  3203. pps = (PROPSHEETPAGE *) GetWindowLongPtr(hDlg, DWLP_USER);
  3204. switch(message)
  3205. {
  3206. case WM_INITDIALOG:
  3207. SetWindowLongPtr(hDlg,DWLP_USER,lParam);
  3208. pps = (PROPSHEETPAGE *) lParam;
  3209. lpPAI->ulFlags |= DETAILS_Initializing;
  3210. ChangeLocaleBasedTabOrder(hDlg, contactBusiness);
  3211. SetDetailsUI(hDlg, lpPAI, lpPAI->ulOperationType,propBusiness);
  3212. lpPAI->ulFlags &= ~DETAILS_Initializing;
  3213. // (*lpbSomethingChanged) = FALSE;
  3214. return TRUE;
  3215. case WM_HELP:
  3216. WABWinHelp(((LPHELPINFO)lParam)->hItemHandle,
  3217. g_szWABHelpFileName,
  3218. HELP_WM_HELP,
  3219. (DWORD_PTR)(LPSTR) rgDetlsHelpIDs );
  3220. break;
  3221. case WM_CONTEXTMENU:
  3222. WABWinHelp((HWND) wParam,
  3223. g_szWABHelpFileName,
  3224. HELP_CONTEXTMENU,
  3225. (DWORD_PTR)(LPVOID) rgDetlsHelpIDs );
  3226. break;
  3227. case WM_COMMAND:
  3228. switch(GET_WM_COMMAND_CMD(wParam,lParam)) //check the notification code
  3229. {
  3230. case EN_CHANGE: //some edit box changed - dont care which
  3231. if(lpPAI->ulFlags & DETAILS_Initializing)
  3232. break;
  3233. if (lpbSomethingChanged)
  3234. (*lpbSomethingChanged) = TRUE;
  3235. break;
  3236. }
  3237. switch(GET_WM_COMMAND_ID(wParam, lParam))
  3238. {
  3239. case IDC_DETAILS_BUSINESS_CHECK_DEFAULTADDRESS:
  3240. if (lpbSomethingChanged)
  3241. (*lpbSomethingChanged) = TRUE;
  3242. lpPAI->ulFlags |= DETAILS_DefBusChanged;
  3243. break;
  3244. case IDCANCEL:
  3245. // This is a windows bug that prevents ESC canceling prop sheets
  3246. // which have MultiLine Edit boxes KB: Q130765
  3247. SendMessage(GetParent(hDlg),message,wParam,lParam);
  3248. break;
  3249. case IDC_DETAILS_BUSINESS_BUTTON_MAP:
  3250. bUpdatePropArray(hDlg, lpPAI, propBusiness); // update the props from the fields onto the prop-object
  3251. ShowExpediaMAP(hDlg, lpPAI->lpPropObj, FALSE);
  3252. break;
  3253. case IDC_DETAILS_BUSINESS_BUTTON_URL:
  3254. ShowURL(hDlg, IDC_DETAILS_BUSINESS_EDIT_URL,NULL);
  3255. break;
  3256. case IDC_DETAILS_BUSINESS_EDIT_COMPANY:
  3257. if(lpPAI->ulFlags & DETAILS_DNisCompanyName)
  3258. {
  3259. TCHAR szBuf[MAX_UI_STR];
  3260. szBuf[0]='\0';
  3261. GetDlgItemText(hDlg, IDC_DETAILS_BUSINESS_EDIT_COMPANY, szBuf, CharSizeOf(szBuf));
  3262. SetWindowPropertiesTitle(GetParent(hDlg), szBuf);
  3263. lpPAI->ulFlags |= DETAILS_ProgChange;
  3264. SetWindowText(lpPAI->hWndDisplayNameField, szBuf);
  3265. lpPAI->ulFlags &= ~DETAILS_ProgChange;
  3266. }
  3267. break;
  3268. }
  3269. break;
  3270. case WM_NOTIFY:
  3271. switch(((NMHDR FAR *)lParam)->code)
  3272. {
  3273. case PSN_SETACTIVE: //initialize
  3274. FillHomeBusinessNotesDetailsUI(hDlg, lpPAI, propBusiness, lpbSomethingChanged);
  3275. break;
  3276. case PSN_KILLACTIVE: //Losing activation to another page
  3277. bUpdatePropArray(hDlg, lpPAI, propBusiness);
  3278. lpPAI->ulFlags &= ~DETAILS_DefBusChanged;
  3279. break;
  3280. case PSN_APPLY: //ok
  3281. //bUpdatePropArray(hDlg, lpPAI, propBusiness);
  3282. if (lpPAI->nRetVal == DETAILS_RESET)
  3283. lpPAI->nRetVal = DETAILS_OK;
  3284. break;
  3285. case PSN_RESET: //cancel
  3286. if (lpPAI->nRetVal == DETAILS_RESET)
  3287. lpPAI->nRetVal = DETAILS_CANCEL;
  3288. break;
  3289. }
  3290. return TRUE;
  3291. }
  3292. return bRet;
  3293. }
  3294. /*//$$***********************************************************************
  3295. * FUNCTION: fnNotesProc
  3296. *
  3297. * PURPOSE: Callback function for handling the NOTES property sheet ...
  3298. *
  3299. ****************************************************************************/
  3300. INT_PTR CALLBACK fnNotesProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)
  3301. {
  3302. PROPSHEETPAGE * pps;
  3303. BOOL bRet = FALSE;
  3304. pps = (PROPSHEETPAGE *) GetWindowLongPtr(hDlg, DWLP_USER);
  3305. switch(message)
  3306. {
  3307. case WM_INITDIALOG:
  3308. SetWindowLongPtr(hDlg,DWLP_USER,lParam);
  3309. pps = (PROPSHEETPAGE *) lParam;
  3310. lpPAI->ulFlags |= DETAILS_Initializing;
  3311. SetDetailsUI(hDlg, lpPAI, lpPAI->ulOperationType,propNotes);
  3312. lpPAI->ulFlags &= ~DETAILS_Initializing;
  3313. // (*lpbSomethingChanged) = FALSE;
  3314. return TRUE;
  3315. case WM_HELP:
  3316. WABWinHelp(((LPHELPINFO)lParam)->hItemHandle,
  3317. g_szWABHelpFileName,
  3318. HELP_WM_HELP,
  3319. (DWORD_PTR)(LPSTR) rgDetlsHelpIDs );
  3320. break;
  3321. case WM_CONTEXTMENU:
  3322. WABWinHelp((HWND) wParam,
  3323. g_szWABHelpFileName,
  3324. HELP_CONTEXTMENU,
  3325. (DWORD_PTR)(LPVOID) rgDetlsHelpIDs );
  3326. break;
  3327. case WM_COMMAND:
  3328. switch(GET_WM_COMMAND_CMD(wParam,lParam)) //check the notification code
  3329. {
  3330. case EN_CHANGE: //some edit box changed - dont care which
  3331. if(lpPAI->ulFlags & DETAILS_Initializing)
  3332. break;
  3333. if (lpbSomethingChanged)
  3334. (*lpbSomethingChanged) = TRUE;
  3335. break;
  3336. }
  3337. switch(GET_WM_COMMAND_ID(wParam, lParam))
  3338. {
  3339. case IDCANCEL:
  3340. // This is a windows bug that prevents ESC canceling prop sheets
  3341. // which have MultiLine Edit boxes KB: Q130765
  3342. SendMessage(GetParent(hDlg),message,wParam,lParam);
  3343. break;
  3344. }
  3345. break;
  3346. case WM_NOTIFY:
  3347. switch(((NMHDR FAR *)lParam)->code)
  3348. {
  3349. case PSN_SETACTIVE: //initialize
  3350. FillHomeBusinessNotesDetailsUI(hDlg, lpPAI, propNotes, lpbSomethingChanged);
  3351. break;
  3352. case PSN_KILLACTIVE: //Losing activation to another page
  3353. bUpdatePropArray(hDlg, lpPAI, propNotes);
  3354. break;
  3355. case PSN_APPLY: //ok
  3356. //bUpdatePropArray(hDlg, lpPAI, propNotes);
  3357. if (lpPAI->nRetVal == DETAILS_RESET)
  3358. lpPAI->nRetVal = DETAILS_OK;
  3359. break;
  3360. case PSN_RESET: //cancel
  3361. if (lpPAI->nRetVal == DETAILS_RESET)
  3362. lpPAI->nRetVal = DETAILS_CANCEL;
  3363. break;
  3364. }
  3365. return TRUE;
  3366. }
  3367. return bRet;
  3368. }
  3369. /*//$$***********************************************************************
  3370. * FUNCTION: fnCertProc
  3371. *
  3372. * PURPOSE: Callback function for handling the Certificates property sheet ...
  3373. *
  3374. ****************************************************************************/
  3375. INT_PTR CALLBACK fnCertProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)
  3376. {
  3377. PROPSHEETPAGE * pps;
  3378. BOOL bRet = FALSE;
  3379. pps = (PROPSHEETPAGE *) GetWindowLongPtr(hDlg, DWLP_USER);
  3380. switch(message)
  3381. {
  3382. case WM_INITDIALOG:
  3383. SetWindowLongPtr(hDlg,DWLP_USER,lParam);
  3384. pps = (PROPSHEETPAGE *) lParam;
  3385. lpPAI->ulFlags |= DETAILS_Initializing;
  3386. SetDetailsUI(hDlg, lpPAI, lpPAI->ulOperationType,propCert);
  3387. lpPAI->ulFlags &= ~DETAILS_Initializing;
  3388. return TRUE;
  3389. case WM_DESTROY:
  3390. bRet = TRUE;
  3391. break;
  3392. case WM_HELP:
  3393. WABWinHelp(((LPHELPINFO)lParam)->hItemHandle,
  3394. g_szWABHelpFileName,
  3395. HELP_WM_HELP,
  3396. (DWORD_PTR)(LPSTR) rgDetlsHelpIDs );
  3397. break;
  3398. case WM_CONTEXTMENU:
  3399. WABWinHelp((HWND) wParam,
  3400. g_szWABHelpFileName,
  3401. HELP_CONTEXTMENU,
  3402. (DWORD_PTR)(LPVOID) rgDetlsHelpIDs );
  3403. break;
  3404. case WM_COMMAND:
  3405. switch(GET_WM_COMMAND_CMD(wParam, lParam))
  3406. {
  3407. case CBN_SELCHANGE:
  3408. UpdateCertListView(hDlg, lpPAI);
  3409. break;
  3410. }
  3411. switch(LOWORD(wParam))
  3412. {
  3413. case IDCANCEL:
  3414. // This is a windows bug that prevents ESC canceling prop sheets
  3415. // which have MultiLine Edit boxes KB: Q130765
  3416. SendMessage(GetParent(hDlg),message,wParam,lParam);
  3417. break;
  3418. case IDC_DETAILS_CERT_BUTTON_PROPERTIES:
  3419. {
  3420. ShowCertProps(hDlg, GetDlgItem(hDlg, IDC_DETAILS_CERT_LIST), NULL);
  3421. }
  3422. break;
  3423. case IDC_DETAILS_CERT_BUTTON_SETDEFAULT:
  3424. {
  3425. HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_CERT_LIST);
  3426. if(ListView_GetSelectedCount(hWndLV)==1)
  3427. {
  3428. SetLVDefaultCert( hWndLV, ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED));
  3429. if (lpbSomethingChanged)
  3430. (*lpbSomethingChanged) = TRUE;
  3431. }
  3432. else if(ListView_GetSelectedCount(hWndLV) <= 0)
  3433. {
  3434. ShowMessageBox(hDlg, IDS_ADDRBK_MESSAGE_NO_ITEM, MB_ICONEXCLAMATION | MB_OK);
  3435. }
  3436. }
  3437. break;
  3438. case IDC_DETAILS_CERT_BUTTON_REMOVE:
  3439. {
  3440. HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_CERT_LIST);
  3441. if(ListView_GetSelectedCount(hWndLV)>=1)
  3442. {
  3443. BOOL bSetNewDefault = FALSE;
  3444. int iItemIndex = ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED);
  3445. while(iItemIndex != -1)
  3446. {
  3447. BOOL bRet = FALSE;
  3448. // KillTrustInSleazyFashion(hWndLV, iItemIndex);
  3449. bRet = DeleteLVCertItem(hWndLV,iItemIndex, lpPAI);
  3450. if (!bSetNewDefault)
  3451. bSetNewDefault = bRet;
  3452. iItemIndex = ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED);
  3453. }
  3454. if (bSetNewDefault && (ListView_GetItemCount(hWndLV) > 0))
  3455. SetLVDefaultCert(hWndLV, 0);
  3456. if (lpbSomethingChanged)
  3457. (*lpbSomethingChanged) = TRUE;
  3458. if (ListView_GetItemCount(hWndLV) <= 0)
  3459. {
  3460. SetFocus(GetDlgItem(hDlg,IDC_DETAILS_CERT_BUTTON_IMPORT));
  3461. EnableWindow(hWndLV,FALSE);
  3462. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_BUTTON_PROPERTIES),FALSE);
  3463. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_BUTTON_REMOVE),FALSE);
  3464. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_BUTTON_SETDEFAULT),FALSE);
  3465. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_BUTTON_EXPORT),FALSE);
  3466. return FALSE;
  3467. }
  3468. else
  3469. {
  3470. //make sure something is selected
  3471. if(ListView_GetSelectedCount(hWndLV) <= 0)
  3472. LVSelectItem(hWndLV,0);
  3473. }
  3474. }
  3475. else
  3476. {
  3477. ShowMessageBox(hDlg, IDS_ADDRBK_MESSAGE_NO_ITEM, MB_ICONEXCLAMATION | MB_OK);
  3478. }
  3479. }
  3480. break;
  3481. case IDC_DETAILS_CERT_BUTTON_IMPORT:
  3482. if(ImportCert(hDlg, lpPAI))
  3483. {
  3484. if (lpbSomethingChanged)
  3485. (*lpbSomethingChanged) = TRUE;
  3486. }
  3487. break;
  3488. case IDC_DETAILS_CERT_BUTTON_EXPORT:
  3489. ExportCert(hDlg);
  3490. break;
  3491. }
  3492. break;
  3493. case WM_NOTIFY:
  3494. switch(((NMHDR FAR *)lParam)->code)
  3495. {
  3496. case PSN_SETACTIVE: //initialize
  3497. FillCertTridentConfDetailsUI(hDlg, lpPAI, propCert, lpbSomethingChanged);
  3498. //FillCertComboWithEmailAddresses(hDlg, lpPAI, NULL);
  3499. //UpdateCertListView(hDlg, lpPAI);
  3500. break;
  3501. case PSN_KILLACTIVE: //Losing activation to another page
  3502. bUpdatePropArray(hDlg, lpPAI, propCert);
  3503. ListView_DeleteAllItems(GetDlgItem(hDlg, IDC_DETAILS_CERT_LIST));
  3504. //lpPAI->lpCItem = NULL;
  3505. break;
  3506. case PSN_APPLY: //ok
  3507. //bUpdatePropArray(hDlg, lpPAI, propCert);
  3508. //FreeLVParams(GetDlgItem(hDlg, IDC_DETAILS_CERT_LIST),LV_CERT);
  3509. FreeCertList(&(lpPAI->lpCItem));
  3510. if (lpPAI->nRetVal == DETAILS_RESET)
  3511. lpPAI->nRetVal = DETAILS_OK;
  3512. break;
  3513. case PSN_RESET: //cancel
  3514. FreeCertList(&(lpPAI->lpCItem));
  3515. if (lpPAI->nRetVal == DETAILS_RESET)
  3516. lpPAI->nRetVal = DETAILS_CANCEL;
  3517. break;
  3518. case NM_DBLCLK:
  3519. switch(wParam)
  3520. {
  3521. case IDC_DETAILS_CERT_LIST:
  3522. {
  3523. NM_LISTVIEW * pNm = (NM_LISTVIEW *)lParam;
  3524. if (ListView_GetSelectedCount(pNm->hdr.hwndFrom) == 1)
  3525. {
  3526. int iItemIndex = ListView_GetNextItem(pNm->hdr.hwndFrom,-1,LVNI_SELECTED);
  3527. SetLVDefaultCert(pNm->hdr.hwndFrom, iItemIndex);
  3528. if (lpbSomethingChanged)
  3529. (*lpbSomethingChanged) = TRUE;
  3530. }
  3531. }
  3532. break;
  3533. }
  3534. break;
  3535. case NM_CUSTOMDRAW:
  3536. switch(wParam)
  3537. {
  3538. case IDC_DETAILS_CERT_LIST:
  3539. {
  3540. NMCUSTOMDRAW *pnmcd=(NMCUSTOMDRAW*)lParam;
  3541. NM_LISTVIEW * pNm = (NM_LISTVIEW *)lParam;
  3542. if(pnmcd->dwDrawStage==CDDS_PREPAINT)
  3543. {
  3544. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, CDRF_NOTIFYITEMDRAW | CDRF_DODEFAULT);
  3545. return TRUE;
  3546. }
  3547. else if(pnmcd->dwDrawStage==CDDS_ITEMPREPAINT)
  3548. {
  3549. LPCERT_ITEM lpItem = (LPCERT_ITEM) pnmcd->lItemlParam;
  3550. if (lpItem)
  3551. {
  3552. if(lpItem->lpCDI->bIsDefault)
  3553. {
  3554. SelectObject(((NMLVCUSTOMDRAW*)lParam)->nmcd.hdc, GetFont(fntsSysIconBold));
  3555. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, CDRF_NEWFONT);
  3556. return TRUE;
  3557. }
  3558. }
  3559. }
  3560. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, CDRF_DODEFAULT);
  3561. return TRUE;
  3562. }
  3563. break;
  3564. }
  3565. break;
  3566. } //WM_NOTIFY
  3567. return TRUE;
  3568. }
  3569. return bRet;
  3570. }
  3571. /*//$$***********************************************************************
  3572. *
  3573. * FUNCTION: HrInitDetlsListView
  3574. *
  3575. * PURPOSE: Initializes the Email Address List View
  3576. *
  3577. ****************************************************************************/
  3578. HRESULT HrInitDetlsListView(HWND hWndLV, DWORD dwStyle, int nLVType)
  3579. {
  3580. HRESULT hr=hrSuccess;
  3581. LV_COLUMN lvC; // list view column structure
  3582. DWORD dwLVStyle;
  3583. RECT rc;
  3584. HIMAGELIST hSmall = NULL;
  3585. ULONG nCols=0;
  3586. ULONG index=0;
  3587. int nBmp=0;
  3588. TCHAR sz[MAX_PATH];
  3589. if (!hWndLV)
  3590. {
  3591. hr = MAPI_E_INVALID_PARAMETER;
  3592. goto out;
  3593. }
  3594. if(nLVType == LV_EMAIL)
  3595. nBmp = IDB_DEFAULT_EMAIL;
  3596. else if(nLVType == LV_CERT)
  3597. nBmp = IDB_CERT_VALID_INVALID;
  3598. else if(nLVType == LV_KIDS)
  3599. nBmp = IDB_DEFAULT_EMAIL;
  3600. else
  3601. nBmp = 0;
  3602. ListView_SetExtendedListViewStyle(hWndLV, LVS_EX_FULLROWSELECT);
  3603. dwLVStyle = GetWindowLong(hWndLV,GWL_STYLE);
  3604. if(( dwLVStyle & LVS_TYPEMASK) != dwStyle)
  3605. SetWindowLong(hWndLV,GWL_STYLE,(dwLVStyle & ~LVS_TYPEMASK) | dwStyle);
  3606. if(nBmp)
  3607. {
  3608. hSmall = gpfnImageList_LoadImage( hinstMapiX,
  3609. MAKEINTRESOURCE(nBmp),
  3610. //(LPCTSTR) ((DWORD) ((WORD) (nBmp))),
  3611. S_BITMAP_WIDTH,
  3612. 0,
  3613. RGB_TRANSPARENT,
  3614. IMAGE_BITMAP,
  3615. 0);
  3616. // Associate the image lists with the list view control.
  3617. ListView_SetImageList (hWndLV, hSmall, LVSIL_SMALL);
  3618. }
  3619. GetWindowRect(hWndLV,&rc);
  3620. lvC.mask = LVCF_FMT | LVCF_WIDTH;
  3621. lvC.fmt = LVCFMT_LEFT; // left-align column
  3622. lvC.cx = rc.right - rc.left - 20; //TBD
  3623. lvC.pszText = NULL;
  3624. if(nLVType == LV_SERVER)
  3625. {
  3626. lvC.mask |= LVCF_TEXT;
  3627. lvC.cx /= 2;
  3628. LoadString(hinstMapiX, idsConfServer, sz, CharSizeOf(sz));
  3629. lvC.pszText = sz;
  3630. }
  3631. lvC.iSubItem = 0;
  3632. if (ListView_InsertColumn (hWndLV, 0, &lvC) == -1)
  3633. {
  3634. DebugPrintError(( TEXT("ListView_InsertColumn Failed\n")));
  3635. hr = E_FAIL;
  3636. goto out;
  3637. }
  3638. // if this is the conferencing server item, add another prop
  3639. if(nLVType == LV_SERVER)
  3640. {
  3641. LoadString(hinstMapiX, idsConfEmail, sz, CharSizeOf(sz));
  3642. lvC.pszText = sz;
  3643. if (ListView_InsertColumn (hWndLV, 1, &lvC) == -1)
  3644. {
  3645. DebugPrintError(( TEXT("ListView_InsertColumn Failed\n")));
  3646. hr = E_FAIL;
  3647. goto out;
  3648. }
  3649. }
  3650. out:
  3651. return hr;
  3652. }
  3653. /*//$$***********************************************************************
  3654. *
  3655. * FUNCTION: FreeLVParams
  3656. *
  3657. * PURPOSE: Frees the memory allocated to the ListView item lParams
  3658. *
  3659. ****************************************************************************/
  3660. void FreeLVParams(HWND hWndLV, int LVType)
  3661. {
  3662. int iItemIndex = ListView_GetItemCount(hWndLV);
  3663. while(iItemIndex > 0)
  3664. {
  3665. if(LVType == LV_EMAIL)
  3666. DeleteLVEmailItem(hWndLV, iItemIndex-1);
  3667. else if(LVType == LV_CERT)
  3668. DeleteLVCertItem(hWndLV, iItemIndex-1, NULL);
  3669. iItemIndex = ListView_GetItemCount(hWndLV);
  3670. }
  3671. return;
  3672. }
  3673. //$$
  3674. BOOL DeleteLVEmailItem(HWND hWndLV, int iItemIndex)
  3675. {
  3676. LV_ITEM lvi;
  3677. LPEMAIL_ITEM lpEItem;
  3678. BOOL bDeletedDefault = FALSE;
  3679. lvi.mask = LVIF_PARAM;
  3680. lvi.iSubItem = 0;
  3681. lvi.iItem = iItemIndex;
  3682. ListView_GetItem(hWndLV, &lvi);
  3683. lpEItem = (LPEMAIL_ITEM) lvi.lParam;
  3684. if (lpEItem->bIsDefault)
  3685. bDeletedDefault = TRUE;
  3686. LocalFreeAndNull(&lpEItem);
  3687. ListView_DeleteItem(hWndLV, lvi.iItem);
  3688. return bDeletedDefault;
  3689. }
  3690. ///$$/////////////////////////////////////////////////////////////////////////
  3691. //
  3692. // AddLVEmailItem - Adds an email address to the personal tab list view
  3693. //
  3694. // lpszAddrType can be NULL in which case a default one of type SMTP will be used
  3695. //
  3696. //////////////////////////////////////////////////////////////////////////////
  3697. void AddLVEmailItem(HWND hWndLV,
  3698. LPTSTR lpszEmailAddress,
  3699. LPTSTR lpszAddrType)
  3700. {
  3701. LV_ITEM lvi = {0};
  3702. TCHAR szBuf[MAX_DISPLAY_NAME_LENGTH];
  3703. ULONG nLen;
  3704. LPEMAIL_ITEM lpEItem = NULL;
  3705. if (!lpszEmailAddress)
  3706. goto out;
  3707. lpEItem = LocalAlloc(LMEM_ZEROINIT, sizeof(EMAIL_ITEM));
  3708. if (!lpEItem)
  3709. {
  3710. DebugPrintError(( TEXT("AddLVEmailItem: Out of Memory\n")));
  3711. goto out;
  3712. }
  3713. lpEItem->bIsDefault = FALSE;
  3714. nLen = lstrlen(lpszEmailAddress) + 1;
  3715. if (nLen > EDIT_LEN)
  3716. {
  3717. ULONG iLen = TruncatePos(lpszEmailAddress, EDIT_LEN - 1);
  3718. CopyMemory(lpEItem->szEmailAddress,lpszEmailAddress,sizeof(TCHAR)*iLen);
  3719. lpEItem->szEmailAddress[iLen] = '\0';
  3720. }
  3721. else
  3722. {
  3723. StrCpyN(lpEItem->szEmailAddress,lpszEmailAddress, ARRAYSIZE(lpEItem->szEmailAddress));
  3724. }
  3725. StrCpyN(lpEItem->szDisplayText,lpEItem->szEmailAddress, ARRAYSIZE(lpEItem->szDisplayText));
  3726. if(!lpszAddrType)
  3727. {
  3728. StrCpyN(szBuf, szSMTP, ARRAYSIZE(szBuf));
  3729. lpszAddrType = szBuf;
  3730. }
  3731. nLen = lstrlen(lpszAddrType) + 1;
  3732. if (nLen > EDIT_LEN)
  3733. {
  3734. ULONG iLen = TruncatePos(lpszAddrType, EDIT_LEN - 1);
  3735. CopyMemory(lpEItem->szAddrType,lpszAddrType,sizeof(TCHAR)*iLen);
  3736. lpEItem->szAddrType[iLen] = '\0';
  3737. }
  3738. else
  3739. {
  3740. StrCpyN(lpEItem->szAddrType,lpszAddrType,ARRAYSIZE(lpEItem->szAddrType));
  3741. }
  3742. lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
  3743. lvi.pszText = lpEItem->szDisplayText;
  3744. lvi.cchTextMax = MAX_UI_STR;
  3745. lvi.iItem = ListView_GetItemCount(hWndLV);
  3746. lvi.iSubItem = 0;
  3747. lvi.iImage = imgNotDefaultEmail;
  3748. lvi.lParam = (LPARAM) lpEItem;
  3749. ListView_InsertItem(hWndLV, &lvi);
  3750. if (ListView_GetItemCount(hWndLV) == 1)
  3751. {
  3752. // only one item in here .. we will take the liberty of making it the
  3753. // default one ...
  3754. SetLVDefaultEmail(hWndLV, 0);
  3755. }
  3756. out:
  3757. return;
  3758. }
  3759. //$$/////////////////////////////////////////////////////////////////////////
  3760. //
  3761. // SetLVDefaultEmail - Makes an email entry the default one ...
  3762. //
  3763. //////////////////////////////////////////////////////////////////////////////
  3764. void SetLVDefaultEmail( HWND hWndLV,
  3765. int iItemIndex)
  3766. {
  3767. int nCount = ListView_GetItemCount(hWndLV);
  3768. int i;
  3769. LPEMAIL_ITEM lpEItem = NULL;
  3770. TCHAR szBuf[MAX_DISPLAY_NAME_LENGTH];
  3771. if (iItemIndex >= nCount)
  3772. goto out;
  3773. for(i=0; i<nCount; i++)
  3774. {
  3775. // At amy given point of time one and only one entry in the
  3776. // list view is the default one ...
  3777. // So we want to reset the previous default and set the new one
  3778. //
  3779. LV_ITEM lvi = {0};
  3780. lvi.iItem = i;
  3781. lvi.mask = LVIF_PARAM;
  3782. if(!ListView_GetItem(hWndLV, &lvi))
  3783. goto out;
  3784. lpEItem = (LPEMAIL_ITEM) lvi.lParam;
  3785. if (lpEItem->bIsDefault)
  3786. {
  3787. // This was the default entry - if its the same one we are setting
  3788. // do nothing ...
  3789. if (i == iItemIndex)
  3790. goto out;
  3791. // else reset this entry ...
  3792. lpEItem->bIsDefault = FALSE;
  3793. lvi.iImage = imgNotDefaultEmail;
  3794. lvi.pszText = lpEItem->szEmailAddress;
  3795. lvi.mask = LVIF_PARAM | LVIF_IMAGE | LVIF_TEXT;
  3796. lvi.iItem = i;
  3797. lvi.iSubItem = 0;
  3798. ListView_SetItem(hWndLV, &lvi);
  3799. }
  3800. if (iItemIndex == i)
  3801. {
  3802. //This is the item we want to modify ..
  3803. lpEItem->bIsDefault = TRUE;
  3804. lvi.iImage = imgDefaultEmail;
  3805. StrCpyN(lpEItem->szDisplayText,lpEItem->szEmailAddress,ARRAYSIZE(lpEItem->szDisplayText));
  3806. LoadString(hinstMapiX, idsDefaultEmail, szBuf, CharSizeOf(szBuf));
  3807. StrCatBuff(lpEItem->szDisplayText, TEXT(" "), ARRAYSIZE(lpEItem->szDisplayText));
  3808. StrCatBuff(lpEItem->szDisplayText, szBuf, ARRAYSIZE(lpEItem->szDisplayText));
  3809. lvi.pszText = lpEItem->szDisplayText;
  3810. lvi.mask = LVIF_PARAM | LVIF_IMAGE | LVIF_TEXT;
  3811. lvi.iItem = i;
  3812. lvi.iSubItem = 0;
  3813. ListView_SetItem(hWndLV, &lvi);
  3814. }
  3815. }
  3816. LVSelectItem(hWndLV, iItemIndex);
  3817. out:
  3818. return;
  3819. }
  3820. #ifdef WIN16 // Enable DDE to communicate IE.
  3821. #include <ddeml.h>
  3822. static char cszIEAppName[] = "IEXPLORE";
  3823. static char cszIEDDEOpenURL[] = "WWW_OpenURL";
  3824. static char cszIEDDEActivate[] = "WWW_Activate";
  3825. static char cszIEIniFile[] = "iexplore.ini";
  3826. static char cszIEIniSectMain[] = "Main";
  3827. static char cszIEIniKeyStart[] = "Home Page";
  3828. static char cszIEIniKeySearch[] = "Search Page";
  3829. static char cszIEReadNews[] = "news:*";
  3830. static char cszIEBinName[] = "iexplore.exe";
  3831. static char cszIERegHtm[] = ".htm";
  3832. static char cszRegShellOpen[] = "shell\\open\\command";
  3833. static HDDEDATA CALLBACK DdeCallback( UINT uType, UINT uFmt, HCONV hConv,
  3834. HSZ hSz1, HSZ hSz2, HDDEDATA hData, DWORD dwData1, DWORD dwData2 )
  3835. {
  3836. return( (HDDEDATA)NULL );
  3837. }
  3838. #define TIME_WAIT_DDE 10000 // waiting for 10 sec, and if doesn't return,
  3839. // assumes News is configured correctly.
  3840. void RunBrowser(LPCSTR cszURL, BOOL bCheckRet )
  3841. {
  3842. if ( GetModuleHandle( cszIEBinName ) == NULL )
  3843. {
  3844. //
  3845. // FIND & RUN IEXPLORE
  3846. //
  3847. // Try to find the browser in the Mail's directory
  3848. char szPath[_MAX_PATH*2+1];
  3849. char *pPtr, *pSlash = NULL;;
  3850. HKEY hKey;
  3851. LONG cbPath;
  3852. char szRegPath[_MAX_PATH];
  3853. GetModuleFileName( hinstMapiXWAB, szPath, _MAX_PATH );
  3854. for ( pPtr = szPath; *pPtr; pPtr = AnsiNext( pPtr ) )
  3855. if ( *pPtr == '\\' )
  3856. {
  3857. pSlash = pPtr;
  3858. }
  3859. if ( pSlash != NULL )
  3860. {
  3861. _fstrcpy( pSlash+1, cszIEBinName );
  3862. _fstrcat( szPath, " " );
  3863. _fstrcat( szPath, cszURL );
  3864. if ( WinExec( szPath, SW_SHOWNORMAL ) >= 32 )
  3865. {
  3866. return;
  3867. }
  3868. }
  3869. // Try to find system default browser from the registry
  3870. _fstrcpy( szRegPath, cszIERegHtm );
  3871. while ( RegOpenKey( HKEY_CLASSES_ROOT, szRegPath, &hKey ) == ERROR_SUCCESS )
  3872. {
  3873. LONG lReg;
  3874. cbPath = CharSizeOf( szPath );
  3875. lReg = RegQueryValue( hKey, cszRegShellOpen, szPath, &cbPath );
  3876. RegCloseKey( hKey );
  3877. if ( lReg == ERROR_SUCCESS )
  3878. {
  3879. char *pFmt = _fstrstr( szPath, "%1" );
  3880. if ( pFmt != NULL )
  3881. {
  3882. _fstrcpy( pFmt, cszURL );
  3883. *pFmt = '\0';
  3884. }
  3885. else
  3886. {
  3887. // Can this case happen???
  3888. _fstrcat( szPath, " " );
  3889. _fstrcat( szPath, cszURL );
  3890. }
  3891. if ( WinExec( szPath, SW_SHOWNORMAL ) >= 32 )
  3892. {
  3893. return;
  3894. }
  3895. else
  3896. break;
  3897. }
  3898. else
  3899. {
  3900. cbPath = CharSizeOf( szRegPath );
  3901. if ( RegQueryValue( HKEY_CLASSES_ROOT, szRegPath,
  3902. szRegPath, &cbPath ) != ERROR_SUCCESS )
  3903. break;
  3904. }
  3905. }
  3906. // Insert proper messagebox here
  3907. // MessageBox( IDS_NOT_FOUND_IEXPLORE );
  3908. return;
  3909. }
  3910. else
  3911. {
  3912. //
  3913. // CALL IEXPLORE DDE
  3914. //
  3915. if ((GetWinFlags() & WF_PMODE) != 0 ) // None-Protected Mode
  3916. {
  3917. DWORD idInst = 0L;
  3918. FARPROC lpDdeProc = MakeProcInstance( (FARPROC)DdeCallback, hinstMapiXWAB );
  3919. if ( DdeInitialize( &idInst, (PFNCALLBACK)lpDdeProc,
  3920. APPCMD_CLIENTONLY,
  3921. 0L ) == DMLERR_NO_ERROR )
  3922. {
  3923. HSZ hszAppName = DdeCreateStringHandle( idInst, cszIEAppName, CP_WINANSI );
  3924. char szParam[256];
  3925. HSZ hszParam;
  3926. // Activate IE
  3927. HSZ hszTopic = DdeCreateStringHandle( idInst, cszIEDDEActivate, CP_WINANSI );
  3928. HCONV hConv = DdeConnect( idInst, hszAppName, hszTopic, (PCONVCONTEXT)NULL );
  3929. DdeFreeStringHandle( idInst, hszTopic );
  3930. if ( hConv != NULL )
  3931. {
  3932. wnsprintf( szParam, ARRAYSIZE(szParam), "0x%lX,0x%lX", 0xFFFFFFFF, 0L );
  3933. hszParam = DdeCreateStringHandle( idInst, szParam, CP_WINANSI );
  3934. DdeClientTransaction( NULL, 0L, hConv, hszParam, CF_TEXT,
  3935. XTYP_REQUEST, TIMEOUT_ASYNC, NULL );
  3936. DdeFreeStringHandle( idInst, hszParam );
  3937. DdeDisconnect( hConv );
  3938. }
  3939. // Request to open URL
  3940. hszTopic = DdeCreateStringHandle( idInst, cszIEDDEOpenURL, CP_WINANSI );
  3941. hConv = DdeConnect( idInst, hszAppName, hszTopic, (PCONVCONTEXT)NULL );
  3942. DdeFreeStringHandle( idInst, hszTopic );
  3943. if ( hConv != NULL )
  3944. {
  3945. HSZ hszParam;
  3946. HDDEDATA hDDE;
  3947. wnsprintf( szParam, ARRAYSIZE(szParam), "\"%s\",,0x%lX,0x%lX,,,", cszURL, 0xFFFFFFFF, 0L );
  3948. hszParam = DdeCreateStringHandle( idInst, szParam, CP_WINANSI );
  3949. hDDE = DdeClientTransaction( NULL, 0L, hConv, hszParam,
  3950. CF_TEXT, XTYP_REQUEST, TIME_WAIT_DDE, NULL );
  3951. if ( bCheckRet && ( hDDE != NULL ) )
  3952. {
  3953. long lRet;
  3954. DdeGetData( hDDE, &lRet, sizeof( lRet ), 0 );
  3955. DdeFreeDataHandle( hDDE );
  3956. if ( lRet == -5L )
  3957. {
  3958. /*
  3959. // Insert Error message.
  3960. CString strErr, strTmp;
  3961. strErr.LoadString( IDS_DDE_NEWS_NOT_READY1 );
  3962. strTmp.LoadString( IDS_DDE_NEWS_NOT_READY2 );
  3963. strErr += strTmp;
  3964. MessageBox( strErr, NULL, MB_ICONINFORMATION | MB_OK );
  3965. */
  3966. ;
  3967. }
  3968. }
  3969. DdeFreeStringHandle( idInst, hszParam );
  3970. DdeDisconnect( hConv );
  3971. }
  3972. DdeFreeStringHandle( idInst, hszAppName );
  3973. DdeUninitialize( idInst );
  3974. }
  3975. FreeProcInstance( lpDdeProc );
  3976. }
  3977. }
  3978. }
  3979. #endif // WIN16
  3980. //$$/////////////////////////////////////////////////////////////////
  3981. //
  3982. // Launches explorer with the URL to show it ...
  3983. //
  3984. /////////////////////////////////////////////////////////////////////
  3985. void ShowURL(HWND hWnd, int id, LPTSTR lpURL)
  3986. {
  3987. TCHAR szBuf[MAX_EDIT_LEN];
  3988. LPTSTR lp = NULL;
  3989. if(!lpURL)
  3990. {
  3991. //get the text in the dialog
  3992. szBuf[0] = 0;
  3993. GetDlgItemText(hWnd, id, szBuf, CharSizeOf(szBuf));
  3994. TrimSpaces(szBuf);
  3995. //if its blank, exit
  3996. if(!lstrlen(szBuf))
  3997. return;
  3998. lpURL = szBuf;
  3999. }
  4000. // if its just the default prefix, ignore
  4001. if(lstrcmpi(szHTTP, lpURL)!=0)
  4002. {
  4003. if(!bIsHttpPrefix(lpURL))
  4004. {
  4005. ULONG cchSize=lstrlen(lpURL)+lstrlen(szHTTP)+1;
  4006. //append the http:// prefix before shellexecing
  4007. lp = LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*cchSize);
  4008. if (lp)
  4009. {
  4010. StrCpyN(lp, szHTTP, cchSize);
  4011. StrCatBuff(lp, szBuf, cchSize);
  4012. }
  4013. }
  4014. IF_WIN32(ShellExecute(hWnd, TEXT("open"), (lp ? lp : lpURL), NULL, NULL, SW_SHOWNORMAL);)
  4015. IF_WIN16(RunBrowser((lp ? lp : lpURL), FALSE);) // Need DDE routine to invoke IEXPLORE.
  4016. if(lp)
  4017. LocalFree(lp);
  4018. }
  4019. }
  4020. //$$/////////////////////////////////////////////////////////////////
  4021. //
  4022. // Sets the TEXT("http://") prefix in the URL edit fields if user doesnt
  4023. // anything in there ....
  4024. //
  4025. ///////////////////////////////////////////////////////////////////
  4026. void SetHTTPPrefix(HWND hDlg, int id)
  4027. {
  4028. TCHAR szBuf[MAX_EDIT_LEN];
  4029. // Check to see if anything is filled in ...
  4030. GetDlgItemText(hDlg, id, szBuf, CharSizeOf(szBuf));
  4031. TrimSpaces(szBuf);
  4032. if (lstrlen(szBuf))
  4033. return;
  4034. StrCpyN(szBuf,szHTTP,ARRAYSIZE(szBuf));
  4035. SetDlgItemText(hDlg, id, szBuf);
  4036. return;
  4037. }
  4038. //$$/////////////////////////////////////////////////////////////////////////
  4039. //
  4040. // AddNewEmailEntry - Adds text from Email edit box to the list box
  4041. //
  4042. // bShowCancelButton - lets us specify whether to show a dialog with a cancel
  4043. // button
  4044. //
  4045. // returns IDYES, IDNO or IDCANCEL
  4046. //
  4047. //////////////////////////////////////////////////////////////////////////////
  4048. int AddNewEmailEntry(HWND hDlg, BOOL bShowCancelButton)
  4049. {
  4050. int nRet = IDYES;
  4051. TCHAR szBuf[EDIT_LEN];
  4052. LPTSTR lpszEmailAddress = szBuf;
  4053. GetDlgItemText( hDlg,
  4054. IDC_DETAILS_PERSONAL_EDIT_ADDEMAIL,
  4055. szBuf,
  4056. CharSizeOf(szBuf));
  4057. TrimSpaces(szBuf);
  4058. if(!lstrlen(szBuf))
  4059. goto out;
  4060. if(!IsInternetAddress(szBuf, &lpszEmailAddress))
  4061. {
  4062. // Check if this is invalid because of high bytes or something else
  4063. // (Need to warn user about entering DBCS email addresses)
  4064. LPTSTR lpsz = szBuf;
  4065. BOOL bHighBits = FALSE;
  4066. while (*lpsz)
  4067. {
  4068. // Internet addresses only allow pure ASCII. No high bits!
  4069. if (*lpsz >= 0x0080)
  4070. {
  4071. bHighBits = TRUE;
  4072. break;
  4073. }
  4074. lpsz++;
  4075. }
  4076. if(bHighBits)
  4077. {
  4078. ShowMessageBox(GetParent(hDlg), idsInvalidDBCSInternetAddress, MB_ICONEXCLAMATION | MB_OK);
  4079. SetFocus(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_EDIT_ADDEMAIL));
  4080. goto out;
  4081. }
  4082. else
  4083. {
  4084. // some other casue for error
  4085. int nFlag = (bShowCancelButton ? MB_YESNOCANCEL : MB_YESNO);
  4086. nRet = ShowMessageBox(GetParent(hDlg), idsInvalidInternetAddress, MB_ICONEXCLAMATION | nFlag);
  4087. if(IDYES != nRet)
  4088. {
  4089. SetFocus(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_EDIT_ADDEMAIL));
  4090. goto out;
  4091. }
  4092. }
  4093. }
  4094. // Add the text to the list box
  4095. AddLVEmailItem( GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_LIST),
  4096. lpszEmailAddress,
  4097. NULL);
  4098. // If there is no display name and there was one specified in the entered address,
  4099. // add a display name.
  4100. if (szBuf != lpszEmailAddress) { // then there was a DisplayName specified in the entered email address
  4101. TCHAR szBuf2[16]; // big enough to rule out likely leading spaces. Doesn't have to fit entire DN.
  4102. szBuf2[0] = '\0';
  4103. GetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME, szBuf2, CharSizeOf(szBuf2));
  4104. TrimSpaces(szBuf2);
  4105. if (lstrlen(szBuf2) == 0) {
  4106. // No display name, set one
  4107. SetComboDNText(hDlg, NULL, FALSE, szBuf); // Set the DN
  4108. }
  4109. }
  4110. //Cleanout the edit control
  4111. SetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_EDIT_ADDEMAIL, szEmpty);
  4112. //Disable the add new button
  4113. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_ADDEMAIL),FALSE);
  4114. // enable/disable other buttons
  4115. if(ListView_GetItemCount(GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_LIST)) > 0)
  4116. {
  4117. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_REMOVE),TRUE);
  4118. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_SETDEFAULT),TRUE);
  4119. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_EDIT),TRUE);
  4120. }
  4121. // Set the focus to the email edit field
  4122. SetFocus(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_EDIT_ADDEMAIL));
  4123. // Set the default id to the OK button
  4124. SendMessage(GetParent(hDlg), DM_SETDEFID, IDOK, 0);
  4125. nRet = IDYES;
  4126. out:
  4127. return nRet;
  4128. }
  4129. //$$///////////////////////////////////////////////////////////////
  4130. //
  4131. // SetDetailsWindowTitle - creates a display name and sets it in
  4132. // the title
  4133. //
  4134. ///////////////////////////////////////////////////////////////////
  4135. void SetDetailsWindowTitle(HWND hDlg, BOOL bModifyDisplayNameField)
  4136. {
  4137. TCHAR szFirst[MAX_UI_STR];
  4138. TCHAR szLast[MAX_UI_STR];
  4139. TCHAR szMiddle[MAX_UI_STR];
  4140. TCHAR * szBuf = NULL;//szBuf[MAX_BUF_STR];
  4141. if(!(szBuf = LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*MAX_BUF_STR)))
  4142. return;
  4143. szFirst[0] = szMiddle[0] = szLast[0] = '\0';
  4144. GetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_EDIT_FIRSTNAME, szFirst, CharSizeOf(szFirst));
  4145. GetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_EDIT_LASTNAME, szLast, CharSizeOf(szLast));
  4146. GetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_EDIT_MIDDLENAME, szMiddle, CharSizeOf(szMiddle));
  4147. szBuf[0]='\0';
  4148. {
  4149. LPTSTR lpszTmp = szBuf;
  4150. SetLocalizedDisplayName(szFirst,
  4151. szMiddle,
  4152. szLast,
  4153. NULL,
  4154. NULL,
  4155. (LPTSTR *) &lpszTmp, //&szBuf,
  4156. MAX_BUF_STR,
  4157. bDNisByLN,
  4158. NULL,
  4159. NULL);
  4160. }
  4161. SetWindowPropertiesTitle(GetParent(hDlg), szBuf);
  4162. if (bModifyDisplayNameField)
  4163. {
  4164. SetComboDNText(hDlg, NULL, FALSE, szBuf);
  4165. //SetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_EDIT_DISPLAYNAME, szBuf);
  4166. }
  4167. LocalFreeAndNull(&szBuf);
  4168. }
  4169. //$$///////////////////////////////////////////////////////////////
  4170. //
  4171. // UpdateCertListView - fills the cert lv with certinfo, based on current
  4172. // listview selection
  4173. //
  4174. ///////////////////////////////////////////////////////////////////
  4175. void UpdateCertListView(HWND hDlg, LPPROP_ARRAY_INFO lpPai)
  4176. {
  4177. HWND hWndLV = GetDlgItem(hDlg,IDC_DETAILS_CERT_LIST);
  4178. HWND hWndCombo = GetDlgItem(hDlg,IDC_DETAILS_CERT_COMBO);
  4179. TCHAR szEmail[MAX_UI_STR];
  4180. LPCERT_ITEM lpCItem = lpPai->lpCItem;
  4181. int nSel = (int) SendMessage(hWndCombo, CB_GETCURSEL, 0, 0);
  4182. int nCount = (int) SendMessage(hWndCombo, CB_GETCOUNT, 0, 0);
  4183. int nCountCerts = 0;
  4184. BOOL * lpbAddCert = NULL;
  4185. BOOL bShowOrphanCerts = FALSE;
  4186. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_LIST),FALSE);
  4187. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_BUTTON_PROPERTIES),FALSE);
  4188. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_BUTTON_REMOVE),FALSE);
  4189. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_BUTTON_SETDEFAULT),FALSE);
  4190. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_BUTTON_EXPORT),FALSE);
  4191. *szEmail = '\0';
  4192. if(!GetWindowText(hWndCombo, szEmail, CharSizeOf(szEmail)))
  4193. goto out;
  4194. if(!nCount || !lpCItem || !lstrlen(szEmail))
  4195. goto out;
  4196. nCountCerts = 0;
  4197. while(lpCItem)
  4198. {
  4199. nCountCerts++;
  4200. lpCItem = lpCItem->lpNext;
  4201. }
  4202. if(!nCountCerts)
  4203. goto out;
  4204. // Clear the list view ....
  4205. ListView_DeleteAllItems(hWndLV);
  4206. // we will have this bool array that we can use to mark which cert to
  4207. // add and which not to add
  4208. lpbAddCert = LocalAlloc(LMEM_ZEROINIT, nCountCerts*sizeof(BOOL));
  4209. if(!lpbAddCert)
  4210. goto out;
  4211. // if the selection is in the last item in the list, then we only
  4212. // show orphan certs ..
  4213. // Orphan certs are certs without email addresses or with email addresses
  4214. // that dont match anything in the current contacts properties ...
  4215. //
  4216. if(nSel == nCount - 1)
  4217. bShowOrphanCerts = TRUE;
  4218. lpCItem = lpPai->lpCItem;
  4219. nCountCerts = 0;
  4220. if(!bShowOrphanCerts)
  4221. {
  4222. // we only need to look at the e-mail address of each cert and match it to
  4223. // the currently selected email address
  4224. while(lpCItem)
  4225. {
  4226. if( lpCItem->lpCDI && lpCItem->lpCDI->lpszEmailAddress &&
  4227. lstrlen(lpCItem->lpCDI->lpszEmailAddress ) &&
  4228. !lstrcmpi(szEmail, lpCItem->lpCDI->lpszEmailAddress) )
  4229. {
  4230. lpbAddCert[nCountCerts] = TRUE; // Add this cert
  4231. }
  4232. nCountCerts++;
  4233. lpCItem = lpCItem->lpNext;
  4234. }
  4235. }
  4236. else
  4237. {
  4238. // Scan all the certs and find the ones that dont match anything
  4239. while(lpCItem)
  4240. {
  4241. int i;
  4242. lpbAddCert[nCountCerts] = TRUE; // Add this cert
  4243. for(i=0;i<nCount-1;i++) // nCount = # e-mail addresses + 1
  4244. {
  4245. int nLen = (int)SendMessage(hWndCombo, CB_GETLBTEXTLEN, (WPARAM)i, 0);
  4246. if (nLen != CB_ERR)
  4247. {
  4248. LPTSTR pszEmail = (LPTSTR)LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*(nLen + 1));
  4249. if (pszEmail)
  4250. {
  4251. pszEmail[0] = 0;
  4252. SendMessage(hWndCombo, CB_GETLBTEXT, (WPARAM) i, (LPARAM) pszEmail);
  4253. if( lpCItem->lpCDI && lpCItem->lpCDI->lpszEmailAddress &&
  4254. lstrlen(lpCItem->lpCDI->lpszEmailAddress ) &&
  4255. !lstrcmpi(pszEmail, lpCItem->lpCDI->lpszEmailAddress) )
  4256. {
  4257. // There is a match
  4258. lpbAddCert[nCountCerts] = FALSE; // Dont add this cert
  4259. }
  4260. LocalFreeAndNull(&pszEmail);
  4261. }
  4262. }
  4263. }
  4264. nCountCerts++;
  4265. lpCItem = lpCItem->lpNext;
  4266. }
  4267. }
  4268. lpCItem = lpPai->lpCItem;
  4269. nCountCerts = 0;
  4270. while(lpCItem)
  4271. {
  4272. if(lpbAddCert[nCountCerts])
  4273. AddLVCertItem( hWndLV, lpCItem, TRUE);
  4274. nCountCerts++;
  4275. lpCItem = lpCItem->lpNext;
  4276. }
  4277. out:
  4278. if(ListView_GetItemCount(hWndLV)>0)
  4279. {
  4280. if(lpPai->ulOperationType != SHOW_ONE_OFF)
  4281. {
  4282. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_BUTTON_REMOVE),TRUE);
  4283. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_BUTTON_SETDEFAULT),TRUE);
  4284. }
  4285. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_LIST),TRUE);
  4286. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_BUTTON_PROPERTIES),TRUE);
  4287. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_BUTTON_EXPORT),TRUE);
  4288. }
  4289. if(lpbAddCert)
  4290. LocalFree(lpbAddCert);
  4291. return;
  4292. }
  4293. //$$
  4294. //
  4295. // Init the CertItem struct from an existing lpCDI struct
  4296. //
  4297. // bImporting - if we are importing a new cert - tests it to see if it can be matched to
  4298. // the current contact and if it can't, prompts user
  4299. //
  4300. BOOL AddNewCertItem(HWND hDlg, LPCERT_DISPLAY_INFO lpCDI, LPPROP_ARRAY_INFO lpPai, BOOL bImporting)
  4301. {
  4302. int nLen = 0;
  4303. BOOL bRet= FALSE;
  4304. HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_CERT_LIST);
  4305. LPCERT_ITEM lpCItem = NULL;
  4306. BOOL bMatchFound = FALSE;
  4307. // 96/12/20 markdu BUG 13029 Check for duplicates before adding.
  4308. if(bImporting)
  4309. {
  4310. int i, nCount;
  4311. // Go through all the lpCDI structs in the listview elements and
  4312. // see if any is a match with the new item
  4313. nCount = ListView_GetItemCount(hWndLV);
  4314. for(i=0;i<nCount;i++)
  4315. {
  4316. LV_ITEM lvi = {0};
  4317. lvi.mask = LVIF_PARAM;
  4318. lvi.iItem = i;
  4319. lvi.iSubItem = 0;
  4320. if (ListView_GetItem(hWndLV, &lvi))
  4321. {
  4322. LPCERT_ITEM lpItem = (LPCERT_ITEM) lvi.lParam;
  4323. if (CertCompareCertificate(X509_ASN_ENCODING, lpItem->lpCDI->pccert->pCertInfo,
  4324. lpCDI->pccert->pCertInfo))
  4325. {
  4326. // This cert is already in the list. Select it.
  4327. ShowMessageBox(hDlg, idsCertAlreadyExists,
  4328. MB_ICONINFORMATION | MB_OK);
  4329. SetFocus(hWndLV);
  4330. LVSelectItem(hWndLV, i);
  4331. bRet = TRUE;
  4332. // Free lpCDI here or we will leak it ...
  4333. FreeCertdisplayinfo(lpCDI);
  4334. goto out;
  4335. }
  4336. }
  4337. }
  4338. }
  4339. if(bImporting && lpCDI->lpszEmailAddress && lstrlen(lpCDI->lpszEmailAddress))
  4340. {
  4341. // Check the e-mail address of this certificate with the ones we already have
  4342. // Warn if we cant find it
  4343. HWND hWndCombo = GetDlgItem(hDlg, IDC_DETAILS_CERT_COMBO);
  4344. TCHAR szEmail[MAX_PATH];
  4345. int i, nCount;
  4346. nCount = (int) SendMessage(hWndCombo, CB_GETCOUNT, 0, 0);
  4347. if(nCount > 1)
  4348. {
  4349. // Go thru all the email addresses in the combo box
  4350. for(i= 0;i<nCount -1; i++)
  4351. {
  4352. int nLen;
  4353. nLen = (int)SendMessage(hWndCombo, CB_GETLBTEXTLEN, (WPARAM)i, 0);
  4354. if (nLen != CB_ERR)
  4355. {
  4356. LPTSTR pszEmail = (LPTSTR)LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*(nLen + 1));
  4357. if (pszEmail)
  4358. {
  4359. pszEmail[0] = '\0';
  4360. SendMessage(hWndCombo, CB_GETLBTEXT, (WPARAM) i, (LPARAM) pszEmail);
  4361. if( lpCDI->lpszEmailAddress && lstrlen(pszEmail) &&
  4362. !lstrcmpi(pszEmail, lpCDI->lpszEmailAddress))
  4363. {
  4364. LocalFreeAndNull(&pszEmail);
  4365. bMatchFound = TRUE;
  4366. break;
  4367. }
  4368. LocalFreeAndNull(&pszEmail);
  4369. }
  4370. }
  4371. }
  4372. }
  4373. if(!bMatchFound)
  4374. {
  4375. switch(ShowMessageBoxParam(hDlg, idsImportCertNoEmail, MB_ICONEXCLAMATION | MB_YESNOCANCEL,
  4376. lpCDI->lpszDisplayString, lpCDI->lpszEmailAddress))
  4377. {
  4378. case IDCANCEL: // cancel this import
  4379. bRet = TRUE;
  4380. // Free lpCDI here or we will leak it ...
  4381. FreeCertdisplayinfo(lpCDI);
  4382. goto out;
  4383. break;
  4384. case IDYES: // Add the email address of this contact to the list of email addresses
  4385. HrAddEmailToObj(lpPai, lpCDI->lpszEmailAddress, (LPTSTR)szSMTP);
  4386. FillCertComboWithEmailAddresses(hDlg, lpPai, lpCDI->lpszEmailAddress);
  4387. break;
  4388. case IDNO: // do nothing just add this certificate
  4389. break;
  4390. }
  4391. }
  4392. }
  4393. if( bImporting &&
  4394. (!lpCDI->lpszEmailAddress || !lstrlen(lpCDI->lpszEmailAddress)) )
  4395. {
  4396. FillCertComboWithEmailAddresses(hDlg, lpPai, szEmpty); //szEmpty forces combo to switch to the TEXT("none") option
  4397. }
  4398. lpCItem = LocalAlloc(LMEM_ZEROINIT, sizeof(CERT_ITEM));
  4399. if (!lpCItem)
  4400. goto out;
  4401. lpCItem->lpCDI = lpCDI;
  4402. lpCItem->pcCert = CertDuplicateCertificateContext(lpCDI->pccert);
  4403. lpCItem->lpPrev = NULL;
  4404. nLen = lstrlen(lpCDI->lpszDisplayString) + 1;
  4405. if (nLen > MAX_PATH)
  4406. {
  4407. ULONG iLen = TruncatePos(lpCDI->lpszDisplayString, MAX_PATH - 1);
  4408. lpCDI->lpszDisplayString[iLen] = '\0';
  4409. }
  4410. StrCpyN(lpCItem->szDisplayText, lpCDI->lpszDisplayString, ARRAYSIZE(lpCItem->szDisplayText));
  4411. lpCItem->lpNext = lpPai->lpCItem;
  4412. if(lpPai->lpCItem)
  4413. lpPai->lpCItem->lpPrev = lpCItem;
  4414. lpPai->lpCItem = lpCItem;
  4415. bRet = TRUE;
  4416. out:
  4417. return bRet;
  4418. }
  4419. //$$///////////////////////////////////////////////////////////////
  4420. //
  4421. // SetCertInfoInUI - fills the cert lv with certinfo, if any exists
  4422. //
  4423. ///////////////////////////////////////////////////////////////////
  4424. HRESULT HrSetCertInfoInUI(HWND hDlg,
  4425. LPSPropValue lpPropMVCert,
  4426. LPPROP_ARRAY_INFO lpPai)
  4427. {
  4428. HRESULT hr = E_FAIL;
  4429. LPCERT_DISPLAY_INFO lpCDI = NULL, lpTemp = NULL;
  4430. if(!lpPropMVCert)
  4431. goto out;
  4432. if(!lpPai->lpCItem)
  4433. {
  4434. if(HR_FAILED(HrGetCertsDisplayInfo(hDlg, lpPropMVCert, &lpCDI)))
  4435. goto out;
  4436. if(!lpCDI)
  4437. {
  4438. hr = MAPI_E_NOT_FOUND;
  4439. goto out;
  4440. }
  4441. lpTemp = lpCDI;
  4442. while(lpTemp)
  4443. {
  4444. AddNewCertItem(hDlg, lpTemp, lpPai, FALSE);
  4445. lpTemp = lpTemp->lpNext;
  4446. }
  4447. }
  4448. UpdateCertListView(hDlg, lpPai);
  4449. hr = S_OK;
  4450. out:
  4451. return hr;
  4452. }
  4453. //$$////////////////////////////////////////////////////////////////////////////////
  4454. //
  4455. // AddLVcertItem - adds an item to the certificates list view
  4456. //
  4457. //
  4458. ////////////////////////////////////////////////////////////////////////////////////
  4459. BOOL AddLVCertItem(HWND hWndLV, LPCERT_ITEM lpCItem, BOOL bCheckForDups)
  4460. {
  4461. LV_ITEM lvi = {0};
  4462. ULONG nLen;
  4463. BOOL bRet = FALSE;
  4464. if(!lpCItem)
  4465. goto out;
  4466. // 96/12/20 markdu BUG 13029 Check for duplicates before adding.
  4467. if (TRUE == bCheckForDups)
  4468. {
  4469. int i, nCount;
  4470. // Go through all the lpCDI structs in the listview elements and
  4471. // see if any is a match with the new item
  4472. nCount = ListView_GetItemCount(hWndLV);
  4473. for(i=0;i<nCount;i++)
  4474. {
  4475. LV_ITEM lvi = {0};
  4476. lvi.mask = LVIF_PARAM;
  4477. lvi.iItem = i;
  4478. lvi.iSubItem = 0;
  4479. if (ListView_GetItem(hWndLV, &lvi))
  4480. {
  4481. LPCERT_ITEM lpItem = (LPCERT_ITEM) lvi.lParam;
  4482. if (CertCompareCertificate(X509_ASN_ENCODING, lpItem->lpCDI->pccert->pCertInfo,
  4483. lpCItem->lpCDI->pccert->pCertInfo))
  4484. {
  4485. // This cert is already in the list. Select it.
  4486. SetFocus(hWndLV);
  4487. LVSelectItem(hWndLV, i);
  4488. goto out;
  4489. }
  4490. }
  4491. }
  4492. }
  4493. lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
  4494. lvi.pszText = lpCItem->lpCDI->bIsDefault ? lpCItem->szDisplayText : lpCItem->lpCDI->lpszDisplayString;
  4495. lvi.iItem = ListView_GetItemCount(hWndLV);
  4496. lvi.iSubItem = 0;
  4497. if(!lpCItem->lpCDI->bIsExpired && !lpCItem->lpCDI->bIsRevoked && lpCItem->lpCDI->bIsTrusted)
  4498. lvi.iImage = imgCertValid;
  4499. else
  4500. lvi.iImage = imgCertInvalid;
  4501. lvi.lParam = (LPARAM) lpCItem;
  4502. {
  4503. int nIndex = ListView_InsertItem(hWndLV, &lvi);
  4504. if (ListView_GetItemCount(hWndLV) == 1)
  4505. {
  4506. // only one item in here .. we will take the liberty of making it the
  4507. // default one ...
  4508. SetLVDefaultCert(hWndLV, 0);
  4509. }
  4510. else if(lpCItem->lpCDI->bIsDefault)
  4511. {
  4512. SetLVDefaultCert(hWndLV, nIndex);
  4513. }
  4514. // Select the cert we just added.
  4515. SetFocus(hWndLV);
  4516. LVSelectItem(hWndLV, nIndex);
  4517. }
  4518. bRet = TRUE;
  4519. out:
  4520. return TRUE;
  4521. }
  4522. //$$/////////////////////////////////////////////////////////////////////////
  4523. //
  4524. // SetLVDefaultCert - Makes an cert entry the default one ...
  4525. //
  4526. //////////////////////////////////////////////////////////////////////////////
  4527. void SetLVDefaultCert( HWND hWndLV,
  4528. int iItemIndex)
  4529. {
  4530. int nCount = ListView_GetItemCount(hWndLV);
  4531. int i;
  4532. LPCERT_ITEM lpItem = NULL;
  4533. TCHAR szBuf[MAX_DISPLAY_NAME_LENGTH];
  4534. if (iItemIndex >= nCount)
  4535. goto out;
  4536. for(i=0; i<nCount; i++)
  4537. {
  4538. // At amy given point of time one and only one entry in the
  4539. // list view is the default one ...
  4540. // So we want to reset the previous default and set the new one
  4541. //
  4542. LV_ITEM lvi = {0};
  4543. lvi.iItem = i;
  4544. lvi.mask = LVIF_PARAM;
  4545. if(!ListView_GetItem(hWndLV, &lvi))
  4546. goto out;
  4547. lpItem = (LPCERT_ITEM) lvi.lParam;
  4548. if (lpItem->lpCDI->bIsDefault)
  4549. {
  4550. // This was the default entry - if its
  4551. // not the same one as the one we are setting,
  4552. // reset the default
  4553. if (i != iItemIndex)
  4554. {
  4555. // else reset this entry ...
  4556. lpItem->lpCDI->bIsDefault = FALSE;
  4557. lvi.pszText = lpItem->lpCDI->lpszDisplayString;
  4558. lvi.mask = LVIF_PARAM | LVIF_TEXT;
  4559. lvi.iItem = i;
  4560. lvi.iSubItem = 0;
  4561. ListView_SetItem(hWndLV, &lvi);
  4562. }
  4563. }
  4564. if (iItemIndex == i)
  4565. {
  4566. //This is the item we want to modify ..
  4567. lpItem->lpCDI->bIsDefault = TRUE;
  4568. StrCpyN(lpItem->szDisplayText,lpItem->lpCDI->lpszDisplayString, ARRAYSIZE(lpItem->szDisplayText));
  4569. LoadString(hinstMapiX, idsDefaultCert, szBuf, CharSizeOf(szBuf));
  4570. StrCatBuff(lpItem->szDisplayText, szBuf, ARRAYSIZE(lpItem->szDisplayText));
  4571. lvi.pszText = lpItem->szDisplayText;
  4572. lvi.mask = LVIF_PARAM | LVIF_TEXT;
  4573. lvi.iItem = i;
  4574. lvi.iSubItem = 0;
  4575. ListView_SetItem(hWndLV, &lvi);
  4576. }
  4577. }
  4578. LVSelectItem(hWndLV, iItemIndex);
  4579. out:
  4580. return;
  4581. }
  4582. extern HRESULT HrGetTrustState(HWND hwndParent, PCCERT_CONTEXT pcCert, DWORD *pdwTrust);
  4583. //$$/////////////////////////////////////////////////////////////////////////
  4584. //
  4585. // ShowCertProps - Shows props for a cert
  4586. //
  4587. //////////////////////////////////////////////////////////////////////////////
  4588. void ShowCertProps(HWND hDlg, HWND hWndLV, BOOL * lpBool)
  4589. {
  4590. DWORD dwTrust = 0;
  4591. int nIndex = ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED);
  4592. LV_ITEM lvi;
  4593. LPCERT_ITEM lpItem;
  4594. BOOL bDeletedDefault = FALSE;
  4595. BOOL bOldTrusted;
  4596. LPSTR oidPurpose = szOID_PKIX_KP_EMAIL_PROTECTION;
  4597. lvi.mask = LVIF_PARAM;
  4598. lvi.iSubItem = 0;
  4599. lvi.iItem = nIndex;
  4600. if(ListView_GetItem(hWndLV, &lvi))
  4601. {
  4602. lpItem = (LPCERT_ITEM) lvi.lParam;
  4603. if(lpItem)
  4604. {
  4605. if(lpItem->pcCert == NULL)
  4606. {
  4607. Assert(lpItem->pcCert);
  4608. return;
  4609. }
  4610. // Only one thing is user changable in the cert UI - the trust info
  4611. // So we will track that piece of info
  4612. // User can change dwTrust and consequently, bIsTrusted can also change
  4613. // which needs to be uppdated in the UI check mark
  4614. bOldTrusted = lpItem->lpCDI->bIsTrusted;
  4615. {
  4616. CERT_VIEWPROPERTIES_STRUCT_A cvps = {0};
  4617. cvps.dwSize = sizeof(CERT_VIEWPROPERTIES_STRUCT);
  4618. cvps.hwndParent = hDlg;
  4619. cvps.hInstance = hinstMapiX;
  4620. cvps.pCertContext = lpItem->pcCert;
  4621. cvps.arrayPurposes = &oidPurpose;
  4622. cvps.cArrayPurposes = 1;
  4623. cvps.nStartPage = 1; // go directly to details page
  4624. cvps.dwFlags = CM_NO_NAMECHANGE;
  4625. CertViewPropertiesA(&cvps);
  4626. }
  4627. // Determine if the trust changed or not
  4628. if (FAILED(HrGetTrustState(hDlg, lpItem->pcCert, &(lpItem->lpCDI->dwTrust))))
  4629. {
  4630. lpItem->lpCDI->dwTrust = CERT_VALIDITY_NO_TRUST_DATA;
  4631. }
  4632. if (0 == lpItem->lpCDI->dwTrust)
  4633. lpItem->lpCDI->bIsTrusted = TRUE;
  4634. else
  4635. lpItem->lpCDI->bIsTrusted = FALSE;
  4636. //N2 if the trust changes, we need to check trust again...
  4637. if (bOldTrusted != lpItem->lpCDI->bIsTrusted)
  4638. {
  4639. LV_ITEM lvi = {0};
  4640. // Update the displayed graphic next to the cert.
  4641. lvi.mask = LVIF_IMAGE;
  4642. lvi.iItem = nIndex;
  4643. lvi.iSubItem = 0;
  4644. if(!lpItem->lpCDI->bIsExpired && !lpItem->lpCDI->bIsRevoked && lpItem->lpCDI->bIsTrusted)
  4645. lvi.iImage = imgCertValid;
  4646. else
  4647. lvi.iImage = imgCertInvalid;
  4648. ListView_SetItem(hWndLV, &lvi);
  4649. }
  4650. if(lpBool)
  4651. *lpBool = TRUE;
  4652. }
  4653. }
  4654. else if(ListView_GetSelectedCount(hWndLV) <= 0)
  4655. {
  4656. ShowMessageBox(hDlg, IDS_ADDRBK_MESSAGE_NO_ITEM, MB_ICONEXCLAMATION | MB_OK);
  4657. }
  4658. return;
  4659. }
  4660. //$$/////////////////////////////////////////////////////////////////////////
  4661. //
  4662. // DeleteLVCertItem - Makes an cert entry the default one ...
  4663. //
  4664. //////////////////////////////////////////////////////////////////////////////
  4665. BOOL DeleteLVCertItem(HWND hWndLV, int iItemIndex, LPPROP_ARRAY_INFO lpPai)
  4666. {
  4667. LV_ITEM lvi;
  4668. LPCERT_ITEM lpItem;
  4669. BOOL bDeletedDefault = FALSE;
  4670. lvi.mask = LVIF_PARAM;
  4671. lvi.iSubItem = 0;
  4672. lvi.iItem = iItemIndex;
  4673. if(ListView_GetItem(hWndLV, &lvi))
  4674. {
  4675. lpItem = (LPCERT_ITEM) lvi.lParam;
  4676. if(lpItem)
  4677. {
  4678. if (lpItem->lpCDI->bIsDefault)
  4679. bDeletedDefault = TRUE;
  4680. if(lpItem->lpCDI->lpNext)
  4681. lpItem->lpCDI->lpNext->lpPrev = lpItem->lpCDI->lpPrev;
  4682. if(lpItem->lpCDI->lpPrev)
  4683. lpItem->lpCDI->lpPrev->lpNext = lpItem->lpCDI->lpNext;
  4684. FreeCertdisplayinfo(lpItem->lpCDI);
  4685. if (lpItem->pcCert)
  4686. CertFreeCertificateContext(lpItem->pcCert);
  4687. if(lpItem->lpNext)
  4688. lpItem->lpNext->lpPrev = lpItem->lpPrev;
  4689. if(lpItem->lpPrev)
  4690. lpItem->lpPrev->lpNext = lpItem->lpNext;
  4691. if(lpPai && lpPai->lpCItem == lpItem)
  4692. lpPai->lpCItem = lpItem->lpNext;
  4693. LocalFree(lpItem);
  4694. ListView_DeleteItem(hWndLV, lvi.iItem);
  4695. }
  4696. }
  4697. return bDeletedDefault;
  4698. }
  4699. const TCHAR szCertFilter[] = TEXT("*.p7c;*.p7b;*.cer");
  4700. const TCHAR szAllFilter[] = TEXT("*.*");
  4701. const TCHAR szCERFilter[] = TEXT("*.cer");
  4702. const TCHAR szCERExt[] = TEXT("ext");
  4703. //$$////////////////////////////////////////////////////////////////////////
  4704. ////
  4705. //// ImportCert - imports a cert from file and then adds it into the list view
  4706. ////
  4707. ////
  4708. ////////////////////////////////////////////////////////////////////////////
  4709. BOOL ImportCert(HWND hDlg, LPPROP_ARRAY_INFO lpPai)
  4710. {
  4711. BOOL bRet = FALSE;
  4712. TCHAR szBuf[MAX_UI_STR];
  4713. // we need to get a file name after poping the file open dialog
  4714. // Then we need to decode it
  4715. // Then we need to add it to the list view
  4716. OPENFILENAME ofn;
  4717. LPTSTR lpFilter = FormatAllocFilter(IDS_CERT_FILE_SPEC,
  4718. szCertFilter,
  4719. IDS_ALL_FILE_SPEC,
  4720. szAllFilter,
  4721. 0,
  4722. NULL);
  4723. TCHAR szFileName[MAX_PATH + 1] = TEXT("");
  4724. ofn.lStructSize = sizeof(ofn);
  4725. ofn.hwndOwner = hDlg;
  4726. ofn.hInstance = hinstMapiX;
  4727. ofn.lpstrFilter = lpFilter;
  4728. ofn.lpstrCustomFilter = NULL;
  4729. ofn.nMaxCustFilter = 0;
  4730. ofn.nFilterIndex = 0;
  4731. ofn.lpstrFile = szFileName;
  4732. ofn.nMaxFile = CharSizeOf(szFileName);
  4733. ofn.lpstrFileTitle = NULL;
  4734. ofn.nMaxFileTitle = 0;
  4735. ofn.lpstrInitialDir = NULL;
  4736. LoadString(hinstMapiX, idsCertImportTitle, szBuf, CharSizeOf(szBuf));
  4737. ofn.lpstrTitle = szBuf;
  4738. ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
  4739. ofn.nFileOffset = 0;
  4740. ofn.nFileExtension = 0;
  4741. ofn.lpstrDefExt = NULL;
  4742. ofn.lCustData = 0;
  4743. ofn.lpfnHook = NULL;
  4744. ofn.lpTemplateName = NULL;
  4745. if (GetOpenFileName(&ofn))
  4746. {
  4747. LPCERT_DISPLAY_INFO lpCDI = NULL;
  4748. LPCERT_ITEM lpCItem = NULL;
  4749. if(!HR_FAILED(HrImportCertFromFile( szFileName,
  4750. &lpCDI)))
  4751. {
  4752. if(!AddNewCertItem(hDlg, lpCDI, lpPai, TRUE))
  4753. goto out;
  4754. UpdateCertListView(hDlg, lpPai);
  4755. }
  4756. else
  4757. {
  4758. ShowMessageBoxParam(hDlg, IDE_VCARD_IMPORT_FILE_ERROR, MB_ICONEXCLAMATION, szFileName);
  4759. goto out;
  4760. }
  4761. }
  4762. else
  4763. goto out;
  4764. bRet = TRUE;
  4765. out:
  4766. LocalFreeAndNull(&lpFilter);
  4767. return bRet;
  4768. }
  4769. //$$////////////////////////////////////////////////////////////////////////
  4770. ////
  4771. //// ExportCert - exports a cert to a file
  4772. ////
  4773. ////
  4774. ////////////////////////////////////////////////////////////////////////////
  4775. BOOL ExportCert(HWND hDlg)
  4776. {
  4777. BOOL bRet = FALSE;
  4778. TCHAR szBuf[MAX_UI_STR];
  4779. HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_CERT_LIST);
  4780. OPENFILENAME ofn;
  4781. LPTSTR lpFilter = FormatAllocFilter(IDS_CER_FILE_SPEC,
  4782. szCERFilter,
  4783. IDS_ALL_FILE_SPEC,
  4784. szAllFilter,
  4785. 0,
  4786. NULL);
  4787. TCHAR szFileName[MAX_PATH + 1] = TEXT("");
  4788. // we need to get a file name after poping the file open dialog
  4789. // Then we need to save the cert to the file name
  4790. // First make sure only one entry is selected for exporting
  4791. if(ListView_GetSelectedCount(hWndLV) > 1)
  4792. {
  4793. ShowMessageBox(hDlg, IDS_ADDRBK_MESSAGE_ACTION, MB_OK | MB_ICONEXCLAMATION);
  4794. goto out;
  4795. }
  4796. else if (ListView_GetSelectedCount(hWndLV) <= 0)
  4797. {
  4798. ShowMessageBox(hDlg, IDS_ADDRBK_MESSAGE_NO_ITEM, MB_OK | MB_ICONEXCLAMATION);
  4799. goto out;
  4800. }
  4801. ofn.lStructSize = sizeof(ofn);
  4802. ofn.hwndOwner = hDlg;
  4803. ofn.hInstance = hinstMapiX;
  4804. ofn.lpstrFilter = lpFilter;
  4805. ofn.lpstrCustomFilter = NULL;
  4806. ofn.nMaxCustFilter = 0;
  4807. ofn.nFilterIndex = 0;
  4808. ofn.lpstrFile = szFileName;
  4809. ofn.nMaxFile = CharSizeOf(szFileName);
  4810. ofn.lpstrFileTitle = NULL;
  4811. ofn.nMaxFileTitle = 0;
  4812. ofn.lpstrInitialDir = NULL;
  4813. LoadString(hinstMapiX, idsCertExportTitle, szBuf, CharSizeOf(szBuf));
  4814. ofn.lpstrTitle = szBuf;
  4815. ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT;
  4816. ofn.nFileOffset = 0;
  4817. ofn.nFileExtension = 0;
  4818. ofn.lpstrDefExt = szCERExt;
  4819. ofn.lCustData = 0;
  4820. ofn.lpfnHook = NULL;
  4821. ofn.lpTemplateName = NULL;
  4822. if (GetSaveFileName(&ofn))
  4823. {
  4824. LV_ITEM lvi = {0};
  4825. lvi.mask = LVIF_PARAM;
  4826. lvi.iItem = ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED);
  4827. lvi.iSubItem = 0;
  4828. if (ListView_GetItem(hWndLV, &lvi))
  4829. {
  4830. LPCERT_ITEM lpItem = (LPCERT_ITEM) lvi.lParam;
  4831. HrExportCertToFile( szFileName, lpItem->lpCDI->pccert, NULL, NULL, FALSE);
  4832. }
  4833. else
  4834. goto out;
  4835. }
  4836. else
  4837. goto out;
  4838. bRet = TRUE;
  4839. out:
  4840. return bRet;
  4841. }
  4842. //$$////////////////////////////////////////////////////////////////////////////////
  4843. //
  4844. // Sets the display name in the Combo box
  4845. //
  4846. // hDlg - handle of Personal Pane
  4847. // lppai - proparrayinfo struct
  4848. // bAddAll - determines whether to fill the combo with all the values or not
  4849. // szTxt - txt to put in the edit field part of the combo. if bAddAll=TRUE,
  4850. // dont need szTxt.
  4851. //
  4852. ////////////////////////////////////////////////////////////////////////////////////
  4853. void SetComboDNText(HWND hDlg, LPPROP_ARRAY_INFO lppai, BOOL bAddAll, LPTSTR szTxt)
  4854. {
  4855. HWND hWndCombo = GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME);
  4856. if(!bAddAll)
  4857. {
  4858. if(szTxt == NULL)
  4859. szTxt = szEmpty;
  4860. // just add the current string to the combo
  4861. SendMessage(hWndCombo, CB_RESETCONTENT, 0, 0);
  4862. SendMessage(hWndCombo, CB_ADDSTRING, 0, (LPARAM) szTxt);
  4863. SendMessage(hWndCombo, CB_SETCURSEL, 0, 0);
  4864. SetWindowText(hWndCombo, szTxt);
  4865. }
  4866. else
  4867. {
  4868. // Populates the drop down list with all other names ...
  4869. TCHAR * szFirst = NULL;//szFirst[MAX_UI_STR*2];
  4870. TCHAR * szMiddle = NULL;//[MAX_UI_STR*2];
  4871. TCHAR * szLast = NULL;//[MAX_UI_STR*2];
  4872. TCHAR * szDisplay = NULL;//[MAX_UI_STR*2];
  4873. ULONG nLen = MAX_UI_STR*2;
  4874. szFirst = LocalAlloc(LMEM_ZEROINIT, nLen*sizeof(TCHAR));
  4875. szLast = LocalAlloc(LMEM_ZEROINIT, nLen*sizeof(TCHAR));
  4876. szMiddle = LocalAlloc(LMEM_ZEROINIT, nLen*sizeof(TCHAR));
  4877. szDisplay = LocalAlloc(LMEM_ZEROINIT, nLen*sizeof(TCHAR));
  4878. if(szFirst && szLast && szMiddle && szDisplay)
  4879. {
  4880. szFirst[0] = szLast[0] = szMiddle[0] = szDisplay[0] = '\0';
  4881. // First get the current text and save it ...
  4882. GetWindowText(hWndCombo, szDisplay, nLen);
  4883. // Clear out combo and add the display name again
  4884. SendMessage(hWndCombo, CB_RESETCONTENT, 0, 0);
  4885. if(lstrlen(szDisplay))
  4886. SendMessage(hWndCombo, CB_ADDSTRING, 0, (LPARAM) szDisplay);
  4887. // Get the localized F/M/L name from F/M/L fields
  4888. // If the localized name does not match the display name, add it
  4889. GetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_EDIT_FIRSTNAME, szFirst, nLen);
  4890. GetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_EDIT_LASTNAME, szLast, nLen);
  4891. GetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_EDIT_MIDDLENAME, szMiddle, nLen);
  4892. {
  4893. ULONG ulSzBuf = MAX_BUF_STR;
  4894. LPTSTR szBuf = LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*ulSzBuf);
  4895. LPTSTR lpszTmp = szBuf;
  4896. if(szBuf) // Get the localized Display Name and reverse localized display name
  4897. {
  4898. if(SetLocalizedDisplayName( szFirst, szMiddle, szLast,
  4899. NULL, // Company Name (not needed)
  4900. NULL, // Nick Name (not needed here)
  4901. (LPTSTR *) &lpszTmp, //&szBuf,
  4902. ulSzBuf, bDNisByLN,
  4903. bDNisByLN ? szResourceDNByCommaLN : szResourceDNByLN,
  4904. NULL))
  4905. {
  4906. if(lstrlen(szBuf) && lstrcmp(szBuf, szDisplay))
  4907. SendMessage(hWndCombo, CB_ADDSTRING, 0, (LPARAM) szBuf);
  4908. }
  4909. szBuf[0] = TEXT('\0');
  4910. if(SetLocalizedDisplayName( szFirst, szMiddle, szLast,
  4911. NULL, // Company Name (not needed)
  4912. NULL, // Nick Name (not needed here)
  4913. (LPTSTR *) &lpszTmp, //&szBuf,
  4914. ulSzBuf, !bDNisByLN, NULL, NULL))
  4915. {
  4916. if(lstrlen(szBuf) && lstrcmp(szBuf, szDisplay))
  4917. SendMessage(hWndCombo, CB_ADDSTRING, 0, (LPARAM) szBuf);
  4918. }
  4919. szBuf[0] = TEXT('\0');
  4920. if(SetLocalizedDisplayName( szFirst, szMiddle, szLast,
  4921. NULL, // Company Name (not needed)
  4922. NULL, // Nick Name (not needed here)
  4923. (LPTSTR *) &lpszTmp, //&szBuf,
  4924. ulSzBuf, bDNisByLN, NULL, NULL))
  4925. {
  4926. if(lstrlen(szBuf) && lstrcmp(szBuf, szDisplay))
  4927. SendMessage(hWndCombo, CB_ADDSTRING, 0, (LPARAM) szBuf);
  4928. }
  4929. LocalFreeAndNull(&szBuf);
  4930. }
  4931. }
  4932. // Get the NickName and if its different add it to this list
  4933. szFirst[0]='\0';
  4934. GetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_EDIT_NICKNAME, szFirst, nLen);
  4935. if(lstrlen(szFirst) && lstrcmp(szFirst, szDisplay))
  4936. SendMessage(hWndCombo, CB_ADDSTRING, 0, (LPARAM) szFirst);
  4937. // Get the Company name and if its different add it to the list
  4938. szFirst[0]='\0';
  4939. {
  4940. ULONG i;
  4941. ULONG ulcPropCount = 0;
  4942. LPSPropValue lpPropArray = NULL;
  4943. SizedSPropTagArray(1, ptaDN) = {1, PR_COMPANY_NAME};
  4944. if(!HR_FAILED(lppai->lpPropObj->lpVtbl->GetProps(lppai->lpPropObj,
  4945. (LPSPropTagArray)&ptaDN,
  4946. MAPI_UNICODE,
  4947. &ulcPropCount,
  4948. &lpPropArray)))
  4949. {
  4950. if(lpPropArray[0].ulPropTag == PR_COMPANY_NAME)
  4951. StrCpyN(szFirst, lpPropArray[0].Value.LPSZ, nLen);
  4952. }
  4953. if(lpPropArray)
  4954. MAPIFreeBuffer(lpPropArray);
  4955. }
  4956. if(lstrlen(szFirst) && lstrcmp(szFirst, szDisplay))
  4957. SendMessage(hWndCombo, CB_ADDSTRING, 0, (LPARAM) szFirst);
  4958. SendMessage(hWndCombo, CB_SETCURSEL, 0, 0);
  4959. SetWindowText(hWndCombo, szDisplay);
  4960. }
  4961. LocalFreeAndNull(&szFirst);
  4962. LocalFreeAndNull(&szLast);
  4963. LocalFreeAndNull(&szMiddle);
  4964. LocalFreeAndNull(&szDisplay);
  4965. }
  4966. //SendMessage(hWndCombo, WM_SETREDRAW, (WPARAM) TRUE, 0);
  4967. UpdateWindow(hWndCombo);
  4968. return;
  4969. }
  4970. //$$////////////////////////////////////////////////////////////////////////////////
  4971. //
  4972. // HrShowOneOffDetailsOnVCard
  4973. //
  4974. // Deciphers a vCard File and then shows one off details on it
  4975. //
  4976. //
  4977. ////////////////////////////////////////////////////////////////////////////////////
  4978. HRESULT HrShowOneOffDetailsOnVCard( LPADRBOOK lpAdrBook,
  4979. HWND hWnd,
  4980. LPTSTR szvCardFile)
  4981. {
  4982. HRESULT hr = E_FAIL;
  4983. HANDLE hFile = NULL;
  4984. LPMAILUSER lpMailUser = NULL;
  4985. LPSTR lpBuf = NULL, lpVCardStart = NULL;
  4986. LPSTR lpVCard = NULL, lpNext = NULL;
  4987. if(!VCardGetBuffer(szvCardFile, NULL, &lpBuf) && hWnd) //no message if no hwnd
  4988. {
  4989. // couldn't open file.
  4990. ShowMessageBoxParam(hWnd, IDE_VCARD_IMPORT_FILE_ERROR,
  4991. MB_ICONEXCLAMATION, szvCardFile);
  4992. goto out;
  4993. }
  4994. lpVCardStart = lpBuf;
  4995. // Loop through showing all the nested vCards one by one ..
  4996. while(VCardGetNextBuffer(lpVCardStart, &lpVCard, &lpNext) && lpVCard)
  4997. {
  4998. // Step 1 - see if we can get a mailuser object out of this file
  4999. if(!HR_FAILED(hr = VCardRetrieve( lpAdrBook, hWnd, MAPI_DIALOG, szvCardFile,
  5000. lpVCard, &lpMailUser)))
  5001. {
  5002. // Step 2 - Show one-off details on this entry
  5003. if(!HR_FAILED(hr = HrShowOneOffDetails( lpAdrBook, hWnd, 0, NULL,
  5004. MAPI_MAILUSER, (LPMAPIPROP) lpMailUser, NULL, SHOW_ONE_OFF)))
  5005. {
  5006. if(lpMailUser)
  5007. lpMailUser->lpVtbl->Release(lpMailUser);
  5008. if(hr == MAPI_E_USER_CANCEL)
  5009. break;
  5010. }
  5011. }
  5012. lpVCard = NULL;
  5013. lpVCardStart = lpNext;
  5014. }
  5015. out:
  5016. LocalFreeAndNull(&lpBuf);
  5017. return hr;
  5018. }
  5019. /*
  5020. HRESULT KillTrustInSleazyFashion(HWND hWndLV, int iItem)
  5021. {
  5022. LV_ITEM lvi = {0};
  5023. HRESULT hr = E_FAIL;
  5024. lvi.mask = LVIF_PARAM;
  5025. lvi.iItem = iItem;
  5026. lvi.iSubItem = 0;
  5027. if (ListView_GetItem(hWndLV, &lvi))
  5028. {
  5029. }
  5030. return hr;
  5031. }
  5032. */
  5033. /*//$$***********************************************************************
  5034. * FUNCTION: fnTridentProc
  5035. *
  5036. * PURPOSE: Callback function for handling the Trident property sheet ...
  5037. *
  5038. ****************************************************************************/
  5039. INT_PTR CALLBACK fnTridentProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)
  5040. {
  5041. PROPSHEETPAGE * pps;
  5042. BOOL bRet = FALSE;
  5043. pps = (PROPSHEETPAGE *) GetWindowLongPtr(hDlg, DWLP_USER);
  5044. switch(message)
  5045. {
  5046. case WM_INITDIALOG:
  5047. {
  5048. SetWindowLongPtr(hDlg,DWLP_USER,lParam);
  5049. pps = (PROPSHEETPAGE *) lParam;
  5050. SetDetailsUI(hDlg, lpPAI, lpPAI->ulOperationType, propTrident);
  5051. FillCertTridentConfDetailsUI(hDlg, lpPAI, propTrident, lpbSomethingChanged);
  5052. return TRUE;
  5053. }
  5054. break;
  5055. case WM_HELP:
  5056. WABWinHelp(((LPHELPINFO)lParam)->hItemHandle,
  5057. g_szWABHelpFileName,
  5058. HELP_WM_HELP,
  5059. (DWORD_PTR)(LPSTR) rgDetlsHelpIDs );
  5060. break;
  5061. case WM_CONTEXTMENU:
  5062. WABWinHelp((HWND) wParam,
  5063. g_szWABHelpFileName,
  5064. HELP_CONTEXTMENU,
  5065. (DWORD_PTR)(LPVOID) rgDetlsHelpIDs );
  5066. break;
  5067. case WM_COMMAND:
  5068. switch(GET_WM_COMMAND_ID(wParam, lParam))
  5069. {
  5070. case IDC_DETAILS_TRIDENT_BUTTON_ADDTOWAB:
  5071. lpPAI->nRetVal = DETAILS_ADDTOWAB;
  5072. SendMessage(GetParent(hDlg), WM_COMMAND, (WPARAM) IDCANCEL, 0);
  5073. break;
  5074. case IDCANCEL:
  5075. // This is a windows bug that prevents ESC canceling prop sheets
  5076. // which have MultiLine Edit boxes KB: Q130765
  5077. SendMessage(GetParent(hDlg),message,wParam,lParam);
  5078. break;
  5079. }
  5080. break;
  5081. case WM_NOTIFY:
  5082. switch(((NMHDR FAR *)lParam)->code)
  5083. {
  5084. case PSN_SETACTIVE: //initialize
  5085. break;
  5086. case PSN_APPLY: //ok
  5087. // in case any of the extended props changed, we need to mark this flag so we wont lose data
  5088. if(lpbSomethingChanged)
  5089. (*lpbSomethingChanged) = ChangedExtDisplayInfo(lpPAI, (*lpbSomethingChanged));
  5090. if (lpPAI->nRetVal == DETAILS_RESET)
  5091. lpPAI->nRetVal = DETAILS_OK;
  5092. break;
  5093. case PSN_KILLACTIVE: //Losing activation to another page
  5094. break;
  5095. case PSN_RESET: //cancel
  5096. if (lpPAI->nRetVal == DETAILS_RESET)
  5097. lpPAI->nRetVal = DETAILS_CANCEL;
  5098. break;
  5099. }
  5100. return TRUE;
  5101. }
  5102. return bRet;
  5103. }
  5104. //$$//////////////////////////////////////////////////////////////////////////
  5105. //
  5106. // SetDefaultServer(hDlg, lpPai)
  5107. //
  5108. // iSelectedItem - the item index to which we should set the Default or Backup
  5109. // bForce - forcibly set the Index to the one specified by iSelectedItem
  5110. // if FALSE, chooses any unused index value
  5111. //
  5112. /////////////////////////////////////////////////////////////////////////////
  5113. void SetDefaultServer(HWND hDlg, LPPROP_ARRAY_INFO lpPai, int iSelectedItem, BOOL bForce)
  5114. {
  5115. HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_NTMTG_LIST_SERVERS);
  5116. int nCount = ListView_GetItemCount(hWndLV);
  5117. TCHAR sz[MAX_PATH];
  5118. TCHAR szTmp[MAX_PATH];
  5119. int oldIndex = lpPai->nDefaultServerIndex;
  5120. if(iSelectedItem == -1)
  5121. {
  5122. iSelectedItem = ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED);
  5123. if(iSelectedItem < 0)
  5124. return; // nothing selected ..
  5125. }
  5126. if(iSelectedItem == lpPai->nBackupServerIndex)
  5127. {
  5128. if(!bForce)
  5129. {
  5130. if(nCount >= 2)
  5131. {
  5132. int nTmp = 0;
  5133. while(nTmp == iSelectedItem && nTmp < nCount)
  5134. nTmp++;
  5135. iSelectedItem = nTmp;
  5136. }
  5137. }
  5138. }
  5139. // replace the old value of the def index item if applicable
  5140. if(lpPai->nDefaultServerIndex >= 0 && lpPai->szDefaultServerName && lstrlen(lpPai->szDefaultServerName))
  5141. {
  5142. ListView_SetItemText(hWndLV, lpPai->nDefaultServerIndex, 0, lpPai->szDefaultServerName);
  5143. lpPai->szDefaultServerName[0] = TEXT('\0');
  5144. }
  5145. // replace the old backup item text if we are reseting the backup item
  5146. if((lpPai->nBackupServerIndex == iSelectedItem) &&
  5147. lpPai->nBackupServerIndex >= 0 && lpPai->szBackupServerName && lstrlen(lpPai->szBackupServerName))
  5148. {
  5149. ListView_SetItemText(hWndLV, lpPai->nBackupServerIndex, 0, lpPai->szBackupServerName);
  5150. lpPai->szBackupServerName[0] = TEXT('\0');
  5151. }
  5152. lpPai->nDefaultServerIndex = iSelectedItem;
  5153. // Now that we have unique indexes for Default and Server Indexes
  5154. // append TEXT("Default") and TEXT("Backup") to these names
  5155. {
  5156. sz[0] = TEXT('\0');
  5157. szTmp[0] = TEXT('\0');
  5158. ListView_GetItemText(hWndLV, lpPai->nDefaultServerIndex, 0, sz, CharSizeOf(sz));
  5159. StrCpyN(lpPai->szDefaultServerName, sz, lpPai->cchDefaultServerName);
  5160. LoadString(hinstMapiX, idsDefaultServer, szTmp, CharSizeOf(szTmp));
  5161. StrCatBuff(sz, TEXT(" "), ARRAYSIZE(sz));
  5162. StrCatBuff(sz, szTmp, ARRAYSIZE(sz));
  5163. ListView_SetItemText(hWndLV, lpPai->nDefaultServerIndex, 0, sz);
  5164. }
  5165. if(lpPai->nBackupServerIndex == iSelectedItem)
  5166. {
  5167. // Update this backup item
  5168. SetBackupServer(hDlg, lpPai, oldIndex, FALSE);
  5169. }
  5170. }
  5171. //$$//////////////////////////////////////////////////////////////////////////
  5172. //
  5173. // SetBackupServer(hDlg, lpPai) - set backup server if possible to do so
  5174. //
  5175. // iSelectedItem - the item index to which we should set the Default or Backup
  5176. // bForce - forcibly set the Index to the one specified by iSelectedItem
  5177. // if FALSE, chooses any unused index value
  5178. //
  5179. /////////////////////////////////////////////////////////////////////////////
  5180. void SetBackupServer(HWND hDlg, LPPROP_ARRAY_INFO lpPai, int iSelectedItem, BOOL bForce)
  5181. {
  5182. HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_NTMTG_LIST_SERVERS);
  5183. int nCount = ListView_GetItemCount(hWndLV);
  5184. TCHAR sz[MAX_PATH];
  5185. TCHAR szTmp[MAX_PATH];
  5186. int oldIndex = lpPai->nBackupServerIndex;
  5187. if(iSelectedItem != -1)
  5188. {
  5189. if(nCount <= 1) // cant overwrite the default to skip
  5190. return;
  5191. }
  5192. else
  5193. {
  5194. iSelectedItem = ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED);
  5195. if(iSelectedItem < 0)
  5196. return; // nothing selected ..
  5197. }
  5198. if(iSelectedItem == lpPai->nDefaultServerIndex)
  5199. {
  5200. if(nCount <= 1)
  5201. return;
  5202. else
  5203. {
  5204. if(!bForce)
  5205. {
  5206. int nTmp = 0;
  5207. while(nTmp == iSelectedItem && nTmp < nCount)
  5208. nTmp++;
  5209. iSelectedItem = nTmp;
  5210. }
  5211. }
  5212. }
  5213. // replace the old value of the def index item if its being overwritten
  5214. if((lpPai->nDefaultServerIndex == iSelectedItem) &&
  5215. lpPai->nDefaultServerIndex >= 0 && lpPai->szDefaultServerName && lstrlen(lpPai->szDefaultServerName))
  5216. {
  5217. ListView_SetItemText(hWndLV, lpPai->nDefaultServerIndex, 0, lpPai->szDefaultServerName);
  5218. lpPai->szDefaultServerName[0] = TEXT('\0');
  5219. }
  5220. // replace the old backup item text if we are reseting the backup item
  5221. if(lpPai->nBackupServerIndex >= 0 && lpPai->szBackupServerName && lstrlen(lpPai->szBackupServerName))
  5222. {
  5223. ListView_SetItemText(hWndLV, lpPai->nBackupServerIndex, 0, lpPai->szBackupServerName);
  5224. lpPai->szBackupServerName[0] = TEXT('\0');
  5225. }
  5226. lpPai->nBackupServerIndex = iSelectedItem;
  5227. {
  5228. sz[0] = TEXT('\0');
  5229. szTmp[0] = TEXT('\0');
  5230. ListView_GetItemText(hWndLV, lpPai->nBackupServerIndex, 0, sz, CharSizeOf(sz));
  5231. StrCpyN(lpPai->szBackupServerName, sz, lpPai->cchBackupServerName);
  5232. LoadString(hinstMapiX, idsBackupServer, szTmp, CharSizeOf(szTmp));
  5233. StrCatBuff(sz, TEXT(" "), ARRAYSIZE(sz));
  5234. StrCatBuff(sz, szTmp, ARRAYSIZE(sz));
  5235. ListView_SetItemText(hWndLV, lpPai->nBackupServerIndex, 0, sz);
  5236. }
  5237. if(lpPai->nDefaultServerIndex == iSelectedItem)
  5238. {
  5239. // Update this backup item
  5240. SetDefaultServer(hDlg, lpPai, oldIndex, FALSE);
  5241. }
  5242. }
  5243. //$$//////////////////////////////////////////////////////////////////////////
  5244. //
  5245. // UpdateServerLVButtons(hDlg);
  5246. //
  5247. /////////////////////////////////////////////////////////////////////////////
  5248. void UpdateServerLVButtons(HWND hDlg, LPPROP_ARRAY_INFO lpPai)
  5249. {
  5250. int nCount = ListView_GetItemCount(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_LIST_SERVERS));
  5251. if(lpPai->ulOperationType == SHOW_ONE_OFF)
  5252. nCount = 0;
  5253. EnableWindow(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_BUTTON_EDIT), (nCount > 0) ? TRUE : FALSE);
  5254. EnableWindow(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_BUTTON_REMOVE), (nCount > 0) ? TRUE : FALSE);
  5255. EnableWindow(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_BUTTON_SETDEFAULT), (nCount > 0) ? TRUE : FALSE);
  5256. EnableWindow(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_BUTTON_SETBACKUP), (nCount > 1) ? TRUE : FALSE);
  5257. }
  5258. //$$//////////////////////////////////////////////////////////////////////////
  5259. //
  5260. // FillComboWithEmailAddresses(HWND hWndLV, HWND hWndCombo);
  5261. //
  5262. /////////////////////////////////////////////////////////////////////////////
  5263. void FillComboWithEmailAddresses(LPPROP_ARRAY_INFO lpPai, HWND hWndCombo, int * lpnDefault)
  5264. {
  5265. ULONG i,j;
  5266. ULONG ulcProps = 0;
  5267. LPSPropValue lpProps = NULL;
  5268. int nSel = (int) SendMessage(hWndCombo, CB_GETCURSEL, 0, 0);
  5269. TCHAR szBuf[MAX_UI_STR];
  5270. BOOL bMatch = FALSE;
  5271. BOOL bFound = FALSE;
  5272. ULONG nEmail = 0xFFFFFFFF;
  5273. enum _EmailProps
  5274. {
  5275. eCEmailAddr=0,
  5276. eCEmailIndex,
  5277. eCEmail,
  5278. eMax
  5279. };
  5280. SizedSPropTagArray(eMax, ptaE) =
  5281. {
  5282. eMax,
  5283. {
  5284. PR_CONTACT_EMAIL_ADDRESSES,
  5285. PR_CONTACT_DEFAULT_ADDRESS_INDEX,
  5286. PR_EMAIL_ADDRESS
  5287. }
  5288. };
  5289. *szBuf = '\0';
  5290. GetWindowText(hWndCombo, szBuf, CharSizeOf(szBuf));
  5291. // Delete all the combo contents
  5292. SendMessage(hWndCombo, CB_RESETCONTENT, 0, 0);
  5293. if(HR_FAILED(lpPai->lpPropObj->lpVtbl->GetProps(lpPai->lpPropObj,
  5294. (LPSPropTagArray)&ptaE,
  5295. MAPI_UNICODE,
  5296. &ulcProps, &lpProps)))
  5297. return;
  5298. // Check if the PR_CONTACT_EMAIL_ADDRESSES already exists ..
  5299. // if it does, tag the email onto it
  5300. // if it doesnt and there is no pr_email_address, we create both
  5301. // else if there is PR_EMAIL address then we cretae contact_email_addresses
  5302. if(lpProps[eCEmailAddr].ulPropTag == PR_CONTACT_EMAIL_ADDRESSES)
  5303. {
  5304. bFound = TRUE;
  5305. for(j=0;j<lpProps[eCEmailAddr].Value.MVSZ.cValues;j++)
  5306. {
  5307. SendMessage(hWndCombo, CB_ADDSTRING, 0, (LPARAM) lpProps[eCEmailAddr].Value.MVSZ.LPPSZ[j]);
  5308. if(!lstrcmp(szBuf, lpProps[eCEmailAddr].Value.MVSZ.LPPSZ[j]))
  5309. {
  5310. bMatch = TRUE;
  5311. nSel = j;
  5312. }
  5313. }
  5314. }
  5315. if( lpProps[eCEmailIndex].ulPropTag == PR_CONTACT_DEFAULT_ADDRESS_INDEX)
  5316. {
  5317. if(lpnDefault)
  5318. *lpnDefault = lpProps[eCEmailIndex].Value.l;
  5319. }
  5320. if(lpProps[eCEmail].ulPropTag == PR_EMAIL_ADDRESS)
  5321. nEmail = eCEmail;
  5322. // if there is no Contact_Email_Addresses but there is an email_address
  5323. if(!bFound && nEmail != 0xFFFFFFFF)
  5324. {
  5325. SendMessage(hWndCombo, CB_ADDSTRING, 0, (LPARAM) lpProps[nEmail].Value.LPSZ);
  5326. if(!lstrcmp(szBuf, lpProps[nEmail].Value.LPSZ))
  5327. {
  5328. bMatch = TRUE;
  5329. nSel = 0;
  5330. }
  5331. }
  5332. if(bMatch)
  5333. SendMessage(hWndCombo, CB_SETCURSEL, (WPARAM) nSel, 0);
  5334. else if(lstrlen(szBuf))
  5335. {
  5336. // make sure this is not the [None .. ] string
  5337. TCHAR sz[MAX_PATH];
  5338. LoadString(hinstMapiX, idsCertsWithoutEmails, sz, CharSizeOf(sz));
  5339. if(lstrcmpi(sz, szBuf))
  5340. {
  5341. int nPos = (int) SendMessage(hWndCombo, CB_ADDSTRING, 0, (LPARAM) szBuf);
  5342. SendMessage(hWndCombo, CB_SETCURSEL, (WPARAM) nPos, 0);
  5343. }
  5344. }
  5345. SetWindowText(hWndCombo, szBuf);
  5346. MAPIFreeBuffer(lpProps);
  5347. }
  5348. /*
  5349. - ClearConfLV
  5350. -
  5351. * Clears out the info alloced into the conferencing list view
  5352. */
  5353. void ClearConfLV(HWND hDlg)
  5354. {
  5355. HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_NTMTG_LIST_SERVERS);
  5356. int nItemCount = ListView_GetItemCount(hWndLV), i = 0;
  5357. for(i=0;i< nItemCount; i++)
  5358. {
  5359. LV_ITEM lvi = {0};
  5360. lvi.mask = LVIF_PARAM;
  5361. lvi.iItem = i; lvi.iSubItem = 0;
  5362. ListView_GetItem(hWndLV, &lvi);
  5363. if(lvi.lParam)
  5364. LocalFreeServerItem((LPSERVER_ITEM) lvi.lParam);
  5365. }
  5366. ListView_DeleteAllItems(hWndLV);
  5367. }
  5368. /*//$$***********************************************************************
  5369. * FUNCTION: fnConferencingProc
  5370. *
  5371. * PURPOSE: Callback function for handling the Conferencing property sheet ...
  5372. *
  5373. ****************************************************************************/
  5374. INT_PTR CALLBACK fnConferencingProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)
  5375. {
  5376. PROPSHEETPAGE * pps;
  5377. BOOL bRet = FALSE;
  5378. pps = (PROPSHEETPAGE *) GetWindowLongPtr(hDlg, DWLP_USER);
  5379. switch(message)
  5380. {
  5381. case WM_INITDIALOG:
  5382. // [PaulHi] EnumChildWindows needs to be called BEFORE SetDetails in this case
  5383. // because it sets list view column strings. SetDetails calls EnumChildWindows
  5384. // at the end but this is too late.
  5385. // @todo - Instead of callinge EnumChildWindows twice just call it at the
  5386. // begninning of SetDetails. Don't want to change the code that much now right
  5387. // before RTM.
  5388. EnumChildWindows(hDlg, SetChildDefaultGUIFont, (LPARAM)0);
  5389. SetWindowLongPtr(hDlg,DWLP_USER,lParam);
  5390. pps = (PROPSHEETPAGE *) lParam;
  5391. lpPAI->ulFlags |= DETAILS_Initializing;
  5392. SetDetailsUI(hDlg, lpPAI, lpPAI->ulOperationType, propConferencing);
  5393. lpPAI->ulFlags &= ~DETAILS_Initializing;
  5394. return TRUE;
  5395. break;
  5396. case WM_DESTROY:
  5397. bRet = TRUE;
  5398. break;
  5399. case WM_HELP:
  5400. WABWinHelp(((LPHELPINFO)lParam)->hItemHandle,
  5401. g_szWABHelpFileName,
  5402. HELP_WM_HELP,
  5403. (DWORD_PTR)(LPSTR) rgDetlsHelpIDs );
  5404. break;
  5405. case WM_CONTEXTMENU:
  5406. WABWinHelp((HWND) wParam,
  5407. g_szWABHelpFileName,
  5408. HELP_CONTEXTMENU,
  5409. (DWORD_PTR)(LPVOID) rgDetlsHelpIDs );
  5410. break;
  5411. case WM_COMMAND:
  5412. switch(GET_WM_COMMAND_CMD(wParam,lParam)) //check the notification code
  5413. {
  5414. case EN_CHANGE:
  5415. if(LOWORD(wParam) == IDC_DETAILS_NTMTG_EDIT_ADDSERVER)
  5416. {
  5417. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_NTMTG_BUTTON_ADDSERVER),TRUE);
  5418. SendMessage(hDlg, DM_SETDEFID, IDC_DETAILS_NTMTG_BUTTON_ADDSERVER, 0);
  5419. return 0;
  5420. break;
  5421. }
  5422. case CBN_EDITCHANGE:
  5423. case CBN_SELCHANGE:
  5424. if (lpbSomethingChanged)
  5425. (*lpbSomethingChanged) = TRUE;
  5426. break;
  5427. }
  5428. switch(GET_WM_COMMAND_ID(wParam, lParam))
  5429. {
  5430. case IDCANCEL:
  5431. // This is a windows bug that prevents ESC canceling prop sheets
  5432. // which have MultiLine Edit boxes KB: Q130765
  5433. SendMessage(GetParent(hDlg),message,wParam,lParam);
  5434. break;
  5435. case IDC_DETAILS_NTMTG_BUTTON_CALL:
  5436. // basically shell-exec a TEXT("callto") command here
  5437. // The format of the TEXT("Callto") protocol is
  5438. // callto://servername/emailalias
  5439. //
  5440. {
  5441. TCHAR * szCalltoURL = NULL;//szCalltoURL[MAX_UI_STR*2];
  5442. ULONG cchCalltoURL=MAX_UI_STR*2;
  5443. TCHAR szEmail[MAX_UI_STR];
  5444. TCHAR szServer[MAX_UI_STR];
  5445. HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_NTMTG_LIST_SERVERS);
  5446. if(szCalltoURL = LocalAlloc(LMEM_ZEROINIT, cchCalltoURL*sizeof(TCHAR)))
  5447. {
  5448. int nItem = ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED);
  5449. {
  5450. LV_ITEM lvi = {0};
  5451. lvi.iItem = nItem;
  5452. lvi.iSubItem = 0;
  5453. lvi.mask = LVIF_PARAM;
  5454. ListView_GetItem(hWndLV, &lvi);
  5455. if(lvi.lParam)
  5456. {
  5457. StrCpyN(szServer, (LPTSTR) ((LPSERVER_ITEM)lvi.lParam)->lpServer, ARRAYSIZE(szServer));
  5458. StrCpyN(szEmail, (LPTSTR) ((LPSERVER_ITEM)lvi.lParam)->lpEmail, ARRAYSIZE(szEmail));
  5459. }
  5460. else
  5461. {
  5462. szServer[0] = TEXT('\0');
  5463. szEmail[0] = TEXT('\0');
  5464. }
  5465. }
  5466. if(lstrlen(szServer) && lstrlen(szEmail))
  5467. {
  5468. StrCpyN(szCalltoURL, szCallto, cchCalltoURL);
  5469. StrCatBuff(szCalltoURL, szServer, cchCalltoURL);
  5470. StrCatBuff(szCalltoURL, TEXT("/"), cchCalltoURL);
  5471. StrCatBuff(szCalltoURL, szEmail, cchCalltoURL);
  5472. ShellExecute(hDlg, TEXT("open"), szCalltoURL, NULL, NULL, SW_SHOWNORMAL);
  5473. }
  5474. else
  5475. ShowMessageBox(hDlg, idsIncompleteConfInfo, MB_OK | MB_ICONINFORMATION);
  5476. LocalFreeAndNull(&szCalltoURL);
  5477. }
  5478. }
  5479. break;
  5480. case IDC_DETAILS_NTMTG_BUTTON_CANCELEDIT:
  5481. {
  5482. HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_NTMTG_LIST_SERVERS);
  5483. LVSelectItem(hWndLV, lpPAI->nConfEditIndex);
  5484. lpPAI->ulFlags &= ~DETAILS_EditingConf;
  5485. ShowWindow(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_BUTTON_CANCELEDIT), SW_HIDE);
  5486. lpPAI->nConfEditIndex = -1;
  5487. SetDlgItemText(hDlg, IDC_DETAILS_NTMTG_EDIT_ADDSERVER, szEmpty);
  5488. SetDlgItemText(hDlg, IDC_DETAILS_NTMTG_COMBO_EMAIL, szEmpty);
  5489. {
  5490. TCHAR sz[MAX_PATH];
  5491. LoadString(hinstMapiX, idsConfAdd, sz, CharSizeOf(sz));
  5492. SetDlgItemText(hDlg, IDC_DETAILS_NTMTG_BUTTON_ADDSERVER, sz);
  5493. }
  5494. }
  5495. break;
  5496. case IDC_DETAILS_NTMTG_BUTTON_ADDSERVER:
  5497. {
  5498. TCHAR szBuf[MAX_UI_STR], szEmail[MAX_UI_STR];
  5499. HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_NTMTG_LIST_SERVERS);
  5500. GetDlgItemText(hDlg, IDC_DETAILS_NTMTG_EDIT_ADDSERVER, szBuf, CharSizeOf(szBuf));
  5501. TrimSpaces(szBuf);
  5502. GetDlgItemText(hDlg, IDC_DETAILS_NTMTG_COMBO_EMAIL, szEmail, CharSizeOf(szEmail));
  5503. TrimSpaces(szEmail);
  5504. if(!lstrlen(szBuf) || !lstrlen(szEmail))
  5505. ShowMessageBox(hDlg, idsIncompleteConfInfo, MB_OK | MB_ICONEXCLAMATION);
  5506. else
  5507. {
  5508. LV_ITEM lvi = {0};
  5509. LPSERVER_ITEM lpSI = (LPSERVER_ITEM) LocalAlloc(LMEM_ZEROINIT, sizeof(SERVER_ITEM));
  5510. ULONG cch = lstrlen(szBuf)+1;
  5511. LPTSTR lp = LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*cch);
  5512. ULONG cchE = lstrlen(szEmail)+1;
  5513. LPTSTR lpE = LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*cchE);
  5514. lvi.mask = LVIF_TEXT | LVIF_PARAM;
  5515. if(lp && lpE && lpSI)
  5516. {
  5517. SendMessage(hWndLV, WM_SETREDRAW, (WPARAM) FALSE, 0);
  5518. StrCpyN(lp, szBuf, cch);
  5519. StrCpyN(lpE, szEmail, cchE);
  5520. lpSI->lpServer = lp;
  5521. lpSI->lpEmail = lpE;
  5522. lvi.lParam = (LPARAM) lpSI;
  5523. if(lpPAI->ulFlags & DETAILS_EditingConf)
  5524. lvi.iItem = lpPAI->nConfEditIndex;
  5525. else
  5526. lvi.iItem = ListView_GetItemCount(hWndLV);
  5527. lvi.cchTextMax = MAX_UI_STR;
  5528. lvi.iSubItem = 0;
  5529. lvi.pszText = szBuf;
  5530. ListView_InsertItem(hWndLV, &lvi);
  5531. ListView_SetItemText (hWndLV, lvi.iItem, 1, szEmail);
  5532. SetDlgItemText(hDlg, IDC_DETAILS_NTMTG_EDIT_ADDSERVER, szEmpty);
  5533. SetDlgItemText(hDlg, IDC_DETAILS_NTMTG_COMBO_EMAIL, szEmpty);
  5534. if(lpPAI->ulFlags & DETAILS_EditingConf)
  5535. {
  5536. LV_ITEM lvii = {0};
  5537. lvii.mask = LVIF_PARAM;
  5538. lvii.iItem = lvi.iItem+1; lvii.iSubItem = 0;
  5539. ListView_GetItem(hWndLV, &lvii);
  5540. if(lvii.lParam)
  5541. LocalFreeServerItem((LPSERVER_ITEM) lvii.lParam);
  5542. ListView_DeleteItem(hWndLV, lvii.iItem);
  5543. if(lvi.iItem == lpPAI->nDefaultServerIndex)
  5544. StrCpyN(lpPAI->szDefaultServerName,lp,lpPAI->cchDefaultServerName);
  5545. else if(lvi.iItem == lpPAI->nBackupServerIndex)
  5546. StrCpyN(lpPAI->szBackupServerName,lp,lpPAI->cchBackupServerName);
  5547. SendMessage(hDlg, WM_COMMAND, (WPARAM) IDC_DETAILS_NTMTG_BUTTON_CANCELEDIT, 0);
  5548. }
  5549. LVSelectItem(hWndLV, lvi.iItem);
  5550. SendMessage(GetParent(hDlg), DM_SETDEFID, IDOK, 0);
  5551. SetDefaultServer(hDlg, lpPAI, lpPAI->nDefaultServerIndex, TRUE);
  5552. SetBackupServer(hDlg, lpPAI, lpPAI->nBackupServerIndex, FALSE);
  5553. SendMessage(hWndLV, WM_SETREDRAW, (WPARAM) TRUE, 0);
  5554. }
  5555. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_NTMTG_BUTTON_ADDSERVER),FALSE);
  5556. SetFocus(GetDlgItem(hDlg,IDC_DETAILS_NTMTG_EDIT_ADDSERVER));
  5557. }
  5558. UpdateWindow(hWndLV);
  5559. if (lpbSomethingChanged)
  5560. (*lpbSomethingChanged) = TRUE;
  5561. UpdateServerLVButtons(hDlg, lpPAI);
  5562. }
  5563. break;
  5564. case IDC_DETAILS_NTMTG_BUTTON_EDIT:
  5565. {
  5566. HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_NTMTG_LIST_SERVERS);
  5567. if(ListView_GetSelectedCount(hWndLV)==1)
  5568. {
  5569. HWND hWndEditLabel;
  5570. int nItem = ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED);
  5571. {
  5572. LV_ITEM lvi = {0};
  5573. lvi.iItem = nItem;
  5574. lvi.iSubItem = 0;
  5575. lvi.mask = LVIF_PARAM;
  5576. ListView_GetItem(hWndLV, &lvi);
  5577. if(lvi.lParam)
  5578. {
  5579. SetDlgItemText(hDlg, IDC_DETAILS_NTMTG_EDIT_ADDSERVER, (LPTSTR) ((LPSERVER_ITEM)lvi.lParam)->lpServer);
  5580. SetDlgItemText(hDlg, IDC_DETAILS_NTMTG_COMBO_EMAIL, (LPTSTR) ((LPSERVER_ITEM)lvi.lParam)->lpEmail);
  5581. // Remove these items from the ListView
  5582. SetFocus(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_EDIT_ADDSERVER));
  5583. SendMessage(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_EDIT_ADDSERVER), EM_SETSEL, 0, -1);
  5584. lpPAI->ulFlags |= DETAILS_EditingConf;
  5585. lpPAI->nConfEditIndex = nItem;
  5586. ShowWindow(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_BUTTON_CANCELEDIT), SW_SHOW);
  5587. {
  5588. TCHAR sz[MAX_PATH];
  5589. LoadString(hinstMapiX, idsConfUpdate, sz, CharSizeOf(sz));
  5590. SetDlgItemText(hDlg, IDC_DETAILS_NTMTG_BUTTON_ADDSERVER, sz);
  5591. }
  5592. }
  5593. }
  5594. }
  5595. }
  5596. break;
  5597. case IDC_DETAILS_NTMTG_BUTTON_REMOVE:
  5598. {
  5599. HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_NTMTG_LIST_SERVERS);
  5600. int iItemIndex = ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED);
  5601. if(iItemIndex != -1)
  5602. {
  5603. BOOL bDef = (iItemIndex == lpPAI->nDefaultServerIndex) ? TRUE : FALSE;
  5604. BOOL bBck = (iItemIndex == lpPAI->nBackupServerIndex) ? TRUE : FALSE;
  5605. if((lpPAI->ulFlags&DETAILS_EditingConf) && (iItemIndex==lpPAI->nConfEditIndex))
  5606. SendMessage(hDlg, WM_COMMAND, (WPARAM)IDC_DETAILS_NTMTG_BUTTON_CANCELEDIT, 0);
  5607. {
  5608. LV_ITEM lvi = {0};
  5609. lvi.mask = LVIF_PARAM;
  5610. lvi.iItem = iItemIndex; lvi.iSubItem = 0;
  5611. ListView_GetItem(hWndLV, &lvi);
  5612. if(lvi.lParam)
  5613. LocalFreeServerItem((LPSERVER_ITEM) lvi.lParam);
  5614. }
  5615. ListView_DeleteItem(hWndLV, iItemIndex);
  5616. if(ListView_GetSelectedCount(hWndLV) <= 0)
  5617. LVSelectItem(hWndLV, (iItemIndex <= 0) ? iItemIndex : iItemIndex-1);
  5618. if (lpbSomethingChanged)
  5619. (*lpbSomethingChanged) = TRUE;
  5620. if(iItemIndex < lpPAI->nDefaultServerIndex)
  5621. lpPAI->nDefaultServerIndex--;
  5622. if(iItemIndex < lpPAI->nBackupServerIndex)
  5623. lpPAI->nBackupServerIndex--;
  5624. if(bDef)
  5625. {
  5626. lpPAI->nDefaultServerIndex = -1;
  5627. lpPAI->szDefaultServerName[0] = TEXT('\0');
  5628. SetDefaultServer(hDlg, lpPAI, -1, FALSE);
  5629. }
  5630. if(bBck)
  5631. {
  5632. lpPAI->nBackupServerIndex = -1;
  5633. lpPAI->szBackupServerName[0] = TEXT('\0');
  5634. SetBackupServer(hDlg, lpPAI, -1, FALSE);
  5635. }
  5636. if (lpbSomethingChanged)
  5637. (*lpbSomethingChanged) = TRUE;
  5638. }
  5639. UpdateServerLVButtons(hDlg, lpPAI);
  5640. }
  5641. break;
  5642. case IDC_DETAILS_NTMTG_BUTTON_SETDEFAULT:
  5643. SetDefaultServer(hDlg, lpPAI, -1, TRUE);
  5644. if (lpbSomethingChanged)
  5645. (*lpbSomethingChanged) = TRUE;
  5646. break;
  5647. case IDC_DETAILS_NTMTG_BUTTON_SETBACKUP:
  5648. SetBackupServer(hDlg, lpPAI, -1, TRUE);
  5649. if (lpbSomethingChanged)
  5650. (*lpbSomethingChanged) = TRUE;
  5651. break;
  5652. }
  5653. break;
  5654. default:
  5655. #ifndef WIN16 // WIN16 doesn't support MSWheel.
  5656. if((g_msgMSWheel && message == g_msgMSWheel)
  5657. // || message == WM_MOUSEWHEEL
  5658. )
  5659. {
  5660. SendMessage(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_LIST_SERVERS), message, wParam, lParam);
  5661. }
  5662. #endif // !WIN16
  5663. break;
  5664. case WM_NOTIFY:
  5665. switch(((NMHDR FAR *)lParam)->code)
  5666. {
  5667. case PSN_SETACTIVE: //initialize
  5668. FillCertTridentConfDetailsUI(hDlg, lpPAI, propConferencing, lpbSomethingChanged);
  5669. // if this is a readonly entry and there is no data in the listview,
  5670. // disable the call now button
  5671. if( lpPAI->ulOperationType == SHOW_ONE_OFF &&
  5672. ListView_GetItemCount(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_LIST_SERVERS)) <= 0)
  5673. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_NTMTG_BUTTON_CALL), FALSE);
  5674. UpdateServerLVButtons(hDlg, lpPAI);
  5675. //FillComboWithEmailAddresses(lpPAI, lpPAI->hWndComboConf, NULL);
  5676. break;
  5677. case PSN_KILLACTIVE: //Losing activation to another page
  5678. // In case there is something sitting in the edit boxes, add it to the lv
  5679. //
  5680. {
  5681. TCHAR szBuf[MAX_UI_STR], szEmail[MAX_UI_STR];
  5682. GetDlgItemText(hDlg, IDC_DETAILS_NTMTG_EDIT_ADDSERVER, szBuf, CharSizeOf(szBuf));
  5683. TrimSpaces(szBuf);
  5684. GetDlgItemText(hDlg, IDC_DETAILS_NTMTG_COMBO_EMAIL, szEmail, CharSizeOf(szEmail));
  5685. TrimSpaces(szEmail);
  5686. if(lstrlen(szBuf) && lstrlen(szEmail))
  5687. SendMessage(hDlg, WM_COMMAND, (WPARAM) IDC_DETAILS_NTMTG_BUTTON_ADDSERVER, 0);
  5688. }
  5689. bUpdatePropArray(hDlg, lpPAI, propConferencing);
  5690. ClearConfLV(hDlg);
  5691. break;
  5692. case PSN_APPLY: //ok
  5693. //bUpdatePropArray(hDlg, lpPAI, propConferencing);
  5694. //ClearConfLV(hDlg);
  5695. if (lpPAI->nRetVal == DETAILS_RESET)
  5696. lpPAI->nRetVal = DETAILS_OK;
  5697. break;
  5698. case PSN_RESET: //cancel
  5699. if(lpPAI->ulFlags & DETAILS_EditingEmail) //cancel any editing else it faults #30235
  5700. ListView_EditLabel(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_LIST_SERVERS), -1);
  5701. if (lpPAI->nRetVal == DETAILS_RESET)
  5702. lpPAI->nRetVal = DETAILS_CANCEL;
  5703. ClearConfLV(hDlg);
  5704. break;
  5705. case NM_CUSTOMDRAW:
  5706. switch(wParam)
  5707. {
  5708. case IDC_DETAILS_NTMTG_LIST_SERVERS:
  5709. {
  5710. NMCUSTOMDRAW *pnmcd=(NMCUSTOMDRAW*)lParam;
  5711. NM_LISTVIEW * pNm = (NM_LISTVIEW *)lParam;
  5712. if(pnmcd->dwDrawStage==CDDS_PREPAINT)
  5713. {
  5714. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, CDRF_NOTIFYITEMDRAW | CDRF_DODEFAULT);
  5715. return TRUE;
  5716. }
  5717. else if(pnmcd->dwDrawStage==CDDS_ITEMPREPAINT)
  5718. {
  5719. if( pnmcd->dwItemSpec == (DWORD) lpPAI->nDefaultServerIndex ||
  5720. pnmcd->dwItemSpec == (DWORD) lpPAI->nBackupServerIndex )
  5721. {
  5722. SelectObject(((NMLVCUSTOMDRAW*)lParam)->nmcd.hdc, GetFont(fntsSysIconBold));
  5723. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, CDRF_NEWFONT);
  5724. return TRUE;
  5725. }
  5726. }
  5727. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, CDRF_DODEFAULT);
  5728. return TRUE;
  5729. }
  5730. break;
  5731. }
  5732. break;
  5733. case NM_DBLCLK:
  5734. switch(wParam)
  5735. {
  5736. case IDC_DETAILS_NTMTG_LIST_SERVERS:
  5737. SetDefaultServer(hDlg, lpPAI, -1, TRUE);
  5738. if (lpbSomethingChanged)
  5739. (*lpbSomethingChanged) = TRUE;
  5740. break;
  5741. }
  5742. break;
  5743. }
  5744. return TRUE;
  5745. }
  5746. return bRet;
  5747. }
  5748. /*//$$***********************************************************************
  5749. * FUNCTION: AddLVLDAPURLEntry
  5750. *
  5751. * PURPOSE: Takes an LDAP URL, converts it to a MailUser and adds the
  5752. * MailUser to the List View
  5753. *
  5754. ****************************************************************************/
  5755. void AddLVLDAPURLEntry(LPADRBOOK lpAdrBook, HWND hWndLV, LPTSTR lpszLDAPURL)
  5756. {
  5757. LPMAILUSER lpMailUser = NULL;
  5758. HrProcessLDAPUrl(lpAdrBook, GetParent(hWndLV),
  5759. WABOBJECT_LDAPURL_RETURN_MAILUSER,
  5760. lpszLDAPURL,
  5761. &lpMailUser);
  5762. if(lpMailUser)
  5763. {
  5764. LPSPropValue lpPropArray = NULL;
  5765. ULONG ulcProps = 0;
  5766. if(!HR_FAILED(lpMailUser->lpVtbl->GetProps(lpMailUser,
  5767. NULL, MAPI_UNICODE,
  5768. &ulcProps, &lpPropArray)))
  5769. {
  5770. LPRECIPIENT_INFO lpItem = LocalAlloc(LMEM_ZEROINIT, sizeof(RECIPIENT_INFO));
  5771. if (lpItem)
  5772. {
  5773. GetRecipItemFromPropArray(ulcProps, lpPropArray, &lpItem);
  5774. if(lpItem)
  5775. AddSingleItemToListView(hWndLV, lpItem);
  5776. }
  5777. MAPIFreeBuffer(lpPropArray);
  5778. }
  5779. lpMailUser->lpVtbl->Release(lpMailUser);
  5780. }
  5781. }
  5782. /*//$$***********************************************************************
  5783. * FUNCTION: FillOrgData
  5784. *
  5785. * PURPOSE: Fills in LDAP data in the Org prop sheets
  5786. *
  5787. ****************************************************************************/
  5788. void FillOrgData(HWND hDlg, LPPROP_ARRAY_INFO lpPai)
  5789. {
  5790. HWND hWndLVManager = GetDlgItem(hDlg, IDC_DETAILS_ORG_LIST_MANAGER);
  5791. HWND hWndLVReports = GetDlgItem(hDlg, IDC_DETAILS_ORG_LIST_REPORTS);
  5792. ULONG i,j;
  5793. ULONG ulcPropCount = 0;
  5794. LPSPropValue lpPA = NULL;
  5795. HCURSOR hOldCur = SetCursor(LoadCursor(NULL, IDC_WAIT));
  5796. enum _org
  5797. {
  5798. oReports=0,
  5799. oManager,
  5800. oMax
  5801. };
  5802. SizedSPropTagArray(oMax, ptaOrg) =
  5803. {
  5804. oMax,
  5805. {
  5806. PR_WAB_REPORTS,
  5807. PR_WAB_MANAGER
  5808. }
  5809. };
  5810. if(!HR_FAILED(lpPai->lpPropObj->lpVtbl->GetProps(lpPai->lpPropObj,
  5811. (LPSPropTagArray)&ptaOrg,
  5812. MAPI_UNICODE,
  5813. &ulcPropCount, &lpPA)))
  5814. {
  5815. if(lpPA[oReports].ulPropTag == PR_WAB_REPORTS)
  5816. {
  5817. for(j=0;j<lpPA[oReports].Value.MVSZ.cValues;j++)
  5818. {
  5819. AddLVLDAPURLEntry(lpPai->lpIAB, hWndLVReports, lpPA[oReports].Value.MVSZ.LPPSZ[j]);
  5820. }
  5821. }
  5822. if(lpPA[oManager].ulPropTag == PR_WAB_MANAGER)
  5823. {
  5824. AddLVLDAPURLEntry(lpPai->lpIAB, hWndLVManager, lpPA[oManager].Value.LPSZ);
  5825. }
  5826. }
  5827. if(ListView_GetItemCount(hWndLVManager) > 0)
  5828. LVSelectItem(hWndLVManager, 0);
  5829. else
  5830. EnableWindow(hWndLVManager, FALSE);
  5831. if(ListView_GetItemCount(hWndLVReports) > 0)
  5832. LVSelectItem(hWndLVReports, 0);
  5833. else
  5834. EnableWindow(hWndLVReports, FALSE);
  5835. if(lpPA)
  5836. MAPIFreeBuffer(lpPA);
  5837. SetCursor(hOldCur);
  5838. }
  5839. /*//$$***********************************************************************
  5840. *
  5841. * FUNCTION: FreeOrgLVData
  5842. *
  5843. * PURPOSE: Frees the Data from the Org LVs
  5844. *
  5845. ****************************************************************************/
  5846. void FreeOrgLVData(HWND hWndLV)
  5847. {
  5848. int i=0, nCount=ListView_GetItemCount(hWndLV);
  5849. for(i=0;i<nCount;i++)
  5850. {
  5851. LV_ITEM lvi = {0};
  5852. lvi.mask = LVIF_PARAM;
  5853. lvi.iItem = i;
  5854. ListView_GetItem(hWndLV, &lvi);
  5855. if(lvi.lParam)
  5856. {
  5857. LPRECIPIENT_INFO lpItem = (LPRECIPIENT_INFO) lvi.lParam;
  5858. FreeRecipItem(&lpItem);
  5859. }
  5860. }
  5861. }
  5862. /*//$$***********************************************************************
  5863. * FUNCTION: fnOrgProc
  5864. *
  5865. * PURPOSE: Callback function for handling the Organization Prop Sheets
  5866. *
  5867. ****************************************************************************/
  5868. INT_PTR CALLBACK fnOrgProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)
  5869. {
  5870. PROPSHEETPAGE * pps;
  5871. BOOL bRet = FALSE;
  5872. pps = (PROPSHEETPAGE *) GetWindowLongPtr(hDlg, DWLP_USER);
  5873. switch(message)
  5874. {
  5875. case WM_INITDIALOG:
  5876. SetWindowLongPtr(hDlg,DWLP_USER,lParam);
  5877. pps = (PROPSHEETPAGE *) lParam;
  5878. HrInitListView(GetDlgItem(hDlg, IDC_DETAILS_ORG_LIST_MANAGER), LVS_REPORT, FALSE);
  5879. HrInitListView(GetDlgItem(hDlg, IDC_DETAILS_ORG_LIST_REPORTS), LVS_REPORT, FALSE);
  5880. UpdateWindow(hDlg);
  5881. FillOrgData(hDlg, lpPAI);
  5882. return TRUE;
  5883. case WM_HELP:
  5884. WABWinHelp(((LPHELPINFO)lParam)->hItemHandle,
  5885. g_szWABHelpFileName,
  5886. HELP_WM_HELP,
  5887. (DWORD_PTR)(LPSTR) rgDetlsHelpIDs );
  5888. break;
  5889. case WM_CONTEXTMENU:
  5890. WABWinHelp((HWND) wParam,
  5891. g_szWABHelpFileName,
  5892. HELP_CONTEXTMENU,
  5893. (DWORD_PTR)(LPVOID) rgDetlsHelpIDs );
  5894. break;
  5895. case WM_COMMAND:
  5896. switch(LOWORD(wParam))
  5897. {
  5898. case IDCANCEL:
  5899. // This is a windows bug that prevents ESC canceling prop sheets
  5900. // which have MultiLine Edit boxes KB: Q130765
  5901. SendMessage(GetParent(hDlg),message,wParam,lParam);
  5902. break;
  5903. }
  5904. break;
  5905. case WM_NOTIFY:
  5906. switch(((NMHDR FAR *)lParam)->code)
  5907. {
  5908. case PSN_SETACTIVE: //initialize
  5909. break;
  5910. case PSN_KILLACTIVE: //Losing activation to another page
  5911. break;
  5912. case PSN_APPLY: //ok
  5913. lpPAI->nRetVal = DETAILS_OK;
  5914. case PSN_RESET: //cancel
  5915. FreeOrgLVData(GetDlgItem(hDlg, IDC_DETAILS_ORG_LIST_MANAGER));
  5916. FreeOrgLVData(GetDlgItem(hDlg, IDC_DETAILS_ORG_LIST_REPORTS));
  5917. if (lpPAI->nRetVal == DETAILS_RESET)
  5918. lpPAI->nRetVal = DETAILS_CANCEL;
  5919. break;
  5920. // if enter pressed ...
  5921. case LVN_KEYDOWN:
  5922. if(((LV_KEYDOWN FAR *) lParam)->wVKey != VK_RETURN)
  5923. break;
  5924. // else fall thru
  5925. case NM_DBLCLK:
  5926. switch(wParam)
  5927. {
  5928. case IDC_DETAILS_ORG_LIST_MANAGER:
  5929. case IDC_DETAILS_ORG_LIST_REPORTS:
  5930. {
  5931. NM_LISTVIEW * pNm = (NM_LISTVIEW *)lParam;
  5932. if (ListView_GetSelectedCount(pNm->hdr.hwndFrom) == 1)
  5933. HrShowLVEntryProperties(pNm->hdr.hwndFrom, 0, lpPAI->lpIAB,NULL);
  5934. }
  5935. break;
  5936. }
  5937. break;
  5938. } //WM_NOTIFY
  5939. return TRUE;
  5940. }
  5941. return bRet;
  5942. }
  5943. void LocalFreeServerItem(LPSERVER_ITEM lpSI)
  5944. {
  5945. if(lpSI)
  5946. {
  5947. if(lpSI->lpServer)
  5948. LocalFree((LPVOID) lpSI->lpServer);
  5949. if(lpSI->lpEmail)
  5950. LocalFree((LPVOID) lpSI->lpEmail);
  5951. LocalFree((LPVOID) lpSI);
  5952. }
  5953. }
  5954. /*//$$***********************************************************************
  5955. * FUNCTION: fnSummaryProc
  5956. *
  5957. *
  5958. ****************************************************************************/
  5959. void UpdateSummaryInfo(HWND hDlg, LPPROP_ARRAY_INFO lpPai)
  5960. {
  5961. ULONG cValues = 0, i = 0, j = 0;
  5962. LPSPropValue lpPropArray = NULL;
  5963. BOOL bFoundEmail = FALSE;
  5964. BOOL bFoundHomeURL = FALSE;
  5965. BOOL bFoundBusURL = FALSE;
  5966. ULONG ulPropTag;
  5967. HWND hURLBtn;
  5968. if(!lpPai->lpPropObj)
  5969. goto out;
  5970. if (HR_FAILED(lpPai->lpPropObj->lpVtbl->GetProps(lpPai->lpPropObj,
  5971. (LPSPropTagArray) &ptaUIDetlsPropsSummary, MAPI_UNICODE,
  5972. &cValues,
  5973. &lpPropArray)))
  5974. {
  5975. goto out;
  5976. }
  5977. for(i=0;i<MAX_SUMMARY_ID;i++)
  5978. {
  5979. SetDlgItemText(hDlg, rgSummaryIDs[i], szEmpty);
  5980. for(j=0;j<cValues;j++)
  5981. {
  5982. ulPropTag = lpPropArray[j].ulPropTag;
  5983. if( ulPropTag == PR_DISPLAY_NAME)
  5984. {
  5985. SetWindowPropertiesTitle(GetParent(hDlg), lpPropArray[j].Value.LPSZ);
  5986. }
  5987. if(ulPropTag == ((LPSPropTagArray) &ptaUIDetlsPropsSummary)->aulPropTag[i])
  5988. {
  5989. if(ulPropTag == PR_EMAIL_ADDRESS)
  5990. bFoundEmail = TRUE;
  5991. else if(ulPropTag == PR_PERSONAL_HOME_PAGE )
  5992. bFoundHomeURL = TRUE;
  5993. else if( ulPropTag == PR_BUSINESS_HOME_PAGE )
  5994. bFoundBusURL = TRUE;
  5995. SetDlgItemText(hDlg, rgSummaryIDs[i], lpPropArray[j].Value.LPSZ);
  5996. break;
  5997. }
  5998. }
  5999. }
  6000. hURLBtn = GetDlgItem( hDlg, IDC_DETAILS_HOME_BUTTON_URL);
  6001. if( bFoundHomeURL )
  6002. {
  6003. // enable and show button
  6004. ShowWindow(hURLBtn, SW_SHOW);
  6005. SendMessage(hURLBtn, WM_ENABLE, (WPARAM)(TRUE), (LPARAM)(0) );
  6006. }
  6007. else
  6008. {
  6009. // hide and disable button
  6010. ShowWindow(hURLBtn, SW_HIDE);
  6011. SendMessage(hURLBtn, WM_ENABLE, (WPARAM)(FALSE), (LPARAM)(0) );
  6012. }
  6013. hURLBtn = GetDlgItem( hDlg, IDC_DETAILS_BUSINESS_BUTTON_URL);
  6014. if( bFoundBusURL )
  6015. {
  6016. // enable and show button
  6017. ShowWindow(hURLBtn, SW_SHOW);
  6018. SendMessage(hURLBtn, WM_ENABLE, (WPARAM)(TRUE), (LPARAM)(0) );
  6019. }
  6020. else
  6021. {
  6022. // hide and disable button
  6023. ShowWindow(hURLBtn, SW_HIDE);
  6024. SendMessage(hURLBtn, WM_ENABLE, (WPARAM)(FALSE), (LPARAM)(0) );
  6025. }
  6026. if(!bFoundEmail)
  6027. {
  6028. // Look for Contact_Email_Addresses and DefaultIndex
  6029. ULONG nEmails = 0xFFFFFFFF, nDef = 0xFFFFFFFF;
  6030. for(i=0;i<cValues;i++)
  6031. {
  6032. if(lpPropArray[i].ulPropTag == PR_CONTACT_EMAIL_ADDRESSES)
  6033. nEmails = i;
  6034. if(lpPropArray[i].ulPropTag == PR_CONTACT_DEFAULT_ADDRESS_INDEX)
  6035. nDef = i;
  6036. }
  6037. if(nEmails != 0xFFFFFFFF)
  6038. SetDlgItemText( hDlg, IDC_DETAILS_SUMMARY_STATIC_EMAIL,
  6039. lpPropArray[nEmails].Value.MVSZ.LPPSZ[(nDef != 0xFFFFFFFF ? lpPropArray[nDef].Value.l : 0)]);
  6040. }
  6041. out:
  6042. if(lpPropArray)
  6043. MAPIFreeBuffer(lpPropArray);
  6044. return;
  6045. }
  6046. /*//$$***********************************************************************
  6047. * FUNCTION: fnSummaryProc
  6048. *
  6049. *
  6050. ****************************************************************************/
  6051. INT_PTR CALLBACK fnSummaryProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)
  6052. {
  6053. PROPSHEETPAGE * pps;
  6054. BOOL bRet = FALSE;
  6055. pps = (PROPSHEETPAGE *) GetWindowLongPtr(hDlg, DWLP_USER);
  6056. switch(message)
  6057. {
  6058. case WM_INITDIALOG:
  6059. {
  6060. EnumChildWindows( hDlg, SetChildDefaultGUIFont, (LPARAM) 0);
  6061. SetWindowLongPtr(hDlg,DWLP_USER,lParam);
  6062. pps = (PROPSHEETPAGE *) lParam;
  6063. if (lpPAI->ulOperationType != SHOW_ONE_OFF ||
  6064. lpPAI->ulFlags & DETAILS_HideAddToWABButton)
  6065. {
  6066. HWND hwnd = GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_BUTTON_ADDTOWAB);
  6067. EnableWindow(hwnd, FALSE);
  6068. ShowWindow(hwnd, SW_HIDE);
  6069. }
  6070. if (lpPAI->ulOperationType == SHOW_ONE_OFF)
  6071. EnableWindow(GetDlgItem(GetParent(hDlg), IDOK), FALSE);
  6072. return TRUE;
  6073. }
  6074. break;
  6075. case WM_HELP:
  6076. WABWinHelp(((LPHELPINFO)lParam)->hItemHandle,
  6077. g_szWABHelpFileName,
  6078. HELP_WM_HELP,
  6079. (DWORD_PTR)(LPSTR) rgDetlsHelpIDs );
  6080. break;
  6081. case WM_CONTEXTMENU:
  6082. WABWinHelp((HWND) wParam,
  6083. g_szWABHelpFileName,
  6084. HELP_CONTEXTMENU,
  6085. (DWORD_PTR)(LPVOID) rgDetlsHelpIDs );
  6086. break;
  6087. case WM_COMMAND:
  6088. switch(GET_WM_COMMAND_ID(wParam, lParam))
  6089. {
  6090. case IDC_DETAILS_PERSONAL_BUTTON_ADDTOWAB:
  6091. lpPAI->nRetVal = DETAILS_ADDTOWAB;
  6092. SendMessage(GetParent(hDlg), WM_COMMAND, (WPARAM) IDCANCEL, 0);
  6093. break;
  6094. case IDCANCEL:
  6095. // This is a windows bug that prevents ESC canceling prop sheets
  6096. // which have MultiLine Edit boxes KB: Q130765
  6097. SendMessage(GetParent(hDlg),message,wParam,lParam);
  6098. break;
  6099. case IDC_DETAILS_HOME_BUTTON_URL:
  6100. ShowURL(hDlg, IDC_DETAILS_SUMMARY_STATIC_PERSONALWEB,NULL);
  6101. break;
  6102. case IDC_DETAILS_BUSINESS_BUTTON_URL:
  6103. ShowURL(hDlg, IDC_DETAILS_SUMMARY_STATIC_BUSINESSWEB,NULL);
  6104. break;
  6105. }
  6106. break;
  6107. case WM_NOTIFY:
  6108. switch(((NMHDR FAR *)lParam)->code)
  6109. {
  6110. case PSN_SETACTIVE: //initialize
  6111. UpdateSummaryInfo(hDlg, lpPAI);
  6112. break;
  6113. case PSN_APPLY: //ok
  6114. // in case any of the extended props changed, we need to mark this flag so we wont lose data
  6115. if(lpbSomethingChanged)
  6116. (*lpbSomethingChanged) = ChangedExtDisplayInfo(lpPAI, (*lpbSomethingChanged));
  6117. if (lpPAI->nRetVal == DETAILS_RESET)
  6118. lpPAI->nRetVal = DETAILS_OK;
  6119. break;
  6120. case PSN_KILLACTIVE: //Losing activation to another page
  6121. break;
  6122. case PSN_RESET: //cancel
  6123. if (lpPAI->nRetVal == DETAILS_RESET)
  6124. lpPAI->nRetVal = DETAILS_CANCEL;
  6125. break;
  6126. }
  6127. return TRUE;
  6128. }
  6129. return bRet;
  6130. }
  6131. /*//$$***************************************************************************
  6132. * FUNCTION: FillPersonalDetails(HWND)
  6133. *
  6134. * PURPOSE: Fills in the dialog items on the property sheet
  6135. *
  6136. ****************************************************************************/
  6137. BOOL FillPersonalDetails(HWND hDlg, LPPROP_ARRAY_INFO lpPai, int nPropSheet, BOOL * lpbChangesMade)
  6138. {
  6139. ULONG i = 0,j = 0;
  6140. BOOL bRet = FALSE;
  6141. LPTSTR lpszDisplayName = NULL, lpszFirstName = NULL, lpszLastName = NULL;
  6142. LPTSTR lpszMiddleName = NULL, lpszNickName = NULL, lpszCompanyName = NULL;
  6143. BOOL bChangesMade = FALSE;
  6144. ID_PROP * lpidProp = NULL;
  6145. ULONG idPropCount = 0;
  6146. LPVOID lpBuffer = NULL;
  6147. BOOL bRichInfo = FALSE;
  6148. ULONG ulcPropCount = 0;
  6149. LPSPropValue lpPropArray = NULL;
  6150. SizedSPropTagArray(14, ptaUIDetlsPropsPersonal)=
  6151. {
  6152. 14,
  6153. {
  6154. PR_DISPLAY_NAME,
  6155. PR_EMAIL_ADDRESS,
  6156. PR_ADDRTYPE,
  6157. PR_CONTACT_EMAIL_ADDRESSES,
  6158. PR_CONTACT_ADDRTYPES,
  6159. PR_CONTACT_DEFAULT_ADDRESS_INDEX,
  6160. PR_GIVEN_NAME,
  6161. PR_SURNAME,
  6162. PR_MIDDLE_NAME,
  6163. PR_NICKNAME,
  6164. PR_SEND_INTERNET_ENCODING,
  6165. PR_DISPLAY_NAME_PREFIX,
  6166. PR_WAB_YOMI_FIRSTNAME,
  6167. PR_WAB_YOMI_LASTNAME
  6168. }
  6169. };
  6170. if(HR_FAILED(lpPai->lpPropObj->lpVtbl->GetProps(lpPai->lpPropObj,
  6171. (LPSPropTagArray)&ptaUIDetlsPropsPersonal,
  6172. MAPI_UNICODE,
  6173. &ulcPropCount, &lpPropArray)))
  6174. goto out;
  6175. lpPai->ulFlags |= DETAILS_Initializing;
  6176. // Set the flag that this sheet was opened
  6177. lpPai->bPropSheetOpened[nPropSheet] = TRUE;
  6178. // Check the check box on the UI for whether this contact can receive rich email messages
  6179. for(i=0;i<ulcPropCount;i++)
  6180. {
  6181. if(lpPropArray[i].ulPropTag == PR_SEND_INTERNET_ENCODING)
  6182. {
  6183. //Check the check box on the UI if no value is chosen for BODY_ENCODING_HTML
  6184. // Bug 2285: wabtags.h had the wrong tag for BODY_ENCODING_HTML .. it was set to
  6185. // be the same as BODY_ENCODING_TEXT_AND_HTML instead .. hence for backward compatibility
  6186. // we have to also check for BODY_ENCODING_TEXT_AND_HTML here and then when
  6187. // saving have to set it back to BODY_ENCODING_HTML ..
  6188. int id = (lpPropArray[i].Value.l & BODY_ENCODING_HTML ||
  6189. lpPropArray[i].Value.l & BODY_ENCODING_TEXT_AND_HTML)
  6190. ? BST_UNCHECKED : BST_CHECKED;
  6191. CheckDlgButton(hDlg, IDC_DETAILS_PERSONAL_CHECK_RICHINFO, id);
  6192. bRichInfo = TRUE;
  6193. break;
  6194. }
  6195. }
  6196. // if we didnt find the PR_SEND_INTERNET_ENCODING, we want to force a save on this contact
  6197. // if the contact is writable ...
  6198. if(!bRichInfo && lpPai->ulOperationType != SHOW_ONE_OFF)
  6199. *lpbChangesMade = TRUE;
  6200. for(i=0;i<ulcPropCount;i++)
  6201. {
  6202. switch(lpPropArray[i].ulPropTag)
  6203. {
  6204. case PR_DISPLAY_NAME:
  6205. lpszDisplayName = lpPropArray[i].Value.LPSZ;
  6206. break;
  6207. case PR_GIVEN_NAME:
  6208. lpszFirstName = lpPropArray[i].Value.LPSZ;
  6209. break;
  6210. case PR_SURNAME:
  6211. lpszLastName = lpPropArray[i].Value.LPSZ;
  6212. break;
  6213. case PR_MIDDLE_NAME:
  6214. lpszMiddleName = lpPropArray[i].Value.LPSZ;
  6215. break;
  6216. case PR_NICKNAME:
  6217. lpszNickName = lpPropArray[i].Value.LPSZ;
  6218. break;
  6219. case PR_COMPANY_NAME:
  6220. lpszCompanyName = lpPropArray[i].Value.LPSZ;
  6221. break;
  6222. }
  6223. }
  6224. /*
  6225. *
  6226. * At this point we always have a display name. We need to track how this
  6227. * display name relates to F/M/L/Nick/Company
  6228. *
  6229. * So we check if
  6230. * Display Name == Nick Name
  6231. * Display Name == Company Name
  6232. * Display Name == FML
  6233. */
  6234. // Check if Display Name was created from First Middle Last
  6235. if( (lpszFirstName && lstrlen(lpszFirstName)) ||
  6236. (lpszMiddleName && lstrlen(lpszMiddleName)) ||
  6237. (lpszLastName && lstrlen(lpszLastName)) )
  6238. {
  6239. ULONG ulSzBuf = 4*MAX_BUF_STR;
  6240. LPTSTR szBuf = LocalAlloc(LMEM_ZEROINIT, ulSzBuf*sizeof(TCHAR));
  6241. LPTSTR lpszTmp = szBuf;
  6242. if(!szBuf)
  6243. goto out;
  6244. if(!SetLocalizedDisplayName(lpszFirstName,
  6245. lpszMiddleName,
  6246. lpszLastName,
  6247. NULL, // Company Name (not needed)
  6248. NULL, // Nick Name (not needed here)
  6249. (LPTSTR *) &lpszTmp, //&szBuf,
  6250. ulSzBuf,
  6251. bDNisByLN,
  6252. NULL,
  6253. NULL))
  6254. {
  6255. //TBD - do we really want to fail here .. ???
  6256. LocalFreeAndNull(&szBuf);
  6257. DebugPrintTrace(( TEXT("SetLocalizedDisplayName failed\n")));
  6258. goto out;
  6259. }
  6260. if(lpszDisplayName && szBuf && !lstrcmp(lpszDisplayName, szBuf))
  6261. lpPai->ulFlags |= DETAILS_DNisFMLName;
  6262. else
  6263. lpPai->ulFlags &= ~DETAILS_DNisFMLName;
  6264. LocalFreeAndNull(&szBuf);
  6265. }
  6266. // if DN was not created from FML ..
  6267. if(!(lpPai->ulFlags & DETAILS_DNisFMLName) )
  6268. {
  6269. // Check if DN == NickName
  6270. if(lpszNickName)
  6271. {
  6272. if(!lstrlen(lpszDisplayName))
  6273. lpszDisplayName = lpszNickName;
  6274. if(!lstrcmp(lpszDisplayName, lpszNickName))
  6275. lpPai->ulFlags |= DETAILS_DNisNickName;
  6276. else
  6277. lpPai->ulFlags &= ~DETAILS_DNisNickName;
  6278. }
  6279. // Check if DN == Company Name
  6280. if(lpszCompanyName)
  6281. {
  6282. if(!lstrlen(lpszDisplayName))
  6283. lpszDisplayName = lpszCompanyName;
  6284. if(!lstrcmp(lpszDisplayName, lpszCompanyName))
  6285. lpPai->ulFlags |= DETAILS_DNisCompanyName;
  6286. else
  6287. lpPai->ulFlags &= ~DETAILS_DNisCompanyName;
  6288. }
  6289. }
  6290. else
  6291. {
  6292. lpPai->ulFlags &= ~DETAILS_DNisNickName;
  6293. lpPai->ulFlags &= ~DETAILS_DNisCompanyName;
  6294. }
  6295. // if DN is none of the above and there is no FML,
  6296. // parse the DN into F and L
  6297. //
  6298. if ( !lpszFirstName &&
  6299. !lpszLastName &&
  6300. !lpszMiddleName &&
  6301. !(lpPai->ulFlags & DETAILS_DNisCompanyName) &&
  6302. !(lpPai->ulFlags & DETAILS_DNisNickName) )
  6303. {
  6304. bChangesMade = ParseDisplayName(
  6305. lpszDisplayName,
  6306. &lpszFirstName,
  6307. &lpszLastName,
  6308. NULL, // lpvRoot
  6309. &lpBuffer); // lppLocalFree
  6310. lpPai->ulFlags |= DETAILS_DNisFMLName;
  6311. }
  6312. // Set the Dialog title to reflect the display name
  6313. SetWindowPropertiesTitle(GetParent(hDlg), lpszDisplayName ? lpszDisplayName : szEmpty);
  6314. //////////////////////////
  6315. // A very inefficient and lazy way of filling the UI
  6316. // but works for now
  6317. //
  6318. for(i=0;i<idPropPersonalCount;i++)
  6319. {
  6320. for(j=0;j<ulcPropCount;j++)
  6321. {
  6322. if(lpPropArray[j].ulPropTag == idPropPersonal[i].ulPropTag)
  6323. SetDlgItemText(hDlg, idPropPersonal[i].idCtl, lpPropArray[j].Value.LPSZ);
  6324. }
  6325. }
  6326. // Add the Yomi prop data
  6327. for(j=0;j<ulcPropCount;j++)
  6328. {
  6329. if(lpPropArray[j].ulPropTag == PR_WAB_YOMI_FIRSTNAME)
  6330. SetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_STATIC_RUBYFIRST, lpPropArray[j].Value.LPSZ);
  6331. if(lpPropArray[j].ulPropTag == PR_WAB_YOMI_LASTNAME)
  6332. SetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_STATIC_RUBYLAST, lpPropArray[j].Value.LPSZ);
  6333. }
  6334. // Overwrite the first last name with out pre calculated values
  6335. if (lpszFirstName)
  6336. SetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_EDIT_FIRSTNAME, lpszFirstName);
  6337. if (lpszLastName)
  6338. SetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_EDIT_LASTNAME, lpszLastName);
  6339. // Fill the Combo
  6340. SetComboDNText(hDlg, NULL, FALSE, lpszDisplayName);
  6341. {
  6342. //
  6343. // Now we fill in the Email addresses .. bunch of cases can exist in here
  6344. // Single email, multiple email, no email etc ...
  6345. //
  6346. // First we search for all the props we need to fill in the email structure
  6347. //
  6348. LPSPropValue lpPropEmail = NULL;
  6349. LPSPropValue lpPropAddrType = NULL;
  6350. LPSPropValue lpPropMVEmail = NULL;
  6351. LPSPropValue lpPropMVAddrType = NULL;
  6352. LPSPropValue lpPropDefaultIndex = NULL;
  6353. BOOL bDefaultSet = FALSE;
  6354. HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_LIST);
  6355. for(i=0;i<ulcPropCount;i++)
  6356. {
  6357. switch(lpPropArray[i].ulPropTag)
  6358. {
  6359. case PR_EMAIL_ADDRESS:
  6360. lpPropEmail = &(lpPropArray[i]);
  6361. break;
  6362. case PR_ADDRTYPE:
  6363. lpPropAddrType = &(lpPropArray[i]);
  6364. break;
  6365. case PR_CONTACT_EMAIL_ADDRESSES:
  6366. lpPropMVEmail = &(lpPropArray[i]);
  6367. break;
  6368. case PR_CONTACT_ADDRTYPES:
  6369. lpPropMVAddrType = &(lpPropArray[i]);
  6370. break;
  6371. case PR_CONTACT_DEFAULT_ADDRESS_INDEX:
  6372. lpPropDefaultIndex = &(lpPropArray[i]);
  6373. break;
  6374. }
  6375. }
  6376. // Assumption:
  6377. // We must have a email address to work with even if we dont have
  6378. // multiple email addresses
  6379. if(lpPropEmail || lpPropMVEmail)
  6380. {
  6381. if(lpPropMVEmail)
  6382. {
  6383. // Assert(lpPropMVAddrType);
  6384. //Assume, if this is present, so is MVAddrType, and defaultindex
  6385. for(i=0;i<lpPropMVEmail->Value.MVSZ.cValues;i++)
  6386. {
  6387. AddLVEmailItem( hWndLV,
  6388. lpPropMVEmail->Value.MVSZ.LPPSZ[i],
  6389. lpPropMVAddrType ? ((lpPropMVAddrType->Value.MVSZ.cValues > i) ?
  6390. lpPropMVAddrType->Value.MVSZ.LPPSZ[i] : (LPTSTR)szSMTP) : (LPTSTR)szSMTP);
  6391. if ( lpPropDefaultIndex && (i == (ULONG) lpPropDefaultIndex->Value.l) )
  6392. {
  6393. // This is the default one so set it ...
  6394. SetLVDefaultEmail( hWndLV, i );
  6395. }
  6396. }
  6397. }
  6398. else
  6399. {
  6400. LPTSTR lpszAddrType = NULL;
  6401. // we dont have multi-valued props yet - lets use the
  6402. // single valued ones and tag a change so that the record is
  6403. // updated ...
  6404. if (lpPropAddrType)
  6405. lpszAddrType = lpPropAddrType->Value.LPSZ;
  6406. AddLVEmailItem( hWndLV,
  6407. lpPropEmail->Value.LPSZ,
  6408. lpszAddrType);
  6409. // Flag that changes occured ...
  6410. bChangesMade = TRUE;
  6411. }
  6412. if((ListView_GetItemCount(hWndLV)>0)&&(lpPai->ulOperationType != SHOW_ONE_OFF))
  6413. {
  6414. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_REMOVE),TRUE);
  6415. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_SETDEFAULT),TRUE);
  6416. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_EDIT),TRUE);
  6417. }
  6418. }
  6419. }
  6420. if(!*lpbChangesMade)
  6421. *lpbChangesMade = bChangesMade;
  6422. bRet = TRUE;
  6423. out:
  6424. if(lpBuffer)
  6425. LocalFreeAndNull(&lpBuffer);
  6426. if(lpPropArray)
  6427. MAPIFreeBuffer(lpPropArray);
  6428. lpPai->ulFlags &= ~DETAILS_Initializing;
  6429. return bRet;
  6430. }
  6431. /*//$$***************************************************************************
  6432. * FUNCTION: FillHomeBusinessNotesDetailsUI(HWND)
  6433. *
  6434. * PURPOSE: Fills in the dialog items on the property sheet
  6435. *
  6436. ****************************************************************************/
  6437. BOOL FillHomeBusinessNotesDetailsUI(HWND hDlg, LPPROP_ARRAY_INFO lpPai, int nPropSheet, BOOL * lpbChangesMade)
  6438. {
  6439. ULONG i = 0,j = 0;
  6440. BOOL bRet = FALSE;
  6441. BOOL bChangesMade = FALSE;
  6442. ID_PROP * lpidProp = NULL;
  6443. ULONG idPropCount = 0;
  6444. LPVOID lpBuffer = NULL;
  6445. ULONG ulcPropCount = 0;
  6446. LPSPropValue lpPropArray = NULL;
  6447. if(HR_FAILED(lpPai->lpPropObj->lpVtbl->GetProps(lpPai->lpPropObj, NULL, MAPI_UNICODE,
  6448. &ulcPropCount, &lpPropArray)))
  6449. goto out;
  6450. lpPai->ulFlags |= DETAILS_Initializing;
  6451. // Set the flag that this sheet was opened
  6452. lpPai->bPropSheetOpened[nPropSheet] = TRUE;
  6453. switch(nPropSheet)
  6454. {
  6455. /************/
  6456. case propHome:
  6457. idPropCount = idPropHomeCount;
  6458. lpidProp = idPropHome;
  6459. lpidProp[idPropHomePostalID].ulPropTag = PR_WAB_POSTALID;
  6460. goto FillProp;
  6461. /************/
  6462. case propBusiness:
  6463. idPropCount = idPropBusinessCount;
  6464. lpidProp = idPropBusiness;
  6465. lpidProp[idPropBusIPPhone].ulPropTag = PR_WAB_IPPHONE;
  6466. lpidProp[idPropBusPostalID].ulPropTag = PR_WAB_POSTALID;
  6467. goto FillProp;
  6468. /************/
  6469. case propNotes:
  6470. {
  6471. // See if this is a folder member and update the folder name on this tab
  6472. BOOL bParent = FALSE;
  6473. if( lpPai->ulOperationType != SHOW_DETAILS )
  6474. {
  6475. SetDlgItemText(hDlg, IDC_DETAILS_NOTES_STATIC_FOLDER, szEmpty);
  6476. }
  6477. else
  6478. {
  6479. for(i=0;i<ulcPropCount;i++)
  6480. {
  6481. if(lpPropArray[i].ulPropTag == PR_WAB_FOLDER_PARENT || lpPropArray[i].ulPropTag == PR_WAB_FOLDER_PARENT_OLDPROP)
  6482. {
  6483. LPSBinary lpsbParent = &(lpPropArray[i].Value.MVbin.lpbin[0]);
  6484. LPWABFOLDER lpWABFolder = FindWABFolder((LPIAB)lpPai->lpIAB, lpsbParent, NULL, NULL);
  6485. if(lpWABFolder) // note if we didnt find the folder then the default TEXT("Shared Contacts") name works fine
  6486. {
  6487. SetDlgItemText(hDlg, IDC_DETAILS_NOTES_STATIC_FOLDER, lpWABFolder->lpFolderName);
  6488. bParent = TRUE;
  6489. }
  6490. break;
  6491. }
  6492. }
  6493. }
  6494. if(!bParent && !bDoesThisWABHaveAnyUsers((LPIAB)lpPai->lpIAB))
  6495. {
  6496. TCHAR sz[MAX_PATH];
  6497. LoadString(hinstMapiX, idsContacts, sz, CharSizeOf(sz));
  6498. SetDlgItemText(hDlg, IDC_DETAILS_NOTES_STATIC_FOLDER, sz);
  6499. }
  6500. // Find out all the groups in which this contact is a member ...
  6501. //
  6502. // if this is not a known entry id but is still non NULL ..
  6503. //
  6504. if( (0 == IsWABEntryID(lpPai->cbEntryID, lpPai->lpEntryID, NULL,NULL,NULL, NULL, NULL)) &&
  6505. lpPai->cbEntryID && lpPai->lpEntryID)
  6506. {
  6507. // Only do this for WAB contacts
  6508. TCHAR szBuf[MAX_BUF_STR];
  6509. SPropertyRestriction PropRes = {0};
  6510. SPropValue sp = {0};
  6511. HRESULT hr = E_FAIL;
  6512. ULONG ulcCount = 0;
  6513. LPSBinary rgsbEntryIDs = NULL;
  6514. sp.ulPropTag = PR_OBJECT_TYPE;
  6515. sp.Value.l = MAPI_DISTLIST;
  6516. PropRes.ulPropTag = PR_OBJECT_TYPE;
  6517. PropRes.relop = RELOP_EQ;
  6518. PropRes.lpProp = &sp;
  6519. szBuf[0] = TEXT('\0');
  6520. // BUGBUG <JasonSo>: Need to pass in the current container here...
  6521. hr = FindRecords( ((LPIAB)lpPai->lpIAB)->lpPropertyStore->hPropertyStore,
  6522. NULL, 0, TRUE, &PropRes, &ulcCount, &rgsbEntryIDs);
  6523. if(!HR_FAILED(hr) && ulcCount)
  6524. {
  6525. // Open all the groups and look at their contents
  6526. ULONG i,j,k;
  6527. for(i=0;i<ulcCount;i++)
  6528. {
  6529. ULONG ulcValues = 0;
  6530. LPSPropValue lpProps = NULL;
  6531. LPTSTR lpszName = NULL;
  6532. hr = HrGetPropArray(lpPai->lpIAB, NULL,
  6533. rgsbEntryIDs[i].cb, (LPENTRYID) rgsbEntryIDs[i].lpb,
  6534. MAPI_UNICODE,
  6535. &ulcValues, &lpProps);
  6536. if(HR_FAILED(hr))
  6537. continue;
  6538. for(j=0;j<ulcValues;j++)
  6539. {
  6540. if (lpProps[j].ulPropTag == PR_DISPLAY_NAME)
  6541. {
  6542. lpszName = lpProps[j].Value.LPSZ;
  6543. break;
  6544. }
  6545. }
  6546. for(j=0;j<ulcValues;j++)
  6547. {
  6548. if(lpProps[j].ulPropTag == PR_WAB_DL_ENTRIES)
  6549. {
  6550. // Look at each entry in the PR_WAB_DL_ENTRIES and recursively check it.
  6551. for (k = 0; k < lpProps[j].Value.MVbin.cValues; k++)
  6552. {
  6553. ULONG cbEID = lpProps[j].Value.MVbin.lpbin[k].cb;
  6554. LPENTRYID lpEID = (LPENTRYID) lpProps[j].Value.MVbin.lpbin[k].lpb;
  6555. if (cbEID == lpPai->cbEntryID) // <TBD> we should be checking if its a wab entryid
  6556. // but we'll just compare sizes for now ...
  6557. {
  6558. if(!memcmp(lpPai->lpEntryID, lpEID, cbEID))
  6559. {
  6560. if( (lstrlen(szCRLF) + lstrlen(szBuf) + lstrlen(lpszName) + 1)<CharSizeOf(szBuf))
  6561. {
  6562. StrCatBuff(szBuf, lpszName, ARRAYSIZE(szBuf));
  6563. StrCatBuff(szBuf, szCRLF, ARRAYSIZE(szBuf));
  6564. break;
  6565. }
  6566. }
  6567. }
  6568. }
  6569. break; // just wanted to look at PR_WAB_DL_ENTRIES
  6570. }
  6571. } // for (j...
  6572. if(lpProps)
  6573. MAPIFreeBuffer(lpProps);
  6574. } // for(i...
  6575. } ///if ..
  6576. FreeEntryIDs(((LPIAB)lpPai->lpIAB)->lpPropertyStore->hPropertyStore,
  6577. ulcCount,
  6578. rgsbEntryIDs);
  6579. if(lstrlen(szBuf))
  6580. SetDlgItemText(hDlg, IDC_DETAILS_NOTES_EDIT_GROUPS, szBuf);
  6581. }
  6582. }
  6583. idPropCount = idPropNotesCount;
  6584. lpidProp = idPropNotes;
  6585. /************/
  6586. FillProp:
  6587. // A very inefficient and lazy way of filling the UI
  6588. for(i=0;i<idPropCount;i++)
  6589. {
  6590. for(j=0;j<ulcPropCount;j++)
  6591. {
  6592. if(lpPropArray[j].ulPropTag == lpidProp[i].ulPropTag)
  6593. {
  6594. if(lpidProp[i].ulPropTag == PR_GENDER)
  6595. {
  6596. SendDlgItemMessage(hDlg, IDC_DETAILS_HOME_COMBO_GENDER, CB_SETCURSEL,
  6597. (WPARAM) lpPropArray[j].Value.i, 0);
  6598. }
  6599. else
  6600. if( lpidProp[i].ulPropTag == PR_WAB_POSTALID )
  6601. {
  6602. if(nPropSheet == propHome)
  6603. CheckDlgButton( hDlg, lpidProp[i].idCtl,
  6604. (lpPropArray[j].Value.l == ADDRESS_HOME)?BST_CHECKED:BST_UNCHECKED);
  6605. else if(nPropSheet == propBusiness)
  6606. CheckDlgButton( hDlg, lpidProp[i].idCtl,
  6607. (lpPropArray[j].Value.l == ADDRESS_WORK)?BST_CHECKED:BST_UNCHECKED);
  6608. }
  6609. else
  6610. SetDlgItemText(hDlg, lpidProp[i].idCtl, lpPropArray[j].Value.LPSZ);
  6611. }
  6612. }
  6613. }
  6614. break;
  6615. }
  6616. bRet = TRUE;
  6617. out:
  6618. if(lpBuffer)
  6619. LocalFreeAndNull(&lpBuffer);
  6620. if(lpPropArray)
  6621. MAPIFreeBuffer(lpPropArray);
  6622. lpPai->ulFlags &= ~DETAILS_Initializing;
  6623. return bRet;
  6624. }
  6625. /*
  6626. - FreeCertList - Frees the list of certificate items in memory
  6627. -
  6628. *
  6629. */
  6630. void FreeCertList(LPCERT_ITEM * lppCItem)
  6631. {
  6632. LPCERT_ITEM lpItem = NULL;
  6633. if(!lppCItem)
  6634. return;
  6635. lpItem = *lppCItem;
  6636. while(lpItem)
  6637. {
  6638. *lppCItem = lpItem->lpNext;
  6639. FreeCertdisplayinfo(lpItem->lpCDI);
  6640. if (lpItem->pcCert)
  6641. CertFreeCertificateContext(lpItem->pcCert);
  6642. LocalFree(lpItem);
  6643. lpItem = *lppCItem;
  6644. }
  6645. *lppCItem = NULL;
  6646. }
  6647. /*//$$***************************************************************************
  6648. * FUNCTION: FillCertTridentConfDetailsUI(HWND)
  6649. *
  6650. * PURPOSE: Fills in the dialog items on the property sheet
  6651. *
  6652. ****************************************************************************/
  6653. BOOL FillCertTridentConfDetailsUI(HWND hDlg, LPPROP_ARRAY_INFO lpPai, int nPropSheet, BOOL * lpbChangesMade)
  6654. {
  6655. ULONG i = 0,j = 0;
  6656. BOOL bRet = FALSE;
  6657. BOOL bChangesMade = FALSE;
  6658. ID_PROP * lpidProp = NULL;
  6659. ULONG idPropCount = 0;
  6660. LPVOID lpBuffer = NULL;
  6661. ULONG ulcPropCount = 0;
  6662. LPSPropValue lpPropArray = NULL;
  6663. if(HR_FAILED(lpPai->lpPropObj->lpVtbl->GetProps(lpPai->lpPropObj, NULL, MAPI_UNICODE,
  6664. &ulcPropCount, &lpPropArray)))
  6665. goto out;
  6666. lpPai->ulFlags |= DETAILS_Initializing;
  6667. // Set the flag that this sheet was opened
  6668. lpPai->bPropSheetOpened[nPropSheet] = TRUE;
  6669. switch(nPropSheet)
  6670. {
  6671. case propCert:
  6672. {
  6673. //
  6674. // Now we fill in the Certificate information
  6675. // Cases that can exist are
  6676. // - no certificates
  6677. // - certificates
  6678. //
  6679. // First we search for all the props we need to fill in the email structure
  6680. //
  6681. LPSPropValue lpPropMVCert = NULL;
  6682. BOOL bDefaultSet = FALSE;
  6683. HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_CERT_LIST);
  6684. HRESULT hr = S_OK;
  6685. for(i=0;i<ulcPropCount;i++)
  6686. {
  6687. if(lpPropArray[i].ulPropTag == PR_USER_X509_CERTIFICATE)
  6688. {
  6689. lpPropMVCert = &(lpPropArray[i]);
  6690. break;
  6691. }
  6692. }
  6693. // Fill the combo with email addresses
  6694. FillCertComboWithEmailAddresses(hDlg, lpPai, NULL);
  6695. hr = HrSetCertInfoInUI(hDlg, lpPropMVCert, lpPai);
  6696. if(hr == MAPI_E_NOT_FOUND && lpPropMVCert)
  6697. {
  6698. // The cert prop seems to contain bogus data .. need to nuke it
  6699. // 48750 : if there is no cert data, dont show a cert icon ..
  6700. // Problem is that we're not entirely sure that just because we couldnt
  6701. // interpret the data that it's invalid, what if there is aata we don't interpret .. ?
  6702. }
  6703. if(lpPropMVCert)
  6704. {
  6705. // Enable the combo, the properties button, and the export button
  6706. //EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_LIST),TRUE);
  6707. EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_COMBO),TRUE);
  6708. //EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_BUTTON_PROPERTIES),TRUE);
  6709. //EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_BUTTON_EXPORT),TRUE);
  6710. }
  6711. }
  6712. break;
  6713. /************/
  6714. case propTrident:
  6715. {
  6716. HrInit(lpPai->lpIWABDocHost, hDlg, IDC_TRIDENT_WINDOW, dhbNone);
  6717. {
  6718. ULONG i;
  6719. LPTSTR lp = NULL, lpURL = NULL, lpLabel = NULL;
  6720. // Find the labeledURI property and parse it
  6721. // This string property contains a URL followed by spaces followed by the label (RFC 2079)
  6722. for(i=0;i<ulcPropCount;i++)
  6723. {
  6724. if(lpPropArray[i].ulPropTag == PR_WAB_LDAP_LABELEDURI)
  6725. {
  6726. // isolate the URL and the label
  6727. // The URL is followed by spaces
  6728. lpURL = lp = lpPropArray[i].Value.LPSZ;
  6729. while(lp && *lp)
  6730. {
  6731. if (IsSpace(lp))
  6732. {
  6733. lpLabel = CharNext(lp);
  6734. *lp = '\0';
  6735. break;
  6736. }
  6737. else
  6738. lp = CharNext(lp);
  6739. }
  6740. // The above is the URL
  6741. // Label starts at first non space char
  6742. while(lpLabel && IsSpace(lpLabel))
  6743. lpLabel = CharNext(lpLabel);
  6744. }
  6745. // Since the trident pane is shown first, update the windows title
  6746. if(lpPropArray[i].ulPropTag == PR_DISPLAY_NAME)
  6747. {
  6748. lp = lpPropArray[i].Value.LPSZ;
  6749. if(lstrlen(lp))
  6750. SetWindowPropertiesTitle(GetParent(hDlg), lp);
  6751. }
  6752. }
  6753. if(lpLabel && lstrlen(lpLabel))
  6754. SetDlgItemText(hDlg, IDC_DETAILS_TRIDENT_STATIC_CAPTION, lpLabel);
  6755. if(lpURL && lstrlen(lpURL))
  6756. {
  6757. if(HR_FAILED(HrLoadURL(lpPai->lpIWABDocHost, lpURL)))
  6758. {
  6759. // remove this property sheet and set the focus to the first prop sheet
  6760. PropSheet_RemovePage(hDlg,lpPai->ulTridentPageIndex,NULL);
  6761. PropSheet_SetCurSel(hDlg, NULL, 0);
  6762. }
  6763. else
  6764. EnableWindow(GetDlgItem(GetParent(hDlg), IDOK), FALSE);
  6765. }
  6766. }
  6767. }
  6768. break;
  6769. /************/
  6770. case propConferencing:
  6771. {
  6772. HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_NTMTG_LIST_SERVERS);
  6773. HWND hWndCombo = GetDlgItem(hDlg, IDC_DETAILS_NTMTG_COMBO_EMAIL);
  6774. FillComboWithEmailAddresses(lpPai, hWndCombo, NULL);
  6775. // Fill in the conferencing related properties
  6776. for(j=0;j<ulcPropCount;j++)
  6777. {
  6778. if(lpPropArray[j].ulPropTag == PR_WAB_CONF_SERVERS)
  6779. {
  6780. LPSPropValue lpProp = &(lpPropArray[j]);
  6781. for(i=0;i<lpProp->Value.MVSZ.cValues; i++)
  6782. {
  6783. if(lstrlen(lpProp->Value.MVSZ.LPPSZ[i]) < lstrlen(szCallto))
  6784. continue; //ignore this one
  6785. // if this is a callto
  6786. if(!StrCmpNI(lpProp->Value.MVSZ.LPPSZ[i], szCallto, lstrlen(szCallto)))
  6787. {
  6788. LV_ITEM lvi = {0};
  6789. LPSERVER_ITEM lpSI = LocalAlloc(LMEM_ZEROINIT, sizeof(SERVER_ITEM));
  6790. if(lpSI)
  6791. {
  6792. ULONG cch = lstrlen(lpProp->Value.MVSZ.LPPSZ[i])+1;
  6793. LPTSTR lp = LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*cch);
  6794. ULONG cchEmail = lstrlen(lpProp->Value.MVSZ.LPPSZ[i])+1;
  6795. LPTSTR lpEmail = LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*cchEmail);
  6796. if(lp && lpEmail)
  6797. {
  6798. lvi.mask = LVIF_TEXT | LVIF_PARAM;
  6799. StrCpyN(lp,lpProp->Value.MVSZ.LPPSZ[i],cch);
  6800. *lpEmail = '\0';
  6801. {
  6802. // isolate just the server name by terminating
  6803. // at the next '/'
  6804. LPTSTR lp1 = lp + lstrlen(szCallto);
  6805. StrCpyN(lp, lp1, cch);
  6806. lp1 = lp;
  6807. while(lp1 && *lp1 && *lp1!='/')
  6808. lp1 = CharNext(lp1);
  6809. if(*lp1 == '/')
  6810. {
  6811. StrCpyN(lpEmail, lp1+1, cchEmail);
  6812. *lp1 = '\0';
  6813. }
  6814. // Now lpEmail contains the email text ...
  6815. // Walk along lpEmail till we hit the next /,?.or \0 and terminate
  6816. lp1 = lpEmail;
  6817. while(lp1 && *lp1 && *lp1!='/' && *lp1!='?')
  6818. lp1 = CharNext(lp1);
  6819. if(*lp1 == '/' || *lp1 == '?')
  6820. *lp1 = '\0';
  6821. }
  6822. lvi.pszText = lp;
  6823. lpSI->lpServer = lp;
  6824. lpSI->lpEmail = lpEmail;
  6825. lvi.lParam = (LPARAM) lpSI;
  6826. lvi.cchTextMax = lstrlen(lp)+1;
  6827. lvi.iItem = ListView_GetItemCount(hWndLV);
  6828. lvi.iSubItem = 0;
  6829. ListView_InsertItem(hWndLV, &lvi);
  6830. ListView_SetItemText(hWndLV, lvi.iItem, 1, lpEmail);
  6831. }
  6832. }
  6833. }
  6834. }
  6835. LVSelectItem(hWndLV, 0);
  6836. break;
  6837. }
  6838. }
  6839. for(j=0;j<ulcPropCount;j++)
  6840. {
  6841. if(lpPropArray[j].ulPropTag == PR_WAB_CONF_BACKUP_INDEX)
  6842. {
  6843. lpPai->nBackupServerIndex = lpPropArray[j].Value.l;
  6844. lpPai->szBackupServerName[0] = TEXT('\0');
  6845. SetBackupServer(hDlg, lpPai, lpPai->nBackupServerIndex, FALSE);
  6846. }
  6847. else if(lpPropArray[j].ulPropTag == PR_WAB_CONF_DEFAULT_INDEX)
  6848. {
  6849. lpPai->nDefaultServerIndex = lpPropArray[j].Value.l;
  6850. lpPai->szDefaultServerName[0] = TEXT('\0');
  6851. SetDefaultServer(hDlg, lpPai, lpPai->nDefaultServerIndex, TRUE);
  6852. }
  6853. }
  6854. // For LDAP servers we will have a single item in PR_SERVERS and no default, backup etc
  6855. // So if there is a single item available, force the default setting
  6856. if(ListView_GetItemCount(hWndLV) == 1 && lpPai->nDefaultServerIndex == -1)
  6857. {
  6858. LV_ITEM lvi = {0};
  6859. lvi.mask = LVIF_PARAM;
  6860. lvi.iItem = 0;
  6861. if(ListView_GetItem(hWndLV, &lvi) && lvi.lParam)
  6862. {
  6863. LPSERVER_ITEM lpSI = (LPSERVER_ITEM) lvi.lParam;
  6864. lpPai->nDefaultServerIndex = 0;
  6865. StrCpyN(lpPai->szDefaultServerName, lpSI->lpServer, lpPai->cchDefaultServerName);
  6866. SetDefaultServer(hDlg, lpPai, lpPai->nDefaultServerIndex, TRUE);
  6867. }
  6868. }
  6869. }
  6870. break;
  6871. }
  6872. bRet = TRUE;
  6873. out:
  6874. if(lpBuffer)
  6875. LocalFreeAndNull(&lpBuffer);
  6876. if(lpPropArray)
  6877. MAPIFreeBuffer(lpPropArray);
  6878. lpPai->ulFlags &= ~DETAILS_Initializing;
  6879. return bRet;
  6880. }
  6881. /*
  6882. - HrAddEmailToObj
  6883. - Adds a single Email to the PropObj
  6884. *
  6885. *
  6886. */
  6887. HRESULT HrAddEmailToObj(LPPROP_ARRAY_INFO lpPai, LPTSTR szEmail, LPTSTR szAddrType)
  6888. {
  6889. ULONG ulcProps = 0, i =0;
  6890. LPSPropValue lpProps = 0;
  6891. HRESULT hr = S_OK;
  6892. ULONG nMVEmailAddress = NOT_FOUND, nMVAddrTypes = NOT_FOUND, nEmailAddress = NOT_FOUND;
  6893. ULONG nAddrType = NOT_FOUND, nDefaultIndex = NOT_FOUND;
  6894. if(HR_FAILED(hr = lpPai->lpPropObj->lpVtbl->GetProps(lpPai->lpPropObj, NULL, MAPI_UNICODE,
  6895. &ulcProps, &lpProps)))
  6896. goto out;
  6897. // Check if the PR_CONTACT_EMAIL_ADDRESSES already exists ..
  6898. // if it does, tag the email onto it
  6899. // if it doesnt and there is no pr_email_address, we create both
  6900. // else if there is PR_EMAIL address then we cretae contact_email_addresses
  6901. for(i=0;i<ulcProps;i++)
  6902. {
  6903. switch(lpProps[i].ulPropTag)
  6904. {
  6905. case PR_EMAIL_ADDRESS:
  6906. nEmailAddress = i;
  6907. break;
  6908. case PR_ADDRTYPE:
  6909. nAddrType = i;
  6910. break;
  6911. case PR_CONTACT_EMAIL_ADDRESSES:
  6912. nMVEmailAddress = i;
  6913. break;
  6914. case PR_CONTACT_ADDRTYPES:
  6915. nMVAddrTypes = i;
  6916. break;
  6917. case PR_CONTACT_DEFAULT_ADDRESS_INDEX:
  6918. nDefaultIndex = i;
  6919. break;
  6920. }
  6921. }
  6922. // if no e-mail address, just add the given prop as e-mail address and in mv e-mail addresses
  6923. if(nEmailAddress == NOT_FOUND)
  6924. {
  6925. SPropValue spv[5];
  6926. spv[0].ulPropTag = PR_EMAIL_ADDRESS;
  6927. spv[0].Value.LPSZ = szEmail;
  6928. spv[1].ulPropTag = PR_ADDRTYPE;
  6929. spv[1].Value.LPSZ = szAddrType;
  6930. spv[2].ulPropTag = PR_CONTACT_EMAIL_ADDRESSES;
  6931. spv[2].Value.MVSZ.cValues = 1;
  6932. spv[2].Value.MVSZ.LPPSZ = LocalAlloc(LMEM_ZEROINIT, sizeof(LPTSTR));
  6933. if(spv[2].Value.MVSZ.LPPSZ)
  6934. spv[2].Value.MVSZ.LPPSZ[0] = szEmail;
  6935. spv[3].ulPropTag = PR_CONTACT_ADDRTYPES;
  6936. spv[3].Value.MVSZ.cValues = 1;
  6937. spv[3].Value.MVSZ.LPPSZ = LocalAlloc(LMEM_ZEROINIT, sizeof(LPTSTR));
  6938. if(spv[3].Value.MVSZ.LPPSZ)
  6939. spv[3].Value.MVSZ.LPPSZ[0] = szAddrType;
  6940. spv[4].ulPropTag = PR_CONTACT_DEFAULT_ADDRESS_INDEX;
  6941. spv[4].Value.l = 0;
  6942. hr = lpPai->lpPropObj->lpVtbl->SetProps(lpPai->lpPropObj, 5, (LPSPropValue)&spv, NULL);
  6943. if(spv[2].Value.MVSZ.LPPSZ)
  6944. LocalFree(spv[2].Value.MVSZ.LPPSZ);
  6945. if(spv[3].Value.MVSZ.LPPSZ)
  6946. LocalFree(spv[3].Value.MVSZ.LPPSZ);
  6947. goto out;
  6948. }
  6949. else
  6950. if(nMVEmailAddress == NOT_FOUND)
  6951. {
  6952. // we have an e-mail address but no contact-email-addresses
  6953. // so we will need to create the contact e-mail addresses
  6954. SPropValue spv[3];
  6955. spv[0].ulPropTag = PR_CONTACT_EMAIL_ADDRESSES;
  6956. spv[0].Value.MVSZ.cValues = 2;
  6957. spv[0].Value.MVSZ.LPPSZ = LocalAlloc(LMEM_ZEROINIT, sizeof(LPTSTR)*2);
  6958. if(spv[0].Value.MVSZ.LPPSZ)
  6959. {
  6960. spv[0].Value.MVSZ.LPPSZ[0] = lpProps[nEmailAddress].Value.LPSZ;
  6961. spv[0].Value.MVSZ.LPPSZ[1] = szEmail;
  6962. }
  6963. spv[1].ulPropTag = PR_CONTACT_ADDRTYPES;
  6964. spv[1].Value.MVSZ.cValues = 2;
  6965. spv[1].Value.MVSZ.LPPSZ = LocalAlloc(LMEM_ZEROINIT, sizeof(LPTSTR)*2);
  6966. if(spv[1].Value.MVSZ.LPPSZ)
  6967. {
  6968. spv[1].Value.MVSZ.LPPSZ[0] = (nAddrType == NOT_FOUND) ? (LPTSTR)szSMTP : lpProps[nAddrType].Value.LPSZ;
  6969. spv[1].Value.MVSZ.LPPSZ[1] = szAddrType;
  6970. }
  6971. spv[2].ulPropTag = PR_CONTACT_DEFAULT_ADDRESS_INDEX;
  6972. spv[2].Value.l = 0;
  6973. hr = lpPai->lpPropObj->lpVtbl->SetProps(lpPai->lpPropObj, 3, (LPSPropValue)&spv, NULL);
  6974. if(spv[0].Value.MVSZ.LPPSZ)
  6975. LocalFree(spv[0].Value.MVSZ.LPPSZ);
  6976. if(spv[1].Value.MVSZ.LPPSZ)
  6977. LocalFree(spv[1].Value.MVSZ.LPPSZ);
  6978. goto out;
  6979. }
  6980. else
  6981. {
  6982. // tag on the new props to the end of the existing contact_address_types
  6983. if(HR_FAILED(hr = AddPropToMVPString(lpProps,ulcProps, nMVEmailAddress, szEmail)))
  6984. {
  6985. DebugPrintError(( TEXT("AddPropToMVString Email failed: %x"),hr));
  6986. goto out;
  6987. }
  6988. if(HR_FAILED(hr = AddPropToMVPString(lpProps, ulcProps, nMVAddrTypes, szAddrType)))
  6989. {
  6990. DebugPrintError(( TEXT("AddPropToMVString AddrType failed: %x"),hr));
  6991. goto out;
  6992. }
  6993. hr = lpPai->lpPropObj->lpVtbl->SetProps(lpPai->lpPropObj, ulcProps, lpProps, NULL);
  6994. }
  6995. out:
  6996. FreeBufferAndNull(&lpProps);
  6997. return hr;
  6998. }
  6999. /*
  7000. - ShowHideMapButton
  7001. -
  7002. * The Expedia maps only work for US addresses right now .. therefore, if the current system locale
  7003. * is not English-US, we will hide the button since we can't deal with international stuff just yet
  7004. */
  7005. void ShowHideMapButton(HWND hWndButton)
  7006. {
  7007. LCID lcid = GetUserDefaultLCID();
  7008. switch (lcid)
  7009. {
  7010. case 0x0804: //chinese
  7011. // case 0x0c04: //chinese - hongkong
  7012. case 0x0411: //japanese
  7013. case 0x0412: //korean
  7014. case 0x0404: //taiwan
  7015. EnableWindow(hWndButton, FALSE);
  7016. ShowWindow(hWndButton, SW_HIDE);
  7017. break;
  7018. }
  7019. }
  7020. /*
  7021. - ShowExpediaMAP
  7022. - if there is sufficient address info in the supplied prop-obj, generate an expedia URL and shell exec it
  7023. * Expedia currently handles US addresses differently from international ones so need to figure that one out <TBD>
  7024. * bHome - TRUE if this is a home address
  7025. */
  7026. // All spaces need to be replaced by '+'s
  7027. //
  7028. // Next two strings moved to resources
  7029. // const LPTSTR szExpediaTemplate = TEXT("http://www.expediamaps.com/default.asp?Street=%1&City=%2&State=%4&Zip=%3");
  7030. // const LPTSTR szExpediaIntlTemplate = TEXT("http://www.expediamaps.com/default.asp?Place=%2,%5"); //city,country
  7031. enum
  7032. {
  7033. prStreet=0,
  7034. prCity,
  7035. prZip,
  7036. prState,
  7037. prCountry,
  7038. prAddressMax,
  7039. };
  7040. void ShowExpediaMAP(HWND hDlg, LPMAPIPROP lpPropObj, BOOL bHome)
  7041. {
  7042. ULONG ulcProps = 0;
  7043. LPSPropValue lpProps = NULL;
  7044. LPSPropTagArray lpta = (bHome ? (LPSPropTagArray)&ptaUIDetlsPropsHome : (LPSPropTagArray)&ptaUIDetlsPropsBusiness);
  7045. if(!HR_FAILED(lpPropObj->lpVtbl->GetProps( lpPropObj, lpta, MAPI_UNICODE, &ulcProps, &lpProps)))
  7046. {
  7047. LPTSTR lp[prAddressMax], lpURL = NULL;
  7048. ULONG i,j, ulCount = 0;
  7049. BOOL bUSAddress = FALSE;
  7050. for(i=0;i<prAddressMax;i++)
  7051. {
  7052. if(lpProps[i].ulPropTag == lpta->aulPropTag[i])
  7053. {
  7054. ulCount++;
  7055. lp[i] = lpProps[i].Value.LPSZ;
  7056. // we need to replace all the spaces in these strings with '+'
  7057. {
  7058. LPTSTR lpTemp = lp[i];
  7059. // need to knock out CRLFs
  7060. while(lpTemp && *lpTemp)
  7061. {
  7062. if(*lpTemp == '\r')
  7063. {
  7064. *lpTemp = '\0';
  7065. break;
  7066. }
  7067. lpTemp = CharNext(lpTemp);
  7068. }
  7069. lpTemp = lp[i];
  7070. while(lpTemp && *lpTemp)
  7071. {
  7072. if(IsSpace(lpTemp))
  7073. {
  7074. LPTSTR lpTemp2 = lpTemp;
  7075. lpTemp = CharNext(lpTemp);
  7076. *lpTemp2 = '+';
  7077. if(lpTemp != lpTemp2+1)
  7078. StrCpyN(lpTemp2+1, lpTemp, lstrlen(lpTemp)+1);
  7079. lpTemp = lpTemp2;
  7080. }
  7081. lpTemp = CharNext(lpTemp);
  7082. }
  7083. }
  7084. }
  7085. else
  7086. lp[i] = szEmpty;
  7087. }
  7088. // <TBD> - Determine if this address is a US address or not ..
  7089. if( !lstrlen(lp[prCountry]) || //no country - assume it's US
  7090. !lstrcmpi(lp[prCountry], TEXT("US")) ||
  7091. !lstrcmpi(lp[prCountry], TEXT("U.S.")) ||
  7092. !lstrcmpi(lp[prCountry], TEXT("USA")) ||
  7093. !lstrcmpi(lp[prCountry], TEXT("U.S.A.")) ||
  7094. !lstrcmpi(lp[prCountry], TEXT("America")) ||
  7095. !lstrcmpi(lp[prCountry], TEXT("United States")) ||
  7096. !lstrcmpi(lp[prCountry], TEXT("United States of America")) )
  7097. {
  7098. bUSAddress = TRUE;
  7099. }
  7100. if( (bUSAddress && (!lstrlen(lp[prStreet]) || ulCount<2)) ||
  7101. (!bUSAddress && !lstrlen(lp[prCity]) && !lstrlen(lp[prCountry])) )
  7102. {
  7103. ShowMessageBox(hDlg, idsInsufficientAddressInfo, MB_ICONINFORMATION);
  7104. }
  7105. else
  7106. {
  7107. TCHAR szText[MAX_BUF_STR] = {0};
  7108. TCHAR *pchWorldAddr = NULL;
  7109. LoadString(hinstMapiX, bUSAddress ? idsExpediaURL : idsExpediaIntlURL, szText, MAX_BUF_STR);
  7110. if(!bUSAddress )
  7111. {
  7112. //IE6 we need to change a little string for World map in Expedia
  7113. ULONG cchWorldAddr = lstrlen(lp[prStreet]) + lstrlen(lp[prCity]) +
  7114. lstrlen(lp[prState]) + lstrlen(lp[prCountry]) + 20;
  7115. if(pchWorldAddr = LocalAlloc(LMEM_ZEROINIT, cchWorldAddr*sizeof(pchWorldAddr[0]))) // we need add also space and commas
  7116. {
  7117. BOOL fAddComma = FALSE;
  7118. /* if(lstrlen(lp[prStreet]))
  7119. {
  7120. StrCatBuff(pchWorldAddr, lp[prStreet], cchWorldAddr);
  7121. fAddComma = TRUE;
  7122. }*/
  7123. if(lstrlen(lp[prCity]))
  7124. {
  7125. if(fAddComma)
  7126. StrCatBuff(pchWorldAddr, TEXT(", "), cchWorldAddr);
  7127. StrCatBuff(pchWorldAddr, lp[prCity], cchWorldAddr);
  7128. fAddComma = TRUE;
  7129. }
  7130. if(lstrlen(lp[prState]))
  7131. {
  7132. if(fAddComma)
  7133. StrCatBuff(pchWorldAddr, TEXT(", "), cchWorldAddr);
  7134. StrCatBuff(pchWorldAddr, lp[prState], cchWorldAddr);
  7135. fAddComma = TRUE;
  7136. }
  7137. if(lstrlen(lp[prCountry]))
  7138. {
  7139. if(fAddComma)
  7140. StrCatBuff(pchWorldAddr, TEXT(", "), cchWorldAddr);
  7141. StrCatBuff(pchWorldAddr, lp[prCountry], cchWorldAddr);
  7142. fAddComma = TRUE;
  7143. }
  7144. }
  7145. lp[prCountry] = pchWorldAddr;
  7146. }
  7147. if ( FormatMessage( FORMAT_MESSAGE_FROM_STRING |
  7148. FORMAT_MESSAGE_ALLOCATE_BUFFER |
  7149. FORMAT_MESSAGE_ARGUMENT_ARRAY,
  7150. szText,
  7151. 0, // stringid
  7152. 0, // dwLanguageId
  7153. (LPTSTR)&lpURL, // output buffer
  7154. 0,
  7155. (va_list *)lp))
  7156. {
  7157. //LPTSTR lpProperURL = NULL;
  7158. //DWORD dw = lstrlen(lpURL)*3+1;
  7159. DebugTrace( TEXT("Expedia URL: %s\n"),lpURL);
  7160. //Need to canoncolize this URL just in case it has unsafe characters in it
  7161. /*
  7162. if(lpProperURL = LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*dw)) // 3times bigger should be big enough
  7163. {
  7164. if(!InternetCanonicalizeUrlA(lpURL, lpProperURL, &dw, 0))
  7165. DebugTrace( TEXT("Error converting URL:%d\n"),GetLastError());
  7166. if(lpProperURL && lstrlen(lpProperURL))
  7167. {
  7168. LocalFree(lpURL);
  7169. lpURL = lpProperURL;
  7170. }
  7171. }
  7172. */
  7173. ShowURL(hDlg, 0, lpURL);
  7174. LocalFreeAndNull(&lpURL);
  7175. if(pchWorldAddr)
  7176. LocalFreeAndNull(&pchWorldAddr);
  7177. }
  7178. }
  7179. MAPIFreeBuffer(lpProps);
  7180. }
  7181. }
  7182. /*//$$***********************************************************************
  7183. * FUNCTION: fnRubyProc
  7184. *
  7185. - WinProc for the RUBY dialog that lets the user enter the ruby first and last name
  7186. *
  7187. ****************************************************************************/
  7188. enum
  7189. {
  7190. sFirst=0,
  7191. sLast,
  7192. sYomiFirst,
  7193. sYomiLast,
  7194. sMax
  7195. };
  7196. int rgIdPropPersonalRuby[] =
  7197. {
  7198. IDC_DETAILS_PERSONAL_EDIT_FIRSTNAME,
  7199. IDC_DETAILS_PERSONAL_EDIT_LASTNAME,
  7200. IDC_DETAILS_PERSONAL_STATIC_RUBYFIRST,
  7201. IDC_DETAILS_PERSONAL_STATIC_RUBYLAST,
  7202. };
  7203. int rgIdPropRubyDlg[] =
  7204. {
  7205. IDC_RUBY_EDIT_FIRSTNAME,
  7206. IDC_RUBY_EDIT_LASTNAME,
  7207. IDC_RUBY_EDIT_YOMIFIRSTNAME,
  7208. IDC_RUBY_EDIT_YOMILASTNAME,
  7209. };
  7210. INT_PTR CALLBACK fnRubyProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)
  7211. {
  7212. switch(message)
  7213. {
  7214. case WM_INITDIALOG:
  7215. {
  7216. LPTSTR * sz = (LPTSTR *) lParam;
  7217. SetWindowLongPtr(hDlg, DWLP_USER, lParam);
  7218. EnumChildWindows( hDlg, SetChildDefaultGUIFont, (LPARAM) 0);
  7219. SendMessage(GetDlgItem(hDlg,IDC_RUBY_EDIT_YOMIFIRSTNAME),EM_SETLIMITTEXT,(WPARAM) EDIT_LEN,0);
  7220. SendMessage(GetDlgItem(hDlg,IDC_RUBY_EDIT_YOMILASTNAME),EM_SETLIMITTEXT,(WPARAM) EDIT_LEN,0);
  7221. SendMessage(GetDlgItem(hDlg,IDC_RUBY_EDIT_FIRSTNAME),EM_SETLIMITTEXT,(WPARAM) EDIT_LEN,0);
  7222. SendMessage(GetDlgItem(hDlg,IDC_RUBY_EDIT_LASTNAME),EM_SETLIMITTEXT,(WPARAM) EDIT_LEN,0);
  7223. {
  7224. int i = 0;
  7225. for(i=0;i<sMax;i++)
  7226. {
  7227. if(lstrlen(sz[i]))
  7228. SetDlgItemText(hDlg, rgIdPropRubyDlg[i], sz[i]);
  7229. }
  7230. }
  7231. }
  7232. return TRUE;
  7233. break;
  7234. /***
  7235. case WM_HELP:
  7236. WABWinHelp(((LPHELPINFO)lParam)->hItemHandle,
  7237. g_szWABHelpFileName,
  7238. HELP_WM_HELP,
  7239. (DWORD_PTR)(LPSTR) rgDetlsHelpIDs );
  7240. break;
  7241. case WM_CONTEXTMENU:
  7242. WABWinHelp((HWND) wParam,
  7243. g_szWABHelpFileName,
  7244. HELP_CONTEXTMENU,
  7245. (DWORD_PTR)(LPVOID) rgDetlsHelpIDs );
  7246. break;
  7247. /****/
  7248. case WM_COMMAND:
  7249. switch(GET_WM_COMMAND_ID(wParam, lParam))
  7250. {
  7251. case IDOK:
  7252. {
  7253. LPTSTR * sz = (LPTSTR *) GetWindowLongPtr(hDlg, DWLP_USER);
  7254. int i =0;
  7255. for(i=0;i<sMax;i++)
  7256. {
  7257. if(!GetDlgItemText(hDlg, rgIdPropRubyDlg[i], sz[i], EDIT_LEN))
  7258. sz[i][0] = TEXT('\0');
  7259. }
  7260. }
  7261. EndDialog(hDlg, TRUE);
  7262. break;
  7263. case IDCANCEL:
  7264. EndDialog(hDlg, FALSE);
  7265. break;
  7266. }
  7267. break;
  7268. }
  7269. return FALSE;
  7270. }
  7271. /*
  7272. - ShoWRubyNameEntryDlg
  7273. -
  7274. * Let's the user enter Ruby First and Ruby Last names
  7275. *
  7276. */
  7277. void ShowRubyNameEntryDlg(HWND hDlg, LPPROP_ARRAY_INFO lpPai)
  7278. {
  7279. LPTSTR sz[sMax];
  7280. int i=0;
  7281. for(i=0;i<sMax;i++) //Read the data off the person tab
  7282. {
  7283. if(sz[i] = LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*EDIT_LEN))
  7284. {
  7285. sz[i][0] = TEXT('\0');
  7286. GetDlgItemText(hDlg, rgIdPropPersonalRuby[i], sz[i], EDIT_LEN);
  7287. }
  7288. }
  7289. if(DialogBoxParam(hinstMapiX, MAKEINTRESOURCE(IDD_DIALOG_RUBY),
  7290. hDlg, fnRubyProc, (LPARAM)sz))
  7291. {
  7292. for(i=0;i<sMax;i++) // put it back in the personal tab
  7293. {
  7294. SetDlgItemText(hDlg, rgIdPropPersonalRuby[i], sz[i]);
  7295. LocalFree(sz[i]);
  7296. }
  7297. lpPai->bSomethingChanged = TRUE;
  7298. }
  7299. }
  7300. /*//$$***************************************************************************
  7301. * FUNCTION: FillFamilyDetailsUI(HWND)
  7302. *
  7303. * PURPOSE: Fills in the data in the family tab
  7304. *
  7305. ****************************************************************************/
  7306. BOOL FillFamilyDetailsUI(HWND hDlg, LPPROP_ARRAY_INFO lpPai, int nPropSheet, BOOL * lpbChangesMade)
  7307. {
  7308. ULONG i = 0,j = 0, k =0;
  7309. BOOL bRet = FALSE;
  7310. BOOL bChangesMade = FALSE;
  7311. ID_PROP * lpidProp = NULL;
  7312. ULONG idPropCount = 0;
  7313. LPVOID lpBuffer = NULL;
  7314. ULONG ulcPropCount = 0;
  7315. LPSPropValue lpPropArray = NULL;
  7316. if(HR_FAILED(lpPai->lpPropObj->lpVtbl->GetProps(lpPai->lpPropObj,
  7317. (LPSPropTagArray)&ptaUIDetlsPropsFamily,
  7318. MAPI_UNICODE,
  7319. &ulcPropCount, &lpPropArray)))
  7320. goto out;
  7321. lpPai->ulFlags |= DETAILS_Initializing;
  7322. // Set the flag that this sheet was opened
  7323. lpPai->bPropSheetOpened[propFamily] = TRUE;
  7324. idPropCount = idPropFamilyCount;
  7325. lpidProp = idPropFamily;
  7326. // A very inefficient and lazy way of filling the UI
  7327. for(i=0;i<idPropCount;i++)
  7328. {
  7329. for(j=0;j<ulcPropCount;j++)
  7330. {
  7331. if(lpPropArray[j].ulPropTag == lpidProp[i].ulPropTag)
  7332. {
  7333. switch(lpidProp[i].ulPropTag)
  7334. {
  7335. case PR_GENDER:
  7336. SendDlgItemMessage(hDlg, IDC_DETAILS_HOME_COMBO_GENDER, CB_SETCURSEL,
  7337. (WPARAM) lpPropArray[j].Value.i, 0);
  7338. break;
  7339. case PR_BIRTHDAY:
  7340. case PR_WEDDING_ANNIVERSARY:
  7341. {
  7342. SYSTEMTIME st = {0};
  7343. FileTimeToSystemTime((FILETIME *) (&lpPropArray[j].Value.ft), &st);
  7344. SendDlgItemMessage(hDlg, lpidProp[i].idCtl,DTM_SETSYSTEMTIME,
  7345. (WPARAM) GDT_VALID, (LPARAM) &st);
  7346. }
  7347. break;
  7348. case PR_CHILDRENS_NAMES:
  7349. for(k=0;k<lpPropArray[j].Value.MVSZ.cValues;k++)
  7350. AddLVNewChild(hDlg, lpPropArray[j].Value.MVSZ.LPPSZ[k]);
  7351. break;
  7352. default:
  7353. SetDlgItemText(hDlg, lpidProp[i].idCtl, lpPropArray[j].Value.LPSZ);
  7354. }
  7355. }
  7356. }
  7357. }
  7358. bRet = TRUE;
  7359. out:
  7360. if(lpBuffer)
  7361. LocalFreeAndNull(&lpBuffer);
  7362. if(lpPropArray)
  7363. MAPIFreeBuffer(lpPropArray);
  7364. lpPai->ulFlags &= ~DETAILS_Initializing;
  7365. return bRet;
  7366. }
  7367. /*
  7368. - AddLVNewChild
  7369. -
  7370. - Adds a new child to the list of children
  7371. - Basically we will add an item called TEXT("New Child") and then
  7372. - force an in-place edit on that item
  7373. -
  7374. - It would be nice to have some image associated with this ListView, eg a Boy/Girl image
  7375. - but that means having to cache seperate Boy/Girl data which would be a pain ..
  7376. -
  7377. *
  7378. */
  7379. void AddLVNewChild(HWND hDlg, LPTSTR lpName)
  7380. {
  7381. HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_FAMILY_LIST_CHILDREN);
  7382. LV_ITEM lvi = {0};
  7383. TCHAR szBuf[MAX_PATH];
  7384. ULONG nLen;
  7385. int nPos;
  7386. LoadString(hinstMapiX, idsNewChild, szBuf, CharSizeOf(szBuf));
  7387. lvi.mask = LVIF_TEXT | LVIF_IMAGE;
  7388. lvi.pszText = lpName ? lpName : szBuf;
  7389. lvi.cchTextMax = MAX_PATH;
  7390. lvi.iItem = ListView_GetItemCount(hWndLV);
  7391. lvi.iSubItem = 0;
  7392. lvi.iImage = imgChild+(lvi.iItem%3);//just add a little color by using more than 1 different colored image
  7393. nPos = ListView_InsertItem(hWndLV, &lvi);
  7394. LVSelectItem(hWndLV, nPos);
  7395. EnableWindow(GetDlgItem(hDlg, IDC_DETAILS_FAMILY_BUTTON_EDITCHILD), TRUE);
  7396. EnableWindow(GetDlgItem(hDlg, IDC_DETAILS_FAMILY_BUTTON_REMOVECHILD), TRUE);
  7397. return;
  7398. }
  7399. /*//$$***********************************************************************
  7400. * FUNCTION: fnFamilyProc
  7401. *
  7402. * PURPOSE: Callback function for handling the Family property sheet ...
  7403. *
  7404. ****************************************************************************/
  7405. INT_PTR CALLBACK fnFamilyProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)
  7406. {
  7407. PROPSHEETPAGE * pps;
  7408. BOOL bRet = FALSE;
  7409. pps = (PROPSHEETPAGE *) GetWindowLongPtr(hDlg, DWLP_USER);
  7410. switch(message)
  7411. {
  7412. case WM_INITDIALOG:
  7413. SetWindowLongPtr(hDlg,DWLP_USER,lParam);
  7414. pps = (PROPSHEETPAGE *) lParam;
  7415. lpPAI->ulFlags |= DETAILS_Initializing;
  7416. SetDetailsUI(hDlg, lpPAI, lpPAI->ulOperationType,propFamily);
  7417. lpPAI->ulFlags &= ~DETAILS_Initializing;
  7418. return TRUE;
  7419. case WM_DESTROY:
  7420. bRet = TRUE;
  7421. break;
  7422. case WM_HELP:
  7423. WABWinHelp(((LPHELPINFO)lParam)->hItemHandle,
  7424. g_szWABHelpFileName,
  7425. HELP_WM_HELP,
  7426. (DWORD_PTR)(LPSTR) rgDetlsHelpIDs );
  7427. break;
  7428. case WM_CONTEXTMENU:
  7429. WABWinHelp((HWND) wParam,
  7430. g_szWABHelpFileName,
  7431. HELP_CONTEXTMENU,
  7432. (DWORD_PTR)(LPVOID) rgDetlsHelpIDs );
  7433. break;
  7434. case WM_COMMAND:
  7435. switch(GET_WM_COMMAND_CMD(wParam,lParam)) //check the notification code
  7436. {
  7437. case CBN_SELCHANGE: //gender combo
  7438. if(lpPAI->ulFlags & DETAILS_Initializing)
  7439. break;
  7440. lpPAI->ulFlags |= DETAILS_GenderChanged;
  7441. if (lpbSomethingChanged)
  7442. (*lpbSomethingChanged) = TRUE;
  7443. break;
  7444. case EN_CHANGE: //some edit box changed - dont care which
  7445. if(lpPAI->ulFlags & DETAILS_Initializing)
  7446. break;
  7447. if (lpbSomethingChanged)
  7448. (*lpbSomethingChanged) = TRUE;
  7449. break;
  7450. }
  7451. switch(GET_WM_COMMAND_ID(wParam, lParam))
  7452. {
  7453. case IDC_DETAILS_FAMILY_BUTTON_ADDCHILD:
  7454. lpPAI->ulFlags |= DETAILS_ChildrenChanged;
  7455. AddLVNewChild(hDlg, NULL);
  7456. SendMessage(hDlg, WM_COMMAND, (WPARAM)IDC_DETAILS_FAMILY_BUTTON_EDITCHILD, 0);
  7457. break;
  7458. case IDC_DETAILS_FAMILY_BUTTON_EDITCHILD:
  7459. lpPAI->ulFlags |= DETAILS_ChildrenChanged;
  7460. {
  7461. HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_FAMILY_LIST_CHILDREN);
  7462. SetFocus(hWndLV);
  7463. if(ListView_GetSelectedCount(hWndLV)==1)
  7464. {
  7465. int index = ListView_GetNextItem(hWndLV,-1,LVNI_SELECTED);
  7466. HWND hWndEditLabel = ListView_EditLabel(hWndLV, index);
  7467. //SendMessage(hWndEditLabel, EM_LIMITTEXT, MAX_PATH, 0);
  7468. }
  7469. }
  7470. break;
  7471. case IDC_DETAILS_FAMILY_BUTTON_REMOVECHILD:
  7472. lpPAI->ulFlags |= DETAILS_ChildrenChanged;
  7473. {
  7474. HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_FAMILY_LIST_CHILDREN);
  7475. if(ListView_GetSelectedCount(hWndLV)==1)
  7476. {
  7477. int index = ListView_GetNextItem(hWndLV,-1,LVNI_SELECTED);
  7478. ListView_DeleteItem(hWndLV, index);
  7479. if(index >= ListView_GetItemCount(hWndLV))
  7480. index--;
  7481. LVSelectItem(hWndLV, index);
  7482. }
  7483. }
  7484. break;
  7485. // [PaulHi] 12/4/98 Raid #58940
  7486. // This fix causes the system to go into an infinite message loop (stack overflow
  7487. // crash on intenational Win9X machines) with DBCS. The fnPersonalProc property
  7488. // sheet also doesn't handle this WM_COMMAND message, probably for the same reason.
  7489. // ESC still works correctly on this property sheet.
  7490. #if 0
  7491. /*
  7492. case IDCANCEL:
  7493. // This is a windows bug that prevents ESC canceling prop sheets
  7494. // which have MultiLine Edit boxes KB: Q130765
  7495. SendMessage(GetParent(hDlg),message,wParam,lParam);
  7496. break;
  7497. */
  7498. #endif
  7499. }
  7500. break;
  7501. case WM_NOTIFY:
  7502. switch(((NMHDR FAR *)lParam)->code)
  7503. {
  7504. case DTN_DATETIMECHANGE: //change in the Month-Date-Time control
  7505. if(lpPAI->ulFlags & DETAILS_Initializing)
  7506. break;
  7507. lpPAI->ulFlags |= DETAILS_DateChanged;
  7508. if (lpbSomethingChanged)
  7509. (*lpbSomethingChanged) = TRUE;
  7510. break;
  7511. case LVN_BEGINLABELEDITA:
  7512. case LVN_BEGINLABELEDITW:
  7513. lpPAI->ulFlags |= DETAILS_EditingChild;
  7514. break;
  7515. case LVN_ENDLABELEDITA:
  7516. case LVN_ENDLABELEDITW:
  7517. {
  7518. // After the user finishes editing the children's name,
  7519. HWND hWndLV = ((NMHDR FAR *)lParam)->hwndFrom;
  7520. LV_ITEM lvi = ((LV_DISPINFO FAR *) lParam)->item;
  7521. // if this is Win9x .. we'llget an LV_ITEMA here .. else a LV_ITEMW
  7522. LPWSTR lpW = NULL;
  7523. LPSTR lpA = NULL;
  7524. if(!g_bRunningOnNT)
  7525. {
  7526. lpA = (LPSTR)lvi.pszText;
  7527. lpW = ConvertAtoW(lpA);
  7528. lvi.pszText = lpW;
  7529. }
  7530. lpPAI->ulFlags &= ~DETAILS_EditingChild;
  7531. if ((lvi.iItem >= 0) && lvi.pszText && (lstrlen(lvi.pszText)))
  7532. {
  7533. ListView_SetItem(hWndLV, &lvi);
  7534. }
  7535. LocalFreeAndNull(&lpW);
  7536. if(!g_bRunningOnNT)
  7537. ((LV_DISPINFO FAR *) lParam)->item.pszText = (LPWSTR)lpA; // reset it as we found it
  7538. }
  7539. break;
  7540. case PSN_SETACTIVE: //initialize
  7541. FillFamilyDetailsUI(hDlg, lpPAI, propFamily, lpbSomethingChanged);
  7542. break;
  7543. case PSN_KILLACTIVE: //Losing activation to another page
  7544. bUpdatePropArray(hDlg, lpPAI, propFamily);
  7545. ListView_DeleteAllItems(GetDlgItem(hDlg, IDC_DETAILS_FAMILY_LIST_CHILDREN));
  7546. lpPAI->ulFlags &= ~DETAILS_GenderChanged;
  7547. lpPAI->ulFlags &= ~DETAILS_DateChanged;
  7548. lpPAI->ulFlags &= ~DETAILS_ChildrenChanged;
  7549. break;
  7550. case PSN_APPLY: //ok
  7551. if (lpPAI->nRetVal == DETAILS_RESET)
  7552. lpPAI->nRetVal = DETAILS_OK;
  7553. break;
  7554. case PSN_RESET: //cancel
  7555. if(lpPAI->ulFlags & DETAILS_EditingChild)
  7556. {
  7557. ListView_EditLabel(GetDlgItem(hDlg, IDC_DETAILS_FAMILY_LIST_CHILDREN), -1);
  7558. lpPAI->ulFlags &= ~DETAILS_EditingChild;
  7559. }
  7560. if (lpPAI->nRetVal == DETAILS_RESET)
  7561. lpPAI->nRetVal = DETAILS_CANCEL;
  7562. break;
  7563. }
  7564. return TRUE;
  7565. }
  7566. return bRet;
  7567. }
  7568. /*
  7569. - CreateDateTimePickerControl
  7570. -
  7571. *
  7572. * Description: Creates and initializes the control on the specified window. The controls destination
  7573. * size is that of the static rectangle IDC_CONTROL_RECT
  7574. * Parameters: idFrame - a dummy static used in the dialog layout to set a size and position for the new control
  7575. * The original static is hidden
  7576. * idControl - the Control ID to assign to the control
  7577. *
  7578. * We also need to make sure that the tab order stays sane,
  7579. * Returns: none
  7580. */
  7581. void CreateDateTimeControl(HWND hDlg, int idFrame, int idControl)
  7582. {
  7583. RECT rectControl;
  7584. SIZE sizeControl;
  7585. HWND hWndDP = NULL;
  7586. HWND hWndFrame = GetDlgItem(hDlg,idFrame);
  7587. // Get bounding rectangle of control and convert to client coordinates
  7588. GetWindowRect(hWndFrame,&rectControl);
  7589. MapWindowPoints(NULL, hDlg, (LPPOINT) &rectControl, 2);
  7590. sizeControl.cx = rectControl.right-rectControl.left;
  7591. sizeControl.cy = rectControl.bottom-rectControl.top;
  7592. // Do not use ScreenToClient(), use MapWindowPoints for mirroring.
  7593. // ScreenToClient(hDlg,&pointControl);
  7594. // Create control which starts at pointControl extends to sizeControl
  7595. // >> Start control specific
  7596. hWndDP = CreateWindowEx( WS_EX_CLIENTEDGE,
  7597. DATETIMEPICK_CLASS,
  7598. NULL,
  7599. WS_CHILD|WS_VISIBLE|WS_TABSTOP|DTS_SHORTDATEFORMAT|DTS_SHOWNONE,
  7600. rectControl.left,
  7601. rectControl.top,
  7602. sizeControl.cx,
  7603. sizeControl.cy,
  7604. hDlg,
  7605. (HMENU)IntToPtr(idControl), // control identifier
  7606. hinstMapiXWAB,
  7607. NULL);
  7608. // Check if control was created
  7609. if(hWndDP)
  7610. {
  7611. TCHAR szFormat[MAX_PATH];
  7612. SYSTEMTIME st = {0};
  7613. LoadString(hinstMapiX, idsDateTimeFormat, szFormat, CharSizeOf(szFormat));
  7614. SendMessage(hWndDP, DTM_SETFORMAT, 0, (LPARAM)szFormat);
  7615. SendMessage(hWndDP, DTM_SETSYSTEMTIME, (WPARAM) GDT_NONE, (LPARAM) &st);
  7616. SetWindowPos(hWndDP, hWndFrame,0,0,0,0,SWP_NOSIZE | SWP_NOMOVE);
  7617. }
  7618. return;
  7619. }