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

1515 lines
54 KiB

/* r
* CSVPick.C
*
* Picker wizard for CSV import/export
*
* Copyright 1997 Microsoft Corporation. All Rights Reserved.
*/
#include "_comctl.h"
#include <windows.h>
#include <commctrl.h>
#include <mapix.h>
#include <wab.h>
#include <wabguid.h>
#include <wabdbg.h>
#include <wabmig.h>
#include <emsabtag.h>
#include "wabimp.h"
#include "..\..\wab32res\resrc2.h"
#include "dbgutil.h"
#include <shlwapi.h>
const TCHAR szCSVFilter[] = "*.csv";
const TCHAR szCSVExt[] = "csv";
#define CHECK_BITMAP_WIDTH 16
typedef struct {
LPPROP_NAME rgPropNames;
LPPROP_NAME * lppImportMapping;
LPHANDLE lphFile;
LPULONG lpcFields;
LPTSTR szSep;
} PROPSHEET_DATA, * LPPROPSHEET_DATA;
TCHAR szCSVFileName[MAX_PATH + 1] = "";
INT_PTR CALLBACK ExportPickFieldsPageProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK ExportFilePageProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK ImportFilePageProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK ImportMapFieldsPageProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK ChangeMappingDialogProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
/***************************************************************************
Name : FillInPropertyPage
Purpose : Fills in the given PROPSHEETPAGE structure
Parameters: psp -> property sheet page structure
idDlg = dialog id
pszProc = title for page
pfnDlgProc -> Dialog procedure
lParam = application specified data
Returns : none
Comment : This function fills in a PROPSHEETPAGE structure with the
information the system needs to create the page.
***************************************************************************/
void FillInPropertyPage(PROPSHEETPAGE* psp, int idDlg, LPSTR pszProc,
DLGPROC pfnDlgProc, LPARAM lParam) {
psp->dwSize = sizeof(PROPSHEETPAGE);
psp->dwFlags = 0;
psp->hInstance = hInst;
psp->pszTemplate = MAKEINTRESOURCE(idDlg);
psp->pszIcon = NULL;
psp->pfnDlgProc = pfnDlgProc;
psp->pszTitle = pszProc;
psp->lParam = lParam;
}
/***************************************************************************
Name : HandleCheckMark
Purpose : Deals with setting the checkmark for a particular item in
the listview.
Parameters: hwndLV = ListView handle
iItem = index of item to set
rgTable = PROP_NAME table
Returns : none
Comment :
***************************************************************************/
void HandleCheckMark(HWND hWndLV, ULONG iItem, LPPROP_NAME rgTable) {
// Locals
LV_ITEM lvi;
// Clear it
ZeroMemory(&lvi, sizeof(LV_ITEM));
lvi.mask = LVIF_PARAM;
lvi.iItem = iItem;
ListView_GetItem(hWndLV, &lvi);
rgTable[lvi.iItem].fChosen =
! rgTable[lvi.iItem].fChosen;
ZeroMemory(&lvi, sizeof(LV_ITEM));
lvi.mask = LVIF_STATE;
lvi.iItem = iItem;
lvi.state = rgTable[iItem].fChosen ?
INDEXTOSTATEIMAGEMASK(iiconStateChecked + 1) :
INDEXTOSTATEIMAGEMASK(iiconStateUnchecked + 1);
lvi.stateMask = LVIS_STATEIMAGEMASK;
ListView_SetItem(hWndLV, &lvi);
}
/***************************************************************************
Name : HandleMultipleCheckMarks
Purpose : Deals with setting the checkmark for a bunch of selected
items in the list view - basically sets every selected item
to the toggled state of the first item in the selection
Parameters: hwndLV = ListView handle
rgTable = LPPROP_NAME table
Returns : none
Comment :
***************************************************************************/
void HandleMultipleCheckMarks(HWND hWndLV, LPPROP_NAME rgTable)
{
// Locals
LV_ITEM lvi;
int nIndex = 0;
BOOL fState = FALSE;
// get the index of the first item
nIndex = ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED);
// toggle this item
HandleCheckMark(hWndLV, nIndex, rgTable);
fState = rgTable[nIndex].fChosen;
while((nIndex = ListView_GetNextItem(hWndLV, nIndex, LVNI_SELECTED)) >= 0)
{
// Set all the other selected items to the same state
rgTable[nIndex].fChosen = fState;
ZeroMemory(&lvi, sizeof(LV_ITEM));
lvi.mask = LVIF_STATE;
lvi.iItem = nIndex;
lvi.state = rgTable[nIndex].fChosen ?
INDEXTOSTATEIMAGEMASK(iiconStateChecked + 1) :
INDEXTOSTATEIMAGEMASK(iiconStateUnchecked + 1);
lvi.stateMask = LVIS_STATEIMAGEMASK;
ListView_SetItem(hWndLV, &lvi);
}
return;
}
/***************************************************************************
Name : ExportWizard
Purpose : Present the Export Wizard
Parameters: hwnd = parent window handle
szFileName -> filename buffer (MAX_PATH + 1, please)
rgPropNames -> property name list
Returns : HRESULT
Comment :
***************************************************************************/
HRESULT ExportWizard(HWND hWnd, LPTSTR szFileName, ULONG cchSize, LPPROP_NAME rgPropNames) {
HRESULT hResult = hrSuccess;
PROPSHEETPAGE psp[NUM_EXPORT_WIZARD_PAGES];
PROPSHEETHEADER psh;
FillInPropertyPage(&psp[0], IDD_CSV_EXPORT_WIZARD_FILE, NULL, ExportFilePageProc, 0);
FillInPropertyPage(&psp[1], IDD_CSV_EXPORT_WIZARD_PICK, NULL, ExportPickFieldsPageProc, 0);
psh.dwSize = sizeof(PROPSHEETHEADER);
psh.dwFlags = PSH_PROPSHEETPAGE | PSH_WIZARD | PSH_NOAPPLYNOW | PSH_USEICONID;
psh.hwndParent = hWnd;
psh.pszCaption = NULL;
psh.pszIcon = MAKEINTRESOURCE(IDI_WabMig);
psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
psh.ppsp = (LPCPROPSHEETPAGE) &psp;
psh.hIcon = NULL;
psh.hInstance = hInst;
psh.nStartPage = 0;
psh.pStartPage = NULL;
switch (PropertySheet(&psh)) {
case -1:
hResult = ResultFromScode(MAPI_E_CALL_FAILED);
DebugTrace("PropertySheet failed -> %u\n", GetLastError());
Assert(FALSE);
break;
case 0:
hResult = ResultFromScode(MAPI_E_USER_CANCEL);
DebugTrace("PropertySheet cancelled by user\n");
break;
default:
StrCpyN(szFileName, szCSVFileName, cchSize);
break;
}
return(hResult);
}
/***************************************************************************
Name : ImportWizard
Purpose : Present the CSV Import Wizard
Parameters: hwnd = parent window handle
szFileName -> filename buffer (MAX_PATH + 1, please)
rgPropNames -> property name list
szSep -> list separator
lppImportMapping -> returned property mapping table
lpcFields -> returned size of property mapping table
lphFile -> returned file handle to CSV file with header
row already parsed out.
Returns : HRESULT
Comment :
***************************************************************************/
HRESULT ImportWizard(HWND hWnd, LPTSTR szFileName, ULONG cchSize, LPPROP_NAME rgPropNames,
LPTSTR szSep, LPPROP_NAME * lppImportMapping, LPULONG lpcFields, LPHANDLE lphFile) {
HRESULT hResult = hrSuccess;
PROPSHEETPAGE psp[NUM_IMPORT_WIZARD_PAGES];
PROPSHEETHEADER psh;
PROPSHEET_DATA pd;
pd.rgPropNames = rgPropNames;
pd.lppImportMapping = lppImportMapping;
pd.lphFile = lphFile;
pd.lpcFields = lpcFields;
pd.szSep = szSep;
FillInPropertyPage(&psp[0], IDD_CSV_IMPORT_WIZARD_FILE, NULL, ImportFilePageProc, (LPARAM)&pd);
FillInPropertyPage(&psp[1], IDD_CSV_IMPORT_WIZARD_MAP, NULL, ImportMapFieldsPageProc, (LPARAM)&pd);
psh.dwSize = sizeof(PROPSHEETHEADER);
psh.dwFlags = PSH_PROPSHEETPAGE | PSH_WIZARD | PSH_NOAPPLYNOW | PSH_USEICONID;
psh.hwndParent = hWnd;
psh.pszCaption = NULL;
psh.pszIcon = MAKEINTRESOURCE(IDI_WabMig);
psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
psh.ppsp = (LPCPROPSHEETPAGE) &psp;
psh.hIcon = NULL;
psh.hInstance = hInst;
psh.nStartPage = 0;
psh.pStartPage = NULL;
switch (PropertySheet(&psh)) {
case -1:
hResult = ResultFromScode(MAPI_E_CALL_FAILED);
DebugTrace("PropertySheet failed -> %u\n", GetLastError());
Assert(FALSE);
break;
case 0:
hResult = ResultFromScode(MAPI_E_USER_CANCEL);
DebugTrace("PropertySheet cancelled by user\n");
break;
default:
StrCpyN(szFileName, szCSVFileName, cchSize);
break;
}
return(hResult);
}
/***************************************************************************
Name : ExportFilePageProc
Purpose : Process messages for "Export Filename" page
Parameters: standard window proc parameters
Returns : standard window proc return
Messages : WM_INITDIALOG - intializes the page
WM_NOTIFY - processes the notifications sent to the page
Comment :
***************************************************************************/
INT_PTR CALLBACK ExportFilePageProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {
static TCHAR szTempFileName[MAX_PATH + 1] = "";
switch (message) {
case WM_INITDIALOG:
StrCpyN(szTempFileName, szCSVFileName, ARRAYSIZE(szTempFileName));
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDC_BROWSE:
SendDlgItemMessage(hDlg, IDE_CSV_EXPORT_NAME, WM_GETTEXT, (WPARAM)MAX_PATH, (LPARAM)szTempFileName);
SaveFileDialog(hDlg,
szTempFileName,
szCSVFilter,
IDS_CSV_FILE_SPEC,
szTextFilter,
IDS_TEXT_FILE_SPEC,
szAllFilter,
IDS_ALL_FILE_SPEC,
szCSVExt,
OFN_HIDEREADONLY | OFN_PATHMUSTEXIST,
hInst,
0, // idsTitle
0); // idsSaveButton
PropSheet_SetWizButtons(GetParent(hDlg), szTempFileName[0] ? PSWIZB_NEXT : 0);
SendMessage(GetDlgItem(hDlg, IDE_CSV_EXPORT_NAME), WM_SETTEXT, 0, (LPARAM)szTempFileName);
break;
case IDE_CSV_EXPORT_NAME:
switch (HIWORD(wParam)) { // notification code
case EN_CHANGE:
SendDlgItemMessage(hDlg, IDE_CSV_EXPORT_NAME, WM_GETTEXT, (WPARAM)MAX_PATH, (LPARAM)szTempFileName);
if ((ULONG)LOWORD(wParam) == IDE_CSV_EXPORT_NAME) {
PropSheet_SetWizButtons(GetParent(hDlg), szTempFileName[0] ? PSWIZB_NEXT : 0);
}
break;
}
break;
}
break;
case WM_NOTIFY:
switch (((NMHDR FAR *) lParam)->code) {
case PSN_KILLACTIVE:
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, FALSE);
return(1);
case PSN_RESET:
// reset to the original values
StrCpyN(szTempFileName, szCSVFileName, ARRAYSIZE(szTempFileName));
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, FALSE);
break;
case PSN_SETACTIVE:
PropSheet_SetWizButtons(GetParent(hDlg), szTempFileName[0] ? PSWIZB_NEXT : 0);
SendMessage(GetDlgItem(hDlg, IDE_CSV_EXPORT_NAME), WM_SETTEXT, 0, (LPARAM)szTempFileName);
break;
case PSN_WIZNEXT:
// the Next button was pressed
SendDlgItemMessage(hDlg, IDE_CSV_EXPORT_NAME, WM_GETTEXT, (WPARAM)MAX_PATH, (LPARAM)szTempFileName);
StrCpyN(szCSVFileName, szTempFileName, ARRAYSIZE(szCSVFileName));
break;
default:
return(FALSE);
}
break;
default:
return(FALSE);
}
return(TRUE);
}
/***************************************************************************
Name : ExportPickFieldsPageProc
Purpose : Process messages for "Pick Fields" page
Parameters: standard window proc parameters
Returns : standard window proc return
Messages : WM_INITDIALOG - intializes the page
WM_NOTIFY - processes the notifications sent to the page
Comment :
***************************************************************************/
INT_PTR CALLBACK ExportPickFieldsPageProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {
HWND hWndLV;
HIMAGELIST himl;
LV_ITEM lvi;
LV_COLUMN lvm;
LV_HITTESTINFO lvh;
POINT point;
ULONG i, nIndex;
NMHDR * pnmhdr;
RECT rect;
switch (message) {
case WM_INITDIALOG:
// Ensure that the common control DLL is loaded.
InitCommonControls();
// List view hwnd
hWndLV = GetDlgItem(hDlg, IDLV_PICKER);
// Load Image List for list view
if (himl = ImageList_LoadBitmap(hInst,
MAKEINTRESOURCE(IDB_CHECKS),
16,
0,
RGB(128, 0, 128))) {
ListView_SetImageList(hWndLV, himl, LVSIL_STATE);
}
// Fill the listview
ZeroMemory(&lvi, sizeof(LV_ITEM));
lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE;
for (i = 0; i < NUM_EXPORT_PROPS; i++) {
lvi.iItem = i;
lvi.pszText = rgPropNames[i].lpszName;
lvi.cchTextMax = lstrlen(lvi.pszText);
lvi.lParam = (LPARAM)&rgPropNames[i];
lvi.state = rgPropNames[i].fChosen ?
INDEXTOSTATEIMAGEMASK(iiconStateChecked + 1) :
INDEXTOSTATEIMAGEMASK(iiconStateUnchecked + 1);
lvi.stateMask = LVIS_STATEIMAGEMASK;
if (ListView_InsertItem(hWndLV, &lvi) == -1) {
DebugTrace("ListView_InsertItem -> %u\n", GetLastError());
Assert(FALSE);
}
}
// Insert a column for the text
// We don't have a header, so we don't need to set the text.
ZeroMemory(&lvm, sizeof(LV_COLUMN));
lvm.mask = LVCF_WIDTH;
// set the column width to the size of our listbox.
GetClientRect(hWndLV, &rect);
lvm.cx = rect.right;
ListView_InsertColumn(hWndLV, 0, &lvm);
// Full row selection on listview
ListView_SetExtendedListViewStyle(hWndLV, LVS_EX_FULLROWSELECT);
// Select the first item in the list
ListView_SetItemState( hWndLV,
0,
LVIS_FOCUSED | LVIS_SELECTED,
LVIS_FOCUSED | LVIS_SELECTED);
return(1);
case WM_COMMAND:
return(TRUE);
break;
case WM_NOTIFY:
pnmhdr = (LPNMHDR)lParam;
switch (((NMHDR FAR *)lParam)->code) {
case NM_CLICK:
case NM_DBLCLK:
hWndLV = GetDlgItem(hDlg, IDLV_PICKER);
i = GetMessagePos();
point.x = LOWORD(i);
point.y = HIWORD(i);
ScreenToClient(hWndLV, &point);
lvh.pt = point;
nIndex = ListView_HitTest(hWndLV, &lvh);
// if single click on icon or double click anywhere, toggle the checkmark.
if (((NMHDR FAR *)lParam)->code == NM_DBLCLK ||
( (lvh.flags & LVHT_ONITEMSTATEICON) && !(lvh.flags & LVHT_ONITEMLABEL))) {
HandleCheckMark(hWndLV, nIndex, rgPropNames);
}
break;
case LVN_KEYDOWN:
hWndLV = GetDlgItem(hDlg, IDLV_PICKER);
// toggle checkmark if SPACE key is pressed
if (pnmhdr->hwndFrom == hWndLV) {
LV_KEYDOWN *pnkd = (LV_KEYDOWN *)lParam;
// BUG 25097 allow multiple select
if (pnkd->wVKey == VK_SPACE)
{
nIndex = ListView_GetSelectedCount(hWndLV);
if(nIndex == 1)
{
nIndex = ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED | LVNI_ALL);
//if (nIndex >= 0) {
HandleCheckMark(hWndLV, nIndex, rgPropNames);
//}
}
else if(nIndex > 1)
{
//multiple select case ...
// Toggle all the selected items to the same state as the
// first item ...
HandleMultipleCheckMarks(hWndLV, rgPropNames);
}
}
}
break;
case PSN_KILLACTIVE:
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, FALSE);
return(1);
break;
case PSN_RESET:
// rest to the original values
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, FALSE);
break;
case PSN_SETACTIVE:
PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_BACK | PSWIZB_FINISH);
break;
case PSN_WIZBACK:
break;
case PSN_WIZFINISH:
// Here's where we do the export
break;
default:
return(FALSE);
}
break;
default:
return(FALSE);
}
return(TRUE);
}
//$$/////////////////////////////////////////////////////////////////////////////
//
// my_atoi - personal version of atoi function
//
// lpsz - string to parse into numbers - non numeral characters are ignored
//
/////////////////////////////////////////////////////////////////////////////////
int my_atoi(LPTSTR lpsz)
{
int i=0;
int nValue = 0;
if(lpsz)
{
if (lstrlen(lpsz))
{
nValue = 0;
while((lpsz[i]!='\0')&&(i<=lstrlen(lpsz)))
{
int tmp = lpsz[i]-'0';
if(tmp <= 9)
nValue = nValue*10 + tmp;
i++;
}
}
}
return nValue;
}
typedef struct {
LPTSTR lpszName;
ULONG iPropNamesTable; // index in rgProp
} SYNONYM, *LPSYNONYM;
/***************************************************************************
Name : FindPropName
Purpose : Finds a property name in the prop name table
Parameters: lpName = name to find or NULL to free the static synonym table
rgPropNames = property name table
ulcPropNames = size of property name table
Returns : index into table or INDEX_NOT_FOUND
Comment :
***************************************************************************/
#define INDEX_NOT_FOUND 0xFFFFFFFF
ULONG FindPropName(PUCHAR lpName, LPPROP_NAME rgPropNames, ULONG ulcPropNames) {
ULONG i;
static LPSYNONYM lpSynonymTable = NULL;
static ULONG ulSynonymsSave = 0;
ULONG ulSynonyms = ulSynonymsSave; // Keep local copy for compiler bug
ULONG ulSynonymStrings = 0;
if (lpName == NULL) {
goto clean_table;
}
for (i = 0; i < ulcPropNames; i++) {
if (! rgPropNames[i].fChosen) { // Don't re-use props!
if (! lstrcmpi(lpName, rgPropNames[i].lpszName)) {
return(i);
}
}
}
// If it wasn't found, look it up in the synonym table resource
// First, make sure we have a synonym table loaded
if (! lpSynonymTable) {
TCHAR szBuffer[MAX_RESOURCE_STRING + 1];
LPTSTR lpSynonym, lpName;
ULONG j;
// Load the synonym table
if (LoadString(hInst,
idsSynonymCount,
szBuffer, sizeof(szBuffer))) {
DebugTrace("Loading synonym table, %s synonyms\n", szBuffer);
ulSynonymStrings = my_atoi(szBuffer);
if (ulSynonymStrings) {
// Allocate the synonym table
if (! (lpSynonymTable = LocalAlloc(LPTR, ulSynonymStrings * sizeof(SYNONYM)))) {
DebugTrace("LocalAlloc synonym table -> %u\n", GetLastError());
goto clean_table;
}
for (i = 0; i < ulSynonymStrings; i++) {
if (LoadString(hInst,
idsSynonym001 + i, // ids of synonym string
szBuffer,
sizeof(szBuffer))) {
// Split the string at the '=' character
lpSynonym = lpName = szBuffer;
while (*lpName) {
if (*lpName == '=') {
// found equal sign, break the string here
*(lpName++) = '\0';
break;
}
lpName = CharNext(lpName);
}
// Find the name specified
for (j = 0; j < ulcPropNames; j++) {
if (! lstrcmpi(lpName, rgPropNames[j].lpszName)) {
// Found it
// Allocate a buffer for the synonym string
Assert(ulSynonyms < ulSynonymStrings);
if (! (lpSynonymTable[ulSynonyms].lpszName = LocalAlloc(LPTR, lstrlen(lpSynonym) + 1))) {
DebugTrace("LocalAlloc in synonym table -> %u\n", GetLastError());
goto clean_table;
}
StrCpyN(lpSynonymTable[ulSynonyms].lpszName, lpSynonym, lstrlen(lpSynonym) + 1);
lpSynonymTable[ulSynonyms].iPropNamesTable = j;
ulSynonyms++;
break;
}
}
}
}
}
}
ulSynonymsSave = ulSynonyms;
}
if (lpSynonymTable) {
// Find it
for (i = 0; i < ulSynonyms; i++) {
if (! lstrcmpi(lpName, lpSynonymTable[i].lpszName)) {
// Found the name. Is it already used?
if (rgPropNames[lpSynonymTable[i].iPropNamesTable].fChosen) {
break; // Found, but already used
}
return(lpSynonymTable[i].iPropNamesTable);
}
}
}
exit:
return(INDEX_NOT_FOUND);
clean_table:
if (lpSynonymTable) {
for (i = 0; i < ulSynonyms; i++) {
if (lpSynonymTable[i].lpszName) {
LocalFree(lpSynonymTable[i].lpszName);
}
}
LocalFree(lpSynonymTable);
lpSynonymTable = NULL;
ulSynonymsSave = 0;
}
goto exit;
}
/***************************************************************************
Name : BuildCSVTable
Purpose : Builds the initial CSV mapping table from the file header.
Parameters: lpFileName = filename to test
rgPropnames = property name table
szSep = separator character
lppImportMapping -> returned mapping table
lpcFields -> returned size of import mapping table
lphFile -> returned file handle for CSV file. File pointer
will be set past the header row.
Returns : HRESULT
Comment :
***************************************************************************/
HRESULT BuildCSVTable(LPTSTR lpFileName, LPPROP_NAME rgPropNames, LPTSTR szSep,
LPPROP_NAME * lppImportMapping, LPULONG lpcFields, LPHANDLE lphFile) {
PUCHAR * rgItems = NULL;
ULONG i, ulcItems = 0;
LPPROP_NAME rgImportMapping = NULL;
HRESULT hResult;
ULONG ulPropIndex;
// Open the file
if ((*lphFile = CreateFile(lpFileName,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_SEQUENTIAL_SCAN,
NULL)) == INVALID_HANDLE_VALUE) {
DebugTrace("Couldn't open file %s -> %u\n", lpFileName, GetLastError());
return(ResultFromScode(MAPI_E_NOT_FOUND));
}
// Parse the first row
if (hResult = ReadCSVLine(*lphFile, szSep, &ulcItems, &rgItems)) {
DebugTrace("Couldn't read the CSV header\n");
goto exit;
}
// Allocate the table
if (! (*lppImportMapping = rgImportMapping = LocalAlloc(LPTR, ulcItems * sizeof(PROP_NAME)))) {
DebugTrace("Allocation of import mapping table -> %u\n", GetLastError());
hResult = ResultFromScode(MAPI_E_NOT_ENOUGH_MEMORY);
goto exit;
}
// Reset flags on WAB property table
for (i = 0; i < NUM_EXPORT_PROPS; i++) {
rgPropNames[i].fChosen = FALSE;
}
// Fill in the CSV fields
for (i = 0; i < ulcItems; i++) {
Assert(rgItems[i]);
if (rgItems[i] && *rgItems[i]) {
rgImportMapping[i].lpszCSVName = rgItems[i];
// Look it up in the WAB property names table
if (INDEX_NOT_FOUND != (ulPropIndex = FindPropName(rgItems[i], rgPropNames, NUM_EXPORT_PROPS))) {
// Found a match
rgImportMapping[i].lpszName = rgPropNames[ulPropIndex].lpszName;
rgImportMapping[i].ids = rgPropNames[ulPropIndex].ids;
rgImportMapping[i].fChosen = TRUE;
rgImportMapping[i].ulPropTag = rgPropNames[ulPropIndex].ulPropTag;
rgPropNames[ulPropIndex].fChosen = TRUE;
DebugTrace("Match %u: %s\n", i, rgItems[i]);
} else {
DebugTrace("Unknown %u: %s\n", i, rgItems[i]);
}
} else {
DebugTrace("Empty %u: %s\n", i, rgItems[i]);
}
}
*lpcFields = ulcItems;
exit:
if (hResult) {
if (*lphFile != INVALID_HANDLE_VALUE) {
CloseHandle(*lphFile);
*lphFile = INVALID_HANDLE_VALUE;
}
if (rgItems) {
for (i = 0; i < ulcItems; i++) {
if (rgItems[i]) {
LocalFree(rgItems[i]);
}
}
}
if (rgImportMapping) {
LocalFree(rgImportMapping);
*lppImportMapping = NULL;
}
}
// If no error, leave the item strings since they are part of the mapping table.
if (rgItems) {
LocalFree(rgItems);
}
// Free the static memory for the synonym table.
FindPropName(NULL, rgPropNames, NUM_EXPORT_PROPS);
return(hResult);
}
/***************************************************************************
Name : FileExists
Purpose : Tests for existence of a file
Parameters: lpFileName = filename to test
Returns : TRUE if the file exists
Comment :
***************************************************************************/
BOOL FileExists(LPTSTR lpFileName) {
DWORD dwRet;
if ((dwRet = GetFileAttributes(lpFileName)) == 0xFFFFFFFF) {
return(FALSE);
} else {
return(! (dwRet & FILE_ATTRIBUTE_DIRECTORY)); // file was found
}
}
/***************************************************************************
Name : ImportFilePageProc
Purpose : Process messages for "Import Filename" page
Parameters: standard window proc parameters
Returns : standard window proc return
Messages : WM_INITDIALOG - intializes the page
WM_NOTIFY - processes the notifications sent to the page
Comment :
***************************************************************************/
INT_PTR CALLBACK ImportFilePageProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {
static TCHAR szTempFileName[MAX_PATH + 1] = "";
static LPPROPSHEET_DATA lppd = NULL;
LPPROPSHEETPAGE lppsp;
switch (message) {
case WM_INITDIALOG:
StrCpyN(szTempFileName, szCSVFileName, ARRAYSIZE(szTempFileName));
lppsp = (LPPROPSHEETPAGE)lParam;
lppd = (LPPROPSHEET_DATA)lppsp->lParam;
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDC_BROWSE:
SendDlgItemMessage(hDlg, IDE_CSV_IMPORT_NAME, WM_GETTEXT, (WPARAM)MAX_PATH, (LPARAM)szTempFileName);
OpenFileDialog(hDlg,
szTempFileName,
szCSVFilter,
IDS_CSV_FILE_SPEC,
szTextFilter,
IDS_TEXT_FILE_SPEC,
szAllFilter,
IDS_ALL_FILE_SPEC,
szCSVExt,
OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST,
hInst,
0, //idsTitle
0); // idsSaveButton
PropSheet_SetWizButtons(GetParent(hDlg), FileExists(szTempFileName) ? PSWIZB_NEXT : 0);
SendMessage(GetDlgItem(hDlg, IDE_CSV_IMPORT_NAME), WM_SETTEXT, 0, (LPARAM)szTempFileName);
break;
case IDE_CSV_IMPORT_NAME:
switch (HIWORD(wParam)) { // notification code
case EN_CHANGE:
SendDlgItemMessage(hDlg, IDE_CSV_IMPORT_NAME, WM_GETTEXT, (WPARAM)MAX_PATH, (LPARAM)szTempFileName);
if ((ULONG)LOWORD(wParam) == IDE_CSV_IMPORT_NAME) {
PropSheet_SetWizButtons(GetParent(hDlg), FileExists(szTempFileName) ? PSWIZB_NEXT : 0);
}
break;
}
break;
}
break;
case WM_NOTIFY:
switch (((NMHDR FAR *) lParam)->code) {
case PSN_KILLACTIVE:
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, FALSE);
return(1);
case PSN_RESET:
// reset to the original values
StrCpyN(szTempFileName, szCSVFileName, ARRAYSIZE(szTempFileName));
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, FALSE);
break;
case PSN_SETACTIVE:
PropSheet_SetWizButtons(GetParent(hDlg), szTempFileName[0] ? PSWIZB_NEXT : 0);
SendMessage(GetDlgItem(hDlg, IDE_CSV_IMPORT_NAME), WM_SETTEXT, 0, (LPARAM)szTempFileName);
break;
case PSN_WIZNEXT:
// the Next button was pressed
SendDlgItemMessage(hDlg, IDE_CSV_IMPORT_NAME, WM_GETTEXT, (WPARAM)MAX_PATH, (LPARAM)szTempFileName);
StrCpyN(szCSVFileName, szTempFileName, ARRAYSIZE(szCSVFileName));
break;
default:
return(FALSE);
}
break;
default:
return(FALSE);
}
return(TRUE);
}
typedef struct {
LPPROP_NAME lpMapping;
LPPROP_NAME rgPropNames;
ULONG ulcPropNames;
ULONG ulColumn;
} CHANGE_MAPPING_INFO, * LPCHANGE_MAPPING_INFO;
void HandleChangeMapping(HWND hDlg, LPPROPSHEET_DATA lppd) {
HWND hWndLV = GetDlgItem(hDlg, IDLV_MAPPER);
ULONG nIndex;
CHANGE_MAPPING_INFO cmi;
LV_ITEM lvi;
ULONG ulPropTagOld, i;
LPPROP_NAME lpMappingTable;
ULONG ulcMapping;
if ((nIndex = ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED)) == 0xFFFFFFFF) {
nIndex = 0;
ListView_SetItemState(hWndLV, nIndex, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED);
}
lpMappingTable = *(lppd->lppImportMapping);
cmi.lpMapping = &(lpMappingTable[nIndex]);
cmi.rgPropNames = lppd->rgPropNames;
cmi.ulcPropNames = NUM_EXPORT_PROPS;
cmi.ulColumn = nIndex;
ulPropTagOld = cmi.lpMapping->ulPropTag;
DialogBoxParam(hInst,
MAKEINTRESOURCE(IDD_CSV_CHANGE_MAPPING),
hDlg,
ChangeMappingDialogProc,
(LPARAM)&cmi);
// Fix the entry in the listbox
ZeroMemory(&lvi, sizeof(LV_ITEM));
// If there is no mapping, ensure that the field is unchosen
if (cmi.lpMapping->ulPropTag == PR_NULL || cmi.lpMapping->ulPropTag == 0 ) {
cmi.lpMapping->fChosen = FALSE;
}
lvi.iItem = nIndex;
lvi.lParam = (LPARAM)NULL;
lvi.mask = LVIF_STATE;
lvi.iSubItem = 0; // Checkbox is in first column
lvi.state = cmi.lpMapping->fChosen ?
INDEXTOSTATEIMAGEMASK(iiconStateChecked + 1) :
INDEXTOSTATEIMAGEMASK(iiconStateUnchecked + 1);
lvi.stateMask = LVIS_STATEIMAGEMASK;
if (ListView_SetItem(hWndLV, &lvi) == -1) {
DebugTrace("ListView_SetItem -> %u\n", GetLastError());
Assert(FALSE);
}
lvi.mask = LVIF_TEXT;
lvi.iSubItem = 1; // WAB Field
lvi.pszText = cmi.lpMapping->lpszName ? cmi.lpMapping->lpszName : (LPTSTR)szEmpty; // new wab field text
if (ListView_SetItem(hWndLV, &lvi) == -1) {
DebugTrace("ListView_SetItem -> %u\n", GetLastError());
Assert(FALSE);
}
// if we changed the mapping, make sure there's not a duplicate proptag mapped.
if (ulPropTagOld != cmi.lpMapping->ulPropTag) {
ulcMapping = *(lppd->lpcFields);
for (i = 0; i < ulcMapping; i++) {
if ((i != nIndex) && cmi.lpMapping->ulPropTag == lpMappingTable[i].ulPropTag) {
// Found a duplicate, nuke it.
lpMappingTable[i].ulPropTag = PR_NULL;
lpMappingTable[i].lpszName = (LPTSTR)szEmpty;
lpMappingTable[i].ids = 0;
lpMappingTable[i].fChosen = FALSE;
// Now, redraw that row in the listview
lvi.iItem = i;
lvi.lParam = (LPARAM)NULL;
// uncheck the box first
lvi.mask = LVIF_STATE;
lvi.iSubItem = 0; // Checkbox is in first column
lvi.state = INDEXTOSTATEIMAGEMASK(iiconStateUnchecked + 1);
lvi.stateMask = LVIS_STATEIMAGEMASK;
if (ListView_SetItem(hWndLV, &lvi) == -1) {
DebugTrace("ListView_SetItem -> %u\n", GetLastError());
Assert(FALSE);
}
// Now, change the name mapping
lvi.mask = LVIF_TEXT;
lvi.iSubItem = 1; // WAB Field
lvi.pszText = (LPTSTR)szEmpty; // new wab field text
if (ListView_SetItem(hWndLV, &lvi) == -1) {
DebugTrace("ListView_SetItem -> %u\n", GetLastError());
Assert(FALSE);
}
}
}
}
}
/***************************************************************************
Name : FieldOrColumnName
Purpose : If the field name is empty, generate one for it.
Parameters: lpField -> Field name pointer (may be null)
index = index of this column
szBuffer = buffer in which to create new string if
needed
cbBuffer = size of szBuffer
Returns : pointer to correct field name
Comment :
***************************************************************************/
LPTSTR FieldOrColumnName(LPTSTR lpField, ULONG index, LPTSTR szBuffer, ULONG cbBuffer) {
LPTSTR lpReturn = (LPTSTR)szEmpty;
if (lpField && *lpField) {
return(lpField);
} else {
TCHAR szFormat[MAX_RESOURCE_STRING + 1];
TCHAR szNumber[11];
LPTSTR lpszArg[1] = {szNumber};
// Format a "Column 23" type of label
wnsprintf(szNumber, ARRAYSIZE(szNumber), "%u", index);
if (LoadString(hInst,
IDS_CSV_COLUMN,
szFormat,
sizeof(szFormat))) {
if (! FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
szFormat,
0, 0, //ignored
szBuffer,
cbBuffer,
(va_list *)lpszArg)) {
DebugTrace("FormatMessage -> %u\n", GetLastError());
} else {
lpReturn = szBuffer;
}
}
}
return(lpReturn);
}
/***************************************************************************
Name : ImportMapFieldsPageProc
Purpose : Process messages for "Mapi Fields" page
Parameters: standard window proc parameters
Returns : standard window proc return
Messages : WM_INITDIALOG - intializes the page
WM_NOTIFY - processes the notifications sent to the page
Comment :
***************************************************************************/
INT_PTR CALLBACK ImportMapFieldsPageProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {
HWND hWndLV;
HIMAGELIST himl;
LV_ITEM lvi;
LV_COLUMN lvm;
LV_HITTESTINFO lvh;
POINT point;
ULONG i, nIndex, nOldIndex;
NMHDR * pnmhdr;
RECT rect;
TCHAR szBuffer[MAX_RESOURCE_STRING + 1 + 10];
ULONG cxTextWidth;
static LPPROPSHEET_DATA lppd = NULL;
LPPROPSHEETPAGE lppsp;
HRESULT hResult;
CHANGE_MAPPING_INFO cmi;
LPPROP_NAME lpImportMapping;
switch (message) {
case WM_INITDIALOG:
lppsp = (LPPROPSHEETPAGE)lParam;
lppd = (LPPROPSHEET_DATA)lppsp->lParam;
// Ensure that the common control DLL is loaded.
InitCommonControls();
// List view hwnd
hWndLV = GetDlgItem(hDlg, IDLV_MAPPER);
// How big should the text columns be?
GetClientRect(hWndLV, &rect);
cxTextWidth = (rect.right - CHECK_BITMAP_WIDTH) / 2;
cxTextWidth -= cxTextWidth % 2;
// Insert a column for the CSV Field Names
ZeroMemory(&lvm, sizeof(LV_COLUMN));
lvm.mask = LVCF_TEXT | LVCF_WIDTH;
lvm.cx = cxTextWidth + 9; // a touch more room for the bitmap
// Get the string for the header
if (LoadString(hInst, IDS_CSV_IMPORT_HEADER_CSV, szBuffer, sizeof(szBuffer))) {
lvm.pszText = szBuffer;
} else {
DebugTrace("Cannot load resource string %u\n", IDS_CSV_IMPORT_HEADER_CSV);
lvm.pszText = NULL;
Assert(FALSE);
}
ListView_InsertColumn(hWndLV, 0, &lvm);
// Insert a column for the WAB Field Names
lvm.mask = LVCF_TEXT | LVCF_WIDTH;
lvm.cx = cxTextWidth - 4; // room for second column text
// Get the string for the header
if (LoadString(hInst, IDS_CSV_IMPORT_HEADER_WAB, szBuffer, sizeof(szBuffer))) {
lvm.pszText = szBuffer;
} else {
DebugTrace("Cannot load resource string %u\n", IDS_CSV_IMPORT_HEADER_WAB);
lvm.pszText = NULL;
Assert(FALSE);
}
ListView_InsertColumn(hWndLV, 1, &lvm);
// Full row selection on listview
ListView_SetExtendedListViewStyle(hWndLV, LVS_EX_FULLROWSELECT);
// Load Image List for list view
if (himl = ImageList_LoadBitmap(hInst,
MAKEINTRESOURCE(IDB_CHECKS),
CHECK_BITMAP_WIDTH,
0,
RGB(128, 0, 128))) {
ListView_SetImageList(hWndLV, himl, LVSIL_STATE);
}
// Fill the listview
ZeroMemory(&lvi, sizeof(LV_ITEM));
// Open the file and parse out the headers line
if ((! (hResult = BuildCSVTable(szCSVFileName, lppd->rgPropNames,
lppd->szSep, lppd->lppImportMapping, lppd->lpcFields, lppd->lphFile))) && ((*lppd->lpcFields) > 0)) {
for (i = 0; i < *lppd->lpcFields; i++) {
ULONG index;
TCHAR szBuffer[MAX_RESOURCE_STRING + 1 + 10];
lpImportMapping = *lppd->lppImportMapping;
lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE;
lvi.iItem = i;
lvi.iSubItem = 0;
lvi.pszText = FieldOrColumnName(lpImportMapping[i].lpszCSVName,
i,
szBuffer,
sizeof(szBuffer));
lvi.cchTextMax = lstrlen(lvi.pszText);
lvi.lParam = (LPARAM)&lpImportMapping[i];
lvi.state = lpImportMapping[i].fChosen ?
INDEXTOSTATEIMAGEMASK(iiconStateChecked + 1) :
INDEXTOSTATEIMAGEMASK(iiconStateUnchecked + 1);
lvi.stateMask = LVIS_STATEIMAGEMASK;
if (index = ListView_InsertItem(hWndLV, &lvi) == -1) {
DebugTrace("ListView_InsertItem -> %u\n", GetLastError());
Assert(FALSE);
}
lvi.mask = LVIF_TEXT;
// lvi.iItem = index;
lvi.iSubItem = 1; // WAB Field
lvi.pszText = lpImportMapping[i].lpszName ? lpImportMapping[i].lpszName : (LPTSTR)szEmpty; // new wab field text
lvi.lParam = (LPARAM)NULL;
if (ListView_SetItem(hWndLV, &lvi) == -1) {
DebugTrace("ListView_SetItem -> %u\n", GetLastError());
Assert(FALSE);
}
}
}
else
EnableWindow(GetDlgItem(hDlg,IDC_CHANGE_MAPPING),FALSE);
// Select the first item in the list
ListView_SetItemState( hWndLV,
0,
LVIS_FOCUSED | LVIS_SELECTED,
LVIS_FOCUSED | LVIS_SELECTED);
return(1);
case WM_NOTIFY:
pnmhdr = (LPNMHDR)lParam;
switch (((NMHDR FAR *)lParam)->code) {
case NM_CLICK:
hWndLV = GetDlgItem(hDlg, IDLV_MAPPER);
i = GetMessagePos();
point.x = LOWORD(i);
point.y = HIWORD(i);
ScreenToClient(hWndLV, &point);
lvh.pt = point;
nIndex = ListView_HitTest(hWndLV, &lvh);
// if single click on icon or double click anywhere, toggle the checkmark.
if (((NMHDR FAR *)lParam)->code == NM_DBLCLK ||
( (lvh.flags & LVHT_ONITEMSTATEICON) && !(lvh.flags & LVHT_ONITEMLABEL))) {
HandleCheckMark(hWndLV, nIndex, *lppd->lppImportMapping);
// if the box is now clicked, but there is no mapping, bring up the
// mapping dialog
if ((*(lppd->lppImportMapping))[nIndex].fChosen &&
(! (*(lppd->lppImportMapping))[nIndex].lpszName ||
lstrlen((*(lppd->lppImportMapping))[nIndex].lpszName) == 0)) {
// Select the row
ListView_SetItemState(hWndLV, nIndex, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED);
HandleChangeMapping(hDlg, lppd);
}
}
break;
case NM_DBLCLK:
hWndLV = GetDlgItem(hDlg, IDLV_MAPPER);
i = GetMessagePos();
point.x = LOWORD(i);
point.y = HIWORD(i);
ScreenToClient(hWndLV, &point);
lvh.pt = point;
nIndex = ListView_HitTest(hWndLV, &lvh);
ListView_SetItemState(hWndLV, nIndex, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED);
HandleChangeMapping(hDlg, lppd);
break;
case LVN_KEYDOWN:
hWndLV = GetDlgItem(hDlg, IDLV_MAPPER);
// toggle checkmark if SPACE key is pressed
if (pnmhdr->hwndFrom == hWndLV) {
LV_KEYDOWN *pnkd = (LV_KEYDOWN *)lParam;
if (pnkd->wVKey == VK_SPACE) {
nIndex = ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED | LVNI_ALL);
//if (nIndex >= 0)
{
HandleCheckMark(hWndLV, nIndex, *lppd->lppImportMapping);
// if the box is now clicked, but there is no mapping, bring up the
// mapping dialog
if ((*(lppd->lppImportMapping))[nIndex].fChosen &&
(! (*(lppd->lppImportMapping))[nIndex].lpszName ||
lstrlen((*(lppd->lppImportMapping))[nIndex].lpszName) == 0)) {
// Select the row
ListView_SetItemState(hWndLV, nIndex, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED);
HandleChangeMapping(hDlg, lppd);
}
}
}
}
break;
case PSN_KILLACTIVE:
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, FALSE);
return(1);
break;
case PSN_RESET:
// rest to the original values
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, FALSE);
break;
case PSN_SETACTIVE:
PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_BACK | PSWIZB_FINISH);
break;
case PSN_WIZBACK:
break;
case PSN_WIZFINISH:
// Validate the properties selected to make sure we have
// name fields of some kind.
lpImportMapping = *lppd->lppImportMapping;
for (i = 0; i < *lppd->lpcFields; i++) {
ULONG ulPropTag = lpImportMapping[i].ulPropTag;
if (lpImportMapping[i].fChosen && (
ulPropTag == PR_DISPLAY_NAME ||
ulPropTag == PR_SURNAME ||
ulPropTag == PR_GIVEN_NAME ||
ulPropTag == PR_NICKNAME ||
ulPropTag == PR_COMPANY_NAME ||
ulPropTag == PR_EMAIL_ADDRESS ||
ulPropTag == PR_MIDDLE_NAME)) {
return(TRUE); // OK to go do the import
}
}
ShowMessageBoxParam(hDlg, IDE_CSV_NO_COLUMNS, 0);
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, -1);
break;
default:
return(FALSE);
}
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDC_CHANGE_MAPPING:
HandleChangeMapping(hDlg, lppd);
break;
}
break;
default:
return(FALSE);
}
return(TRUE);
}
INT_PTR CALLBACK ChangeMappingDialogProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
LPCHANGE_MAPPING_INFO lpcmi = (LPCHANGE_MAPPING_INFO)GetWindowLongPtr(hwnd, DWLP_USER);
static BOOL fChosenSave = FALSE;
ULONG iItem;
switch (message) {
case WM_INITDIALOG:
{
TCHAR szFormat[MAX_RESOURCE_STRING + 1];
TCHAR szBuffer[MAX_RESOURCE_STRING + 1 + 10];
LPTSTR lpszMessage = NULL;
ULONG ids, i, iDefault = 0xFFFFFFFF;
HWND hwndComboBox = GetDlgItem(hwnd, IDC_CSV_MAPPING_COMBO);
SetWindowLongPtr(hwnd, DWLP_USER, lParam); //Save this for future reference
lpcmi = (LPCHANGE_MAPPING_INFO)lParam;
fChosenSave = lpcmi->lpMapping->fChosen;
if (LoadString(hInst,
IDS_CSV_CHANGE_MAPPING_TEXT_FIELD,
szFormat, sizeof(szFormat))) {
LPTSTR lpszArg[1] = {FieldOrColumnName(lpcmi->lpMapping->lpszCSVName,
lpcmi->ulColumn,
szBuffer,
sizeof(szBuffer))};
if (! FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_ALLOCATE_BUFFER,
szFormat,
0, 0, //ignored
(LPTSTR)&lpszMessage,
0,
(va_list *)lpszArg)) {
DebugTrace("FormatMessage -> %u\n", GetLastError());
} else {
if (! SetDlgItemText(hwnd, IDC_CSV_CHANGE_MAPPING_TEXT_FIELD, lpszMessage)) {
DebugTrace("SetDlgItemText -> %u\n", GetLastError());
}
LocalFree(lpszMessage);
}
}
// Fill in the combo box
for (i = 0; i < lpcmi->ulcPropNames; i++) {
SendMessage(hwndComboBox, CB_ADDSTRING, 0, (LPARAM)lpcmi->rgPropNames[i].lpszName);
if (lpcmi->lpMapping->ids == lpcmi->rgPropNames[i].ids) {
SendMessage(hwndComboBox, CB_SETCURSEL, (WPARAM)i, 0);
}
}
// Add blank line
SendMessage(hwndComboBox, CB_ADDSTRING, 0, (LPARAM)szEmpty);
if (lpcmi->lpMapping->ids == 0) {
SendMessage(hwndComboBox, CB_SETCURSEL, (WPARAM)(i + 1), 0);
}
// Init the checkbox
CheckDlgButton(hwnd, IDC_CSV_MAPPING_SELECT, fChosenSave ? BST_CHECKED : BST_UNCHECKED);
return(TRUE);
}
case WM_COMMAND :
switch (LOWORD(wParam)) {
case IDCANCEL:
lpcmi->lpMapping->fChosen = fChosenSave;
SendMessage(hwnd, WM_CLOSE, 0, 0L);
return(0);
case IDCLOSE:
SendMessage(hwnd, WM_CLOSE, 0, 0L);
return(0);
case IDOK:
// Set the state of the parameter
// Get the mapping
if ((iItem = (ULONG) SendMessage(GetDlgItem(hwnd, IDC_CSV_MAPPING_COMBO), CB_GETCURSEL, 0, 0)) != CB_ERR) {
if (iItem >= lpcmi->ulcPropNames) {
lpcmi->lpMapping->lpszName = (LPTSTR)szEmpty;
lpcmi->lpMapping->ids = 0;
lpcmi->lpMapping->ulPropTag = PR_NULL;
lpcmi->lpMapping->fChosen = FALSE;
} else {
lpcmi->lpMapping->lpszName = rgPropNames[iItem].lpszName;
lpcmi->lpMapping->ids = rgPropNames[iItem].ids;
lpcmi->lpMapping->ulPropTag = rgPropNames[iItem].ulPropTag;
}
}
SendMessage(hwnd, WM_CLOSE, 0, 0);
return(0);
case IDM_EXIT:
SendMessage(hwnd, WM_DESTROY, 0, 0L);
return(0);
case IDC_CSV_MAPPING_SELECT:
switch (HIWORD(wParam)) {
case BN_CLICKED:
if ((int)LOWORD(wParam) == IDC_CSV_MAPPING_SELECT) {
// toggle the checkbox
lpcmi->lpMapping->fChosen = ! lpcmi->lpMapping->fChosen;
CheckDlgButton(hwnd, IDC_CSV_MAPPING_SELECT, lpcmi->lpMapping->fChosen ? BST_CHECKED : BST_UNCHECKED);
}
break;
}
break;
}
break;
case IDCANCEL:
SendMessage(hwnd, WM_CLOSE, 0, 0);
break;
case WM_CLOSE:
EndDialog(hwnd, FALSE);
return(0);
default:
return(FALSE);
}
return(TRUE);
}