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
8745 lines
310 KiB
/**********************************************************************************
|
|
*
|
|
*
|
|
* Details.C - contains functions for the Details dialog
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
**********************************************************************************/
|
|
|
|
#include "_apipch.h"
|
|
|
|
#define _CRYPTDLG_
|
|
#define EDIT_LEN MAX_UI_STR*2
|
|
#define MAX_EDIT_LEN MAX_BUF_STR*2
|
|
|
|
#define IDC_TRIDENT_WINDOW 9903
|
|
|
|
extern BOOL bDNisByLN;
|
|
|
|
extern HINSTANCE ghCommCtrlDLLInst;
|
|
|
|
// extern LPPROPERTYSHEET gpfnPropertySheet;
|
|
// extern LPIMAGELIST_LOADIMAGE gpfnImageList_LoadImage;
|
|
// extern LP_CREATEPROPERTYSHEETPAGE gpfnCreatePropertySheetPage;
|
|
extern LPPROPERTYSHEET_A gpfnPropertySheetA;
|
|
extern LPPROPERTYSHEET_W gpfnPropertySheetW;
|
|
extern LPIMAGELIST_LOADIMAGE_A gpfnImageList_LoadImageA;
|
|
extern LPIMAGELIST_LOADIMAGE_W gpfnImageList_LoadImageW;
|
|
extern LP_CREATEPROPERTYSHEETPAGE_A gpfnCreatePropertySheetPageA;
|
|
extern LP_CREATEPROPERTYSHEETPAGE_W gpfnCreatePropertySheetPageW;
|
|
|
|
extern HRESULT HandleSaveChangedInsufficientDiskSpace(HWND hWnd, LPMAILUSER lpMailUser);
|
|
extern BOOL GetOpenFileName(LPOPENFILENAME pof);
|
|
extern BOOL GetSaveFileName(LPOPENFILENAME pof);
|
|
extern BOOL bIsIE401OrGreater();
|
|
extern void ChangeLocaleBasedTabOrder(HWND hWnd, int nPropSheet);
|
|
|
|
const LPTSTR szInternetCallKey = TEXT("Software\\Clients\\Internet Call");
|
|
const LPTSTR szCallto = TEXT("callto://");
|
|
const LPTSTR szHTTP = TEXT("http://");
|
|
|
|
|
|
/* Context-Sensitive Help IDs
|
|
|
|
The following is a giant list of Control IDs and corresponding Help IDs for
|
|
all the controls on all the property sheets .. when adding new prop sheets
|
|
just append your controls to the bottom of the list
|
|
*/
|
|
static DWORD rgDetlsHelpIDs[] =
|
|
{
|
|
IDC_DETAILS_PERSONAL_FRAME_NAME, IDH_WAB_COMM_GROUPBOX,
|
|
IDC_DETAILS_PERSONAL_FRAME_EMAIL, IDH_WAB_ADD_EMAIL_NAME,
|
|
IDC_DETAILS_PERSONAL_STATIC_FIRSTNAME, IDH_WAB_CONTACT_PROPS_FIRST,
|
|
IDC_DETAILS_PERSONAL_EDIT_FIRSTNAME, IDH_WAB_CONTACT_PROPS_FIRST,
|
|
IDC_DETAILS_PERSONAL_STATIC_LASTNAME, IDH_WAB_CONTACT_PROPS_LAST,
|
|
IDC_DETAILS_PERSONAL_EDIT_LASTNAME, IDH_WAB_CONTACT_PROPS_LAST,
|
|
IDC_DETAILS_PERSONAL_STATIC_MIDDLENAME, IDH_WAB_MIDDLE_NAME,
|
|
IDC_DETAILS_PERSONAL_EDIT_MIDDLENAME, IDH_WAB_MIDDLE_NAME,
|
|
IDC_DETAILS_PERSONAL_STATIC_NICKNAME, IDH_WAB_NICKNAME,
|
|
IDC_DETAILS_PERSONAL_EDIT_NICKNAME, IDH_WAB_NICKNAME,
|
|
IDC_DETAILS_PERSONAL_STATIC_DISPLAYNAME,IDH_WAB_PERSONAL_NAME_DISPLAY,
|
|
IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME, IDH_WAB_PERSONAL_NAME_DISPLAY,
|
|
IDC_DETAILS_PERSONAL_STATIC_TITLE, IDH_WAB_CONTACT_PROPS_TITLE,
|
|
IDC_DETAILS_PERSONAL_EDIT_TITLE, IDH_WAB_CONTACT_PROPS_TITLE,
|
|
IDC_DETAILS_PERSONAL_STATIC_CAPTION3, IDH_WAB_ADD_EMAIL_NAME,
|
|
IDC_DETAILS_PERSONAL_EDIT_ADDEMAIL, IDH_WAB_ADD_EMAIL_NAME,
|
|
IDC_DETAILS_PERSONAL_BUTTON_ADDEMAIL, IDH_WAB_ADD_EMAIL_NAME,
|
|
IDC_DETAILS_PERSONAL_LIST, IDH_WAB_EMAIL_NAME_LIST,
|
|
IDC_DETAILS_PERSONAL_BUTTON_REMOVE, IDH_WAB_DELETE_EMAIL_NAME,
|
|
IDC_DETAILS_PERSONAL_BUTTON_SETDEFAULT, IDH_WAB_DEFAULT_EMAIL_NAME,
|
|
IDC_DETAILS_PERSONAL_BUTTON_EDIT, IDH_WAB_EDIT_EMAIL_NAME,
|
|
IDC_DETAILS_PERSONAL_BUTTON_ADDTOWAB, IDH_WAB_DIRSERV_ADDADDRESS,
|
|
IDC_DETAILS_PERSONAL_CHECK_RICHINFO, IDH_WAB_PROPERTIES_SEND_USING_PLAIN_TEXT,
|
|
|
|
IDC_DETAILS_HOME_STATIC_ADDRESS, IDH_WAB_HOME_ADDRESS,
|
|
IDC_DETAILS_HOME_EDIT_ADDRESS, IDH_WAB_HOME_ADDRESS,
|
|
IDC_DETAILS_HOME_STATIC_CITY, IDH_WAB_HOME_CITY,
|
|
IDC_DETAILS_HOME_EDIT_CITY, IDH_WAB_HOME_CITY,
|
|
IDC_DETAILS_HOME_STATIC_STATE, IDH_WAB_HOME_STATE,
|
|
IDC_DETAILS_HOME_EDIT_STATE, IDH_WAB_HOME_STATE,
|
|
IDC_DETAILS_HOME_STATIC_ZIP, IDH_WAB_HOME_ZIP,
|
|
IDC_DETAILS_HOME_EDIT_ZIP, IDH_WAB_HOME_ZIP,
|
|
IDC_DETAILS_HOME_STATIC_COUNTRY, IDH_WAB_HOME_COUNTRY,
|
|
IDC_DETAILS_HOME_EDIT_COUNTRY, IDH_WAB_HOME_COUNTRY,
|
|
IDC_DETAILS_HOME_CHECK_DEFAULTADDRESS, IDH_WAB_BUSINESS_DEFAULTBOX,
|
|
IDC_DETAILS_HOME_BUTTON_MAP, IDH_WAB_BUSINESS_VIEWMAP,
|
|
IDC_DETAILS_HOME_STATIC_WEB, IDH_WAB_HOMEPAGE,
|
|
IDC_DETAILS_HOME_EDIT_URL, IDH_WAB_HOMEPAGE,
|
|
IDC_DETAILS_HOME_BUTTON_URL, IDH_WAB_HOMEPAGE_BUTTON,
|
|
IDC_DETAILS_HOME_STATIC_PHONE, IDH_WAB_BUS_PHONE,
|
|
IDC_DETAILS_HOME_EDIT_PHONE, IDH_WAB_BUS_PHONE,
|
|
IDC_DETAILS_HOME_STATIC_FAX, IDH_WAB_BUS_FAX,
|
|
IDC_DETAILS_HOME_EDIT_FAX, IDH_WAB_BUS_FAX,
|
|
IDC_DETAILS_HOME_STATIC_CELLULAR, IDH_WAB_BUS_CELLULAR,
|
|
IDC_DETAILS_HOME_EDIT_CELLULAR, IDH_WAB_BUS_CELLULAR,
|
|
IDC_DETAILS_HOME_COMBO_GENDER, IDH_WAB_HOME_GENDER,
|
|
|
|
IDC_DETAILS_BUSINESS_STATIC_COMPANY, IDH_WAB_BUS_COMPANY,
|
|
IDC_DETAILS_BUSINESS_EDIT_COMPANY, IDH_WAB_BUS_COMPANY,
|
|
IDC_DETAILS_BUSINESS_STATIC_ADDRESS, IDH_WAB_BUS_ADDRESS,
|
|
IDC_DETAILS_BUSINESS_EDIT_ADDRESS, IDH_WAB_BUS_ADDRESS,
|
|
IDC_DETAILS_BUSINESS_STATIC_CITY, IDH_WAB_BUS_CITY,
|
|
IDC_DETAILS_BUSINESS_EDIT_CITY, IDH_WAB_BUS_CITY,
|
|
IDC_DETAILS_BUSINESS_STATIC_STATE, IDH_WAB_BUS_STATE,
|
|
IDC_DETAILS_BUSINESS_EDIT_STATE, IDH_WAB_BUS_STATE,
|
|
IDC_DETAILS_BUSINESS_STATIC_ZIP, IDH_WAB_BUS_ZIP,
|
|
IDC_DETAILS_BUSINESS_EDIT_ZIP, IDH_WAB_BUS_ZIP,
|
|
IDC_DETAILS_BUSINESS_STATIC_COUNTRY, IDH_WAB_BUS_COUNTRY,
|
|
IDC_DETAILS_BUSINESS_EDIT_COUNTRY, IDH_WAB_BUS_COUNTRY,
|
|
IDC_DETAILS_BUSINESS_CHECK_DEFAULTADDRESS, IDH_WAB_BUSINESS_DEFAULTBOX,
|
|
IDC_DETAILS_BUSINESS_BUTTON_MAP, IDH_WAB_BUSINESS_VIEWMAP,
|
|
IDC_DETAILS_BUSINESS_STATIC_JOBTITLE, IDH_WAB_BUS_TITLE,
|
|
IDC_DETAILS_BUSINESS_EDIT_JOBTITLE, IDH_WAB_BUS_TITLE,
|
|
IDC_DETAILS_BUSINESS_STATIC_DEPARTMENT, IDH_WAB_BUS_DEPT,
|
|
IDC_DETAILS_BUSINESS_EDIT_DEPARTMENT, IDH_WAB_BUS_DEPT,
|
|
IDC_DETAILS_BUSINESS_STATIC_OFFICE, IDH_WAB_BUS_OFFICE,
|
|
IDC_DETAILS_BUSINESS_EDIT_OFFICE, IDH_WAB_BUS_OFFICE,
|
|
IDC_DETAILS_BUSINESS_STATIC_PHONE, IDH_WAB_BUS_PHONE,
|
|
IDC_DETAILS_BUSINESS_EDIT_PHONE, IDH_WAB_BUS_PHONE,
|
|
IDC_DETAILS_BUSINESS_STATIC_FAX, IDH_WAB_BUS_FAX,
|
|
IDC_DETAILS_BUSINESS_EDIT_FAX, IDH_WAB_BUS_FAX,
|
|
IDC_DETAILS_BUSINESS_STATIC_PAGER, IDH_WAB_BUS_PAGER,
|
|
IDC_DETAILS_BUSINESS_EDIT_PAGER, IDH_WAB_BUS_PAGER,
|
|
IDC_DETAILS_BUSINESS_STATIC_IPPHONE, IDH_WAB_BUSINESS_IPPHONE,
|
|
IDC_DETAILS_BUSINESS_EDIT_IPPHONE, IDH_WAB_BUSINESS_IPPHONE,
|
|
|
|
IDC_DETAILS_BUSINESS_STATIC_WEB, IDH_WAB_HOMEPAGE,
|
|
IDC_DETAILS_BUSINESS_EDIT_URL, IDH_WAB_HOMEPAGE,
|
|
IDC_DETAILS_BUSINESS_BUTTON_URL, IDH_WAB_HOMEPAGE_BUTTON,
|
|
|
|
IDC_DETAILS_NOTES_STATIC_NOTES, IDH_WAB_NOTES,
|
|
IDC_DETAILS_NOTES_EDIT_NOTES, IDH_WAB_NOTES,
|
|
IDC_DETAILS_NOTES_STATIC_NOTES_GROUP, IDH_WAB_OTHER_GROUP_MEMBERSHIP,
|
|
IDC_DETAILS_NOTES_EDIT_GROUPS, IDH_WAB_OTHER_GROUP_MEMBERSHIP,
|
|
IDC_DETAILS_NOTES_FRAME_FOLDER, IDH_WAB_OTHER_FOLDER,
|
|
IDC_DETAILS_NOTES_STATIC_FOLDER, IDH_WAB_OTHER_FOLDER,
|
|
|
|
IDC_DETAILS_CERT_FRAME, IDH_WAB_COMM_GROUPBOX,
|
|
IDC_DETAILS_CERT_LIST, IDH_WAB_PROPERTIES_CERTIFICATES,
|
|
IDC_DETAILS_CERT_BUTTON_PROPERTIES, IDH_WAB_PROPERTIES_PROPERTIES,
|
|
IDC_DETAILS_CERT_BUTTON_REMOVE, IDH_WAB_PROPERTIES_REMOVE,
|
|
IDC_DETAILS_CERT_BUTTON_SETDEFAULT, IDH_WAB_PROPERTIES_SETASDEFAULT,
|
|
IDC_DETAILS_CERT_BUTTON_IMPORT, IDH_WAB_PROPERTIES_IMPORT,
|
|
IDC_DETAILS_CERT_BUTTON_EXPORT, IDH_WAB_PROPERTIES_EXPORT,
|
|
IDC_DETAILS_CERT_COMBO, IDH_WAB_CERTIFICATES_SELECT_EMAIL_ADDRESS,
|
|
IDC_DETAILS_CERT_STATIC2, IDH_WAB_CERTIFICATES_SELECT_EMAIL_ADDRESS,
|
|
|
|
IDC_DETAILS_NTMTG_FRAME_SERVERS, IDH_WAB_COMM_GROUPBOX,
|
|
IDC_DETAILS_NTMTG_FRAME_SERVERS2, IDH_WAB_COMM_GROUPBOX,
|
|
IDC_DETAILS_NTMTG_STATIC_CAPTION2, IDH_WAB_CONFERENCE_SELECT_ADDRESS,
|
|
IDC_DETAILS_NTMTG_COMBO_EMAIL, IDH_WAB_CONFERENCE_SELECT_ADDRESS,
|
|
IDC_DETAILS_NTMTG_BUTTON_CALL, IDH_WAB_CONFERENCE_CALL_NOW,
|
|
IDC_DETAILS_NTMTG_STATIC_CAPTION3, IDH_WAB_CONFERENCE_SERVER_NAME,
|
|
IDC_DETAILS_NTMTG_EDIT_ADDSERVER, IDH_WAB_CONFERENCE_SERVER_NAME,
|
|
IDC_DETAILS_NTMTG_BUTTON_ADDSERVER, IDH_WAB_CONFERENCE_ADD_SERVER,
|
|
IDC_DETAILS_NTMTG_BUTTON_EDIT, IDH_WAB_CONFERENCE_EDIT_SERVER,
|
|
IDC_DETAILS_NTMTG_BUTTON_REMOVE, IDH_WAB_CONFERENCE_REMOVE_SERVER,
|
|
IDC_DETAILS_NTMTG_BUTTON_SETDEFAULT, IDH_WAB_CONFERENCE_SET_DEFAULT,
|
|
IDC_DETAILS_NTMTG_BUTTON_SETBACKUP, IDH_WAB_CONFERENCE_SET_BACKUP,
|
|
IDC_DETAILS_NTMTG_LIST_SERVERS, IDH_WAB_CONFERENCE_SERVER_LIST,
|
|
|
|
IDC_DETAILS_TRIDENT_BUTTON_ADDTOWAB, IDH_WAB_DIRSERV_ADDADDRESS,
|
|
|
|
IDC_DETAILS_SUMMARY_STATIC_NAME, IDH_WAB_SUMMARY,
|
|
IDC_DETAILS_SUMMARY_STATIC_EMAIL, IDH_WAB_SUMMARY,
|
|
IDC_DETAILS_SUMMARY_STATIC_HOMEPHONE, IDH_WAB_SUMMARY,
|
|
IDC_DETAILS_SUMMARY_STATIC_PAGER, IDH_WAB_SUMMARY,
|
|
IDC_DETAILS_SUMMARY_STATIC_CELLULAR, IDH_WAB_SUMMARY,
|
|
IDC_DETAILS_SUMMARY_STATIC_PERSONALWEB, IDH_WAB_SUMMARY,
|
|
IDC_DETAILS_SUMMARY_STATIC_BUSINESSPHONE, IDH_WAB_SUMMARY,
|
|
IDC_DETAILS_SUMMARY_STATIC_BUSINESSFAX, IDH_WAB_SUMMARY,
|
|
IDC_DETAILS_SUMMARY_STATIC_JOBTITLE, IDH_WAB_SUMMARY,
|
|
IDC_DETAILS_SUMMARY_STATIC_DEPARTMENT, IDH_WAB_SUMMARY,
|
|
IDC_DETAILS_SUMMARY_STATIC_OFFICE, IDH_WAB_SUMMARY,
|
|
IDC_DETAILS_SUMMARY_STATIC_COMPANYNAME, IDH_WAB_SUMMARY,
|
|
IDC_DETAILS_SUMMARY_STATIC_BUSINESSWEB, IDH_WAB_SUMMARY,
|
|
|
|
IDC_DETAILS_ORG_STATIC_MANAGER, IDH_WAB_ORGANIZATION_MANAGER,
|
|
IDC_DETAILS_ORG_LIST_MANAGER, IDH_WAB_ORGANIZATION_MANAGER,
|
|
IDC_DETAILS_ORG_STATIC_REPORTS, IDH_WAB_ORGANIZATION_REPORTS,
|
|
IDC_DETAILS_ORG_LIST_REPORTS, IDH_WAB_ORGANIZATION_REPORTS,
|
|
|
|
IDC_DETAILS_FAMILY_STATIC_SPOUSE, IDH_WAB_PERSONAL_SPOUSE,
|
|
IDC_DETAILS_FAMILY_EDIT_SPOUSE, IDH_WAB_PERSONAL_SPOUSE,
|
|
IDC_DETAILS_FAMILY_STATIC_CHILDREN, IDH_WAB_PERSONAL_CHILDREN,
|
|
IDC_DETAILS_FAMILY_LIST_CHILDREN, IDH_WAB_PERSONAL_CHILDREN,
|
|
IDC_DETAILS_FAMILY_BUTTON_ADDCHILD, IDH_WAB_PERSONAL_ADD,
|
|
IDC_DETAILS_FAMILY_BUTTON_EDITCHILD, IDH_WAB_PERSONAL_EDIT,
|
|
IDC_DETAILS_FAMILY_BUTTON_REMOVECHILD, IDH_WAB_PERSONAL_REMOVE,
|
|
IDC_DETAILS_FAMILY_STATIC_BIRTHDAY, IDH_WAB_PERSONAL_BIRTHDAY,
|
|
IDC_DETAILS_FAMILY_STATIC_ANNIVERSARY, IDH_WAB_PERSONAL_ANNIVERSARY,
|
|
IDC_DETAILS_FAMILY_DATE_BIRTHDAY, IDH_WAB_PERSONAL_BIRTHDAY,
|
|
IDC_DETAILS_FAMILY_DATE_ANNIVERSARY, IDH_WAB_PERSONAL_ANNIVERSARY,
|
|
|
|
|
|
0,0
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
Structs for Filling in data in the PropSheets
|
|
|
|
When filling in IDs into each property sheet, we do a GetProps on the displayed
|
|
object for the specific Props needed for each page .. we then use the returned
|
|
data to fill in the current prop sheet ..
|
|
Named properties need some special handling since we can't pre-allocate them into the structs -
|
|
the named properties need to be added prior to using them
|
|
Non-string properties may also need special handling
|
|
*/
|
|
|
|
|
|
/* -- Summary TAB info --*/
|
|
#define MAX_SUMMARY_ID 13
|
|
|
|
int rgSummaryIDs[] =
|
|
{
|
|
IDC_DETAILS_SUMMARY_STATIC_NAME,
|
|
IDC_DETAILS_SUMMARY_STATIC_EMAIL,
|
|
IDC_DETAILS_SUMMARY_STATIC_BUSINESSPHONE,
|
|
IDC_DETAILS_SUMMARY_STATIC_BUSINESSFAX,
|
|
IDC_DETAILS_SUMMARY_STATIC_HOMEPHONE,
|
|
IDC_DETAILS_SUMMARY_STATIC_PAGER,
|
|
IDC_DETAILS_SUMMARY_STATIC_CELLULAR,
|
|
IDC_DETAILS_SUMMARY_STATIC_JOBTITLE,
|
|
IDC_DETAILS_SUMMARY_STATIC_DEPARTMENT,
|
|
IDC_DETAILS_SUMMARY_STATIC_OFFICE,
|
|
IDC_DETAILS_SUMMARY_STATIC_COMPANYNAME,
|
|
IDC_DETAILS_SUMMARY_STATIC_BUSINESSWEB,
|
|
IDC_DETAILS_SUMMARY_STATIC_PERSONALWEB,
|
|
};
|
|
|
|
static const SizedSPropTagArray(MAX_SUMMARY_ID + 2, ptaUIDetlsPropsSummary) =
|
|
{
|
|
MAX_SUMMARY_ID + 2,
|
|
{
|
|
PR_DISPLAY_NAME,
|
|
PR_EMAIL_ADDRESS,
|
|
PR_BUSINESS_TELEPHONE_NUMBER,
|
|
PR_BUSINESS_FAX_NUMBER,
|
|
PR_HOME_TELEPHONE_NUMBER,
|
|
PR_PAGER_TELEPHONE_NUMBER,
|
|
PR_CELLULAR_TELEPHONE_NUMBER,
|
|
PR_TITLE,
|
|
PR_DEPARTMENT_NAME,
|
|
PR_OFFICE_LOCATION,
|
|
PR_COMPANY_NAME,
|
|
PR_BUSINESS_HOME_PAGE,
|
|
PR_PERSONAL_HOME_PAGE,
|
|
PR_CONTACT_EMAIL_ADDRESSES,
|
|
PR_CONTACT_DEFAULT_ADDRESS_INDEX,
|
|
}
|
|
};
|
|
|
|
/* -- Personal/Name TAB info --*/
|
|
|
|
/*
|
|
* [PaulHi] 4/8/99 Since the personal property sheet contains global properties
|
|
* (i.e., the Ruby properties ... PR_WAB_YOMI_LASTNAME, PR_WAB_YOMI_FIRSTNAME),
|
|
* this tag array cannot be static.
|
|
static const SizedSPropTagArray(12, ptaUIDetlsPropsPersonal)=
|
|
{
|
|
12,
|
|
{
|
|
PR_DISPLAY_NAME,
|
|
PR_EMAIL_ADDRESS,
|
|
PR_ADDRTYPE,
|
|
PR_CONTACT_EMAIL_ADDRESSES,
|
|
PR_CONTACT_ADDRTYPES,
|
|
PR_CONTACT_DEFAULT_ADDRESS_INDEX,
|
|
PR_GIVEN_NAME,
|
|
PR_SURNAME,
|
|
PR_MIDDLE_NAME,
|
|
PR_NICKNAME,
|
|
PR_SEND_INTERNET_ENCODING,
|
|
PR_DISPLAY_NAME_PREFIX
|
|
}
|
|
};
|
|
*/
|
|
|
|
/* -- Home TAB info --*/
|
|
static SizedSPropTagArray(10, ptaUIDetlsPropsHome)=
|
|
{
|
|
10,
|
|
{
|
|
PR_HOME_ADDRESS_STREET,
|
|
PR_HOME_ADDRESS_CITY,
|
|
PR_HOME_ADDRESS_POSTAL_CODE,
|
|
PR_HOME_ADDRESS_STATE_OR_PROVINCE,
|
|
PR_HOME_ADDRESS_COUNTRY,
|
|
PR_PERSONAL_HOME_PAGE,
|
|
PR_HOME_TELEPHONE_NUMBER,
|
|
PR_HOME_FAX_NUMBER,
|
|
PR_CELLULAR_TELEPHONE_NUMBER,
|
|
PR_NULL, /*PR_WAB_POSTALID*/
|
|
}
|
|
};
|
|
|
|
/* -- Business TAB info --*/
|
|
static SizedSPropTagArray(15, ptaUIDetlsPropsBusiness)=
|
|
{
|
|
15,
|
|
{
|
|
PR_BUSINESS_ADDRESS_STREET,
|
|
PR_BUSINESS_ADDRESS_CITY,
|
|
PR_BUSINESS_ADDRESS_POSTAL_CODE,
|
|
PR_BUSINESS_ADDRESS_STATE_OR_PROVINCE,
|
|
PR_BUSINESS_ADDRESS_COUNTRY,
|
|
PR_BUSINESS_HOME_PAGE,
|
|
PR_BUSINESS_TELEPHONE_NUMBER,
|
|
PR_BUSINESS_FAX_NUMBER,
|
|
PR_PAGER_TELEPHONE_NUMBER,
|
|
PR_COMPANY_NAME,
|
|
PR_TITLE,
|
|
PR_DEPARTMENT_NAME,
|
|
PR_OFFICE_LOCATION,
|
|
PR_NULL, /*PR_WAB_IPPHONE*/
|
|
PR_NULL, /*PR_WAB_POSTALID*/
|
|
|
|
}
|
|
};
|
|
|
|
/* -- Notes TAB info --*/
|
|
static const SizedSPropTagArray(1, ptaUIDetlsPropsNotes)=
|
|
{
|
|
1,
|
|
{
|
|
PR_COMMENT,
|
|
}
|
|
};
|
|
|
|
/* -- Digital ID TAB info --*/
|
|
static const SizedSPropTagArray(1, ptaUIDetlsPropsCert)=
|
|
{
|
|
1,
|
|
{
|
|
PR_USER_X509_CERTIFICATE,
|
|
}
|
|
};
|
|
|
|
/* -- Family TAB info --*/
|
|
static const SizedSPropTagArray(5, ptaUIDetlsPropsFamily)=
|
|
{
|
|
5,
|
|
{
|
|
PR_SPOUSE_NAME,
|
|
PR_CHILDRENS_NAMES,
|
|
PR_GENDER,
|
|
PR_BIRTHDAY,
|
|
PR_WEDDING_ANNIVERSARY,
|
|
}
|
|
};
|
|
|
|
|
|
|
|
enum _ImgEmail
|
|
{
|
|
imgNotDefaultEmail=0,
|
|
imgDefaultEmail,
|
|
imgChild
|
|
};
|
|
|
|
typedef struct _EmailItem
|
|
{
|
|
TCHAR szDisplayText[EDIT_LEN*2];
|
|
TCHAR szEmailAddress[EDIT_LEN];
|
|
TCHAR szAddrType[EDIT_LEN];
|
|
BOOL bIsDefault;
|
|
|
|
} EMAIL_ITEM, * LPEMAIL_ITEM;
|
|
|
|
|
|
typedef struct _ServerItem
|
|
{
|
|
LPTSTR lpServer;
|
|
LPTSTR lpEmail;
|
|
} SERVER_ITEM, * LPSERVER_ITEM;
|
|
|
|
|
|
enum _CertValidity
|
|
{
|
|
imgCertValid=0,
|
|
imgCertInvalid
|
|
};
|
|
|
|
|
|
enum _ListViewType
|
|
{
|
|
LV_EMAIL=0,
|
|
LV_CERT,
|
|
LV_SERVER,
|
|
LV_KIDS
|
|
};
|
|
|
|
|
|
// forward declarations
|
|
LRESULT CALLBACK RubySubClassedProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
|
|
|
int CreateDetailsPropertySheet(HWND hwndOwner,LPPROP_ARRAY_INFO lpPropArrayInfo);
|
|
|
|
INT_PTR CALLBACK fnSummaryProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam);
|
|
INT_PTR CALLBACK fnPersonalProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam);
|
|
INT_PTR CALLBACK fnHomeProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam);
|
|
INT_PTR CALLBACK fnBusinessProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam);
|
|
INT_PTR CALLBACK fnNotesProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam);
|
|
INT_PTR CALLBACK fnCertProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam);
|
|
INT_PTR CALLBACK fnTridentProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam);
|
|
INT_PTR CALLBACK fnConferencingProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam);
|
|
INT_PTR CALLBACK fnOrgProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam);
|
|
INT_PTR CALLBACK fnFamilyProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam);
|
|
|
|
void FillComboWithEmailAddresses(LPPROP_ARRAY_INFO lpPai, HWND hWndCombo, int * lpnDefault);
|
|
void SetBackupServer(HWND hDlg, LPPROP_ARRAY_INFO lpPai, int iSelectedItem, BOOL bForce);
|
|
void SetDefaultServer(HWND hDlg, LPPROP_ARRAY_INFO lpPai, int iSelectedItem, BOOL bForce);
|
|
BOOL FillPersonalDetails(HWND hDlg, LPPROP_ARRAY_INFO lpPai, int nPropSheet, BOOL * lpbChangesMade);
|
|
BOOL FillHomeBusinessNotesDetailsUI(HWND hDlg, LPPROP_ARRAY_INFO lpPai, int nPropSheet, BOOL * lpbChangesMade);
|
|
BOOL FillCertTridentConfDetailsUI(HWND hDlg, LPPROP_ARRAY_INFO lpPai, int nPropSheet, BOOL * lpbChangesMade);
|
|
BOOL FillFamilyDetailsUI(HWND hDlg, LPPROP_ARRAY_INFO lpPai, int nPropSheet, BOOL * lpbChangesMade);
|
|
BOOL GetDetailsFromUI(HWND hDlg, LPPROP_ARRAY_INFO lpPai , BOOL bSomethingChanged, int nPropSheet, LPSPropValue * lppPropArray, LPULONG lpulcPropCount);
|
|
BOOL SetDetailsUI(HWND hDlg, LPPROP_ARRAY_INFO lpPai, ULONG ulOperationType,int nPropSheet);
|
|
|
|
void CreateDateTimeControl(HWND hDlg, int idFrame, int idControl);
|
|
void AddLVNewChild(HWND hDlg, LPTSTR lpName);
|
|
|
|
void ShowExpediaMAP(HWND hDlg, LPMAPIPROP lpPropObj, BOOL bHome);
|
|
// [PaulHi] 4/5/99 Raid 57504 Enable the View Map button(s) for all locales.
|
|
// [PaulHi] 6/17/99 Raid 80805 Disable the View Map button again for various locales.
|
|
void ShowHideMapButton(HWND hWndButton);
|
|
|
|
HRESULT HrInitDetlsListView(HWND hWndLV, DWORD dwStyle, int nLVType);
|
|
void FreeLVParams(HWND hWndLV, int LVType);
|
|
void SetLVDefaultEmail( HWND hWndLV, int iItemIndex);
|
|
void AddLVEmailItem(HWND hWndLV, LPTSTR lpszEmailAddress, LPTSTR lpszAddrType);
|
|
BOOL DeleteLVEmailItem(HWND hWndLV, int iItemIndex);
|
|
void ShowURL(HWND hWnd, int id, LPTSTR lpURL);
|
|
void SetHTTPPrefix(HWND hDlg, int id);
|
|
int AddNewEmailEntry(HWND hDlg, BOOL bShowCancelButton);
|
|
void SetDetailsWindowTitle(HWND hDlg, BOOL bModifyDisplayNameField);
|
|
void ShowRubyNameEntryDlg(HWND hDlg, LPPROP_ARRAY_INFO lpPai);
|
|
|
|
void SetComboDNText(HWND hDlg, LPPROP_ARRAY_INFO lpPAI, BOOL bAddAll, LPTSTR szTxt);
|
|
void FreeCertList(LPCERT_ITEM * lppCItem);
|
|
|
|
HRESULT HrSetCertInfoInUI(HWND hDlg, LPSPropValue lpPropMVCert, LPPROP_ARRAY_INFO lpPai);
|
|
BOOL AddLVCertItem(HWND hWndLV, LPCERT_ITEM lpCItem, BOOL bCheckForDups);
|
|
void SetLVDefaultCert( HWND hWndLV,int iItemIndex);
|
|
BOOL DeleteLVCertItem(HWND hWndLV, int iItemIndex, LPPROP_ARRAY_INFO lpPAI);
|
|
void ShowCertProps(HWND hDlg, HWND hWndLV, BOOL * lpBool);
|
|
BOOL ImportCert(HWND hDlg, LPPROP_ARRAY_INFO lpPai);
|
|
BOOL ExportCert(HWND hDlg);
|
|
void UpdateCertListView(HWND hDlg, LPPROP_ARRAY_INFO lpPai);
|
|
|
|
//HRESULT KillTrustInSleazyFashion(HWND hWndLV, int iItem);
|
|
void LocalFreeServerItem(LPSERVER_ITEM lpSI);
|
|
HRESULT HrAddEmailToObj(LPPROP_ARRAY_INFO lpPai, LPTSTR szEmail, LPTSTR szAddrType);
|
|
|
|
|
|
//$$/////////////////////////////////////////////////////////////////
|
|
//
|
|
// Ensure lower case character
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
TCHAR lowercase(TCHAR ch) {
|
|
if (ch >= 'A' && ch <= 'Z') {
|
|
ch = ch + ('a' - 'A');
|
|
}
|
|
return(ch);
|
|
}
|
|
|
|
//$$///////////////////////////////////////////////////////////////////
|
|
//
|
|
// bIsHttpPrefix(LPTSTR szBuf) - verify that the URL is http: not file://fdisk.exe
|
|
//
|
|
//$$///////////////////////////////////////////////////////////////////
|
|
BOOL bIsHttpPrefix(LPTSTR szBuf)
|
|
{
|
|
// SECURITY: make sure it's http:
|
|
if (lstrlen(szBuf) > 5)
|
|
{
|
|
if (lowercase(szBuf[0]) == 'h' &&
|
|
lowercase(szBuf[1]) == 't' &&
|
|
lowercase(szBuf[2]) == 't' &&
|
|
lowercase(szBuf[3]) == 'p' &&
|
|
lowercase(szBuf[4]) == ':')
|
|
{
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
// BUGBUG: Susan Higgs wants a dialog here, but BruceK thinks
|
|
// it's superfluous. If people are nice to each other, we should
|
|
// not ever get here. I regard this as a last ditch line of
|
|
// security to keep ruthless people from exploiting our use
|
|
// of ShellExecute.
|
|
DebugTrace( TEXT("Whoa! Somebody's put something other than a web page in the web page slot! %sf\n"), szBuf);
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
// TBD - merge these two functions HrShowDetails and HrShowOneOffDetails
|
|
|
|
//$$///////////////////////////////////////////////////////////////////
|
|
//
|
|
// HrShowOneOffDetails - shows read-onlydetails for one-off addresses
|
|
//
|
|
//
|
|
// We either pass in a cbEntryID-lpEntryID combination or
|
|
// we pass in a ulcValues-lpPropArray combination or
|
|
// we pass in a lpPropObj to display
|
|
//
|
|
// If we are displaying one-off props on a LDAP URL result, the LDAP
|
|
// URL is also added so that it can be piped into extension prop sheets
|
|
// that need the LDAP URL information
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
HRESULT HrShowOneOffDetails( LPADRBOOK lpAdrBook,
|
|
HWND hWndParent,
|
|
ULONG cbEntryID,
|
|
LPENTRYID lpEntryID,
|
|
ULONG ulObjectType,
|
|
LPMAPIPROP lpPropObj,
|
|
LPTSTR szLDAPURL,
|
|
ULONG ulFlags)
|
|
{
|
|
HRESULT hr = hrSuccess;
|
|
SCODE sc = SUCCESS_SUCCESS;
|
|
ULONG cValues = 0;
|
|
LPSPropValue lpPropArray = NULL;
|
|
ULONG i=0;
|
|
PROP_ARRAY_INFO PropArrayInfo = {0};
|
|
|
|
// if no common control, exit
|
|
if (NULL == ghCommCtrlDLLInst) {
|
|
hr = ResultFromScode(MAPI_E_UNCONFIGURED);
|
|
goto out;
|
|
}
|
|
|
|
if(ulFlags & WAB_ONEOFF_NOADDBUTTON)
|
|
{
|
|
ulFlags &= ~WAB_ONEOFF_NOADDBUTTON;
|
|
PropArrayInfo.ulFlags |= DETAILS_HideAddToWABButton;
|
|
}
|
|
|
|
if ( ((!lpEntryID) && (!lpPropObj)) ||
|
|
(ulFlags != SHOW_ONE_OFF))
|
|
{
|
|
hr = MAPI_E_INVALID_PARAMETER;
|
|
goto out;
|
|
}
|
|
|
|
if(cbEntryID && lpEntryID)
|
|
{
|
|
// if this is a one-off address, do an open entry and then a get props to
|
|
// get an lpPropArray from this guy ...
|
|
|
|
if (HR_FAILED(hr = lpAdrBook->lpVtbl->OpenEntry(lpAdrBook,
|
|
cbEntryID, // cbEntryID
|
|
lpEntryID, // entryid
|
|
NULL, // interface
|
|
0, // ulFlags
|
|
&(PropArrayInfo.ulObjectType),
|
|
(LPUNKNOWN *)&(PropArrayInfo.lpPropObj) )))
|
|
{
|
|
// Failed! Hmmm.
|
|
if((HR_FAILED(hr)) && (MAPI_E_USER_CANCEL != hr))
|
|
{
|
|
int ids;
|
|
UINT flags = MB_OK | MB_ICONEXCLAMATION;
|
|
|
|
switch(hr)
|
|
{
|
|
case MAPI_E_UNABLE_TO_COMPLETE:
|
|
case MAPI_E_AMBIGUOUS_RECIP:
|
|
ids = idsLDAPAmbiguousRecip;
|
|
break;
|
|
case MAPI_E_NOT_FOUND:
|
|
ids = idsLDAPSearchNoResults;
|
|
break;
|
|
case MAPI_E_NO_ACCESS:
|
|
ids = idsLDAPAccessDenied;
|
|
break;
|
|
case MAPI_E_TIMEOUT:
|
|
ids = idsLDAPSearchTimedOut;
|
|
break;
|
|
case MAPI_E_NETWORK_ERROR:
|
|
ids = idsLDAPCouldNotFindServer;
|
|
break;
|
|
default:
|
|
ids = idsEntryNotFound;
|
|
break;
|
|
}
|
|
|
|
ShowMessageBox( hWndParent, ids, flags);
|
|
}
|
|
goto out;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
PropArrayInfo.ulObjectType = ulObjectType;
|
|
PropArrayInfo.lpPropObj = lpPropObj;
|
|
}
|
|
|
|
|
|
if (HR_FAILED(hr = PropArrayInfo.lpPropObj->lpVtbl->GetProps(PropArrayInfo.lpPropObj,
|
|
NULL, MAPI_UNICODE,
|
|
&cValues, // how many properties were there?
|
|
&lpPropArray)))
|
|
{
|
|
goto out;
|
|
}
|
|
|
|
if (cValues == 0)
|
|
{
|
|
// nothing to show
|
|
hr = E_FAIL;
|
|
goto out;
|
|
}
|
|
else
|
|
PropArrayInfo.ulFlags |= DETAILS_ShowSummary;
|
|
|
|
PropArrayInfo.lpIAB = lpAdrBook;
|
|
|
|
//Now we can call the property sheets ...
|
|
PropArrayInfo.cbEntryID = 0; //this will be ignored for one-offs
|
|
PropArrayInfo.lpEntryID = NULL;
|
|
PropArrayInfo.bSomethingChanged = FALSE;
|
|
|
|
for(i=0;i<TOTAL_PROP_SHEETS;i++)
|
|
PropArrayInfo.bPropSheetOpened[i] = FALSE;
|
|
|
|
PropArrayInfo.ulOperationType = SHOW_ONE_OFF;
|
|
PropArrayInfo.nRetVal = DETAILS_RESET;
|
|
|
|
if(InitCryptoLib())
|
|
PropArrayInfo.ulFlags |= DETAILS_ShowCerts;
|
|
|
|
// Do we show the org tab ?
|
|
for(i=0;i<cValues;i++)
|
|
{
|
|
if( lpPropArray[i].ulPropTag == PR_WAB_MANAGER ||
|
|
lpPropArray[i].ulPropTag == PR_WAB_REPORTS )
|
|
{
|
|
PropArrayInfo.ulFlags |= DETAILS_ShowOrg;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Check if we need to show the Trident Pane
|
|
#ifndef WIN16 // WIN16FF
|
|
for(i=0;i<cValues;i++)
|
|
{
|
|
if(lpPropArray[i].ulPropTag == PR_WAB_LDAP_LABELEDURI)
|
|
{
|
|
if(lstrlen(lpPropArray[i].Value.LPSZ) &&
|
|
bIsHttpPrefix((LPTSTR)lpPropArray[i].Value.LPSZ) )
|
|
{
|
|
// We have the correct property, now check - do we have Trident installed
|
|
// on this machine ???
|
|
hr = HrNewWABDocHostObject(&(PropArrayInfo.lpIWABDocHost));
|
|
if(!HR_FAILED(hr) && PropArrayInfo.lpIWABDocHost)
|
|
{
|
|
// Check to see if we can load IE4 and whether its the right
|
|
// version of IE4 .. <TBD> this should actually be a global so we
|
|
// dont do this for each entry ...
|
|
// <TBD> dont hardcode these strings ..
|
|
LPDLLGETVERSIONPROCOE lpfnDllGetVersionProc = NULL;
|
|
HINSTANCE hTrident = LoadLibrary( TEXT("shdocvw.dll"));
|
|
if(hTrident)
|
|
{
|
|
lpfnDllGetVersionProc = (LPDLLGETVERSIONPROCOE) GetProcAddress(hTrident, "DllGetVersion");
|
|
if(lpfnDllGetVersionProc)
|
|
{
|
|
// Check the version number
|
|
DLLVERSIONINFO dvi = {0};
|
|
dvi.cbSize = sizeof(dvi);
|
|
lpfnDllGetVersionProc(&dvi);
|
|
// we are looking for IE4 version 4.71.0544.1 or more
|
|
if( dvi.dwMajorVersion > 4 ||
|
|
(dvi.dwMajorVersion == 4 && dvi.dwMinorVersion >= 71 && dvi.dwBuildNumber >= 544))
|
|
{
|
|
PropArrayInfo.ulFlags |= DETAILS_ShowTrident;
|
|
}
|
|
}
|
|
FreeLibrary(hTrident);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
// if this is an ldap entry, turn the ldap entryid into an ldapurl and pass that
|
|
// to the extension prop sheets .. this enables the NTDS prop sheets to appropriately
|
|
// display themselves ..
|
|
if( cbEntryID && lpEntryID )
|
|
{
|
|
LPTSTR lpURL = NULL;
|
|
CreateLDAPURLFromEntryID(cbEntryID, lpEntryID, &lpURL, &PropArrayInfo.bIsNTDSURL);
|
|
PropArrayInfo.lpLDAPURL = lpURL;
|
|
}
|
|
else
|
|
PropArrayInfo.lpLDAPURL = szLDAPURL;
|
|
|
|
GetExtDisplayInfo((LPIAB)lpAdrBook, &PropArrayInfo, TRUE, TRUE);
|
|
|
|
if (CreateDetailsPropertySheet(hWndParent,&PropArrayInfo) == -1)
|
|
{
|
|
// Something failed ...
|
|
hr = E_FAIL;
|
|
goto out;
|
|
}
|
|
|
|
// This was a read only operation so we dont care for the results ...
|
|
// so nothing more to do ....
|
|
if(PropArrayInfo.nRetVal == DETAILS_ADDTOWAB)
|
|
{
|
|
ULONG cbEID = 0, cbPABEID = 0;
|
|
LPENTRYID lpEID = NULL, lpPABEID = NULL;
|
|
|
|
// We need to strip out the PR_WAB_LDAP_LABELEDURI prop and the
|
|
// old entryid if it exists
|
|
for(i=0;i<cValues;i++)
|
|
{
|
|
switch(lpPropArray[i].ulPropTag)
|
|
{
|
|
case PR_WAB_LDAP_LABELEDURI:
|
|
// remove the ldap url from this object
|
|
case PR_ENTRYID:
|
|
lpPropArray[i].ulPropTag = PR_NULL;
|
|
break;
|
|
}
|
|
if(lpPropArray[i].ulPropTag == PR_WAB_MANAGER ||
|
|
lpPropArray[i].ulPropTag == PR_WAB_REPORTS )
|
|
lpPropArray[i].ulPropTag = PR_NULL;
|
|
}
|
|
|
|
if(!HR_FAILED(hr = lpAdrBook->lpVtbl->GetPAB(lpAdrBook, &cbPABEID, &lpPABEID)))
|
|
{
|
|
hr = HrCreateNewEntry( lpAdrBook,
|
|
hWndParent,
|
|
MAPI_MAILUSER, //MAILUSER or DISTLIST
|
|
cbPABEID, lpPABEID,
|
|
MAPI_ABCONT,//container entryid
|
|
CREATE_CHECK_DUP_STRICT,
|
|
TRUE,
|
|
cValues,
|
|
lpPropArray,
|
|
&cbEID,
|
|
&lpEID);
|
|
}
|
|
|
|
if(lpPABEID)
|
|
MAPIFreeBuffer(lpPABEID);
|
|
if(lpEID)
|
|
MAPIFreeBuffer(lpEID);
|
|
}
|
|
|
|
out:
|
|
|
|
if(PropArrayInfo.lpLDAPURL && PropArrayInfo.lpLDAPURL!=szLDAPURL)
|
|
LocalFree(PropArrayInfo.lpLDAPURL);
|
|
|
|
LocalFreeAndNull(&PropArrayInfo.lpszOldName);
|
|
|
|
FreeExtDisplayInfo(&PropArrayInfo);
|
|
|
|
if(PropArrayInfo.szDefaultServerName)
|
|
LocalFree(PropArrayInfo.szDefaultServerName);
|
|
|
|
if(PropArrayInfo.szBackupServerName)
|
|
LocalFree(PropArrayInfo.szBackupServerName);
|
|
|
|
if(PropArrayInfo.lpIWABDocHost)
|
|
(PropArrayInfo.lpIWABDocHost)->lpVtbl->Release(PropArrayInfo.lpIWABDocHost);
|
|
|
|
if(PropArrayInfo.lpPropObj && !lpPropObj)
|
|
PropArrayInfo.lpPropObj->lpVtbl->Release(PropArrayInfo.lpPropObj);
|
|
|
|
if(lpPropArray)
|
|
MAPIFreeBuffer(lpPropArray);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
//$$/////////////////////////////////////////////////////////////////
|
|
//
|
|
// HrShowDetails - shows details/new entry UI
|
|
//
|
|
// lpIAB - lpAdrBook object
|
|
// hWndParent - hWnd of parent
|
|
// hPropertyStore - Handle to property store (can be retrieved from lpIAB)
|
|
// cbEIDContainer - EntryID of container in which to create the entry
|
|
// lpEIDContainer - EntryID of container in which to create the entry
|
|
// lppEntryID - entry id of object to display .. if a new object,
|
|
// contains the lpentryid of the created object
|
|
// lpPropObj - sometimes used in lieu of the entryid .. useful for
|
|
// adding objects like vCards and LDAP entries which have
|
|
// an object but dont currently exist in the WAB
|
|
// ulFlags - unused
|
|
// lpbChangesMade - Indicates if object was modified or not
|
|
//
|
|
///////////////////////////////////////////////////////////////////
|
|
HRESULT HrShowDetails( LPADRBOOK lpIAB,
|
|
HWND hWndParent,
|
|
HANDLE hPropertyStore,
|
|
ULONG cbEIDContainer,
|
|
LPENTRYID lpEIDContainer,
|
|
ULONG *lpcbEntryID,
|
|
LPENTRYID *lppEntryID,
|
|
LPMAPIPROP lpPropObj, // [optional] IN:IMAPIProp object
|
|
ULONG ulFlags,
|
|
ULONG ulObjectType,
|
|
BOOL * lpbChangesMade)
|
|
{
|
|
HRESULT hr = hrSuccess;
|
|
SCODE sc = SUCCESS_SUCCESS;
|
|
|
|
ULONG cbpta = 0;
|
|
ULONG ulNumOldProps = 0;
|
|
|
|
ULONG cbEntryID = 0;
|
|
LPENTRYID lpEntryID = NULL;
|
|
|
|
int nRet = 0, nRetVal = 0;
|
|
ULONG i = 0, j = 0, k = 0;
|
|
PROP_ARRAY_INFO PropArrayInfo = {0};
|
|
BOOL bChanges = FALSE;
|
|
|
|
ULONG nMaxSheets = 0;
|
|
|
|
DebugPrintTrace(( TEXT("----------\nHrShowDetails Entry\n")));
|
|
|
|
// if no common control, exit
|
|
if (NULL == ghCommCtrlDLLInst) {
|
|
hr = ResultFromScode(MAPI_E_UNCONFIGURED);
|
|
goto out;
|
|
}
|
|
|
|
if(lppEntryID)
|
|
lpEntryID = *lppEntryID;
|
|
|
|
if (lpcbEntryID)
|
|
cbEntryID = *lpcbEntryID;
|
|
|
|
|
|
if ( (!(ulFlags & SHOW_OBJECT) && hPropertyStore == NULL) ||
|
|
( (ulFlags & SHOW_DETAILS) && (lpEntryID == NULL)) ||
|
|
( (ulFlags & SHOW_OBJECT) && (lpPropObj == NULL)))
|
|
{
|
|
hr = MAPI_E_INVALID_PARAMETER;
|
|
goto out;
|
|
}
|
|
|
|
if(cbEntryID && lpEntryID)
|
|
{
|
|
PropArrayInfo.cbEntryID = cbEntryID;
|
|
PropArrayInfo.lpEntryID = LocalAlloc(LMEM_ZEROINIT, cbEntryID);
|
|
|
|
CopyMemory(PropArrayInfo.lpEntryID, lpEntryID, cbEntryID);
|
|
PropArrayInfo.ulFlags |= DETAILS_ShowSummary;
|
|
}
|
|
else if (ulFlags & SHOW_DETAILS)
|
|
{
|
|
// cant show details without a valid entryid
|
|
hr = MAPI_E_INVALID_PARAMETER;
|
|
goto out;
|
|
}
|
|
|
|
*lpbChangesMade = FALSE;
|
|
|
|
if (ulFlags & SHOW_DETAILS)
|
|
{
|
|
if (HR_FAILED(hr = lpIAB->lpVtbl->OpenEntry(lpIAB,
|
|
cbEntryID, // cbEntryID
|
|
lpEntryID, // entryid
|
|
NULL, // interface
|
|
MAPI_BEST_ACCESS, // ulFlags
|
|
&(PropArrayInfo.ulObjectType),
|
|
(LPUNKNOWN *)&(PropArrayInfo.lpPropObj) )))
|
|
{
|
|
// Failed! Hmmm.
|
|
goto out;
|
|
}
|
|
}
|
|
else if (ulFlags & SHOW_OBJECT)
|
|
{
|
|
Assert(lpPropObj);
|
|
PropArrayInfo.lpPropObj = lpPropObj;
|
|
PropArrayInfo.ulObjectType = ulObjectType;
|
|
}
|
|
else
|
|
{
|
|
SBinary sb = {0};
|
|
sb.cb = cbEIDContainer;
|
|
sb.lpb = (LPBYTE) lpEIDContainer;
|
|
if(HR_FAILED(hr = HrCreateNewObject( lpIAB,
|
|
&sb,
|
|
ulObjectType,
|
|
0,
|
|
&(PropArrayInfo.lpPropObj))))
|
|
{
|
|
goto out;
|
|
}
|
|
PropArrayInfo.ulObjectType = ulObjectType;
|
|
PropArrayInfo.cbEntryID = 0;
|
|
PropArrayInfo.lpEntryID = NULL;
|
|
PropArrayInfo.ulFlags |= DETAILS_DNisFMLName;
|
|
}
|
|
|
|
PropArrayInfo.lpIAB = lpIAB;
|
|
|
|
nMaxSheets = (ulObjectType == MAPI_DISTLIST) ? propDLMax : TOTAL_PROP_SHEETS;
|
|
|
|
for(i=0;i<nMaxSheets;i++)
|
|
PropArrayInfo.bPropSheetOpened[i] = FALSE;
|
|
|
|
PropArrayInfo.ulOperationType = ulFlags;
|
|
PropArrayInfo.nRetVal = DETAILS_RESET;
|
|
PropArrayInfo.bSomethingChanged = FALSE;
|
|
|
|
if(InitCryptoLib())
|
|
PropArrayInfo.ulFlags |= DETAILS_ShowCerts;
|
|
|
|
// Never show trident for regular people - only for LDAP contacts
|
|
// PropArrayInfo.bShowTrident = FALSE;
|
|
|
|
GetExtDisplayInfo((LPIAB) lpIAB, &PropArrayInfo, FALSE, (ulObjectType == MAPI_MAILUSER));
|
|
|
|
if(ulObjectType == MAPI_MAILUSER)
|
|
{
|
|
if (CreateDetailsPropertySheet(hWndParent,&PropArrayInfo) == -1)
|
|
{
|
|
// Something failed ...
|
|
hr = E_FAIL;
|
|
goto out;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (CreateDLPropertySheet(hWndParent,&PropArrayInfo) == -1)
|
|
{
|
|
// Something failed ...
|
|
hr = E_FAIL;
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
if (PropArrayInfo.nRetVal == DETAILS_CANCEL)
|
|
{
|
|
hr = MAPI_E_USER_CANCEL;
|
|
goto out;
|
|
}
|
|
|
|
bChanges = PropArrayInfo.bSomethingChanged;
|
|
|
|
/*
|
|
if(!bChanges)
|
|
{
|
|
for(i=0;i<nMaxSheets;i++)
|
|
{
|
|
if(PropArrayInfo.bPropSheetOpened[i])
|
|
{
|
|
// The returned prop array is not null
|
|
// or the sheet was opened (which should return something) but
|
|
// the returned array is null (which means every thing on that
|
|
// particular sheet has been deleted).
|
|
|
|
bChanges = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
|
|
if(!bChanges && PropArrayInfo.lpWED)
|
|
{
|
|
if(PropArrayInfo.lpWED->fDataChanged)
|
|
{
|
|
bChanges = TRUE;
|
|
}
|
|
}
|
|
|
|
if (!bChanges) goto out;
|
|
|
|
// if its an object, dont save changes yet
|
|
if(!(ulFlags & SHOW_OBJECT))
|
|
{
|
|
// Bug: 56220 - a retail-only bug in which for some reason the ObjAccess flag on
|
|
// Groups gets reset to IPROP_READONLY which causes a write failure. I can't figure out
|
|
// the cause for the problem but as a temporary solution, I'm forcing the access flag to
|
|
// say READWRITE and everythng works fine then. Note that if we're at this code point, then
|
|
// the object flag will ALWAYS be READWRITE anyway
|
|
((LPMailUser)PropArrayInfo.lpPropObj)->ulObjAccess = IPROP_READWRITE;
|
|
|
|
hr = (PropArrayInfo.lpPropObj)->lpVtbl->SaveChanges( (PropArrayInfo.lpPropObj), // this
|
|
KEEP_OPEN_READWRITE);
|
|
if(hr == MAPI_E_NOT_ENOUGH_DISK)
|
|
hr = HandleSaveChangedInsufficientDiskSpace( hWndParent,
|
|
(LPMAILUSER) PropArrayInfo.lpPropObj);
|
|
*lpbChangesMade = TRUE;
|
|
}
|
|
|
|
// if we want entryids back, make sure we get them
|
|
{
|
|
if(lppEntryID && lpcbEntryID && !*lppEntryID && !*lpcbEntryID)
|
|
{
|
|
LPSPropValue lpSPV = NULL;
|
|
ULONG ulSPV = 0;
|
|
if(!HR_FAILED(hr = (PropArrayInfo.lpPropObj)->lpVtbl->GetProps(PropArrayInfo.lpPropObj,
|
|
(LPSPropTagArray)&ptaEid, MAPI_UNICODE,
|
|
&ulSPV, &lpSPV)))
|
|
{
|
|
if(lpSPV[ieidPR_ENTRYID].ulPropTag == PR_ENTRYID)
|
|
{
|
|
sc = MAPIAllocateBuffer(lpSPV[ieidPR_ENTRYID].Value.bin.cb, lppEntryID);
|
|
if(!sc)
|
|
{
|
|
*lpcbEntryID = lpSPV[ieidPR_ENTRYID].Value.bin.cb;
|
|
CopyMemory(*lppEntryID, lpSPV[ieidPR_ENTRYID].Value.bin.lpb, *lpcbEntryID);
|
|
}
|
|
}
|
|
MAPIFreeBuffer(lpSPV);
|
|
}
|
|
}
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
out:
|
|
FreeExtDisplayInfo(&PropArrayInfo);
|
|
|
|
LocalFreeAndNull(&PropArrayInfo.lpszOldName);
|
|
|
|
if(PropArrayInfo.szDefaultServerName)
|
|
LocalFree(PropArrayInfo.szDefaultServerName);
|
|
|
|
if(PropArrayInfo.szBackupServerName)
|
|
LocalFree(PropArrayInfo.szBackupServerName);
|
|
|
|
if(PropArrayInfo.lpEntryID)
|
|
LocalFree(PropArrayInfo.lpEntryID);
|
|
|
|
if(PropArrayInfo.lpPropObj && !lpPropObj)
|
|
PropArrayInfo.lpPropObj->lpVtbl->Release(PropArrayInfo.lpPropObj);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
|
|
/*//$$***************************************************************************
|
|
* FUNCTION: CreateDetailsPropertySheet(HWND)
|
|
*
|
|
* PURPOSE: Creates the Details property sheet
|
|
*
|
|
****************************************************************************/
|
|
int CreateDetailsPropertySheet(HWND hwndOwner,
|
|
LPPROP_ARRAY_INFO lpPropArrayInfo)
|
|
{
|
|
PROPSHEETPAGE psp[TOTAL_PROP_SHEETS];
|
|
PROPSHEETHEADER psh;
|
|
//TCHAR szBuf[TOTAL_PROP_SHEETS][MAX_UI_STR];
|
|
LPTSTR * szBuf = NULL;
|
|
TCHAR szBuf2[MAX_UI_STR];
|
|
ULONG ulProp = 0;
|
|
ULONG ulTotal = 0;
|
|
HPROPSHEETPAGE * lph = NULL;
|
|
ULONG ulCount = 0;
|
|
int i = 0;
|
|
int nRet = 0;
|
|
BOOL bRet = FALSE;
|
|
// If it's an NTDS entry and we have the requisite prop sheets, then we are going to hide the
|
|
// WAB's version of the prop sheets and show the NTDS ones upfront instead
|
|
//
|
|
// NTDS folks want us to hide the following: personal, home, business and other
|
|
//
|
|
BOOL bShowNTDSProps = ( lpPropArrayInfo->nNTDSPropSheetPages &&
|
|
lpPropArrayInfo->lphNTDSpages &&
|
|
lpPropArrayInfo->bIsNTDSURL);
|
|
|
|
ulTotal = TOTAL_PROP_SHEETS // Predefined ones +
|
|
+ lpPropArrayInfo->nPropSheetPages
|
|
+ lpPropArrayInfo->nNTDSPropSheetPages;
|
|
|
|
if(!(szBuf = LocalAlloc(LMEM_ZEROINIT, sizeof(LPTSTR)*TOTAL_PROP_SHEETS)))
|
|
goto out;
|
|
for(i=0;i<TOTAL_PROP_SHEETS;i++)
|
|
{
|
|
if(!(szBuf[i] = LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*MAX_UI_STR)))
|
|
goto out;
|
|
}
|
|
|
|
lph = LocalAlloc(LMEM_ZEROINIT, sizeof(HPROPSHEETPAGE) * ulTotal);
|
|
if(!lph)
|
|
goto out;
|
|
|
|
psh.nStartPage = 0;
|
|
|
|
//
|
|
// Initialize info for the various property sheets
|
|
//
|
|
if( (lpPropArrayInfo->ulFlags & DETAILS_ShowSummary) && !bShowNTDSProps )
|
|
{
|
|
// Personal
|
|
psp[propSummary].dwSize = sizeof(PROPSHEETPAGE);
|
|
psp[propSummary].dwFlags = PSP_USETITLE;
|
|
psp[propSummary].hInstance = hinstMapiX;
|
|
psp[propSummary].pszTemplate = MAKEINTRESOURCE(IDD_DETAILS_SUMMARY);
|
|
psp[propSummary].pszIcon = NULL;
|
|
psp[propSummary].pfnDlgProc = fnSummaryProc;
|
|
LoadString(hinstMapiX, idsDetailsSummaryTitle, szBuf[propSummary], MAX_UI_STR);
|
|
psp[propSummary].pszTitle = szBuf[propSummary];
|
|
psp[propSummary].lParam = (LPARAM) lpPropArrayInfo;
|
|
|
|
lph[ulCount] = gpfnCreatePropertySheetPage(&(psp[propSummary]));
|
|
if(lph[ulCount])
|
|
ulCount++;
|
|
|
|
// Start page is personal page
|
|
psh.nStartPage = propSummary;
|
|
}
|
|
|
|
if(!bShowNTDSProps)
|
|
{
|
|
// Personal
|
|
// Check if this is Japan/China/Korea and use the RUBY personal prop sheet instead
|
|
if(bIsRubyLocale())
|
|
lpPropArrayInfo->ulFlags |= DETAILS_UseRubyPersonal;
|
|
|
|
psp[propPersonal].dwSize = sizeof(PROPSHEETPAGE);
|
|
psp[propPersonal].dwFlags = PSP_USETITLE;
|
|
psp[propPersonal].hInstance = hinstMapiX;
|
|
psp[propPersonal].pszTemplate = MAKEINTRESOURCE((lpPropArrayInfo->ulFlags & DETAILS_UseRubyPersonal) ? IDD_DETAILS_PERSONAL_RUBY : IDD_DETAILS_PERSONAL);
|
|
psp[propPersonal].pszIcon = NULL;
|
|
psp[propPersonal].pfnDlgProc = fnPersonalProc;
|
|
LoadString(hinstMapiX, idsName, szBuf[propPersonal], MAX_UI_STR);
|
|
psp[propPersonal].pszTitle = szBuf[propPersonal];
|
|
psp[propPersonal].lParam = (LPARAM) lpPropArrayInfo;
|
|
|
|
lph[ulCount] = gpfnCreatePropertySheetPage(&(psp[propPersonal]));
|
|
|
|
if(lph[ulCount])
|
|
ulCount++;
|
|
}
|
|
|
|
if(!bShowNTDSProps)
|
|
{
|
|
// Home
|
|
psp[propHome].dwSize = sizeof(PROPSHEETPAGE);
|
|
psp[propHome].dwFlags = PSP_USETITLE;
|
|
psp[propHome].hInstance = hinstMapiX;
|
|
psp[propHome].pszTemplate = MAKEINTRESOURCE(IDD_DETAILS_HOME);
|
|
psp[propHome].pszIcon = NULL;
|
|
psp[propHome].pfnDlgProc = fnHomeProc;
|
|
LoadString(hinstMapiX, idsDetailsHomeTitle, szBuf[propHome], MAX_UI_STR);
|
|
psp[propHome].pszTitle = szBuf[propHome];
|
|
psp[propHome].lParam = (LPARAM) lpPropArrayInfo;
|
|
|
|
lph[ulCount] = gpfnCreatePropertySheetPage(&(psp[propHome]));
|
|
if(lph[ulCount])
|
|
ulCount++;
|
|
}
|
|
|
|
if(!bShowNTDSProps)
|
|
{
|
|
// Business
|
|
psp[propBusiness].dwSize = sizeof(PROPSHEETPAGE);
|
|
psp[propBusiness].dwFlags = PSP_USETITLE;
|
|
psp[propBusiness].hInstance = hinstMapiX;
|
|
psp[propBusiness].pszTemplate = MAKEINTRESOURCE(IDD_DETAILS_BUSINESS);
|
|
psp[propBusiness].pszIcon = NULL;
|
|
psp[propBusiness].pfnDlgProc = fnBusinessProc;
|
|
LoadString(hinstMapiX, idsDetailsBusinessTitle, szBuf[propBusiness], MAX_UI_STR);
|
|
psp[propBusiness].pszTitle = szBuf[propBusiness];
|
|
psp[propBusiness].lParam = (LPARAM) lpPropArrayInfo;
|
|
|
|
lph[ulCount] = gpfnCreatePropertySheetPage(&(psp[propBusiness]));
|
|
if(lph[ulCount])
|
|
ulCount++;
|
|
}
|
|
|
|
if(!bShowNTDSProps)
|
|
{
|
|
psp[propFamily].dwSize = sizeof(PROPSHEETPAGE);
|
|
psp[propFamily].dwFlags = PSP_USETITLE;
|
|
psp[propFamily].hInstance = hinstMapiX;
|
|
psp[propFamily].pszTemplate = MAKEINTRESOURCE(IDD_DETAILS_FAMILY);
|
|
psp[propFamily].pszIcon = NULL;
|
|
psp[propFamily].pfnDlgProc = fnFamilyProc;
|
|
LoadString(hinstMapiX, idsDetailsPersonalTitle, szBuf[propFamily], MAX_UI_STR);
|
|
psp[propFamily].pszTitle = szBuf[propFamily];
|
|
psp[propFamily].lParam = (LPARAM) lpPropArrayInfo;
|
|
lph[ulCount] = gpfnCreatePropertySheetPage(&(psp[propFamily]));
|
|
if(lph[ulCount])
|
|
ulCount++;
|
|
}
|
|
|
|
if(!bShowNTDSProps)
|
|
{
|
|
// Notes
|
|
psp[propNotes].dwSize = sizeof(PROPSHEETPAGE);
|
|
psp[propNotes].dwFlags = PSP_USETITLE;
|
|
psp[propNotes].hInstance = hinstMapiX;
|
|
psp[propNotes].pszTemplate = MAKEINTRESOURCE(IDD_DETAILS_NOTES);
|
|
psp[propNotes].pszIcon = NULL;
|
|
psp[propNotes].pfnDlgProc = fnNotesProc;
|
|
LoadString(hinstMapiX, idsDetailsNotesTitle, szBuf[propNotes], MAX_UI_STR);
|
|
psp[propNotes].pszTitle = szBuf[propNotes];
|
|
psp[propNotes].lParam = (LPARAM) lpPropArrayInfo;
|
|
|
|
lph[ulCount] = gpfnCreatePropertySheetPage(&(psp[propNotes]));
|
|
if(lph[ulCount])
|
|
ulCount++;
|
|
}
|
|
|
|
if(bShowNTDSProps) //now insert the NTDS props at this point instead of the above lot..
|
|
{
|
|
// Now do the extended props if any
|
|
for(i=0;i<lpPropArrayInfo->nNTDSPropSheetPages;i++)
|
|
{
|
|
if(lpPropArrayInfo->lphNTDSpages)
|
|
{
|
|
lph[ulCount] = lpPropArrayInfo->lphNTDSpages[i];
|
|
ulCount++;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Conferencing
|
|
psp[propConferencing].dwSize = sizeof(PROPSHEETPAGE);
|
|
psp[propConferencing].dwFlags = PSP_USETITLE;
|
|
psp[propConferencing].hInstance = hinstMapiX;
|
|
psp[propConferencing].pszTemplate = MAKEINTRESOURCE(IDD_DETAILS_NTMTG);
|
|
psp[propConferencing].pszIcon = NULL;
|
|
psp[propConferencing].pfnDlgProc = fnConferencingProc;
|
|
{
|
|
TCHAR sz[MAX_PATH];
|
|
LONG cbSize = CharSizeOf(sz);
|
|
*sz='\0';
|
|
if(RegQueryValue(HKEY_LOCAL_MACHINE, szInternetCallKey, sz, &cbSize) == ERROR_SUCCESS
|
|
&& lstrlen(sz)
|
|
&& !lstrcmpi(sz,TEXT("Microsoft NetMeeting")))
|
|
{
|
|
StrCpyN(szBuf[propConferencing], TEXT("NetMeeting"), MAX_UI_STR);
|
|
}
|
|
else
|
|
LoadString(hinstMapiX, idsDetailsConferencingTitle, szBuf[propConferencing], MAX_UI_STR);
|
|
}
|
|
psp[propConferencing].pszTitle = szBuf[propConferencing];
|
|
psp[propConferencing].lParam = (LPARAM) lpPropArrayInfo;
|
|
|
|
lph[ulCount] = gpfnCreatePropertySheetPage(&(psp[propConferencing]));
|
|
if(lph[ulCount])
|
|
ulCount++;
|
|
|
|
|
|
ulProp = propConferencing + 1;
|
|
|
|
|
|
if(lpPropArrayInfo->ulFlags & DETAILS_ShowCerts)
|
|
{
|
|
// Certificates
|
|
psp[ulProp].dwSize = sizeof(PROPSHEETPAGE);
|
|
psp[ulProp].dwFlags = PSP_USETITLE;
|
|
psp[ulProp].hInstance = hinstMapiX;
|
|
psp[ulProp].pszTemplate = MAKEINTRESOURCE(IDD_DETAILS_CERT);
|
|
psp[ulProp].pszIcon = NULL;
|
|
psp[ulProp].pfnDlgProc = fnCertProc;
|
|
LoadString(hinstMapiX, idsDetailsCertTitle, szBuf[propCert], MAX_UI_STR);
|
|
psp[ulProp].pszTitle = szBuf[propCert];
|
|
psp[ulProp].lParam = (LPARAM) lpPropArrayInfo;
|
|
|
|
lph[ulCount] = gpfnCreatePropertySheetPage(&(psp[ulProp]));
|
|
if(lph[ulCount])
|
|
ulCount++;
|
|
|
|
ulProp++;
|
|
}
|
|
|
|
|
|
if( !bShowNTDSProps &&
|
|
(lpPropArrayInfo->ulFlags & DETAILS_ShowOrg) )
|
|
{
|
|
// Organization
|
|
psp[ulProp].dwSize = sizeof(PROPSHEETPAGE);
|
|
psp[ulProp].dwFlags = PSP_USETITLE;
|
|
psp[ulProp].hInstance = hinstMapiX;
|
|
psp[ulProp].pszTemplate = MAKEINTRESOURCE(IDD_DETAILS_ORG);
|
|
psp[ulProp].pszIcon = NULL;
|
|
psp[ulProp].pfnDlgProc = fnOrgProc;
|
|
LoadString(hinstMapiX, idsDetailsOrgTitle, szBuf[propOrg], MAX_UI_STR);
|
|
psp[ulProp].pszTitle = szBuf[propOrg];
|
|
psp[ulProp].lParam = (LPARAM) lpPropArrayInfo;
|
|
|
|
lph[ulCount] = gpfnCreatePropertySheetPage(&(psp[ulProp]));
|
|
if(lph[ulCount])
|
|
ulCount++;
|
|
|
|
ulProp++;
|
|
}
|
|
|
|
|
|
if(lpPropArrayInfo->ulFlags & DETAILS_ShowTrident)
|
|
{
|
|
// Trident sheet
|
|
psp[ulProp].dwSize = sizeof(PROPSHEETPAGE);
|
|
psp[ulProp].dwFlags = PSP_USETITLE;
|
|
psp[ulProp].hInstance = hinstMapiX;
|
|
psp[ulProp].pszTemplate = MAKEINTRESOURCE(IDD_DETAILS_TRIDENT);
|
|
psp[ulProp].pszIcon = NULL;
|
|
psp[ulProp].pfnDlgProc = fnTridentProc;
|
|
LoadString(hinstMapiX, idsDetailsTridentTitle, szBuf[propTrident], MAX_UI_STR);
|
|
psp[ulProp].pszTitle = szBuf[propTrident];
|
|
psp[ulProp].lParam = (LPARAM) lpPropArrayInfo;
|
|
|
|
lph[ulCount] = gpfnCreatePropertySheetPage(&(psp[ulProp]));
|
|
if(lph[ulCount])
|
|
{
|
|
// Start page is trident page
|
|
psh.nStartPage = ulCount;
|
|
ulCount++;
|
|
}
|
|
|
|
lpPropArrayInfo->ulTridentPageIndex = ulProp;
|
|
ulProp++;
|
|
}
|
|
|
|
|
|
// Now do the extended props if any
|
|
for(i=0;i<lpPropArrayInfo->nPropSheetPages;i++)
|
|
{
|
|
if(lpPropArrayInfo->lphpages)
|
|
{
|
|
lph[ulCount] = lpPropArrayInfo->lphpages[i];
|
|
ulCount++;
|
|
}
|
|
}
|
|
|
|
/*** US dialogs get truncated on FE OSes .. we want the comctl to fix the truncation
|
|
but this is only implemented in IE4.01 and beyond .. the problem with this being
|
|
that wab is specifically compiled with the IE = 0x0300 so we're not pulling in the
|
|
correct flag from the commctrl header .. so we will define the flag here and pray
|
|
that commctrl never changes it ***/
|
|
#define PSH_USEPAGELANG 0x00200000 // use frame dialog template matched to page
|
|
/*** ***/
|
|
|
|
psh.dwSize = sizeof(PROPSHEETHEADER);
|
|
psh.dwFlags = PSH_NOAPPLYNOW;
|
|
if(bIsIE401OrGreater())
|
|
psh.dwFlags |= PSH_USEPAGELANG;
|
|
psh.hwndParent = hwndOwner;
|
|
psh.hInstance = hinstMapiX;
|
|
psh.pszIcon = NULL;
|
|
LoadString(hinstMapiX, IDS_DETAILS_CAPTION, szBuf2, CharSizeOf(szBuf2));
|
|
psh.pszCaption = szBuf2;
|
|
psh.nPages = ulCount; // ulProp //sizeof(psp) / sizeof(PROPSHEETPAGE);
|
|
|
|
psh.phpage = lph;
|
|
|
|
nRet = (int) gpfnPropertySheet(&psh);
|
|
|
|
bRet = TRUE;
|
|
out:
|
|
LocalFreeAndNull((LPVOID*)&lph);
|
|
|
|
if(szBuf)
|
|
{
|
|
for(i=0;i<TOTAL_PROP_SHEETS;i++)
|
|
LocalFreeAndNull(&(szBuf[i]));
|
|
LocalFreeAndNull((LPVOID*)&szBuf);
|
|
}
|
|
return nRet;
|
|
}
|
|
|
|
/* Filling in the Data in a Prop Sheet
|
|
|
|
Since most props handled in the UI are string props, and it's just a
|
|
matter of doing SetText/GetText with the data on the appropriate edit
|
|
control, we create control-property pairs of edit-controls and string props
|
|
and use them to fill in props in a simple loop
|
|
|
|
Non string props and named props end up needing special handling
|
|
*/
|
|
|
|
typedef struct _tagIDProp
|
|
{
|
|
ULONG ulPropTag;
|
|
int idCtl;
|
|
|
|
} ID_PROP;
|
|
|
|
|
|
// Control IDs corresponding to the Personal property sheet
|
|
|
|
ID_PROP idPropPersonal[]=
|
|
{
|
|
{PR_DISPLAY_NAME, IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME},
|
|
{PR_GIVEN_NAME, IDC_DETAILS_PERSONAL_EDIT_FIRSTNAME},
|
|
{PR_SURNAME, IDC_DETAILS_PERSONAL_EDIT_LASTNAME},
|
|
{PR_MIDDLE_NAME, IDC_DETAILS_PERSONAL_EDIT_MIDDLENAME},
|
|
{PR_NICKNAME, IDC_DETAILS_PERSONAL_EDIT_NICKNAME},
|
|
{PR_DISPLAY_NAME_PREFIX, IDC_DETAILS_PERSONAL_EDIT_TITLE},
|
|
{0, IDC_DETAILS_PERSONAL_EDIT_ADDEMAIL},
|
|
{PR_NULL/*YOMI_LAST*/,IDC_DETAILS_PERSONAL_STATIC_RUBYLAST},
|
|
{PR_NULL/*YOMI_FIRST*/,IDC_DETAILS_PERSONAL_STATIC_RUBYFIRST}
|
|
};
|
|
const ULONG idPropPersonalCount = 9;
|
|
|
|
|
|
|
|
// Control IDs corresponding to the Home property sheet
|
|
|
|
ID_PROP idPropHome[]=
|
|
{
|
|
{PR_HOME_ADDRESS_STREET, IDC_DETAILS_HOME_EDIT_ADDRESS},
|
|
{PR_HOME_ADDRESS_CITY, IDC_DETAILS_HOME_EDIT_CITY},
|
|
{PR_HOME_ADDRESS_POSTAL_CODE, IDC_DETAILS_HOME_EDIT_ZIP},
|
|
{PR_HOME_ADDRESS_STATE_OR_PROVINCE, IDC_DETAILS_HOME_EDIT_STATE},
|
|
{PR_HOME_ADDRESS_COUNTRY, IDC_DETAILS_HOME_EDIT_COUNTRY},
|
|
{PR_PERSONAL_HOME_PAGE, IDC_DETAILS_HOME_EDIT_URL},
|
|
{PR_HOME_TELEPHONE_NUMBER, IDC_DETAILS_HOME_EDIT_PHONE},
|
|
{PR_HOME_FAX_NUMBER, IDC_DETAILS_HOME_EDIT_FAX},
|
|
{PR_CELLULAR_TELEPHONE_NUMBER, IDC_DETAILS_HOME_EDIT_CELLULAR},
|
|
{PR_NULL/*PR_WAB_POSTALID*/, IDC_DETAILS_HOME_CHECK_DEFAULTADDRESS},
|
|
};
|
|
#define idPropHomePostalID 9 // since POSTALID is dynamically generated prop, it needs to be reset anytime the array is used
|
|
const ULONG idPropHomeCount = 10;
|
|
|
|
|
|
// Control IDs corresponding to the Business property sheet
|
|
|
|
ID_PROP idPropBusiness[]=
|
|
{
|
|
{PR_BUSINESS_ADDRESS_STREET, IDC_DETAILS_BUSINESS_EDIT_ADDRESS},
|
|
{PR_BUSINESS_ADDRESS_CITY, IDC_DETAILS_BUSINESS_EDIT_CITY},
|
|
{PR_BUSINESS_ADDRESS_POSTAL_CODE, IDC_DETAILS_BUSINESS_EDIT_ZIP},
|
|
{PR_BUSINESS_ADDRESS_STATE_OR_PROVINCE, IDC_DETAILS_BUSINESS_EDIT_STATE},
|
|
{PR_BUSINESS_ADDRESS_COUNTRY, IDC_DETAILS_BUSINESS_EDIT_COUNTRY},
|
|
{PR_BUSINESS_HOME_PAGE, IDC_DETAILS_BUSINESS_EDIT_URL},
|
|
{PR_BUSINESS_TELEPHONE_NUMBER, IDC_DETAILS_BUSINESS_EDIT_PHONE},
|
|
{PR_BUSINESS_FAX_NUMBER, IDC_DETAILS_BUSINESS_EDIT_FAX},
|
|
{PR_PAGER_TELEPHONE_NUMBER, IDC_DETAILS_BUSINESS_EDIT_PAGER},
|
|
{PR_COMPANY_NAME, IDC_DETAILS_BUSINESS_EDIT_COMPANY},
|
|
{PR_TITLE, IDC_DETAILS_BUSINESS_EDIT_JOBTITLE},
|
|
{PR_DEPARTMENT_NAME, IDC_DETAILS_BUSINESS_EDIT_DEPARTMENT},
|
|
{PR_OFFICE_LOCATION, IDC_DETAILS_BUSINESS_EDIT_OFFICE},
|
|
{PR_NULL/*PR_WAB_IPPHONE*/, IDC_DETAILS_BUSINESS_EDIT_IPPHONE},
|
|
{PR_NULL/*PR_WAB_POSTALID*/, IDC_DETAILS_BUSINESS_CHECK_DEFAULTADDRESS},
|
|
};
|
|
#define idPropBusIPPhone 13 // since PR_WAB_IPPHONE is dynamically generated prop, it needs to be reset anytime the array is used
|
|
#define idPropBusPostalID 14 // since POSTALID is dynamically generated prop, it needs to be reset anytime the array is used
|
|
const ULONG idPropBusinessCount = 15;
|
|
|
|
|
|
// Control IDs corresponding to the Notes property sheet
|
|
ID_PROP idPropNotes[] =
|
|
{
|
|
{PR_COMMENT, IDC_DETAILS_NOTES_EDIT_NOTES} //PR_COMMENT
|
|
};
|
|
const ULONG idPropNotesCount = 1;
|
|
|
|
// Control IDs corresponding to the Family property sheet
|
|
ID_PROP idPropFamily[] =
|
|
{
|
|
{PR_SPOUSE_NAME, IDC_DETAILS_FAMILY_EDIT_SPOUSE},
|
|
{PR_GENDER, IDC_DETAILS_HOME_COMBO_GENDER},
|
|
{PR_BIRTHDAY, IDC_DETAILS_FAMILY_DATE_BIRTHDAY},
|
|
{PR_WEDDING_ANNIVERSARY, IDC_DETAILS_FAMILY_DATE_ANNIVERSARY},
|
|
{PR_CHILDRENS_NAMES, IDC_DETAILS_FAMILY_LIST_CHILDREN}
|
|
};
|
|
const ULONG idPropFamilyCount = 5;
|
|
|
|
|
|
/*
|
|
A list of all the buttons on all the propsheets .. this is mostly used to render the buttons
|
|
disabled when reading read-only data (such as vCards and LDAP)
|
|
*/
|
|
ULONG idSetReadOnlyControls[] = {
|
|
IDC_DETAILS_PERSONAL_BUTTON_ADDEMAIL,
|
|
IDC_DETAILS_PERSONAL_BUTTON_REMOVE,
|
|
IDC_DETAILS_PERSONAL_BUTTON_SETDEFAULT,
|
|
IDC_DETAILS_PERSONAL_BUTTON_EDIT,
|
|
IDC_DETAILS_HOME_BUTTON_URL,
|
|
IDC_DETAILS_BUSINESS_BUTTON_URL,
|
|
IDC_DETAILS_CERT_BUTTON_PROPERTIES,
|
|
IDC_DETAILS_CERT_BUTTON_REMOVE,
|
|
IDC_DETAILS_CERT_BUTTON_SETDEFAULT,
|
|
IDC_DETAILS_CERT_BUTTON_IMPORT,
|
|
IDC_DETAILS_CERT_BUTTON_EXPORT,
|
|
IDC_DETAILS_NTMTG_BUTTON_ADDSERVER,
|
|
IDC_DETAILS_NTMTG_BUTTON_EDIT,
|
|
IDC_DETAILS_NTMTG_BUTTON_REMOVE,
|
|
IDC_DETAILS_NTMTG_BUTTON_SETDEFAULT,
|
|
IDC_DETAILS_NTMTG_BUTTON_SETBACKUP,
|
|
IDC_DETAILS_NTMTG_COMBO_EMAIL,
|
|
IDC_DETAILS_NTMTG_LIST_SERVERS,
|
|
IDC_DETAILS_NTMTG_EDIT_ADDSERVER,
|
|
IDC_DETAILS_FAMILY_EDIT_SPOUSE,
|
|
IDC_DETAILS_FAMILY_LIST_CHILDREN,
|
|
IDC_DETAILS_FAMILY_BUTTON_ADDCHILD,
|
|
IDC_DETAILS_FAMILY_BUTTON_EDITCHILD,
|
|
IDC_DETAILS_FAMILY_BUTTON_REMOVECHILD,
|
|
IDC_DETAILS_FAMILY_DATE_BIRTHDAY,
|
|
IDC_DETAILS_FAMILY_DATE_ANNIVERSARY,
|
|
IDC_DETAILS_HOME_COMBO_GENDER,
|
|
IDC_DETAILS_HOME_CHECK_DEFAULTADDRESS,
|
|
IDC_DETAILS_BUSINESS_CHECK_DEFAULTADDRESS,
|
|
IDC_DETAILS_PERSONAL_LIST,
|
|
IDC_DETAILS_PERSONAL_CHECK_RICHINFO,
|
|
IDC_DETAILS_CERT_LIST,
|
|
IDC_DETAILS_CERT_COMBO,
|
|
|
|
};
|
|
const ULONG idSetReadOnlyCount = 33;
|
|
|
|
|
|
|
|
/*//$$***************************************************************************
|
|
* FUNCTION: SetDetailsUI
|
|
*
|
|
* PURPOSE: Generic function that is used for doing the legwork for preparing
|
|
* the prop sheet to receive the data. This will include setting the text limits
|
|
* rendering controls read-only etc. Most of the propsheets call this same
|
|
* function since there is a lot of common work for each property sheet.
|
|
* To add future prop sheets, you can extend this function or you can just
|
|
* write your own...
|
|
*
|
|
****************************************************************************/
|
|
BOOL SetDetailsUI(HWND hDlg, LPPROP_ARRAY_INFO lpPai, ULONG ulOperationType, int nPropSheet)
|
|
{
|
|
ULONG i =0;
|
|
ID_PROP * lpidProp = NULL;
|
|
ULONG idCount = 0;
|
|
|
|
switch(nPropSheet)
|
|
{
|
|
case propPersonal:
|
|
//Check the send-plain text check box on the UI off by default
|
|
CheckDlgButton(hDlg, IDC_DETAILS_PERSONAL_CHECK_RICHINFO, BST_UNCHECKED);
|
|
// Initialize the list view
|
|
lpPai->hWndDisplayNameField = GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME);
|
|
HrInitDetlsListView(GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_LIST), LVS_REPORT, LV_EMAIL);
|
|
if (ulOperationType == SHOW_ONE_OFF)
|
|
{
|
|
EnableWindow(lpPai->hWndDisplayNameField , FALSE);
|
|
EnableWindow(GetDlgItem(GetParent(hDlg), IDOK), FALSE);
|
|
}
|
|
lpidProp = idPropPersonal;
|
|
idCount = idPropPersonalCount;
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_ADDEMAIL),FALSE);
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_REMOVE),FALSE);
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_SETDEFAULT),FALSE);
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_EDIT),FALSE);
|
|
SendMessage(GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME),
|
|
CB_LIMITTEXT, (WPARAM) EDIT_LEN, 0);
|
|
if(lpPai->ulFlags & DETAILS_UseRubyPersonal)
|
|
{
|
|
SetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_STATIC_RUBYFIRST, szEmpty);
|
|
SetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_STATIC_RUBYLAST, szEmpty);
|
|
|
|
// [PaulHi] 3/29/99 Subclass the first and last name edit boxes. The
|
|
// static Ruby fields will be updated automatically.
|
|
// Only do this for Japanese locales.
|
|
if (GetUserDefaultLCID() == 0x0411)
|
|
{
|
|
HWND hWndEdit;
|
|
WNDPROC OldWndProc = NULL;
|
|
|
|
hWndEdit = GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_EDIT_FIRSTNAME);
|
|
Assert(hWndEdit);
|
|
OldWndProc = (WNDPROC)SetWindowLongPtr(hWndEdit, GWLP_WNDPROC, (LONG_PTR)RubySubClassedProc);
|
|
Assert(GetWindowLongPtr(hWndEdit, GWLP_USERDATA) == 0);
|
|
SetWindowLongPtr(hWndEdit, GWLP_USERDATA, (LONG_PTR)OldWndProc);
|
|
|
|
hWndEdit = GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_EDIT_LASTNAME);
|
|
Assert(hWndEdit);
|
|
OldWndProc = (WNDPROC)SetWindowLongPtr(hWndEdit, GWLP_WNDPROC, (LONG_PTR)RubySubClassedProc);
|
|
Assert(GetWindowLongPtr(hWndEdit, GWLP_USERDATA) == 0);
|
|
SetWindowLongPtr(hWndEdit, GWLP_USERDATA, (LONG_PTR)OldWndProc);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case propHome:
|
|
lpidProp = idPropHome;
|
|
idCount = idPropHomeCount;
|
|
lpidProp[idPropHomePostalID].ulPropTag = PR_WAB_POSTALID;
|
|
ShowHideMapButton(GetDlgItem(hDlg, IDC_DETAILS_HOME_BUTTON_MAP));
|
|
ImmAssociateContext(GetDlgItem(hDlg, IDC_DETAILS_HOME_EDIT_PHONE), (HIMC) NULL);
|
|
ImmAssociateContext(GetDlgItem(hDlg, IDC_DETAILS_HOME_EDIT_FAX), (HIMC) NULL);
|
|
ImmAssociateContext(GetDlgItem(hDlg, IDC_DETAILS_HOME_EDIT_CELLULAR), (HIMC) NULL);
|
|
break;
|
|
|
|
case propBusiness:
|
|
lpidProp = idPropBusiness;
|
|
idCount = idPropBusinessCount;
|
|
lpidProp[idPropBusIPPhone].ulPropTag = PR_WAB_IPPHONE;
|
|
lpidProp[idPropBusPostalID].ulPropTag = PR_WAB_POSTALID;
|
|
|
|
ShowHideMapButton(GetDlgItem(hDlg, IDC_DETAILS_BUSINESS_BUTTON_MAP));
|
|
ImmAssociateContext(GetDlgItem(hDlg, IDC_DETAILS_BUSINESS_EDIT_PHONE), (HIMC) NULL);
|
|
ImmAssociateContext(GetDlgItem(hDlg, IDC_DETAILS_BUSINESS_EDIT_FAX), (HIMC) NULL);
|
|
ImmAssociateContext(GetDlgItem(hDlg, IDC_DETAILS_BUSINESS_EDIT_PAGER), (HIMC) NULL);
|
|
ImmAssociateContext(GetDlgItem(hDlg, IDC_DETAILS_BUSINESS_EDIT_IPPHONE), (HIMC) NULL);
|
|
break;
|
|
|
|
case propNotes:
|
|
lpidProp = idPropNotes;
|
|
idCount = idPropNotesCount;
|
|
break;
|
|
|
|
case propFamily:
|
|
lpidProp = idPropFamily;
|
|
idCount = idPropFamilyCount;
|
|
{ // Gender Combo stuff
|
|
TCHAR szBuf[MAX_PATH];
|
|
HWND hWndCombo = GetDlgItem(hDlg, IDC_DETAILS_HOME_COMBO_GENDER);
|
|
SendMessage(hWndCombo, CB_RESETCONTENT, 0, 0);
|
|
for(i=0;i<3;i++)
|
|
{
|
|
LoadString(hinstMapiX, idsGender+i, szBuf, CharSizeOf(szBuf));
|
|
SendMessage(hWndCombo, CB_ADDSTRING, 0, (LPARAM) szBuf);
|
|
}
|
|
SendMessage(hWndCombo, CB_SETCURSEL, 0, 0); //default is unspecified gender
|
|
}
|
|
//Need to create the month date controls for this dialog
|
|
CreateDateTimeControl(hDlg, IDC_STATIC_BIRTHDAY, IDC_DETAILS_FAMILY_DATE_BIRTHDAY);
|
|
CreateDateTimeControl(hDlg, IDC_STATIC_ANNIVERSARY, IDC_DETAILS_FAMILY_DATE_ANNIVERSARY);
|
|
//Setup the ListView for the children's names
|
|
HrInitDetlsListView(GetDlgItem(hDlg, IDC_DETAILS_FAMILY_LIST_CHILDREN), LVS_REPORT, LV_KIDS);
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_FAMILY_BUTTON_REMOVECHILD),FALSE);
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_FAMILY_BUTTON_EDITCHILD),FALSE);
|
|
break;
|
|
|
|
case propCert:
|
|
HrInitDetlsListView(GetDlgItem(hDlg, IDC_DETAILS_CERT_LIST), LVS_REPORT, LV_CERT);
|
|
lpidProp = NULL;
|
|
idCount = 0;
|
|
break;
|
|
|
|
case propTrident:
|
|
if (ulOperationType != SHOW_ONE_OFF)
|
|
{
|
|
HWND hwnd = GetDlgItem(hDlg, IDC_DETAILS_TRIDENT_BUTTON_ADDTOWAB);
|
|
EnableWindow(hwnd, FALSE);
|
|
ShowWindow(hwnd, SW_HIDE);
|
|
}
|
|
lpidProp = NULL;
|
|
idCount = 0;
|
|
break;
|
|
|
|
case propConferencing:
|
|
// If there is a Internet Call client installed, enable CallNow
|
|
// else disable it
|
|
{
|
|
LONG cbSize = 0;
|
|
if(RegQueryValue(HKEY_LOCAL_MACHINE, szInternetCallKey, NULL, &cbSize) == ERROR_SUCCESS && cbSize >= 1)
|
|
EnableWindow(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_BUTTON_CALL), TRUE);
|
|
else
|
|
EnableWindow(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_BUTTON_CALL), FALSE);
|
|
|
|
HrInitDetlsListView(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_LIST_SERVERS), LVS_REPORT, LV_SERVER);
|
|
lpPai->hWndComboConf = GetDlgItem(hDlg, IDC_DETAILS_NTMTG_COMBO_EMAIL);
|
|
|
|
lpPai->nDefaultServerIndex = -1;
|
|
lpPai->nBackupServerIndex = -1;
|
|
lpPai->cchDefaultServerName = MAX_UI_STR;
|
|
lpPai->szDefaultServerName = LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*(lpPai->cchDefaultServerName));
|
|
lpPai->cchBackupServerName = MAX_UI_STR;
|
|
lpPai->szBackupServerName = LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*(lpPai->cchBackupServerName));
|
|
EnableWindow(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_BUTTON_ADDSERVER), FALSE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_BUTTON_EDIT), FALSE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_BUTTON_REMOVE), FALSE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_BUTTON_SETDEFAULT), FALSE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_BUTTON_SETBACKUP), FALSE);
|
|
}
|
|
break;
|
|
}
|
|
|
|
if(lpidProp && idCount)
|
|
{
|
|
|
|
//Set max input limits on the edit fields
|
|
for(i=0;i<idCount;i++)
|
|
{
|
|
ULONG ulLen = EDIT_LEN; //512
|
|
HWND hWndC= GetDlgItem(hDlg,lpidProp[i].idCtl);
|
|
if(!hWndC)
|
|
continue;
|
|
// Some fields need to be longer than others ...
|
|
switch(lpidProp[i].idCtl)
|
|
{
|
|
case IDC_DETAILS_HOME_EDIT_URL:
|
|
case IDC_DETAILS_BUSINESS_EDIT_URL:
|
|
case IDC_DETAILS_NOTES_EDIT_NOTES:
|
|
ulLen = MAX_EDIT_LEN-MAX_DISPLAY_NAME_LENGTH; // ~2K
|
|
break;
|
|
case IDC_DETAILS_HOME_CHECK_DEFAULTADDRESS: //make exceptions for non-string props
|
|
case IDC_DETAILS_BUSINESS_CHECK_DEFAULTADDRESS:
|
|
case IDC_DETAILS_HOME_COMBO_GENDER:
|
|
continue;
|
|
break;
|
|
}
|
|
SendMessage(hWndC,EM_SETLIMITTEXT,(WPARAM) ulLen,0);
|
|
if (ulOperationType == SHOW_ONE_OFF) // Make all the controls readonly
|
|
SendMessage(hWndC,EM_SETREADONLY,(WPARAM) TRUE,0);
|
|
}
|
|
|
|
}
|
|
|
|
if(nPropSheet == propHome)
|
|
SetHTTPPrefix(hDlg, IDC_DETAILS_HOME_EDIT_URL);
|
|
else if(nPropSheet == propBusiness)
|
|
SetHTTPPrefix(hDlg, IDC_DETAILS_BUSINESS_EDIT_URL);
|
|
|
|
if (ulOperationType == SHOW_ONE_OFF)
|
|
{
|
|
// Make all the readonlyable controls readonly
|
|
for(i=0;i<idSetReadOnlyCount;i++)
|
|
{
|
|
switch(idSetReadOnlyControls[i])
|
|
{
|
|
case IDC_DETAILS_HOME_BUTTON_URL:
|
|
case IDC_DETAILS_BUSINESS_BUTTON_URL:
|
|
break;
|
|
default:
|
|
{
|
|
HWND hWnd = GetDlgItem(hDlg,idSetReadOnlyControls[i]);
|
|
if(hWnd)
|
|
EnableWindow(hWnd,FALSE);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Set the font of all the children to the default GUI font
|
|
EnumChildWindows( hDlg, SetChildDefaultGUIFont, (LPARAM) 0);
|
|
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// RubySubClassedProc
|
|
//
|
|
// Subclassed window proc for the Ruby static edit fields. Used to provide
|
|
// IME support.
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
#define CCHMAX_RUBYSIZE 1024
|
|
|
|
LRESULT CALLBACK RubySubClassedProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
WNDPROC OldWndProc = (WNDPROC)GetWindowLongPtr(hWnd, GWLP_USERDATA);
|
|
HIMC hIMC;
|
|
WCHAR wszTemp[CCHMAX_RUBYSIZE];
|
|
WCHAR wszRuby[CCHMAX_RUBYSIZE];
|
|
HWND hWndParent;
|
|
LONG lId;
|
|
HWND hWndRuby = NULL;
|
|
|
|
Assert(OldWndProc);
|
|
|
|
switch (uMsg)
|
|
{
|
|
case WM_IME_COMPOSITION:
|
|
if ( (hIMC = ImmGetContext(hWnd)) )
|
|
{
|
|
// IME does not include zero terminating character
|
|
ZeroMemory(wszTemp, sizeof(wszTemp));
|
|
ZeroMemory(wszRuby, sizeof(wszRuby));
|
|
|
|
ImmGetCompositionStringW(hIMC, GCS_RESULTREADSTR, wszTemp, (sizeof(WCHAR) * (CCHMAX_RUBYSIZE-1)));
|
|
// This subclassing only takes place for Japanese systems (lcid = 0x0411).
|
|
LCMapString(0x0411, LCMAP_FULLWIDTH | LCMAP_HIRAGANA, wszTemp, lstrlen(wszTemp), wszRuby, CCHMAX_RUBYSIZE-1);
|
|
ImmReleaseContext(hWnd, hIMC);
|
|
|
|
// Set either the first or last name ruby field, depending on which edit control
|
|
// this is.
|
|
hWndParent = GetParent(hWnd);
|
|
Assert(hWndParent);
|
|
lId = (LONG)GetWindowLongPtr(hWnd, GWL_ID);
|
|
|
|
switch (lId)
|
|
{
|
|
case IDC_DETAILS_PERSONAL_EDIT_FIRSTNAME:
|
|
hWndRuby = GetDlgItem(hWndParent, IDC_DETAILS_PERSONAL_STATIC_RUBYFIRST);
|
|
break;
|
|
|
|
case IDC_DETAILS_PERSONAL_EDIT_LASTNAME:
|
|
hWndRuby = GetDlgItem(hWndParent, IDC_DETAILS_PERSONAL_STATIC_RUBYLAST);
|
|
break;
|
|
|
|
default:
|
|
Assert(0); // What the heck did we subclass if not the two Ruby fields above?
|
|
break;
|
|
}
|
|
|
|
if (hWndRuby)
|
|
{
|
|
BOOL bDoConcat = TRUE;
|
|
DWORD dwStartSel = 0;
|
|
DWORD dwEndSel = 0;
|
|
|
|
// If we have selected text in the edit field or it is empty then
|
|
// start over in Ruby field
|
|
SendMessage(hWnd, EM_GETSEL, (WPARAM)&dwStartSel, (LPARAM)&dwEndSel);
|
|
GetWindowText(hWnd, wszTemp, (CCHMAX_RUBYSIZE-1));
|
|
if ( (dwEndSel > dwStartSel) || ((*wszTemp) == '\0') )
|
|
bDoConcat = FALSE;
|
|
|
|
// Concatenate the text to what already exists in the Ruby field
|
|
if (bDoConcat)
|
|
{
|
|
GetWindowText(hWndRuby, wszTemp, (CCHMAX_RUBYSIZE-1));
|
|
|
|
if ( (lstrlen(wszTemp) + lstrlen(wszRuby) + 1) < CCHMAX_RUBYSIZE )
|
|
{
|
|
StrCatBuff(wszTemp, wszRuby, ARRAYSIZE(wszTemp));
|
|
SetWindowText(hWndRuby, wszTemp);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Default
|
|
SetWindowText(hWndRuby, wszRuby);
|
|
}
|
|
}
|
|
break;
|
|
|
|
} // end switch(uMsg)
|
|
|
|
return CallWindowProc(OldWndProc, hWnd, uMsg, wParam, lParam);
|
|
}
|
|
|
|
/*//$$***************************************************************************
|
|
* FUNCTION: FillCertComboWithEmailAddresses(hDlg, lpPai);
|
|
*
|
|
*
|
|
* PURPOSE: Fills in the dialog items on the property sheet
|
|
*
|
|
* szEmail - if an email address is specified that exists in the
|
|
* combo, that email address is selected
|
|
*
|
|
****************************************************************************/
|
|
void FillCertComboWithEmailAddresses(HWND hDlg, LPPROP_ARRAY_INFO lpPai, LPTSTR szEmail)
|
|
{
|
|
HWND hWndCombo = GetDlgItem(hDlg, IDC_DETAILS_CERT_COMBO);
|
|
TCHAR sz[MAX_UI_STR];
|
|
int nDefault = 0;
|
|
|
|
FillComboWithEmailAddresses(lpPai, hWndCombo, &nDefault);
|
|
|
|
if( lpPai->ulOperationType != SHOW_ONE_OFF &&
|
|
SendMessage(hWndCombo, CB_GETCOUNT, 0, 0) > 0 &&
|
|
SendMessage(hWndCombo, CB_GETCOUNT, 0, 0) != CB_ERR )
|
|
EnableWindow(hWndCombo, TRUE);
|
|
|
|
// Append the item [None - certificates without e-mail addresses]
|
|
// to this list
|
|
*sz = '\0';
|
|
|
|
LoadString(hinstMapiX, idsCertsWithoutEmails, sz, CharSizeOf(sz));
|
|
|
|
// *** NOTE ***
|
|
// This item should always be the last item in the combo - several
|
|
// places in this file work on that assumption
|
|
//
|
|
if(lstrlen(sz))
|
|
SendMessage(hWndCombo, CB_ADDSTRING, 0, (LPARAM) sz);
|
|
|
|
if(szEmail)
|
|
{
|
|
// Set focus to a specific email address
|
|
int nCount = (int) SendMessage(hWndCombo, CB_GETCOUNT, 0, 0);
|
|
if(lstrlen(szEmail))
|
|
{
|
|
int i;
|
|
for(i=0;i<nCount-1;i++)
|
|
{
|
|
int nLen = (int)SendMessage(hWndCombo, CB_GETLBTEXTLEN, (WPARAM)i, 0);
|
|
if (nLen != CB_ERR)
|
|
{
|
|
LPTSTR psz = (LPTSTR)LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*(nLen + 1));
|
|
if (psz)
|
|
{
|
|
psz[0] = 0;
|
|
SendMessage(hWndCombo, CB_GETLBTEXT, (WPARAM) i, (LPARAM) psz);
|
|
if( lstrlen(psz) &&
|
|
!lstrcmpi(psz, szEmail))
|
|
{
|
|
LocalFreeAndNull(&psz);
|
|
SendMessage(hWndCombo, CB_SETCURSEL, (WPARAM) i, 0);
|
|
break;
|
|
}
|
|
LocalFreeAndNull(&psz);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// passed in an empty email string which means we have just imported
|
|
// a cert without an email address which means set the focus to the
|
|
// last item in the combo
|
|
SendMessage(hWndCombo, CB_SETCURSEL, (WPARAM) nCount-1, 0);
|
|
}
|
|
}
|
|
else
|
|
SendMessage(hWndCombo, CB_SETCURSEL, (WPARAM) nDefault, 0);
|
|
}
|
|
|
|
|
|
|
|
//$$//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// bVerifyRequiredData
|
|
//
|
|
// Checks that all the required data for a given prop sheet is filled in,
|
|
// If not, returns FALSE and ID of control to set focus on
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
BOOL bVerifyRequiredData(HWND hDlg,
|
|
LPPROP_ARRAY_INFO lpPai,
|
|
int nPropSheet,
|
|
int * lpCtlID)
|
|
{
|
|
TCHAR szBuf[2 * MAX_UI_STR];
|
|
ULONG ulSzBuf = CharSizeOf(szBuf);
|
|
|
|
//
|
|
// First check the required property (which is the GroupName)
|
|
//
|
|
*lpCtlID = 0;
|
|
szBuf[0]='\0';
|
|
|
|
switch (nPropSheet)
|
|
{
|
|
case propPersonal:
|
|
// We need to check that all the required properties are filled in ...
|
|
// For now all we really want a display Name
|
|
|
|
szBuf[0] = '\0';
|
|
GetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME, szBuf, ulSzBuf);
|
|
TrimSpaces(szBuf);
|
|
if (lstrlen(szBuf) == 0)
|
|
{
|
|
// Nothing in the display name field ..
|
|
// Try to populate the field with the various info.
|
|
// If we are successful in populating the field, we'll pick the first
|
|
// entry as the default display name
|
|
// If we are unsuccessful in picking something, we will stop and warn the
|
|
// user
|
|
HWND hWndCombo = GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME);
|
|
int nItemCount = 0;
|
|
SetComboDNText(hDlg, lpPai, TRUE, NULL);
|
|
nItemCount = (int) SendMessage(hWndCombo, CB_GETCOUNT, 0, 0);
|
|
if(nItemCount == 0)
|
|
{
|
|
//still nothing , warn and abort
|
|
ShowMessageBox(GetParent(hDlg), IDS_DETAILS_MESSAGE_FIRST_LAST_REQUIRED, MB_ICONEXCLAMATION | MB_OK);
|
|
*lpCtlID = IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME;
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
//Get the combo current selection which will be item 0
|
|
SendMessage(hWndCombo, CB_GETLBTEXT, (WPARAM) 0, (LPARAM) szBuf);
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//$$//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// bUpdateOldPropTagArray
|
|
//
|
|
// For each prop sheet that is accessed, we will update the list of old prop tags
|
|
// for that sheet so that the old props can be knocked out of existing mailuser objects
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
BOOL bUpdateOldPropTagArray(LPPROP_ARRAY_INFO lpPai, int nIndex)
|
|
{
|
|
LPSPropTagArray lpta = NULL;
|
|
|
|
SizedSPropTagArray(14, ptaUIDetlsPropsPersonal)=
|
|
{
|
|
14,
|
|
{
|
|
PR_DISPLAY_NAME,
|
|
PR_EMAIL_ADDRESS,
|
|
PR_ADDRTYPE,
|
|
PR_CONTACT_EMAIL_ADDRESSES,
|
|
PR_CONTACT_ADDRTYPES,
|
|
PR_CONTACT_DEFAULT_ADDRESS_INDEX,
|
|
PR_GIVEN_NAME,
|
|
PR_SURNAME,
|
|
PR_MIDDLE_NAME,
|
|
PR_NICKNAME,
|
|
PR_SEND_INTERNET_ENCODING,
|
|
PR_DISPLAY_NAME_PREFIX,
|
|
PR_WAB_YOMI_FIRSTNAME,
|
|
PR_WAB_YOMI_LASTNAME
|
|
}
|
|
};
|
|
|
|
switch(nIndex)
|
|
{
|
|
case propPersonal:
|
|
lpta = (LPSPropTagArray) &ptaUIDetlsPropsPersonal;
|
|
break;
|
|
case propHome:
|
|
ptaUIDetlsPropsHome.aulPropTag[idPropHomePostalID] = PR_WAB_POSTALID;
|
|
lpta = (LPSPropTagArray) &ptaUIDetlsPropsHome;
|
|
break;
|
|
case propBusiness:
|
|
ptaUIDetlsPropsBusiness.aulPropTag[idPropBusIPPhone] = PR_WAB_IPPHONE;
|
|
ptaUIDetlsPropsBusiness.aulPropTag[idPropBusPostalID] = PR_WAB_POSTALID;
|
|
lpta = (LPSPropTagArray) &ptaUIDetlsPropsBusiness;
|
|
break;
|
|
case propNotes:
|
|
lpta = (LPSPropTagArray) &ptaUIDetlsPropsNotes;
|
|
break;
|
|
case propCert:
|
|
lpta = (LPSPropTagArray) &ptaUIDetlsPropsCert;
|
|
break;
|
|
case propConferencing:
|
|
lpta = (LPSPropTagArray) &ptaUIDetlsPropsConferencing;
|
|
break;
|
|
case propFamily:
|
|
lpta = (LPSPropTagArray) &ptaUIDetlsPropsFamily;
|
|
break;
|
|
}
|
|
|
|
if(!lpta)
|
|
return TRUE;
|
|
|
|
if(lpPai->lpPropObj && lpPai->bSomethingChanged)
|
|
{
|
|
// Knock out these old props from the PropObject
|
|
if( (lpPai->lpPropObj)->lpVtbl->DeleteProps( (lpPai->lpPropObj),lpta,NULL))
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/*
|
|
-
|
|
- bGetHomeBusNotesInfo - Gets data from the Home/Business/Notes fields
|
|
-
|
|
*/
|
|
BOOL bGetHomeBusNotesInfo(HWND hDlg, LPPROP_ARRAY_INFO lpPai,
|
|
int nPropSheet, ID_PROP * lpidProp, ULONG idPropCount,
|
|
LPSPropValue * lppPropArray, LPULONG lpulcPropCount)
|
|
{
|
|
ULONG ulSzBuf = 4*MAX_BUF_STR;
|
|
LPTSTR szBuf = LocalAlloc(LMEM_ZEROINIT, ulSzBuf*sizeof(TCHAR));
|
|
// The idea is to first count all the properties that have non-zero values
|
|
// Then create a lpPropArray of that size and fill in the text from the props ..
|
|
//
|
|
BOOL bRet = FALSE;
|
|
ULONG ulNotEmptyCount = 0;
|
|
SCODE sc = S_OK;
|
|
ULONG i = 0;
|
|
LPSPropValue lpPropArray = NULL;
|
|
ULONG ulcPropCount = 0,ulIndex=0;
|
|
|
|
//The biggest field in the UI is about 2K length - just to be safe we want about 4K
|
|
// in this buffer so we need to allocate it dynamically
|
|
if(!szBuf)
|
|
{
|
|
DebugTrace(( TEXT("LocalAlloc failed to allocate memory\n")));
|
|
return FALSE;
|
|
}
|
|
|
|
for(i=0;i<idPropCount;i++)
|
|
{
|
|
switch(lpidProp[i].idCtl)
|
|
{
|
|
case IDC_DETAILS_HOME_CHECK_DEFAULTADDRESS:
|
|
if(lpPai->ulFlags & DETAILS_DefHomeChanged)
|
|
ulNotEmptyCount++;
|
|
continue;
|
|
break;
|
|
case IDC_DETAILS_BUSINESS_CHECK_DEFAULTADDRESS:
|
|
if(lpPai->ulFlags & DETAILS_DefBusChanged)
|
|
ulNotEmptyCount++;
|
|
continue;
|
|
break;
|
|
}
|
|
szBuf[0]='\0'; //reset
|
|
GetDlgItemText(hDlg, lpidProp[i].idCtl, szBuf, ulSzBuf);
|
|
TrimSpaces(szBuf);
|
|
if(lstrlen(szBuf) && lpidProp[i].ulPropTag) //some text
|
|
ulNotEmptyCount++;
|
|
// if its just the default prefix, ignore
|
|
if( ((lpidProp[i].idCtl == IDC_DETAILS_HOME_EDIT_URL) ||
|
|
(lpidProp[i].idCtl == IDC_DETAILS_BUSINESS_EDIT_URL)) &&
|
|
(lstrcmpi(szHTTP, szBuf)==0))
|
|
ulNotEmptyCount--;
|
|
|
|
}
|
|
|
|
if (ulNotEmptyCount == 0)
|
|
{
|
|
bRet = TRUE;
|
|
goto out;
|
|
}
|
|
|
|
ulcPropCount = ulNotEmptyCount;
|
|
|
|
sc = MAPIAllocateBuffer(sizeof(SPropValue) * ulcPropCount, &lpPropArray);
|
|
if (sc!=S_OK)
|
|
{
|
|
DebugTrace(( TEXT("Error allocating memory\n")));
|
|
goto out;
|
|
}
|
|
|
|
ulIndex = 0; //now we reuse this variable as an index
|
|
|
|
// Now read the props again and fill in the lpPropArray
|
|
for(i=0;i<idPropCount;i++)
|
|
{
|
|
switch(lpidProp[i].idCtl)
|
|
{
|
|
case IDC_DETAILS_HOME_CHECK_DEFAULTADDRESS:
|
|
case IDC_DETAILS_BUSINESS_CHECK_DEFAULTADDRESS:
|
|
continue;
|
|
break;
|
|
}
|
|
|
|
szBuf[0]='\0'; //reset
|
|
GetDlgItemText(hDlg, lpidProp[i].idCtl, szBuf, ulSzBuf);
|
|
TrimSpaces(szBuf);
|
|
|
|
if( ((lpidProp[i].idCtl == IDC_DETAILS_HOME_EDIT_URL) ||
|
|
(lpidProp[i].idCtl == IDC_DETAILS_BUSINESS_EDIT_URL)) &&
|
|
(lstrcmpi(szHTTP, szBuf)==0))
|
|
continue;
|
|
|
|
if(lstrlen(szBuf) && lpidProp[i].ulPropTag) //some text
|
|
{
|
|
ULONG nLen = sizeof(TCHAR)*(lstrlen(szBuf)+1);
|
|
lpPropArray[ulIndex].ulPropTag = lpidProp[i].ulPropTag;
|
|
sc = MAPIAllocateMore(nLen, lpPropArray, (LPVOID *) (&(lpPropArray[ulIndex].Value.LPSZ)));
|
|
|
|
if (sc!=S_OK)
|
|
{
|
|
DebugPrintError(( TEXT("Error allocating memory\n")));
|
|
goto out;
|
|
}
|
|
StrCpyN(lpPropArray[ulIndex].Value.LPSZ,szBuf,nLen/sizeof(TCHAR));
|
|
ulIndex++;
|
|
}
|
|
}
|
|
if(nPropSheet == propHome)
|
|
{
|
|
if(lpPai->ulFlags & DETAILS_DefHomeChanged)
|
|
{
|
|
lpPropArray[ulIndex].ulPropTag = PR_WAB_POSTALID;
|
|
lpPropArray[ulIndex].Value.l = (IsDlgButtonChecked(hDlg, IDC_DETAILS_HOME_CHECK_DEFAULTADDRESS)) ?
|
|
ADDRESS_HOME : ADDRESS_NONE;
|
|
ulIndex++;
|
|
}
|
|
}
|
|
else if(nPropSheet == propBusiness)
|
|
{
|
|
if(lpPai->ulFlags & DETAILS_DefBusChanged)
|
|
{
|
|
lpPropArray[ulIndex].ulPropTag = PR_WAB_POSTALID;
|
|
lpPropArray[ulIndex].Value.l = (IsDlgButtonChecked(hDlg, IDC_DETAILS_BUSINESS_CHECK_DEFAULTADDRESS)) ?
|
|
ADDRESS_WORK : ADDRESS_NONE;
|
|
ulIndex++;
|
|
}
|
|
}
|
|
|
|
*lppPropArray = lpPropArray;
|
|
*lpulcPropCount = ulIndex;
|
|
|
|
bRet = TRUE;
|
|
|
|
out:
|
|
if (!bRet)
|
|
{
|
|
if ((lpPropArray) && (ulcPropCount > 0))
|
|
{
|
|
MAPIFreeBuffer(lpPropArray);
|
|
ulcPropCount = 0;
|
|
}
|
|
}
|
|
LocalFreeAndNull(&szBuf);
|
|
return bRet;
|
|
}
|
|
|
|
|
|
/*
|
|
- bGetPersonalInfo
|
|
- Get Data from Personal Prop sheet
|
|
*
|
|
*/
|
|
BOOL bGetPersonalInfo( HWND hDlg, LPPROP_ARRAY_INFO lpPai,
|
|
ID_PROP * lpidProp, ULONG idPropCount,
|
|
LPSPropValue * lppPropArray, LPULONG lpulcPropCount)
|
|
{
|
|
ULONG ulSzBuf = 4*MAX_BUF_STR;
|
|
LPTSTR szBuf = LocalAlloc(LMEM_ZEROINIT, ulSzBuf*sizeof(TCHAR));
|
|
BOOL bRet = FALSE;
|
|
ULONG ulNotEmptyCount = 0;
|
|
SCODE sc = S_OK;
|
|
HRESULT hr = S_OK;
|
|
ULONG i = 0;
|
|
LPSPropValue lpPropArray = NULL;
|
|
ULONG ulcPropCount = 0,ulIndex=0;
|
|
ULONG ulcProps = 0;
|
|
LPSPropValue rgProps = NULL;
|
|
|
|
HWND hWndLV = NULL;
|
|
TCHAR szConf[MAX_UI_STR];
|
|
|
|
SizedSPropTagArray(1, ptaIC) = {1, PR_SEND_INTERNET_ENCODING};
|
|
|
|
//The biggest field in the UI is about 2K length - just to be safe we want about 4K
|
|
// in this buffer so we need to allocate it dynamically
|
|
if(!szBuf)
|
|
{
|
|
DebugTrace(( TEXT("LocalAlloc failed to allocate memory\n")));
|
|
return FALSE;
|
|
}
|
|
|
|
if(HR_FAILED(lpPai->lpPropObj->lpVtbl->GetProps(lpPai->lpPropObj, (LPSPropTagArray)&ptaIC,
|
|
MAPI_UNICODE, &ulcProps, &rgProps)))
|
|
goto out;
|
|
|
|
szBuf[0] = '\0';
|
|
hWndLV = GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_LIST);
|
|
|
|
GetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME, (LPTSTR)szBuf, ulSzBuf);
|
|
TrimSpaces(szBuf);
|
|
if (lstrlen(szBuf) == 0)
|
|
{
|
|
// Nothing in the display name field ..
|
|
// Try to populate the field with the various info.
|
|
// If we are successful in populating the field, we'll pick the first
|
|
// entry as the default display name
|
|
// If we are unsuccessful in picking something, we will stop and warn the
|
|
// user
|
|
HWND hWndCombo = GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME);
|
|
int nItemCount = 0;
|
|
|
|
SetComboDNText(hDlg, lpPai, TRUE, NULL);
|
|
nItemCount = (int) SendMessage(hWndCombo, CB_GETCOUNT, 0, 0);
|
|
if(nItemCount && nItemCount != CB_ERR)
|
|
{
|
|
//Get the combo current selection which will be item 0
|
|
SendMessage(hWndCombo, CB_GETLBTEXT, (WPARAM) 0, (LPARAM) szBuf);
|
|
}
|
|
}
|
|
|
|
ulNotEmptyCount = 0;
|
|
for(i=0;i<idPropCount;i++)
|
|
{
|
|
HWND hWndC = GetDlgItem(hDlg, lpidProp[i].idCtl);
|
|
if(!hWndC)
|
|
continue;
|
|
szBuf[0]='\0'; //reset
|
|
if(GetWindowText(hWndC, szBuf, ulSzBuf))
|
|
{
|
|
TrimSpaces(szBuf);
|
|
if(lstrlen(szBuf) && lpidProp[i].ulPropTag) //some text
|
|
ulNotEmptyCount++;
|
|
}
|
|
}
|
|
|
|
|
|
if ((ulNotEmptyCount == 0) &&
|
|
(ListView_GetItemCount(hWndLV) <= 0)) // Bug 14274 - werent looking for an email address before bailing out ..
|
|
{
|
|
// This prop sheet is empty ... ignore it
|
|
bRet = TRUE;
|
|
goto out;
|
|
}
|
|
|
|
ulcPropCount = ulNotEmptyCount;
|
|
|
|
ulcPropCount++; // We create an entryid
|
|
|
|
if(ListView_GetItemCount(hWndLV) > 0)
|
|
ulcPropCount += 5; // +1 for email1_address,
|
|
// +1 for addrtype,
|
|
// +1 for contact_email_addresses,
|
|
// +1 for contact_addrtypes
|
|
// +1 for contact_default_index,
|
|
|
|
ulcPropCount++; //Add one for the PR_SEND_INTERNET_ENCODING property
|
|
|
|
sc = MAPIAllocateBuffer(sizeof(SPropValue) * ulcPropCount, &lpPropArray);
|
|
if (sc!=S_OK)
|
|
{
|
|
DebugPrintError(( TEXT("Error allocating memory\n")));
|
|
goto out;
|
|
}
|
|
|
|
ulIndex = 0;
|
|
|
|
// Now read the props again and fill in the lpPropArray
|
|
for(i=0;i<idPropCount;i++)
|
|
{
|
|
HWND hWndC = GetDlgItem(hDlg, lpidProp[i].idCtl);
|
|
if(!hWndC)
|
|
continue;
|
|
szBuf[0]='\0'; //reset
|
|
GetWindowText(hWndC, szBuf, ulSzBuf);
|
|
TrimSpaces(szBuf);
|
|
if(lstrlen(szBuf))
|
|
{
|
|
if(lpidProp[i].idCtl == IDC_DETAILS_PERSONAL_STATIC_RUBYFIRST)
|
|
lpidProp[i].ulPropTag = PR_WAB_YOMI_FIRSTNAME;
|
|
else if(lpidProp[i].idCtl == IDC_DETAILS_PERSONAL_STATIC_RUBYLAST)
|
|
lpidProp[i].ulPropTag = PR_WAB_YOMI_LASTNAME;
|
|
|
|
if(lpidProp[i].ulPropTag) //some text
|
|
{
|
|
ULONG nLen = sizeof(TCHAR)*(lstrlen(szBuf)+1);
|
|
lpPropArray[ulIndex].ulPropTag = lpidProp[i].ulPropTag;
|
|
|
|
sc = MAPIAllocateMore(nLen, lpPropArray, (LPVOID *) (&(lpPropArray[ulIndex].Value.LPSZ)));
|
|
if (sc!=S_OK)
|
|
{
|
|
DebugPrintError(( TEXT("Error allocating memory\n")));
|
|
goto out;
|
|
}
|
|
StrCpyN(lpPropArray[ulIndex].Value.LPSZ,szBuf,nLen/sizeof(TCHAR));
|
|
ulIndex++;
|
|
}
|
|
}
|
|
}
|
|
|
|
// TBD - write code for getting all the other props
|
|
|
|
// if this is a new entry, we want to give it a blank PR_ENTRYID property
|
|
// else we want to set its PR_ENTRYID property
|
|
lpPropArray[ulIndex].ulPropTag = PR_ENTRYID;
|
|
|
|
if (lpPai->cbEntryID == 0)
|
|
{
|
|
lpPropArray[ulIndex].Value.bin.cb = 0;
|
|
lpPropArray[ulIndex].Value.bin.lpb = NULL;
|
|
}
|
|
else
|
|
{
|
|
lpPropArray[ulIndex].Value.bin.cb = lpPai->cbEntryID;
|
|
sc = MAPIAllocateMore(lpPai->cbEntryID, lpPropArray, (LPVOID *) (&(lpPropArray[ulIndex].Value.bin.lpb)));
|
|
if (sc!=S_OK)
|
|
{
|
|
DebugPrintError(( TEXT("Error allocating memory\n")));
|
|
goto out;
|
|
}
|
|
|
|
CopyMemory(lpPropArray[ulIndex].Value.bin.lpb,lpPai->lpEntryID,lpPai->cbEntryID);
|
|
}
|
|
|
|
ulIndex++;
|
|
|
|
szConf[0] = TEXT('\0');
|
|
|
|
// Check if we need to change the COnf_server_email_index prop
|
|
if(lpPai->hWndComboConf)
|
|
{
|
|
GetWindowText(lpPai->hWndComboConf, szConf, CharSizeOf(szConf));
|
|
TrimSpaces(szConf);
|
|
}
|
|
|
|
if(ListView_GetItemCount(hWndLV) > 0)
|
|
{
|
|
// Find out how many elements we need to add
|
|
ULONG nEmailCount = ListView_GetItemCount(hWndLV);
|
|
|
|
// we'll use the following as indexes for lpPropArray
|
|
ULONG nMVEmailAddress = ulIndex++;//ulIndex+0;
|
|
ULONG nMVAddrTypes = ulIndex++;//ulIndex+1;
|
|
ULONG nEmailAddress = ulIndex++;//ulIndex+2;
|
|
ULONG nAddrType = ulIndex++;//ulIndex+3;
|
|
ULONG nDefaultIndex = ulIndex++;//ulIndex+4;
|
|
|
|
lpPropArray[nEmailAddress].ulPropTag = PR_EMAIL_ADDRESS;
|
|
lpPropArray[nAddrType].ulPropTag = PR_ADDRTYPE;
|
|
lpPropArray[nDefaultIndex].ulPropTag = PR_CONTACT_DEFAULT_ADDRESS_INDEX;
|
|
lpPropArray[nMVEmailAddress].ulPropTag = PR_CONTACT_EMAIL_ADDRESSES;
|
|
lpPropArray[nMVAddrTypes].ulPropTag = PR_CONTACT_ADDRTYPES;
|
|
|
|
// initialize before using ...
|
|
lpPropArray[nMVEmailAddress].Value.MVSZ.cValues = 0;
|
|
lpPropArray[nMVEmailAddress].Value.MVSZ.LPPSZ = NULL;
|
|
lpPropArray[nMVAddrTypes].Value.MVSZ.cValues = 0;
|
|
lpPropArray[nMVAddrTypes].Value.MVSZ.LPPSZ = NULL;
|
|
|
|
// For thetime being just null them all
|
|
for(i=0;i<nEmailCount;i++)
|
|
{
|
|
LV_ITEM lvi = {0};
|
|
lvi.mask = LVIF_PARAM;
|
|
lvi.iItem = i;
|
|
lvi.iSubItem = 0;
|
|
if (ListView_GetItem(hWndLV, &lvi))
|
|
{
|
|
LPEMAIL_ITEM lpEItem = (LPEMAIL_ITEM) lvi.lParam;
|
|
|
|
if(HR_FAILED(hr = AddPropToMVPString(
|
|
lpPropArray,
|
|
ulcPropCount,
|
|
nMVEmailAddress,
|
|
lpEItem->szEmailAddress)))
|
|
{
|
|
DebugPrintError(( TEXT("AddPropToMVString Email failed: %x"),hr));
|
|
goto out;
|
|
}
|
|
|
|
if(HR_FAILED(hr = AddPropToMVPString(
|
|
lpPropArray,
|
|
ulcPropCount,
|
|
nMVAddrTypes,
|
|
lpEItem->szAddrType)))
|
|
{
|
|
DebugPrintError(( TEXT("AddPropToMVString AddrType failed: %x"),hr));
|
|
goto out;
|
|
}
|
|
|
|
if(lpEItem->bIsDefault)
|
|
{
|
|
ULONG cchSize;
|
|
|
|
// For the default e-mail ... set all the other props
|
|
lpPropArray[nDefaultIndex].Value.l = i;
|
|
|
|
cchSize = lstrlen(lpEItem->szEmailAddress)+1;
|
|
sc = MAPIAllocateMore( sizeof(TCHAR)*cchSize,
|
|
lpPropArray,
|
|
(LPVOID *) (&(lpPropArray[nEmailAddress].Value.LPSZ)));
|
|
if(FAILED(sc))
|
|
{
|
|
DebugPrintError(( TEXT("MApiAllocateMore failed\n")));
|
|
hr = ResultFromScode(sc);
|
|
goto out;
|
|
}
|
|
StrCpyN(lpPropArray[nEmailAddress].Value.LPSZ,lpEItem->szEmailAddress,cchSize);
|
|
|
|
cchSize = lstrlen(lpEItem->szAddrType)+1;
|
|
sc = MAPIAllocateMore( sizeof(TCHAR)*cchSize,
|
|
lpPropArray,
|
|
(LPVOID *) (&(lpPropArray[nAddrType].Value.LPSZ)));
|
|
if(FAILED(sc))
|
|
{
|
|
DebugPrintError(( TEXT("MApiAllocateMore failed\n")));
|
|
hr = ResultFromScode(sc);
|
|
goto out;
|
|
}
|
|
StrCpyN(lpPropArray[nAddrType].Value.LPSZ,lpEItem->szAddrType,cchSize);
|
|
|
|
} // if bIsDefault...
|
|
} // if LV_GetItem ...
|
|
} // for i = ...
|
|
|
|
} // if LV_GetItemCount ...
|
|
|
|
// Add the PR_SEND_INTERNET_ENCODING property
|
|
lpPropArray[ulIndex].ulPropTag = PR_SEND_INTERNET_ENCODING;
|
|
lpPropArray[ulIndex].Value.l = 0;
|
|
|
|
// The PR_SEND_INTERNET_ECODING is a bit mask of several flags and we dont want
|
|
// to loose any information that was in the original set of bits so we get it again
|
|
if(rgProps[0].ulPropTag == PR_SEND_INTERNET_ENCODING)
|
|
{
|
|
//Check the check box on the UI
|
|
lpPropArray[ulIndex].Value.l = rgProps[0].Value.l;
|
|
}
|
|
|
|
lpPropArray[ulIndex].Value.l &= ~BODY_ENCODING_MASK; //BODY_ENCODING_HTML;
|
|
if(IsDlgButtonChecked(hDlg, IDC_DETAILS_PERSONAL_CHECK_RICHINFO) != BST_CHECKED)
|
|
lpPropArray[ulIndex].Value.l |= BODY_ENCODING_TEXT_AND_HTML; //BODY_ENCODING_HTML;
|
|
|
|
ulIndex++;
|
|
|
|
*lppPropArray = lpPropArray;
|
|
*lpulcPropCount = ulIndex;
|
|
|
|
bRet = TRUE;
|
|
|
|
out:
|
|
if (!bRet)
|
|
{
|
|
if ((lpPropArray) && (ulcPropCount > 0))
|
|
{
|
|
MAPIFreeBuffer(lpPropArray);
|
|
ulcPropCount = 0;
|
|
}
|
|
}
|
|
LocalFreeAndNull(&szBuf);
|
|
FreeBufferAndNull(&rgProps);
|
|
return bRet;
|
|
}
|
|
|
|
|
|
/*
|
|
- bGetConferencingInfo
|
|
- Get Data from Conferencing Prop sheet
|
|
*
|
|
*/
|
|
BOOL bGetConferencingInfo( HWND hDlg, LPPROP_ARRAY_INFO lpPai,
|
|
LPSPropValue * lppPropArray, LPULONG lpulcPropCount)
|
|
{
|
|
ULONG ulSzBuf = 4*MAX_BUF_STR;
|
|
LPTSTR szBuf = LocalAlloc(LMEM_ZEROINIT, ulSzBuf*sizeof(TCHAR));
|
|
BOOL bRet = FALSE;
|
|
ULONG ulNotEmptyCount = 0;
|
|
SCODE sc = S_OK;
|
|
HRESULT hr = S_OK;
|
|
ULONG i = 0;
|
|
LPSPropValue lpPropArray = NULL;
|
|
ULONG ulcPropCount = 0,ulIndex=0;
|
|
HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_NTMTG_LIST_SERVERS);
|
|
int nItemCount = ListView_GetItemCount(hWndLV);
|
|
TCHAR szEmail[MAX_UI_STR];
|
|
ULONG ulcProps = 0;
|
|
LPSPropValue rgProps = NULL;
|
|
|
|
SizedSPropTagArray(1, ptaCf) = {1, PR_WAB_CONF_SERVERS};
|
|
|
|
//The biggest field in the UI is about 2K length - just to be safe we want about 4K
|
|
// in this buffer so we need to allocate it dynamically
|
|
if(!szBuf)
|
|
{
|
|
DebugTrace(( TEXT("LocalAlloc failed to allocate memory\n")));
|
|
return FALSE;
|
|
}
|
|
|
|
if(HR_FAILED(lpPai->lpPropObj->lpVtbl->GetProps(lpPai->lpPropObj, (LPSPropTagArray)&ptaCf,
|
|
MAPI_UNICODE, &ulcProps, &rgProps)))
|
|
goto out;
|
|
|
|
// For the conferencing tab, we need to save 4 properties
|
|
// Conferencing Server Names
|
|
// Default Index
|
|
// Backup Index
|
|
// Email Address Index
|
|
//
|
|
ulNotEmptyCount = 0;
|
|
|
|
if(nItemCount > 0)
|
|
{
|
|
ulNotEmptyCount += 2; // CONF_SERVERS and DEFAULT_INDEX
|
|
|
|
if(lpPai->nBackupServerIndex != -1)
|
|
ulNotEmptyCount++;
|
|
}
|
|
|
|
if (ulNotEmptyCount == 0)
|
|
{
|
|
// This prop sheet is empty ... ignore it
|
|
bRet = TRUE;
|
|
goto out;
|
|
}
|
|
|
|
ulcPropCount = ulNotEmptyCount;
|
|
|
|
sc = MAPIAllocateBuffer(sizeof(SPropValue) * ulcPropCount, &lpPropArray);
|
|
if (sc!=S_OK)
|
|
goto out;
|
|
|
|
ulIndex = 0; //now we reuse this variable as an index
|
|
|
|
if(nItemCount > 0)
|
|
{
|
|
TCHAR * szCalltoStr = NULL; //szCalltoStr[MAX_UI_STR * 3];
|
|
ULONG cchCalltoStr = MAX_UI_STR*3;
|
|
ULONG i,j;
|
|
|
|
if (szCalltoStr = LocalAlloc(LMEM_ZEROINIT, cchCalltoStr*sizeof(TCHAR)))
|
|
{
|
|
lpPropArray[ulIndex].ulPropTag = PR_WAB_CONF_SERVERS;
|
|
lpPropArray[ulIndex].Value.MVSZ.cValues = 0;
|
|
lpPropArray[ulIndex].Value.MVSZ.LPPSZ = NULL;
|
|
|
|
// first scan the original prop array for any PR_SERVERS props that
|
|
// we didnt touch - retain those props witout losing them
|
|
|
|
{
|
|
j = 0; //index of PR_WAB_CONF_SERVERS prop
|
|
if(rgProps[j].ulPropTag == PR_WAB_CONF_SERVERS)
|
|
{
|
|
LPSPropValue lpProp = &(rgProps[j]);
|
|
for(i=0;i<lpProp->Value.MVSZ.cValues; i++)
|
|
{
|
|
LPTSTR lp = lpProp->Value.MVSZ.LPPSZ[i];
|
|
TCHAR sz[32];
|
|
int iLenCallto = lstrlen(szCallto);
|
|
if(!SubstringSearch(lp, TEXT("://")))
|
|
continue;
|
|
if(lstrlen(lp) < iLenCallto)
|
|
continue;
|
|
|
|
if (StrCmpNI(lp, szCallto, iLenCallto))
|
|
{
|
|
// Not a callto string .. retain it
|
|
if(HR_FAILED(hr = AddPropToMVPString( lpPropArray, ulcPropCount, ulIndex, lp)))
|
|
{
|
|
DebugPrintError(( TEXT("AddPropToMVString Conf server %s failed: %x"),lp, hr));
|
|
goto out;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
for(i=0;i< (ULONG) nItemCount; i++)
|
|
{
|
|
szBuf[0]='\0';
|
|
szEmail[0] = '\0';
|
|
{
|
|
LV_ITEM lvi = {0};
|
|
lvi.mask = LVIF_PARAM;
|
|
lvi.iItem = i; lvi.iSubItem = 0;
|
|
ListView_GetItem(hWndLV, &lvi);
|
|
if(lvi.lParam)
|
|
{
|
|
LPSERVER_ITEM lpSI = (LPSERVER_ITEM) lvi.lParam;
|
|
|
|
if(lpSI->lpServer)
|
|
StrCpyN(szBuf, lpSI->lpServer, ulSzBuf);
|
|
if(lpSI->lpEmail)
|
|
StrCpyN(szEmail, lpSI->lpEmail, ARRAYSIZE(szEmail));
|
|
}
|
|
}
|
|
|
|
if(lstrlen(szBuf) && lstrlen(szEmail))
|
|
{
|
|
StrCpyN(szCalltoStr, szCallto, cchCalltoStr);
|
|
StrCatBuff(szCalltoStr, szBuf, cchCalltoStr);
|
|
StrCatBuff(szCalltoStr, TEXT("/"), cchCalltoStr);
|
|
StrCatBuff(szCalltoStr, szEmail, cchCalltoStr);
|
|
if(HR_FAILED(hr = AddPropToMVPString( lpPropArray, ulcPropCount, ulIndex, szCalltoStr)))
|
|
{
|
|
DebugPrintError(( TEXT("AddPropToMVString Conf server %s failed: %x"),szCalltoStr, hr));
|
|
goto out;
|
|
}
|
|
}
|
|
}
|
|
LocalFreeAndNull(&szCalltoStr);
|
|
}
|
|
|
|
ulIndex++;
|
|
lpPropArray[ulIndex].ulPropTag = PR_WAB_CONF_DEFAULT_INDEX;
|
|
lpPropArray[ulIndex].Value.l = (ULONG) lpPai->nDefaultServerIndex;
|
|
|
|
ulIndex++;
|
|
|
|
if(lpPai->nBackupServerIndex != -1)
|
|
{
|
|
lpPropArray[ulIndex].ulPropTag = PR_WAB_CONF_BACKUP_INDEX;
|
|
lpPropArray[ulIndex].Value.l = (ULONG) lpPai->nBackupServerIndex;
|
|
ulIndex++;
|
|
}
|
|
}
|
|
|
|
*lppPropArray = lpPropArray;
|
|
*lpulcPropCount = ulIndex;
|
|
|
|
bRet = TRUE;
|
|
|
|
out:
|
|
if (!bRet)
|
|
{
|
|
if ((lpPropArray) && (ulcPropCount > 0))
|
|
{
|
|
MAPIFreeBuffer(lpPropArray);
|
|
ulcPropCount = 0;
|
|
}
|
|
}
|
|
LocalFreeAndNull(&szBuf);
|
|
FreeBufferAndNull(&rgProps);
|
|
return bRet;
|
|
}
|
|
|
|
/*
|
|
- bGetFamilyInfo - get's info back from the Family Prop
|
|
-
|
|
*/
|
|
BOOL bGetFamilyInfo(HWND hDlg, LPPROP_ARRAY_INFO lpPai,
|
|
ID_PROP * lpidProp, ULONG idPropCount,
|
|
LPSPropValue * lppPropArray, ULONG * lpulcPropCount)
|
|
{
|
|
ULONG ulSzBuf = 4*MAX_BUF_STR;
|
|
LPTSTR szBuf = LocalAlloc(LMEM_ZEROINIT, ulSzBuf*sizeof(TCHAR));
|
|
BOOL bRet = FALSE;
|
|
ULONG ulNotEmptyCount = 0;
|
|
SCODE sc = S_OK;
|
|
ULONG i = 0;
|
|
LPSPropValue lpPropArray = NULL;
|
|
ULONG ulcPropCount = 0,ulIndex=0;
|
|
HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_FAMILY_LIST_CHILDREN);
|
|
SYSTEMTIME st = {0};
|
|
short int nSel = 0;
|
|
int nCount = 0;
|
|
|
|
//The biggest field in the UI is about 2K length - just to be safe we want about 4K
|
|
// in this buffer so we need to allocate it dynamically
|
|
if(!szBuf)
|
|
{
|
|
DebugTrace(( TEXT("LocalAlloc failed to allocate memory\n")));
|
|
return FALSE;
|
|
}
|
|
|
|
for(i=0;i<idPropCount;i++)
|
|
{
|
|
switch(lpidProp[i].idCtl)
|
|
{
|
|
case IDC_DETAILS_FAMILY_LIST_CHILDREN:
|
|
if( lpPai->ulFlags & DETAILS_ChildrenChanged ||
|
|
ListView_GetItemCount(hWndLV) > 0)
|
|
ulNotEmptyCount++;
|
|
continue;
|
|
break;
|
|
case IDC_DETAILS_FAMILY_DATE_BIRTHDAY:
|
|
case IDC_DETAILS_FAMILY_DATE_ANNIVERSARY:
|
|
{
|
|
SYSTEMTIME st = {0};
|
|
if( lpPai->ulFlags & DETAILS_DateChanged ||
|
|
GDT_VALID == SendDlgItemMessage(hDlg, lpidProp[i].idCtl, DTM_GETSYSTEMTIME, 0, (LPARAM) &st))
|
|
ulNotEmptyCount++;
|
|
}
|
|
continue;
|
|
case IDC_DETAILS_HOME_COMBO_GENDER:
|
|
if( lpPai->ulFlags & DETAILS_GenderChanged ||
|
|
SendDlgItemMessage(hDlg, IDC_DETAILS_HOME_COMBO_GENDER, CB_GETCURSEL, 0, 0)>0 )
|
|
ulNotEmptyCount++;
|
|
continue;
|
|
break;
|
|
}
|
|
szBuf[0]='\0'; //reset
|
|
GetDlgItemText(hDlg, lpidProp[i].idCtl, szBuf, ulSzBuf);
|
|
TrimSpaces(szBuf);
|
|
if(lstrlen(szBuf) && lpidProp[i].ulPropTag) //some text
|
|
ulNotEmptyCount++;
|
|
}
|
|
|
|
if (ulNotEmptyCount == 0)
|
|
{
|
|
bRet = TRUE;
|
|
goto out;
|
|
}
|
|
|
|
ulcPropCount = ulNotEmptyCount;
|
|
|
|
sc = MAPIAllocateBuffer(sizeof(SPropValue) * ulcPropCount, &lpPropArray);
|
|
if (sc!=S_OK)
|
|
{
|
|
DebugTrace(( TEXT("Error allocating memory\n")));
|
|
goto out;
|
|
}
|
|
|
|
ulIndex = 0; //now we reuse this variable as an index
|
|
|
|
// Now read the props again and fill in the lpPropArray
|
|
for(i=0;i<idPropCount;i++)
|
|
{
|
|
switch(lpidProp[i].idCtl)
|
|
{
|
|
case IDC_DETAILS_FAMILY_DATE_BIRTHDAY:
|
|
case IDC_DETAILS_FAMILY_DATE_ANNIVERSARY:
|
|
case IDC_DETAILS_HOME_COMBO_GENDER:
|
|
case IDC_DETAILS_FAMILY_LIST_CHILDREN:
|
|
continue;
|
|
break;
|
|
}
|
|
|
|
szBuf[0]='\0'; //reset
|
|
GetDlgItemText(hDlg, lpidProp[i].idCtl, szBuf, ulSzBuf);
|
|
TrimSpaces(szBuf);
|
|
|
|
if(lstrlen(szBuf) && lpidProp[i].ulPropTag) //some text
|
|
{
|
|
ULONG nLen = sizeof(TCHAR)*(lstrlen(szBuf)+1);
|
|
lpPropArray[ulIndex].ulPropTag = lpidProp[i].ulPropTag;
|
|
sc = MAPIAllocateMore(nLen, lpPropArray, (LPVOID *) (&(lpPropArray[ulIndex].Value.LPSZ)));
|
|
if (sc!=S_OK)
|
|
{
|
|
DebugTrace( TEXT("Error allocating memory\n"));
|
|
goto out;
|
|
}
|
|
StrCpyN(lpPropArray[ulIndex].Value.LPSZ,szBuf,nLen/sizeof(TCHAR));
|
|
ulIndex++;
|
|
}
|
|
}
|
|
|
|
// Get the Gender data
|
|
//
|
|
nCount = ListView_GetItemCount(hWndLV);
|
|
if(lpPai->ulFlags & DETAILS_ChildrenChanged || nCount>0)
|
|
{
|
|
ULONG ulCount = 0;
|
|
if(nCount > 0)
|
|
{
|
|
lpPropArray[ulIndex].ulPropTag = PR_CHILDRENS_NAMES;
|
|
sc = MAPIAllocateMore(nCount * sizeof(LPTSTR), lpPropArray, (LPVOID *)&(lpPropArray[ulIndex].Value.MVSZ.LPPSZ));
|
|
if (sc!=S_OK)
|
|
{
|
|
DebugTrace( TEXT("Error allocating memory\n"));
|
|
goto out;
|
|
}
|
|
for(i=0;i<(ULONG)nCount;i++)
|
|
{
|
|
*szBuf = '\0';
|
|
ListView_GetItemText(hWndLV, i, 0, szBuf, ulSzBuf);
|
|
if(szBuf && lstrlen(szBuf))
|
|
{
|
|
ULONG cchSize=lstrlen(szBuf)+1;
|
|
sc = MAPIAllocateMore(sizeof(TCHAR)*cchSize, lpPropArray, (LPVOID *) (&(lpPropArray[ulIndex].Value.MVSZ.LPPSZ[ulCount])));
|
|
if (sc!=S_OK)
|
|
{
|
|
DebugTrace( TEXT("Error allocating memory\n"));
|
|
goto out;
|
|
}
|
|
StrCpyN(lpPropArray[ulIndex].Value.MVSZ.LPPSZ[ulCount], szBuf, cchSize);
|
|
ulCount++;
|
|
}
|
|
}
|
|
lpPropArray[ulIndex].Value.MVSZ.cValues = ulCount;
|
|
ulIndex++;
|
|
}
|
|
|
|
}
|
|
nSel = (short int) SendDlgItemMessage(hDlg, IDC_DETAILS_HOME_COMBO_GENDER, CB_GETCURSEL, 0, 0);
|
|
if(nSel == CB_ERR)
|
|
nSel = 0;
|
|
if(lpPai->ulFlags & DETAILS_GenderChanged || nSel>0)
|
|
{
|
|
lpPropArray[ulIndex].ulPropTag = PR_GENDER;
|
|
lpPropArray[ulIndex].Value.i = nSel;
|
|
ulIndex++;
|
|
}
|
|
|
|
if(GDT_VALID == SendDlgItemMessage(hDlg, IDC_DETAILS_FAMILY_DATE_BIRTHDAY, DTM_GETSYSTEMTIME, 0, (LPARAM) &st))
|
|
{
|
|
lpPropArray[ulIndex].ulPropTag = PR_BIRTHDAY;
|
|
SystemTimeToFileTime(&st, (FILETIME *) (&lpPropArray[ulIndex].Value.ft));
|
|
ulIndex++;
|
|
}
|
|
|
|
if(GDT_VALID == SendDlgItemMessage(hDlg, IDC_DETAILS_FAMILY_DATE_ANNIVERSARY, DTM_GETSYSTEMTIME, 0, (LPARAM) &st))
|
|
{
|
|
lpPropArray[ulIndex].ulPropTag = PR_WEDDING_ANNIVERSARY;
|
|
SystemTimeToFileTime(&st, (FILETIME *) (&lpPropArray[ulIndex].Value.ft));
|
|
ulIndex++;
|
|
}
|
|
|
|
*lppPropArray = lpPropArray;
|
|
*lpulcPropCount = ulIndex;
|
|
|
|
bRet = TRUE;
|
|
|
|
out:
|
|
if (!bRet)
|
|
{
|
|
if ((lpPropArray) && (ulcPropCount > 0))
|
|
{
|
|
MAPIFreeBuffer(lpPropArray);
|
|
ulcPropCount = 0;
|
|
}
|
|
}
|
|
LocalFreeAndNull(&szBuf);
|
|
return bRet;
|
|
}
|
|
|
|
|
|
//$$//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// GetDetails from UI - reads the UI for its parameters and verifies that
|
|
// all required fields are set.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
BOOL GetDetailsFromUI( HWND hDlg, LPPROP_ARRAY_INFO lpPai ,
|
|
BOOL bSomethingChanged, int nPropSheet,
|
|
LPSPropValue * lppPropArray, LPULONG lpulcPropCount)
|
|
{
|
|
BOOL bRet = TRUE;
|
|
ULONG i = 0;
|
|
|
|
LPSPropValue lpPropArray = NULL;
|
|
ULONG ulcPropCount = 0,ulIndex=0;
|
|
|
|
ID_PROP * lpidProp = NULL;
|
|
ULONG idPropCount = 0;
|
|
|
|
ULONG ulNotEmptyCount = 0;
|
|
SCODE sc = S_OK;
|
|
HRESULT hr = hrSuccess;
|
|
|
|
if (!bSomethingChanged)
|
|
{
|
|
bRet = TRUE;
|
|
goto out;
|
|
}
|
|
|
|
*lppPropArray = NULL;
|
|
*lpulcPropCount = 0;
|
|
|
|
DebugTrace( TEXT("GetDetailsFromUI: %d\n"),nPropSheet);
|
|
|
|
switch(nPropSheet)
|
|
{
|
|
case propHome:
|
|
idPropCount = idPropHomeCount;
|
|
lpidProp = idPropHome;
|
|
lpidProp[idPropHomePostalID].ulPropTag = PR_WAB_POSTALID;
|
|
goto GetProp;
|
|
case propBusiness:
|
|
idPropCount = idPropBusinessCount;
|
|
lpidProp = idPropBusiness;
|
|
lpidProp[idPropBusIPPhone].ulPropTag = PR_WAB_IPPHONE;
|
|
lpidProp[idPropBusPostalID].ulPropTag = PR_WAB_POSTALID;
|
|
goto GetProp;
|
|
case propNotes:
|
|
idPropCount = idPropNotesCount;
|
|
lpidProp = idPropNotes;
|
|
GetProp:
|
|
bRet = bGetHomeBusNotesInfo(hDlg, lpPai, nPropSheet,
|
|
lpidProp, idPropCount,lppPropArray, lpulcPropCount);
|
|
break;
|
|
/***********/
|
|
case propPersonal:
|
|
bRet = bGetPersonalInfo(hDlg, lpPai, idPropPersonal, idPropPersonalCount, lppPropArray, lpulcPropCount);
|
|
break; // case propPersonal
|
|
/***********/
|
|
case propCert:
|
|
// There is only 1 property, PR_USER_X509_CERTIFICATE
|
|
if(lpPai->lpCItem)
|
|
{
|
|
if(HR_FAILED(HrSetCertsFromDisplayInfo( lpPai->lpCItem, lpulcPropCount, lppPropArray)))
|
|
bRet = FALSE;
|
|
}
|
|
break;
|
|
/***********/
|
|
case propConferencing:
|
|
bRet = bGetConferencingInfo(hDlg, lpPai,lppPropArray, lpulcPropCount);
|
|
break;
|
|
/***********/
|
|
case propFamily:
|
|
bRet = bGetFamilyInfo(hDlg, lpPai, idPropFamily, idPropFamilyCount, lppPropArray, lpulcPropCount);
|
|
break;
|
|
}
|
|
|
|
out:
|
|
if (!bRet)
|
|
{
|
|
if ((lpPropArray) && (ulcPropCount > 0))
|
|
{
|
|
MAPIFreeBuffer(lpPropArray);
|
|
ulcPropCount = 0;
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
//$$//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// bUpdatePropArray
|
|
//
|
|
// Updates the prop array info for each sheet that is stored in the globaly accessible
|
|
// pointer
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
BOOL bUpdatePropArray(HWND hDlg, LPPROP_ARRAY_INFO lpPai, int nPropSheet)
|
|
{
|
|
BOOL bRet = TRUE;
|
|
ULONG cValues = 0;
|
|
LPSPropValue rgPropVals = NULL;
|
|
if (lpPai->ulOperationType != SHOW_ONE_OFF)
|
|
{
|
|
bUpdateOldPropTagArray(lpPai, nPropSheet);
|
|
|
|
lpPai->bSomethingChanged = ChangedExtDisplayInfo(lpPai, lpPai->bSomethingChanged);
|
|
|
|
if(lpPai->bSomethingChanged)
|
|
{
|
|
bRet = GetDetailsFromUI( hDlg, lpPai, lpPai->bSomethingChanged, nPropSheet, &rgPropVals, &cValues);
|
|
if(cValues && rgPropVals)
|
|
{
|
|
#ifdef DEBUG
|
|
_DebugProperties(rgPropVals, cValues, TEXT("GetDetails from UI\n"));
|
|
#endif
|
|
lpPai->lpPropObj->lpVtbl->SetProps(lpPai->lpPropObj, cValues, rgPropVals, NULL);
|
|
}
|
|
}
|
|
}
|
|
FreeBufferAndNull(&rgPropVals);
|
|
return bRet;
|
|
}
|
|
|
|
|
|
|
|
|
|
#define lpPAI ((LPPROP_ARRAY_INFO) pps->lParam)
|
|
#define lpbSomethingChanged (&(lpPAI->bSomethingChanged))
|
|
|
|
/*//$$***********************************************************************
|
|
* FUNCTION: fnPersonalProc
|
|
*
|
|
* PURPOSE: Callback function for handling the PERSONAL property sheet ...
|
|
*
|
|
****************************************************************************/
|
|
INT_PTR CALLBACK fnPersonalProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)
|
|
{
|
|
PROPSHEETPAGE * pps;
|
|
BOOL bRet = FALSE;
|
|
|
|
pps = (PROPSHEETPAGE *) GetWindowLongPtr(hDlg, DWLP_USER);
|
|
|
|
switch(message)
|
|
{
|
|
case WM_INITDIALOG:
|
|
SetWindowLongPtr(hDlg,DWLP_USER,lParam);
|
|
pps = (PROPSHEETPAGE *) lParam;
|
|
lpPAI->ulFlags |= DETAILS_Initializing;
|
|
ChangeLocaleBasedTabOrder(hDlg, contactPersonal);
|
|
SetDetailsUI(hDlg,lpPAI, lpPAI->ulOperationType,propPersonal);
|
|
lpPAI->ulFlags &= ~DETAILS_Initializing;
|
|
return TRUE;
|
|
|
|
case WM_DESTROY:
|
|
bRet = TRUE;
|
|
break;
|
|
|
|
case WM_SYSCOLORCHANGE:
|
|
//Forward any system changes to the list view
|
|
SendMessage(GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_LIST), message, wParam, lParam);
|
|
break;
|
|
|
|
case WM_HELP:
|
|
WABWinHelp(((LPHELPINFO)lParam)->hItemHandle,
|
|
g_szWABHelpFileName,
|
|
HELP_WM_HELP,
|
|
(DWORD_PTR)(LPSTR) rgDetlsHelpIDs );
|
|
break;
|
|
|
|
case WM_CONTEXTMENU:
|
|
WABWinHelp((HWND) wParam,
|
|
g_szWABHelpFileName,
|
|
HELP_CONTEXTMENU,
|
|
(DWORD_PTR)(LPVOID) rgDetlsHelpIDs );
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch(GET_WM_COMMAND_CMD(wParam,lParam)) //check the notification code
|
|
{
|
|
case CBN_DROPDOWN:
|
|
switch(LOWORD(wParam))
|
|
{
|
|
case IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME:
|
|
SetComboDNText(hDlg, lpPAI, TRUE, NULL);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case CBN_SELCHANGE:
|
|
switch(LOWORD(wParam))
|
|
{
|
|
case IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME:
|
|
{
|
|
int nSel = (int) SendDlgItemMessage(hDlg, IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME, CB_GETCURSEL, 0, 0);
|
|
if(nSel != CB_ERR)
|
|
{
|
|
int nLen = (int) SendDlgItemMessage(hDlg, IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME, CB_GETLBTEXTLEN, (WPARAM)nSel, 0);
|
|
if(nLen != CB_ERR)
|
|
{
|
|
LPTSTR lpsz = LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*(nLen + 1));
|
|
if(lpsz)
|
|
{
|
|
SendDlgItemMessage(hDlg, IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME, CB_GETLBTEXT, (WPARAM)nSel, (LPARAM)lpsz);
|
|
SetWindowPropertiesTitle(GetParent(hDlg), lpsz);
|
|
if (lpbSomethingChanged) //some edit box changed - dont care which
|
|
(*lpbSomethingChanged) = TRUE;
|
|
LocalFreeAndNull(&lpsz);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case CBN_EDITCHANGE:
|
|
switch(LOWORD(wParam))
|
|
{
|
|
case IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME:
|
|
if(!(lpPAI->ulFlags & DETAILS_ProgChange) )
|
|
{
|
|
lpPAI->ulFlags &= ~DETAILS_DNisFMLName;
|
|
lpPAI->ulFlags &= ~DETAILS_DNisNickName;
|
|
lpPAI->ulFlags &= ~DETAILS_DNisCompanyName;
|
|
}
|
|
{
|
|
TCHAR szBuf[MAX_UI_STR];
|
|
szBuf[0]='\0';
|
|
GetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME, szBuf, CharSizeOf(szBuf));
|
|
SetWindowPropertiesTitle(GetParent(hDlg), szBuf);
|
|
if (lpbSomethingChanged) //some edit box changed - dont care which
|
|
(*lpbSomethingChanged) = TRUE;
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case EN_CHANGE:
|
|
if(lpPAI->ulFlags & DETAILS_Initializing)
|
|
break;
|
|
if (lpbSomethingChanged) //some edit box changed - dont care which
|
|
(*lpbSomethingChanged) = TRUE;
|
|
switch(LOWORD(wParam))
|
|
{
|
|
case IDC_DETAILS_PERSONAL_EDIT_ADDEMAIL:
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_ADDEMAIL),TRUE);
|
|
SendMessage(hDlg, DM_SETDEFID, IDC_DETAILS_PERSONAL_BUTTON_ADDEMAIL, 0);
|
|
return 0;
|
|
break;
|
|
|
|
case IDC_DETAILS_PERSONAL_EDIT_FIRSTNAME:
|
|
case IDC_DETAILS_PERSONAL_EDIT_LASTNAME:
|
|
case IDC_DETAILS_PERSONAL_EDIT_MIDDLENAME:
|
|
// if there is nothing in the display name field (new contact)
|
|
// and we are typing here, update the display name
|
|
//TCHAR szBuf[2];
|
|
//int nText = GetWindowText(lpPAI->hWndDisplayNameField, szBuf, CharSizeOf(szBuf));
|
|
if(lpPAI->ulFlags & DETAILS_DNisFMLName)// || !nText)
|
|
{
|
|
lpPAI->ulFlags |= DETAILS_ProgChange;
|
|
SetDetailsWindowTitle(hDlg, TRUE);
|
|
lpPAI->ulFlags &= ~DETAILS_ProgChange;
|
|
}
|
|
|
|
// [PaulHi] 4/8/99
|
|
// If the text in the edit box was deleted then also delete the corresponding
|
|
// Ruby field text
|
|
if(lpPAI->ulFlags & DETAILS_UseRubyPersonal)
|
|
{
|
|
HWND hWndEdit = GetDlgItem(hDlg, LOWORD(wParam));
|
|
HWND hWndRuby = NULL;
|
|
WCHAR wszTemp[EDIT_LEN];
|
|
|
|
Assert(hWndEdit);
|
|
|
|
GetWindowText(hWndEdit, wszTemp, EDIT_LEN);
|
|
if (*wszTemp == '\0')
|
|
{
|
|
// Clear either the first or last name ruby field, depending on which
|
|
// edit control this is.
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case IDC_DETAILS_PERSONAL_EDIT_FIRSTNAME:
|
|
hWndRuby = GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_STATIC_RUBYFIRST);
|
|
break;
|
|
|
|
case IDC_DETAILS_PERSONAL_EDIT_LASTNAME:
|
|
hWndRuby = GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_STATIC_RUBYLAST);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (hWndRuby)
|
|
SetWindowText(hWndRuby, szEmpty);
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case IDC_DETAILS_PERSONAL_EDIT_NICKNAME:
|
|
{
|
|
if(lpPAI->ulFlags & DETAILS_DNisNickName)
|
|
{
|
|
TCHAR szBuf[MAX_UI_STR];
|
|
szBuf[0]='\0';
|
|
GetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_EDIT_NICKNAME, szBuf, CharSizeOf(szBuf));
|
|
lpPAI->ulFlags |= DETAILS_ProgChange;
|
|
SetComboDNText(hDlg, lpPAI, FALSE, szBuf);
|
|
lpPAI->ulFlags &= ~DETAILS_ProgChange;
|
|
}
|
|
else
|
|
SetComboDNText(hDlg, lpPAI, TRUE, NULL);
|
|
|
|
}
|
|
break;
|
|
|
|
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
switch(GET_WM_COMMAND_ID(wParam, lParam))
|
|
{
|
|
case IDC_DETAILS_PERSONAL_BUTTON_RUBY:
|
|
ShowRubyNameEntryDlg(hDlg, lpPAI);
|
|
break;
|
|
|
|
case IDC_DETAILS_PERSONAL_CHECK_RICHINFO:
|
|
if (lpbSomethingChanged)
|
|
(*lpbSomethingChanged) = TRUE;
|
|
break;
|
|
|
|
case IDC_DETAILS_PERSONAL_BUTTON_SETDEFAULT:
|
|
{
|
|
HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_LIST);
|
|
if(ListView_GetSelectedCount(hWndLV)==1)
|
|
{
|
|
SetLVDefaultEmail( hWndLV, ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED));
|
|
if (lpbSomethingChanged)
|
|
(*lpbSomethingChanged) = TRUE;
|
|
}
|
|
|
|
}
|
|
break;
|
|
|
|
case IDC_DETAILS_PERSONAL_BUTTON_EDIT:
|
|
{
|
|
HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_LIST);
|
|
if(ListView_GetSelectedCount(hWndLV)==1)
|
|
{
|
|
HWND hWndEditLabel;
|
|
int index = ListView_GetNextItem(hWndLV,-1,LVNI_SELECTED);
|
|
SetFocus(hWndLV);
|
|
hWndEditLabel = ListView_EditLabel(hWndLV, index);
|
|
// Set Text Limit on this Edit Box
|
|
SendMessage(hWndEditLabel, EM_LIMITTEXT, EDIT_LEN, 0);
|
|
}
|
|
|
|
}
|
|
break;
|
|
|
|
case IDC_DETAILS_PERSONAL_BUTTON_REMOVE:
|
|
{
|
|
HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_LIST);
|
|
if(ListView_GetSelectedCount(hWndLV)>=1)
|
|
{
|
|
BOOL bSetNewDefault = FALSE;
|
|
int iItemIndex = ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED);
|
|
while(iItemIndex != -1)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
bRet = DeleteLVEmailItem(hWndLV,iItemIndex);
|
|
if (!bSetNewDefault)
|
|
bSetNewDefault = bRet;
|
|
iItemIndex = ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED);
|
|
}
|
|
|
|
if (bSetNewDefault && (ListView_GetItemCount(hWndLV) > 0))
|
|
SetLVDefaultEmail(hWndLV, 0);
|
|
|
|
if (lpbSomethingChanged)
|
|
(*lpbSomethingChanged) = TRUE;
|
|
|
|
if (ListView_GetItemCount(hWndLV) <= 0)
|
|
{
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_REMOVE),FALSE);
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_SETDEFAULT),FALSE);
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_EDIT),FALSE);
|
|
SetFocus(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_EDIT_ADDEMAIL));
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
//make sure something is selected
|
|
if(ListView_GetSelectedCount(hWndLV) <= 0)
|
|
LVSelectItem(hWndLV,0);
|
|
}
|
|
}
|
|
|
|
}
|
|
break;
|
|
|
|
case IDC_DETAILS_PERSONAL_BUTTON_ADDEMAIL:
|
|
AddNewEmailEntry(hDlg,FALSE);
|
|
return FALSE;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
|
|
case WM_NOTIFY:
|
|
switch(((NMHDR FAR *)lParam)->code)
|
|
{
|
|
case PSN_SETACTIVE: //initialize
|
|
FillPersonalDetails(hDlg, lpPAI, propPersonal, lpbSomethingChanged);
|
|
if(lpPAI->ulOperationType != SHOW_ONE_OFF)
|
|
{
|
|
// Since items to this list view can be added from certs and conf panes,
|
|
// update this everytime the focus somes back to us
|
|
if(ListView_GetItemCount(GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_LIST)) > 0)
|
|
{
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_REMOVE),TRUE);
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_SETDEFAULT),TRUE);
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_EDIT),TRUE);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case PSN_KILLACTIVE: //Losing activation to another page
|
|
if (lpPAI->ulOperationType != SHOW_ONE_OFF)
|
|
{
|
|
// check if there is some pending email entry
|
|
if(IDCANCEL == AddNewEmailEntry(hDlg,TRUE))
|
|
{
|
|
//abort this ok
|
|
SetFocus(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_EDIT_ADDEMAIL));
|
|
SetWindowLongPtr(hDlg,DWLP_MSGRESULT, TRUE);
|
|
return TRUE;
|
|
}
|
|
}
|
|
bUpdatePropArray(hDlg, lpPAI, propPersonal);
|
|
FreeLVParams(GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_LIST),LV_EMAIL);
|
|
break;
|
|
|
|
case PSN_APPLY: //ok
|
|
if (lpPAI->ulOperationType != SHOW_ONE_OFF)
|
|
{
|
|
int CtlID = 0; //used to determine which required field in the UI has not been set
|
|
ULONG ulcPropCount = 0;
|
|
if(!bVerifyRequiredData(hDlg, lpPAI, propPersonal, &CtlID))
|
|
{
|
|
SetFocus(GetDlgItem(hDlg,CtlID));
|
|
SetWindowLongPtr(hDlg,DWLP_MSGRESULT, TRUE);
|
|
return TRUE;
|
|
}
|
|
}
|
|
//bUpdatePropArray(hDlg, lpPAI, propPersonal);
|
|
//FreeLVParams(GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_LIST),LV_EMAIL);
|
|
if (lpPAI->nRetVal == DETAILS_RESET)
|
|
lpPAI->nRetVal = DETAILS_OK;
|
|
break;
|
|
|
|
case PSN_RESET: //cancel
|
|
if(lpPAI->ulFlags & DETAILS_EditingEmail) //cancel any email editing else it faults #30235
|
|
{
|
|
ListView_EditLabel(GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_LIST), -1);
|
|
lpPAI->ulFlags &= ~DETAILS_EditingEmail;
|
|
}
|
|
FreeLVParams(GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_LIST),LV_EMAIL);
|
|
if (lpPAI->nRetVal == DETAILS_RESET)
|
|
lpPAI->nRetVal = DETAILS_CANCEL;
|
|
break;
|
|
|
|
case LVN_BEGINLABELEDITA:
|
|
case LVN_BEGINLABELEDITW:
|
|
{
|
|
// We are editing a email address in teh list box
|
|
// We need to get:
|
|
// item index number
|
|
// item lParam
|
|
// edit box hWnd
|
|
// and replace the text with the actual email address
|
|
HWND hWndLV = ((NMHDR FAR *)lParam)->hwndFrom;
|
|
LV_ITEM lvi = ((LV_DISPINFO FAR *) lParam)->item;
|
|
if (lvi.iItem >= 0)
|
|
{
|
|
HWND hWndLVEdit = NULL;
|
|
LPEMAIL_ITEM lpEItem = NULL;
|
|
if (lvi.mask & LVIF_PARAM)
|
|
{
|
|
lpEItem = (LPEMAIL_ITEM) lvi.lParam;
|
|
}
|
|
else
|
|
{
|
|
lvi.mask |= LVIF_PARAM;
|
|
if (ListView_GetItem(hWndLV, &lvi))
|
|
lpEItem = (LPEMAIL_ITEM) lvi.lParam;
|
|
}
|
|
if (!lpEItem)
|
|
return TRUE; //prevents editing
|
|
|
|
hWndLVEdit = ListView_GetEditControl(hWndLV);
|
|
|
|
if (!hWndLVEdit)
|
|
return TRUE;
|
|
|
|
lpPAI->ulFlags |= DETAILS_EditingEmail;
|
|
|
|
SendMessage(hWndLVEdit, WM_SETTEXT, 0, (LPARAM) lpEItem->szEmailAddress);//lpText);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
}
|
|
return TRUE;
|
|
break;
|
|
|
|
case LVN_ENDLABELEDITA:
|
|
case LVN_ENDLABELEDITW:
|
|
{
|
|
// We get the text from the edit box and put it in the item data
|
|
BOOL bRet = FALSE;
|
|
HWND hWndLV = ((NMHDR FAR *)lParam)->hwndFrom;
|
|
LV_ITEM lvi = ((LV_DISPINFO FAR *) lParam)->item;
|
|
LPWSTR lpW = NULL;
|
|
LPSTR lpA = NULL;
|
|
if(!g_bRunningOnNT) //on Win9x we will get an LV_ITEMA, not a LV_ITEMW
|
|
{
|
|
lpA = (LPSTR)lvi.pszText;
|
|
lpW = ConvertAtoW(lpA);
|
|
lvi.pszText = lpW;
|
|
}
|
|
if ((lvi.iItem >= 0) && lvi.pszText && (lstrlen(lvi.pszText)))
|
|
{
|
|
LV_ITEM lviActual = {0};
|
|
LPEMAIL_ITEM lpEItem = NULL;
|
|
BOOL bSetDefault = FALSE;
|
|
LPTSTR lpText = lvi.pszText;
|
|
LPTSTR lpszEmailAddress = NULL;
|
|
if(!IsInternetAddress(lpText, &lpszEmailAddress))
|
|
{
|
|
if(IDNO == ShowMessageBox(GetParent(hDlg), idsInvalidInternetAddress, MB_ICONEXCLAMATION | MB_YESNO))
|
|
{
|
|
bRet = TRUE;
|
|
goto endN;
|
|
}
|
|
}
|
|
|
|
// bobn, Raid 87496, IsInternetAddress can correctly leave lpszEmailAddress NULL
|
|
// if it returns false. If the user said to use it, we need to set it accordingly.
|
|
if(!lpszEmailAddress)
|
|
lpszEmailAddress = lpText;
|
|
|
|
lviActual.mask = LVIF_PARAM | LVIF_TEXT;
|
|
lviActual.iItem = lvi.iItem;
|
|
|
|
if (ListView_GetItem(hWndLV, &lviActual))
|
|
lpEItem = (LPEMAIL_ITEM) lviActual.lParam;
|
|
|
|
if (!lpEItem)
|
|
{
|
|
bRet = TRUE;
|
|
goto endN;
|
|
}
|
|
|
|
StrCpyN(lpEItem->szEmailAddress, lpszEmailAddress, ARRAYSIZE(lpEItem->szEmailAddress));
|
|
StrCpyN(lpEItem->szDisplayText, lpszEmailAddress, ARRAYSIZE(lpEItem->szDisplayText));
|
|
lviActual.pszText = lpszEmailAddress;
|
|
|
|
// Throw away any display name that may have been entered here.
|
|
|
|
bSetDefault = lpEItem->bIsDefault;
|
|
lpEItem->bIsDefault = FALSE; //this will be set again in SetLVDefaultEmail function
|
|
|
|
ListView_SetItem(hWndLV, &lviActual);
|
|
if (bSetDefault)
|
|
SetLVDefaultEmail(hWndLV, lvi.iItem);
|
|
|
|
lpPAI->ulFlags &= ~DETAILS_EditingEmail;
|
|
|
|
bRet = FALSE;
|
|
}
|
|
endN:
|
|
LocalFreeAndNull(&lpW);
|
|
if(!g_bRunningOnNT)
|
|
((LV_DISPINFO FAR *) lParam)->item.pszText = (LPWSTR)lpA; // reset it as we found it
|
|
return bRet;
|
|
}
|
|
return TRUE;
|
|
break;
|
|
|
|
case NM_DBLCLK:
|
|
switch(wParam)
|
|
{
|
|
case IDC_DETAILS_PERSONAL_LIST:
|
|
{
|
|
NM_LISTVIEW * pNm = (NM_LISTVIEW *)lParam;
|
|
if (ListView_GetSelectedCount(pNm->hdr.hwndFrom) == 1)
|
|
{
|
|
int iItemIndex = ListView_GetNextItem(pNm->hdr.hwndFrom,-1,LVNI_SELECTED);
|
|
SetLVDefaultEmail(pNm->hdr.hwndFrom, iItemIndex);
|
|
if (lpbSomethingChanged)
|
|
(*lpbSomethingChanged) = TRUE;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case NM_CUSTOMDRAW:
|
|
switch(wParam)
|
|
{
|
|
case IDC_DETAILS_PERSONAL_LIST:
|
|
{
|
|
NMCUSTOMDRAW *pnmcd=(NMCUSTOMDRAW*)lParam;
|
|
NM_LISTVIEW * pNm = (NM_LISTVIEW *)lParam;
|
|
if(pnmcd->dwDrawStage==CDDS_PREPAINT)
|
|
{
|
|
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, CDRF_NOTIFYITEMDRAW | CDRF_DODEFAULT);
|
|
return TRUE;
|
|
}
|
|
else if(pnmcd->dwDrawStage==CDDS_ITEMPREPAINT)
|
|
{
|
|
LPEMAIL_ITEM lpEItem = (LPEMAIL_ITEM) pnmcd->lItemlParam;
|
|
|
|
if (lpEItem)
|
|
{
|
|
if(lpEItem->bIsDefault)
|
|
{
|
|
SelectObject(((NMLVCUSTOMDRAW*)lParam)->nmcd.hdc, GetFont(fntsSysIconBold));
|
|
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, CDRF_NEWFONT);
|
|
return TRUE;
|
|
}
|
|
#ifdef WIN16 // Set font
|
|
else
|
|
{
|
|
SelectObject(((NMLVCUSTOMDRAW*)lParam)->nmcd.hdc, GetFont(fntsSysIcon));
|
|
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, CDRF_NEWFONT);
|
|
return TRUE;
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, CDRF_DODEFAULT);
|
|
return TRUE;
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
}
|
|
break; //WM_NOTIFY
|
|
|
|
default:
|
|
#ifndef WIN16 // WIN16 doesn't support MSWheel.
|
|
if((g_msgMSWheel && message == g_msgMSWheel)
|
|
// || message == WM_MOUSEWHEEL
|
|
)
|
|
{
|
|
SendMessage(GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_LIST), message, wParam, lParam);
|
|
}
|
|
#endif
|
|
break;
|
|
|
|
} //switch
|
|
|
|
|
|
return bRet;
|
|
|
|
}
|
|
|
|
|
|
/*//$$***********************************************************************
|
|
* FUNCTION: fnHomeProc
|
|
*
|
|
* PURPOSE: Callback function for handling the HOME property sheet ...
|
|
*
|
|
****************************************************************************/
|
|
INT_PTR CALLBACK fnHomeProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)
|
|
{
|
|
PROPSHEETPAGE * pps;
|
|
BOOL bRet = FALSE;
|
|
|
|
pps = (PROPSHEETPAGE *) GetWindowLongPtr(hDlg, DWLP_USER);
|
|
|
|
switch(message)
|
|
{
|
|
case WM_INITDIALOG:
|
|
SetWindowLongPtr(hDlg,DWLP_USER,lParam);
|
|
pps = (PROPSHEETPAGE *) lParam;
|
|
lpPAI->ulFlags |= DETAILS_Initializing;
|
|
SetDetailsUI(hDlg, lpPAI, lpPAI->ulOperationType,propHome);
|
|
ChangeLocaleBasedTabOrder(hDlg, contactHome);
|
|
lpPAI->ulFlags &= ~DETAILS_Initializing;
|
|
return TRUE;
|
|
|
|
case WM_HELP:
|
|
WABWinHelp(((LPHELPINFO)lParam)->hItemHandle,
|
|
g_szWABHelpFileName,
|
|
HELP_WM_HELP,
|
|
(DWORD_PTR)(LPSTR) rgDetlsHelpIDs );
|
|
break;
|
|
|
|
case WM_CONTEXTMENU:
|
|
WABWinHelp((HWND)wParam,
|
|
g_szWABHelpFileName,
|
|
HELP_CONTEXTMENU,
|
|
(DWORD_PTR)(LPVOID) rgDetlsHelpIDs );
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch(GET_WM_COMMAND_CMD(wParam,lParam)) //check the notification code
|
|
{
|
|
case EN_CHANGE: //some edit box changed - dont care which
|
|
if(lpPAI->ulFlags & DETAILS_Initializing)
|
|
break;
|
|
if (lpbSomethingChanged)
|
|
(*lpbSomethingChanged) = TRUE;
|
|
break;
|
|
}
|
|
{
|
|
int nCmd = GET_WM_COMMAND_ID(wParam, lParam);
|
|
switch(nCmd)
|
|
{
|
|
case IDC_DETAILS_HOME_CHECK_DEFAULTADDRESS:
|
|
if (lpbSomethingChanged)
|
|
(*lpbSomethingChanged) = TRUE;
|
|
lpPAI->ulFlags |= DETAILS_DefHomeChanged;
|
|
break;
|
|
case IDCANCEL:
|
|
// This is a windows bug that prevents ESC canceling prop sheets
|
|
// which have MultiLine Edit boxes KB: Q130765
|
|
SendMessage(GetParent(hDlg),message,wParam,lParam);
|
|
break;
|
|
case IDC_DETAILS_HOME_BUTTON_MAP:
|
|
bUpdatePropArray(hDlg, lpPAI, propHome); // update the props from the fields onto the prop-object
|
|
ShowExpediaMAP(hDlg, lpPAI->lpPropObj, TRUE);
|
|
break;
|
|
|
|
case IDC_DETAILS_HOME_BUTTON_URL:
|
|
ShowURL(hDlg, IDC_DETAILS_HOME_EDIT_URL,NULL);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
|
|
|
|
case WM_NOTIFY:
|
|
switch(((NMHDR FAR *)lParam)->code)
|
|
{
|
|
case PSN_SETACTIVE: //initialize
|
|
FillHomeBusinessNotesDetailsUI(hDlg, lpPAI, propHome, lpbSomethingChanged);
|
|
break;
|
|
|
|
case PSN_KILLACTIVE: //Losing activation to another page
|
|
bUpdatePropArray(hDlg, lpPAI, propHome);
|
|
lpPAI->ulFlags &= ~DETAILS_DefHomeChanged; //reset flag
|
|
break;
|
|
|
|
case PSN_APPLY: //ok
|
|
//bUpdatePropArray(hDlg, lpPAI, propHome);
|
|
// in case any of the extended props changed, we need to mark this flag so we wont lose data
|
|
if (lpPAI->nRetVal == DETAILS_RESET)
|
|
lpPAI->nRetVal = DETAILS_OK;
|
|
break;
|
|
|
|
case PSN_RESET: //cancel
|
|
if (lpPAI->nRetVal == DETAILS_RESET)
|
|
lpPAI->nRetVal = DETAILS_CANCEL;
|
|
break;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return bRet;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*//$$***********************************************************************
|
|
* FUNCTION: fnBusinessProc
|
|
*
|
|
* PURPOSE: Callback function for handling the BUSINESS property sheet ...
|
|
*
|
|
****************************************************************************/
|
|
INT_PTR CALLBACK fnBusinessProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)
|
|
{
|
|
PROPSHEETPAGE * pps;
|
|
BOOL bRet = FALSE;
|
|
|
|
pps = (PROPSHEETPAGE *) GetWindowLongPtr(hDlg, DWLP_USER);
|
|
|
|
switch(message)
|
|
{
|
|
case WM_INITDIALOG:
|
|
SetWindowLongPtr(hDlg,DWLP_USER,lParam);
|
|
pps = (PROPSHEETPAGE *) lParam;
|
|
lpPAI->ulFlags |= DETAILS_Initializing;
|
|
ChangeLocaleBasedTabOrder(hDlg, contactBusiness);
|
|
SetDetailsUI(hDlg, lpPAI, lpPAI->ulOperationType,propBusiness);
|
|
lpPAI->ulFlags &= ~DETAILS_Initializing;
|
|
// (*lpbSomethingChanged) = FALSE;
|
|
return TRUE;
|
|
|
|
case WM_HELP:
|
|
WABWinHelp(((LPHELPINFO)lParam)->hItemHandle,
|
|
g_szWABHelpFileName,
|
|
HELP_WM_HELP,
|
|
(DWORD_PTR)(LPSTR) rgDetlsHelpIDs );
|
|
break;
|
|
|
|
case WM_CONTEXTMENU:
|
|
WABWinHelp((HWND) wParam,
|
|
g_szWABHelpFileName,
|
|
HELP_CONTEXTMENU,
|
|
(DWORD_PTR)(LPVOID) rgDetlsHelpIDs );
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch(GET_WM_COMMAND_CMD(wParam,lParam)) //check the notification code
|
|
{
|
|
case EN_CHANGE: //some edit box changed - dont care which
|
|
if(lpPAI->ulFlags & DETAILS_Initializing)
|
|
break;
|
|
if (lpbSomethingChanged)
|
|
(*lpbSomethingChanged) = TRUE;
|
|
break;
|
|
}
|
|
switch(GET_WM_COMMAND_ID(wParam, lParam))
|
|
{
|
|
case IDC_DETAILS_BUSINESS_CHECK_DEFAULTADDRESS:
|
|
if (lpbSomethingChanged)
|
|
(*lpbSomethingChanged) = TRUE;
|
|
lpPAI->ulFlags |= DETAILS_DefBusChanged;
|
|
break;
|
|
case IDCANCEL:
|
|
// This is a windows bug that prevents ESC canceling prop sheets
|
|
// which have MultiLine Edit boxes KB: Q130765
|
|
SendMessage(GetParent(hDlg),message,wParam,lParam);
|
|
break;
|
|
|
|
case IDC_DETAILS_BUSINESS_BUTTON_MAP:
|
|
bUpdatePropArray(hDlg, lpPAI, propBusiness); // update the props from the fields onto the prop-object
|
|
ShowExpediaMAP(hDlg, lpPAI->lpPropObj, FALSE);
|
|
break;
|
|
|
|
case IDC_DETAILS_BUSINESS_BUTTON_URL:
|
|
ShowURL(hDlg, IDC_DETAILS_BUSINESS_EDIT_URL,NULL);
|
|
break;
|
|
|
|
case IDC_DETAILS_BUSINESS_EDIT_COMPANY:
|
|
if(lpPAI->ulFlags & DETAILS_DNisCompanyName)
|
|
{
|
|
TCHAR szBuf[MAX_UI_STR];
|
|
szBuf[0]='\0';
|
|
GetDlgItemText(hDlg, IDC_DETAILS_BUSINESS_EDIT_COMPANY, szBuf, CharSizeOf(szBuf));
|
|
SetWindowPropertiesTitle(GetParent(hDlg), szBuf);
|
|
lpPAI->ulFlags |= DETAILS_ProgChange;
|
|
SetWindowText(lpPAI->hWndDisplayNameField, szBuf);
|
|
lpPAI->ulFlags &= ~DETAILS_ProgChange;
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
|
|
|
|
case WM_NOTIFY:
|
|
switch(((NMHDR FAR *)lParam)->code)
|
|
{
|
|
case PSN_SETACTIVE: //initialize
|
|
FillHomeBusinessNotesDetailsUI(hDlg, lpPAI, propBusiness, lpbSomethingChanged);
|
|
break;
|
|
|
|
case PSN_KILLACTIVE: //Losing activation to another page
|
|
bUpdatePropArray(hDlg, lpPAI, propBusiness);
|
|
lpPAI->ulFlags &= ~DETAILS_DefBusChanged;
|
|
break;
|
|
|
|
case PSN_APPLY: //ok
|
|
//bUpdatePropArray(hDlg, lpPAI, propBusiness);
|
|
if (lpPAI->nRetVal == DETAILS_RESET)
|
|
lpPAI->nRetVal = DETAILS_OK;
|
|
break;
|
|
|
|
case PSN_RESET: //cancel
|
|
if (lpPAI->nRetVal == DETAILS_RESET)
|
|
lpPAI->nRetVal = DETAILS_CANCEL;
|
|
break;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return bRet;
|
|
|
|
}
|
|
|
|
|
|
/*//$$***********************************************************************
|
|
* FUNCTION: fnNotesProc
|
|
*
|
|
* PURPOSE: Callback function for handling the NOTES property sheet ...
|
|
*
|
|
****************************************************************************/
|
|
INT_PTR CALLBACK fnNotesProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)
|
|
{
|
|
PROPSHEETPAGE * pps;
|
|
BOOL bRet = FALSE;
|
|
|
|
pps = (PROPSHEETPAGE *) GetWindowLongPtr(hDlg, DWLP_USER);
|
|
|
|
switch(message)
|
|
{
|
|
case WM_INITDIALOG:
|
|
SetWindowLongPtr(hDlg,DWLP_USER,lParam);
|
|
pps = (PROPSHEETPAGE *) lParam;
|
|
lpPAI->ulFlags |= DETAILS_Initializing;
|
|
SetDetailsUI(hDlg, lpPAI, lpPAI->ulOperationType,propNotes);
|
|
lpPAI->ulFlags &= ~DETAILS_Initializing;
|
|
// (*lpbSomethingChanged) = FALSE;
|
|
return TRUE;
|
|
|
|
case WM_HELP:
|
|
WABWinHelp(((LPHELPINFO)lParam)->hItemHandle,
|
|
g_szWABHelpFileName,
|
|
HELP_WM_HELP,
|
|
(DWORD_PTR)(LPSTR) rgDetlsHelpIDs );
|
|
break;
|
|
|
|
case WM_CONTEXTMENU:
|
|
WABWinHelp((HWND) wParam,
|
|
g_szWABHelpFileName,
|
|
HELP_CONTEXTMENU,
|
|
(DWORD_PTR)(LPVOID) rgDetlsHelpIDs );
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch(GET_WM_COMMAND_CMD(wParam,lParam)) //check the notification code
|
|
{
|
|
case EN_CHANGE: //some edit box changed - dont care which
|
|
if(lpPAI->ulFlags & DETAILS_Initializing)
|
|
break;
|
|
if (lpbSomethingChanged)
|
|
(*lpbSomethingChanged) = TRUE;
|
|
break;
|
|
}
|
|
switch(GET_WM_COMMAND_ID(wParam, lParam))
|
|
{
|
|
case IDCANCEL:
|
|
// This is a windows bug that prevents ESC canceling prop sheets
|
|
// which have MultiLine Edit boxes KB: Q130765
|
|
SendMessage(GetParent(hDlg),message,wParam,lParam);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
|
|
case WM_NOTIFY:
|
|
switch(((NMHDR FAR *)lParam)->code)
|
|
{
|
|
case PSN_SETACTIVE: //initialize
|
|
FillHomeBusinessNotesDetailsUI(hDlg, lpPAI, propNotes, lpbSomethingChanged);
|
|
break;
|
|
|
|
case PSN_KILLACTIVE: //Losing activation to another page
|
|
bUpdatePropArray(hDlg, lpPAI, propNotes);
|
|
break;
|
|
|
|
case PSN_APPLY: //ok
|
|
//bUpdatePropArray(hDlg, lpPAI, propNotes);
|
|
if (lpPAI->nRetVal == DETAILS_RESET)
|
|
lpPAI->nRetVal = DETAILS_OK;
|
|
break;
|
|
|
|
case PSN_RESET: //cancel
|
|
if (lpPAI->nRetVal == DETAILS_RESET)
|
|
lpPAI->nRetVal = DETAILS_CANCEL;
|
|
break;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return bRet;
|
|
|
|
}
|
|
|
|
/*//$$***********************************************************************
|
|
* FUNCTION: fnCertProc
|
|
*
|
|
* PURPOSE: Callback function for handling the Certificates property sheet ...
|
|
*
|
|
****************************************************************************/
|
|
INT_PTR CALLBACK fnCertProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)
|
|
{
|
|
PROPSHEETPAGE * pps;
|
|
BOOL bRet = FALSE;
|
|
|
|
pps = (PROPSHEETPAGE *) GetWindowLongPtr(hDlg, DWLP_USER);
|
|
|
|
switch(message)
|
|
{
|
|
case WM_INITDIALOG:
|
|
SetWindowLongPtr(hDlg,DWLP_USER,lParam);
|
|
pps = (PROPSHEETPAGE *) lParam;
|
|
lpPAI->ulFlags |= DETAILS_Initializing;
|
|
SetDetailsUI(hDlg, lpPAI, lpPAI->ulOperationType,propCert);
|
|
lpPAI->ulFlags &= ~DETAILS_Initializing;
|
|
return TRUE;
|
|
|
|
case WM_DESTROY:
|
|
bRet = TRUE;
|
|
break;
|
|
|
|
case WM_HELP:
|
|
WABWinHelp(((LPHELPINFO)lParam)->hItemHandle,
|
|
g_szWABHelpFileName,
|
|
HELP_WM_HELP,
|
|
(DWORD_PTR)(LPSTR) rgDetlsHelpIDs );
|
|
break;
|
|
|
|
case WM_CONTEXTMENU:
|
|
WABWinHelp((HWND) wParam,
|
|
g_szWABHelpFileName,
|
|
HELP_CONTEXTMENU,
|
|
(DWORD_PTR)(LPVOID) rgDetlsHelpIDs );
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch(GET_WM_COMMAND_CMD(wParam, lParam))
|
|
{
|
|
case CBN_SELCHANGE:
|
|
UpdateCertListView(hDlg, lpPAI);
|
|
break;
|
|
|
|
}
|
|
switch(LOWORD(wParam))
|
|
{
|
|
case IDCANCEL:
|
|
// This is a windows bug that prevents ESC canceling prop sheets
|
|
// which have MultiLine Edit boxes KB: Q130765
|
|
SendMessage(GetParent(hDlg),message,wParam,lParam);
|
|
break;
|
|
|
|
case IDC_DETAILS_CERT_BUTTON_PROPERTIES:
|
|
{
|
|
ShowCertProps(hDlg, GetDlgItem(hDlg, IDC_DETAILS_CERT_LIST), NULL);
|
|
}
|
|
break;
|
|
|
|
case IDC_DETAILS_CERT_BUTTON_SETDEFAULT:
|
|
{
|
|
HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_CERT_LIST);
|
|
if(ListView_GetSelectedCount(hWndLV)==1)
|
|
{
|
|
SetLVDefaultCert( hWndLV, ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED));
|
|
if (lpbSomethingChanged)
|
|
(*lpbSomethingChanged) = TRUE;
|
|
}
|
|
else if(ListView_GetSelectedCount(hWndLV) <= 0)
|
|
{
|
|
ShowMessageBox(hDlg, IDS_ADDRBK_MESSAGE_NO_ITEM, MB_ICONEXCLAMATION | MB_OK);
|
|
}
|
|
|
|
}
|
|
break;
|
|
|
|
case IDC_DETAILS_CERT_BUTTON_REMOVE:
|
|
{
|
|
HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_CERT_LIST);
|
|
if(ListView_GetSelectedCount(hWndLV)>=1)
|
|
{
|
|
BOOL bSetNewDefault = FALSE;
|
|
int iItemIndex = ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED);
|
|
while(iItemIndex != -1)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
// KillTrustInSleazyFashion(hWndLV, iItemIndex);
|
|
bRet = DeleteLVCertItem(hWndLV,iItemIndex, lpPAI);
|
|
if (!bSetNewDefault)
|
|
bSetNewDefault = bRet;
|
|
|
|
iItemIndex = ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED);
|
|
}
|
|
|
|
if (bSetNewDefault && (ListView_GetItemCount(hWndLV) > 0))
|
|
SetLVDefaultCert(hWndLV, 0);
|
|
|
|
if (lpbSomethingChanged)
|
|
(*lpbSomethingChanged) = TRUE;
|
|
|
|
if (ListView_GetItemCount(hWndLV) <= 0)
|
|
{
|
|
SetFocus(GetDlgItem(hDlg,IDC_DETAILS_CERT_BUTTON_IMPORT));
|
|
EnableWindow(hWndLV,FALSE);
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_BUTTON_PROPERTIES),FALSE);
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_BUTTON_REMOVE),FALSE);
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_BUTTON_SETDEFAULT),FALSE);
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_BUTTON_EXPORT),FALSE);
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
//make sure something is selected
|
|
if(ListView_GetSelectedCount(hWndLV) <= 0)
|
|
LVSelectItem(hWndLV,0);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ShowMessageBox(hDlg, IDS_ADDRBK_MESSAGE_NO_ITEM, MB_ICONEXCLAMATION | MB_OK);
|
|
}
|
|
|
|
}
|
|
break;
|
|
|
|
case IDC_DETAILS_CERT_BUTTON_IMPORT:
|
|
if(ImportCert(hDlg, lpPAI))
|
|
{
|
|
if (lpbSomethingChanged)
|
|
(*lpbSomethingChanged) = TRUE;
|
|
}
|
|
break;
|
|
|
|
case IDC_DETAILS_CERT_BUTTON_EXPORT:
|
|
ExportCert(hDlg);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
|
|
case WM_NOTIFY:
|
|
switch(((NMHDR FAR *)lParam)->code)
|
|
{
|
|
case PSN_SETACTIVE: //initialize
|
|
FillCertTridentConfDetailsUI(hDlg, lpPAI, propCert, lpbSomethingChanged);
|
|
//FillCertComboWithEmailAddresses(hDlg, lpPAI, NULL);
|
|
//UpdateCertListView(hDlg, lpPAI);
|
|
break;
|
|
|
|
case PSN_KILLACTIVE: //Losing activation to another page
|
|
bUpdatePropArray(hDlg, lpPAI, propCert);
|
|
ListView_DeleteAllItems(GetDlgItem(hDlg, IDC_DETAILS_CERT_LIST));
|
|
//lpPAI->lpCItem = NULL;
|
|
break;
|
|
|
|
case PSN_APPLY: //ok
|
|
//bUpdatePropArray(hDlg, lpPAI, propCert);
|
|
//FreeLVParams(GetDlgItem(hDlg, IDC_DETAILS_CERT_LIST),LV_CERT);
|
|
FreeCertList(&(lpPAI->lpCItem));
|
|
if (lpPAI->nRetVal == DETAILS_RESET)
|
|
lpPAI->nRetVal = DETAILS_OK;
|
|
break;
|
|
|
|
case PSN_RESET: //cancel
|
|
FreeCertList(&(lpPAI->lpCItem));
|
|
if (lpPAI->nRetVal == DETAILS_RESET)
|
|
lpPAI->nRetVal = DETAILS_CANCEL;
|
|
break;
|
|
|
|
|
|
case NM_DBLCLK:
|
|
switch(wParam)
|
|
{
|
|
case IDC_DETAILS_CERT_LIST:
|
|
{
|
|
NM_LISTVIEW * pNm = (NM_LISTVIEW *)lParam;
|
|
if (ListView_GetSelectedCount(pNm->hdr.hwndFrom) == 1)
|
|
{
|
|
int iItemIndex = ListView_GetNextItem(pNm->hdr.hwndFrom,-1,LVNI_SELECTED);
|
|
SetLVDefaultCert(pNm->hdr.hwndFrom, iItemIndex);
|
|
if (lpbSomethingChanged)
|
|
(*lpbSomethingChanged) = TRUE;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case NM_CUSTOMDRAW:
|
|
switch(wParam)
|
|
{
|
|
case IDC_DETAILS_CERT_LIST:
|
|
{
|
|
NMCUSTOMDRAW *pnmcd=(NMCUSTOMDRAW*)lParam;
|
|
NM_LISTVIEW * pNm = (NM_LISTVIEW *)lParam;
|
|
if(pnmcd->dwDrawStage==CDDS_PREPAINT)
|
|
{
|
|
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, CDRF_NOTIFYITEMDRAW | CDRF_DODEFAULT);
|
|
return TRUE;
|
|
}
|
|
else if(pnmcd->dwDrawStage==CDDS_ITEMPREPAINT)
|
|
{
|
|
LPCERT_ITEM lpItem = (LPCERT_ITEM) pnmcd->lItemlParam;
|
|
|
|
if (lpItem)
|
|
{
|
|
if(lpItem->lpCDI->bIsDefault)
|
|
{
|
|
SelectObject(((NMLVCUSTOMDRAW*)lParam)->nmcd.hdc, GetFont(fntsSysIconBold));
|
|
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, CDRF_NEWFONT);
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, CDRF_DODEFAULT);
|
|
return TRUE;
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
} //WM_NOTIFY
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return bRet;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*//$$***********************************************************************
|
|
*
|
|
* FUNCTION: HrInitDetlsListView
|
|
*
|
|
* PURPOSE: Initializes the Email Address List View
|
|
*
|
|
****************************************************************************/
|
|
HRESULT HrInitDetlsListView(HWND hWndLV, DWORD dwStyle, int nLVType)
|
|
{
|
|
HRESULT hr=hrSuccess;
|
|
LV_COLUMN lvC; // list view column structure
|
|
DWORD dwLVStyle;
|
|
RECT rc;
|
|
HIMAGELIST hSmall = NULL;
|
|
ULONG nCols=0;
|
|
ULONG index=0;
|
|
int nBmp=0;
|
|
TCHAR sz[MAX_PATH];
|
|
|
|
if (!hWndLV)
|
|
{
|
|
hr = MAPI_E_INVALID_PARAMETER;
|
|
goto out;
|
|
}
|
|
|
|
if(nLVType == LV_EMAIL)
|
|
nBmp = IDB_DEFAULT_EMAIL;
|
|
else if(nLVType == LV_CERT)
|
|
nBmp = IDB_CERT_VALID_INVALID;
|
|
else if(nLVType == LV_KIDS)
|
|
nBmp = IDB_DEFAULT_EMAIL;
|
|
else
|
|
nBmp = 0;
|
|
|
|
ListView_SetExtendedListViewStyle(hWndLV, LVS_EX_FULLROWSELECT);
|
|
|
|
dwLVStyle = GetWindowLong(hWndLV,GWL_STYLE);
|
|
if(( dwLVStyle & LVS_TYPEMASK) != dwStyle)
|
|
SetWindowLong(hWndLV,GWL_STYLE,(dwLVStyle & ~LVS_TYPEMASK) | dwStyle);
|
|
|
|
|
|
if(nBmp)
|
|
{
|
|
hSmall = gpfnImageList_LoadImage( hinstMapiX,
|
|
MAKEINTRESOURCE(nBmp),
|
|
//(LPCTSTR) ((DWORD) ((WORD) (nBmp))),
|
|
S_BITMAP_WIDTH,
|
|
0,
|
|
RGB_TRANSPARENT,
|
|
IMAGE_BITMAP,
|
|
0);
|
|
|
|
// Associate the image lists with the list view control.
|
|
ListView_SetImageList (hWndLV, hSmall, LVSIL_SMALL);
|
|
}
|
|
|
|
GetWindowRect(hWndLV,&rc);
|
|
|
|
lvC.mask = LVCF_FMT | LVCF_WIDTH;
|
|
lvC.fmt = LVCFMT_LEFT; // left-align column
|
|
lvC.cx = rc.right - rc.left - 20; //TBD
|
|
lvC.pszText = NULL;
|
|
|
|
if(nLVType == LV_SERVER)
|
|
{
|
|
lvC.mask |= LVCF_TEXT;
|
|
lvC.cx /= 2;
|
|
LoadString(hinstMapiX, idsConfServer, sz, CharSizeOf(sz));
|
|
lvC.pszText = sz;
|
|
}
|
|
|
|
lvC.iSubItem = 0;
|
|
|
|
if (ListView_InsertColumn (hWndLV, 0, &lvC) == -1)
|
|
{
|
|
DebugPrintError(( TEXT("ListView_InsertColumn Failed\n")));
|
|
hr = E_FAIL;
|
|
goto out;
|
|
}
|
|
|
|
// if this is the conferencing server item, add another prop
|
|
if(nLVType == LV_SERVER)
|
|
{
|
|
LoadString(hinstMapiX, idsConfEmail, sz, CharSizeOf(sz));
|
|
lvC.pszText = sz;
|
|
if (ListView_InsertColumn (hWndLV, 1, &lvC) == -1)
|
|
{
|
|
DebugPrintError(( TEXT("ListView_InsertColumn Failed\n")));
|
|
hr = E_FAIL;
|
|
goto out;
|
|
}
|
|
|
|
}
|
|
|
|
out:
|
|
return hr;
|
|
}
|
|
|
|
/*//$$***********************************************************************
|
|
*
|
|
* FUNCTION: FreeLVParams
|
|
*
|
|
* PURPOSE: Frees the memory allocated to the ListView item lParams
|
|
*
|
|
****************************************************************************/
|
|
void FreeLVParams(HWND hWndLV, int LVType)
|
|
{
|
|
int iItemIndex = ListView_GetItemCount(hWndLV);
|
|
|
|
while(iItemIndex > 0)
|
|
{
|
|
if(LVType == LV_EMAIL)
|
|
DeleteLVEmailItem(hWndLV, iItemIndex-1);
|
|
else if(LVType == LV_CERT)
|
|
DeleteLVCertItem(hWndLV, iItemIndex-1, NULL);
|
|
|
|
iItemIndex = ListView_GetItemCount(hWndLV);
|
|
}
|
|
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
//$$
|
|
BOOL DeleteLVEmailItem(HWND hWndLV, int iItemIndex)
|
|
{
|
|
LV_ITEM lvi;
|
|
LPEMAIL_ITEM lpEItem;
|
|
BOOL bDeletedDefault = FALSE;
|
|
|
|
lvi.mask = LVIF_PARAM;
|
|
lvi.iSubItem = 0;
|
|
lvi.iItem = iItemIndex;
|
|
|
|
ListView_GetItem(hWndLV, &lvi);
|
|
lpEItem = (LPEMAIL_ITEM) lvi.lParam;
|
|
|
|
if (lpEItem->bIsDefault)
|
|
bDeletedDefault = TRUE;
|
|
|
|
LocalFreeAndNull(&lpEItem);
|
|
|
|
ListView_DeleteItem(hWndLV, lvi.iItem);
|
|
|
|
return bDeletedDefault;
|
|
|
|
}
|
|
|
|
|
|
///$$/////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// AddLVEmailItem - Adds an email address to the personal tab list view
|
|
//
|
|
// lpszAddrType can be NULL in which case a default one of type SMTP will be used
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
void AddLVEmailItem(HWND hWndLV,
|
|
LPTSTR lpszEmailAddress,
|
|
LPTSTR lpszAddrType)
|
|
{
|
|
LV_ITEM lvi = {0};
|
|
TCHAR szBuf[MAX_DISPLAY_NAME_LENGTH];
|
|
ULONG nLen;
|
|
LPEMAIL_ITEM lpEItem = NULL;
|
|
|
|
if (!lpszEmailAddress)
|
|
goto out;
|
|
|
|
lpEItem = LocalAlloc(LMEM_ZEROINIT, sizeof(EMAIL_ITEM));
|
|
if (!lpEItem)
|
|
{
|
|
DebugPrintError(( TEXT("AddLVEmailItem: Out of Memory\n")));
|
|
goto out;
|
|
}
|
|
|
|
lpEItem->bIsDefault = FALSE;
|
|
|
|
nLen = lstrlen(lpszEmailAddress) + 1;
|
|
if (nLen > EDIT_LEN)
|
|
{
|
|
ULONG iLen = TruncatePos(lpszEmailAddress, EDIT_LEN - 1);
|
|
CopyMemory(lpEItem->szEmailAddress,lpszEmailAddress,sizeof(TCHAR)*iLen);
|
|
lpEItem->szEmailAddress[iLen] = '\0';
|
|
}
|
|
else
|
|
{
|
|
StrCpyN(lpEItem->szEmailAddress,lpszEmailAddress, ARRAYSIZE(lpEItem->szEmailAddress));
|
|
}
|
|
|
|
StrCpyN(lpEItem->szDisplayText,lpEItem->szEmailAddress, ARRAYSIZE(lpEItem->szDisplayText));
|
|
|
|
if(!lpszAddrType)
|
|
{
|
|
StrCpyN(szBuf, szSMTP, ARRAYSIZE(szBuf));
|
|
lpszAddrType = szBuf;
|
|
}
|
|
|
|
nLen = lstrlen(lpszAddrType) + 1;
|
|
if (nLen > EDIT_LEN)
|
|
{
|
|
ULONG iLen = TruncatePos(lpszAddrType, EDIT_LEN - 1);
|
|
CopyMemory(lpEItem->szAddrType,lpszAddrType,sizeof(TCHAR)*iLen);
|
|
lpEItem->szAddrType[iLen] = '\0';
|
|
}
|
|
else
|
|
{
|
|
StrCpyN(lpEItem->szAddrType,lpszAddrType,ARRAYSIZE(lpEItem->szAddrType));
|
|
}
|
|
|
|
lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
|
|
lvi.pszText = lpEItem->szDisplayText;
|
|
lvi.cchTextMax = MAX_UI_STR;
|
|
lvi.iItem = ListView_GetItemCount(hWndLV);
|
|
lvi.iSubItem = 0;
|
|
lvi.iImage = imgNotDefaultEmail;
|
|
lvi.lParam = (LPARAM) lpEItem;
|
|
|
|
ListView_InsertItem(hWndLV, &lvi);
|
|
|
|
if (ListView_GetItemCount(hWndLV) == 1)
|
|
{
|
|
// only one item in here .. we will take the liberty of making it the
|
|
// default one ...
|
|
SetLVDefaultEmail(hWndLV, 0);
|
|
}
|
|
|
|
out:
|
|
return;
|
|
}
|
|
|
|
|
|
//$$/////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// SetLVDefaultEmail - Makes an email entry the default one ...
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
void SetLVDefaultEmail( HWND hWndLV,
|
|
int iItemIndex)
|
|
{
|
|
int nCount = ListView_GetItemCount(hWndLV);
|
|
int i;
|
|
LPEMAIL_ITEM lpEItem = NULL;
|
|
TCHAR szBuf[MAX_DISPLAY_NAME_LENGTH];
|
|
|
|
if (iItemIndex >= nCount)
|
|
goto out;
|
|
|
|
for(i=0; i<nCount; i++)
|
|
{
|
|
// At amy given point of time one and only one entry in the
|
|
// list view is the default one ...
|
|
// So we want to reset the previous default and set the new one
|
|
//
|
|
LV_ITEM lvi = {0};
|
|
lvi.iItem = i;
|
|
lvi.mask = LVIF_PARAM;
|
|
if(!ListView_GetItem(hWndLV, &lvi))
|
|
goto out;
|
|
lpEItem = (LPEMAIL_ITEM) lvi.lParam;
|
|
if (lpEItem->bIsDefault)
|
|
{
|
|
// This was the default entry - if its the same one we are setting
|
|
// do nothing ...
|
|
if (i == iItemIndex)
|
|
goto out;
|
|
|
|
// else reset this entry ...
|
|
lpEItem->bIsDefault = FALSE;
|
|
lvi.iImage = imgNotDefaultEmail;
|
|
lvi.pszText = lpEItem->szEmailAddress;
|
|
lvi.mask = LVIF_PARAM | LVIF_IMAGE | LVIF_TEXT;
|
|
lvi.iItem = i;
|
|
lvi.iSubItem = 0;
|
|
ListView_SetItem(hWndLV, &lvi);
|
|
}
|
|
if (iItemIndex == i)
|
|
{
|
|
//This is the item we want to modify ..
|
|
lpEItem->bIsDefault = TRUE;
|
|
lvi.iImage = imgDefaultEmail;
|
|
|
|
StrCpyN(lpEItem->szDisplayText,lpEItem->szEmailAddress,ARRAYSIZE(lpEItem->szDisplayText));
|
|
LoadString(hinstMapiX, idsDefaultEmail, szBuf, CharSizeOf(szBuf));
|
|
StrCatBuff(lpEItem->szDisplayText, TEXT(" "), ARRAYSIZE(lpEItem->szDisplayText));
|
|
StrCatBuff(lpEItem->szDisplayText, szBuf, ARRAYSIZE(lpEItem->szDisplayText));
|
|
|
|
lvi.pszText = lpEItem->szDisplayText;
|
|
lvi.mask = LVIF_PARAM | LVIF_IMAGE | LVIF_TEXT;
|
|
lvi.iItem = i;
|
|
lvi.iSubItem = 0;
|
|
ListView_SetItem(hWndLV, &lvi);
|
|
}
|
|
}
|
|
|
|
LVSelectItem(hWndLV, iItemIndex);
|
|
|
|
out:
|
|
return;
|
|
}
|
|
|
|
#ifdef WIN16 // Enable DDE to communicate IE.
|
|
#include <ddeml.h>
|
|
|
|
static char cszIEAppName[] = "IEXPLORE";
|
|
static char cszIEDDEOpenURL[] = "WWW_OpenURL";
|
|
static char cszIEDDEActivate[] = "WWW_Activate";
|
|
|
|
static char cszIEIniFile[] = "iexplore.ini";
|
|
static char cszIEIniSectMain[] = "Main";
|
|
static char cszIEIniKeyStart[] = "Home Page";
|
|
static char cszIEIniKeySearch[] = "Search Page";
|
|
static char cszIEReadNews[] = "news:*";
|
|
|
|
static char cszIEBinName[] = "iexplore.exe";
|
|
static char cszIERegHtm[] = ".htm";
|
|
static char cszRegShellOpen[] = "shell\\open\\command";
|
|
|
|
static HDDEDATA CALLBACK DdeCallback( UINT uType, UINT uFmt, HCONV hConv,
|
|
HSZ hSz1, HSZ hSz2, HDDEDATA hData, DWORD dwData1, DWORD dwData2 )
|
|
{
|
|
return( (HDDEDATA)NULL );
|
|
}
|
|
|
|
#define TIME_WAIT_DDE 10000 // waiting for 10 sec, and if doesn't return,
|
|
// assumes News is configured correctly.
|
|
|
|
void RunBrowser(LPCSTR cszURL, BOOL bCheckRet )
|
|
{
|
|
if ( GetModuleHandle( cszIEBinName ) == NULL )
|
|
{
|
|
//
|
|
// FIND & RUN IEXPLORE
|
|
//
|
|
// Try to find the browser in the Mail's directory
|
|
char szPath[_MAX_PATH*2+1];
|
|
char *pPtr, *pSlash = NULL;;
|
|
HKEY hKey;
|
|
LONG cbPath;
|
|
char szRegPath[_MAX_PATH];
|
|
|
|
GetModuleFileName( hinstMapiXWAB, szPath, _MAX_PATH );
|
|
for ( pPtr = szPath; *pPtr; pPtr = AnsiNext( pPtr ) )
|
|
if ( *pPtr == '\\' )
|
|
{
|
|
pSlash = pPtr;
|
|
}
|
|
if ( pSlash != NULL )
|
|
{
|
|
_fstrcpy( pSlash+1, cszIEBinName );
|
|
_fstrcat( szPath, " " );
|
|
_fstrcat( szPath, cszURL );
|
|
|
|
if ( WinExec( szPath, SW_SHOWNORMAL ) >= 32 )
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Try to find system default browser from the registry
|
|
_fstrcpy( szRegPath, cszIERegHtm );
|
|
while ( RegOpenKey( HKEY_CLASSES_ROOT, szRegPath, &hKey ) == ERROR_SUCCESS )
|
|
{
|
|
LONG lReg;
|
|
cbPath = CharSizeOf( szPath );
|
|
lReg = RegQueryValue( hKey, cszRegShellOpen, szPath, &cbPath );
|
|
RegCloseKey( hKey );
|
|
if ( lReg == ERROR_SUCCESS )
|
|
{
|
|
char *pFmt = _fstrstr( szPath, "%1" );
|
|
if ( pFmt != NULL )
|
|
{
|
|
_fstrcpy( pFmt, cszURL );
|
|
*pFmt = '\0';
|
|
}
|
|
else
|
|
{
|
|
// Can this case happen???
|
|
_fstrcat( szPath, " " );
|
|
_fstrcat( szPath, cszURL );
|
|
}
|
|
|
|
if ( WinExec( szPath, SW_SHOWNORMAL ) >= 32 )
|
|
{
|
|
return;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
cbPath = CharSizeOf( szRegPath );
|
|
if ( RegQueryValue( HKEY_CLASSES_ROOT, szRegPath,
|
|
szRegPath, &cbPath ) != ERROR_SUCCESS )
|
|
break;
|
|
}
|
|
}
|
|
// Insert proper messagebox here
|
|
// MessageBox( IDS_NOT_FOUND_IEXPLORE );
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// CALL IEXPLORE DDE
|
|
//
|
|
if ((GetWinFlags() & WF_PMODE) != 0 ) // None-Protected Mode
|
|
{
|
|
DWORD idInst = 0L;
|
|
FARPROC lpDdeProc = MakeProcInstance( (FARPROC)DdeCallback, hinstMapiXWAB );
|
|
|
|
if ( DdeInitialize( &idInst, (PFNCALLBACK)lpDdeProc,
|
|
APPCMD_CLIENTONLY,
|
|
0L ) == DMLERR_NO_ERROR )
|
|
{
|
|
HSZ hszAppName = DdeCreateStringHandle( idInst, cszIEAppName, CP_WINANSI );
|
|
char szParam[256];
|
|
HSZ hszParam;
|
|
// Activate IE
|
|
HSZ hszTopic = DdeCreateStringHandle( idInst, cszIEDDEActivate, CP_WINANSI );
|
|
HCONV hConv = DdeConnect( idInst, hszAppName, hszTopic, (PCONVCONTEXT)NULL );
|
|
|
|
DdeFreeStringHandle( idInst, hszTopic );
|
|
if ( hConv != NULL )
|
|
{
|
|
wnsprintf( szParam, ARRAYSIZE(szParam), "0x%lX,0x%lX", 0xFFFFFFFF, 0L );
|
|
hszParam = DdeCreateStringHandle( idInst, szParam, CP_WINANSI );
|
|
DdeClientTransaction( NULL, 0L, hConv, hszParam, CF_TEXT,
|
|
XTYP_REQUEST, TIMEOUT_ASYNC, NULL );
|
|
DdeFreeStringHandle( idInst, hszParam );
|
|
DdeDisconnect( hConv );
|
|
}
|
|
|
|
// Request to open URL
|
|
hszTopic = DdeCreateStringHandle( idInst, cszIEDDEOpenURL, CP_WINANSI );
|
|
hConv = DdeConnect( idInst, hszAppName, hszTopic, (PCONVCONTEXT)NULL );
|
|
DdeFreeStringHandle( idInst, hszTopic );
|
|
if ( hConv != NULL )
|
|
{
|
|
HSZ hszParam;
|
|
HDDEDATA hDDE;
|
|
|
|
wnsprintf( szParam, ARRAYSIZE(szParam), "\"%s\",,0x%lX,0x%lX,,,", cszURL, 0xFFFFFFFF, 0L );
|
|
hszParam = DdeCreateStringHandle( idInst, szParam, CP_WINANSI );
|
|
hDDE = DdeClientTransaction( NULL, 0L, hConv, hszParam,
|
|
CF_TEXT, XTYP_REQUEST, TIME_WAIT_DDE, NULL );
|
|
if ( bCheckRet && ( hDDE != NULL ) )
|
|
{
|
|
long lRet;
|
|
DdeGetData( hDDE, &lRet, sizeof( lRet ), 0 );
|
|
DdeFreeDataHandle( hDDE );
|
|
if ( lRet == -5L )
|
|
{
|
|
/*
|
|
// Insert Error message.
|
|
CString strErr, strTmp;
|
|
strErr.LoadString( IDS_DDE_NEWS_NOT_READY1 );
|
|
strTmp.LoadString( IDS_DDE_NEWS_NOT_READY2 );
|
|
strErr += strTmp;
|
|
MessageBox( strErr, NULL, MB_ICONINFORMATION | MB_OK );
|
|
*/
|
|
;
|
|
}
|
|
}
|
|
DdeFreeStringHandle( idInst, hszParam );
|
|
DdeDisconnect( hConv );
|
|
}
|
|
|
|
DdeFreeStringHandle( idInst, hszAppName );
|
|
DdeUninitialize( idInst );
|
|
}
|
|
|
|
FreeProcInstance( lpDdeProc );
|
|
}
|
|
}
|
|
}
|
|
#endif // WIN16
|
|
|
|
|
|
|
|
//$$/////////////////////////////////////////////////////////////////
|
|
//
|
|
// Launches explorer with the URL to show it ...
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
void ShowURL(HWND hWnd, int id, LPTSTR lpURL)
|
|
{
|
|
TCHAR szBuf[MAX_EDIT_LEN];
|
|
LPTSTR lp = NULL;
|
|
|
|
if(!lpURL)
|
|
{
|
|
//get the text in the dialog
|
|
szBuf[0] = 0;
|
|
GetDlgItemText(hWnd, id, szBuf, CharSizeOf(szBuf));
|
|
TrimSpaces(szBuf);
|
|
//if its blank, exit
|
|
if(!lstrlen(szBuf))
|
|
return;
|
|
lpURL = szBuf;
|
|
}
|
|
|
|
// if its just the default prefix, ignore
|
|
if(lstrcmpi(szHTTP, lpURL)!=0)
|
|
{
|
|
if(!bIsHttpPrefix(lpURL))
|
|
{
|
|
ULONG cchSize=lstrlen(lpURL)+lstrlen(szHTTP)+1;
|
|
//append the http:// prefix before shellexecing
|
|
lp = LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*cchSize);
|
|
if (lp)
|
|
{
|
|
StrCpyN(lp, szHTTP, cchSize);
|
|
StrCatBuff(lp, szBuf, cchSize);
|
|
}
|
|
}
|
|
|
|
IF_WIN32(ShellExecute(hWnd, TEXT("open"), (lp ? lp : lpURL), NULL, NULL, SW_SHOWNORMAL);)
|
|
IF_WIN16(RunBrowser((lp ? lp : lpURL), FALSE);) // Need DDE routine to invoke IEXPLORE.
|
|
|
|
if(lp)
|
|
LocalFree(lp);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//$$/////////////////////////////////////////////////////////////////
|
|
//
|
|
// Sets the TEXT("http://") prefix in the URL edit fields if user doesnt
|
|
// anything in there ....
|
|
//
|
|
///////////////////////////////////////////////////////////////////
|
|
void SetHTTPPrefix(HWND hDlg, int id)
|
|
{
|
|
TCHAR szBuf[MAX_EDIT_LEN];
|
|
|
|
// Check to see if anything is filled in ...
|
|
GetDlgItemText(hDlg, id, szBuf, CharSizeOf(szBuf));
|
|
|
|
TrimSpaces(szBuf);
|
|
|
|
if (lstrlen(szBuf))
|
|
return;
|
|
|
|
StrCpyN(szBuf,szHTTP,ARRAYSIZE(szBuf));
|
|
SetDlgItemText(hDlg, id, szBuf);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
//$$/////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// AddNewEmailEntry - Adds text from Email edit box to the list box
|
|
//
|
|
// bShowCancelButton - lets us specify whether to show a dialog with a cancel
|
|
// button
|
|
//
|
|
// returns IDYES, IDNO or IDCANCEL
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
int AddNewEmailEntry(HWND hDlg, BOOL bShowCancelButton)
|
|
{
|
|
int nRet = IDYES;
|
|
TCHAR szBuf[EDIT_LEN];
|
|
LPTSTR lpszEmailAddress = szBuf;
|
|
GetDlgItemText( hDlg,
|
|
IDC_DETAILS_PERSONAL_EDIT_ADDEMAIL,
|
|
szBuf,
|
|
CharSizeOf(szBuf));
|
|
|
|
TrimSpaces(szBuf);
|
|
|
|
if(!lstrlen(szBuf))
|
|
goto out;
|
|
|
|
if(!IsInternetAddress(szBuf, &lpszEmailAddress))
|
|
{
|
|
// Check if this is invalid because of high bytes or something else
|
|
// (Need to warn user about entering DBCS email addresses)
|
|
LPTSTR lpsz = szBuf;
|
|
BOOL bHighBits = FALSE;
|
|
while (*lpsz)
|
|
{
|
|
// Internet addresses only allow pure ASCII. No high bits!
|
|
if (*lpsz >= 0x0080)
|
|
{
|
|
bHighBits = TRUE;
|
|
break;
|
|
}
|
|
lpsz++;
|
|
}
|
|
|
|
if(bHighBits)
|
|
{
|
|
ShowMessageBox(GetParent(hDlg), idsInvalidDBCSInternetAddress, MB_ICONEXCLAMATION | MB_OK);
|
|
SetFocus(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_EDIT_ADDEMAIL));
|
|
goto out;
|
|
}
|
|
else
|
|
{
|
|
// some other casue for error
|
|
int nFlag = (bShowCancelButton ? MB_YESNOCANCEL : MB_YESNO);
|
|
nRet = ShowMessageBox(GetParent(hDlg), idsInvalidInternetAddress, MB_ICONEXCLAMATION | nFlag);
|
|
if(IDYES != nRet)
|
|
{
|
|
SetFocus(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_EDIT_ADDEMAIL));
|
|
goto out;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Add the text to the list box
|
|
AddLVEmailItem( GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_LIST),
|
|
lpszEmailAddress,
|
|
NULL);
|
|
|
|
// If there is no display name and there was one specified in the entered address,
|
|
// add a display name.
|
|
if (szBuf != lpszEmailAddress) { // then there was a DisplayName specified in the entered email address
|
|
TCHAR szBuf2[16]; // big enough to rule out likely leading spaces. Doesn't have to fit entire DN.
|
|
|
|
szBuf2[0] = '\0';
|
|
GetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME, szBuf2, CharSizeOf(szBuf2));
|
|
TrimSpaces(szBuf2);
|
|
if (lstrlen(szBuf2) == 0) {
|
|
// No display name, set one
|
|
SetComboDNText(hDlg, NULL, FALSE, szBuf); // Set the DN
|
|
}
|
|
}
|
|
|
|
|
|
//Cleanout the edit control
|
|
SetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_EDIT_ADDEMAIL, szEmpty);
|
|
|
|
//Disable the add new button
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_ADDEMAIL),FALSE);
|
|
|
|
// enable/disable other buttons
|
|
if(ListView_GetItemCount(GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_LIST)) > 0)
|
|
{
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_REMOVE),TRUE);
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_SETDEFAULT),TRUE);
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_EDIT),TRUE);
|
|
}
|
|
|
|
// Set the focus to the email edit field
|
|
SetFocus(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_EDIT_ADDEMAIL));
|
|
|
|
// Set the default id to the OK button
|
|
SendMessage(GetParent(hDlg), DM_SETDEFID, IDOK, 0);
|
|
|
|
nRet = IDYES;
|
|
|
|
out:
|
|
return nRet;
|
|
}
|
|
|
|
|
|
//$$///////////////////////////////////////////////////////////////
|
|
//
|
|
// SetDetailsWindowTitle - creates a display name and sets it in
|
|
// the title
|
|
//
|
|
///////////////////////////////////////////////////////////////////
|
|
void SetDetailsWindowTitle(HWND hDlg, BOOL bModifyDisplayNameField)
|
|
{
|
|
TCHAR szFirst[MAX_UI_STR];
|
|
TCHAR szLast[MAX_UI_STR];
|
|
TCHAR szMiddle[MAX_UI_STR];
|
|
TCHAR * szBuf = NULL;//szBuf[MAX_BUF_STR];
|
|
|
|
if(!(szBuf = LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*MAX_BUF_STR)))
|
|
return;
|
|
|
|
szFirst[0] = szMiddle[0] = szLast[0] = '\0';
|
|
|
|
GetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_EDIT_FIRSTNAME, szFirst, CharSizeOf(szFirst));
|
|
GetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_EDIT_LASTNAME, szLast, CharSizeOf(szLast));
|
|
GetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_EDIT_MIDDLENAME, szMiddle, CharSizeOf(szMiddle));
|
|
|
|
szBuf[0]='\0';
|
|
{
|
|
LPTSTR lpszTmp = szBuf;
|
|
SetLocalizedDisplayName(szFirst,
|
|
szMiddle,
|
|
szLast,
|
|
NULL,
|
|
NULL,
|
|
(LPTSTR *) &lpszTmp, //&szBuf,
|
|
MAX_BUF_STR,
|
|
bDNisByLN,
|
|
NULL,
|
|
NULL);
|
|
}
|
|
|
|
SetWindowPropertiesTitle(GetParent(hDlg), szBuf);
|
|
|
|
if (bModifyDisplayNameField)
|
|
{
|
|
SetComboDNText(hDlg, NULL, FALSE, szBuf);
|
|
//SetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_EDIT_DISPLAYNAME, szBuf);
|
|
}
|
|
LocalFreeAndNull(&szBuf);
|
|
}
|
|
|
|
//$$///////////////////////////////////////////////////////////////
|
|
//
|
|
// UpdateCertListView - fills the cert lv with certinfo, based on current
|
|
// listview selection
|
|
//
|
|
///////////////////////////////////////////////////////////////////
|
|
void UpdateCertListView(HWND hDlg, LPPROP_ARRAY_INFO lpPai)
|
|
{
|
|
HWND hWndLV = GetDlgItem(hDlg,IDC_DETAILS_CERT_LIST);
|
|
HWND hWndCombo = GetDlgItem(hDlg,IDC_DETAILS_CERT_COMBO);
|
|
TCHAR szEmail[MAX_UI_STR];
|
|
LPCERT_ITEM lpCItem = lpPai->lpCItem;
|
|
int nSel = (int) SendMessage(hWndCombo, CB_GETCURSEL, 0, 0);
|
|
int nCount = (int) SendMessage(hWndCombo, CB_GETCOUNT, 0, 0);
|
|
int nCountCerts = 0;
|
|
BOOL * lpbAddCert = NULL;
|
|
BOOL bShowOrphanCerts = FALSE;
|
|
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_LIST),FALSE);
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_BUTTON_PROPERTIES),FALSE);
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_BUTTON_REMOVE),FALSE);
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_BUTTON_SETDEFAULT),FALSE);
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_BUTTON_EXPORT),FALSE);
|
|
|
|
*szEmail = '\0';
|
|
if(!GetWindowText(hWndCombo, szEmail, CharSizeOf(szEmail)))
|
|
goto out;
|
|
|
|
if(!nCount || !lpCItem || !lstrlen(szEmail))
|
|
goto out;
|
|
|
|
|
|
nCountCerts = 0;
|
|
while(lpCItem)
|
|
{
|
|
nCountCerts++;
|
|
lpCItem = lpCItem->lpNext;
|
|
}
|
|
|
|
if(!nCountCerts)
|
|
goto out;
|
|
|
|
// Clear the list view ....
|
|
ListView_DeleteAllItems(hWndLV);
|
|
|
|
// we will have this bool array that we can use to mark which cert to
|
|
// add and which not to add
|
|
lpbAddCert = LocalAlloc(LMEM_ZEROINIT, nCountCerts*sizeof(BOOL));
|
|
|
|
if(!lpbAddCert)
|
|
goto out;
|
|
|
|
// if the selection is in the last item in the list, then we only
|
|
// show orphan certs ..
|
|
// Orphan certs are certs without email addresses or with email addresses
|
|
// that dont match anything in the current contacts properties ...
|
|
//
|
|
if(nSel == nCount - 1)
|
|
bShowOrphanCerts = TRUE;
|
|
|
|
lpCItem = lpPai->lpCItem;
|
|
nCountCerts = 0;
|
|
|
|
if(!bShowOrphanCerts)
|
|
{
|
|
// we only need to look at the e-mail address of each cert and match it to
|
|
// the currently selected email address
|
|
while(lpCItem)
|
|
{
|
|
if( lpCItem->lpCDI && lpCItem->lpCDI->lpszEmailAddress &&
|
|
lstrlen(lpCItem->lpCDI->lpszEmailAddress ) &&
|
|
!lstrcmpi(szEmail, lpCItem->lpCDI->lpszEmailAddress) )
|
|
{
|
|
lpbAddCert[nCountCerts] = TRUE; // Add this cert
|
|
}
|
|
|
|
nCountCerts++;
|
|
lpCItem = lpCItem->lpNext;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Scan all the certs and find the ones that dont match anything
|
|
while(lpCItem)
|
|
{
|
|
int i;
|
|
|
|
lpbAddCert[nCountCerts] = TRUE; // Add this cert
|
|
|
|
for(i=0;i<nCount-1;i++) // nCount = # e-mail addresses + 1
|
|
{
|
|
int nLen = (int)SendMessage(hWndCombo, CB_GETLBTEXTLEN, (WPARAM)i, 0);
|
|
if (nLen != CB_ERR)
|
|
{
|
|
LPTSTR pszEmail = (LPTSTR)LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*(nLen + 1));
|
|
if (pszEmail)
|
|
{
|
|
pszEmail[0] = 0;
|
|
SendMessage(hWndCombo, CB_GETLBTEXT, (WPARAM) i, (LPARAM) pszEmail);
|
|
|
|
if( lpCItem->lpCDI && lpCItem->lpCDI->lpszEmailAddress &&
|
|
lstrlen(lpCItem->lpCDI->lpszEmailAddress ) &&
|
|
!lstrcmpi(pszEmail, lpCItem->lpCDI->lpszEmailAddress) )
|
|
{
|
|
// There is a match
|
|
lpbAddCert[nCountCerts] = FALSE; // Dont add this cert
|
|
}
|
|
LocalFreeAndNull(&pszEmail);
|
|
}
|
|
}
|
|
}
|
|
nCountCerts++;
|
|
lpCItem = lpCItem->lpNext;
|
|
}
|
|
}
|
|
|
|
|
|
lpCItem = lpPai->lpCItem;
|
|
nCountCerts = 0;
|
|
|
|
|
|
while(lpCItem)
|
|
{
|
|
if(lpbAddCert[nCountCerts])
|
|
AddLVCertItem( hWndLV, lpCItem, TRUE);
|
|
|
|
nCountCerts++;
|
|
lpCItem = lpCItem->lpNext;
|
|
}
|
|
|
|
out:
|
|
if(ListView_GetItemCount(hWndLV)>0)
|
|
{
|
|
if(lpPai->ulOperationType != SHOW_ONE_OFF)
|
|
{
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_BUTTON_REMOVE),TRUE);
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_BUTTON_SETDEFAULT),TRUE);
|
|
}
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_LIST),TRUE);
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_BUTTON_PROPERTIES),TRUE);
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_BUTTON_EXPORT),TRUE);
|
|
}
|
|
|
|
if(lpbAddCert)
|
|
LocalFree(lpbAddCert);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
//$$
|
|
//
|
|
// Init the CertItem struct from an existing lpCDI struct
|
|
//
|
|
// bImporting - if we are importing a new cert - tests it to see if it can be matched to
|
|
// the current contact and if it can't, prompts user
|
|
//
|
|
BOOL AddNewCertItem(HWND hDlg, LPCERT_DISPLAY_INFO lpCDI, LPPROP_ARRAY_INFO lpPai, BOOL bImporting)
|
|
{
|
|
int nLen = 0;
|
|
BOOL bRet= FALSE;
|
|
HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_CERT_LIST);
|
|
LPCERT_ITEM lpCItem = NULL;
|
|
BOOL bMatchFound = FALSE;
|
|
|
|
// 96/12/20 markdu BUG 13029 Check for duplicates before adding.
|
|
if(bImporting)
|
|
{
|
|
int i, nCount;
|
|
|
|
// Go through all the lpCDI structs in the listview elements and
|
|
// see if any is a match with the new item
|
|
nCount = ListView_GetItemCount(hWndLV);
|
|
for(i=0;i<nCount;i++)
|
|
{
|
|
LV_ITEM lvi = {0};
|
|
lvi.mask = LVIF_PARAM;
|
|
lvi.iItem = i;
|
|
lvi.iSubItem = 0;
|
|
if (ListView_GetItem(hWndLV, &lvi))
|
|
{
|
|
LPCERT_ITEM lpItem = (LPCERT_ITEM) lvi.lParam;
|
|
if (CertCompareCertificate(X509_ASN_ENCODING, lpItem->lpCDI->pccert->pCertInfo,
|
|
lpCDI->pccert->pCertInfo))
|
|
{
|
|
// This cert is already in the list. Select it.
|
|
ShowMessageBox(hDlg, idsCertAlreadyExists,
|
|
MB_ICONINFORMATION | MB_OK);
|
|
SetFocus(hWndLV);
|
|
LVSelectItem(hWndLV, i);
|
|
bRet = TRUE;
|
|
// Free lpCDI here or we will leak it ...
|
|
FreeCertdisplayinfo(lpCDI);
|
|
goto out;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(bImporting && lpCDI->lpszEmailAddress && lstrlen(lpCDI->lpszEmailAddress))
|
|
{
|
|
// Check the e-mail address of this certificate with the ones we already have
|
|
// Warn if we cant find it
|
|
HWND hWndCombo = GetDlgItem(hDlg, IDC_DETAILS_CERT_COMBO);
|
|
TCHAR szEmail[MAX_PATH];
|
|
int i, nCount;
|
|
nCount = (int) SendMessage(hWndCombo, CB_GETCOUNT, 0, 0);
|
|
|
|
if(nCount > 1)
|
|
{
|
|
// Go thru all the email addresses in the combo box
|
|
for(i= 0;i<nCount -1; i++)
|
|
{
|
|
int nLen;
|
|
|
|
nLen = (int)SendMessage(hWndCombo, CB_GETLBTEXTLEN, (WPARAM)i, 0);
|
|
if (nLen != CB_ERR)
|
|
{
|
|
LPTSTR pszEmail = (LPTSTR)LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*(nLen + 1));
|
|
if (pszEmail)
|
|
{
|
|
pszEmail[0] = '\0';
|
|
SendMessage(hWndCombo, CB_GETLBTEXT, (WPARAM) i, (LPARAM) pszEmail);
|
|
if( lpCDI->lpszEmailAddress && lstrlen(pszEmail) &&
|
|
!lstrcmpi(pszEmail, lpCDI->lpszEmailAddress))
|
|
{
|
|
LocalFreeAndNull(&pszEmail);
|
|
bMatchFound = TRUE;
|
|
break;
|
|
}
|
|
LocalFreeAndNull(&pszEmail);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(!bMatchFound)
|
|
{
|
|
switch(ShowMessageBoxParam(hDlg, idsImportCertNoEmail, MB_ICONEXCLAMATION | MB_YESNOCANCEL,
|
|
lpCDI->lpszDisplayString, lpCDI->lpszEmailAddress))
|
|
{
|
|
case IDCANCEL: // cancel this import
|
|
bRet = TRUE;
|
|
// Free lpCDI here or we will leak it ...
|
|
FreeCertdisplayinfo(lpCDI);
|
|
goto out;
|
|
break;
|
|
case IDYES: // Add the email address of this contact to the list of email addresses
|
|
HrAddEmailToObj(lpPai, lpCDI->lpszEmailAddress, (LPTSTR)szSMTP);
|
|
FillCertComboWithEmailAddresses(hDlg, lpPai, lpCDI->lpszEmailAddress);
|
|
break;
|
|
case IDNO: // do nothing just add this certificate
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if( bImporting &&
|
|
(!lpCDI->lpszEmailAddress || !lstrlen(lpCDI->lpszEmailAddress)) )
|
|
{
|
|
FillCertComboWithEmailAddresses(hDlg, lpPai, szEmpty); //szEmpty forces combo to switch to the TEXT("none") option
|
|
}
|
|
|
|
lpCItem = LocalAlloc(LMEM_ZEROINIT, sizeof(CERT_ITEM));
|
|
|
|
if (!lpCItem)
|
|
goto out;
|
|
|
|
lpCItem->lpCDI = lpCDI;
|
|
lpCItem->pcCert = CertDuplicateCertificateContext(lpCDI->pccert);
|
|
lpCItem->lpPrev = NULL;
|
|
|
|
nLen = lstrlen(lpCDI->lpszDisplayString) + 1;
|
|
if (nLen > MAX_PATH)
|
|
{
|
|
ULONG iLen = TruncatePos(lpCDI->lpszDisplayString, MAX_PATH - 1);
|
|
lpCDI->lpszDisplayString[iLen] = '\0';
|
|
}
|
|
|
|
StrCpyN(lpCItem->szDisplayText, lpCDI->lpszDisplayString, ARRAYSIZE(lpCItem->szDisplayText));
|
|
|
|
lpCItem->lpNext = lpPai->lpCItem;
|
|
if(lpPai->lpCItem)
|
|
lpPai->lpCItem->lpPrev = lpCItem;
|
|
lpPai->lpCItem = lpCItem;
|
|
|
|
bRet = TRUE;
|
|
out:
|
|
return bRet;
|
|
|
|
}
|
|
//$$///////////////////////////////////////////////////////////////
|
|
//
|
|
// SetCertInfoInUI - fills the cert lv with certinfo, if any exists
|
|
//
|
|
///////////////////////////////////////////////////////////////////
|
|
HRESULT HrSetCertInfoInUI(HWND hDlg,
|
|
LPSPropValue lpPropMVCert,
|
|
LPPROP_ARRAY_INFO lpPai)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
LPCERT_DISPLAY_INFO lpCDI = NULL, lpTemp = NULL;
|
|
|
|
if(!lpPropMVCert)
|
|
goto out;
|
|
|
|
if(!lpPai->lpCItem)
|
|
{
|
|
if(HR_FAILED(HrGetCertsDisplayInfo(hDlg, lpPropMVCert, &lpCDI)))
|
|
goto out;
|
|
|
|
if(!lpCDI)
|
|
{
|
|
hr = MAPI_E_NOT_FOUND;
|
|
goto out;
|
|
}
|
|
lpTemp = lpCDI;
|
|
while(lpTemp)
|
|
{
|
|
|
|
AddNewCertItem(hDlg, lpTemp, lpPai, FALSE);
|
|
|
|
lpTemp = lpTemp->lpNext;
|
|
}
|
|
}
|
|
|
|
|
|
UpdateCertListView(hDlg, lpPai);
|
|
|
|
hr = S_OK;
|
|
|
|
out:
|
|
return hr;
|
|
}
|
|
|
|
|
|
//$$////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// AddLVcertItem - adds an item to the certificates list view
|
|
//
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////////
|
|
BOOL AddLVCertItem(HWND hWndLV, LPCERT_ITEM lpCItem, BOOL bCheckForDups)
|
|
{
|
|
LV_ITEM lvi = {0};
|
|
ULONG nLen;
|
|
BOOL bRet = FALSE;
|
|
|
|
if(!lpCItem)
|
|
goto out;
|
|
|
|
// 96/12/20 markdu BUG 13029 Check for duplicates before adding.
|
|
if (TRUE == bCheckForDups)
|
|
{
|
|
int i, nCount;
|
|
|
|
// Go through all the lpCDI structs in the listview elements and
|
|
// see if any is a match with the new item
|
|
nCount = ListView_GetItemCount(hWndLV);
|
|
for(i=0;i<nCount;i++)
|
|
{
|
|
LV_ITEM lvi = {0};
|
|
lvi.mask = LVIF_PARAM;
|
|
lvi.iItem = i;
|
|
lvi.iSubItem = 0;
|
|
if (ListView_GetItem(hWndLV, &lvi))
|
|
{
|
|
LPCERT_ITEM lpItem = (LPCERT_ITEM) lvi.lParam;
|
|
if (CertCompareCertificate(X509_ASN_ENCODING, lpItem->lpCDI->pccert->pCertInfo,
|
|
lpCItem->lpCDI->pccert->pCertInfo))
|
|
{
|
|
// This cert is already in the list. Select it.
|
|
SetFocus(hWndLV);
|
|
LVSelectItem(hWndLV, i);
|
|
goto out;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
|
|
lvi.pszText = lpCItem->lpCDI->bIsDefault ? lpCItem->szDisplayText : lpCItem->lpCDI->lpszDisplayString;
|
|
lvi.iItem = ListView_GetItemCount(hWndLV);
|
|
lvi.iSubItem = 0;
|
|
|
|
if(!lpCItem->lpCDI->bIsExpired && !lpCItem->lpCDI->bIsRevoked && lpCItem->lpCDI->bIsTrusted)
|
|
lvi.iImage = imgCertValid;
|
|
else
|
|
lvi.iImage = imgCertInvalid;
|
|
|
|
lvi.lParam = (LPARAM) lpCItem;
|
|
|
|
{
|
|
int nIndex = ListView_InsertItem(hWndLV, &lvi);
|
|
if (ListView_GetItemCount(hWndLV) == 1)
|
|
{
|
|
// only one item in here .. we will take the liberty of making it the
|
|
// default one ...
|
|
SetLVDefaultCert(hWndLV, 0);
|
|
}
|
|
else if(lpCItem->lpCDI->bIsDefault)
|
|
{
|
|
SetLVDefaultCert(hWndLV, nIndex);
|
|
}
|
|
|
|
// Select the cert we just added.
|
|
SetFocus(hWndLV);
|
|
LVSelectItem(hWndLV, nIndex);
|
|
}
|
|
bRet = TRUE;
|
|
|
|
out:
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//$$/////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// SetLVDefaultCert - Makes an cert entry the default one ...
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
void SetLVDefaultCert( HWND hWndLV,
|
|
int iItemIndex)
|
|
{
|
|
int nCount = ListView_GetItemCount(hWndLV);
|
|
int i;
|
|
LPCERT_ITEM lpItem = NULL;
|
|
TCHAR szBuf[MAX_DISPLAY_NAME_LENGTH];
|
|
|
|
if (iItemIndex >= nCount)
|
|
goto out;
|
|
|
|
for(i=0; i<nCount; i++)
|
|
{
|
|
// At amy given point of time one and only one entry in the
|
|
// list view is the default one ...
|
|
// So we want to reset the previous default and set the new one
|
|
//
|
|
LV_ITEM lvi = {0};
|
|
lvi.iItem = i;
|
|
lvi.mask = LVIF_PARAM;
|
|
if(!ListView_GetItem(hWndLV, &lvi))
|
|
goto out;
|
|
lpItem = (LPCERT_ITEM) lvi.lParam;
|
|
if (lpItem->lpCDI->bIsDefault)
|
|
{
|
|
// This was the default entry - if its
|
|
// not the same one as the one we are setting,
|
|
// reset the default
|
|
if (i != iItemIndex)
|
|
{
|
|
// else reset this entry ...
|
|
lpItem->lpCDI->bIsDefault = FALSE;
|
|
lvi.pszText = lpItem->lpCDI->lpszDisplayString;
|
|
lvi.mask = LVIF_PARAM | LVIF_TEXT;
|
|
lvi.iItem = i;
|
|
lvi.iSubItem = 0;
|
|
ListView_SetItem(hWndLV, &lvi);
|
|
}
|
|
}
|
|
if (iItemIndex == i)
|
|
{
|
|
//This is the item we want to modify ..
|
|
lpItem->lpCDI->bIsDefault = TRUE;
|
|
StrCpyN(lpItem->szDisplayText,lpItem->lpCDI->lpszDisplayString, ARRAYSIZE(lpItem->szDisplayText));
|
|
LoadString(hinstMapiX, idsDefaultCert, szBuf, CharSizeOf(szBuf));
|
|
StrCatBuff(lpItem->szDisplayText, szBuf, ARRAYSIZE(lpItem->szDisplayText));
|
|
|
|
lvi.pszText = lpItem->szDisplayText;
|
|
lvi.mask = LVIF_PARAM | LVIF_TEXT;
|
|
lvi.iItem = i;
|
|
lvi.iSubItem = 0;
|
|
ListView_SetItem(hWndLV, &lvi);
|
|
}
|
|
}
|
|
|
|
LVSelectItem(hWndLV, iItemIndex);
|
|
|
|
out:
|
|
return;
|
|
}
|
|
|
|
extern HRESULT HrGetTrustState(HWND hwndParent, PCCERT_CONTEXT pcCert, DWORD *pdwTrust);
|
|
|
|
//$$/////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// ShowCertProps - Shows props for a cert
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
void ShowCertProps(HWND hDlg, HWND hWndLV, BOOL * lpBool)
|
|
{
|
|
DWORD dwTrust = 0;
|
|
int nIndex = ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED);
|
|
LV_ITEM lvi;
|
|
LPCERT_ITEM lpItem;
|
|
BOOL bDeletedDefault = FALSE;
|
|
BOOL bOldTrusted;
|
|
LPSTR oidPurpose = szOID_PKIX_KP_EMAIL_PROTECTION;
|
|
|
|
lvi.mask = LVIF_PARAM;
|
|
lvi.iSubItem = 0;
|
|
lvi.iItem = nIndex;
|
|
|
|
if(ListView_GetItem(hWndLV, &lvi))
|
|
{
|
|
lpItem = (LPCERT_ITEM) lvi.lParam;
|
|
if(lpItem)
|
|
{
|
|
if(lpItem->pcCert == NULL)
|
|
{
|
|
Assert(lpItem->pcCert);
|
|
return;
|
|
}
|
|
|
|
// Only one thing is user changable in the cert UI - the trust info
|
|
// So we will track that piece of info
|
|
// User can change dwTrust and consequently, bIsTrusted can also change
|
|
// which needs to be uppdated in the UI check mark
|
|
|
|
bOldTrusted = lpItem->lpCDI->bIsTrusted;
|
|
|
|
{
|
|
CERT_VIEWPROPERTIES_STRUCT_A cvps = {0};
|
|
|
|
cvps.dwSize = sizeof(CERT_VIEWPROPERTIES_STRUCT);
|
|
cvps.hwndParent = hDlg;
|
|
cvps.hInstance = hinstMapiX;
|
|
cvps.pCertContext = lpItem->pcCert;
|
|
cvps.arrayPurposes = &oidPurpose;
|
|
cvps.cArrayPurposes = 1;
|
|
cvps.nStartPage = 1; // go directly to details page
|
|
cvps.dwFlags = CM_NO_NAMECHANGE;
|
|
|
|
CertViewPropertiesA(&cvps);
|
|
}
|
|
|
|
// Determine if the trust changed or not
|
|
if (FAILED(HrGetTrustState(hDlg, lpItem->pcCert, &(lpItem->lpCDI->dwTrust))))
|
|
{
|
|
lpItem->lpCDI->dwTrust = CERT_VALIDITY_NO_TRUST_DATA;
|
|
}
|
|
|
|
if (0 == lpItem->lpCDI->dwTrust)
|
|
lpItem->lpCDI->bIsTrusted = TRUE;
|
|
else
|
|
lpItem->lpCDI->bIsTrusted = FALSE;
|
|
|
|
//N2 if the trust changes, we need to check trust again...
|
|
if (bOldTrusted != lpItem->lpCDI->bIsTrusted)
|
|
{
|
|
LV_ITEM lvi = {0};
|
|
|
|
// Update the displayed graphic next to the cert.
|
|
lvi.mask = LVIF_IMAGE;
|
|
lvi.iItem = nIndex;
|
|
lvi.iSubItem = 0;
|
|
if(!lpItem->lpCDI->bIsExpired && !lpItem->lpCDI->bIsRevoked && lpItem->lpCDI->bIsTrusted)
|
|
lvi.iImage = imgCertValid;
|
|
else
|
|
lvi.iImage = imgCertInvalid;
|
|
ListView_SetItem(hWndLV, &lvi);
|
|
}
|
|
if(lpBool)
|
|
*lpBool = TRUE;
|
|
}
|
|
}
|
|
else if(ListView_GetSelectedCount(hWndLV) <= 0)
|
|
{
|
|
ShowMessageBox(hDlg, IDS_ADDRBK_MESSAGE_NO_ITEM, MB_ICONEXCLAMATION | MB_OK);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
//$$/////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// DeleteLVCertItem - Makes an cert entry the default one ...
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
BOOL DeleteLVCertItem(HWND hWndLV, int iItemIndex, LPPROP_ARRAY_INFO lpPai)
|
|
{
|
|
LV_ITEM lvi;
|
|
LPCERT_ITEM lpItem;
|
|
BOOL bDeletedDefault = FALSE;
|
|
|
|
lvi.mask = LVIF_PARAM;
|
|
lvi.iSubItem = 0;
|
|
lvi.iItem = iItemIndex;
|
|
|
|
if(ListView_GetItem(hWndLV, &lvi))
|
|
{
|
|
lpItem = (LPCERT_ITEM) lvi.lParam;
|
|
|
|
if(lpItem)
|
|
{
|
|
if (lpItem->lpCDI->bIsDefault)
|
|
bDeletedDefault = TRUE;
|
|
|
|
if(lpItem->lpCDI->lpNext)
|
|
lpItem->lpCDI->lpNext->lpPrev = lpItem->lpCDI->lpPrev;
|
|
|
|
if(lpItem->lpCDI->lpPrev)
|
|
lpItem->lpCDI->lpPrev->lpNext = lpItem->lpCDI->lpNext;
|
|
|
|
FreeCertdisplayinfo(lpItem->lpCDI);
|
|
|
|
if (lpItem->pcCert)
|
|
CertFreeCertificateContext(lpItem->pcCert);
|
|
|
|
if(lpItem->lpNext)
|
|
lpItem->lpNext->lpPrev = lpItem->lpPrev;
|
|
|
|
if(lpItem->lpPrev)
|
|
lpItem->lpPrev->lpNext = lpItem->lpNext;
|
|
|
|
if(lpPai && lpPai->lpCItem == lpItem)
|
|
lpPai->lpCItem = lpItem->lpNext;
|
|
|
|
LocalFree(lpItem);
|
|
|
|
ListView_DeleteItem(hWndLV, lvi.iItem);
|
|
}
|
|
}
|
|
return bDeletedDefault;
|
|
}
|
|
|
|
|
|
const TCHAR szCertFilter[] = TEXT("*.p7c;*.p7b;*.cer");
|
|
const TCHAR szAllFilter[] = TEXT("*.*");
|
|
const TCHAR szCERFilter[] = TEXT("*.cer");
|
|
const TCHAR szCERExt[] = TEXT("ext");
|
|
|
|
|
|
//$$////////////////////////////////////////////////////////////////////////
|
|
////
|
|
//// ImportCert - imports a cert from file and then adds it into the list view
|
|
////
|
|
////
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL ImportCert(HWND hDlg, LPPROP_ARRAY_INFO lpPai)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
TCHAR szBuf[MAX_UI_STR];
|
|
|
|
// we need to get a file name after poping the file open dialog
|
|
// Then we need to decode it
|
|
// Then we need to add it to the list view
|
|
|
|
OPENFILENAME ofn;
|
|
LPTSTR lpFilter = FormatAllocFilter(IDS_CERT_FILE_SPEC,
|
|
szCertFilter,
|
|
IDS_ALL_FILE_SPEC,
|
|
szAllFilter,
|
|
0,
|
|
NULL);
|
|
TCHAR szFileName[MAX_PATH + 1] = TEXT("");
|
|
|
|
ofn.lStructSize = sizeof(ofn);
|
|
ofn.hwndOwner = hDlg;
|
|
ofn.hInstance = hinstMapiX;
|
|
ofn.lpstrFilter = lpFilter;
|
|
ofn.lpstrCustomFilter = NULL;
|
|
ofn.nMaxCustFilter = 0;
|
|
ofn.nFilterIndex = 0;
|
|
ofn.lpstrFile = szFileName;
|
|
ofn.nMaxFile = CharSizeOf(szFileName);
|
|
ofn.lpstrFileTitle = NULL;
|
|
ofn.nMaxFileTitle = 0;
|
|
ofn.lpstrInitialDir = NULL;
|
|
LoadString(hinstMapiX, idsCertImportTitle, szBuf, CharSizeOf(szBuf));
|
|
ofn.lpstrTitle = szBuf;
|
|
ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
|
|
ofn.nFileOffset = 0;
|
|
ofn.nFileExtension = 0;
|
|
ofn.lpstrDefExt = NULL;
|
|
ofn.lCustData = 0;
|
|
ofn.lpfnHook = NULL;
|
|
ofn.lpTemplateName = NULL;
|
|
|
|
|
|
if (GetOpenFileName(&ofn))
|
|
{
|
|
LPCERT_DISPLAY_INFO lpCDI = NULL;
|
|
LPCERT_ITEM lpCItem = NULL;
|
|
if(!HR_FAILED(HrImportCertFromFile( szFileName,
|
|
&lpCDI)))
|
|
{
|
|
if(!AddNewCertItem(hDlg, lpCDI, lpPai, TRUE))
|
|
goto out;
|
|
|
|
UpdateCertListView(hDlg, lpPai);
|
|
}
|
|
else
|
|
{
|
|
ShowMessageBoxParam(hDlg, IDE_VCARD_IMPORT_FILE_ERROR, MB_ICONEXCLAMATION, szFileName);
|
|
goto out;
|
|
}
|
|
}
|
|
else
|
|
goto out;
|
|
|
|
|
|
bRet = TRUE;
|
|
|
|
out:
|
|
LocalFreeAndNull(&lpFilter);
|
|
return bRet;
|
|
}
|
|
|
|
|
|
//$$////////////////////////////////////////////////////////////////////////
|
|
////
|
|
//// ExportCert - exports a cert to a file
|
|
////
|
|
////
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL ExportCert(HWND hDlg)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
TCHAR szBuf[MAX_UI_STR];
|
|
HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_CERT_LIST);
|
|
|
|
OPENFILENAME ofn;
|
|
LPTSTR lpFilter = FormatAllocFilter(IDS_CER_FILE_SPEC,
|
|
szCERFilter,
|
|
IDS_ALL_FILE_SPEC,
|
|
szAllFilter,
|
|
0,
|
|
NULL);
|
|
TCHAR szFileName[MAX_PATH + 1] = TEXT("");
|
|
|
|
|
|
// we need to get a file name after poping the file open dialog
|
|
// Then we need to save the cert to the file name
|
|
|
|
// First make sure only one entry is selected for exporting
|
|
if(ListView_GetSelectedCount(hWndLV) > 1)
|
|
{
|
|
ShowMessageBox(hDlg, IDS_ADDRBK_MESSAGE_ACTION, MB_OK | MB_ICONEXCLAMATION);
|
|
goto out;
|
|
}
|
|
else if (ListView_GetSelectedCount(hWndLV) <= 0)
|
|
{
|
|
ShowMessageBox(hDlg, IDS_ADDRBK_MESSAGE_NO_ITEM, MB_OK | MB_ICONEXCLAMATION);
|
|
goto out;
|
|
}
|
|
|
|
ofn.lStructSize = sizeof(ofn);
|
|
ofn.hwndOwner = hDlg;
|
|
ofn.hInstance = hinstMapiX;
|
|
ofn.lpstrFilter = lpFilter;
|
|
ofn.lpstrCustomFilter = NULL;
|
|
ofn.nMaxCustFilter = 0;
|
|
ofn.nFilterIndex = 0;
|
|
ofn.lpstrFile = szFileName;
|
|
ofn.nMaxFile = CharSizeOf(szFileName);
|
|
ofn.lpstrFileTitle = NULL;
|
|
ofn.nMaxFileTitle = 0;
|
|
ofn.lpstrInitialDir = NULL;
|
|
LoadString(hinstMapiX, idsCertExportTitle, szBuf, CharSizeOf(szBuf));
|
|
ofn.lpstrTitle = szBuf;
|
|
ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT;
|
|
ofn.nFileOffset = 0;
|
|
ofn.nFileExtension = 0;
|
|
ofn.lpstrDefExt = szCERExt;
|
|
ofn.lCustData = 0;
|
|
ofn.lpfnHook = NULL;
|
|
ofn.lpTemplateName = NULL;
|
|
|
|
|
|
if (GetSaveFileName(&ofn))
|
|
{
|
|
LV_ITEM lvi = {0};
|
|
lvi.mask = LVIF_PARAM;
|
|
lvi.iItem = ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED);
|
|
lvi.iSubItem = 0;
|
|
if (ListView_GetItem(hWndLV, &lvi))
|
|
{
|
|
LPCERT_ITEM lpItem = (LPCERT_ITEM) lvi.lParam;
|
|
HrExportCertToFile( szFileName, lpItem->lpCDI->pccert, NULL, NULL, FALSE);
|
|
}
|
|
else
|
|
goto out;
|
|
}
|
|
else
|
|
goto out;
|
|
|
|
|
|
bRet = TRUE;
|
|
|
|
out:
|
|
return bRet;
|
|
}
|
|
|
|
//$$////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Sets the display name in the Combo box
|
|
//
|
|
// hDlg - handle of Personal Pane
|
|
// lppai - proparrayinfo struct
|
|
// bAddAll - determines whether to fill the combo with all the values or not
|
|
// szTxt - txt to put in the edit field part of the combo. if bAddAll=TRUE,
|
|
// dont need szTxt.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////////
|
|
void SetComboDNText(HWND hDlg, LPPROP_ARRAY_INFO lppai, BOOL bAddAll, LPTSTR szTxt)
|
|
{
|
|
HWND hWndCombo = GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_COMBO_DISPLAYNAME);
|
|
|
|
if(!bAddAll)
|
|
{
|
|
if(szTxt == NULL)
|
|
szTxt = szEmpty;
|
|
// just add the current string to the combo
|
|
SendMessage(hWndCombo, CB_RESETCONTENT, 0, 0);
|
|
SendMessage(hWndCombo, CB_ADDSTRING, 0, (LPARAM) szTxt);
|
|
SendMessage(hWndCombo, CB_SETCURSEL, 0, 0);
|
|
SetWindowText(hWndCombo, szTxt);
|
|
}
|
|
else
|
|
{
|
|
// Populates the drop down list with all other names ...
|
|
TCHAR * szFirst = NULL;//szFirst[MAX_UI_STR*2];
|
|
TCHAR * szMiddle = NULL;//[MAX_UI_STR*2];
|
|
TCHAR * szLast = NULL;//[MAX_UI_STR*2];
|
|
TCHAR * szDisplay = NULL;//[MAX_UI_STR*2];
|
|
ULONG nLen = MAX_UI_STR*2;
|
|
szFirst = LocalAlloc(LMEM_ZEROINIT, nLen*sizeof(TCHAR));
|
|
szLast = LocalAlloc(LMEM_ZEROINIT, nLen*sizeof(TCHAR));
|
|
szMiddle = LocalAlloc(LMEM_ZEROINIT, nLen*sizeof(TCHAR));
|
|
szDisplay = LocalAlloc(LMEM_ZEROINIT, nLen*sizeof(TCHAR));
|
|
|
|
if(szFirst && szLast && szMiddle && szDisplay)
|
|
{
|
|
szFirst[0] = szLast[0] = szMiddle[0] = szDisplay[0] = '\0';
|
|
|
|
// First get the current text and save it ...
|
|
GetWindowText(hWndCombo, szDisplay, nLen);
|
|
|
|
// Clear out combo and add the display name again
|
|
SendMessage(hWndCombo, CB_RESETCONTENT, 0, 0);
|
|
|
|
if(lstrlen(szDisplay))
|
|
SendMessage(hWndCombo, CB_ADDSTRING, 0, (LPARAM) szDisplay);
|
|
|
|
// Get the localized F/M/L name from F/M/L fields
|
|
// If the localized name does not match the display name, add it
|
|
GetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_EDIT_FIRSTNAME, szFirst, nLen);
|
|
GetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_EDIT_LASTNAME, szLast, nLen);
|
|
GetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_EDIT_MIDDLENAME, szMiddle, nLen);
|
|
|
|
{
|
|
ULONG ulSzBuf = MAX_BUF_STR;
|
|
LPTSTR szBuf = LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*ulSzBuf);
|
|
LPTSTR lpszTmp = szBuf;
|
|
|
|
if(szBuf) // Get the localized Display Name and reverse localized display name
|
|
{
|
|
if(SetLocalizedDisplayName( szFirst, szMiddle, szLast,
|
|
NULL, // Company Name (not needed)
|
|
NULL, // Nick Name (not needed here)
|
|
(LPTSTR *) &lpszTmp, //&szBuf,
|
|
ulSzBuf, bDNisByLN,
|
|
bDNisByLN ? szResourceDNByCommaLN : szResourceDNByLN,
|
|
NULL))
|
|
{
|
|
if(lstrlen(szBuf) && lstrcmp(szBuf, szDisplay))
|
|
SendMessage(hWndCombo, CB_ADDSTRING, 0, (LPARAM) szBuf);
|
|
}
|
|
szBuf[0] = TEXT('\0');
|
|
if(SetLocalizedDisplayName( szFirst, szMiddle, szLast,
|
|
NULL, // Company Name (not needed)
|
|
NULL, // Nick Name (not needed here)
|
|
(LPTSTR *) &lpszTmp, //&szBuf,
|
|
ulSzBuf, !bDNisByLN, NULL, NULL))
|
|
{
|
|
if(lstrlen(szBuf) && lstrcmp(szBuf, szDisplay))
|
|
SendMessage(hWndCombo, CB_ADDSTRING, 0, (LPARAM) szBuf);
|
|
}
|
|
szBuf[0] = TEXT('\0');
|
|
if(SetLocalizedDisplayName( szFirst, szMiddle, szLast,
|
|
NULL, // Company Name (not needed)
|
|
NULL, // Nick Name (not needed here)
|
|
(LPTSTR *) &lpszTmp, //&szBuf,
|
|
ulSzBuf, bDNisByLN, NULL, NULL))
|
|
{
|
|
if(lstrlen(szBuf) && lstrcmp(szBuf, szDisplay))
|
|
SendMessage(hWndCombo, CB_ADDSTRING, 0, (LPARAM) szBuf);
|
|
}
|
|
LocalFreeAndNull(&szBuf);
|
|
}
|
|
}
|
|
|
|
// Get the NickName and if its different add it to this list
|
|
szFirst[0]='\0';
|
|
GetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_EDIT_NICKNAME, szFirst, nLen);
|
|
if(lstrlen(szFirst) && lstrcmp(szFirst, szDisplay))
|
|
SendMessage(hWndCombo, CB_ADDSTRING, 0, (LPARAM) szFirst);
|
|
|
|
// Get the Company name and if its different add it to the list
|
|
szFirst[0]='\0';
|
|
{
|
|
ULONG i;
|
|
ULONG ulcPropCount = 0;
|
|
LPSPropValue lpPropArray = NULL;
|
|
SizedSPropTagArray(1, ptaDN) = {1, PR_COMPANY_NAME};
|
|
if(!HR_FAILED(lppai->lpPropObj->lpVtbl->GetProps(lppai->lpPropObj,
|
|
(LPSPropTagArray)&ptaDN,
|
|
MAPI_UNICODE,
|
|
&ulcPropCount,
|
|
&lpPropArray)))
|
|
{
|
|
if(lpPropArray[0].ulPropTag == PR_COMPANY_NAME)
|
|
StrCpyN(szFirst, lpPropArray[0].Value.LPSZ, nLen);
|
|
}
|
|
if(lpPropArray)
|
|
MAPIFreeBuffer(lpPropArray);
|
|
}
|
|
|
|
if(lstrlen(szFirst) && lstrcmp(szFirst, szDisplay))
|
|
SendMessage(hWndCombo, CB_ADDSTRING, 0, (LPARAM) szFirst);
|
|
|
|
SendMessage(hWndCombo, CB_SETCURSEL, 0, 0);
|
|
SetWindowText(hWndCombo, szDisplay);
|
|
}
|
|
LocalFreeAndNull(&szFirst);
|
|
LocalFreeAndNull(&szLast);
|
|
LocalFreeAndNull(&szMiddle);
|
|
LocalFreeAndNull(&szDisplay);
|
|
}
|
|
|
|
//SendMessage(hWndCombo, WM_SETREDRAW, (WPARAM) TRUE, 0);
|
|
UpdateWindow(hWndCombo);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
//$$////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// HrShowOneOffDetailsOnVCard
|
|
//
|
|
// Deciphers a vCard File and then shows one off details on it
|
|
//
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT HrShowOneOffDetailsOnVCard( LPADRBOOK lpAdrBook,
|
|
HWND hWnd,
|
|
LPTSTR szvCardFile)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
HANDLE hFile = NULL;
|
|
LPMAILUSER lpMailUser = NULL;
|
|
LPSTR lpBuf = NULL, lpVCardStart = NULL;
|
|
LPSTR lpVCard = NULL, lpNext = NULL;
|
|
|
|
if(!VCardGetBuffer(szvCardFile, NULL, &lpBuf) && hWnd) //no message if no hwnd
|
|
{
|
|
// couldn't open file.
|
|
ShowMessageBoxParam(hWnd, IDE_VCARD_IMPORT_FILE_ERROR,
|
|
MB_ICONEXCLAMATION, szvCardFile);
|
|
goto out;
|
|
}
|
|
|
|
lpVCardStart = lpBuf;
|
|
|
|
// Loop through showing all the nested vCards one by one ..
|
|
while(VCardGetNextBuffer(lpVCardStart, &lpVCard, &lpNext) && lpVCard)
|
|
{
|
|
// Step 1 - see if we can get a mailuser object out of this file
|
|
if(!HR_FAILED(hr = VCardRetrieve( lpAdrBook, hWnd, MAPI_DIALOG, szvCardFile,
|
|
lpVCard, &lpMailUser)))
|
|
{
|
|
// Step 2 - Show one-off details on this entry
|
|
if(!HR_FAILED(hr = HrShowOneOffDetails( lpAdrBook, hWnd, 0, NULL,
|
|
MAPI_MAILUSER, (LPMAPIPROP) lpMailUser, NULL, SHOW_ONE_OFF)))
|
|
{
|
|
if(lpMailUser)
|
|
lpMailUser->lpVtbl->Release(lpMailUser);
|
|
if(hr == MAPI_E_USER_CANCEL)
|
|
break;
|
|
}
|
|
}
|
|
|
|
lpVCard = NULL;
|
|
lpVCardStart = lpNext;
|
|
}
|
|
|
|
|
|
out:
|
|
LocalFreeAndNull(&lpBuf);
|
|
return hr;
|
|
}
|
|
/*
|
|
HRESULT KillTrustInSleazyFashion(HWND hWndLV, int iItem)
|
|
{
|
|
LV_ITEM lvi = {0};
|
|
HRESULT hr = E_FAIL;
|
|
|
|
lvi.mask = LVIF_PARAM;
|
|
lvi.iItem = iItem;
|
|
lvi.iSubItem = 0;
|
|
|
|
if (ListView_GetItem(hWndLV, &lvi))
|
|
{
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
*/
|
|
|
|
|
|
/*//$$***********************************************************************
|
|
* FUNCTION: fnTridentProc
|
|
*
|
|
* PURPOSE: Callback function for handling the Trident property sheet ...
|
|
*
|
|
****************************************************************************/
|
|
INT_PTR CALLBACK fnTridentProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)
|
|
{
|
|
PROPSHEETPAGE * pps;
|
|
BOOL bRet = FALSE;
|
|
|
|
pps = (PROPSHEETPAGE *) GetWindowLongPtr(hDlg, DWLP_USER);
|
|
|
|
switch(message)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
SetWindowLongPtr(hDlg,DWLP_USER,lParam);
|
|
pps = (PROPSHEETPAGE *) lParam;
|
|
SetDetailsUI(hDlg, lpPAI, lpPAI->ulOperationType, propTrident);
|
|
FillCertTridentConfDetailsUI(hDlg, lpPAI, propTrident, lpbSomethingChanged);
|
|
return TRUE;
|
|
}
|
|
break;
|
|
|
|
case WM_HELP:
|
|
WABWinHelp(((LPHELPINFO)lParam)->hItemHandle,
|
|
g_szWABHelpFileName,
|
|
HELP_WM_HELP,
|
|
(DWORD_PTR)(LPSTR) rgDetlsHelpIDs );
|
|
break;
|
|
|
|
case WM_CONTEXTMENU:
|
|
WABWinHelp((HWND) wParam,
|
|
g_szWABHelpFileName,
|
|
HELP_CONTEXTMENU,
|
|
(DWORD_PTR)(LPVOID) rgDetlsHelpIDs );
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch(GET_WM_COMMAND_ID(wParam, lParam))
|
|
{
|
|
case IDC_DETAILS_TRIDENT_BUTTON_ADDTOWAB:
|
|
lpPAI->nRetVal = DETAILS_ADDTOWAB;
|
|
SendMessage(GetParent(hDlg), WM_COMMAND, (WPARAM) IDCANCEL, 0);
|
|
break;
|
|
|
|
case IDCANCEL:
|
|
// This is a windows bug that prevents ESC canceling prop sheets
|
|
// which have MultiLine Edit boxes KB: Q130765
|
|
SendMessage(GetParent(hDlg),message,wParam,lParam);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
|
|
case WM_NOTIFY:
|
|
switch(((NMHDR FAR *)lParam)->code)
|
|
{
|
|
case PSN_SETACTIVE: //initialize
|
|
break;
|
|
|
|
case PSN_APPLY: //ok
|
|
// in case any of the extended props changed, we need to mark this flag so we wont lose data
|
|
if(lpbSomethingChanged)
|
|
(*lpbSomethingChanged) = ChangedExtDisplayInfo(lpPAI, (*lpbSomethingChanged));
|
|
|
|
if (lpPAI->nRetVal == DETAILS_RESET)
|
|
lpPAI->nRetVal = DETAILS_OK;
|
|
break;
|
|
|
|
case PSN_KILLACTIVE: //Losing activation to another page
|
|
break;
|
|
|
|
case PSN_RESET: //cancel
|
|
if (lpPAI->nRetVal == DETAILS_RESET)
|
|
lpPAI->nRetVal = DETAILS_CANCEL;
|
|
break;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return bRet;
|
|
|
|
}
|
|
|
|
|
|
|
|
//$$//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// SetDefaultServer(hDlg, lpPai)
|
|
//
|
|
// iSelectedItem - the item index to which we should set the Default or Backup
|
|
// bForce - forcibly set the Index to the one specified by iSelectedItem
|
|
// if FALSE, chooses any unused index value
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void SetDefaultServer(HWND hDlg, LPPROP_ARRAY_INFO lpPai, int iSelectedItem, BOOL bForce)
|
|
{
|
|
HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_NTMTG_LIST_SERVERS);
|
|
int nCount = ListView_GetItemCount(hWndLV);
|
|
TCHAR sz[MAX_PATH];
|
|
TCHAR szTmp[MAX_PATH];
|
|
int oldIndex = lpPai->nDefaultServerIndex;
|
|
|
|
|
|
|
|
if(iSelectedItem == -1)
|
|
{
|
|
iSelectedItem = ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED);
|
|
if(iSelectedItem < 0)
|
|
return; // nothing selected ..
|
|
}
|
|
|
|
|
|
if(iSelectedItem == lpPai->nBackupServerIndex)
|
|
{
|
|
if(!bForce)
|
|
{
|
|
if(nCount >= 2)
|
|
{
|
|
int nTmp = 0;
|
|
while(nTmp == iSelectedItem && nTmp < nCount)
|
|
nTmp++;
|
|
iSelectedItem = nTmp;
|
|
}
|
|
}
|
|
}
|
|
|
|
// replace the old value of the def index item if applicable
|
|
if(lpPai->nDefaultServerIndex >= 0 && lpPai->szDefaultServerName && lstrlen(lpPai->szDefaultServerName))
|
|
{
|
|
ListView_SetItemText(hWndLV, lpPai->nDefaultServerIndex, 0, lpPai->szDefaultServerName);
|
|
lpPai->szDefaultServerName[0] = TEXT('\0');
|
|
}
|
|
|
|
// replace the old backup item text if we are reseting the backup item
|
|
if((lpPai->nBackupServerIndex == iSelectedItem) &&
|
|
lpPai->nBackupServerIndex >= 0 && lpPai->szBackupServerName && lstrlen(lpPai->szBackupServerName))
|
|
{
|
|
ListView_SetItemText(hWndLV, lpPai->nBackupServerIndex, 0, lpPai->szBackupServerName);
|
|
lpPai->szBackupServerName[0] = TEXT('\0');
|
|
}
|
|
|
|
lpPai->nDefaultServerIndex = iSelectedItem;
|
|
|
|
// Now that we have unique indexes for Default and Server Indexes
|
|
// append TEXT("Default") and TEXT("Backup") to these names
|
|
|
|
{
|
|
sz[0] = TEXT('\0');
|
|
szTmp[0] = TEXT('\0');
|
|
ListView_GetItemText(hWndLV, lpPai->nDefaultServerIndex, 0, sz, CharSizeOf(sz));
|
|
StrCpyN(lpPai->szDefaultServerName, sz, lpPai->cchDefaultServerName);
|
|
LoadString(hinstMapiX, idsDefaultServer, szTmp, CharSizeOf(szTmp));
|
|
StrCatBuff(sz, TEXT(" "), ARRAYSIZE(sz));
|
|
StrCatBuff(sz, szTmp, ARRAYSIZE(sz));
|
|
ListView_SetItemText(hWndLV, lpPai->nDefaultServerIndex, 0, sz);
|
|
}
|
|
|
|
if(lpPai->nBackupServerIndex == iSelectedItem)
|
|
{
|
|
// Update this backup item
|
|
SetBackupServer(hDlg, lpPai, oldIndex, FALSE);
|
|
}
|
|
}
|
|
|
|
|
|
//$$//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// SetBackupServer(hDlg, lpPai) - set backup server if possible to do so
|
|
//
|
|
// iSelectedItem - the item index to which we should set the Default or Backup
|
|
// bForce - forcibly set the Index to the one specified by iSelectedItem
|
|
// if FALSE, chooses any unused index value
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void SetBackupServer(HWND hDlg, LPPROP_ARRAY_INFO lpPai, int iSelectedItem, BOOL bForce)
|
|
{
|
|
HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_NTMTG_LIST_SERVERS);
|
|
int nCount = ListView_GetItemCount(hWndLV);
|
|
TCHAR sz[MAX_PATH];
|
|
TCHAR szTmp[MAX_PATH];
|
|
int oldIndex = lpPai->nBackupServerIndex;
|
|
|
|
if(iSelectedItem != -1)
|
|
{
|
|
if(nCount <= 1) // cant overwrite the default to skip
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
iSelectedItem = ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED);
|
|
if(iSelectedItem < 0)
|
|
return; // nothing selected ..
|
|
}
|
|
|
|
|
|
if(iSelectedItem == lpPai->nDefaultServerIndex)
|
|
{
|
|
if(nCount <= 1)
|
|
return;
|
|
else
|
|
{
|
|
if(!bForce)
|
|
{
|
|
int nTmp = 0;
|
|
while(nTmp == iSelectedItem && nTmp < nCount)
|
|
nTmp++;
|
|
iSelectedItem = nTmp;
|
|
}
|
|
}
|
|
}
|
|
|
|
// replace the old value of the def index item if its being overwritten
|
|
if((lpPai->nDefaultServerIndex == iSelectedItem) &&
|
|
lpPai->nDefaultServerIndex >= 0 && lpPai->szDefaultServerName && lstrlen(lpPai->szDefaultServerName))
|
|
{
|
|
ListView_SetItemText(hWndLV, lpPai->nDefaultServerIndex, 0, lpPai->szDefaultServerName);
|
|
lpPai->szDefaultServerName[0] = TEXT('\0');
|
|
}
|
|
|
|
// replace the old backup item text if we are reseting the backup item
|
|
if(lpPai->nBackupServerIndex >= 0 && lpPai->szBackupServerName && lstrlen(lpPai->szBackupServerName))
|
|
{
|
|
ListView_SetItemText(hWndLV, lpPai->nBackupServerIndex, 0, lpPai->szBackupServerName);
|
|
lpPai->szBackupServerName[0] = TEXT('\0');
|
|
}
|
|
|
|
lpPai->nBackupServerIndex = iSelectedItem;
|
|
|
|
{
|
|
sz[0] = TEXT('\0');
|
|
szTmp[0] = TEXT('\0');
|
|
ListView_GetItemText(hWndLV, lpPai->nBackupServerIndex, 0, sz, CharSizeOf(sz));
|
|
StrCpyN(lpPai->szBackupServerName, sz, lpPai->cchBackupServerName);
|
|
LoadString(hinstMapiX, idsBackupServer, szTmp, CharSizeOf(szTmp));
|
|
StrCatBuff(sz, TEXT(" "), ARRAYSIZE(sz));
|
|
StrCatBuff(sz, szTmp, ARRAYSIZE(sz));
|
|
ListView_SetItemText(hWndLV, lpPai->nBackupServerIndex, 0, sz);
|
|
}
|
|
|
|
if(lpPai->nDefaultServerIndex == iSelectedItem)
|
|
{
|
|
// Update this backup item
|
|
SetDefaultServer(hDlg, lpPai, oldIndex, FALSE);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//$$//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// UpdateServerLVButtons(hDlg);
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void UpdateServerLVButtons(HWND hDlg, LPPROP_ARRAY_INFO lpPai)
|
|
{
|
|
int nCount = ListView_GetItemCount(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_LIST_SERVERS));
|
|
|
|
if(lpPai->ulOperationType == SHOW_ONE_OFF)
|
|
nCount = 0;
|
|
|
|
EnableWindow(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_BUTTON_EDIT), (nCount > 0) ? TRUE : FALSE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_BUTTON_REMOVE), (nCount > 0) ? TRUE : FALSE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_BUTTON_SETDEFAULT), (nCount > 0) ? TRUE : FALSE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_BUTTON_SETBACKUP), (nCount > 1) ? TRUE : FALSE);
|
|
|
|
}
|
|
|
|
//$$//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// FillComboWithEmailAddresses(HWND hWndLV, HWND hWndCombo);
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void FillComboWithEmailAddresses(LPPROP_ARRAY_INFO lpPai, HWND hWndCombo, int * lpnDefault)
|
|
{
|
|
ULONG i,j;
|
|
ULONG ulcProps = 0;
|
|
LPSPropValue lpProps = NULL;
|
|
int nSel = (int) SendMessage(hWndCombo, CB_GETCURSEL, 0, 0);
|
|
TCHAR szBuf[MAX_UI_STR];
|
|
BOOL bMatch = FALSE;
|
|
BOOL bFound = FALSE;
|
|
ULONG nEmail = 0xFFFFFFFF;
|
|
|
|
enum _EmailProps
|
|
{
|
|
eCEmailAddr=0,
|
|
eCEmailIndex,
|
|
eCEmail,
|
|
eMax
|
|
};
|
|
|
|
SizedSPropTagArray(eMax, ptaE) =
|
|
{
|
|
eMax,
|
|
{
|
|
PR_CONTACT_EMAIL_ADDRESSES,
|
|
PR_CONTACT_DEFAULT_ADDRESS_INDEX,
|
|
PR_EMAIL_ADDRESS
|
|
}
|
|
};
|
|
*szBuf = '\0';
|
|
GetWindowText(hWndCombo, szBuf, CharSizeOf(szBuf));
|
|
|
|
|
|
// Delete all the combo contents
|
|
SendMessage(hWndCombo, CB_RESETCONTENT, 0, 0);
|
|
|
|
if(HR_FAILED(lpPai->lpPropObj->lpVtbl->GetProps(lpPai->lpPropObj,
|
|
(LPSPropTagArray)&ptaE,
|
|
MAPI_UNICODE,
|
|
&ulcProps, &lpProps)))
|
|
return;
|
|
|
|
// Check if the PR_CONTACT_EMAIL_ADDRESSES already exists ..
|
|
// if it does, tag the email onto it
|
|
// if it doesnt and there is no pr_email_address, we create both
|
|
// else if there is PR_EMAIL address then we cretae contact_email_addresses
|
|
|
|
if(lpProps[eCEmailAddr].ulPropTag == PR_CONTACT_EMAIL_ADDRESSES)
|
|
{
|
|
bFound = TRUE;
|
|
for(j=0;j<lpProps[eCEmailAddr].Value.MVSZ.cValues;j++)
|
|
{
|
|
SendMessage(hWndCombo, CB_ADDSTRING, 0, (LPARAM) lpProps[eCEmailAddr].Value.MVSZ.LPPSZ[j]);
|
|
if(!lstrcmp(szBuf, lpProps[eCEmailAddr].Value.MVSZ.LPPSZ[j]))
|
|
{
|
|
bMatch = TRUE;
|
|
nSel = j;
|
|
}
|
|
}
|
|
}
|
|
if( lpProps[eCEmailIndex].ulPropTag == PR_CONTACT_DEFAULT_ADDRESS_INDEX)
|
|
{
|
|
if(lpnDefault)
|
|
*lpnDefault = lpProps[eCEmailIndex].Value.l;
|
|
}
|
|
if(lpProps[eCEmail].ulPropTag == PR_EMAIL_ADDRESS)
|
|
nEmail = eCEmail;
|
|
|
|
// if there is no Contact_Email_Addresses but there is an email_address
|
|
if(!bFound && nEmail != 0xFFFFFFFF)
|
|
{
|
|
SendMessage(hWndCombo, CB_ADDSTRING, 0, (LPARAM) lpProps[nEmail].Value.LPSZ);
|
|
if(!lstrcmp(szBuf, lpProps[nEmail].Value.LPSZ))
|
|
{
|
|
bMatch = TRUE;
|
|
nSel = 0;
|
|
}
|
|
}
|
|
|
|
if(bMatch)
|
|
SendMessage(hWndCombo, CB_SETCURSEL, (WPARAM) nSel, 0);
|
|
else if(lstrlen(szBuf))
|
|
{
|
|
// make sure this is not the [None .. ] string
|
|
TCHAR sz[MAX_PATH];
|
|
LoadString(hinstMapiX, idsCertsWithoutEmails, sz, CharSizeOf(sz));
|
|
if(lstrcmpi(sz, szBuf))
|
|
{
|
|
int nPos = (int) SendMessage(hWndCombo, CB_ADDSTRING, 0, (LPARAM) szBuf);
|
|
SendMessage(hWndCombo, CB_SETCURSEL, (WPARAM) nPos, 0);
|
|
}
|
|
}
|
|
|
|
SetWindowText(hWndCombo, szBuf);
|
|
|
|
MAPIFreeBuffer(lpProps);
|
|
|
|
}
|
|
|
|
/*
|
|
- ClearConfLV
|
|
-
|
|
* Clears out the info alloced into the conferencing list view
|
|
*/
|
|
void ClearConfLV(HWND hDlg)
|
|
{
|
|
HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_NTMTG_LIST_SERVERS);
|
|
int nItemCount = ListView_GetItemCount(hWndLV), i = 0;
|
|
for(i=0;i< nItemCount; i++)
|
|
{
|
|
LV_ITEM lvi = {0};
|
|
lvi.mask = LVIF_PARAM;
|
|
lvi.iItem = i; lvi.iSubItem = 0;
|
|
ListView_GetItem(hWndLV, &lvi);
|
|
if(lvi.lParam)
|
|
LocalFreeServerItem((LPSERVER_ITEM) lvi.lParam);
|
|
}
|
|
ListView_DeleteAllItems(hWndLV);
|
|
}
|
|
|
|
|
|
/*//$$***********************************************************************
|
|
* FUNCTION: fnConferencingProc
|
|
*
|
|
* PURPOSE: Callback function for handling the Conferencing property sheet ...
|
|
*
|
|
****************************************************************************/
|
|
INT_PTR CALLBACK fnConferencingProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)
|
|
{
|
|
PROPSHEETPAGE * pps;
|
|
BOOL bRet = FALSE;
|
|
|
|
pps = (PROPSHEETPAGE *) GetWindowLongPtr(hDlg, DWLP_USER);
|
|
|
|
switch(message)
|
|
{
|
|
case WM_INITDIALOG:
|
|
// [PaulHi] EnumChildWindows needs to be called BEFORE SetDetails in this case
|
|
// because it sets list view column strings. SetDetails calls EnumChildWindows
|
|
// at the end but this is too late.
|
|
// @todo - Instead of callinge EnumChildWindows twice just call it at the
|
|
// begninning of SetDetails. Don't want to change the code that much now right
|
|
// before RTM.
|
|
EnumChildWindows(hDlg, SetChildDefaultGUIFont, (LPARAM)0);
|
|
SetWindowLongPtr(hDlg,DWLP_USER,lParam);
|
|
pps = (PROPSHEETPAGE *) lParam;
|
|
lpPAI->ulFlags |= DETAILS_Initializing;
|
|
SetDetailsUI(hDlg, lpPAI, lpPAI->ulOperationType, propConferencing);
|
|
lpPAI->ulFlags &= ~DETAILS_Initializing;
|
|
return TRUE;
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
bRet = TRUE;
|
|
break;
|
|
|
|
case WM_HELP:
|
|
WABWinHelp(((LPHELPINFO)lParam)->hItemHandle,
|
|
g_szWABHelpFileName,
|
|
HELP_WM_HELP,
|
|
(DWORD_PTR)(LPSTR) rgDetlsHelpIDs );
|
|
break;
|
|
|
|
case WM_CONTEXTMENU:
|
|
WABWinHelp((HWND) wParam,
|
|
g_szWABHelpFileName,
|
|
HELP_CONTEXTMENU,
|
|
(DWORD_PTR)(LPVOID) rgDetlsHelpIDs );
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch(GET_WM_COMMAND_CMD(wParam,lParam)) //check the notification code
|
|
{
|
|
case EN_CHANGE:
|
|
if(LOWORD(wParam) == IDC_DETAILS_NTMTG_EDIT_ADDSERVER)
|
|
{
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_NTMTG_BUTTON_ADDSERVER),TRUE);
|
|
SendMessage(hDlg, DM_SETDEFID, IDC_DETAILS_NTMTG_BUTTON_ADDSERVER, 0);
|
|
return 0;
|
|
break;
|
|
}
|
|
case CBN_EDITCHANGE:
|
|
case CBN_SELCHANGE:
|
|
if (lpbSomethingChanged)
|
|
(*lpbSomethingChanged) = TRUE;
|
|
break;
|
|
|
|
}
|
|
switch(GET_WM_COMMAND_ID(wParam, lParam))
|
|
{
|
|
case IDCANCEL:
|
|
// This is a windows bug that prevents ESC canceling prop sheets
|
|
// which have MultiLine Edit boxes KB: Q130765
|
|
SendMessage(GetParent(hDlg),message,wParam,lParam);
|
|
break;
|
|
|
|
case IDC_DETAILS_NTMTG_BUTTON_CALL:
|
|
// basically shell-exec a TEXT("callto") command here
|
|
// The format of the TEXT("Callto") protocol is
|
|
// callto://servername/emailalias
|
|
//
|
|
{
|
|
TCHAR * szCalltoURL = NULL;//szCalltoURL[MAX_UI_STR*2];
|
|
ULONG cchCalltoURL=MAX_UI_STR*2;
|
|
TCHAR szEmail[MAX_UI_STR];
|
|
TCHAR szServer[MAX_UI_STR];
|
|
HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_NTMTG_LIST_SERVERS);
|
|
if(szCalltoURL = LocalAlloc(LMEM_ZEROINIT, cchCalltoURL*sizeof(TCHAR)))
|
|
{
|
|
int nItem = ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED);
|
|
{
|
|
LV_ITEM lvi = {0};
|
|
lvi.iItem = nItem;
|
|
lvi.iSubItem = 0;
|
|
lvi.mask = LVIF_PARAM;
|
|
ListView_GetItem(hWndLV, &lvi);
|
|
|
|
if(lvi.lParam)
|
|
{
|
|
StrCpyN(szServer, (LPTSTR) ((LPSERVER_ITEM)lvi.lParam)->lpServer, ARRAYSIZE(szServer));
|
|
StrCpyN(szEmail, (LPTSTR) ((LPSERVER_ITEM)lvi.lParam)->lpEmail, ARRAYSIZE(szEmail));
|
|
}
|
|
else
|
|
{
|
|
szServer[0] = TEXT('\0');
|
|
szEmail[0] = TEXT('\0');
|
|
}
|
|
}
|
|
if(lstrlen(szServer) && lstrlen(szEmail))
|
|
{
|
|
StrCpyN(szCalltoURL, szCallto, cchCalltoURL);
|
|
StrCatBuff(szCalltoURL, szServer, cchCalltoURL);
|
|
StrCatBuff(szCalltoURL, TEXT("/"), cchCalltoURL);
|
|
StrCatBuff(szCalltoURL, szEmail, cchCalltoURL);
|
|
ShellExecute(hDlg, TEXT("open"), szCalltoURL, NULL, NULL, SW_SHOWNORMAL);
|
|
}
|
|
else
|
|
ShowMessageBox(hDlg, idsIncompleteConfInfo, MB_OK | MB_ICONINFORMATION);
|
|
LocalFreeAndNull(&szCalltoURL);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IDC_DETAILS_NTMTG_BUTTON_CANCELEDIT:
|
|
{
|
|
HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_NTMTG_LIST_SERVERS);
|
|
LVSelectItem(hWndLV, lpPAI->nConfEditIndex);
|
|
lpPAI->ulFlags &= ~DETAILS_EditingConf;
|
|
ShowWindow(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_BUTTON_CANCELEDIT), SW_HIDE);
|
|
lpPAI->nConfEditIndex = -1;
|
|
SetDlgItemText(hDlg, IDC_DETAILS_NTMTG_EDIT_ADDSERVER, szEmpty);
|
|
SetDlgItemText(hDlg, IDC_DETAILS_NTMTG_COMBO_EMAIL, szEmpty);
|
|
{
|
|
TCHAR sz[MAX_PATH];
|
|
LoadString(hinstMapiX, idsConfAdd, sz, CharSizeOf(sz));
|
|
SetDlgItemText(hDlg, IDC_DETAILS_NTMTG_BUTTON_ADDSERVER, sz);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IDC_DETAILS_NTMTG_BUTTON_ADDSERVER:
|
|
{
|
|
TCHAR szBuf[MAX_UI_STR], szEmail[MAX_UI_STR];
|
|
HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_NTMTG_LIST_SERVERS);
|
|
GetDlgItemText(hDlg, IDC_DETAILS_NTMTG_EDIT_ADDSERVER, szBuf, CharSizeOf(szBuf));
|
|
TrimSpaces(szBuf);
|
|
GetDlgItemText(hDlg, IDC_DETAILS_NTMTG_COMBO_EMAIL, szEmail, CharSizeOf(szEmail));
|
|
TrimSpaces(szEmail);
|
|
if(!lstrlen(szBuf) || !lstrlen(szEmail))
|
|
ShowMessageBox(hDlg, idsIncompleteConfInfo, MB_OK | MB_ICONEXCLAMATION);
|
|
else
|
|
{
|
|
LV_ITEM lvi = {0};
|
|
LPSERVER_ITEM lpSI = (LPSERVER_ITEM) LocalAlloc(LMEM_ZEROINIT, sizeof(SERVER_ITEM));
|
|
ULONG cch = lstrlen(szBuf)+1;
|
|
LPTSTR lp = LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*cch);
|
|
ULONG cchE = lstrlen(szEmail)+1;
|
|
LPTSTR lpE = LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*cchE);
|
|
lvi.mask = LVIF_TEXT | LVIF_PARAM;
|
|
if(lp && lpE && lpSI)
|
|
{
|
|
SendMessage(hWndLV, WM_SETREDRAW, (WPARAM) FALSE, 0);
|
|
StrCpyN(lp, szBuf, cch);
|
|
StrCpyN(lpE, szEmail, cchE);
|
|
lpSI->lpServer = lp;
|
|
lpSI->lpEmail = lpE;
|
|
lvi.lParam = (LPARAM) lpSI;
|
|
if(lpPAI->ulFlags & DETAILS_EditingConf)
|
|
lvi.iItem = lpPAI->nConfEditIndex;
|
|
else
|
|
lvi.iItem = ListView_GetItemCount(hWndLV);
|
|
lvi.cchTextMax = MAX_UI_STR;
|
|
lvi.iSubItem = 0;
|
|
lvi.pszText = szBuf;
|
|
ListView_InsertItem(hWndLV, &lvi);
|
|
ListView_SetItemText (hWndLV, lvi.iItem, 1, szEmail);
|
|
SetDlgItemText(hDlg, IDC_DETAILS_NTMTG_EDIT_ADDSERVER, szEmpty);
|
|
SetDlgItemText(hDlg, IDC_DETAILS_NTMTG_COMBO_EMAIL, szEmpty);
|
|
if(lpPAI->ulFlags & DETAILS_EditingConf)
|
|
{
|
|
LV_ITEM lvii = {0};
|
|
lvii.mask = LVIF_PARAM;
|
|
lvii.iItem = lvi.iItem+1; lvii.iSubItem = 0;
|
|
ListView_GetItem(hWndLV, &lvii);
|
|
if(lvii.lParam)
|
|
LocalFreeServerItem((LPSERVER_ITEM) lvii.lParam);
|
|
ListView_DeleteItem(hWndLV, lvii.iItem);
|
|
if(lvi.iItem == lpPAI->nDefaultServerIndex)
|
|
StrCpyN(lpPAI->szDefaultServerName,lp,lpPAI->cchDefaultServerName);
|
|
else if(lvi.iItem == lpPAI->nBackupServerIndex)
|
|
StrCpyN(lpPAI->szBackupServerName,lp,lpPAI->cchBackupServerName);
|
|
SendMessage(hDlg, WM_COMMAND, (WPARAM) IDC_DETAILS_NTMTG_BUTTON_CANCELEDIT, 0);
|
|
}
|
|
LVSelectItem(hWndLV, lvi.iItem);
|
|
SendMessage(GetParent(hDlg), DM_SETDEFID, IDOK, 0);
|
|
SetDefaultServer(hDlg, lpPAI, lpPAI->nDefaultServerIndex, TRUE);
|
|
SetBackupServer(hDlg, lpPAI, lpPAI->nBackupServerIndex, FALSE);
|
|
SendMessage(hWndLV, WM_SETREDRAW, (WPARAM) TRUE, 0);
|
|
}
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_NTMTG_BUTTON_ADDSERVER),FALSE);
|
|
SetFocus(GetDlgItem(hDlg,IDC_DETAILS_NTMTG_EDIT_ADDSERVER));
|
|
}
|
|
UpdateWindow(hWndLV);
|
|
if (lpbSomethingChanged)
|
|
(*lpbSomethingChanged) = TRUE;
|
|
UpdateServerLVButtons(hDlg, lpPAI);
|
|
}
|
|
break;
|
|
|
|
case IDC_DETAILS_NTMTG_BUTTON_EDIT:
|
|
{
|
|
HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_NTMTG_LIST_SERVERS);
|
|
if(ListView_GetSelectedCount(hWndLV)==1)
|
|
{
|
|
HWND hWndEditLabel;
|
|
int nItem = ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED);
|
|
{
|
|
LV_ITEM lvi = {0};
|
|
lvi.iItem = nItem;
|
|
lvi.iSubItem = 0;
|
|
lvi.mask = LVIF_PARAM;
|
|
ListView_GetItem(hWndLV, &lvi);
|
|
if(lvi.lParam)
|
|
{
|
|
SetDlgItemText(hDlg, IDC_DETAILS_NTMTG_EDIT_ADDSERVER, (LPTSTR) ((LPSERVER_ITEM)lvi.lParam)->lpServer);
|
|
SetDlgItemText(hDlg, IDC_DETAILS_NTMTG_COMBO_EMAIL, (LPTSTR) ((LPSERVER_ITEM)lvi.lParam)->lpEmail);
|
|
// Remove these items from the ListView
|
|
SetFocus(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_EDIT_ADDSERVER));
|
|
SendMessage(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_EDIT_ADDSERVER), EM_SETSEL, 0, -1);
|
|
lpPAI->ulFlags |= DETAILS_EditingConf;
|
|
lpPAI->nConfEditIndex = nItem;
|
|
ShowWindow(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_BUTTON_CANCELEDIT), SW_SHOW);
|
|
{
|
|
TCHAR sz[MAX_PATH];
|
|
LoadString(hinstMapiX, idsConfUpdate, sz, CharSizeOf(sz));
|
|
SetDlgItemText(hDlg, IDC_DETAILS_NTMTG_BUTTON_ADDSERVER, sz);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IDC_DETAILS_NTMTG_BUTTON_REMOVE:
|
|
{
|
|
HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_NTMTG_LIST_SERVERS);
|
|
int iItemIndex = ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED);
|
|
if(iItemIndex != -1)
|
|
{
|
|
BOOL bDef = (iItemIndex == lpPAI->nDefaultServerIndex) ? TRUE : FALSE;
|
|
BOOL bBck = (iItemIndex == lpPAI->nBackupServerIndex) ? TRUE : FALSE;
|
|
|
|
if((lpPAI->ulFlags&DETAILS_EditingConf) && (iItemIndex==lpPAI->nConfEditIndex))
|
|
SendMessage(hDlg, WM_COMMAND, (WPARAM)IDC_DETAILS_NTMTG_BUTTON_CANCELEDIT, 0);
|
|
|
|
{
|
|
LV_ITEM lvi = {0};
|
|
lvi.mask = LVIF_PARAM;
|
|
lvi.iItem = iItemIndex; lvi.iSubItem = 0;
|
|
ListView_GetItem(hWndLV, &lvi);
|
|
if(lvi.lParam)
|
|
LocalFreeServerItem((LPSERVER_ITEM) lvi.lParam);
|
|
}
|
|
ListView_DeleteItem(hWndLV, iItemIndex);
|
|
if(ListView_GetSelectedCount(hWndLV) <= 0)
|
|
LVSelectItem(hWndLV, (iItemIndex <= 0) ? iItemIndex : iItemIndex-1);
|
|
if (lpbSomethingChanged)
|
|
(*lpbSomethingChanged) = TRUE;
|
|
|
|
if(iItemIndex < lpPAI->nDefaultServerIndex)
|
|
lpPAI->nDefaultServerIndex--;
|
|
|
|
if(iItemIndex < lpPAI->nBackupServerIndex)
|
|
lpPAI->nBackupServerIndex--;
|
|
|
|
if(bDef)
|
|
{
|
|
lpPAI->nDefaultServerIndex = -1;
|
|
lpPAI->szDefaultServerName[0] = TEXT('\0');
|
|
SetDefaultServer(hDlg, lpPAI, -1, FALSE);
|
|
}
|
|
|
|
if(bBck)
|
|
{
|
|
lpPAI->nBackupServerIndex = -1;
|
|
lpPAI->szBackupServerName[0] = TEXT('\0');
|
|
SetBackupServer(hDlg, lpPAI, -1, FALSE);
|
|
}
|
|
|
|
if (lpbSomethingChanged)
|
|
(*lpbSomethingChanged) = TRUE;
|
|
}
|
|
UpdateServerLVButtons(hDlg, lpPAI);
|
|
}
|
|
break;
|
|
|
|
case IDC_DETAILS_NTMTG_BUTTON_SETDEFAULT:
|
|
SetDefaultServer(hDlg, lpPAI, -1, TRUE);
|
|
if (lpbSomethingChanged)
|
|
(*lpbSomethingChanged) = TRUE;
|
|
break;
|
|
|
|
case IDC_DETAILS_NTMTG_BUTTON_SETBACKUP:
|
|
SetBackupServer(hDlg, lpPAI, -1, TRUE);
|
|
if (lpbSomethingChanged)
|
|
(*lpbSomethingChanged) = TRUE;
|
|
break;
|
|
|
|
|
|
}
|
|
break;
|
|
|
|
default:
|
|
#ifndef WIN16 // WIN16 doesn't support MSWheel.
|
|
if((g_msgMSWheel && message == g_msgMSWheel)
|
|
// || message == WM_MOUSEWHEEL
|
|
)
|
|
{
|
|
SendMessage(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_LIST_SERVERS), message, wParam, lParam);
|
|
}
|
|
#endif // !WIN16
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
switch(((NMHDR FAR *)lParam)->code)
|
|
{
|
|
case PSN_SETACTIVE: //initialize
|
|
FillCertTridentConfDetailsUI(hDlg, lpPAI, propConferencing, lpbSomethingChanged);
|
|
// if this is a readonly entry and there is no data in the listview,
|
|
// disable the call now button
|
|
if( lpPAI->ulOperationType == SHOW_ONE_OFF &&
|
|
ListView_GetItemCount(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_LIST_SERVERS)) <= 0)
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_NTMTG_BUTTON_CALL), FALSE);
|
|
UpdateServerLVButtons(hDlg, lpPAI);
|
|
//FillComboWithEmailAddresses(lpPAI, lpPAI->hWndComboConf, NULL);
|
|
break;
|
|
|
|
case PSN_KILLACTIVE: //Losing activation to another page
|
|
// In case there is something sitting in the edit boxes, add it to the lv
|
|
//
|
|
{
|
|
TCHAR szBuf[MAX_UI_STR], szEmail[MAX_UI_STR];
|
|
GetDlgItemText(hDlg, IDC_DETAILS_NTMTG_EDIT_ADDSERVER, szBuf, CharSizeOf(szBuf));
|
|
TrimSpaces(szBuf);
|
|
GetDlgItemText(hDlg, IDC_DETAILS_NTMTG_COMBO_EMAIL, szEmail, CharSizeOf(szEmail));
|
|
TrimSpaces(szEmail);
|
|
if(lstrlen(szBuf) && lstrlen(szEmail))
|
|
SendMessage(hDlg, WM_COMMAND, (WPARAM) IDC_DETAILS_NTMTG_BUTTON_ADDSERVER, 0);
|
|
}
|
|
bUpdatePropArray(hDlg, lpPAI, propConferencing);
|
|
ClearConfLV(hDlg);
|
|
break;
|
|
|
|
case PSN_APPLY: //ok
|
|
//bUpdatePropArray(hDlg, lpPAI, propConferencing);
|
|
//ClearConfLV(hDlg);
|
|
if (lpPAI->nRetVal == DETAILS_RESET)
|
|
lpPAI->nRetVal = DETAILS_OK;
|
|
break;
|
|
|
|
case PSN_RESET: //cancel
|
|
if(lpPAI->ulFlags & DETAILS_EditingEmail) //cancel any editing else it faults #30235
|
|
ListView_EditLabel(GetDlgItem(hDlg, IDC_DETAILS_NTMTG_LIST_SERVERS), -1);
|
|
if (lpPAI->nRetVal == DETAILS_RESET)
|
|
lpPAI->nRetVal = DETAILS_CANCEL;
|
|
ClearConfLV(hDlg);
|
|
break;
|
|
|
|
case NM_CUSTOMDRAW:
|
|
switch(wParam)
|
|
{
|
|
case IDC_DETAILS_NTMTG_LIST_SERVERS:
|
|
{
|
|
NMCUSTOMDRAW *pnmcd=(NMCUSTOMDRAW*)lParam;
|
|
NM_LISTVIEW * pNm = (NM_LISTVIEW *)lParam;
|
|
if(pnmcd->dwDrawStage==CDDS_PREPAINT)
|
|
{
|
|
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, CDRF_NOTIFYITEMDRAW | CDRF_DODEFAULT);
|
|
return TRUE;
|
|
}
|
|
else if(pnmcd->dwDrawStage==CDDS_ITEMPREPAINT)
|
|
{
|
|
if( pnmcd->dwItemSpec == (DWORD) lpPAI->nDefaultServerIndex ||
|
|
pnmcd->dwItemSpec == (DWORD) lpPAI->nBackupServerIndex )
|
|
{
|
|
SelectObject(((NMLVCUSTOMDRAW*)lParam)->nmcd.hdc, GetFont(fntsSysIconBold));
|
|
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, CDRF_NEWFONT);
|
|
return TRUE;
|
|
}
|
|
}
|
|
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, CDRF_DODEFAULT);
|
|
return TRUE;
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case NM_DBLCLK:
|
|
switch(wParam)
|
|
{
|
|
case IDC_DETAILS_NTMTG_LIST_SERVERS:
|
|
SetDefaultServer(hDlg, lpPAI, -1, TRUE);
|
|
if (lpbSomethingChanged)
|
|
(*lpbSomethingChanged) = TRUE;
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
return bRet;
|
|
|
|
}
|
|
|
|
/*//$$***********************************************************************
|
|
* FUNCTION: AddLVLDAPURLEntry
|
|
*
|
|
* PURPOSE: Takes an LDAP URL, converts it to a MailUser and adds the
|
|
* MailUser to the List View
|
|
*
|
|
****************************************************************************/
|
|
void AddLVLDAPURLEntry(LPADRBOOK lpAdrBook, HWND hWndLV, LPTSTR lpszLDAPURL)
|
|
{
|
|
LPMAILUSER lpMailUser = NULL;
|
|
|
|
HrProcessLDAPUrl(lpAdrBook, GetParent(hWndLV),
|
|
WABOBJECT_LDAPURL_RETURN_MAILUSER,
|
|
lpszLDAPURL,
|
|
&lpMailUser);
|
|
if(lpMailUser)
|
|
{
|
|
LPSPropValue lpPropArray = NULL;
|
|
ULONG ulcProps = 0;
|
|
if(!HR_FAILED(lpMailUser->lpVtbl->GetProps(lpMailUser,
|
|
NULL, MAPI_UNICODE,
|
|
&ulcProps, &lpPropArray)))
|
|
{
|
|
LPRECIPIENT_INFO lpItem = LocalAlloc(LMEM_ZEROINIT, sizeof(RECIPIENT_INFO));
|
|
if (lpItem)
|
|
{
|
|
GetRecipItemFromPropArray(ulcProps, lpPropArray, &lpItem);
|
|
if(lpItem)
|
|
AddSingleItemToListView(hWndLV, lpItem);
|
|
}
|
|
MAPIFreeBuffer(lpPropArray);
|
|
}
|
|
lpMailUser->lpVtbl->Release(lpMailUser);
|
|
}
|
|
}
|
|
|
|
/*//$$***********************************************************************
|
|
* FUNCTION: FillOrgData
|
|
*
|
|
* PURPOSE: Fills in LDAP data in the Org prop sheets
|
|
*
|
|
****************************************************************************/
|
|
void FillOrgData(HWND hDlg, LPPROP_ARRAY_INFO lpPai)
|
|
{
|
|
HWND hWndLVManager = GetDlgItem(hDlg, IDC_DETAILS_ORG_LIST_MANAGER);
|
|
HWND hWndLVReports = GetDlgItem(hDlg, IDC_DETAILS_ORG_LIST_REPORTS);
|
|
|
|
ULONG i,j;
|
|
ULONG ulcPropCount = 0;
|
|
LPSPropValue lpPA = NULL;
|
|
|
|
HCURSOR hOldCur = SetCursor(LoadCursor(NULL, IDC_WAIT));
|
|
enum _org
|
|
{
|
|
oReports=0,
|
|
oManager,
|
|
oMax
|
|
};
|
|
SizedSPropTagArray(oMax, ptaOrg) =
|
|
{
|
|
oMax,
|
|
{
|
|
PR_WAB_REPORTS,
|
|
PR_WAB_MANAGER
|
|
}
|
|
};
|
|
if(!HR_FAILED(lpPai->lpPropObj->lpVtbl->GetProps(lpPai->lpPropObj,
|
|
(LPSPropTagArray)&ptaOrg,
|
|
MAPI_UNICODE,
|
|
&ulcPropCount, &lpPA)))
|
|
{
|
|
if(lpPA[oReports].ulPropTag == PR_WAB_REPORTS)
|
|
{
|
|
for(j=0;j<lpPA[oReports].Value.MVSZ.cValues;j++)
|
|
{
|
|
AddLVLDAPURLEntry(lpPai->lpIAB, hWndLVReports, lpPA[oReports].Value.MVSZ.LPPSZ[j]);
|
|
}
|
|
}
|
|
if(lpPA[oManager].ulPropTag == PR_WAB_MANAGER)
|
|
{
|
|
AddLVLDAPURLEntry(lpPai->lpIAB, hWndLVManager, lpPA[oManager].Value.LPSZ);
|
|
}
|
|
}
|
|
|
|
if(ListView_GetItemCount(hWndLVManager) > 0)
|
|
LVSelectItem(hWndLVManager, 0);
|
|
else
|
|
EnableWindow(hWndLVManager, FALSE);
|
|
|
|
if(ListView_GetItemCount(hWndLVReports) > 0)
|
|
LVSelectItem(hWndLVReports, 0);
|
|
else
|
|
EnableWindow(hWndLVReports, FALSE);
|
|
|
|
|
|
if(lpPA)
|
|
MAPIFreeBuffer(lpPA);
|
|
|
|
SetCursor(hOldCur);
|
|
}
|
|
|
|
|
|
|
|
/*//$$***********************************************************************
|
|
*
|
|
* FUNCTION: FreeOrgLVData
|
|
*
|
|
* PURPOSE: Frees the Data from the Org LVs
|
|
*
|
|
****************************************************************************/
|
|
void FreeOrgLVData(HWND hWndLV)
|
|
{
|
|
int i=0, nCount=ListView_GetItemCount(hWndLV);
|
|
for(i=0;i<nCount;i++)
|
|
{
|
|
LV_ITEM lvi = {0};
|
|
lvi.mask = LVIF_PARAM;
|
|
lvi.iItem = i;
|
|
ListView_GetItem(hWndLV, &lvi);
|
|
if(lvi.lParam)
|
|
{
|
|
LPRECIPIENT_INFO lpItem = (LPRECIPIENT_INFO) lvi.lParam;
|
|
FreeRecipItem(&lpItem);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*//$$***********************************************************************
|
|
* FUNCTION: fnOrgProc
|
|
*
|
|
* PURPOSE: Callback function for handling the Organization Prop Sheets
|
|
*
|
|
****************************************************************************/
|
|
INT_PTR CALLBACK fnOrgProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)
|
|
{
|
|
PROPSHEETPAGE * pps;
|
|
BOOL bRet = FALSE;
|
|
|
|
pps = (PROPSHEETPAGE *) GetWindowLongPtr(hDlg, DWLP_USER);
|
|
|
|
switch(message)
|
|
{
|
|
case WM_INITDIALOG:
|
|
SetWindowLongPtr(hDlg,DWLP_USER,lParam);
|
|
pps = (PROPSHEETPAGE *) lParam;
|
|
HrInitListView(GetDlgItem(hDlg, IDC_DETAILS_ORG_LIST_MANAGER), LVS_REPORT, FALSE);
|
|
HrInitListView(GetDlgItem(hDlg, IDC_DETAILS_ORG_LIST_REPORTS), LVS_REPORT, FALSE);
|
|
UpdateWindow(hDlg);
|
|
FillOrgData(hDlg, lpPAI);
|
|
return TRUE;
|
|
|
|
case WM_HELP:
|
|
WABWinHelp(((LPHELPINFO)lParam)->hItemHandle,
|
|
g_szWABHelpFileName,
|
|
HELP_WM_HELP,
|
|
(DWORD_PTR)(LPSTR) rgDetlsHelpIDs );
|
|
break;
|
|
|
|
case WM_CONTEXTMENU:
|
|
WABWinHelp((HWND) wParam,
|
|
g_szWABHelpFileName,
|
|
HELP_CONTEXTMENU,
|
|
(DWORD_PTR)(LPVOID) rgDetlsHelpIDs );
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch(LOWORD(wParam))
|
|
{
|
|
case IDCANCEL:
|
|
// This is a windows bug that prevents ESC canceling prop sheets
|
|
// which have MultiLine Edit boxes KB: Q130765
|
|
SendMessage(GetParent(hDlg),message,wParam,lParam);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
|
|
case WM_NOTIFY:
|
|
switch(((NMHDR FAR *)lParam)->code)
|
|
{
|
|
case PSN_SETACTIVE: //initialize
|
|
break;
|
|
|
|
case PSN_KILLACTIVE: //Losing activation to another page
|
|
break;
|
|
|
|
case PSN_APPLY: //ok
|
|
lpPAI->nRetVal = DETAILS_OK;
|
|
case PSN_RESET: //cancel
|
|
FreeOrgLVData(GetDlgItem(hDlg, IDC_DETAILS_ORG_LIST_MANAGER));
|
|
FreeOrgLVData(GetDlgItem(hDlg, IDC_DETAILS_ORG_LIST_REPORTS));
|
|
if (lpPAI->nRetVal == DETAILS_RESET)
|
|
lpPAI->nRetVal = DETAILS_CANCEL;
|
|
break;
|
|
|
|
|
|
// if enter pressed ...
|
|
case LVN_KEYDOWN:
|
|
if(((LV_KEYDOWN FAR *) lParam)->wVKey != VK_RETURN)
|
|
break;
|
|
// else fall thru
|
|
case NM_DBLCLK:
|
|
switch(wParam)
|
|
{
|
|
case IDC_DETAILS_ORG_LIST_MANAGER:
|
|
case IDC_DETAILS_ORG_LIST_REPORTS:
|
|
{
|
|
NM_LISTVIEW * pNm = (NM_LISTVIEW *)lParam;
|
|
if (ListView_GetSelectedCount(pNm->hdr.hwndFrom) == 1)
|
|
HrShowLVEntryProperties(pNm->hdr.hwndFrom, 0, lpPAI->lpIAB,NULL);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
} //WM_NOTIFY
|
|
return TRUE;
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
void LocalFreeServerItem(LPSERVER_ITEM lpSI)
|
|
{
|
|
if(lpSI)
|
|
{
|
|
if(lpSI->lpServer)
|
|
LocalFree((LPVOID) lpSI->lpServer);
|
|
if(lpSI->lpEmail)
|
|
LocalFree((LPVOID) lpSI->lpEmail);
|
|
LocalFree((LPVOID) lpSI);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*//$$***********************************************************************
|
|
* FUNCTION: fnSummaryProc
|
|
*
|
|
*
|
|
****************************************************************************/
|
|
void UpdateSummaryInfo(HWND hDlg, LPPROP_ARRAY_INFO lpPai)
|
|
{
|
|
ULONG cValues = 0, i = 0, j = 0;
|
|
LPSPropValue lpPropArray = NULL;
|
|
BOOL bFoundEmail = FALSE;
|
|
BOOL bFoundHomeURL = FALSE;
|
|
BOOL bFoundBusURL = FALSE;
|
|
ULONG ulPropTag;
|
|
HWND hURLBtn;
|
|
|
|
if(!lpPai->lpPropObj)
|
|
goto out;
|
|
|
|
if (HR_FAILED(lpPai->lpPropObj->lpVtbl->GetProps(lpPai->lpPropObj,
|
|
(LPSPropTagArray) &ptaUIDetlsPropsSummary, MAPI_UNICODE,
|
|
&cValues,
|
|
&lpPropArray)))
|
|
{
|
|
goto out;
|
|
}
|
|
|
|
for(i=0;i<MAX_SUMMARY_ID;i++)
|
|
{
|
|
SetDlgItemText(hDlg, rgSummaryIDs[i], szEmpty);
|
|
for(j=0;j<cValues;j++)
|
|
{
|
|
ulPropTag = lpPropArray[j].ulPropTag;
|
|
if( ulPropTag == PR_DISPLAY_NAME)
|
|
{
|
|
SetWindowPropertiesTitle(GetParent(hDlg), lpPropArray[j].Value.LPSZ);
|
|
}
|
|
if(ulPropTag == ((LPSPropTagArray) &ptaUIDetlsPropsSummary)->aulPropTag[i])
|
|
{
|
|
if(ulPropTag == PR_EMAIL_ADDRESS)
|
|
bFoundEmail = TRUE;
|
|
else if(ulPropTag == PR_PERSONAL_HOME_PAGE )
|
|
bFoundHomeURL = TRUE;
|
|
else if( ulPropTag == PR_BUSINESS_HOME_PAGE )
|
|
bFoundBusURL = TRUE;
|
|
|
|
SetDlgItemText(hDlg, rgSummaryIDs[i], lpPropArray[j].Value.LPSZ);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
hURLBtn = GetDlgItem( hDlg, IDC_DETAILS_HOME_BUTTON_URL);
|
|
if( bFoundHomeURL )
|
|
{
|
|
// enable and show button
|
|
ShowWindow(hURLBtn, SW_SHOW);
|
|
SendMessage(hURLBtn, WM_ENABLE, (WPARAM)(TRUE), (LPARAM)(0) );
|
|
}
|
|
else
|
|
{
|
|
// hide and disable button
|
|
ShowWindow(hURLBtn, SW_HIDE);
|
|
SendMessage(hURLBtn, WM_ENABLE, (WPARAM)(FALSE), (LPARAM)(0) );
|
|
}
|
|
|
|
hURLBtn = GetDlgItem( hDlg, IDC_DETAILS_BUSINESS_BUTTON_URL);
|
|
if( bFoundBusURL )
|
|
{
|
|
// enable and show button
|
|
|
|
ShowWindow(hURLBtn, SW_SHOW);
|
|
SendMessage(hURLBtn, WM_ENABLE, (WPARAM)(TRUE), (LPARAM)(0) );
|
|
}
|
|
else
|
|
{
|
|
// hide and disable button
|
|
ShowWindow(hURLBtn, SW_HIDE);
|
|
SendMessage(hURLBtn, WM_ENABLE, (WPARAM)(FALSE), (LPARAM)(0) );
|
|
}
|
|
|
|
if(!bFoundEmail)
|
|
{
|
|
// Look for Contact_Email_Addresses and DefaultIndex
|
|
ULONG nEmails = 0xFFFFFFFF, nDef = 0xFFFFFFFF;
|
|
for(i=0;i<cValues;i++)
|
|
{
|
|
if(lpPropArray[i].ulPropTag == PR_CONTACT_EMAIL_ADDRESSES)
|
|
nEmails = i;
|
|
if(lpPropArray[i].ulPropTag == PR_CONTACT_DEFAULT_ADDRESS_INDEX)
|
|
nDef = i;
|
|
}
|
|
if(nEmails != 0xFFFFFFFF)
|
|
SetDlgItemText( hDlg, IDC_DETAILS_SUMMARY_STATIC_EMAIL,
|
|
lpPropArray[nEmails].Value.MVSZ.LPPSZ[(nDef != 0xFFFFFFFF ? lpPropArray[nDef].Value.l : 0)]);
|
|
}
|
|
|
|
out:
|
|
if(lpPropArray)
|
|
MAPIFreeBuffer(lpPropArray);
|
|
|
|
return;
|
|
}
|
|
|
|
/*//$$***********************************************************************
|
|
* FUNCTION: fnSummaryProc
|
|
*
|
|
*
|
|
****************************************************************************/
|
|
INT_PTR CALLBACK fnSummaryProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)
|
|
{
|
|
PROPSHEETPAGE * pps;
|
|
BOOL bRet = FALSE;
|
|
|
|
pps = (PROPSHEETPAGE *) GetWindowLongPtr(hDlg, DWLP_USER);
|
|
|
|
switch(message)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
EnumChildWindows( hDlg, SetChildDefaultGUIFont, (LPARAM) 0);
|
|
SetWindowLongPtr(hDlg,DWLP_USER,lParam);
|
|
pps = (PROPSHEETPAGE *) lParam;
|
|
if (lpPAI->ulOperationType != SHOW_ONE_OFF ||
|
|
lpPAI->ulFlags & DETAILS_HideAddToWABButton)
|
|
{
|
|
HWND hwnd = GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_BUTTON_ADDTOWAB);
|
|
EnableWindow(hwnd, FALSE);
|
|
ShowWindow(hwnd, SW_HIDE);
|
|
}
|
|
if (lpPAI->ulOperationType == SHOW_ONE_OFF)
|
|
EnableWindow(GetDlgItem(GetParent(hDlg), IDOK), FALSE);
|
|
return TRUE;
|
|
}
|
|
break;
|
|
|
|
case WM_HELP:
|
|
WABWinHelp(((LPHELPINFO)lParam)->hItemHandle,
|
|
g_szWABHelpFileName,
|
|
HELP_WM_HELP,
|
|
(DWORD_PTR)(LPSTR) rgDetlsHelpIDs );
|
|
break;
|
|
|
|
case WM_CONTEXTMENU:
|
|
WABWinHelp((HWND) wParam,
|
|
g_szWABHelpFileName,
|
|
HELP_CONTEXTMENU,
|
|
(DWORD_PTR)(LPVOID) rgDetlsHelpIDs );
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch(GET_WM_COMMAND_ID(wParam, lParam))
|
|
{
|
|
case IDC_DETAILS_PERSONAL_BUTTON_ADDTOWAB:
|
|
lpPAI->nRetVal = DETAILS_ADDTOWAB;
|
|
SendMessage(GetParent(hDlg), WM_COMMAND, (WPARAM) IDCANCEL, 0);
|
|
break;
|
|
case IDCANCEL:
|
|
// This is a windows bug that prevents ESC canceling prop sheets
|
|
// which have MultiLine Edit boxes KB: Q130765
|
|
SendMessage(GetParent(hDlg),message,wParam,lParam);
|
|
break;
|
|
case IDC_DETAILS_HOME_BUTTON_URL:
|
|
ShowURL(hDlg, IDC_DETAILS_SUMMARY_STATIC_PERSONALWEB,NULL);
|
|
break;
|
|
case IDC_DETAILS_BUSINESS_BUTTON_URL:
|
|
ShowURL(hDlg, IDC_DETAILS_SUMMARY_STATIC_BUSINESSWEB,NULL);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
|
|
case WM_NOTIFY:
|
|
switch(((NMHDR FAR *)lParam)->code)
|
|
{
|
|
case PSN_SETACTIVE: //initialize
|
|
UpdateSummaryInfo(hDlg, lpPAI);
|
|
break;
|
|
|
|
case PSN_APPLY: //ok
|
|
// in case any of the extended props changed, we need to mark this flag so we wont lose data
|
|
if(lpbSomethingChanged)
|
|
(*lpbSomethingChanged) = ChangedExtDisplayInfo(lpPAI, (*lpbSomethingChanged));
|
|
if (lpPAI->nRetVal == DETAILS_RESET)
|
|
lpPAI->nRetVal = DETAILS_OK;
|
|
break;
|
|
|
|
case PSN_KILLACTIVE: //Losing activation to another page
|
|
break;
|
|
|
|
case PSN_RESET: //cancel
|
|
if (lpPAI->nRetVal == DETAILS_RESET)
|
|
lpPAI->nRetVal = DETAILS_CANCEL;
|
|
break;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
return bRet;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*//$$***************************************************************************
|
|
* FUNCTION: FillPersonalDetails(HWND)
|
|
*
|
|
* PURPOSE: Fills in the dialog items on the property sheet
|
|
*
|
|
****************************************************************************/
|
|
BOOL FillPersonalDetails(HWND hDlg, LPPROP_ARRAY_INFO lpPai, int nPropSheet, BOOL * lpbChangesMade)
|
|
{
|
|
ULONG i = 0,j = 0;
|
|
BOOL bRet = FALSE;
|
|
LPTSTR lpszDisplayName = NULL, lpszFirstName = NULL, lpszLastName = NULL;
|
|
LPTSTR lpszMiddleName = NULL, lpszNickName = NULL, lpszCompanyName = NULL;
|
|
BOOL bChangesMade = FALSE;
|
|
ID_PROP * lpidProp = NULL;
|
|
ULONG idPropCount = 0;
|
|
LPVOID lpBuffer = NULL;
|
|
BOOL bRichInfo = FALSE;
|
|
|
|
ULONG ulcPropCount = 0;
|
|
LPSPropValue lpPropArray = NULL;
|
|
|
|
SizedSPropTagArray(14, ptaUIDetlsPropsPersonal)=
|
|
{
|
|
14,
|
|
{
|
|
PR_DISPLAY_NAME,
|
|
PR_EMAIL_ADDRESS,
|
|
PR_ADDRTYPE,
|
|
PR_CONTACT_EMAIL_ADDRESSES,
|
|
PR_CONTACT_ADDRTYPES,
|
|
PR_CONTACT_DEFAULT_ADDRESS_INDEX,
|
|
PR_GIVEN_NAME,
|
|
PR_SURNAME,
|
|
PR_MIDDLE_NAME,
|
|
PR_NICKNAME,
|
|
PR_SEND_INTERNET_ENCODING,
|
|
PR_DISPLAY_NAME_PREFIX,
|
|
PR_WAB_YOMI_FIRSTNAME,
|
|
PR_WAB_YOMI_LASTNAME
|
|
}
|
|
};
|
|
|
|
if(HR_FAILED(lpPai->lpPropObj->lpVtbl->GetProps(lpPai->lpPropObj,
|
|
(LPSPropTagArray)&ptaUIDetlsPropsPersonal,
|
|
MAPI_UNICODE,
|
|
&ulcPropCount, &lpPropArray)))
|
|
goto out;
|
|
|
|
lpPai->ulFlags |= DETAILS_Initializing;
|
|
|
|
// Set the flag that this sheet was opened
|
|
lpPai->bPropSheetOpened[nPropSheet] = TRUE;
|
|
|
|
// Check the check box on the UI for whether this contact can receive rich email messages
|
|
for(i=0;i<ulcPropCount;i++)
|
|
{
|
|
if(lpPropArray[i].ulPropTag == PR_SEND_INTERNET_ENCODING)
|
|
{
|
|
//Check the check box on the UI if no value is chosen for BODY_ENCODING_HTML
|
|
// Bug 2285: wabtags.h had the wrong tag for BODY_ENCODING_HTML .. it was set to
|
|
// be the same as BODY_ENCODING_TEXT_AND_HTML instead .. hence for backward compatibility
|
|
// we have to also check for BODY_ENCODING_TEXT_AND_HTML here and then when
|
|
// saving have to set it back to BODY_ENCODING_HTML ..
|
|
|
|
int id = (lpPropArray[i].Value.l & BODY_ENCODING_HTML ||
|
|
lpPropArray[i].Value.l & BODY_ENCODING_TEXT_AND_HTML)
|
|
? BST_UNCHECKED : BST_CHECKED;
|
|
CheckDlgButton(hDlg, IDC_DETAILS_PERSONAL_CHECK_RICHINFO, id);
|
|
bRichInfo = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
// if we didnt find the PR_SEND_INTERNET_ENCODING, we want to force a save on this contact
|
|
// if the contact is writable ...
|
|
if(!bRichInfo && lpPai->ulOperationType != SHOW_ONE_OFF)
|
|
*lpbChangesMade = TRUE;
|
|
|
|
for(i=0;i<ulcPropCount;i++)
|
|
{
|
|
switch(lpPropArray[i].ulPropTag)
|
|
{
|
|
case PR_DISPLAY_NAME:
|
|
lpszDisplayName = lpPropArray[i].Value.LPSZ;
|
|
break;
|
|
case PR_GIVEN_NAME:
|
|
lpszFirstName = lpPropArray[i].Value.LPSZ;
|
|
break;
|
|
case PR_SURNAME:
|
|
lpszLastName = lpPropArray[i].Value.LPSZ;
|
|
break;
|
|
case PR_MIDDLE_NAME:
|
|
lpszMiddleName = lpPropArray[i].Value.LPSZ;
|
|
break;
|
|
case PR_NICKNAME:
|
|
lpszNickName = lpPropArray[i].Value.LPSZ;
|
|
break;
|
|
case PR_COMPANY_NAME:
|
|
lpszCompanyName = lpPropArray[i].Value.LPSZ;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*
|
|
*
|
|
* At this point we always have a display name. We need to track how this
|
|
* display name relates to F/M/L/Nick/Company
|
|
*
|
|
* So we check if
|
|
* Display Name == Nick Name
|
|
* Display Name == Company Name
|
|
* Display Name == FML
|
|
*/
|
|
|
|
// Check if Display Name was created from First Middle Last
|
|
if( (lpszFirstName && lstrlen(lpszFirstName)) ||
|
|
(lpszMiddleName && lstrlen(lpszMiddleName)) ||
|
|
(lpszLastName && lstrlen(lpszLastName)) )
|
|
{
|
|
ULONG ulSzBuf = 4*MAX_BUF_STR;
|
|
LPTSTR szBuf = LocalAlloc(LMEM_ZEROINIT, ulSzBuf*sizeof(TCHAR));
|
|
LPTSTR lpszTmp = szBuf;
|
|
|
|
if(!szBuf)
|
|
goto out;
|
|
|
|
if(!SetLocalizedDisplayName(lpszFirstName,
|
|
lpszMiddleName,
|
|
lpszLastName,
|
|
NULL, // Company Name (not needed)
|
|
NULL, // Nick Name (not needed here)
|
|
(LPTSTR *) &lpszTmp, //&szBuf,
|
|
ulSzBuf,
|
|
bDNisByLN,
|
|
NULL,
|
|
NULL))
|
|
{
|
|
//TBD - do we really want to fail here .. ???
|
|
LocalFreeAndNull(&szBuf);
|
|
DebugPrintTrace(( TEXT("SetLocalizedDisplayName failed\n")));
|
|
goto out;
|
|
}
|
|
|
|
if(lpszDisplayName && szBuf && !lstrcmp(lpszDisplayName, szBuf))
|
|
lpPai->ulFlags |= DETAILS_DNisFMLName;
|
|
else
|
|
lpPai->ulFlags &= ~DETAILS_DNisFMLName;
|
|
|
|
LocalFreeAndNull(&szBuf);
|
|
}
|
|
|
|
// if DN was not created from FML ..
|
|
if(!(lpPai->ulFlags & DETAILS_DNisFMLName) )
|
|
{
|
|
// Check if DN == NickName
|
|
if(lpszNickName)
|
|
{
|
|
if(!lstrlen(lpszDisplayName))
|
|
lpszDisplayName = lpszNickName;
|
|
|
|
if(!lstrcmp(lpszDisplayName, lpszNickName))
|
|
lpPai->ulFlags |= DETAILS_DNisNickName;
|
|
else
|
|
lpPai->ulFlags &= ~DETAILS_DNisNickName;
|
|
}
|
|
|
|
// Check if DN == Company Name
|
|
if(lpszCompanyName)
|
|
{
|
|
if(!lstrlen(lpszDisplayName))
|
|
lpszDisplayName = lpszCompanyName;
|
|
|
|
if(!lstrcmp(lpszDisplayName, lpszCompanyName))
|
|
lpPai->ulFlags |= DETAILS_DNisCompanyName;
|
|
else
|
|
lpPai->ulFlags &= ~DETAILS_DNisCompanyName;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
lpPai->ulFlags &= ~DETAILS_DNisNickName;
|
|
lpPai->ulFlags &= ~DETAILS_DNisCompanyName;
|
|
}
|
|
|
|
// if DN is none of the above and there is no FML,
|
|
// parse the DN into F and L
|
|
//
|
|
if ( !lpszFirstName &&
|
|
!lpszLastName &&
|
|
!lpszMiddleName &&
|
|
!(lpPai->ulFlags & DETAILS_DNisCompanyName) &&
|
|
!(lpPai->ulFlags & DETAILS_DNisNickName) )
|
|
{
|
|
bChangesMade = ParseDisplayName(
|
|
lpszDisplayName,
|
|
&lpszFirstName,
|
|
&lpszLastName,
|
|
NULL, // lpvRoot
|
|
&lpBuffer); // lppLocalFree
|
|
|
|
lpPai->ulFlags |= DETAILS_DNisFMLName;
|
|
}
|
|
|
|
// Set the Dialog title to reflect the display name
|
|
SetWindowPropertiesTitle(GetParent(hDlg), lpszDisplayName ? lpszDisplayName : szEmpty);
|
|
|
|
//////////////////////////
|
|
// A very inefficient and lazy way of filling the UI
|
|
// but works for now
|
|
//
|
|
for(i=0;i<idPropPersonalCount;i++)
|
|
{
|
|
for(j=0;j<ulcPropCount;j++)
|
|
{
|
|
if(lpPropArray[j].ulPropTag == idPropPersonal[i].ulPropTag)
|
|
SetDlgItemText(hDlg, idPropPersonal[i].idCtl, lpPropArray[j].Value.LPSZ);
|
|
}
|
|
}
|
|
|
|
// Add the Yomi prop data
|
|
for(j=0;j<ulcPropCount;j++)
|
|
{
|
|
if(lpPropArray[j].ulPropTag == PR_WAB_YOMI_FIRSTNAME)
|
|
SetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_STATIC_RUBYFIRST, lpPropArray[j].Value.LPSZ);
|
|
if(lpPropArray[j].ulPropTag == PR_WAB_YOMI_LASTNAME)
|
|
SetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_STATIC_RUBYLAST, lpPropArray[j].Value.LPSZ);
|
|
}
|
|
|
|
// Overwrite the first last name with out pre calculated values
|
|
if (lpszFirstName)
|
|
SetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_EDIT_FIRSTNAME, lpszFirstName);
|
|
if (lpszLastName)
|
|
SetDlgItemText(hDlg, IDC_DETAILS_PERSONAL_EDIT_LASTNAME, lpszLastName);
|
|
|
|
// Fill the Combo
|
|
SetComboDNText(hDlg, NULL, FALSE, lpszDisplayName);
|
|
|
|
{
|
|
//
|
|
// Now we fill in the Email addresses .. bunch of cases can exist in here
|
|
// Single email, multiple email, no email etc ...
|
|
//
|
|
// First we search for all the props we need to fill in the email structure
|
|
//
|
|
LPSPropValue lpPropEmail = NULL;
|
|
LPSPropValue lpPropAddrType = NULL;
|
|
LPSPropValue lpPropMVEmail = NULL;
|
|
LPSPropValue lpPropMVAddrType = NULL;
|
|
LPSPropValue lpPropDefaultIndex = NULL;
|
|
BOOL bDefaultSet = FALSE;
|
|
HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_PERSONAL_LIST);
|
|
|
|
for(i=0;i<ulcPropCount;i++)
|
|
{
|
|
switch(lpPropArray[i].ulPropTag)
|
|
{
|
|
case PR_EMAIL_ADDRESS:
|
|
lpPropEmail = &(lpPropArray[i]);
|
|
break;
|
|
case PR_ADDRTYPE:
|
|
lpPropAddrType = &(lpPropArray[i]);
|
|
break;
|
|
case PR_CONTACT_EMAIL_ADDRESSES:
|
|
lpPropMVEmail = &(lpPropArray[i]);
|
|
break;
|
|
case PR_CONTACT_ADDRTYPES:
|
|
lpPropMVAddrType = &(lpPropArray[i]);
|
|
break;
|
|
case PR_CONTACT_DEFAULT_ADDRESS_INDEX:
|
|
lpPropDefaultIndex = &(lpPropArray[i]);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Assumption:
|
|
// We must have a email address to work with even if we dont have
|
|
// multiple email addresses
|
|
if(lpPropEmail || lpPropMVEmail)
|
|
{
|
|
if(lpPropMVEmail)
|
|
{
|
|
// Assert(lpPropMVAddrType);
|
|
|
|
//Assume, if this is present, so is MVAddrType, and defaultindex
|
|
for(i=0;i<lpPropMVEmail->Value.MVSZ.cValues;i++)
|
|
{
|
|
AddLVEmailItem( hWndLV,
|
|
lpPropMVEmail->Value.MVSZ.LPPSZ[i],
|
|
lpPropMVAddrType ? ((lpPropMVAddrType->Value.MVSZ.cValues > i) ?
|
|
lpPropMVAddrType->Value.MVSZ.LPPSZ[i] : (LPTSTR)szSMTP) : (LPTSTR)szSMTP);
|
|
|
|
if ( lpPropDefaultIndex && (i == (ULONG) lpPropDefaultIndex->Value.l) )
|
|
{
|
|
// This is the default one so set it ...
|
|
SetLVDefaultEmail( hWndLV, i );
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LPTSTR lpszAddrType = NULL;
|
|
// we dont have multi-valued props yet - lets use the
|
|
// single valued ones and tag a change so that the record is
|
|
// updated ...
|
|
if (lpPropAddrType)
|
|
lpszAddrType = lpPropAddrType->Value.LPSZ;
|
|
|
|
AddLVEmailItem( hWndLV,
|
|
lpPropEmail->Value.LPSZ,
|
|
lpszAddrType);
|
|
|
|
// Flag that changes occured ...
|
|
bChangesMade = TRUE;
|
|
}
|
|
|
|
if((ListView_GetItemCount(hWndLV)>0)&&(lpPai->ulOperationType != SHOW_ONE_OFF))
|
|
{
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_REMOVE),TRUE);
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_SETDEFAULT),TRUE);
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_PERSONAL_BUTTON_EDIT),TRUE);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(!*lpbChangesMade)
|
|
*lpbChangesMade = bChangesMade;
|
|
|
|
bRet = TRUE;
|
|
|
|
out:
|
|
if(lpBuffer)
|
|
LocalFreeAndNull(&lpBuffer);
|
|
|
|
if(lpPropArray)
|
|
MAPIFreeBuffer(lpPropArray);
|
|
|
|
lpPai->ulFlags &= ~DETAILS_Initializing;
|
|
|
|
return bRet;
|
|
}
|
|
|
|
/*//$$***************************************************************************
|
|
* FUNCTION: FillHomeBusinessNotesDetailsUI(HWND)
|
|
*
|
|
* PURPOSE: Fills in the dialog items on the property sheet
|
|
*
|
|
****************************************************************************/
|
|
BOOL FillHomeBusinessNotesDetailsUI(HWND hDlg, LPPROP_ARRAY_INFO lpPai, int nPropSheet, BOOL * lpbChangesMade)
|
|
{
|
|
ULONG i = 0,j = 0;
|
|
BOOL bRet = FALSE;
|
|
BOOL bChangesMade = FALSE;
|
|
ID_PROP * lpidProp = NULL;
|
|
ULONG idPropCount = 0;
|
|
LPVOID lpBuffer = NULL;
|
|
|
|
ULONG ulcPropCount = 0;
|
|
LPSPropValue lpPropArray = NULL;
|
|
|
|
if(HR_FAILED(lpPai->lpPropObj->lpVtbl->GetProps(lpPai->lpPropObj, NULL, MAPI_UNICODE,
|
|
&ulcPropCount, &lpPropArray)))
|
|
goto out;
|
|
|
|
lpPai->ulFlags |= DETAILS_Initializing;
|
|
|
|
// Set the flag that this sheet was opened
|
|
lpPai->bPropSheetOpened[nPropSheet] = TRUE;
|
|
|
|
switch(nPropSheet)
|
|
{
|
|
/************/
|
|
case propHome:
|
|
idPropCount = idPropHomeCount;
|
|
lpidProp = idPropHome;
|
|
lpidProp[idPropHomePostalID].ulPropTag = PR_WAB_POSTALID;
|
|
goto FillProp;
|
|
/************/
|
|
case propBusiness:
|
|
idPropCount = idPropBusinessCount;
|
|
lpidProp = idPropBusiness;
|
|
lpidProp[idPropBusIPPhone].ulPropTag = PR_WAB_IPPHONE;
|
|
lpidProp[idPropBusPostalID].ulPropTag = PR_WAB_POSTALID;
|
|
goto FillProp;
|
|
/************/
|
|
case propNotes:
|
|
{
|
|
// See if this is a folder member and update the folder name on this tab
|
|
BOOL bParent = FALSE;
|
|
if( lpPai->ulOperationType != SHOW_DETAILS )
|
|
{
|
|
SetDlgItemText(hDlg, IDC_DETAILS_NOTES_STATIC_FOLDER, szEmpty);
|
|
}
|
|
else
|
|
{
|
|
for(i=0;i<ulcPropCount;i++)
|
|
{
|
|
if(lpPropArray[i].ulPropTag == PR_WAB_FOLDER_PARENT || lpPropArray[i].ulPropTag == PR_WAB_FOLDER_PARENT_OLDPROP)
|
|
{
|
|
LPSBinary lpsbParent = &(lpPropArray[i].Value.MVbin.lpbin[0]);
|
|
LPWABFOLDER lpWABFolder = FindWABFolder((LPIAB)lpPai->lpIAB, lpsbParent, NULL, NULL);
|
|
if(lpWABFolder) // note if we didnt find the folder then the default TEXT("Shared Contacts") name works fine
|
|
{
|
|
SetDlgItemText(hDlg, IDC_DETAILS_NOTES_STATIC_FOLDER, lpWABFolder->lpFolderName);
|
|
bParent = TRUE;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if(!bParent && !bDoesThisWABHaveAnyUsers((LPIAB)lpPai->lpIAB))
|
|
{
|
|
TCHAR sz[MAX_PATH];
|
|
LoadString(hinstMapiX, idsContacts, sz, CharSizeOf(sz));
|
|
SetDlgItemText(hDlg, IDC_DETAILS_NOTES_STATIC_FOLDER, sz);
|
|
}
|
|
|
|
// Find out all the groups in which this contact is a member ...
|
|
//
|
|
// if this is not a known entry id but is still non NULL ..
|
|
//
|
|
if( (0 == IsWABEntryID(lpPai->cbEntryID, lpPai->lpEntryID, NULL,NULL,NULL, NULL, NULL)) &&
|
|
lpPai->cbEntryID && lpPai->lpEntryID)
|
|
{
|
|
// Only do this for WAB contacts
|
|
TCHAR szBuf[MAX_BUF_STR];
|
|
SPropertyRestriction PropRes = {0};
|
|
SPropValue sp = {0};
|
|
HRESULT hr = E_FAIL;
|
|
ULONG ulcCount = 0;
|
|
LPSBinary rgsbEntryIDs = NULL;
|
|
|
|
sp.ulPropTag = PR_OBJECT_TYPE;
|
|
sp.Value.l = MAPI_DISTLIST;
|
|
|
|
PropRes.ulPropTag = PR_OBJECT_TYPE;
|
|
PropRes.relop = RELOP_EQ;
|
|
PropRes.lpProp = &sp;
|
|
|
|
szBuf[0] = TEXT('\0');
|
|
|
|
// BUGBUG <JasonSo>: Need to pass in the current container here...
|
|
hr = FindRecords( ((LPIAB)lpPai->lpIAB)->lpPropertyStore->hPropertyStore,
|
|
NULL, 0, TRUE, &PropRes, &ulcCount, &rgsbEntryIDs);
|
|
|
|
if(!HR_FAILED(hr) && ulcCount)
|
|
{
|
|
// Open all the groups and look at their contents
|
|
ULONG i,j,k;
|
|
|
|
for(i=0;i<ulcCount;i++)
|
|
{
|
|
ULONG ulcValues = 0;
|
|
LPSPropValue lpProps = NULL;
|
|
LPTSTR lpszName = NULL;
|
|
|
|
hr = HrGetPropArray(lpPai->lpIAB, NULL,
|
|
rgsbEntryIDs[i].cb, (LPENTRYID) rgsbEntryIDs[i].lpb,
|
|
MAPI_UNICODE,
|
|
&ulcValues, &lpProps);
|
|
if(HR_FAILED(hr))
|
|
continue;
|
|
|
|
for(j=0;j<ulcValues;j++)
|
|
{
|
|
if (lpProps[j].ulPropTag == PR_DISPLAY_NAME)
|
|
{
|
|
lpszName = lpProps[j].Value.LPSZ;
|
|
break;
|
|
}
|
|
}
|
|
|
|
for(j=0;j<ulcValues;j++)
|
|
{
|
|
if(lpProps[j].ulPropTag == PR_WAB_DL_ENTRIES)
|
|
{
|
|
// Look at each entry in the PR_WAB_DL_ENTRIES and recursively check it.
|
|
for (k = 0; k < lpProps[j].Value.MVbin.cValues; k++)
|
|
{
|
|
ULONG cbEID = lpProps[j].Value.MVbin.lpbin[k].cb;
|
|
LPENTRYID lpEID = (LPENTRYID) lpProps[j].Value.MVbin.lpbin[k].lpb;
|
|
if (cbEID == lpPai->cbEntryID) // <TBD> we should be checking if its a wab entryid
|
|
// but we'll just compare sizes for now ...
|
|
{
|
|
if(!memcmp(lpPai->lpEntryID, lpEID, cbEID))
|
|
{
|
|
if( (lstrlen(szCRLF) + lstrlen(szBuf) + lstrlen(lpszName) + 1)<CharSizeOf(szBuf))
|
|
{
|
|
StrCatBuff(szBuf, lpszName, ARRAYSIZE(szBuf));
|
|
StrCatBuff(szBuf, szCRLF, ARRAYSIZE(szBuf));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break; // just wanted to look at PR_WAB_DL_ENTRIES
|
|
}
|
|
} // for (j...
|
|
|
|
if(lpProps)
|
|
MAPIFreeBuffer(lpProps);
|
|
|
|
} // for(i...
|
|
|
|
} ///if ..
|
|
|
|
FreeEntryIDs(((LPIAB)lpPai->lpIAB)->lpPropertyStore->hPropertyStore,
|
|
ulcCount,
|
|
rgsbEntryIDs);
|
|
|
|
if(lstrlen(szBuf))
|
|
SetDlgItemText(hDlg, IDC_DETAILS_NOTES_EDIT_GROUPS, szBuf);
|
|
|
|
}
|
|
}
|
|
idPropCount = idPropNotesCount;
|
|
lpidProp = idPropNotes;
|
|
|
|
/************/
|
|
FillProp:
|
|
// A very inefficient and lazy way of filling the UI
|
|
for(i=0;i<idPropCount;i++)
|
|
{
|
|
for(j=0;j<ulcPropCount;j++)
|
|
{
|
|
if(lpPropArray[j].ulPropTag == lpidProp[i].ulPropTag)
|
|
{
|
|
if(lpidProp[i].ulPropTag == PR_GENDER)
|
|
{
|
|
SendDlgItemMessage(hDlg, IDC_DETAILS_HOME_COMBO_GENDER, CB_SETCURSEL,
|
|
(WPARAM) lpPropArray[j].Value.i, 0);
|
|
}
|
|
else
|
|
if( lpidProp[i].ulPropTag == PR_WAB_POSTALID )
|
|
{
|
|
if(nPropSheet == propHome)
|
|
CheckDlgButton( hDlg, lpidProp[i].idCtl,
|
|
(lpPropArray[j].Value.l == ADDRESS_HOME)?BST_CHECKED:BST_UNCHECKED);
|
|
else if(nPropSheet == propBusiness)
|
|
CheckDlgButton( hDlg, lpidProp[i].idCtl,
|
|
(lpPropArray[j].Value.l == ADDRESS_WORK)?BST_CHECKED:BST_UNCHECKED);
|
|
}
|
|
else
|
|
SetDlgItemText(hDlg, lpidProp[i].idCtl, lpPropArray[j].Value.LPSZ);
|
|
}
|
|
}
|
|
|
|
}
|
|
break;
|
|
}
|
|
|
|
bRet = TRUE;
|
|
out:
|
|
if(lpBuffer)
|
|
LocalFreeAndNull(&lpBuffer);
|
|
|
|
if(lpPropArray)
|
|
MAPIFreeBuffer(lpPropArray);
|
|
|
|
lpPai->ulFlags &= ~DETAILS_Initializing;
|
|
|
|
return bRet;
|
|
}
|
|
|
|
|
|
/*
|
|
- FreeCertList - Frees the list of certificate items in memory
|
|
-
|
|
*
|
|
*/
|
|
void FreeCertList(LPCERT_ITEM * lppCItem)
|
|
{
|
|
LPCERT_ITEM lpItem = NULL;
|
|
if(!lppCItem)
|
|
return;
|
|
lpItem = *lppCItem;
|
|
while(lpItem)
|
|
{
|
|
*lppCItem = lpItem->lpNext;
|
|
FreeCertdisplayinfo(lpItem->lpCDI);
|
|
if (lpItem->pcCert)
|
|
CertFreeCertificateContext(lpItem->pcCert);
|
|
LocalFree(lpItem);
|
|
lpItem = *lppCItem;
|
|
}
|
|
*lppCItem = NULL;
|
|
}
|
|
|
|
|
|
/*//$$***************************************************************************
|
|
* FUNCTION: FillCertTridentConfDetailsUI(HWND)
|
|
*
|
|
* PURPOSE: Fills in the dialog items on the property sheet
|
|
*
|
|
****************************************************************************/
|
|
BOOL FillCertTridentConfDetailsUI(HWND hDlg, LPPROP_ARRAY_INFO lpPai, int nPropSheet, BOOL * lpbChangesMade)
|
|
{
|
|
ULONG i = 0,j = 0;
|
|
BOOL bRet = FALSE;
|
|
BOOL bChangesMade = FALSE;
|
|
ID_PROP * lpidProp = NULL;
|
|
ULONG idPropCount = 0;
|
|
LPVOID lpBuffer = NULL;
|
|
|
|
ULONG ulcPropCount = 0;
|
|
LPSPropValue lpPropArray = NULL;
|
|
|
|
if(HR_FAILED(lpPai->lpPropObj->lpVtbl->GetProps(lpPai->lpPropObj, NULL, MAPI_UNICODE,
|
|
&ulcPropCount, &lpPropArray)))
|
|
goto out;
|
|
|
|
lpPai->ulFlags |= DETAILS_Initializing;
|
|
|
|
// Set the flag that this sheet was opened
|
|
lpPai->bPropSheetOpened[nPropSheet] = TRUE;
|
|
|
|
switch(nPropSheet)
|
|
{
|
|
case propCert:
|
|
{
|
|
//
|
|
// Now we fill in the Certificate information
|
|
// Cases that can exist are
|
|
// - no certificates
|
|
// - certificates
|
|
//
|
|
// First we search for all the props we need to fill in the email structure
|
|
//
|
|
LPSPropValue lpPropMVCert = NULL;
|
|
BOOL bDefaultSet = FALSE;
|
|
HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_CERT_LIST);
|
|
HRESULT hr = S_OK;
|
|
for(i=0;i<ulcPropCount;i++)
|
|
{
|
|
if(lpPropArray[i].ulPropTag == PR_USER_X509_CERTIFICATE)
|
|
{
|
|
lpPropMVCert = &(lpPropArray[i]);
|
|
break;
|
|
}
|
|
}
|
|
// Fill the combo with email addresses
|
|
FillCertComboWithEmailAddresses(hDlg, lpPai, NULL);
|
|
hr = HrSetCertInfoInUI(hDlg, lpPropMVCert, lpPai);
|
|
if(hr == MAPI_E_NOT_FOUND && lpPropMVCert)
|
|
{
|
|
// The cert prop seems to contain bogus data .. need to nuke it
|
|
// 48750 : if there is no cert data, dont show a cert icon ..
|
|
// Problem is that we're not entirely sure that just because we couldnt
|
|
// interpret the data that it's invalid, what if there is aata we don't interpret .. ?
|
|
}
|
|
if(lpPropMVCert)
|
|
{
|
|
// Enable the combo, the properties button, and the export button
|
|
//EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_LIST),TRUE);
|
|
EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_COMBO),TRUE);
|
|
//EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_BUTTON_PROPERTIES),TRUE);
|
|
//EnableWindow(GetDlgItem(hDlg,IDC_DETAILS_CERT_BUTTON_EXPORT),TRUE);
|
|
}
|
|
}
|
|
break;
|
|
/************/
|
|
case propTrident:
|
|
{
|
|
HrInit(lpPai->lpIWABDocHost, hDlg, IDC_TRIDENT_WINDOW, dhbNone);
|
|
{
|
|
ULONG i;
|
|
LPTSTR lp = NULL, lpURL = NULL, lpLabel = NULL;
|
|
// Find the labeledURI property and parse it
|
|
// This string property contains a URL followed by spaces followed by the label (RFC 2079)
|
|
for(i=0;i<ulcPropCount;i++)
|
|
{
|
|
if(lpPropArray[i].ulPropTag == PR_WAB_LDAP_LABELEDURI)
|
|
{
|
|
// isolate the URL and the label
|
|
// The URL is followed by spaces
|
|
lpURL = lp = lpPropArray[i].Value.LPSZ;
|
|
while(lp && *lp)
|
|
{
|
|
if (IsSpace(lp))
|
|
{
|
|
lpLabel = CharNext(lp);
|
|
*lp = '\0';
|
|
break;
|
|
}
|
|
else
|
|
lp = CharNext(lp);
|
|
}
|
|
// The above is the URL
|
|
// Label starts at first non space char
|
|
while(lpLabel && IsSpace(lpLabel))
|
|
lpLabel = CharNext(lpLabel);
|
|
}
|
|
// Since the trident pane is shown first, update the windows title
|
|
if(lpPropArray[i].ulPropTag == PR_DISPLAY_NAME)
|
|
{
|
|
lp = lpPropArray[i].Value.LPSZ;
|
|
if(lstrlen(lp))
|
|
SetWindowPropertiesTitle(GetParent(hDlg), lp);
|
|
}
|
|
}
|
|
if(lpLabel && lstrlen(lpLabel))
|
|
SetDlgItemText(hDlg, IDC_DETAILS_TRIDENT_STATIC_CAPTION, lpLabel);
|
|
if(lpURL && lstrlen(lpURL))
|
|
{
|
|
if(HR_FAILED(HrLoadURL(lpPai->lpIWABDocHost, lpURL)))
|
|
{
|
|
// remove this property sheet and set the focus to the first prop sheet
|
|
PropSheet_RemovePage(hDlg,lpPai->ulTridentPageIndex,NULL);
|
|
PropSheet_SetCurSel(hDlg, NULL, 0);
|
|
}
|
|
else
|
|
EnableWindow(GetDlgItem(GetParent(hDlg), IDOK), FALSE);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
/************/
|
|
case propConferencing:
|
|
{
|
|
HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_NTMTG_LIST_SERVERS);
|
|
HWND hWndCombo = GetDlgItem(hDlg, IDC_DETAILS_NTMTG_COMBO_EMAIL);
|
|
|
|
FillComboWithEmailAddresses(lpPai, hWndCombo, NULL);
|
|
|
|
// Fill in the conferencing related properties
|
|
for(j=0;j<ulcPropCount;j++)
|
|
{
|
|
if(lpPropArray[j].ulPropTag == PR_WAB_CONF_SERVERS)
|
|
{
|
|
LPSPropValue lpProp = &(lpPropArray[j]);
|
|
for(i=0;i<lpProp->Value.MVSZ.cValues; i++)
|
|
{
|
|
if(lstrlen(lpProp->Value.MVSZ.LPPSZ[i]) < lstrlen(szCallto))
|
|
continue; //ignore this one
|
|
|
|
// if this is a callto
|
|
if(!StrCmpNI(lpProp->Value.MVSZ.LPPSZ[i], szCallto, lstrlen(szCallto)))
|
|
{
|
|
LV_ITEM lvi = {0};
|
|
LPSERVER_ITEM lpSI = LocalAlloc(LMEM_ZEROINIT, sizeof(SERVER_ITEM));
|
|
if(lpSI)
|
|
{
|
|
ULONG cch = lstrlen(lpProp->Value.MVSZ.LPPSZ[i])+1;
|
|
LPTSTR lp = LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*cch);
|
|
ULONG cchEmail = lstrlen(lpProp->Value.MVSZ.LPPSZ[i])+1;
|
|
LPTSTR lpEmail = LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*cchEmail);
|
|
if(lp && lpEmail)
|
|
{
|
|
lvi.mask = LVIF_TEXT | LVIF_PARAM;
|
|
StrCpyN(lp,lpProp->Value.MVSZ.LPPSZ[i],cch);
|
|
*lpEmail = '\0';
|
|
|
|
{
|
|
// isolate just the server name by terminating
|
|
// at the next '/'
|
|
LPTSTR lp1 = lp + lstrlen(szCallto);
|
|
StrCpyN(lp, lp1, cch);
|
|
lp1 = lp;
|
|
while(lp1 && *lp1 && *lp1!='/')
|
|
lp1 = CharNext(lp1);
|
|
if(*lp1 == '/')
|
|
{
|
|
StrCpyN(lpEmail, lp1+1, cchEmail);
|
|
*lp1 = '\0';
|
|
}
|
|
// Now lpEmail contains the email text ...
|
|
// Walk along lpEmail till we hit the next /,?.or \0 and terminate
|
|
lp1 = lpEmail;
|
|
while(lp1 && *lp1 && *lp1!='/' && *lp1!='?')
|
|
lp1 = CharNext(lp1);
|
|
if(*lp1 == '/' || *lp1 == '?')
|
|
*lp1 = '\0';
|
|
}
|
|
lvi.pszText = lp;
|
|
lpSI->lpServer = lp;
|
|
lpSI->lpEmail = lpEmail;
|
|
lvi.lParam = (LPARAM) lpSI;
|
|
lvi.cchTextMax = lstrlen(lp)+1;
|
|
lvi.iItem = ListView_GetItemCount(hWndLV);
|
|
lvi.iSubItem = 0;
|
|
ListView_InsertItem(hWndLV, &lvi);
|
|
ListView_SetItemText(hWndLV, lvi.iItem, 1, lpEmail);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
LVSelectItem(hWndLV, 0);
|
|
break;
|
|
}
|
|
}
|
|
for(j=0;j<ulcPropCount;j++)
|
|
{
|
|
if(lpPropArray[j].ulPropTag == PR_WAB_CONF_BACKUP_INDEX)
|
|
{
|
|
lpPai->nBackupServerIndex = lpPropArray[j].Value.l;
|
|
lpPai->szBackupServerName[0] = TEXT('\0');
|
|
SetBackupServer(hDlg, lpPai, lpPai->nBackupServerIndex, FALSE);
|
|
}
|
|
else if(lpPropArray[j].ulPropTag == PR_WAB_CONF_DEFAULT_INDEX)
|
|
{
|
|
lpPai->nDefaultServerIndex = lpPropArray[j].Value.l;
|
|
lpPai->szDefaultServerName[0] = TEXT('\0');
|
|
SetDefaultServer(hDlg, lpPai, lpPai->nDefaultServerIndex, TRUE);
|
|
}
|
|
}
|
|
|
|
// For LDAP servers we will have a single item in PR_SERVERS and no default, backup etc
|
|
// So if there is a single item available, force the default setting
|
|
if(ListView_GetItemCount(hWndLV) == 1 && lpPai->nDefaultServerIndex == -1)
|
|
{
|
|
LV_ITEM lvi = {0};
|
|
lvi.mask = LVIF_PARAM;
|
|
lvi.iItem = 0;
|
|
if(ListView_GetItem(hWndLV, &lvi) && lvi.lParam)
|
|
{
|
|
LPSERVER_ITEM lpSI = (LPSERVER_ITEM) lvi.lParam;
|
|
lpPai->nDefaultServerIndex = 0;
|
|
StrCpyN(lpPai->szDefaultServerName, lpSI->lpServer, lpPai->cchDefaultServerName);
|
|
SetDefaultServer(hDlg, lpPai, lpPai->nDefaultServerIndex, TRUE);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
bRet = TRUE;
|
|
out:
|
|
if(lpBuffer)
|
|
LocalFreeAndNull(&lpBuffer);
|
|
|
|
if(lpPropArray)
|
|
MAPIFreeBuffer(lpPropArray);
|
|
|
|
lpPai->ulFlags &= ~DETAILS_Initializing;
|
|
|
|
return bRet;
|
|
}
|
|
|
|
/*
|
|
- HrAddEmailToObj
|
|
- Adds a single Email to the PropObj
|
|
*
|
|
*
|
|
*/
|
|
HRESULT HrAddEmailToObj(LPPROP_ARRAY_INFO lpPai, LPTSTR szEmail, LPTSTR szAddrType)
|
|
{
|
|
ULONG ulcProps = 0, i =0;
|
|
LPSPropValue lpProps = 0;
|
|
HRESULT hr = S_OK;
|
|
ULONG nMVEmailAddress = NOT_FOUND, nMVAddrTypes = NOT_FOUND, nEmailAddress = NOT_FOUND;
|
|
ULONG nAddrType = NOT_FOUND, nDefaultIndex = NOT_FOUND;
|
|
|
|
if(HR_FAILED(hr = lpPai->lpPropObj->lpVtbl->GetProps(lpPai->lpPropObj, NULL, MAPI_UNICODE,
|
|
&ulcProps, &lpProps)))
|
|
goto out;
|
|
|
|
// Check if the PR_CONTACT_EMAIL_ADDRESSES already exists ..
|
|
// if it does, tag the email onto it
|
|
// if it doesnt and there is no pr_email_address, we create both
|
|
// else if there is PR_EMAIL address then we cretae contact_email_addresses
|
|
|
|
for(i=0;i<ulcProps;i++)
|
|
{
|
|
switch(lpProps[i].ulPropTag)
|
|
{
|
|
case PR_EMAIL_ADDRESS:
|
|
nEmailAddress = i;
|
|
break;
|
|
case PR_ADDRTYPE:
|
|
nAddrType = i;
|
|
break;
|
|
case PR_CONTACT_EMAIL_ADDRESSES:
|
|
nMVEmailAddress = i;
|
|
break;
|
|
case PR_CONTACT_ADDRTYPES:
|
|
nMVAddrTypes = i;
|
|
break;
|
|
case PR_CONTACT_DEFAULT_ADDRESS_INDEX:
|
|
nDefaultIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// if no e-mail address, just add the given prop as e-mail address and in mv e-mail addresses
|
|
if(nEmailAddress == NOT_FOUND)
|
|
{
|
|
SPropValue spv[5];
|
|
spv[0].ulPropTag = PR_EMAIL_ADDRESS;
|
|
spv[0].Value.LPSZ = szEmail;
|
|
spv[1].ulPropTag = PR_ADDRTYPE;
|
|
spv[1].Value.LPSZ = szAddrType;
|
|
spv[2].ulPropTag = PR_CONTACT_EMAIL_ADDRESSES;
|
|
spv[2].Value.MVSZ.cValues = 1;
|
|
spv[2].Value.MVSZ.LPPSZ = LocalAlloc(LMEM_ZEROINIT, sizeof(LPTSTR));
|
|
if(spv[2].Value.MVSZ.LPPSZ)
|
|
spv[2].Value.MVSZ.LPPSZ[0] = szEmail;
|
|
spv[3].ulPropTag = PR_CONTACT_ADDRTYPES;
|
|
spv[3].Value.MVSZ.cValues = 1;
|
|
spv[3].Value.MVSZ.LPPSZ = LocalAlloc(LMEM_ZEROINIT, sizeof(LPTSTR));
|
|
if(spv[3].Value.MVSZ.LPPSZ)
|
|
spv[3].Value.MVSZ.LPPSZ[0] = szAddrType;
|
|
spv[4].ulPropTag = PR_CONTACT_DEFAULT_ADDRESS_INDEX;
|
|
spv[4].Value.l = 0;
|
|
hr = lpPai->lpPropObj->lpVtbl->SetProps(lpPai->lpPropObj, 5, (LPSPropValue)&spv, NULL);
|
|
if(spv[2].Value.MVSZ.LPPSZ)
|
|
LocalFree(spv[2].Value.MVSZ.LPPSZ);
|
|
if(spv[3].Value.MVSZ.LPPSZ)
|
|
LocalFree(spv[3].Value.MVSZ.LPPSZ);
|
|
goto out;
|
|
}
|
|
else
|
|
if(nMVEmailAddress == NOT_FOUND)
|
|
{
|
|
// we have an e-mail address but no contact-email-addresses
|
|
// so we will need to create the contact e-mail addresses
|
|
SPropValue spv[3];
|
|
spv[0].ulPropTag = PR_CONTACT_EMAIL_ADDRESSES;
|
|
spv[0].Value.MVSZ.cValues = 2;
|
|
spv[0].Value.MVSZ.LPPSZ = LocalAlloc(LMEM_ZEROINIT, sizeof(LPTSTR)*2);
|
|
if(spv[0].Value.MVSZ.LPPSZ)
|
|
{
|
|
spv[0].Value.MVSZ.LPPSZ[0] = lpProps[nEmailAddress].Value.LPSZ;
|
|
spv[0].Value.MVSZ.LPPSZ[1] = szEmail;
|
|
}
|
|
spv[1].ulPropTag = PR_CONTACT_ADDRTYPES;
|
|
spv[1].Value.MVSZ.cValues = 2;
|
|
spv[1].Value.MVSZ.LPPSZ = LocalAlloc(LMEM_ZEROINIT, sizeof(LPTSTR)*2);
|
|
if(spv[1].Value.MVSZ.LPPSZ)
|
|
{
|
|
spv[1].Value.MVSZ.LPPSZ[0] = (nAddrType == NOT_FOUND) ? (LPTSTR)szSMTP : lpProps[nAddrType].Value.LPSZ;
|
|
spv[1].Value.MVSZ.LPPSZ[1] = szAddrType;
|
|
}
|
|
spv[2].ulPropTag = PR_CONTACT_DEFAULT_ADDRESS_INDEX;
|
|
spv[2].Value.l = 0;
|
|
hr = lpPai->lpPropObj->lpVtbl->SetProps(lpPai->lpPropObj, 3, (LPSPropValue)&spv, NULL);
|
|
if(spv[0].Value.MVSZ.LPPSZ)
|
|
LocalFree(spv[0].Value.MVSZ.LPPSZ);
|
|
if(spv[1].Value.MVSZ.LPPSZ)
|
|
LocalFree(spv[1].Value.MVSZ.LPPSZ);
|
|
goto out;
|
|
}
|
|
else
|
|
{
|
|
// tag on the new props to the end of the existing contact_address_types
|
|
if(HR_FAILED(hr = AddPropToMVPString(lpProps,ulcProps, nMVEmailAddress, szEmail)))
|
|
{
|
|
DebugPrintError(( TEXT("AddPropToMVString Email failed: %x"),hr));
|
|
goto out;
|
|
}
|
|
|
|
if(HR_FAILED(hr = AddPropToMVPString(lpProps, ulcProps, nMVAddrTypes, szAddrType)))
|
|
{
|
|
DebugPrintError(( TEXT("AddPropToMVString AddrType failed: %x"),hr));
|
|
goto out;
|
|
}
|
|
hr = lpPai->lpPropObj->lpVtbl->SetProps(lpPai->lpPropObj, ulcProps, lpProps, NULL);
|
|
}
|
|
|
|
out:
|
|
FreeBufferAndNull(&lpProps);
|
|
return hr;
|
|
}
|
|
|
|
/*
|
|
- ShowHideMapButton
|
|
-
|
|
* The Expedia maps only work for US addresses right now .. therefore, if the current system locale
|
|
* is not English-US, we will hide the button since we can't deal with international stuff just yet
|
|
*/
|
|
void ShowHideMapButton(HWND hWndButton)
|
|
{
|
|
LCID lcid = GetUserDefaultLCID();
|
|
|
|
switch (lcid)
|
|
{
|
|
case 0x0804: //chinese
|
|
// case 0x0c04: //chinese - hongkong
|
|
case 0x0411: //japanese
|
|
case 0x0412: //korean
|
|
case 0x0404: //taiwan
|
|
EnableWindow(hWndButton, FALSE);
|
|
ShowWindow(hWndButton, SW_HIDE);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*
|
|
- ShowExpediaMAP
|
|
- if there is sufficient address info in the supplied prop-obj, generate an expedia URL and shell exec it
|
|
* Expedia currently handles US addresses differently from international ones so need to figure that one out <TBD>
|
|
* bHome - TRUE if this is a home address
|
|
*/
|
|
|
|
// All spaces need to be replaced by '+'s
|
|
//
|
|
// Next two strings moved to resources
|
|
// const LPTSTR szExpediaTemplate = TEXT("http://www.expediamaps.com/default.asp?Street=%1&City=%2&State=%4&Zip=%3");
|
|
// const LPTSTR szExpediaIntlTemplate = TEXT("http://www.expediamaps.com/default.asp?Place=%2,%5"); //city,country
|
|
enum
|
|
{
|
|
prStreet=0,
|
|
prCity,
|
|
prZip,
|
|
prState,
|
|
prCountry,
|
|
prAddressMax,
|
|
};
|
|
void ShowExpediaMAP(HWND hDlg, LPMAPIPROP lpPropObj, BOOL bHome)
|
|
{
|
|
ULONG ulcProps = 0;
|
|
LPSPropValue lpProps = NULL;
|
|
LPSPropTagArray lpta = (bHome ? (LPSPropTagArray)&ptaUIDetlsPropsHome : (LPSPropTagArray)&ptaUIDetlsPropsBusiness);
|
|
|
|
if(!HR_FAILED(lpPropObj->lpVtbl->GetProps( lpPropObj, lpta, MAPI_UNICODE, &ulcProps, &lpProps)))
|
|
{
|
|
LPTSTR lp[prAddressMax], lpURL = NULL;
|
|
ULONG i,j, ulCount = 0;
|
|
BOOL bUSAddress = FALSE;
|
|
|
|
for(i=0;i<prAddressMax;i++)
|
|
{
|
|
if(lpProps[i].ulPropTag == lpta->aulPropTag[i])
|
|
{
|
|
ulCount++;
|
|
lp[i] = lpProps[i].Value.LPSZ;
|
|
// we need to replace all the spaces in these strings with '+'
|
|
{
|
|
LPTSTR lpTemp = lp[i];
|
|
// need to knock out CRLFs
|
|
while(lpTemp && *lpTemp)
|
|
{
|
|
if(*lpTemp == '\r')
|
|
{
|
|
*lpTemp = '\0';
|
|
break;
|
|
}
|
|
lpTemp = CharNext(lpTemp);
|
|
}
|
|
lpTemp = lp[i];
|
|
|
|
while(lpTemp && *lpTemp)
|
|
{
|
|
if(IsSpace(lpTemp))
|
|
{
|
|
LPTSTR lpTemp2 = lpTemp;
|
|
lpTemp = CharNext(lpTemp);
|
|
*lpTemp2 = '+';
|
|
if(lpTemp != lpTemp2+1)
|
|
StrCpyN(lpTemp2+1, lpTemp, lstrlen(lpTemp)+1);
|
|
lpTemp = lpTemp2;
|
|
}
|
|
lpTemp = CharNext(lpTemp);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
lp[i] = szEmpty;
|
|
}
|
|
// <TBD> - Determine if this address is a US address or not ..
|
|
if( !lstrlen(lp[prCountry]) || //no country - assume it's US
|
|
!lstrcmpi(lp[prCountry], TEXT("US")) ||
|
|
!lstrcmpi(lp[prCountry], TEXT("U.S.")) ||
|
|
!lstrcmpi(lp[prCountry], TEXT("USA")) ||
|
|
!lstrcmpi(lp[prCountry], TEXT("U.S.A.")) ||
|
|
!lstrcmpi(lp[prCountry], TEXT("America")) ||
|
|
!lstrcmpi(lp[prCountry], TEXT("United States")) ||
|
|
!lstrcmpi(lp[prCountry], TEXT("United States of America")) )
|
|
{
|
|
bUSAddress = TRUE;
|
|
}
|
|
if( (bUSAddress && (!lstrlen(lp[prStreet]) || ulCount<2)) ||
|
|
(!bUSAddress && !lstrlen(lp[prCity]) && !lstrlen(lp[prCountry])) )
|
|
{
|
|
ShowMessageBox(hDlg, idsInsufficientAddressInfo, MB_ICONINFORMATION);
|
|
}
|
|
else
|
|
{
|
|
TCHAR szText[MAX_BUF_STR] = {0};
|
|
TCHAR *pchWorldAddr = NULL;
|
|
LoadString(hinstMapiX, bUSAddress ? idsExpediaURL : idsExpediaIntlURL, szText, MAX_BUF_STR);
|
|
|
|
if(!bUSAddress )
|
|
{
|
|
//IE6 we need to change a little string for World map in Expedia
|
|
ULONG cchWorldAddr = lstrlen(lp[prStreet]) + lstrlen(lp[prCity]) +
|
|
lstrlen(lp[prState]) + lstrlen(lp[prCountry]) + 20;
|
|
if(pchWorldAddr = LocalAlloc(LMEM_ZEROINIT, cchWorldAddr*sizeof(pchWorldAddr[0]))) // we need add also space and commas
|
|
{
|
|
BOOL fAddComma = FALSE;
|
|
|
|
/* if(lstrlen(lp[prStreet]))
|
|
{
|
|
StrCatBuff(pchWorldAddr, lp[prStreet], cchWorldAddr);
|
|
fAddComma = TRUE;
|
|
}*/
|
|
|
|
if(lstrlen(lp[prCity]))
|
|
{
|
|
if(fAddComma)
|
|
StrCatBuff(pchWorldAddr, TEXT(", "), cchWorldAddr);
|
|
StrCatBuff(pchWorldAddr, lp[prCity], cchWorldAddr);
|
|
fAddComma = TRUE;
|
|
|
|
}
|
|
|
|
if(lstrlen(lp[prState]))
|
|
{
|
|
if(fAddComma)
|
|
StrCatBuff(pchWorldAddr, TEXT(", "), cchWorldAddr);
|
|
StrCatBuff(pchWorldAddr, lp[prState], cchWorldAddr);
|
|
fAddComma = TRUE;
|
|
|
|
}
|
|
if(lstrlen(lp[prCountry]))
|
|
{
|
|
if(fAddComma)
|
|
StrCatBuff(pchWorldAddr, TEXT(", "), cchWorldAddr);
|
|
StrCatBuff(pchWorldAddr, lp[prCountry], cchWorldAddr);
|
|
fAddComma = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
lp[prCountry] = pchWorldAddr;
|
|
}
|
|
|
|
if ( FormatMessage( FORMAT_MESSAGE_FROM_STRING |
|
|
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
FORMAT_MESSAGE_ARGUMENT_ARRAY,
|
|
szText,
|
|
0, // stringid
|
|
0, // dwLanguageId
|
|
(LPTSTR)&lpURL, // output buffer
|
|
0,
|
|
(va_list *)lp))
|
|
{
|
|
//LPTSTR lpProperURL = NULL;
|
|
//DWORD dw = lstrlen(lpURL)*3+1;
|
|
DebugTrace( TEXT("Expedia URL: %s\n"),lpURL);
|
|
//Need to canoncolize this URL just in case it has unsafe characters in it
|
|
/*
|
|
if(lpProperURL = LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*dw)) // 3times bigger should be big enough
|
|
{
|
|
if(!InternetCanonicalizeUrlA(lpURL, lpProperURL, &dw, 0))
|
|
DebugTrace( TEXT("Error converting URL:%d\n"),GetLastError());
|
|
if(lpProperURL && lstrlen(lpProperURL))
|
|
{
|
|
LocalFree(lpURL);
|
|
lpURL = lpProperURL;
|
|
}
|
|
}
|
|
*/
|
|
ShowURL(hDlg, 0, lpURL);
|
|
LocalFreeAndNull(&lpURL);
|
|
if(pchWorldAddr)
|
|
LocalFreeAndNull(&pchWorldAddr);
|
|
}
|
|
}
|
|
MAPIFreeBuffer(lpProps);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*//$$***********************************************************************
|
|
* FUNCTION: fnRubyProc
|
|
*
|
|
- WinProc for the RUBY dialog that lets the user enter the ruby first and last name
|
|
*
|
|
****************************************************************************/
|
|
enum
|
|
{
|
|
sFirst=0,
|
|
sLast,
|
|
sYomiFirst,
|
|
sYomiLast,
|
|
sMax
|
|
};
|
|
|
|
int rgIdPropPersonalRuby[] =
|
|
{
|
|
IDC_DETAILS_PERSONAL_EDIT_FIRSTNAME,
|
|
IDC_DETAILS_PERSONAL_EDIT_LASTNAME,
|
|
IDC_DETAILS_PERSONAL_STATIC_RUBYFIRST,
|
|
IDC_DETAILS_PERSONAL_STATIC_RUBYLAST,
|
|
};
|
|
|
|
int rgIdPropRubyDlg[] =
|
|
{
|
|
IDC_RUBY_EDIT_FIRSTNAME,
|
|
IDC_RUBY_EDIT_LASTNAME,
|
|
IDC_RUBY_EDIT_YOMIFIRSTNAME,
|
|
IDC_RUBY_EDIT_YOMILASTNAME,
|
|
};
|
|
|
|
|
|
INT_PTR CALLBACK fnRubyProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)
|
|
{
|
|
switch(message)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
LPTSTR * sz = (LPTSTR *) lParam;
|
|
SetWindowLongPtr(hDlg, DWLP_USER, lParam);
|
|
EnumChildWindows( hDlg, SetChildDefaultGUIFont, (LPARAM) 0);
|
|
SendMessage(GetDlgItem(hDlg,IDC_RUBY_EDIT_YOMIFIRSTNAME),EM_SETLIMITTEXT,(WPARAM) EDIT_LEN,0);
|
|
SendMessage(GetDlgItem(hDlg,IDC_RUBY_EDIT_YOMILASTNAME),EM_SETLIMITTEXT,(WPARAM) EDIT_LEN,0);
|
|
SendMessage(GetDlgItem(hDlg,IDC_RUBY_EDIT_FIRSTNAME),EM_SETLIMITTEXT,(WPARAM) EDIT_LEN,0);
|
|
SendMessage(GetDlgItem(hDlg,IDC_RUBY_EDIT_LASTNAME),EM_SETLIMITTEXT,(WPARAM) EDIT_LEN,0);
|
|
{
|
|
int i = 0;
|
|
for(i=0;i<sMax;i++)
|
|
{
|
|
if(lstrlen(sz[i]))
|
|
SetDlgItemText(hDlg, rgIdPropRubyDlg[i], sz[i]);
|
|
}
|
|
}
|
|
}
|
|
return TRUE;
|
|
break;
|
|
|
|
/***
|
|
case WM_HELP:
|
|
WABWinHelp(((LPHELPINFO)lParam)->hItemHandle,
|
|
g_szWABHelpFileName,
|
|
HELP_WM_HELP,
|
|
(DWORD_PTR)(LPSTR) rgDetlsHelpIDs );
|
|
break;
|
|
|
|
case WM_CONTEXTMENU:
|
|
WABWinHelp((HWND) wParam,
|
|
g_szWABHelpFileName,
|
|
HELP_CONTEXTMENU,
|
|
(DWORD_PTR)(LPVOID) rgDetlsHelpIDs );
|
|
break;
|
|
/****/
|
|
|
|
case WM_COMMAND:
|
|
switch(GET_WM_COMMAND_ID(wParam, lParam))
|
|
{
|
|
case IDOK:
|
|
{
|
|
LPTSTR * sz = (LPTSTR *) GetWindowLongPtr(hDlg, DWLP_USER);
|
|
int i =0;
|
|
for(i=0;i<sMax;i++)
|
|
{
|
|
if(!GetDlgItemText(hDlg, rgIdPropRubyDlg[i], sz[i], EDIT_LEN))
|
|
sz[i][0] = TEXT('\0');
|
|
}
|
|
}
|
|
EndDialog(hDlg, TRUE);
|
|
break;
|
|
case IDCANCEL:
|
|
EndDialog(hDlg, FALSE);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*
|
|
- ShoWRubyNameEntryDlg
|
|
-
|
|
* Let's the user enter Ruby First and Ruby Last names
|
|
*
|
|
*/
|
|
void ShowRubyNameEntryDlg(HWND hDlg, LPPROP_ARRAY_INFO lpPai)
|
|
{
|
|
LPTSTR sz[sMax];
|
|
int i=0;
|
|
for(i=0;i<sMax;i++) //Read the data off the person tab
|
|
{
|
|
if(sz[i] = LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*EDIT_LEN))
|
|
{
|
|
sz[i][0] = TEXT('\0');
|
|
GetDlgItemText(hDlg, rgIdPropPersonalRuby[i], sz[i], EDIT_LEN);
|
|
}
|
|
}
|
|
|
|
if(DialogBoxParam(hinstMapiX, MAKEINTRESOURCE(IDD_DIALOG_RUBY),
|
|
hDlg, fnRubyProc, (LPARAM)sz))
|
|
{
|
|
for(i=0;i<sMax;i++) // put it back in the personal tab
|
|
{
|
|
SetDlgItemText(hDlg, rgIdPropPersonalRuby[i], sz[i]);
|
|
LocalFree(sz[i]);
|
|
}
|
|
lpPai->bSomethingChanged = TRUE;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
/*//$$***************************************************************************
|
|
* FUNCTION: FillFamilyDetailsUI(HWND)
|
|
*
|
|
* PURPOSE: Fills in the data in the family tab
|
|
*
|
|
****************************************************************************/
|
|
BOOL FillFamilyDetailsUI(HWND hDlg, LPPROP_ARRAY_INFO lpPai, int nPropSheet, BOOL * lpbChangesMade)
|
|
{
|
|
ULONG i = 0,j = 0, k =0;
|
|
BOOL bRet = FALSE;
|
|
BOOL bChangesMade = FALSE;
|
|
ID_PROP * lpidProp = NULL;
|
|
ULONG idPropCount = 0;
|
|
LPVOID lpBuffer = NULL;
|
|
|
|
ULONG ulcPropCount = 0;
|
|
LPSPropValue lpPropArray = NULL;
|
|
|
|
if(HR_FAILED(lpPai->lpPropObj->lpVtbl->GetProps(lpPai->lpPropObj,
|
|
(LPSPropTagArray)&ptaUIDetlsPropsFamily,
|
|
MAPI_UNICODE,
|
|
&ulcPropCount, &lpPropArray)))
|
|
goto out;
|
|
|
|
lpPai->ulFlags |= DETAILS_Initializing;
|
|
|
|
// Set the flag that this sheet was opened
|
|
lpPai->bPropSheetOpened[propFamily] = TRUE;
|
|
|
|
idPropCount = idPropFamilyCount;
|
|
lpidProp = idPropFamily;
|
|
|
|
// A very inefficient and lazy way of filling the UI
|
|
for(i=0;i<idPropCount;i++)
|
|
{
|
|
for(j=0;j<ulcPropCount;j++)
|
|
{
|
|
if(lpPropArray[j].ulPropTag == lpidProp[i].ulPropTag)
|
|
{
|
|
switch(lpidProp[i].ulPropTag)
|
|
{
|
|
case PR_GENDER:
|
|
SendDlgItemMessage(hDlg, IDC_DETAILS_HOME_COMBO_GENDER, CB_SETCURSEL,
|
|
(WPARAM) lpPropArray[j].Value.i, 0);
|
|
break;
|
|
case PR_BIRTHDAY:
|
|
case PR_WEDDING_ANNIVERSARY:
|
|
{
|
|
SYSTEMTIME st = {0};
|
|
FileTimeToSystemTime((FILETIME *) (&lpPropArray[j].Value.ft), &st);
|
|
SendDlgItemMessage(hDlg, lpidProp[i].idCtl,DTM_SETSYSTEMTIME,
|
|
(WPARAM) GDT_VALID, (LPARAM) &st);
|
|
}
|
|
break;
|
|
case PR_CHILDRENS_NAMES:
|
|
for(k=0;k<lpPropArray[j].Value.MVSZ.cValues;k++)
|
|
AddLVNewChild(hDlg, lpPropArray[j].Value.MVSZ.LPPSZ[k]);
|
|
break;
|
|
default:
|
|
SetDlgItemText(hDlg, lpidProp[i].idCtl, lpPropArray[j].Value.LPSZ);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bRet = TRUE;
|
|
out:
|
|
if(lpBuffer)
|
|
LocalFreeAndNull(&lpBuffer);
|
|
|
|
if(lpPropArray)
|
|
MAPIFreeBuffer(lpPropArray);
|
|
|
|
lpPai->ulFlags &= ~DETAILS_Initializing;
|
|
|
|
return bRet;
|
|
}
|
|
|
|
/*
|
|
- AddLVNewChild
|
|
-
|
|
- Adds a new child to the list of children
|
|
- Basically we will add an item called TEXT("New Child") and then
|
|
- force an in-place edit on that item
|
|
-
|
|
- It would be nice to have some image associated with this ListView, eg a Boy/Girl image
|
|
- but that means having to cache seperate Boy/Girl data which would be a pain ..
|
|
-
|
|
*
|
|
*/
|
|
void AddLVNewChild(HWND hDlg, LPTSTR lpName)
|
|
{
|
|
HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_FAMILY_LIST_CHILDREN);
|
|
LV_ITEM lvi = {0};
|
|
TCHAR szBuf[MAX_PATH];
|
|
ULONG nLen;
|
|
int nPos;
|
|
LoadString(hinstMapiX, idsNewChild, szBuf, CharSizeOf(szBuf));
|
|
lvi.mask = LVIF_TEXT | LVIF_IMAGE;
|
|
lvi.pszText = lpName ? lpName : szBuf;
|
|
lvi.cchTextMax = MAX_PATH;
|
|
lvi.iItem = ListView_GetItemCount(hWndLV);
|
|
lvi.iSubItem = 0;
|
|
lvi.iImage = imgChild+(lvi.iItem%3);//just add a little color by using more than 1 different colored image
|
|
nPos = ListView_InsertItem(hWndLV, &lvi);
|
|
LVSelectItem(hWndLV, nPos);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_DETAILS_FAMILY_BUTTON_EDITCHILD), TRUE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_DETAILS_FAMILY_BUTTON_REMOVECHILD), TRUE);
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
/*//$$***********************************************************************
|
|
* FUNCTION: fnFamilyProc
|
|
*
|
|
* PURPOSE: Callback function for handling the Family property sheet ...
|
|
*
|
|
****************************************************************************/
|
|
INT_PTR CALLBACK fnFamilyProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)
|
|
{
|
|
PROPSHEETPAGE * pps;
|
|
BOOL bRet = FALSE;
|
|
|
|
pps = (PROPSHEETPAGE *) GetWindowLongPtr(hDlg, DWLP_USER);
|
|
|
|
switch(message)
|
|
{
|
|
case WM_INITDIALOG:
|
|
SetWindowLongPtr(hDlg,DWLP_USER,lParam);
|
|
pps = (PROPSHEETPAGE *) lParam;
|
|
lpPAI->ulFlags |= DETAILS_Initializing;
|
|
SetDetailsUI(hDlg, lpPAI, lpPAI->ulOperationType,propFamily);
|
|
lpPAI->ulFlags &= ~DETAILS_Initializing;
|
|
return TRUE;
|
|
|
|
case WM_DESTROY:
|
|
bRet = TRUE;
|
|
break;
|
|
|
|
case WM_HELP:
|
|
WABWinHelp(((LPHELPINFO)lParam)->hItemHandle,
|
|
g_szWABHelpFileName,
|
|
HELP_WM_HELP,
|
|
(DWORD_PTR)(LPSTR) rgDetlsHelpIDs );
|
|
break;
|
|
|
|
case WM_CONTEXTMENU:
|
|
WABWinHelp((HWND) wParam,
|
|
g_szWABHelpFileName,
|
|
HELP_CONTEXTMENU,
|
|
(DWORD_PTR)(LPVOID) rgDetlsHelpIDs );
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch(GET_WM_COMMAND_CMD(wParam,lParam)) //check the notification code
|
|
{
|
|
case CBN_SELCHANGE: //gender combo
|
|
if(lpPAI->ulFlags & DETAILS_Initializing)
|
|
break;
|
|
lpPAI->ulFlags |= DETAILS_GenderChanged;
|
|
if (lpbSomethingChanged)
|
|
(*lpbSomethingChanged) = TRUE;
|
|
break;
|
|
|
|
case EN_CHANGE: //some edit box changed - dont care which
|
|
if(lpPAI->ulFlags & DETAILS_Initializing)
|
|
break;
|
|
if (lpbSomethingChanged)
|
|
(*lpbSomethingChanged) = TRUE;
|
|
break;
|
|
}
|
|
switch(GET_WM_COMMAND_ID(wParam, lParam))
|
|
{
|
|
case IDC_DETAILS_FAMILY_BUTTON_ADDCHILD:
|
|
lpPAI->ulFlags |= DETAILS_ChildrenChanged;
|
|
AddLVNewChild(hDlg, NULL);
|
|
SendMessage(hDlg, WM_COMMAND, (WPARAM)IDC_DETAILS_FAMILY_BUTTON_EDITCHILD, 0);
|
|
break;
|
|
case IDC_DETAILS_FAMILY_BUTTON_EDITCHILD:
|
|
lpPAI->ulFlags |= DETAILS_ChildrenChanged;
|
|
{
|
|
HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_FAMILY_LIST_CHILDREN);
|
|
SetFocus(hWndLV);
|
|
if(ListView_GetSelectedCount(hWndLV)==1)
|
|
{
|
|
int index = ListView_GetNextItem(hWndLV,-1,LVNI_SELECTED);
|
|
HWND hWndEditLabel = ListView_EditLabel(hWndLV, index);
|
|
//SendMessage(hWndEditLabel, EM_LIMITTEXT, MAX_PATH, 0);
|
|
}
|
|
}
|
|
break;
|
|
case IDC_DETAILS_FAMILY_BUTTON_REMOVECHILD:
|
|
lpPAI->ulFlags |= DETAILS_ChildrenChanged;
|
|
{
|
|
HWND hWndLV = GetDlgItem(hDlg, IDC_DETAILS_FAMILY_LIST_CHILDREN);
|
|
if(ListView_GetSelectedCount(hWndLV)==1)
|
|
{
|
|
int index = ListView_GetNextItem(hWndLV,-1,LVNI_SELECTED);
|
|
ListView_DeleteItem(hWndLV, index);
|
|
if(index >= ListView_GetItemCount(hWndLV))
|
|
index--;
|
|
LVSelectItem(hWndLV, index);
|
|
}
|
|
}
|
|
break;
|
|
// [PaulHi] 12/4/98 Raid #58940
|
|
// This fix causes the system to go into an infinite message loop (stack overflow
|
|
// crash on intenational Win9X machines) with DBCS. The fnPersonalProc property
|
|
// sheet also doesn't handle this WM_COMMAND message, probably for the same reason.
|
|
// ESC still works correctly on this property sheet.
|
|
#if 0
|
|
/*
|
|
case IDCANCEL:
|
|
// This is a windows bug that prevents ESC canceling prop sheets
|
|
// which have MultiLine Edit boxes KB: Q130765
|
|
SendMessage(GetParent(hDlg),message,wParam,lParam);
|
|
break;
|
|
*/
|
|
#endif
|
|
}
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
switch(((NMHDR FAR *)lParam)->code)
|
|
{
|
|
case DTN_DATETIMECHANGE: //change in the Month-Date-Time control
|
|
if(lpPAI->ulFlags & DETAILS_Initializing)
|
|
break;
|
|
lpPAI->ulFlags |= DETAILS_DateChanged;
|
|
if (lpbSomethingChanged)
|
|
(*lpbSomethingChanged) = TRUE;
|
|
break;
|
|
|
|
case LVN_BEGINLABELEDITA:
|
|
case LVN_BEGINLABELEDITW:
|
|
lpPAI->ulFlags |= DETAILS_EditingChild;
|
|
break;
|
|
|
|
case LVN_ENDLABELEDITA:
|
|
case LVN_ENDLABELEDITW:
|
|
{
|
|
// After the user finishes editing the children's name,
|
|
HWND hWndLV = ((NMHDR FAR *)lParam)->hwndFrom;
|
|
LV_ITEM lvi = ((LV_DISPINFO FAR *) lParam)->item;
|
|
// if this is Win9x .. we'llget an LV_ITEMA here .. else a LV_ITEMW
|
|
LPWSTR lpW = NULL;
|
|
LPSTR lpA = NULL;
|
|
if(!g_bRunningOnNT)
|
|
{
|
|
lpA = (LPSTR)lvi.pszText;
|
|
lpW = ConvertAtoW(lpA);
|
|
lvi.pszText = lpW;
|
|
}
|
|
lpPAI->ulFlags &= ~DETAILS_EditingChild;
|
|
if ((lvi.iItem >= 0) && lvi.pszText && (lstrlen(lvi.pszText)))
|
|
{
|
|
ListView_SetItem(hWndLV, &lvi);
|
|
}
|
|
LocalFreeAndNull(&lpW);
|
|
if(!g_bRunningOnNT)
|
|
((LV_DISPINFO FAR *) lParam)->item.pszText = (LPWSTR)lpA; // reset it as we found it
|
|
}
|
|
break;
|
|
|
|
case PSN_SETACTIVE: //initialize
|
|
FillFamilyDetailsUI(hDlg, lpPAI, propFamily, lpbSomethingChanged);
|
|
break;
|
|
|
|
case PSN_KILLACTIVE: //Losing activation to another page
|
|
bUpdatePropArray(hDlg, lpPAI, propFamily);
|
|
ListView_DeleteAllItems(GetDlgItem(hDlg, IDC_DETAILS_FAMILY_LIST_CHILDREN));
|
|
lpPAI->ulFlags &= ~DETAILS_GenderChanged;
|
|
lpPAI->ulFlags &= ~DETAILS_DateChanged;
|
|
lpPAI->ulFlags &= ~DETAILS_ChildrenChanged;
|
|
break;
|
|
|
|
case PSN_APPLY: //ok
|
|
if (lpPAI->nRetVal == DETAILS_RESET)
|
|
lpPAI->nRetVal = DETAILS_OK;
|
|
break;
|
|
|
|
case PSN_RESET: //cancel
|
|
if(lpPAI->ulFlags & DETAILS_EditingChild)
|
|
{
|
|
ListView_EditLabel(GetDlgItem(hDlg, IDC_DETAILS_FAMILY_LIST_CHILDREN), -1);
|
|
lpPAI->ulFlags &= ~DETAILS_EditingChild;
|
|
}
|
|
if (lpPAI->nRetVal == DETAILS_RESET)
|
|
lpPAI->nRetVal = DETAILS_CANCEL;
|
|
break;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
|
|
/*
|
|
- CreateDateTimePickerControl
|
|
-
|
|
*
|
|
* Description: Creates and initializes the control on the specified window. The controls destination
|
|
* size is that of the static rectangle IDC_CONTROL_RECT
|
|
* Parameters: idFrame - a dummy static used in the dialog layout to set a size and position for the new control
|
|
* The original static is hidden
|
|
* idControl - the Control ID to assign to the control
|
|
*
|
|
* We also need to make sure that the tab order stays sane,
|
|
* Returns: none
|
|
*/
|
|
void CreateDateTimeControl(HWND hDlg, int idFrame, int idControl)
|
|
{
|
|
RECT rectControl;
|
|
SIZE sizeControl;
|
|
HWND hWndDP = NULL;
|
|
HWND hWndFrame = GetDlgItem(hDlg,idFrame);
|
|
// Get bounding rectangle of control and convert to client coordinates
|
|
GetWindowRect(hWndFrame,&rectControl);
|
|
MapWindowPoints(NULL, hDlg, (LPPOINT) &rectControl, 2);
|
|
|
|
sizeControl.cx = rectControl.right-rectControl.left;
|
|
sizeControl.cy = rectControl.bottom-rectControl.top;
|
|
// Do not use ScreenToClient(), use MapWindowPoints for mirroring.
|
|
// ScreenToClient(hDlg,&pointControl);
|
|
|
|
// Create control which starts at pointControl extends to sizeControl
|
|
// >> Start control specific
|
|
hWndDP = CreateWindowEx( WS_EX_CLIENTEDGE,
|
|
DATETIMEPICK_CLASS,
|
|
NULL,
|
|
WS_CHILD|WS_VISIBLE|WS_TABSTOP|DTS_SHORTDATEFORMAT|DTS_SHOWNONE,
|
|
rectControl.left,
|
|
rectControl.top,
|
|
sizeControl.cx,
|
|
sizeControl.cy,
|
|
hDlg,
|
|
(HMENU)IntToPtr(idControl), // control identifier
|
|
hinstMapiXWAB,
|
|
NULL);
|
|
|
|
// Check if control was created
|
|
if(hWndDP)
|
|
{
|
|
TCHAR szFormat[MAX_PATH];
|
|
SYSTEMTIME st = {0};
|
|
LoadString(hinstMapiX, idsDateTimeFormat, szFormat, CharSizeOf(szFormat));
|
|
SendMessage(hWndDP, DTM_SETFORMAT, 0, (LPARAM)szFormat);
|
|
SendMessage(hWndDP, DTM_SETSYSTEMTIME, (WPARAM) GDT_NONE, (LPARAM) &st);
|
|
|
|
SetWindowPos(hWndDP, hWndFrame,0,0,0,0,SWP_NOSIZE | SWP_NOMOVE);
|
|
}
|
|
|
|
return;
|
|
}
|