Windows2003-3790/inetcore/outlookexpress/wabw/wabapi/ui_srch.c
2020-09-30 16:53:55 +02:00

3180 lines
105 KiB
C

/*--------------------------------------------------------------
*
*
* 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;
}