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.
3179 lines
105 KiB
3179 lines
105 KiB
/*--------------------------------------------------------------
|
|
*
|
|
*
|
|
* ui_srch.c - contains stuff for showing the WAB search dialog
|
|
* with LDAP Search and Local Search
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
* 9/96 - created VikramM
|
|
--------------------------------------------------------------*/
|
|
#include "_apipch.h"
|
|
|
|
#define CONTROL_SPACE 7 //pixels
|
|
#define BORDER_SPACE 11 //pixels
|
|
|
|
typedef struct _ServerDat
|
|
{
|
|
HIMAGELIST himl;
|
|
SBinary SB;
|
|
} SERVERDAT, * LPSERVERDAT;
|
|
|
|
enum
|
|
{
|
|
IS_LDAP = 0,
|
|
IS_PAB,
|
|
IS_OLK,
|
|
IS_ERR
|
|
};
|
|
|
|
enum
|
|
{
|
|
tabSimple=0,
|
|
tabAdvanced,
|
|
tabMax
|
|
};
|
|
|
|
// Structure passed to Search Dialog Proc
|
|
typedef struct _FindParams
|
|
{
|
|
LDAP_SEARCH_PARAMS LDAPsp;
|
|
SORT_INFO SortInfo;
|
|
LPRECIPIENT_INFO lpContentsList;
|
|
LPADRPARM_FINDINFO lpAPFI;
|
|
BOOL bShowFullDialog; // Determines whether to show the full dialog or the truncated dialog
|
|
BOOL bLDAPActionInProgress;
|
|
LPLDAPURL lplu;
|
|
BOOL bInitialized;
|
|
BOOL bUserCancel;
|
|
int MinDlgWidth;
|
|
int MinDlgHeight;
|
|
int MinDlgHeightWithResults;
|
|
} WAB_FIND_PARAMS, * LPWAB_FIND_PARAMS;
|
|
|
|
|
|
// Search dialog control arrays
|
|
int rgAdrParmButtonID[] =
|
|
{
|
|
IDC_FIND_BUTTON_TO,
|
|
IDC_FIND_BUTTON_CC,
|
|
IDC_FIND_BUTTON_BCC
|
|
};
|
|
|
|
int rgAdvancedButtons[] =
|
|
{
|
|
IDC_FIND_BUTTON_ADDCONDITION,
|
|
IDC_FIND_BUTTON_REMOVECONDITION
|
|
};
|
|
|
|
int rgSearchEditID[] =
|
|
{
|
|
IDC_FIND_EDIT_NAME,
|
|
IDC_FIND_EDIT_EMAIL,
|
|
IDC_FIND_EDIT_STREET,
|
|
IDC_FIND_EDIT_PHONE,
|
|
IDC_FIND_EDIT_ANY,
|
|
};
|
|
#define SEARCH_EDIT_MAX 5 //sync with above array
|
|
|
|
/*
|
|
* Prototypes
|
|
*/
|
|
|
|
// extern LPIMAGELIST_LOADIMAGE gpfnImageList_LoadImage;
|
|
extern LPIMAGELIST_LOADIMAGE_A gpfnImageList_LoadImageA;
|
|
extern LPIMAGELIST_LOADIMAGE_W gpfnImageList_LoadImageW;
|
|
|
|
extern LPIMAGELIST_DESTROY gpfnImageList_Destroy;
|
|
extern LPIMAGELIST_DRAW gpfnImageList_Draw;
|
|
|
|
extern BOOL bIsHttpPrefix(LPTSTR szBuf);
|
|
extern const LPTSTR lpszRegFindPositionKeyValueName;
|
|
extern BOOL ListAddItem(HWND hDlg, HWND hWndAddr, int CtlID, LPRECIPIENT_INFO * lppList, ULONG RecipientType);
|
|
extern HRESULT LDAPSearchWithoutContainer(HWND hWnd, LPLDAPURL lplu,
|
|
LPSRestriction lpres,
|
|
LPTSTR lpAdvFilter,
|
|
BOOL bReturnSinglePropArray,
|
|
ULONG ulFlags,
|
|
LPRECIPIENT_INFO * lppContentsList,
|
|
LPULONG lpulcProps,
|
|
LPSPropValue * lppPropArray);
|
|
extern HRESULT HrGetLDAPSearchRestriction(LDAP_SEARCH_PARAMS LDAPsp, LPSRestriction lpSRes);
|
|
|
|
#ifdef PAGED_RESULT_SUPPORT
|
|
extern BOOL bMorePagedResultsAvailable();
|
|
extern void ClearCachedPagedResultParams();
|
|
#endif //#ifdef PAGED_RESULT_SUPPORT
|
|
|
|
|
|
int ComboAddItem(HWND hWndLV, LPTSTR lpszItemText, LPARAM lParam, LPTSTR szPref, int * lpnStart, BOOL * lpbAddedPref);
|
|
INT_PTR CALLBACK fnSearch( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
|
|
void UpdateButtons(HWND hDlg, HWND hWndLVResults, HWND hWndLV, LPLDAPURL lplu);
|
|
//HRESULT HrInitServerListLV(HWND hWndLV);
|
|
LRESULT ProcessLVMessages(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
|
LRESULT ProcessLVResultsMessages(HWND hWnd,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam,
|
|
LPWAB_FIND_PARAMS lpWFP);
|
|
BOOL DoTheSearchThing(HWND hDlg, LPWAB_FIND_PARAMS lpWFP);
|
|
void SaveFindWindowPos(HWND hWnd, LPIAB lpIAB);
|
|
int CurrentContainerIsPAB(HWND hWndLV);
|
|
|
|
static const LPTSTR szKeyLastFindServer = TEXT("Software\\Microsoft\\WAB\\WAB4\\LastFind");
|
|
static const LPTSTR c_tszPolicyPrefAccount = TEXT("Software\\Policies\\Microsoft\\Internet Account Manager\\Account Pref");
|
|
|
|
|
|
/***/
|
|
static DWORD rgSrchHelpIDs[] =
|
|
{
|
|
IDC_FIND_STATIC_FINDIN, IDH_WAB_DIR_SER_LIST,
|
|
IDC_FIND_COMBO_LIST, IDH_WAB_DIR_SER_LIST,
|
|
IDC_FIND_STATIC_NAME, IDH_WAB_FIND_FIRST,
|
|
IDC_FIND_EDIT_NAME, IDH_WAB_FIND_FIRST,
|
|
IDC_FIND_STATIC_EMAIL, IDH_WAB_FIND_E_MAIL,
|
|
IDC_FIND_EDIT_EMAIL, IDH_WAB_FIND_E_MAIL,
|
|
IDC_FIND_STATIC_STREET, IDH_WAB_FIND_ADDRESS,
|
|
IDC_FIND_EDIT_STREET, IDH_WAB_FIND_ADDRESS,
|
|
IDC_FIND_STATIC_PHONE, IDH_WAB_FIND_PHONE,
|
|
IDC_FIND_EDIT_PHONE, IDH_WAB_FIND_PHONE,
|
|
IDC_FIND_STATIC_ANY, IDH_WAB_FIND_OTHER,
|
|
IDC_FIND_EDIT_ANY, IDH_WAB_FIND_OTHER,
|
|
IDC_FIND_BUTTON_FIND, IDH_WAB_FIND_FINDNOW,
|
|
IDC_FIND_BUTTON_CLEAR, IDH_WAB_FIND_CLEARALL,
|
|
IDC_FIND_BUTTON_CLOSE, IDH_WAB_FIND_CLOSE,
|
|
IDC_FIND_LIST_RESULTS, IDH_WAB_FIND_RESULTS,
|
|
IDC_FIND_BUTTON_PROPERTIES, IDH_WAB_PICK_RECIP_NAME_PROPERTIES,
|
|
IDC_FIND_BUTTON_DELETE, IDH_WAB_FIND_DELETE,
|
|
IDC_FIND_BUTTON_ADDTOWAB, IDH_WAB_FIND_ADD2WAB,
|
|
IDC_FIND_BUTTON_TO, IDH_WAB_PICK_RECIP_NAME_TO_BUTTON,
|
|
IDC_FIND_BUTTON_CC, IDH_WAB_PICK_RECIP_NAME_CC_BUTTON,
|
|
IDC_FIND_BUTTON_BCC, IDH_WAB_PICK_RECIP_NAME_BCC_BUTTON,
|
|
IDC_TAB_FIND, IDH_WAB_COMM_GROUPBOX,
|
|
IDC_FIND_BUTTON_SERVER_INFO, IDH_WAB_VISITDS_BUTTON,
|
|
IDC_FIND_BUTTON_STOP, IDH_WAB_FIND_STOP,
|
|
IDC_FIND_STATIC_ADVANCED, IDH_WAB_FIND_ADV_CRITERIA,
|
|
IDC_FIND_COMBO_FIELD, IDH_WAB_FIND_ADV_CRITERIA,
|
|
IDC_FIND_COMBO_CONDITION, IDH_WAB_FIND_ADV_CRITERIA,
|
|
IDC_FIND_EDIT_ADVANCED, IDH_WAB_FIND_ADV_CRITERIA,
|
|
IDC_FIND_LIST_CONDITIONS, IDH_WAB_FIND_ADV_CRITERIA_DISPLAY,
|
|
IDC_FIND_BUTTON_ADDCONDITION, IDH_WAB_FIND_ADV_CRITERIA_ADD,
|
|
IDC_FIND_BUTTON_REMOVECONDITION,IDH_WAB_FIND_ADV_CRITERIA_REMOVE,
|
|
0,0
|
|
};
|
|
|
|
|
|
/*
|
|
-
|
|
- ShowHideMoreResultsButton
|
|
*
|
|
* This is called to show the MORE RESULTS button whenever
|
|
* a paged result was done and a Cookie was cached
|
|
* The button is hidden whenever search parameters change
|
|
*
|
|
*/
|
|
void ShowHideMoreResultsButton(HWND hDlg, BOOL bShow)
|
|
{
|
|
HWND hWnd = GetDlgItem(hDlg, IDC_FIND_BUTTON_MORE);
|
|
EnableWindow(hWnd, bShow);
|
|
ShowWindow(hWnd, bShow ? SW_NORMAL : SW_HIDE);
|
|
}
|
|
|
|
|
|
/***/
|
|
/*
|
|
- ResizeSearchDlg
|
|
-
|
|
*
|
|
*/
|
|
void ResizeSearchDlg(HWND hDlg, LPWAB_FIND_PARAMS lpWFP)
|
|
{
|
|
// resize the dialog to show the full results and let the user
|
|
// resize it henceforth without restriction
|
|
RECT rc;
|
|
HWND hWndLVResults = GetDlgItem(hDlg, IDC_FIND_LIST_RESULTS);
|
|
|
|
GetWindowRect(hDlg, &rc);
|
|
lpWFP->bShowFullDialog = TRUE;
|
|
SetWindowPos(hDlg, HWND_TOP, rc.left, rc.top,
|
|
rc.right - rc.left, lpWFP->MinDlgHeightWithResults,
|
|
SWP_NOMOVE | SWP_NOZORDER);
|
|
SetColumnHeaderBmp( hWndLVResults, lpWFP->SortInfo);
|
|
|
|
// Also set the WS_TABSTOP style on the results Listview once the dialog is
|
|
// expanded
|
|
{
|
|
DWORD dwStyle = GetWindowLong(hWndLVResults, GWL_STYLE);
|
|
dwStyle |= WS_TABSTOP;
|
|
SetWindowLong(hWndLVResults, GWL_STYLE, dwStyle);
|
|
}
|
|
}
|
|
|
|
//$$///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// AddTabItem
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void AddTabItem(HWND hDlg, int nIndex)
|
|
{
|
|
HWND hWndTab = GetDlgItem(hDlg, IDC_TAB_FIND);
|
|
TC_ITEM tci ={0};
|
|
TCHAR sz[MAX_PATH];
|
|
LoadString(hinstMapiX, idsFindTabTitle+nIndex, sz, ARRAYSIZE(sz));
|
|
tci.mask = TCIF_TEXT;
|
|
tci.pszText = sz;
|
|
tci.cchTextMax = lstrlen(sz)+1;
|
|
TabCtrl_InsertItem(hWndTab, nIndex, &tci);
|
|
}
|
|
|
|
//$$////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Gets the text of the currently selected item in the combo .. defaults to
|
|
// item 0 if no selection
|
|
//
|
|
// szBuf should be a large enough predefined buffer
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void GetSelectedText(HWND hWndCombo, LPTSTR * lppBuf)
|
|
{
|
|
int iItemIndex = (int) SendMessage(hWndCombo, CB_GETCURSEL, 0, 0);
|
|
int nLen = 0;
|
|
|
|
if(!lppBuf)
|
|
return;
|
|
|
|
*lppBuf = NULL;
|
|
|
|
if(iItemIndex == CB_ERR)
|
|
{
|
|
SendMessage(hWndCombo, CB_SETCURSEL, 0, 0);
|
|
iItemIndex = 0;
|
|
}
|
|
|
|
nLen = (int) SendMessage(hWndCombo, CB_GETLBTEXTLEN, (WPARAM) iItemIndex, 0);
|
|
|
|
if (nLen != CB_ERR)
|
|
{
|
|
nLen++; // Make space for the terminator
|
|
*lppBuf = LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR) * nLen);
|
|
|
|
if(*lppBuf)
|
|
{
|
|
*lppBuf[0] = TEXT('\0');
|
|
SendMessage(hWndCombo, CB_GETLBTEXT, (WPARAM) iItemIndex, (LPARAM) *lppBuf);
|
|
}
|
|
}
|
|
}
|
|
|
|
//$$/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// hrShowSearchDialog - wrapper for Search UI
|
|
//
|
|
// lpAPFI - is a special structure passed in by the select recipients dialog
|
|
// that enables us to add memebers to the select recipients dialog from the
|
|
// find dialog
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
HRESULT HrShowSearchDialog(LPADRBOOK lpAdrBook,
|
|
HWND hWndParent,
|
|
LPADRPARM_FINDINFO lpAPFI,
|
|
LPLDAPURL lplu,
|
|
LPSORT_INFO lpSortInfo)
|
|
{
|
|
LPPTGDATA lpPTGData=GetThreadStoragePointer();
|
|
LPIAB lpIAB = (LPIAB)lpAdrBook;
|
|
HRESULT hr = hrSuccess;
|
|
int nRetVal = SEARCH_ERROR;
|
|
WAB_FIND_PARAMS fp = {0};
|
|
|
|
InitLDAPClientLib();
|
|
|
|
fp.lpContentsList = NULL;
|
|
|
|
if(!lpSortInfo)
|
|
ReadRegistrySortInfo(lpIAB, &(fp.SortInfo));
|
|
else
|
|
fp.SortInfo = *lpSortInfo;
|
|
|
|
#ifndef WIN16 // Disable until ldap16.dll is available.
|
|
if(!lplu) //dont want anything filled in if this was a ldapurl thing
|
|
fp.LDAPsp = pt_LDAPsp;
|
|
fp.LDAPsp.lpIAB = lpAdrBook;
|
|
#endif
|
|
|
|
fp.lpAPFI = lpAPFI;
|
|
fp.lplu = lplu;
|
|
|
|
if(lplu)
|
|
{
|
|
if(lplu->lpList)
|
|
fp.bShowFullDialog = TRUE;
|
|
}
|
|
fp.bLDAPActionInProgress = FALSE;
|
|
|
|
nRetVal = (int) DialogBoxParam(
|
|
hinstMapiX,
|
|
MAKEINTRESOURCE(IDD_DIALOG_FIND),
|
|
hWndParent,
|
|
fnSearch,
|
|
(LPARAM) &fp);
|
|
|
|
#ifndef WIN16 // Disable until ldap16.dll is available.
|
|
pt_LDAPsp = fp.LDAPsp;
|
|
#endif
|
|
|
|
if(lpAPFI)
|
|
lpAPFI->nRetVal = nRetVal;
|
|
|
|
switch(nRetVal)
|
|
{
|
|
case SEARCH_CANCEL:
|
|
hr = MAPI_E_USER_CANCEL;
|
|
break;
|
|
case SEARCH_CLOSE:
|
|
case SEARCH_OK:
|
|
case SEARCH_USE:
|
|
hr = S_OK;
|
|
break;
|
|
case SEARCH_ERROR:
|
|
hr = E_FAIL;
|
|
break;
|
|
}
|
|
|
|
if(fp.lpContentsList)
|
|
{
|
|
LPRECIPIENT_INFO lpItem;
|
|
lpItem = fp.lpContentsList;
|
|
while(lpItem)
|
|
{
|
|
fp.lpContentsList = lpItem->lpNext;
|
|
FreeRecipItem(&lpItem);
|
|
lpItem = fp.lpContentsList;
|
|
}
|
|
fp.lpContentsList = NULL;
|
|
}
|
|
|
|
DeinitLDAPClientLib();
|
|
|
|
return hr;
|
|
}
|
|
|
|
//$$/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// SetEnableDisableUI - shows/hides edit fields based on whether selected item
|
|
// in the list view is WAB or Directory Service
|
|
//
|
|
// hDlg - Parent dialog
|
|
// hWndLV - List View
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void SetEnableDisableUI(HWND hDlg, HWND hWndCombo, LPLDAPURL lplu, int nTab)
|
|
{
|
|
BOOL bIsWAB = FALSE, bHasLogo = FALSE;
|
|
int swShowSimple, swShowSimpleWAB, swShowAdvanced;
|
|
ULONG cbEID;
|
|
LPENTRYID lpEID;
|
|
|
|
// Just in case the list view lost its selection,
|
|
// dont modify the UI
|
|
|
|
|
|
if(!lplu && (CurrentContainerIsPAB(hWndCombo) != IS_LDAP))
|
|
bIsWAB = TRUE;
|
|
|
|
swShowSimple = (nTab == tabSimple) ? SW_SHOWNORMAL : SW_HIDE;
|
|
swShowSimpleWAB = (nTab == tabSimple && bIsWAB) ? SW_SHOWNORMAL : SW_HIDE;
|
|
swShowAdvanced = (nTab == tabAdvanced) ? SW_SHOWNORMAL : SW_HIDE;
|
|
|
|
// Show / Hide the simple tab elements based on what this is
|
|
//
|
|
ShowWindow(GetDlgItem(hDlg,IDC_FIND_EDIT_NAME), swShowSimple);
|
|
ShowWindow(GetDlgItem(hDlg,IDC_FIND_STATIC_NAME), swShowSimple);
|
|
ShowWindow(GetDlgItem(hDlg,IDC_FIND_EDIT_EMAIL), swShowSimple);
|
|
ShowWindow(GetDlgItem(hDlg,IDC_FIND_STATIC_EMAIL), swShowSimple);
|
|
ShowWindow(GetDlgItem(hDlg,IDC_FIND_EDIT_STREET), swShowSimpleWAB);
|
|
ShowWindow(GetDlgItem(hDlg,IDC_FIND_STATIC_STREET), swShowSimpleWAB);
|
|
ShowWindow(GetDlgItem(hDlg,IDC_FIND_EDIT_PHONE), swShowSimpleWAB);
|
|
ShowWindow(GetDlgItem(hDlg,IDC_FIND_STATIC_PHONE), swShowSimpleWAB);
|
|
ShowWindow(GetDlgItem(hDlg,IDC_FIND_EDIT_ANY), swShowSimpleWAB);
|
|
ShowWindow(GetDlgItem(hDlg,IDC_FIND_STATIC_ANY), swShowSimpleWAB);
|
|
|
|
|
|
EnableWindow(GetDlgItem(hDlg,IDC_FIND_EDIT_STREET), bIsWAB);
|
|
EnableWindow(GetDlgItem(hDlg,IDC_FIND_STATIC_STREET), bIsWAB);
|
|
EnableWindow(GetDlgItem(hDlg,IDC_FIND_EDIT_PHONE), bIsWAB);
|
|
EnableWindow(GetDlgItem(hDlg,IDC_FIND_STATIC_PHONE), bIsWAB);
|
|
EnableWindow(GetDlgItem(hDlg,IDC_FIND_EDIT_ANY), bIsWAB);
|
|
EnableWindow(GetDlgItem(hDlg,IDC_FIND_STATIC_ANY), bIsWAB);
|
|
|
|
|
|
// Show / Hide the advanced tab elements based on what this is
|
|
//
|
|
ShowWindow(GetDlgItem(hDlg, IDC_FIND_STATIC_ADVANCED), swShowAdvanced);
|
|
ShowWindow(GetDlgItem(hDlg, IDC_FIND_COMBO_FIELD), swShowAdvanced);
|
|
ShowWindow(GetDlgItem(hDlg, IDC_FIND_COMBO_CONDITION), swShowAdvanced);
|
|
ShowWindow(GetDlgItem(hDlg, IDC_FIND_EDIT_ADVANCED), swShowAdvanced);
|
|
ShowWindow(GetDlgItem(hDlg, IDC_FIND_LIST_CONDITIONS), swShowAdvanced);
|
|
ShowWindow(GetDlgItem(hDlg, IDC_FIND_BUTTON_ADDCONDITION), swShowAdvanced);
|
|
ShowWindow(GetDlgItem(hDlg, IDC_FIND_BUTTON_REMOVECONDITION), swShowAdvanced);
|
|
|
|
// Turn off advanced searching for WAB
|
|
//EnableWindow(GetDlgItem(hDlg, IDC_FIND_STATIC_ADVANCED), !bIsWAB);
|
|
//EnableWindow(GetDlgItem(hDlg, IDC_FIND_COMBO_FIELD), !bIsWAB);
|
|
//EnableWindow(GetDlgItem(hDlg, IDC_FIND_COMBO_CONDITION), !bIsWAB);
|
|
//EnableWindow(GetDlgItem(hDlg, IDC_FIND_EDIT_ADVANCED), !bIsWAB);
|
|
//EnableWindow(GetDlgItem(hDlg, IDC_FIND_LIST_CONDITIONS), !bIsWAB);
|
|
//EnableWindow(GetDlgItem(hDlg, IDC_FIND_BUTTON_ADDCONDITION), !bIsWAB);
|
|
//EnableWindow(GetDlgItem(hDlg, IDC_FIND_BUTTON_REMOVECONDITION), !bIsWAB);
|
|
//EnableWindow(GetDlgItem(hDlg, IDC_FIND_LIST_CONDITIONS), !bIsWAB);
|
|
|
|
|
|
if (! bIsWAB)
|
|
{ // This is an LDAP container
|
|
LDAPSERVERPARAMS lsp = {0};
|
|
ULONG iItemIndex;
|
|
LPTSTR lpBuf = NULL;
|
|
|
|
// Does it have a URL registered?
|
|
// Get the LDAP server properties for the selected container
|
|
|
|
GetSelectedText(hWndCombo, &lpBuf);
|
|
|
|
GetLDAPServerParams(lpBuf, &lsp);
|
|
|
|
if( nTab == tabSimple &&
|
|
lsp.lpszLogoPath && lstrlen(lsp.lpszLogoPath) &&
|
|
GetFileAttributes(lsp.lpszLogoPath) != 0xFFFFFFFF )
|
|
{
|
|
HANDLE hbm = LoadImage( hinstMapiX, lsp.lpszLogoPath,
|
|
IMAGE_BITMAP, 134,38,
|
|
LR_LOADFROMFILE | LR_LOADMAP3DCOLORS); //| LR_LOADTRANSPARENT | LR_LOADMAP3DCOLORS); //LR_DEFAULTCOLOR);
|
|
if(hbm)
|
|
{
|
|
SendDlgItemMessage(hDlg, IDC_FIND_STATIC_LOGO, STM_SETIMAGE, (WPARAM) IMAGE_BITMAP, (LPARAM) hbm);
|
|
bHasLogo = TRUE;
|
|
}
|
|
}
|
|
|
|
|
|
if (lsp.lpszURL && lstrlen(lsp.lpszURL) && bIsHttpPrefix(lsp.lpszURL))
|
|
EnableWindow(GetDlgItem(hDlg, IDC_FIND_BUTTON_SERVER_INFO), TRUE);
|
|
else
|
|
EnableWindow(GetDlgItem(hDlg, IDC_FIND_BUTTON_SERVER_INFO), FALSE);
|
|
|
|
FreeLDAPServerParams(lsp);
|
|
|
|
if(lpBuf)
|
|
LocalFree(lpBuf);
|
|
}
|
|
else
|
|
EnableWindow(GetDlgItem(hDlg, IDC_FIND_BUTTON_SERVER_INFO), FALSE);
|
|
|
|
ShowWindow(GetDlgItem(hDlg, IDC_FIND_STATIC_LOGO), (bHasLogo ? SW_SHOW : SW_HIDE));
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
//$$/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// SetSearchUI - Sets up the Search UI
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
BOOL SetSearchUI(HWND hDlg, LPWAB_FIND_PARAMS lpWFP)
|
|
{
|
|
ABOOK_POSCOLSIZE ABPosColSize = {0};
|
|
int i =0;
|
|
|
|
// Set the font of all the children to the default GUI font
|
|
EnumChildWindows( hDlg,
|
|
SetChildDefaultGUIFont,
|
|
(LPARAM) 0);
|
|
|
|
// Set the title on the TAB
|
|
AddTabItem(hDlg, tabSimple);
|
|
AddTabItem(hDlg, tabAdvanced);
|
|
|
|
//
|
|
// Set the max text length of all the edit boxes to MAX_UI_STR
|
|
//
|
|
for(i=0;i<SEARCH_EDIT_MAX;i++)
|
|
{
|
|
SendMessage(GetDlgItem(hDlg,rgSearchEditID[i]),EM_SETLIMITTEXT,(WPARAM) MAX_UI_STR-16,0);
|
|
}
|
|
SendMessage(GetDlgItem(hDlg,IDC_FIND_EDIT_ADVANCED),EM_SETLIMITTEXT,(WPARAM) MAX_UI_STR-16,0);
|
|
|
|
|
|
HrInitListView( GetDlgItem(hDlg, IDC_FIND_LIST_RESULTS),
|
|
LVS_REPORT,
|
|
TRUE);
|
|
|
|
{
|
|
HWND hWndAnim = GetDlgItem(hDlg, IDC_FIND_ANIMATE1);
|
|
if(Animate_Open(hWndAnim, MAKEINTRESOURCE(IDR_AVI_WABFIND)))
|
|
{
|
|
if(Animate_Play(hWndAnim, 0, 1, 0))
|
|
Animate_Stop(hWndAnim);
|
|
}
|
|
}
|
|
|
|
// Set the to, cc, bcc buttons appropriately
|
|
if(lpWFP->lpAPFI)
|
|
{
|
|
// if this pointer is not null then we were called by a select recipients dlg
|
|
if(lpWFP->lpAPFI->lpAdrParms)
|
|
{
|
|
LPADRPARM lpAdrParms = lpWFP->lpAPFI->lpAdrParms;
|
|
ULONG i;
|
|
|
|
// If this is called from the PickUser dialog, then the results list view
|
|
// needs to be single select
|
|
if(lpWFP->lpAPFI->DialogState == STATE_PICK_USER)
|
|
{
|
|
HWND hWndLV = GetDlgItem(hDlg, IDC_FIND_LIST_RESULTS);
|
|
DWORD dwStyle= GetWindowLong(hWndLV , GWL_STYLE);
|
|
SetWindowLong(hWndLV , GWL_STYLE, dwStyle | LVS_SINGLESEL);
|
|
}
|
|
|
|
for(i=0;i < lpAdrParms->cDestFields; i++)
|
|
{
|
|
HWND hWndButton = GetDlgItem(hDlg, rgAdrParmButtonID[i]);
|
|
ShowWindow(hWndButton, SW_NORMAL);
|
|
EnableWindow(hWndButton, TRUE);
|
|
if(lpAdrParms->lppszDestTitles)
|
|
{
|
|
LPTSTR lpTitle = (lpAdrParms->ulFlags & MAPI_UNICODE) ?
|
|
(LPWSTR)lpAdrParms->lppszDestTitles[i] :
|
|
ConvertAtoW((LPSTR)lpAdrParms->lppszDestTitles[i]);
|
|
if(lpTitle)
|
|
{
|
|
ULONG Len = lstrlen(lpTitle);
|
|
TCHAR szBuf[32];
|
|
if (Len > ARRAYSIZE(szBuf) - 4)
|
|
{
|
|
ULONG iLen = TruncatePos(lpTitle, ARRAYSIZE(szBuf) - 4);
|
|
CopyMemory(szBuf, lpTitle, min(iLen*sizeof(TCHAR), sizeof(szBuf)));
|
|
szBuf[iLen] = '\0';
|
|
}
|
|
else
|
|
StrCpyN(szBuf,lpTitle, ARRAYSIZE(szBuf));
|
|
StrCatBuff(szBuf,szArrow, ARRAYSIZE(szBuf));
|
|
SetWindowText(hWndButton, szBuf);
|
|
if(lpTitle != lpAdrParms->lppszDestTitles[i])
|
|
LocalFreeAndNull(&lpTitle);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if(ReadRegistryPositionInfo((LPIAB)lpWFP->LDAPsp.lpIAB, &ABPosColSize, lpszRegFindPositionKeyValueName))
|
|
{
|
|
if( IsWindowOnScreen( &ABPosColSize.rcPos) )
|
|
{
|
|
int nW = ABPosColSize.rcPos.right-ABPosColSize.rcPos.left;
|
|
MoveWindow(hDlg,
|
|
ABPosColSize.rcPos.left,
|
|
ABPosColSize.rcPos.top,
|
|
(nW < lpWFP->MinDlgWidth) ? lpWFP->MinDlgWidth : nW,
|
|
lpWFP->MinDlgHeight,
|
|
FALSE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
MoveWindow(hDlg,
|
|
20,
|
|
20,
|
|
lpWFP->MinDlgWidth,
|
|
lpWFP->MinDlgHeight,
|
|
FALSE);
|
|
}
|
|
|
|
if(ABPosColSize.nTab > tabMax)
|
|
ABPosColSize.nTab = tabSimple;
|
|
|
|
TabCtrl_SetCurSel(GetDlgItem(hDlg, IDC_TAB_FIND), ABPosColSize.nTab);
|
|
|
|
|
|
if(lpWFP->bShowFullDialog)
|
|
ResizeSearchDlg(hDlg, lpWFP);
|
|
|
|
{
|
|
TCHAR szBuf[MAX_PATH];
|
|
LoadString(hinstMapiX, idsSearchDialogTitle, szBuf, ARRAYSIZE(szBuf));
|
|
SetWindowText(hDlg, szBuf);
|
|
}
|
|
|
|
ImmAssociateContext(GetDlgItem(hDlg, IDC_FIND_EDIT_PHONE), (HIMC)NULL);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//$$/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// ClearFieldCombo - Clears any allocated memory in the Advanced Field Combo
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
void ClearFieldCombo(HWND hWndCombo)
|
|
{
|
|
int nCount = (int) SendMessage(hWndCombo, CB_GETCOUNT, 0, 0);
|
|
LPTSTR lp = NULL;
|
|
if(!nCount || nCount == CB_ERR)
|
|
return;
|
|
|
|
if(nCount >= LDAPFilterFieldMax)
|
|
{
|
|
// Get the item behind the first element
|
|
// This item is a pointer to an allocated string
|
|
lp = (LPTSTR) SendMessage(hWndCombo, CB_GETITEMDATA, (WPARAM) LDAPFilterFieldMax, 0);
|
|
if(lp && (CB_ERR != (ULONG_PTR)lp))
|
|
LocalFreeAndNull(&lp);
|
|
}
|
|
SendMessage(hWndCombo, CB_RESETCONTENT, 0, 0);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
//$$/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// FillAdvancedFieldCombos - Fills the Search UI with various information
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
void FillAdvancedFieldCombos(HWND hDlg, HWND hWndComboContainer)
|
|
{
|
|
// The 2 advanced tab combos have data based on the current container ..
|
|
// Hence need the CurrentContainerInfo here...
|
|
BOOL bIsPAB = (CurrentContainerIsPAB(hWndComboContainer) != IS_LDAP);
|
|
HWND hWndComboField = GetDlgItem(hDlg, IDC_FIND_COMBO_FIELD);
|
|
HWND hWndComboCondition = GetDlgItem(hDlg, IDC_FIND_COMBO_CONDITION);
|
|
int i = 0, nPos = 0, nMax = 0;
|
|
TCHAR sz[MAX_PATH];
|
|
|
|
ClearFieldCombo(hWndComboField);
|
|
SendMessage(hWndComboCondition, CB_RESETCONTENT, 0, 0);
|
|
|
|
{
|
|
HWND hWndTab = GetDlgItem(hDlg, IDC_TAB_FIND);
|
|
if(bIsPAB)
|
|
{
|
|
TabCtrl_SetCurSel(hWndTab, tabSimple);
|
|
TabCtrl_DeleteItem(GetDlgItem(hDlg,IDC_TAB_FIND), tabAdvanced);
|
|
}
|
|
else
|
|
{
|
|
if(TabCtrl_GetItemCount(hWndTab) < tabMax)
|
|
AddTabItem(hDlg, tabAdvanced);
|
|
}
|
|
}
|
|
|
|
// If this is the WAB only give the "contains" option
|
|
nMax = bIsPAB ? 1 : LDAPFilterOptionMax;
|
|
|
|
for(i=0;i<nMax;i++)
|
|
{
|
|
LoadString(hinstMapiX, idsLDAPFilterOption1+i, sz, ARRAYSIZE(sz));
|
|
nPos = (int) SendMessage(hWndComboCondition, CB_ADDSTRING, 0, (LPARAM) sz);
|
|
}
|
|
|
|
// Now add the default set of searchable attributes
|
|
{
|
|
LPTSTR lp = NULL;
|
|
// If this is the WAB only give the Name and E-Mail option
|
|
nMax = bIsPAB ? 2 : LDAPFilterFieldMax;
|
|
|
|
for(i=0;i<nMax;i++)
|
|
{
|
|
LoadString(hinstMapiX, idsLDAPFilterField1+i, sz, ARRAYSIZE(sz));
|
|
nPos = (int) SendMessage(hWndComboField, CB_ADDSTRING, 0, (LPARAM) sz);
|
|
SendMessage(hWndComboField, CB_SETITEMDATA, (WPARAM) nPos, (LPARAM) g_rgszAdvancedFindAttrs[i]);
|
|
}
|
|
}
|
|
|
|
// Check if this server has advanced Search attributes registered
|
|
if(!bIsPAB)
|
|
{
|
|
LDAPSERVERPARAMS lsp = {0};
|
|
LPTSTR lpBuf = NULL;
|
|
|
|
GetSelectedText(hWndComboContainer, &lpBuf);
|
|
GetLDAPServerParams(lpBuf, &lsp);
|
|
if(lpBuf)
|
|
LocalFree(lpBuf);
|
|
|
|
if(lsp.lpszAdvancedSearchAttr && *(lsp.lpszAdvancedSearchAttr))
|
|
{
|
|
// we need to use this advanced search attributes
|
|
ULONG cchSize = lstrlen(lsp.lpszAdvancedSearchAttr) + 1;
|
|
LPTSTR lp = LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*(cchSize));
|
|
LPTSTR lpAttr = NULL, lpName = NULL;
|
|
BOOL bAssigned = FALSE;
|
|
|
|
if(!lp)
|
|
return;
|
|
StrCpyN(lp, lsp.lpszAdvancedSearchAttr, cchSize);
|
|
|
|
// Attribute format is:
|
|
// Attribute-Display-Name:Attribute,Attribute-Display-Name:Attribute, etc
|
|
// e.g.
|
|
// co:Company,cn:Common Name,etc
|
|
//
|
|
// So we will parse this string and feed it into the combo
|
|
lpAttr = lp;
|
|
while(*lpAttr)
|
|
{
|
|
LPTSTR lpTemp = lpAttr;
|
|
while(*lpTemp && *lpTemp != ':')
|
|
lpTemp++;
|
|
if(*lpTemp != ':')
|
|
break;
|
|
lpName = lpTemp+1;
|
|
*lpTemp = '\0';
|
|
lpTemp = lpName;
|
|
while(*lpTemp && *lpTemp != ',')
|
|
lpTemp++;
|
|
if(*lpTemp == ',')
|
|
{
|
|
*lpTemp = '\0';
|
|
lpTemp++;
|
|
}
|
|
|
|
// Note that the LDAPFilterFieldMax-th item in the list will point to the allocated
|
|
// String 'lp'
|
|
// Hence to clean up we only need to free this item in the combo
|
|
// [PaulHi] 3/4/99 Memory leak fix and @todo
|
|
// Why not just make a copy of g_rgszAdvancedFindAttrs so
|
|
// that special cases like these can be added?
|
|
nPos = (int) SendMessage(hWndComboField, CB_ADDSTRING, 0, (LPARAM) lpName);
|
|
SendMessage(hWndComboField, CB_SETITEMDATA, (WPARAM) nPos, (LPARAM) lpAttr);
|
|
bAssigned = TRUE;
|
|
|
|
lpAttr = lpTemp;
|
|
}
|
|
|
|
// [PaulHi] 3/4/99 Memory leak fix. If this lp pointer isn't passed to the hWndComboField
|
|
// combo box, for whatever reason, we need to deallocate it here.
|
|
if (!bAssigned)
|
|
LocalFreeAndNull(&lp);
|
|
}
|
|
FreeLDAPServerParams(lsp);
|
|
}
|
|
|
|
SendMessage(hWndComboField, CB_SETCURSEL, 0, 0);
|
|
SendMessage(hWndComboCondition, CB_SETCURSEL, 0, 0);
|
|
|
|
}
|
|
|
|
|
|
//$$/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// FillSearchUI - Fills the Search UI with various information
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
BOOL FillSearchUI(HWND hDlg,LPWAB_FIND_PARAMS lpWFP)
|
|
{
|
|
|
|
int i;
|
|
BOOL bRet = FALSE;
|
|
HWND hWndCombo;
|
|
|
|
TCHAR szBuf[MAX_UI_STR];
|
|
LPLDAP_SEARCH_PARAMS lpLDAPsp = &(lpWFP->LDAPsp);
|
|
//
|
|
// Fill the fields if there is anything in the LDAPsp structure
|
|
//
|
|
for(i=0;i<SEARCH_EDIT_MAX;i++)
|
|
{
|
|
switch(rgSearchEditID[i])
|
|
{
|
|
case IDC_FIND_EDIT_NAME:
|
|
StrCpyN(szBuf,lpLDAPsp->szData[ldspDisplayName], ARRAYSIZE(szBuf));
|
|
break;
|
|
case IDC_FIND_EDIT_EMAIL:
|
|
StrCpyN(szBuf,lpLDAPsp->szData[ldspEmail], ARRAYSIZE(szBuf));
|
|
break;
|
|
case IDC_FIND_EDIT_STREET:
|
|
StrCpyN(szBuf,lpLDAPsp->szData[ldspAddress], ARRAYSIZE(szBuf));
|
|
break;
|
|
case IDC_FIND_EDIT_PHONE:
|
|
StrCpyN(szBuf,lpLDAPsp->szData[ldspPhone], ARRAYSIZE(szBuf));
|
|
break;
|
|
case IDC_FIND_EDIT_ANY:
|
|
StrCpyN(szBuf,lpLDAPsp->szData[ldspOther], ARRAYSIZE(szBuf));
|
|
break;
|
|
}
|
|
szBuf[MAX_UI_STR -1] = '\0';
|
|
SetDlgItemText(hDlg,rgSearchEditID[i],szBuf);
|
|
}
|
|
|
|
|
|
//
|
|
// Populate the combo box with the list of LDAP containers and set it to the current selection
|
|
//
|
|
hWndCombo = GetDlgItem(hDlg, IDC_FIND_COMBO_LIST);
|
|
|
|
FreeLVItemParam(hWndCombo);
|
|
|
|
if(lpWFP->lplu)
|
|
{
|
|
LPSERVERDAT lpSD = LocalAlloc(LMEM_ZEROINIT,sizeof(SERVERDAT));
|
|
// Add this one item in the directory service list only ..
|
|
if(lpSD)
|
|
{
|
|
lpSD->himl = NULL;
|
|
lpSD->SB.cb = 0;
|
|
lpSD->SB.lpb = NULL;
|
|
ComboAddItem( hWndCombo, //hWndLV,
|
|
lpWFP->lplu->lpszServer,
|
|
(LPARAM) lpSD,
|
|
NULL, NULL, NULL);
|
|
SetWindowText(hWndCombo, lpWFP->lplu->lpszServer);
|
|
SendMessage(hWndCombo, CB_SETCURSEL, 0, 0);
|
|
}
|
|
|
|
if(lpWFP->lplu->lpList)
|
|
{
|
|
HWND hWndLVResults = GetDlgItem(hDlg, IDC_FIND_LIST_RESULTS);
|
|
HrFillListView(hWndLVResults,
|
|
lpWFP->lplu->lpList);
|
|
UpdateButtons(hDlg, hWndLVResults, hWndCombo, lpWFP->lplu); //hWndLV);
|
|
if(ListView_GetItemCount(hWndLVResults) > 0)
|
|
{
|
|
TCHAR szBuf[MAX_PATH];
|
|
TCHAR szBufStr[MAX_PATH - 6];
|
|
LoadString(hinstMapiX, idsSearchDialogTitleWithResults, szBufStr, ARRAYSIZE(szBufStr));
|
|
wnsprintf(szBuf, ARRAYSIZE(szBuf), szBufStr, ListView_GetItemCount(hWndLVResults));
|
|
SetWindowText(hDlg, szBuf);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TCHAR tsz[MAX_PATH];
|
|
ULONG cb = ARRAYSIZE(tsz);
|
|
LPTSTR lptszPreferredName = NULL;
|
|
|
|
if(!lstrlen(lpLDAPsp->szContainerName))
|
|
{
|
|
LPIAB lpIAB = (LPIAB)lpLDAPsp->lpIAB;
|
|
HKEY hKeyRoot = (lpIAB && lpIAB->hKeyCurrentUser) ? lpIAB->hKeyCurrentUser : HKEY_CURRENT_USER;
|
|
|
|
// Read the last used container name from the registry
|
|
if (ERROR_SUCCESS == RegQueryValue(hKeyRoot, szKeyLastFindServer, tsz, &cb))
|
|
{
|
|
StrCpyN(lpLDAPsp->szContainerName, tsz, ARRAYSIZE(lpLDAPsp->szContainerName));
|
|
}
|
|
|
|
// [PaulHi] 3/19/99 Raid 73461 First check to see if there is a policy setting
|
|
// pointing to the preferred selected server. If so pass this server name in as
|
|
// the preferred container name. We still use the below "szContainerName" as
|
|
// back up if the preferred name doesn't exist in the server enumeration.
|
|
// [PaulHi] 6/22/99 I acutally had this backwards. The policy should be checked
|
|
// in this order: HKLM, HKCU, Identity (instead of Identity, HKCU, HKLM).
|
|
cb = ARRAYSIZE(tsz);
|
|
if (ERROR_SUCCESS == RegQueryValue(HKEY_LOCAL_MACHINE, c_tszPolicyPrefAccount, tsz, &cb))
|
|
{
|
|
lptszPreferredName = tsz;
|
|
}
|
|
else
|
|
{
|
|
// Try looking at HKCU
|
|
cb = ARRAYSIZE(tsz);
|
|
if ( (hKeyRoot != HKEY_CURRENT_USER) &&
|
|
(ERROR_SUCCESS == RegQueryValue(HKEY_CURRENT_USER, c_tszPolicyPrefAccount, tsz, &cb)) )
|
|
{
|
|
lptszPreferredName = tsz;
|
|
}
|
|
else
|
|
{
|
|
// Finally try looking in current identity
|
|
cb = ARRAYSIZE(tsz);
|
|
if(ERROR_SUCCESS == RegQueryValue(hKeyRoot, c_tszPolicyPrefAccount, tsz, &cb))
|
|
{
|
|
lptszPreferredName = tsz;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
PopulateContainerList(lpLDAPsp->lpIAB,
|
|
hWndCombo, // hWndLV,
|
|
lpLDAPsp->szContainerName, // Last used server name
|
|
lptszPreferredName); // Preferred server name
|
|
}
|
|
|
|
// Fill the combos for the advanced field
|
|
FillAdvancedFieldCombos(hDlg, hWndCombo);
|
|
|
|
SetEnableDisableUI(hDlg, hWndCombo, lpWFP->lplu,
|
|
TabCtrl_GetCurSel(GetDlgItem(hDlg, IDC_TAB_FIND)) );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//$$/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// UpdateButtons - Sets the state of the buttons based on various criteria
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
void UpdateButtons(HWND hDlg, HWND hWndLVResults, HWND hWndCombo, LPLDAPURL lplu)
|
|
{
|
|
|
|
BOOL bIsWAB = FALSE;
|
|
BOOL bHasResults = (ListView_GetItemCount(hWndLVResults) > 0) ? TRUE : FALSE;
|
|
int i;
|
|
|
|
if(!lplu && CurrentContainerIsPAB(hWndCombo) != IS_LDAP)
|
|
bIsWAB = TRUE;
|
|
|
|
if (bIsWAB && bHasResults)
|
|
{
|
|
// We have some search results
|
|
EnableWindow(GetDlgItem(hDlg, IDC_FIND_BUTTON_DELETE), TRUE);
|
|
}
|
|
else
|
|
{
|
|
EnableWindow(GetDlgItem(hDlg, IDC_FIND_BUTTON_DELETE), FALSE);
|
|
}
|
|
|
|
if (!bIsWAB && bHasResults)
|
|
{
|
|
EnableWindow(GetDlgItem(hDlg, IDC_FIND_BUTTON_ADDTOWAB), TRUE);
|
|
}
|
|
else
|
|
{
|
|
EnableWindow(GetDlgItem(hDlg, IDC_FIND_BUTTON_ADDTOWAB), FALSE);
|
|
}
|
|
|
|
if(bHasResults)
|
|
{
|
|
EnableWindow(GetDlgItem(hDlg, IDC_FIND_BUTTON_PROPERTIES), TRUE);
|
|
SendMessage (hDlg, DM_SETDEFID, IDC_FIND_BUTTON_PROPERTIES, 0);
|
|
|
|
if(IsWindowVisible(GetDlgItem(hDlg, IDC_FIND_BUTTON_TO)))
|
|
EnableWindow(GetDlgItem(hDlg, IDC_FIND_BUTTON_TO), TRUE);
|
|
if(IsWindowVisible(GetDlgItem(hDlg, IDC_FIND_BUTTON_CC)))
|
|
EnableWindow(GetDlgItem(hDlg, IDC_FIND_BUTTON_CC), TRUE);
|
|
if(IsWindowVisible(GetDlgItem(hDlg, IDC_FIND_BUTTON_BCC)))
|
|
EnableWindow(GetDlgItem(hDlg, IDC_FIND_BUTTON_BCC), TRUE);
|
|
}
|
|
else
|
|
{
|
|
EnableWindow(GetDlgItem(hDlg, IDC_FIND_BUTTON_PROPERTIES), FALSE);
|
|
SendMessage (hDlg, DM_SETDEFID, IDC_FIND_BUTTON_FIND, 0);
|
|
|
|
if(IsWindowVisible(GetDlgItem(hDlg, IDC_FIND_BUTTON_TO)))
|
|
EnableWindow(GetDlgItem(hDlg, IDC_FIND_BUTTON_TO), FALSE);
|
|
if(IsWindowVisible(GetDlgItem(hDlg, IDC_FIND_BUTTON_CC)))
|
|
EnableWindow(GetDlgItem(hDlg, IDC_FIND_BUTTON_CC), FALSE);
|
|
if(IsWindowVisible(GetDlgItem(hDlg, IDC_FIND_BUTTON_BCC)))
|
|
EnableWindow(GetDlgItem(hDlg, IDC_FIND_BUTTON_BCC), FALSE);
|
|
}
|
|
return;
|
|
}
|
|
|
|
|
|
//$$/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// GetAdvancedFilter - Creates an advanced filter from the pieces in the listbox
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
void GetAdvancedFilter(HWND hDlg, LPTSTR * lppAdvFilter, BOOL bLocalSearch, LPLDAP_SEARCH_PARAMS lpLDAPsp)
|
|
{
|
|
LPTSTR lpF = NULL, lp =NULL;
|
|
HWND hWndLB = GetDlgItem(hDlg, IDC_FIND_LIST_CONDITIONS);
|
|
int nCount = 0, nLen = 0, i = 0;
|
|
DWORD cchSizeF = 0;
|
|
|
|
*lppAdvFilter = NULL;
|
|
|
|
nCount = (int) SendMessage(hWndLB, LB_GETCOUNT, 0, 0);
|
|
if(!nCount)
|
|
return;
|
|
|
|
for(i=0;i<nCount;i++)
|
|
{
|
|
lp = (LPTSTR) SendMessage(hWndLB, LB_GETITEMDATA, (WPARAM) i, 0);
|
|
if(lp)
|
|
nLen += lstrlen(lp) + 1;
|
|
}
|
|
|
|
cchSizeF = (nLen+4);
|
|
lpF = LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR) * cchSizeF); //add enough extra spaces for a 3 chars to each subfilter '(''&'')'
|
|
if(!lpF)
|
|
return;
|
|
|
|
StrCpyN(lpF, szEmpty, cchSizeF);
|
|
|
|
// We have to AND all the filters together
|
|
if(nCount > 1)
|
|
StrCatBuff(lpF, TEXT("(&"), cchSizeF);
|
|
|
|
for(i=0;i<nCount;i++)
|
|
{
|
|
lp = (LPTSTR) SendMessage(hWndLB, LB_GETITEMDATA, (WPARAM) i, 0);
|
|
if(lp)
|
|
StrCatBuff(lpF, lp, cchSizeF);
|
|
}
|
|
|
|
if(nCount > 1)
|
|
StrCatBuff(lpF, TEXT(")"), cchSizeF);
|
|
|
|
DebugTrace( TEXT("Filter:%s\n"),lpF);
|
|
|
|
*lppAdvFilter = lpF;
|
|
|
|
if(bLocalSearch)
|
|
{
|
|
// the local search only allows searching on
|
|
}
|
|
}
|
|
|
|
extern OlkContInfo *FindContainer(LPIAB lpIAB, ULONG cbEntryID, LPENTRYID lpEID);
|
|
|
|
//$$/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// DoTheSearchThing - Does the search thing and produces results
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
BOOL DoTheSearchThing(HWND hDlg, LPWAB_FIND_PARAMS lpWFP)
|
|
{
|
|
|
|
int i =0, iItemIndex=0;
|
|
LPTSTR lpBuf = NULL;
|
|
TCHAR szBuf[MAX_UI_STR];
|
|
HWND hWndCombo = GetDlgItem(hDlg, IDC_FIND_COMBO_LIST);
|
|
HWND hWndLVResults = GetDlgItem(hDlg, IDC_FIND_LIST_RESULTS);
|
|
BOOL bRet = FALSE;
|
|
LPLDAP_SEARCH_PARAMS lpLDAPsp = &(lpWFP->LDAPsp);
|
|
HWND hWndAnim = GetDlgItem(hDlg, IDC_FIND_ANIMATE1);
|
|
BOOL bAnimateStart = FALSE;
|
|
HRESULT hr = E_FAIL;
|
|
int SearchType = TRUE;
|
|
LPSBinary lpsbCont = NULL;
|
|
SBinary sbCont = {0};
|
|
LPPTGDATA lpPTGData=GetThreadStoragePointer();
|
|
|
|
HCURSOR hOldCur = SetCursor(LoadCursor(NULL, IDC_WAIT));
|
|
|
|
int nTab = TabCtrl_GetCurSel(GetDlgItem(hDlg, IDC_TAB_FIND));
|
|
LPTSTR lpAdvFilter = NULL;
|
|
|
|
// Check if the current container is an LDAP container or a PAB container
|
|
// or an Outlook contact store container
|
|
if(lpWFP->lplu)
|
|
SearchType = IS_LDAP;
|
|
else
|
|
SearchType = CurrentContainerIsPAB(hWndCombo);
|
|
|
|
// if this is an advanced search, assemble a search filter
|
|
if(tabAdvanced == nTab)
|
|
GetAdvancedFilter(hDlg, &lpAdvFilter, (SearchType != IS_LDAP), lpLDAPsp);
|
|
else
|
|
{
|
|
for(i=0;i<SEARCH_EDIT_MAX;i++)
|
|
{
|
|
if(IsWindowEnabled(GetDlgItem(hDlg, rgSearchEditID[i])))
|
|
{
|
|
GetDlgItemText(hDlg,rgSearchEditID[i],szBuf,ARRAYSIZE(szBuf));
|
|
TrimSpaces(szBuf);
|
|
if (lstrlen(szBuf))
|
|
bRet = TRUE;
|
|
|
|
switch(rgSearchEditID[i])
|
|
{
|
|
case IDC_FIND_EDIT_NAME:
|
|
StrCpyN(lpLDAPsp->szData[ldspDisplayName], szBuf, ARRAYSIZE(lpLDAPsp->szData[0]));
|
|
break;
|
|
case IDC_FIND_EDIT_EMAIL:
|
|
StrCpyN(lpLDAPsp->szData[ldspEmail], szBuf, ARRAYSIZE(lpLDAPsp->szData[0]));
|
|
break;
|
|
case IDC_FIND_EDIT_STREET:
|
|
StrCpyN(lpLDAPsp->szData[ldspAddress], szBuf, ARRAYSIZE(lpLDAPsp->szData[0]));
|
|
break;
|
|
case IDC_FIND_EDIT_PHONE:
|
|
StrCpyN(lpLDAPsp->szData[ldspPhone], szBuf, ARRAYSIZE(lpLDAPsp->szData[0]));
|
|
break;
|
|
case IDC_FIND_EDIT_ANY:
|
|
StrCpyN(lpLDAPsp->szData[ldspOther], szBuf, ARRAYSIZE(lpLDAPsp->szData[0]));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
GetSelectedText(hWndCombo, &lpBuf);
|
|
|
|
StrCpyN(lpLDAPsp->szContainerName, (lpBuf ? lpBuf : szEmpty), ARRAYSIZE(lpLDAPsp->szContainerName));
|
|
|
|
if(lpBuf)
|
|
LocalFree(lpBuf);
|
|
|
|
if((!bRet && nTab == tabSimple) ||
|
|
(!lpAdvFilter && nTab == tabAdvanced) )
|
|
{
|
|
ShowMessageBox(hDlg,idsSpecifySearchCriteria,MB_ICONEXCLAMATION | MB_OK);
|
|
goto out;
|
|
}
|
|
|
|
if(Animate_Open(hWndAnim, MAKEINTRESOURCE(IDR_AVI_WABFIND)))
|
|
{
|
|
if(Animate_Play(hWndAnim, 0, -1, -1))
|
|
bAnimateStart = TRUE;
|
|
}
|
|
|
|
{ // reset the window title
|
|
TCHAR szBuf[MAX_PATH];
|
|
LoadString(hinstMapiX, idsSearchDialogTitle, szBuf, ARRAYSIZE(szBuf));
|
|
SetWindowText(hDlg, szBuf);
|
|
}
|
|
|
|
if(SearchType == IS_PAB)
|
|
{
|
|
lpsbCont = NULL;
|
|
}
|
|
else if(SearchType == IS_OLK)
|
|
{
|
|
if (pt_bIsWABOpenExSession)
|
|
{
|
|
OlkContInfo *polkci;
|
|
// is this an outlook container ?
|
|
GetCurrentContainerEID(hWndCombo,
|
|
&(sbCont.cb),
|
|
(LPENTRYID *)&(sbCont.lpb));
|
|
|
|
EnterCriticalSection((&((LPIAB)lpLDAPsp->lpIAB)->cs));
|
|
polkci = FindContainer((LPIAB)(lpLDAPsp->lpIAB),
|
|
sbCont.cb, (LPENTRYID) sbCont.lpb);
|
|
if(polkci)
|
|
lpsbCont = &sbCont;
|
|
LeaveCriticalSection((&((LPIAB)lpLDAPsp->lpIAB)->cs));
|
|
}
|
|
}
|
|
|
|
// We do the actual search over here ....
|
|
if(SearchType != IS_LDAP)
|
|
{
|
|
// Local Search
|
|
ULONG ulFoundCount = 0;
|
|
LPSBinary rgsbEntryIDs = NULL;
|
|
|
|
ClearListView(hWndLVResults, &(lpWFP->lpContentsList));
|
|
|
|
HrDoLocalWABSearch( ((LPIAB)lpWFP->LDAPsp.lpIAB)->lpPropertyStore->hPropertyStore,
|
|
lpsbCont,
|
|
lpWFP->LDAPsp,
|
|
&ulFoundCount,
|
|
&rgsbEntryIDs);
|
|
|
|
if(ulFoundCount && rgsbEntryIDs)
|
|
{
|
|
ULONG i;
|
|
|
|
for(i=0;i<ulFoundCount;i++)
|
|
{
|
|
LPRECIPIENT_INFO lpItem = NULL;
|
|
|
|
if(!ReadSingleContentItem( lpWFP->LDAPsp.lpIAB,
|
|
rgsbEntryIDs[i].cb,
|
|
(LPENTRYID) rgsbEntryIDs[i].lpb,
|
|
&lpItem))
|
|
continue;
|
|
|
|
if(!lpItem)
|
|
continue;
|
|
//
|
|
// Hook in the lpItem into the lpContentsList so we can free it later
|
|
//
|
|
lpItem->lpPrev = NULL;
|
|
lpItem->lpNext = lpWFP->lpContentsList;
|
|
if (lpWFP->lpContentsList)
|
|
(lpWFP->lpContentsList)->lpPrev = lpItem;
|
|
(lpWFP->lpContentsList) = lpItem;
|
|
}
|
|
|
|
HrFillListView(hWndLVResults, lpWFP->lpContentsList);
|
|
}
|
|
|
|
FreeEntryIDs(((LPIAB)lpWFP->LDAPsp.lpIAB)->lpPropertyStore->hPropertyStore,
|
|
ulFoundCount,
|
|
rgsbEntryIDs);
|
|
|
|
if(ListView_GetItemCount(hWndLVResults) <= 0)
|
|
ShowMessageBox(hDlg,
|
|
pt_bIsWABOpenExSession ? idsNoFolderSearchResults : idsNoLocalSearchResults,
|
|
MB_OK | MB_ICONINFORMATION);
|
|
|
|
hr = S_OK;
|
|
}
|
|
else
|
|
{
|
|
|
|
pt_hWndFind = hDlg;
|
|
|
|
//
|
|
// At this point we can discard the old data
|
|
//
|
|
ClearListView(hWndLVResults,
|
|
(lpWFP->lplu && lpWFP->lplu->lpList) ? &(lpWFP->lplu->lpList) : &(lpWFP->lpContentsList));
|
|
|
|
if(lpWFP->lplu)
|
|
{
|
|
SRestriction Sres = {0};
|
|
if(!lpAdvFilter)
|
|
hr = HrGetLDAPSearchRestriction(lpWFP->LDAPsp, &Sres);
|
|
|
|
hr = LDAPSearchWithoutContainer(hDlg, lpWFP->lplu,
|
|
&Sres,
|
|
lpAdvFilter,
|
|
FALSE,
|
|
MAPI_DIALOG,
|
|
&(lpWFP->lpContentsList),
|
|
NULL,
|
|
NULL);
|
|
|
|
if(!lpAdvFilter && Sres.res.resAnd.lpRes)
|
|
MAPIFreeBuffer(Sres.res.resAnd.lpRes);
|
|
}
|
|
else
|
|
{
|
|
|
|
hr = HrSearchAndGetLDAPContents( lpWFP->LDAPsp,
|
|
lpAdvFilter,
|
|
hWndCombo,
|
|
lpWFP->LDAPsp.lpIAB,
|
|
lpWFP->SortInfo,
|
|
&(lpWFP->lpContentsList));
|
|
}
|
|
|
|
pt_hWndFind = NULL;
|
|
|
|
if(!HR_FAILED(hr))
|
|
{
|
|
#ifdef PAGED_RESULT_SUPPORT
|
|
if(bMorePagedResultsAvailable())
|
|
ShowHideMoreResultsButton(hDlg, TRUE);
|
|
#endif //#ifdef PAGED_RESULT_SUPPORT
|
|
hr = HrFillListView(hWndLVResults,
|
|
lpWFP->lpContentsList);
|
|
}
|
|
else
|
|
{
|
|
#ifdef PAGED_RESULT_SUPPORT
|
|
ClearCachedPagedResultParams();
|
|
ShowHideMoreResultsButton(hDlg, FALSE);
|
|
#endif //#ifdef PAGED_RESULT_SUPPORT
|
|
}
|
|
}
|
|
|
|
UpdateButtons(hDlg, hWndLVResults, hWndCombo, lpWFP->lplu);
|
|
|
|
if(!HR_FAILED(hr))
|
|
{
|
|
// The LDAp search results may not be in any sorted order - so always sort ...
|
|
SortListViewColumn((LPIAB)lpWFP->LDAPsp.lpIAB, hWndLVResults, colDisplayName, &(lpWFP->SortInfo), TRUE);
|
|
|
|
LVSelectItem(hWndLVResults, 0);
|
|
SetFocus(hWndLVResults);
|
|
}
|
|
|
|
if(ListView_GetItemCount(hWndLVResults) > 0)
|
|
{
|
|
TCHAR szBuf[MAX_PATH];
|
|
TCHAR szBufStr[MAX_PATH - 6];
|
|
LoadString(hinstMapiX, idsSearchDialogTitleWithResults, szBufStr, ARRAYSIZE(szBufStr));
|
|
wnsprintf(szBuf, ARRAYSIZE(szBuf), szBufStr, ListView_GetItemCount(hWndLVResults));
|
|
SetWindowText(hDlg, szBuf);
|
|
}
|
|
|
|
bRet = TRUE;
|
|
|
|
out:
|
|
if (bAnimateStart)
|
|
Animate_Stop(hWndAnim);
|
|
|
|
SetCursor(hOldCur);
|
|
|
|
if( bRet &&
|
|
!lpWFP->bShowFullDialog &&
|
|
(ListView_GetItemCount(hWndLVResults) > 0))
|
|
{
|
|
ResizeSearchDlg(hDlg, lpWFP);
|
|
}
|
|
LocalFreeAndNull(&lpAdvFilter);
|
|
return bRet;
|
|
}
|
|
|
|
|
|
//$$/////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Enforces a size in response to user resizing
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////
|
|
LRESULT EnforceSize(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LPWAB_FIND_PARAMS lpWFP )
|
|
{
|
|
LPPOINT lppt = (LPPOINT)lParam; // lParam points to array of POINTs
|
|
if(!lpWFP->bInitialized)
|
|
{
|
|
RECT rc, rc1;
|
|
TCHAR sz[32];
|
|
GetWindowRect(hWnd, &rc);
|
|
GetWindowRect(GetDlgItem(hWnd, IDC_FIND_LIST_RESULTS), &rc1);
|
|
LoadString(hinstMapiX, idsFindDlgWidth, sz, CharSizeOf(sz));
|
|
lpWFP->MinDlgWidth = my_atoi(sz); // the resource is really wide to help localizers .. dont need that much
|
|
lpWFP->MinDlgHeight = (rc1.top - rc.top - 3);
|
|
lpWFP->MinDlgHeightWithResults = (rc.bottom - rc.top);
|
|
}
|
|
lppt[3].x = lpWFP->MinDlgWidth;
|
|
if(!lpWFP->bShowFullDialog)
|
|
{
|
|
lppt[4].y = lppt[3].y = lpWFP->MinDlgHeight;
|
|
}
|
|
else
|
|
{
|
|
lppt[3].y = lpWFP->MinDlgHeightWithResults;
|
|
}
|
|
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
|
|
|
}
|
|
|
|
|
|
#define FIND_BUTTON_MAX 12 //Keep in sync with array below
|
|
int rgFindButtonID[]=
|
|
{
|
|
IDC_FIND_BUTTON_FIND,
|
|
IDC_FIND_BUTTON_SERVER_INFO,
|
|
IDC_FIND_BUTTON_STOP,
|
|
IDC_FIND_BUTTON_CLEAR,
|
|
IDC_FIND_BUTTON_CLOSE,
|
|
IDC_FIND_BUTTON_PROPERTIES,
|
|
IDC_FIND_BUTTON_DELETE,
|
|
IDC_FIND_BUTTON_ADDTOWAB,
|
|
IDC_FIND_BUTTON_MORE,
|
|
IDC_FIND_BUTTON_TO,
|
|
IDC_FIND_BUTTON_CC,
|
|
IDC_FIND_BUTTON_BCC
|
|
};
|
|
|
|
//$$*************************************************************************
|
|
//
|
|
// ResizeFindDialog - Resizes the child controls on the dialog in response to
|
|
// a WM_SIZE message
|
|
//
|
|
//
|
|
//***************************************************************************
|
|
void ResizeFindDialog(HWND hDlg, WPARAM wParam, LPARAM lParam, LPWAB_FIND_PARAMS lpWFP)
|
|
{
|
|
DWORD fwSizeType = (DWORD) wParam; // resizing flag
|
|
int nWidth = LOWORD(lParam); // width of client area
|
|
int nHeight = HIWORD(lParam); // height of client area
|
|
POINT ptLU; // Left, Upper vertex
|
|
POINT ptRB; // Right, Bottom vertex
|
|
RECT rc, rc1, rcDlg;
|
|
int nButtonWidth, nButtonHeight;
|
|
int nEditWidth, nEditHeight;
|
|
int nLVWidth, nLVHeight;
|
|
int nFrameWidth;
|
|
int nAnimateWidth, nAnimateHeight;
|
|
HWND hWndC = NULL;
|
|
|
|
int i;
|
|
|
|
HDWP hdwp = BeginDeferWindowPos(12);
|
|
|
|
// Resize based on width
|
|
|
|
// Move all the buttons to the right edge
|
|
for(i=0;i<FIND_BUTTON_MAX;i++)
|
|
{
|
|
hWndC = GetDlgItem(hDlg,rgFindButtonID[i]);
|
|
GetWindowRect(hWndC,&rc);
|
|
nButtonWidth = (rc.right - rc.left);
|
|
nButtonHeight = (rc.bottom - rc.top);
|
|
|
|
ptLU.y = rc.top;
|
|
ptLU.x = 0;
|
|
|
|
ScreenToClient(hDlg, &ptLU);
|
|
ptLU.x = nWidth - BORDER_SPACE - nButtonWidth;
|
|
|
|
MoveWindow(hWndC,ptLU.x,ptLU.y,nButtonWidth, nButtonHeight, TRUE);
|
|
}
|
|
|
|
nLVWidth = nWidth - BORDER_SPACE - BORDER_SPACE - nButtonWidth - BORDER_SPACE;
|
|
|
|
// Move the animation control too
|
|
hWndC = GetDlgItem(hDlg,IDC_FIND_ANIMATE1);
|
|
GetWindowRect(hWndC,&rc1);
|
|
nAnimateWidth = rc1.right - rc1.left;
|
|
nAnimateHeight = rc1.bottom - rc1.top;
|
|
ptLU.x = rc1.left;
|
|
ptLU.y = rc1.top;
|
|
ScreenToClient(hDlg, &ptLU);
|
|
ptLU.x = nWidth - BORDER_SPACE - nButtonWidth + (nButtonWidth - nAnimateWidth)/2;
|
|
MoveWindow(hWndC, ptLU.x, ptLU.y, nAnimateWidth, nAnimateHeight,TRUE);
|
|
|
|
// Resize the Combo
|
|
hWndC = GetDlgItem(hDlg,IDC_FIND_COMBO_LIST);
|
|
GetWindowRect(hWndC,&rc);
|
|
nLVHeight = rc.bottom - rc.top;
|
|
//
|
|
//This api works for both mirrored and unmirrored windows.
|
|
//
|
|
MapWindowPoints(NULL, hDlg, (LPPOINT)&rc, 2);
|
|
ptLU.x = rc.left;
|
|
ptLU.y = rc.top;
|
|
nFrameWidth = nLVWidth + BORDER_SPACE - ptLU.x;
|
|
MoveWindow(hWndC, ptLU.x, ptLU.y, nFrameWidth, nLVHeight,TRUE);
|
|
ptRB.x = ptLU.x + nFrameWidth;
|
|
|
|
// Resize the TAB
|
|
hWndC = GetDlgItem(hDlg,IDC_TAB_FIND);
|
|
GetWindowRect(hWndC,&rc);
|
|
nLVHeight = rc.bottom - rc.top;
|
|
//
|
|
//This api working in both mirrored and unmirrored windows.
|
|
//
|
|
MapWindowPoints(NULL, hDlg, (LPPOINT)&rc, 2);
|
|
ptLU.x = rc.left;
|
|
ptLU.y = rc.top;
|
|
nFrameWidth = nLVWidth + BORDER_SPACE - ptLU.x;
|
|
MoveWindow(hWndC, ptLU.x, ptLU.y, nFrameWidth, nLVHeight,TRUE);
|
|
ptRB.x = ptLU.x + nFrameWidth;
|
|
|
|
// Resize the Edit Controls
|
|
for(i=0;i<SEARCH_EDIT_MAX;i++)
|
|
{
|
|
hWndC = GetDlgItem(hDlg,rgSearchEditID[i]);
|
|
GetWindowRect(hWndC,&rc);
|
|
|
|
nEditHeight = (rc.bottom - rc.top);
|
|
//
|
|
//This api works for both mirrored and unmirrored windows.
|
|
//
|
|
MapWindowPoints(NULL, hDlg, (LPPOINT)&rc, 2);
|
|
|
|
ptLU.y = rc.top;
|
|
ptLU.x = rc.left;
|
|
|
|
nEditWidth = ptRB.x - BORDER_SPACE - ptLU.x; //ptRB.x is x coordinate of frame right edge
|
|
|
|
MoveWindow(hWndC,ptLU.x,ptLU.y,nEditWidth, nEditHeight, TRUE);
|
|
}
|
|
|
|
// Resize the advanced controls
|
|
// First the group-box
|
|
{
|
|
hWndC = GetDlgItem(hDlg,IDC_FIND_STATIC_ADVANCED);
|
|
GetWindowRect(hWndC,&rc);
|
|
nEditHeight = (rc.bottom - rc.top);
|
|
//
|
|
//This api works for both mirrored and unmirrored windows.
|
|
//
|
|
MapWindowPoints(NULL, hDlg, (LPPOINT)&rc, 2);
|
|
ptLU.y = rc.top;
|
|
ptLU.x = rc.left;
|
|
nEditWidth = ptRB.x - BORDER_SPACE - ptLU.x; //ptRB.x is x coordinate of tab right edge
|
|
// update this variable with the group-box right border
|
|
ptRB.x = ptLU.x + nEditWidth;
|
|
MoveWindow(hWndC,ptLU.x,ptLU.y,nEditWidth, nEditHeight, TRUE);
|
|
}
|
|
|
|
// Resize the Advanced edit controls also
|
|
{
|
|
hWndC = GetDlgItem(hDlg,IDC_FIND_COMBO_FIELD);
|
|
GetWindowRect(hWndC,&rc);
|
|
nEditHeight = (rc.bottom - rc.top);
|
|
//
|
|
//This api works for both mirrored and unmirrored windows.
|
|
//
|
|
MapWindowPoints(NULL, hDlg, (LPPOINT)&rc, 2);
|
|
ptLU.y = rc.top;
|
|
ptLU.x = rc.left;
|
|
nEditWidth = (ptRB.x - BORDER_SPACE - 2*CONTROL_SPACE - ptLU.x)/3; //ptRB.x is x coordinate of frame right edge
|
|
MoveWindow(hWndC,ptLU.x,ptLU.y,nEditWidth, nEditHeight, TRUE);
|
|
|
|
hWndC = GetDlgItem(hDlg,IDC_FIND_COMBO_CONDITION);
|
|
ptLU.x += nEditWidth + CONTROL_SPACE;
|
|
MoveWindow(hWndC,ptLU.x,ptLU.y,nEditWidth, nEditHeight, TRUE);
|
|
|
|
hWndC = GetDlgItem(hDlg,IDC_FIND_EDIT_ADVANCED);
|
|
ptLU.x += nEditWidth + CONTROL_SPACE;
|
|
MoveWindow(hWndC,ptLU.x,ptLU.y,nEditWidth, nEditHeight, TRUE);
|
|
}
|
|
|
|
// Move the two advanced buttons
|
|
for(i=0;i<2;i++)
|
|
{
|
|
hWndC = GetDlgItem(hDlg,rgAdvancedButtons[i]);
|
|
GetWindowRect(hWndC,&rc);
|
|
nEditHeight = (rc.bottom - rc.top);
|
|
//
|
|
//This api works for both mirrored and unmirrored windows.
|
|
//
|
|
MapWindowPoints(NULL, hDlg, (LPPOINT)&rc, 2);
|
|
ptLU.y = rc.top;
|
|
ptLU.x = rc.left;
|
|
nEditWidth = rc.right - rc.left; // Dont modify width of the button
|
|
ptLU.x = ptRB.x - BORDER_SPACE - nEditWidth;
|
|
MoveWindow(hWndC,ptLU.x,ptLU.y,nEditWidth, nEditHeight, TRUE);
|
|
}
|
|
// update this variable with the left edge of the button
|
|
// List box width is adjusted based on this
|
|
ptRB.x = ptLU.x;
|
|
|
|
// Adjust the listbox width
|
|
{
|
|
hWndC = GetDlgItem(hDlg,IDC_FIND_LIST_CONDITIONS);
|
|
GetWindowRect(hWndC,&rc);
|
|
nEditHeight = (rc.bottom - rc.top);
|
|
//
|
|
//This api works for both mirrored and unmirrored windows.
|
|
//
|
|
MapWindowPoints(NULL, hDlg, (LPPOINT)&rc, 2);
|
|
ptLU.y = rc.top;
|
|
ptLU.x = rc.left;
|
|
nEditWidth = ptRB.x - BORDER_SPACE - ptLU.x; //ptRB.x is x coordinate of frame right edge
|
|
MoveWindow(hWndC,ptLU.x,ptLU.y,nEditWidth, nEditHeight, TRUE);
|
|
}
|
|
|
|
// For the height, we only adjust the list view height
|
|
|
|
// Resize the List View
|
|
hWndC = GetDlgItem(hDlg,IDC_FIND_LIST_RESULTS);
|
|
GetWindowRect(hWndC,&rc);
|
|
//
|
|
//This api works for both mirrored and unmirrored windows.
|
|
//
|
|
MapWindowPoints(NULL, hDlg, (LPPOINT)&rc, 2);
|
|
ptLU.x = rc.left;
|
|
ptLU.y = rc.top;
|
|
nLVHeight = nHeight - BORDER_SPACE - ptLU.y;
|
|
MoveWindow(hWndC, ptLU.x, ptLU.y, nLVWidth, nLVHeight,TRUE);
|
|
|
|
EndDeferWindowPos(hdwp);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
//$$**************************************************************************
|
|
//
|
|
// ShowContainerContextMenu - Shows the context menu for the container list
|
|
//
|
|
//
|
|
//****************************************************************************
|
|
/****/
|
|
void ShowContainerContextMenu(HWND hDlg,
|
|
HWND hWndCombo, //hWndLV,
|
|
LPARAM lParam)
|
|
{
|
|
HMENU hMenu = LoadMenu(hinstMapiX, MAKEINTRESOURCE(IDM_FIND_CONTEXTMENU_CONTAINER));
|
|
HMENU hMenuTrackPopUp = GetSubMenu(hMenu, 0);
|
|
|
|
if (!hMenu || !hMenuTrackPopUp)
|
|
{
|
|
DebugPrintError(( TEXT("LoadMenu failed: %x\n"),GetLastError()));
|
|
goto out;
|
|
}
|
|
|
|
if (CurrentContainerIsPAB(hWndCombo) != IS_LDAP)
|
|
EnableMenuItem(hMenuTrackPopUp,IDM_FIND_CONTAINERPROPERTIES,MF_BYCOMMAND | MF_GRAYED);
|
|
|
|
//
|
|
// Popup the menu
|
|
//
|
|
TrackPopupMenu( hMenuTrackPopUp,
|
|
TPM_LEFTALIGN | TPM_RIGHTBUTTON,
|
|
LOWORD(lParam),
|
|
HIWORD(lParam),
|
|
0,
|
|
hDlg,
|
|
NULL);
|
|
|
|
DestroyMenu(hMenu);
|
|
|
|
out:
|
|
return;
|
|
}
|
|
/****/
|
|
//$$**************************************************************************
|
|
//
|
|
// ShowContainerProperties - Shows the context menu for the container list
|
|
//
|
|
// hWndLV - list containing the list of containers
|
|
// We dont show any properties for the address book
|
|
//
|
|
//****************************************************************************
|
|
void ShowContainerProperties( HWND hDlg,
|
|
HWND hWndCombo,
|
|
LPWAB_FIND_PARAMS lpWFP)
|
|
{
|
|
LPTSTR lpBuf = NULL;
|
|
|
|
GetSelectedText(hWndCombo, &lpBuf);
|
|
|
|
if(!lpBuf || !lstrlen(lpBuf))
|
|
{
|
|
ShowMessageBox(hDlg, IDS_ADDRBK_MESSAGE_NO_ITEM, MB_OK | MB_ICONEXCLAMATION);
|
|
}
|
|
else
|
|
{
|
|
if(CurrentContainerIsPAB(hWndCombo) == IS_LDAP)
|
|
{
|
|
LPTSTR ptszName=NULL;
|
|
|
|
HrShowDSProps(hDlg, lpBuf, &ptszName, FALSE);
|
|
|
|
if (ptszName)
|
|
{
|
|
if(lstrcmpi(lpBuf, ptszName))
|
|
{
|
|
// The name changed, update it in the list view ...
|
|
SendMessage(hWndCombo, WM_SETREDRAW, FALSE, 0);
|
|
FreeLVItemParam(hWndCombo);
|
|
SendMessage(hWndCombo, CB_RESETCONTENT, 0, 0);
|
|
PopulateContainerList( lpWFP->LDAPsp.lpIAB,
|
|
hWndCombo, ptszName, NULL);
|
|
|
|
SendMessage(hWndCombo, WM_SETREDRAW, TRUE, 0);
|
|
SetEnableDisableUI(hDlg, hWndCombo, lpWFP->lplu,
|
|
TabCtrl_GetCurSel(GetDlgItem(hDlg, IDC_TAB_FIND)));
|
|
}
|
|
LocalFreeAndNull(&ptszName);
|
|
}
|
|
}
|
|
}
|
|
LocalFreeAndNull(&lpBuf);
|
|
return;
|
|
}
|
|
|
|
enum
|
|
{
|
|
filtContains=0,
|
|
filtIs,
|
|
filtStartsWith,
|
|
filtEndsWith,
|
|
filtSoundsLike,
|
|
filtMax
|
|
};
|
|
|
|
|
|
extern void EscapeIllegalChars(LPTSTR lpszSrcStr, LPTSTR lpszDestStr, ULONG cchDestStr);
|
|
|
|
/*//$$************************************************************************
|
|
//
|
|
// CreateSubFilter();
|
|
// Creates a subfilter basedon available data
|
|
//
|
|
// szFIlter is a preallocated buffer big enough
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////*/
|
|
void CreateSubFilter(LPTSTR pszField, int nCondition, LPTSTR pszText, LPTSTR pszFilter, DWORD cchSizeFilter)
|
|
{
|
|
LPTSTR pszTemplate = NULL;
|
|
TCHAR szCleanText[MAX_PATH*2];
|
|
|
|
EscapeIllegalChars(pszText, szCleanText, ARRAYSIZE(szCleanText));
|
|
|
|
switch(nCondition)
|
|
{
|
|
case filtContains:
|
|
pszTemplate = TEXT("(%s=*%s*)");
|
|
break;
|
|
case filtIs:
|
|
pszTemplate = TEXT("(%s=%s)");
|
|
break;
|
|
case filtStartsWith:
|
|
pszTemplate = TEXT("(%s=%s*)");
|
|
break;
|
|
case filtEndsWith:
|
|
pszTemplate = TEXT("(%s=*%s)");
|
|
break;
|
|
case filtSoundsLike:
|
|
pszTemplate = TEXT("(%s=~%s)");
|
|
break;
|
|
}
|
|
wnsprintf(pszFilter, cchSizeFilter, pszTemplate, pszField, szCleanText);
|
|
}
|
|
|
|
/*//$$************************************************************************
|
|
//
|
|
// HrAddFindFilterCondition(hDlg);
|
|
// Adds a condition to the advanced find list box
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////*/
|
|
HRESULT HrAddFindFilterCondition(HWND hDlg)
|
|
{
|
|
HWND hWndComboField = GetDlgItem(hDlg, IDC_FIND_COMBO_FIELD);
|
|
HWND hWndComboCondition = GetDlgItem(hDlg, IDC_FIND_COMBO_CONDITION);
|
|
HWND hWndLB = GetDlgItem(hDlg, IDC_FIND_LIST_CONDITIONS);
|
|
HRESULT hr = E_FAIL;
|
|
int nID = 0, nCount = 0, nPos = 0;
|
|
LPTSTR lpField = NULL, lpCondition = NULL, lpsz[3], lpFilter = NULL;
|
|
TCHAR szField[MAX_PATH], szCondition[MAX_PATH];
|
|
TCHAR szText[MAX_PATH], szString[MAX_PATH], szFormat[MAX_PATH];
|
|
DWORD cchSize = 0;
|
|
|
|
// if the text field is empty, do nothing
|
|
GetDlgItemText(hDlg, IDC_FIND_EDIT_ADVANCED, szText, ARRAYSIZE(szText));
|
|
if(!lstrlen(szText))
|
|
goto out;
|
|
|
|
// depending on whether this is the 1st item or not, there is an And in the beginning
|
|
nCount = (int) SendMessage(hWndLB, LB_GETCOUNT, 0, 0);
|
|
nID = ((nCount > 0) ? idsFindFilterAnd : idsFindFilter);
|
|
LoadString(hinstMapiX, nID, szFormat, ARRAYSIZE(szFormat));
|
|
|
|
// Get the selected item in the Field Combo
|
|
nPos = (int) SendMessage(hWndComboField, CB_GETCURSEL, 0, 0);
|
|
if(nPos == CB_ERR)
|
|
goto out;
|
|
cchSize = (DWORD)SendMessage(hWndComboField, CB_GETLBTEXTLEN, (WPARAM) nPos, (LPARAM) 0);
|
|
if ((cchSize == CB_ERR) || (ARRAYSIZE(szField) < cchSize))
|
|
goto out;
|
|
SendMessage(hWndComboField, CB_GETLBTEXT, (WPARAM) nPos, (LPARAM) szField);
|
|
lpField = (LPTSTR) SendMessage(hWndComboField, CB_GETITEMDATA, (WPARAM) nPos, 0);
|
|
|
|
// Get the selected item in the Condition Combo
|
|
nPos = (int) SendMessage(hWndComboCondition, CB_GETCURSEL, 0, 0);
|
|
if(nPos == CB_ERR)
|
|
goto out;
|
|
cchSize =(DWORD)SendMessage(hWndComboCondition, CB_GETLBTEXTLEN, (WPARAM) nPos, (LPARAM) 0);
|
|
if ((cchSize == CB_ERR) || (ARRAYSIZE(szCondition) < cchSize))
|
|
goto out;
|
|
SendMessage(hWndComboCondition, CB_GETLBTEXT, (WPARAM) nPos, (LPARAM) szCondition);
|
|
|
|
// Now create the formatted message
|
|
if( (lstrlen(szField) > 1023) ||
|
|
(lstrlen(szCondition) > 1023) ||
|
|
(lstrlen(szText) > 1023))
|
|
goto out;
|
|
|
|
lpsz[0] = szField;
|
|
lpsz[1] = szCondition;
|
|
lpsz[2] = szText;
|
|
|
|
if (! FormatMessage( FORMAT_MESSAGE_FROM_STRING |
|
|
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
FORMAT_MESSAGE_ARGUMENT_ARRAY,
|
|
szFormat,
|
|
0, // stringid
|
|
0, // dwLanguageId
|
|
(LPTSTR)&lpCondition, // output buffer
|
|
0,
|
|
(va_list *)lpsz))
|
|
{
|
|
DebugTrace( TEXT("FormatMessage -> %u\n"), GetLastError());
|
|
goto out;
|
|
}
|
|
// <TBD> create the sub filter at this point
|
|
CreateSubFilter(lpField, nPos, szText, szString, ARRAYSIZE(szString));
|
|
|
|
cchSize = (lstrlen(szString)+1);
|
|
lpFilter = LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)* cchSize);
|
|
if(!lpFilter)
|
|
goto out;
|
|
StrCpyN(lpFilter, szString, cchSize);
|
|
|
|
nPos = (int) SendMessage(hWndLB, LB_ADDSTRING, 0, (LPARAM) lpCondition);
|
|
SendMessage(hWndLB, LB_SETITEMDATA, (WPARAM) nPos, (LPARAM) lpFilter);
|
|
SendMessage(hWndLB, LB_SETCURSEL, (WPARAM) nPos, 0);
|
|
DebugTrace( TEXT("%s\n"), lpFilter);
|
|
|
|
hr = S_OK;
|
|
out:
|
|
IF_WIN32(LocalFree(lpCondition);)
|
|
IF_WIN16(FormatMessageFreeMem(lpCondition);)
|
|
return hr;
|
|
}
|
|
|
|
|
|
//$$*************************************************************************
|
|
//
|
|
// DoInitialFindDlgResizing -
|
|
//
|
|
// There are so many controls (some which overlap) on the find dialog that
|
|
// localizers can't make head or tail of them - so we spread the controls around
|
|
// in the resource description and then at runtime, we move them all to their
|
|
// appropriate locations - right now, this means shifting the Advanced-Pane
|
|
// controls to be flush left with the beginning of the name static ..
|
|
//
|
|
//***************************************************************************
|
|
void DoInitialFindDlgResizing (HWND hDlg)
|
|
{
|
|
POINT ptLU; // Left, Upper vertex
|
|
RECT rcN, rcF, rc;
|
|
HWND hWndC = NULL;
|
|
int nMove = 0, nButtonWidth = 0 , nButtonHeight = 0;
|
|
|
|
int rgAdv[] = { IDC_FIND_STATIC_ADVANCED,
|
|
IDC_FIND_COMBO_FIELD,
|
|
IDC_FIND_COMBO_CONDITION,
|
|
IDC_FIND_EDIT_ADVANCED,
|
|
IDC_FIND_LIST_CONDITIONS,
|
|
IDC_FIND_BUTTON_ADDCONDITION,
|
|
IDC_FIND_BUTTON_REMOVECONDITION };
|
|
int i = 0, nAdvMax = 7;
|
|
|
|
GetWindowRect(GetDlgItem(hDlg, IDC_FIND_STATIC_NAME), &rcN);
|
|
GetWindowRect(GetDlgItem(hDlg, IDC_FIND_STATIC_ADVANCED), &rcF);
|
|
MapWindowPoints(NULL, hDlg, (LPPOINT)&rcN, 2);
|
|
MapWindowPoints(NULL, hDlg, (LPPOINT)&rcF, 2);
|
|
|
|
nMove = rcF.left - rcN.left; // we want to move everything left this many units
|
|
|
|
for(i=0;i<nAdvMax;i++)
|
|
{
|
|
hWndC = GetDlgItem(hDlg,rgAdv[i]);
|
|
GetWindowRect(hWndC,&rc);
|
|
|
|
nButtonWidth = (rc.right - rc.left);
|
|
nButtonHeight = (rc.bottom - rc.top);
|
|
|
|
MapWindowPoints(NULL, hDlg, (LPPOINT)&rc, 2);
|
|
|
|
ptLU.y = rc.top;
|
|
ptLU.x = rc.left;
|
|
|
|
// ScreenToClient(hDlg, &ptLU);
|
|
ptLU.x -= nMove;
|
|
|
|
MoveWindow(hWndC,ptLU.x,ptLU.y,nButtonWidth, nButtonHeight, TRUE);
|
|
}
|
|
}
|
|
/****/
|
|
|
|
/*//$$************************************************************************
|
|
//
|
|
// fnSearch - Search Dialog Proc
|
|
//
|
|
**************************************************************************/
|
|
INT_PTR CALLBACK fnSearch(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
ULONG nLen = 0, nLenMax = 0, nRetVal=0;
|
|
HRESULT hr = hrSuccess;
|
|
static FILETIME ftLast = {0};
|
|
|
|
LPWAB_FIND_PARAMS lpWFP = (LPWAB_FIND_PARAMS) GetWindowLongPtr(hDlg,DWLP_USER);
|
|
LPLDAP_SEARCH_PARAMS lpLDAPsp = &(lpWFP->LDAPsp);
|
|
|
|
switch(message)
|
|
{
|
|
case WM_INITDIALOG:
|
|
SetWindowLongPtr(hDlg,DWLP_USER,lParam); //Save this for future reference
|
|
lpWFP = (LPWAB_FIND_PARAMS) lParam;
|
|
lpLDAPsp = &(lpWFP->LDAPsp);
|
|
{
|
|
HICON hIcon = LoadIcon(hinstMapiX, MAKEINTRESOURCE(IDI_ICON_ABOOK));
|
|
SendMessage(hDlg, WM_SETICON, (WPARAM) ICON_BIG, (LPARAM) hIcon);
|
|
}
|
|
DoInitialFindDlgResizing (hDlg);
|
|
SetSearchUI(hDlg,lpWFP);
|
|
FillSearchUI(hDlg,lpWFP);
|
|
if(!GetParent(hDlg))
|
|
{
|
|
// Then this is going to be a top level dialog and won't block any identity
|
|
// changes .. most likely it came from the Find | People option
|
|
// In case the address book object is ready to receive identity change
|
|
// notifications, we should set our hWnd on the LPIAB object so we get a
|
|
// message telling us to refresh the user ..
|
|
((LPIAB)(lpLDAPsp->lpIAB))->hWndBrowse = hDlg;
|
|
}
|
|
SetForegroundWindow(hDlg); // On OSR2, this window will sometimes not come up in focus - needs explicit call
|
|
lpWFP->bInitialized = TRUE;
|
|
break;
|
|
|
|
case WM_GETMINMAXINFO:
|
|
//enforce a minimum size for sanity
|
|
return EnforceSize(hDlg, message, wParam, lParam, lpWFP);
|
|
break;
|
|
|
|
default:
|
|
#ifndef WIN16
|
|
if((g_msgMSWheel && message == g_msgMSWheel)
|
|
// || message == WM_MOUSEWHEEL
|
|
)
|
|
{
|
|
if(GetFocus() == GetDlgItem(hDlg, IDC_FIND_LIST_RESULTS))
|
|
SendMessage(GetDlgItem(hDlg, IDC_FIND_LIST_RESULTS), message, wParam, lParam);
|
|
break;
|
|
}
|
|
#endif
|
|
return FALSE;
|
|
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
|
|
ShowHideMoreResultsButton(hDlg, FALSE);
|
|
switch(LOWORD(wParam))
|
|
{
|
|
case IDC_FIND_EDIT_ADVANCED:
|
|
EnableWindow(GetDlgItem(hDlg, IDC_FIND_BUTTON_ADDCONDITION), TRUE);
|
|
// Set focus on the ADD button
|
|
SendMessage (hDlg, DM_SETDEFID, IDC_FIND_BUTTON_ADDCONDITION, 0);
|
|
break;
|
|
default:
|
|
SendMessage (hDlg, DM_SETDEFID, IDC_FIND_BUTTON_FIND, 0);
|
|
break;
|
|
}
|
|
break;
|
|
case CBN_SELCHANGE:
|
|
ShowHideMoreResultsButton(hDlg, FALSE);
|
|
switch(LOWORD(wParam))
|
|
{
|
|
case IDC_FIND_COMBO_LIST:
|
|
FillAdvancedFieldCombos(hDlg, (HWND) lParam);
|
|
SetEnableDisableUI(hDlg, (HWND) lParam, lpWFP->lplu,
|
|
TabCtrl_GetCurSel(GetDlgItem(hDlg, IDC_TAB_FIND)));
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
switch (GET_WM_COMMAND_ID(wParam,lParam))
|
|
{
|
|
default:
|
|
return ProcessActionCommands( (LPIAB) lpWFP->LDAPsp.lpIAB,
|
|
GetDlgItem(hDlg, IDC_FIND_LIST_RESULTS),
|
|
hDlg, message, wParam, lParam);
|
|
break;
|
|
|
|
case IDC_FIND_BUTTON_REMOVECONDITION:
|
|
{
|
|
HWND hWndLB = GetDlgItem(hDlg, IDC_FIND_LIST_CONDITIONS);
|
|
int nCount = 0, nPos = (int) SendMessage(hWndLB, LB_GETCURSEL, 0, 0);
|
|
if(nPos != LB_ERR)
|
|
{
|
|
LPTSTR lp = (LPTSTR) SendMessage(hWndLB, LB_GETITEMDATA, (WPARAM) nPos, 0);
|
|
if(lp)
|
|
LocalFree(lp);
|
|
SendMessage(hWndLB, LB_DELETESTRING, (WPARAM) nPos, 0);
|
|
nCount = (int) SendMessage(hWndLB, LB_GETCOUNT, 0, 0);
|
|
if(nCount == 0)
|
|
EnableWindow(GetDlgItem(hDlg, IDC_FIND_BUTTON_REMOVECONDITION), FALSE);
|
|
else
|
|
{
|
|
if(nPos >= nCount)
|
|
nPos--;
|
|
SendMessage(hWndLB, LB_SETCURSEL, (WPARAM) nPos, 0);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case IDC_FIND_BUTTON_ADDCONDITION:
|
|
HrAddFindFilterCondition(hDlg);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_FIND_BUTTON_REMOVECONDITION), TRUE);
|
|
// Default button is FIND
|
|
SendMessage (hDlg, DM_SETDEFID, IDC_FIND_BUTTON_FIND, 0);
|
|
break;
|
|
|
|
case IDC_FIND_BUTTON_STOP:
|
|
if(lpWFP->bLDAPActionInProgress)
|
|
{
|
|
LPPTGDATA lpPTGData=GetThreadStoragePointer();
|
|
if(pt_hDlgCancel)
|
|
SendMessage(pt_hDlgCancel, WM_COMMAND, (WPARAM) IDCANCEL, 0);
|
|
}
|
|
break;
|
|
|
|
|
|
// only difference between FIND and MORE is that
|
|
// in MORE we repeat the search with the cached paged result cookie
|
|
// if one exists. If the cookie doesnt exist, user wouldnt get to
|
|
// see the MORE button
|
|
// Any change in search parameters also hides the MORE button
|
|
case IDC_FIND_BUTTON_FIND:
|
|
#ifdef PAGED_RESULT_SUPPORT
|
|
if(!lpWFP->bLDAPActionInProgress)
|
|
ClearCachedPagedResultParams();
|
|
#endif //#ifdef PAGED_RESULT_SUPPORT
|
|
case IDC_FIND_BUTTON_MORE:
|
|
// 96/11/20 markdu BUG 11030
|
|
// Disable the find now button so we only get one search.
|
|
if(!lpWFP->bLDAPActionInProgress)
|
|
{
|
|
LPPTGDATA lpPTGData=GetThreadStoragePointer();
|
|
pt_bDontShowCancel = TRUE;
|
|
lpWFP->bUserCancel = FALSE;
|
|
lpWFP->bLDAPActionInProgress = TRUE;
|
|
ShowHideMoreResultsButton(hDlg, FALSE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_FIND_BUTTON_FIND), FALSE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_FIND_BUTTON_STOP), TRUE);
|
|
DoTheSearchThing(hDlg, lpWFP);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_FIND_BUTTON_FIND), TRUE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_FIND_BUTTON_STOP), FALSE);
|
|
lpWFP->bLDAPActionInProgress = FALSE;
|
|
pt_bDontShowCancel = FALSE;
|
|
if(lpWFP->bUserCancel) // DId the user try to cancel while the search was happening
|
|
{
|
|
lpWFP->bUserCancel = FALSE;
|
|
PostMessage(hDlg, WM_COMMAND, (WPARAM) IDC_FIND_BUTTON_CLOSE, 0);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IDC_FIND_BUTTON_CLEAR:
|
|
if(!lpWFP->bLDAPActionInProgress)
|
|
{
|
|
int i;
|
|
TCHAR szBuf[MAX_PATH];
|
|
|
|
LoadString(hinstMapiX, idsSearchDialogTitle, szBuf, ARRAYSIZE(szBuf));
|
|
SetWindowText(hDlg, szBuf);
|
|
|
|
for(i=0;i<SEARCH_EDIT_MAX;i++)
|
|
SetDlgItemText(hDlg, rgSearchEditID[i], szEmpty);
|
|
|
|
// Clear the advanced buttons too
|
|
SetDlgItemText(hDlg, IDC_FIND_EDIT_ADVANCED, szEmpty);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_FIND_BUTTON_ADDCONDITION), FALSE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_FIND_BUTTON_REMOVECONDITION), FALSE);
|
|
SendDlgItemMessage(hDlg, IDC_FIND_LIST_CONDITIONS, LB_RESETCONTENT, 0, 0);
|
|
|
|
ClearListView( GetDlgItem(hDlg, IDC_FIND_LIST_RESULTS),
|
|
(lpWFP->lplu && lpWFP->lplu->lpList) ? &(lpWFP->lplu->lpList) : &(lpWFP->lpContentsList));
|
|
|
|
for(i=0;i<ldspMAX;i++)
|
|
{
|
|
StrCpyN(lpLDAPsp->szData[i], szEmpty, ARRAYSIZE(lpLDAPsp->szData[i]));
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IDOK:
|
|
case IDCANCEL:
|
|
case IDC_FIND_BUTTON_CLOSE:
|
|
// Clear any contents in the Advanced LB
|
|
{
|
|
int nCount = 0, i = 0;
|
|
HWND hWndLB = GetDlgItem(hDlg, IDC_FIND_LIST_CONDITIONS);
|
|
nCount = (int) SendMessage(hWndLB, LB_GETCOUNT, 0, 0);
|
|
if(nCount)
|
|
{
|
|
for(i=0;i<nCount;i++)
|
|
{
|
|
LPTSTR lp = (LPTSTR) SendMessage(hWndLB, LB_GETITEMDATA, (WPARAM) i, 0);
|
|
if(lp)
|
|
LocalFree(lp);
|
|
}
|
|
SendMessage(hWndLB, LB_RESETCONTENT, 0, 0);
|
|
}
|
|
// Clear any allocated memory in the field combo box
|
|
ClearFieldCombo(GetDlgItem(hDlg, IDC_FIND_COMBO_FIELD));
|
|
}
|
|
// if there is an LDAP operation in progress, close it and set the
|
|
// flag to cancel from where the LDAP operation was initialized
|
|
// This prevents aborting any process incompletely and faulting
|
|
if(lpWFP->bLDAPActionInProgress)
|
|
{
|
|
LPPTGDATA lpPTGData=GetThreadStoragePointer();
|
|
if(pt_hDlgCancel)
|
|
SendMessage(pt_hDlgCancel, WM_COMMAND, (WPARAM) IDCANCEL, 0);
|
|
lpWFP->bUserCancel= TRUE;
|
|
}
|
|
else
|
|
{
|
|
SaveFindWindowPos(hDlg, (LPIAB)lpWFP->LDAPsp.lpIAB);
|
|
FreeLVItemParam(GetDlgItem(hDlg, IDC_FIND_COMBO_LIST));//IDC_FIND_LIST));
|
|
EndDialog(hDlg, SEARCH_CLOSE);
|
|
}
|
|
break;
|
|
|
|
case IDM_LVCONTEXT_COPY:
|
|
HrCopyItemDataToClipboard( hDlg,
|
|
lpWFP->LDAPsp.lpIAB,
|
|
GetDlgItem(hDlg, IDC_FIND_LIST_RESULTS));
|
|
break;
|
|
|
|
case IDM_LVCONTEXT_PROPERTIES:
|
|
case IDC_FIND_BUTTON_PROPERTIES:
|
|
if(!lpWFP->bLDAPActionInProgress)
|
|
{
|
|
lpWFP->bLDAPActionInProgress = TRUE;
|
|
EnableWindow(GetDlgItem(hDlg, IDC_FIND_BUTTON_PROPERTIES), FALSE);
|
|
HrShowLVEntryProperties(GetDlgItem(hDlg, IDC_FIND_LIST_RESULTS), 0,
|
|
lpWFP->LDAPsp.lpIAB,
|
|
&ftLast);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_FIND_BUTTON_PROPERTIES), TRUE);
|
|
lpWFP->bLDAPActionInProgress = FALSE;
|
|
}
|
|
break;
|
|
|
|
case IDM_LVCONTEXT_DELETE:
|
|
case IDC_FIND_BUTTON_DELETE:
|
|
if(!lpWFP->bLDAPActionInProgress)
|
|
{
|
|
HWND hWndLVResults = GetDlgItem(hDlg, IDC_FIND_LIST_RESULTS);
|
|
DeleteSelectedItems(hWndLVResults,
|
|
(LPADRBOOK)lpWFP->LDAPsp.lpIAB,
|
|
((LPIAB)lpWFP->LDAPsp.lpIAB)->lpPropertyStore->hPropertyStore, &ftLast);
|
|
UpdateButtons( hDlg,
|
|
hWndLVResults,
|
|
GetDlgItem(hDlg, IDC_FIND_COMBO_LIST),
|
|
lpWFP->lplu);
|
|
{
|
|
TCHAR szBuf[MAX_PATH];
|
|
ULONG nItemCount = ListView_GetItemCount(hWndLVResults);
|
|
if (nItemCount <= 0)
|
|
{
|
|
LoadString(hinstMapiX, idsSearchDialogTitle, szBuf, ARRAYSIZE(szBuf));
|
|
// also free up the contents list so we dont show the deleted contents again
|
|
FreeRecipList(&(lpWFP->lpContentsList));
|
|
}
|
|
else
|
|
{
|
|
TCHAR szBufStr[MAX_PATH - 6];
|
|
LoadString(hinstMapiX, idsSearchDialogTitleWithResults, szBufStr, ARRAYSIZE(szBufStr));
|
|
wnsprintf(szBuf, ARRAYSIZE(szBuf), szBufStr, ListView_GetItemCount(hWndLVResults));
|
|
}
|
|
SetWindowText(hDlg, szBuf);
|
|
}
|
|
return 0;
|
|
}
|
|
break;
|
|
|
|
case IDM_LVCONTEXT_ADDTOWAB:
|
|
case IDC_FIND_BUTTON_ADDTOWAB:
|
|
if(!lpWFP->bLDAPActionInProgress)
|
|
{
|
|
HWND hWndLVResults = GetDlgItem(hDlg, IDC_FIND_LIST_RESULTS);
|
|
lpWFP->bLDAPActionInProgress = TRUE;
|
|
EnableWindow(GetDlgItem(hDlg, IDC_FIND_BUTTON_ADDTOWAB), FALSE);
|
|
EnableWindow(hWndLVResults, FALSE); // need to do this to preserve the selection in the list
|
|
HrAddToWAB( lpWFP->LDAPsp.lpIAB,
|
|
hWndLVResults,
|
|
&ftLast);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_FIND_BUTTON_ADDTOWAB), TRUE);
|
|
EnableWindow(hWndLVResults, TRUE);
|
|
SetColumnHeaderBmp(hWndLVResults, lpWFP->SortInfo);
|
|
lpWFP->bLDAPActionInProgress = FALSE;
|
|
SetFocus(hWndLVResults);
|
|
}
|
|
break;
|
|
|
|
case IDM_FIND_CONTAINERPROPERTIES:
|
|
if(!lpWFP->lplu)
|
|
{
|
|
ShowContainerProperties(hDlg,
|
|
GetDlgItem(hDlg, IDC_FIND_COMBO_LIST),
|
|
lpWFP);
|
|
}
|
|
break;
|
|
|
|
case IDM_NOTIFY_REFRESHUSER:
|
|
ReadWABCustomColumnProps((LPIAB)lpWFP->LDAPsp.lpIAB);
|
|
ReadRegistrySortInfo((LPIAB)lpWFP->LDAPsp.lpIAB, &(lpWFP->SortInfo));
|
|
case IDM_FIND_DIRECTORYSERVICES:
|
|
if(!lpWFP->bLDAPActionInProgress)
|
|
{
|
|
LPTSTR lpBuf = NULL;
|
|
HWND hWndCombo = GetDlgItem(hDlg, IDC_FIND_COMBO_LIST);
|
|
GetSelectedText(hWndCombo, &lpBuf);
|
|
if(lpBuf)
|
|
{
|
|
if(GET_WM_COMMAND_ID(wParam,lParam) == IDM_FIND_DIRECTORYSERVICES)
|
|
HrShowDirectoryServiceModificationDlg(hDlg, (LPIAB)lpWFP->LDAPsp.lpIAB);
|
|
FreeLVItemParam(hWndCombo);
|
|
PopulateContainerList( lpWFP->LDAPsp.lpIAB, hWndCombo, lpBuf, NULL);
|
|
SetEnableDisableUI(hDlg, hWndCombo, lpWFP->lplu, TabCtrl_GetCurSel(GetDlgItem(hDlg, IDC_TAB_FIND)));
|
|
LocalFree(lpBuf);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IDC_FIND_BUTTON_TO:
|
|
{
|
|
if(lpWFP->lpAPFI->DialogState == STATE_SELECT_RECIPIENTS)
|
|
{
|
|
ULONG ulMapiTo = MAPI_TO;
|
|
if ((lpWFP->lpAPFI->lpAdrParms->cDestFields > 0) && (lpWFP->lpAPFI->lpAdrParms->lpulDestComps))
|
|
ulMapiTo = lpWFP->lpAPFI->lpAdrParms->lpulDestComps[0];
|
|
ListAddItem( GetParent(hDlg),
|
|
GetDlgItem(hDlg, IDC_FIND_LIST_RESULTS),
|
|
IDC_ADDRBK_LIST_TO,
|
|
lpWFP->lpAPFI->lppTo,
|
|
ulMapiTo);
|
|
SendMessage (hDlg, WM_COMMAND, (WPARAM) IDOK, 0);
|
|
}
|
|
else if(lpWFP->lpAPFI->DialogState == STATE_PICK_USER)
|
|
{
|
|
// Here we need to do a couple of things:
|
|
// - if no entry is selected, tell the user to select one
|
|
// - if an entry is selected, get its entryid and cache it
|
|
// and close this dialog
|
|
HWND hWndLV = GetDlgItem(hDlg, IDC_FIND_LIST_RESULTS);
|
|
int iItemIndex = ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED);
|
|
if (iItemIndex == -1)
|
|
ShowMessageBox(hDlg, IDS_ADDRBK_MESSAGE_NO_ITEM, MB_OK | MB_ICONEXCLAMATION);
|
|
else
|
|
{
|
|
// Get the entryid of this selected item
|
|
LPRECIPIENT_INFO lpItem = GetItemFromLV(hWndLV, iItemIndex);
|
|
if (lpItem)
|
|
{
|
|
// remove this item from our linked list of arrays
|
|
// if this is the first item in the list then handle that special case too
|
|
lpWFP->lpAPFI->lpEntryID = LocalAlloc(LMEM_ZEROINIT, lpItem->cbEntryID);
|
|
if(lpWFP->lpAPFI->lpEntryID)
|
|
{
|
|
CopyMemory(lpWFP->lpAPFI->lpEntryID, lpItem->lpEntryID, lpItem->cbEntryID);
|
|
lpWFP->lpAPFI->cbEntryID = lpItem->cbEntryID;
|
|
SaveFindWindowPos(hDlg, (LPIAB)lpWFP->LDAPsp.lpIAB);
|
|
FreeLVItemParam(GetDlgItem(hDlg, IDC_FIND_COMBO_LIST));
|
|
EndDialog(hDlg, SEARCH_USE);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IDC_FIND_BUTTON_CC:
|
|
{
|
|
ULONG ulMapiTo = MAPI_CC;
|
|
if ((lpWFP->lpAPFI->lpAdrParms->cDestFields > 0) && (lpWFP->lpAPFI->lpAdrParms->lpulDestComps))
|
|
ulMapiTo = lpWFP->lpAPFI->lpAdrParms->lpulDestComps[1];
|
|
ListAddItem( GetParent(hDlg),
|
|
GetDlgItem(hDlg, IDC_FIND_LIST_RESULTS),
|
|
IDC_ADDRBK_LIST_CC,
|
|
lpWFP->lpAPFI->lppCC,
|
|
ulMapiTo);
|
|
SendMessage (hDlg, WM_COMMAND, (WPARAM) IDOK, 0);
|
|
}
|
|
break;
|
|
|
|
case IDC_FIND_BUTTON_BCC:
|
|
{
|
|
ULONG ulMapiTo = MAPI_BCC;
|
|
if ((lpWFP->lpAPFI->lpAdrParms->cDestFields > 0) && (lpWFP->lpAPFI->lpAdrParms->lpulDestComps))
|
|
ulMapiTo = lpWFP->lpAPFI->lpAdrParms->lpulDestComps[2];
|
|
ListAddItem( GetParent(hDlg),
|
|
GetDlgItem(hDlg, IDC_FIND_LIST_RESULTS),
|
|
IDC_ADDRBK_LIST_BCC,
|
|
lpWFP->lpAPFI->lppBCC,
|
|
ulMapiTo);
|
|
SendMessage (hDlg, WM_COMMAND, (WPARAM) IDOK, 0);
|
|
}
|
|
break;
|
|
|
|
case IDC_FIND_BUTTON_SERVER_INFO:
|
|
{
|
|
LDAPSERVERPARAMS lsp = {0};
|
|
ULONG iItemIndex;
|
|
LPTSTR lpBuf = NULL;
|
|
HWND hWndCombo = GetDlgItem(hDlg, IDC_FIND_COMBO_LIST);
|
|
HINSTANCE hInst;
|
|
|
|
// Does it have a URL registered?
|
|
// Get the LDAP server properties for the selected container
|
|
|
|
GetSelectedText(hWndCombo, &lpBuf);
|
|
|
|
if(lpBuf)
|
|
{
|
|
GetLDAPServerParams(lpBuf, &lsp);
|
|
if (lsp.lpszURL && lstrlen(lsp.lpszURL) && bIsHttpPrefix(lsp.lpszURL))
|
|
{
|
|
// Yes, there is a URL, shell execute it to bring up the browser.
|
|
HCURSOR hOldCur = SetCursor(LoadCursor(NULL, IDC_WAIT));
|
|
hInst = ShellExecute(GetParent(hDlg), TEXT("open"), lsp.lpszURL, NULL, NULL, SW_SHOWNORMAL);
|
|
SetCursor(hOldCur);
|
|
}
|
|
FreeLDAPServerParams(lsp);
|
|
LocalFree(lpBuf);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WM_SIZE:
|
|
ResizeFindDialog(hDlg, wParam, lParam, lpWFP);
|
|
return 0;
|
|
break;
|
|
|
|
case WM_CLOSE:
|
|
//treat it like a cancel button
|
|
SendMessage (hDlg, WM_COMMAND, (WPARAM) IDCANCEL, 0);
|
|
break;
|
|
|
|
case WM_HELP:
|
|
WABWinHelp(((LPHELPINFO)lParam)->hItemHandle,
|
|
g_szWABHelpFileName,
|
|
HELP_WM_HELP,
|
|
(DWORD_PTR)(LPSTR) rgSrchHelpIDs );
|
|
break;
|
|
|
|
case WM_CONTEXTMENU:
|
|
if ((HWND)wParam == GetDlgItem(hDlg, IDC_FIND_LIST_RESULTS))
|
|
{
|
|
ShowLVContextMenu( lvDialogFind,
|
|
GetDlgItem(hDlg, IDC_FIND_LIST_RESULTS),
|
|
GetDlgItem(hDlg, IDC_FIND_COMBO_LIST),
|
|
lParam,
|
|
NULL,
|
|
lpWFP->LDAPsp.lpIAB, NULL);
|
|
}
|
|
else if ((HWND)wParam == GetDlgItem(hDlg, IDC_FIND_COMBO_LIST) && (!lpWFP->lplu))
|
|
{
|
|
ShowContainerContextMenu( hDlg,
|
|
GetDlgItem(hDlg, IDC_FIND_COMBO_LIST),
|
|
lParam);
|
|
}
|
|
else
|
|
{
|
|
WABWinHelp((HWND) wParam,
|
|
g_szWABHelpFileName,
|
|
HELP_CONTEXTMENU,
|
|
(DWORD_PTR)(LPVOID) rgSrchHelpIDs );
|
|
}
|
|
break;
|
|
|
|
break;
|
|
|
|
case WM_VKEYTOITEM:
|
|
if( VK_DELETE == LOWORD(wParam) &&
|
|
SendMessage((HWND) lParam, LB_GETCOUNT, 0, 0) > 0) // Delete pressed
|
|
{
|
|
SendMessage(hDlg, WM_COMMAND, (WPARAM) IDC_FIND_BUTTON_REMOVECONDITION, 0);
|
|
return -2; // means we handled the keystroke completely
|
|
}
|
|
else
|
|
return DefWindowProc(hDlg, message, wParam, lParam);
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
switch((int) wParam)
|
|
{
|
|
case IDC_TAB_FIND:
|
|
if(((NMHDR FAR *)lParam)->code == TCN_SELCHANGE)
|
|
{
|
|
int nTab = TabCtrl_GetCurSel(((NMHDR FAR *)lParam)->hwndFrom);
|
|
SetEnableDisableUI( hDlg,
|
|
GetDlgItem(hDlg, IDC_FIND_COMBO_LIST),
|
|
lpWFP->lplu,
|
|
nTab);
|
|
if(nTab == tabSimple)
|
|
SetFocus(GetDlgItem(hDlg, IDC_FIND_EDIT_NAME));
|
|
else
|
|
SetFocus(GetDlgItem(hDlg, IDC_FIND_EDIT_ADVANCED));
|
|
}
|
|
break;
|
|
|
|
case IDC_FIND_LIST_RESULTS:
|
|
#ifdef WIN16 // Context menu handler for WIN16
|
|
if(((NMHDR FAR *)lParam)->code == NM_RCLICK)
|
|
{
|
|
POINT pt;
|
|
|
|
GetCursorPos(&pt);
|
|
ShowLVContextMenu( lvDialogFind,
|
|
GetDlgItem(hDlg, IDC_FIND_LIST_RESULTS),
|
|
GetDlgItem(hDlg, IDC_FIND_COMBO_LIST),
|
|
MAKELPARAM(pt.x, pt.y),
|
|
NULL,
|
|
lpWFP->LDAPsp.lpIAB, NULL);
|
|
}
|
|
#endif
|
|
return ProcessLVResultsMessages(hDlg,message,wParam,lParam, lpWFP);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/**********
|
|
//$$////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// ProcessLVMessages - Processes messages for the Container list view control
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
LRESULT ProcessLVMessages(HWND hWnd, UINT uMsg, UINT wParam, LPARAM lParam)
|
|
{
|
|
|
|
NM_LISTVIEW * pNm = (NM_LISTVIEW *)lParam;
|
|
HWND hWndLV = pNm->hdr.hwndFrom;
|
|
LPPTGDATA lpPTGData=GetThreadStoragePointer();
|
|
|
|
switch(pNm->hdr.code)
|
|
{
|
|
|
|
case NM_DBLCLK:
|
|
SendMessage (hWnd, WM_COMMAND, (WPARAM) IDM_FIND_CONTAINERPROPERTIES, 0);
|
|
break;
|
|
|
|
case LVN_ITEMCHANGED:
|
|
case NM_SETFOCUS:
|
|
case NM_CLICK:
|
|
case NM_RCLICK:
|
|
SetEnableDisableUI(hWnd, hWndLV);
|
|
break;
|
|
|
|
case NM_CUSTOMDRAW:
|
|
{
|
|
NMCUSTOMDRAW *pnmcd=(NMCUSTOMDRAW*)lParam;
|
|
NM_LISTVIEW * pNm = (NM_LISTVIEW *)lParam;
|
|
NMLVCUSTOMDRAW * pnmlvcd = (NMLVCUSTOMDRAW * )lParam;
|
|
|
|
if(pnmcd->dwDrawStage==CDDS_PREPAINT)
|
|
{
|
|
SetWindowLong(hWnd, DWL_MSGRESULT, CDRF_NOTIFYITEMDRAW | CDRF_DODEFAULT);
|
|
return TRUE;
|
|
}
|
|
else if(pnmcd->dwDrawStage==CDDS_ITEMPREPAINT)
|
|
{
|
|
LPSERVERDAT lpSD = (LPSERVERDAT) pnmcd->lItemlParam;
|
|
|
|
if(lpSD != 0 &&
|
|
(WAB_PAB != IsWABEntryID(lpSD->SB.cb,
|
|
(LPENTRYID) lpSD->SB.lpb,
|
|
NULL, NULL, NULL)) &&
|
|
lpSD->himl)
|
|
{
|
|
HDC hdcLV = pnmlvcd->nmcd.hdc;
|
|
RECT rcLVItem;
|
|
UINT fType = ILD_NORMAL;
|
|
|
|
ListView_GetItemRect(hWndLV, pnmcd->dwItemSpec, &rcLVItem, LVIR_BOUNDS);
|
|
if (ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED) == (int) pnmcd->dwItemSpec)
|
|
{
|
|
FillRect(hdcLV, &rcLVItem, (HBRUSH) (COLOR_HIGHLIGHT+1));
|
|
//fType |= ILD_BLEND25;
|
|
DrawFocusRect(hdcLV, &rcLVItem);
|
|
}
|
|
else
|
|
FillRect(hdcLV, &rcLVItem, (HBRUSH) (COLOR_WINDOW+1));
|
|
|
|
if(!gpfnImageList_Draw( lpSD->himl,
|
|
0,
|
|
hdcLV,
|
|
rcLVItem.left + L_BITMAP_WIDTH + 1, //gives enough space to paint the icon
|
|
rcLVItem.top,
|
|
fType))
|
|
{
|
|
DebugPrintError(( TEXT("ImageList_Draw failed\n")));
|
|
}
|
|
|
|
if (ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED) == (int) pnmcd->dwItemSpec)
|
|
fType |= ILD_BLEND25;
|
|
|
|
{
|
|
HIMAGELIST himlLV = ListView_GetImageList(hWndLV,LVSIL_SMALL);
|
|
gpfnImageList_Draw(himlLV, imageDirectoryServer, hdcLV, rcLVItem.left + 1, rcLVItem.top, fType);
|
|
}
|
|
SetWindowLong(hWnd, DWL_MSGRESULT, CDRF_SKIPDEFAULT);
|
|
return TRUE;
|
|
}
|
|
}
|
|
SetWindowLong(hWnd, DWL_MSGRESULT, CDRF_DODEFAULT);
|
|
return TRUE;
|
|
}
|
|
break;
|
|
|
|
}
|
|
|
|
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
|
}
|
|
/********/
|
|
|
|
//$$////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// ProcessLVResultsMessages - Processes messages for the Search Results list view control
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
LRESULT ProcessLVResultsMessages(HWND hWnd,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam,
|
|
LPWAB_FIND_PARAMS lpWFP)
|
|
{
|
|
|
|
NM_LISTVIEW * pNm = (NM_LISTVIEW *)lParam;
|
|
HWND hWndLV = pNm->hdr.hwndFrom;
|
|
|
|
// Bug 17027: GPF due to null lpWFP
|
|
if(lpWFP)
|
|
{
|
|
if(lpWFP->bLDAPActionInProgress)
|
|
return 0;
|
|
}
|
|
|
|
switch(pNm->hdr.code)
|
|
{
|
|
case LVN_COLUMNCLICK:
|
|
if(lpWFP)
|
|
SortListViewColumn((LPIAB)lpWFP->LDAPsp.lpIAB, hWndLV, pNm->iSubItem, &(lpWFP->SortInfo), FALSE);
|
|
break;
|
|
|
|
|
|
case LVN_KEYDOWN:
|
|
switch(((LV_KEYDOWN FAR *) lParam)->wVKey)
|
|
{
|
|
case VK_DELETE:
|
|
if(CurrentContainerIsPAB(GetDlgItem(hWnd, IDC_FIND_COMBO_LIST)) != IS_LDAP)
|
|
SendMessage (hWnd, WM_COMMAND, (WPARAM) IDC_FIND_BUTTON_DELETE, 0);
|
|
return 0;
|
|
break;
|
|
case VK_RETURN:
|
|
SendMessage (hWnd, WM_COMMAND, (WPARAM) IDC_FIND_BUTTON_PROPERTIES, 0);
|
|
return 0;
|
|
}
|
|
break;
|
|
|
|
|
|
case NM_DBLCLK:
|
|
SendMessage (hWnd, WM_COMMAND, (WPARAM) IDC_FIND_BUTTON_PROPERTIES, 0);
|
|
return 0;
|
|
break;
|
|
|
|
case NM_CUSTOMDRAW:
|
|
return ProcessLVCustomDraw(hWnd, lParam, TRUE);
|
|
break;
|
|
}
|
|
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
|
}
|
|
|
|
|
|
//$$////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// SaveFindWindowPos - saves the find window position and size
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
void SaveFindWindowPos(HWND hWnd, LPIAB lpIAB)
|
|
{
|
|
ABOOK_POSCOLSIZE ABPosColSize = {0};
|
|
WINDOWPLACEMENT wpl = {0};
|
|
|
|
wpl.length = sizeof(WINDOWPLACEMENT);
|
|
|
|
// This call tells us the window state and normal size and position
|
|
GetWindowPlacement(hWnd, &wpl);
|
|
|
|
// There seems to be a bug in GetWindowPlacement that
|
|
// doesnt account for various taskbars on the screen when
|
|
// returning the Window's Normal Position .. as a result
|
|
// the stored coordinates won't be accurate. Instead, we'll
|
|
// use those coordinates only if the window is maximized or
|
|
// minimized - otherwise we will use the GetWindowRect
|
|
// coordinates.
|
|
|
|
// Get the screen position of this window
|
|
GetWindowRect(hWnd, &(ABPosColSize.rcPos));
|
|
|
|
if(wpl.showCmd != SW_SHOWNORMAL)
|
|
{
|
|
ABPosColSize.rcPos = wpl.rcNormalPosition;
|
|
}
|
|
|
|
ABPosColSize.nTab = TabCtrl_GetCurSel(GetDlgItem(hWnd, IDC_TAB_FIND));
|
|
|
|
WriteRegistryPositionInfo(lpIAB, &ABPosColSize,lpszRegFindPositionKeyValueName);
|
|
|
|
// Also save the last used server name in the registry for the next
|
|
// session
|
|
{
|
|
LPTSTR lpBuf = NULL;
|
|
GetSelectedText(GetDlgItem(hWnd, IDC_FIND_COMBO_LIST), &lpBuf);
|
|
if(lpBuf)
|
|
{
|
|
HKEY hKeyRoot = (lpIAB && lpIAB->hKeyCurrentUser) ? lpIAB->hKeyCurrentUser : HKEY_CURRENT_USER;
|
|
RegSetValue(hKeyRoot, szKeyLastFindServer, REG_SZ, lpBuf, lstrlen(lpBuf));
|
|
LocalFree(lpBuf);
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
/*************************************************************************
|
|
//$$
|
|
// HrInitServerListLV - Initializes the list view that displays the list
|
|
// of servers ...
|
|
//
|
|
// hWndLV - handle of list view
|
|
//
|
|
**************************************************************************/
|
|
/****
|
|
HRESULT HrInitServerListLV(HWND hWndLV)
|
|
{
|
|
HRESULT hr = hrSuccess;
|
|
LV_COLUMN lvC; // list view column structure
|
|
HIMAGELIST hSmall=NULL;
|
|
|
|
DWORD dwLVStyle;
|
|
ULONG nCols=0;
|
|
ULONG index=0;
|
|
|
|
if (!hWndLV)
|
|
{
|
|
hr = MAPI_E_INVALID_PARAMETER;
|
|
goto out;
|
|
}
|
|
|
|
ListView_SetExtendedListViewStyle(hWndLV, LVS_EX_FULLROWSELECT);
|
|
|
|
dwLVStyle = GetWindowLong(hWndLV,GWL_STYLE);
|
|
if(dwLVStyle & LVS_EDITLABELS)
|
|
SetWindowLong(hWndLV,GWL_STYLE,(dwLVStyle & ~LVS_EDITLABELS));
|
|
|
|
hSmall = gpfnImageList_LoadImage( hinstMapiX,
|
|
MAKEINTRESOURCE(IDB_BITMAP_LARGE),
|
|
L_BITMAP_WIDTH,
|
|
0,
|
|
RGB_TRANSPARENT,
|
|
IMAGE_BITMAP,
|
|
0);
|
|
|
|
ListView_SetImageList (hWndLV, hSmall, LVSIL_SMALL);
|
|
|
|
lvC.mask = LVCF_FMT | LVCF_WIDTH;
|
|
lvC.fmt = LVCFMT_LEFT; // left-align column
|
|
|
|
{
|
|
RECT rc;
|
|
GetWindowRect(hWndLV, &rc);
|
|
lvC.cx = rc.right - rc.left - L_BITMAP_WIDTH - 10;
|
|
}
|
|
lvC.pszText = NULL;
|
|
|
|
lvC.iSubItem = 0;
|
|
|
|
if (ListView_InsertColumn (hWndLV, 0, &lvC) == -1)
|
|
{
|
|
DebugPrintError(( TEXT("ListView_InsertColumn Failed\n")));
|
|
hr = E_FAIL;
|
|
goto out;
|
|
}
|
|
|
|
|
|
out:
|
|
|
|
return hr;
|
|
}
|
|
/***/
|
|
|
|
|
|
//$$
|
|
//*------------------------------------------------------------------------
|
|
//| FreeLVItemParam: Frees the LPSBinary structure associated with each element
|
|
//| of the list view containing a container list
|
|
//|
|
|
//| hWndLV - Handle of List View whose data we are freeing
|
|
//|
|
|
//*------------------------------------------------------------------------
|
|
void FreeLVItemParam(HWND hWndCombo)//hWndLV)
|
|
{
|
|
int i = 0;
|
|
int nCount;
|
|
|
|
if(!hWndCombo)
|
|
return;
|
|
|
|
nCount = (int) SendMessage(hWndCombo, CB_GETCOUNT, 0, 0);
|
|
|
|
// Each Combo item has a entryid associated with it which we need to free up
|
|
for(i=0;i<nCount;i++)
|
|
{
|
|
LPSERVERDAT lpSD = NULL;
|
|
|
|
lpSD = (LPSERVERDAT) SendMessage(hWndCombo, CB_GETITEMDATA, (WPARAM) i, 0);
|
|
|
|
if(lpSD != NULL)
|
|
{
|
|
if(lpSD->himl)
|
|
gpfnImageList_Destroy(lpSD->himl);
|
|
LocalFreeAndNull((LPVOID *) (&(lpSD->SB.lpb)));
|
|
LocalFreeAndNull(&lpSD);
|
|
}
|
|
}
|
|
SendMessage(hWndCombo, CB_RESETCONTENT, 0, 0);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
//$$
|
|
//*------------------------------------------------------------------------
|
|
//| PopulateContainerList: Enumerates potential container names and fills
|
|
//| combo ...
|
|
//|
|
|
//| lpIAB - AdrBook Object
|
|
//| hWndCombo - Handle of Combo we are populating
|
|
//| lpszSelection - NULL or some value - if exists, this value is set as the
|
|
//| combo selection otherwise the local store is the default
|
|
//| selection
|
|
//| lptszPreferredSelection - NULL or some value - if exists then set as the
|
|
//| combo selection, otherwise the above
|
|
//| lpszSelection or local store is the default.
|
|
//|
|
|
//*------------------------------------------------------------------------
|
|
HRESULT PopulateContainerList(
|
|
LPADRBOOK lpAdrBook,
|
|
HWND hWndCombo,
|
|
LPTSTR lpszSelection,
|
|
LPTSTR lptszPreferredSelection)
|
|
{
|
|
LPPTGDATA lpPTGData=GetThreadStoragePointer();
|
|
HRESULT hr = hrSuccess;
|
|
ULONG ulObjectType = 0;
|
|
LPROOT lpRoot = NULL;
|
|
LPMAPITABLE lpContentsTable = NULL;
|
|
LPSRowSet lpSRowSet = NULL;
|
|
ULONG i=0,j=0;
|
|
TCHAR szPref[MAX_PATH];
|
|
int nPos = 0;
|
|
int nStart = 1; // pos we start sorting at ... always after the TEXT("WAB") item
|
|
BOOL bAddedPref = FALSE;
|
|
LPIAB lpIAB = (LPIAB)lpAdrBook;
|
|
BOOL bFoundSelection = FALSE;
|
|
BOOL bFoundPreferredSelection = FALSE;
|
|
|
|
if( !lpAdrBook ||
|
|
!hWndCombo)
|
|
{
|
|
hr = MAPI_E_INVALID_PARAMETER;
|
|
DebugPrintError(( TEXT("Invalid Params\n")));
|
|
goto out;
|
|
}
|
|
|
|
// if running against outlook, there can be more than 1 contact folder and
|
|
// we need to push them all to the top of the list .. so we will really start
|
|
// adding generic stuff after the colkci position
|
|
//
|
|
if (pt_bIsWABOpenExSession)
|
|
{
|
|
nStart = lpIAB->lpPropertyStore->colkci;
|
|
}
|
|
|
|
*szPref = '\0';
|
|
LoadString(hinstMapiX, idsPreferedPartnerCode, szPref, ARRAYSIZE(szPref));
|
|
|
|
hr = lpAdrBook->lpVtbl->OpenEntry( lpAdrBook,
|
|
0,
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
&ulObjectType,
|
|
(LPUNKNOWN *) &lpRoot );
|
|
|
|
if (HR_FAILED(hr))
|
|
{
|
|
DebugPrintError(( TEXT("OpenEntry Failed: %x\n"),hr));
|
|
goto out;
|
|
}
|
|
|
|
// if this is a profile aware session, only put the All Contacts item in the drop down list
|
|
// unless it's an outlook session in which case don't do anything
|
|
{
|
|
ULONG ulFlags = MAPI_UNICODE;
|
|
if(bIsWABSessionProfileAware(lpIAB))
|
|
ulFlags |= WAB_NO_PROFILE_CONTAINERS;
|
|
|
|
hr = lpRoot->lpVtbl->GetContentsTable( lpRoot,
|
|
ulFlags,
|
|
&lpContentsTable);
|
|
}
|
|
|
|
if (HR_FAILED(hr))
|
|
{
|
|
DebugPrintError(( TEXT("GetContentsTable Failed: %x\n"),hr));
|
|
goto out;
|
|
}
|
|
|
|
hr = HrQueryAllRows(lpContentsTable,
|
|
NULL, NULL, NULL, 0,
|
|
&lpSRowSet);
|
|
|
|
if (HR_FAILED(hr))
|
|
{
|
|
DebugPrintError(( TEXT("HrQueryAllRows Failed: %x\n"),hr));
|
|
goto out;
|
|
}
|
|
|
|
for(i=0;i<lpSRowSet->cRows;i++)
|
|
{
|
|
LPTSTR lpszDisplayName = NULL;
|
|
LPSERVERDAT lpSD = LocalAlloc(LMEM_ZEROINIT, sizeof(SERVERDAT));
|
|
|
|
if(!lpSD)
|
|
{
|
|
DebugPrintError(( TEXT("LocalAlloc failed to allocate memory\n")));
|
|
goto out;
|
|
}
|
|
lpSD->himl = NULL;
|
|
|
|
for(j=0;j<lpSRowSet->aRow[i].cValues;j++)
|
|
{
|
|
LPSPropValue lpPropArray = lpSRowSet->aRow[i].lpProps;
|
|
|
|
switch(lpPropArray[j].ulPropTag)
|
|
{
|
|
case PR_DISPLAY_NAME:
|
|
lpszDisplayName = lpPropArray[j].Value.LPSZ;
|
|
break;
|
|
case PR_ENTRYID:
|
|
lpSD->SB.cb = lpPropArray[j].Value.bin.cb;
|
|
if(lpSD->SB.cb > 0)
|
|
{
|
|
lpSD->SB.lpb = LocalAlloc(LMEM_ZEROINIT, lpSD->SB.cb);
|
|
if(!lpSD->SB.lpb)
|
|
{
|
|
DebugPrintError(( TEXT("LocalAlloc failed to allocate memory\n")));
|
|
goto out;
|
|
}
|
|
CopyMemory(lpSD->SB.lpb, lpPropArray[j].Value.bin.lpb,lpSD->SB.cb);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
nPos = ComboAddItem( hWndCombo,
|
|
lpszDisplayName,
|
|
(LPARAM) lpSD,
|
|
szPref,
|
|
&nStart, &bAddedPref);
|
|
|
|
if(!bFoundPreferredSelection && lpszSelection && !lstrcmpi(lpszDisplayName, lpszSelection))
|
|
{
|
|
bFoundSelection = TRUE;
|
|
SendMessage(hWndCombo, CB_SETCURSEL, (WPARAM)nPos, 0);
|
|
SetWindowText(hWndCombo, lpszSelection);
|
|
}
|
|
|
|
if (lptszPreferredSelection && !lstrcmpi(lpszDisplayName, lptszPreferredSelection))
|
|
{
|
|
bFoundPreferredSelection = TRUE;
|
|
SendMessage(hWndCombo, CB_SETCURSEL, (WPARAM)nPos, 0);
|
|
SetWindowText(hWndCombo, lptszPreferredSelection);
|
|
}
|
|
}
|
|
|
|
out:
|
|
|
|
if (!bFoundSelection && !bFoundPreferredSelection)
|
|
SendMessage(hWndCombo, CB_SETCURSEL, 0, 0);
|
|
|
|
if (lpSRowSet)
|
|
FreeProws(lpSRowSet);
|
|
|
|
if(lpContentsTable)
|
|
lpContentsTable->lpVtbl->Release(lpContentsTable);
|
|
|
|
if(lpRoot)
|
|
lpRoot->lpVtbl->Release(lpRoot);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//$$/////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CurrentContainerIsPAB - Returns TRUE if the current viewed container is the PAB
|
|
//
|
|
// hWndLV - List Containing the list of containers.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
int CurrentContainerIsPAB(HWND hWndCombo)
|
|
{
|
|
HRESULT hr = hrSuccess;
|
|
ULONG cbContainerEID = 0;
|
|
LPENTRYID lpContainerEID = NULL;
|
|
BYTE bType = 0;
|
|
|
|
GetCurrentContainerEID(hWndCombo,
|
|
&cbContainerEID,
|
|
&lpContainerEID);
|
|
|
|
//
|
|
// Check if this entryid is a Local WAB store
|
|
//
|
|
if(!cbContainerEID && !lpContainerEID)
|
|
return IS_PAB;
|
|
|
|
bType = IsWABEntryID(cbContainerEID, lpContainerEID, NULL, NULL, NULL, NULL, NULL);
|
|
|
|
if(bType == WAB_LDAP_CONTAINER)
|
|
return IS_LDAP;
|
|
|
|
if(bType == WAB_PAB || bType == WAB_PABSHARED)
|
|
return IS_PAB;
|
|
|
|
// for now we'll figure anything else is a Outlook container
|
|
return IS_OLK;
|
|
}
|
|
|
|
//$$
|
|
/******************************************************************************
|
|
//
|
|
// HrSearchAndGetLDAPContents - Gets and fills the current list view with contents from
|
|
// an LDAP server.
|
|
//
|
|
// hWndCombo - Handle to TEXT("ShowNames") combo (in case we need to update it
|
|
// hWndList - Handle to List View which we will populate
|
|
// lpIAB - Handle to Address Bok object
|
|
// SortInfo - Current Sort State
|
|
// lppContentsList - linked list in which we will store info about entries
|
|
// lpAdvFilter - an advanced search filter that is used for advanced searches
|
|
//
|
|
/******************************************************************************/
|
|
HRESULT HrSearchAndGetLDAPContents( LDAP_SEARCH_PARAMS LDAPsp,
|
|
LPTSTR lpAdvFilter,
|
|
HWND hWndCombo,
|
|
LPADRBOOK lpAdrBook,
|
|
SORT_INFO SortInfo,
|
|
LPRECIPIENT_INFO * lppContentsList)
|
|
{
|
|
LPPTGDATA lpPTGData=GetThreadStoragePointer();
|
|
HRESULT hr = hrSuccess;
|
|
SCODE sc = ERROR_SUCCESS;
|
|
ULONG cbContainerEID = 0;
|
|
LPENTRYID lpContainerEID = NULL;
|
|
TCHAR szBuf[MAX_UI_STR];
|
|
|
|
ULONG ulCurSel = 0;
|
|
SRestriction SRes = {0};
|
|
LPSRestriction lpPropRes = NULL;
|
|
ULONG ulcPropCount = 0;
|
|
ULONG i = 0;
|
|
HCURSOR hOldCursor = NULL;
|
|
BOOL bKeepSearching = TRUE;
|
|
|
|
//while(bKeepSearching)
|
|
{
|
|
hOldCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
|
|
//
|
|
// Then we get the container entry id for thie container
|
|
//
|
|
GetCurrentContainerEID( hWndCombo,
|
|
&cbContainerEID,
|
|
&lpContainerEID);
|
|
|
|
//
|
|
// Now we have the search dialog data .. we need to create a restriction from it which
|
|
// we can use with the LDAP contents table..
|
|
//
|
|
if(!lpAdvFilter)
|
|
{
|
|
if(HR_FAILED(HrGetLDAPSearchRestriction(LDAPsp, &SRes)))
|
|
goto out;
|
|
lpPropRes = SRes.res.resAnd.lpRes;
|
|
}
|
|
|
|
hr = HrGetLDAPContentsList(
|
|
lpAdrBook,
|
|
cbContainerEID,
|
|
lpContainerEID,
|
|
SortInfo,
|
|
&SRes,
|
|
lpAdvFilter,
|
|
NULL,
|
|
0,
|
|
lppContentsList);
|
|
|
|
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:
|
|
ids = idsLDAPSearchTimeExceeded;
|
|
break;
|
|
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 = idsLDAPErrorOccured;
|
|
DebugPrintError(( TEXT("HrGetLDAPContentsList failed:%x\n"),hr));
|
|
break;
|
|
}
|
|
ShowMessageBox( GetParent(hWndCombo),ids, flags);
|
|
goto out;
|
|
}
|
|
else
|
|
{
|
|
if(hr == MAPI_W_PARTIAL_COMPLETION)
|
|
ShowMessageBox( GetParent(hWndCombo),
|
|
idsLDAPPartialResults, MB_OK | MB_ICONINFORMATION);
|
|
}
|
|
} // while(bKeepSearching)
|
|
|
|
out:
|
|
|
|
if(lpPropRes)
|
|
MAPIFreeBuffer(lpPropRes);
|
|
|
|
if(hOldCursor)
|
|
SetCursor(hOldCursor);
|
|
|
|
return(hr);
|
|
}
|
|
|
|
//$$
|
|
//*------------------------------------------------------------------------
|
|
//| GetCurrentContainerEID: Gets EntryID of Current Container - takes a handle
|
|
//| to a populated combo, gets the current selection, and then
|
|
//| gets the ItemData (EntryID) for that current selection.
|
|
//|
|
|
//| hWndLV - Handle of a ListView containing the container list
|
|
//| lpcbContEID,lppContEID - returned Container Entry ID
|
|
//|
|
|
//| **NOTE** lpContEID is not allocated - its just a pointer and should not be freed
|
|
//|
|
|
//*------------------------------------------------------------------------
|
|
void GetCurrentContainerEID(HWND hWndCombo, //hWndLV,
|
|
LPULONG lpcbContEID,
|
|
LPENTRYID * lppContEID)
|
|
{
|
|
LPSERVERDAT lpSD = NULL;
|
|
int iItemIndex = 0;
|
|
|
|
if(!lpcbContEID || !lppContEID)
|
|
goto out;
|
|
|
|
*lpcbContEID = 0;
|
|
*lppContEID = NULL;
|
|
|
|
iItemIndex = (int) SendMessage(hWndCombo, CB_GETCURSEL, 0, 0);
|
|
|
|
if(iItemIndex == CB_ERR)
|
|
goto out;
|
|
|
|
lpSD = (LPSERVERDAT) SendMessage(hWndCombo, CB_GETITEMDATA, (WPARAM) iItemIndex, 0);
|
|
|
|
if(!lpSD)
|
|
goto out;
|
|
|
|
*lpcbContEID = lpSD->SB.cb;
|
|
*lppContEID = (LPENTRYID) lpSD->SB.lpb;
|
|
|
|
out:
|
|
return;
|
|
}
|
|
|
|
|
|
//$$////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// ComboAddItem Generic function for adding items to list view
|
|
//
|
|
// hWndLV - HWND of List View
|
|
// lpszItemText - ItemText
|
|
// lParam - LPARAM (can be NULL)
|
|
// lpnStart - position at which to start adding generic servers .. in the case where there
|
|
// is more than one server at the top of the list
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////////////////
|
|
int ComboAddItem( HWND hWndCombo, //hWndLV,
|
|
LPTSTR lpszItemText,
|
|
LPARAM lParam,
|
|
LPTSTR szPref,
|
|
int * lpnStart, BOOL * lpbAddedPref)
|
|
{
|
|
LPTSTR lp = NULL;
|
|
int nPos = 0, nStart = 1;
|
|
int nCount = (int) SendMessage(hWndCombo, CB_GETCOUNT, 0, 0);
|
|
LDAPSERVERPARAMS Params = {0};
|
|
|
|
if(lpnStart && *lpnStart)
|
|
nStart = *lpnStart;
|
|
|
|
GetLDAPServerParams(lpszItemText, &Params);
|
|
|
|
|
|
if( Params.dwIsNTDS == LDAP_NTDS_IS) // NTDS accounts need to come upfront after the Address Book
|
|
{
|
|
// if the prefered accounts have already been added at nStart .. only add the NT accounts at
|
|
// nStart - 1
|
|
nPos = (int) SendMessage(hWndCombo, CB_INSERTSTRING,
|
|
(WPARAM) ((lpbAddedPref && *lpbAddedPref == TRUE) ? nStart - 1 : nStart),
|
|
(LPARAM) lpszItemText);
|
|
if(lpnStart)
|
|
(*lpnStart)++;
|
|
}
|
|
else
|
|
if( ( szPref && lstrlen(szPref) && lpszItemText && lstrlen(lpszItemText) && SubstringSearch(lpszItemText, szPref)) )
|
|
{
|
|
nPos = (int) SendMessage(hWndCombo, CB_INSERTSTRING, (WPARAM) nStart, (LPARAM) lpszItemText); // Prefered partner goes in after contact folders at top of the list
|
|
if(lpnStart)
|
|
(*lpnStart)++;
|
|
if(lpbAddedPref)
|
|
*lpbAddedPref = TRUE;
|
|
}
|
|
else
|
|
{
|
|
// Once we add the pref server, we only need to compare from after that item
|
|
if(nCount >= nStart)
|
|
{
|
|
// need to start adding alphabetically
|
|
// We cant set this list to a sorted state because we always want the Address Book first
|
|
// and then the prefered partner second
|
|
int i,nLen;
|
|
|
|
for(i=nStart; i< nCount; i++)
|
|
{
|
|
// get the current string in the combo
|
|
nLen = (int) SendMessage(hWndCombo, CB_GETLBTEXTLEN, (WPARAM) i, 0);
|
|
if (nLen && (CB_ERR != nLen))
|
|
{
|
|
if(lp)
|
|
{
|
|
LocalFree(lp);
|
|
lp = NULL;
|
|
}
|
|
lp = LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*(nLen+1));
|
|
if(lp)
|
|
{
|
|
SendMessage(hWndCombo, CB_GETLBTEXT, (WPARAM) i, (LPARAM)lp);
|
|
if(lstrlen(lp) && lstrcmpi(lp, lpszItemText) >= 0)
|
|
{
|
|
nPos = i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if(nPos)
|
|
{
|
|
// we have a valid position to add the string to
|
|
nPos = (int) SendMessage(hWndCombo, CB_INSERTSTRING, (WPARAM) nPos, (LPARAM) lpszItemText); // Prefered partner goes in after Address book at top of the list
|
|
}
|
|
else
|
|
{
|
|
// just tag it to the end
|
|
nPos = (int) SendMessage(hWndCombo, CB_ADDSTRING, 0, (LPARAM) lpszItemText);
|
|
}
|
|
}
|
|
|
|
SendMessage(hWndCombo, CB_SETITEMDATA, (WPARAM) nPos, lParam);
|
|
|
|
if(lp)
|
|
LocalFree(lp);
|
|
|
|
FreeLDAPServerParams(Params);
|
|
|
|
return nPos;
|
|
}
|
|
|