2025-04-27 07:49:33 -04:00

457 lines
13 KiB
C

//*********************************************************************
//* Microsoft Windows **
//* Copyright(c) Microsoft Corp., 1994 **
//*********************************************************************
#include "admincfg.h"
typedef struct tagLISTBOXDLGINFO {
HGLOBAL hUser;
SETTINGS * pSettings;
UINT uDataIndex;
} LISTBOXDLGINFO;
typedef struct tagADDITEMINFO {
BOOL fExplicitValName;
BOOL fValPrefix;
HWND hwndListbox;
TCHAR szValueName[MAX_PATH+1]; // only used if fExplicitValName is ser
TCHAR szValueData[MAX_PATH+1];
} ADDITEMINFO;
INT_PTR CALLBACK ShowListboxDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,
LPARAM lParam);
INT_PTR CALLBACK ListboxAddDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,
LPARAM lParam);
BOOL InitShowlistboxDlg(HWND hDlg,LISTBOXDLGINFO * pListboxDlgInfo);
BOOL ProcessShowlistboxDlg(HWND hDlg);
VOID EnableShowListboxButtons(HWND hDlg);
UINT uListboxID;
VOID ShowListbox(HWND hParent,HGLOBAL hUser,SETTINGS * pSettings,UINT uDataIndex)
{
LISTBOXDLGINFO ListboxDlgInfo;
ListboxDlgInfo.hUser = hUser;
ListboxDlgInfo.pSettings = pSettings;
ListboxDlgInfo.uDataIndex = uDataIndex;
DialogBoxParam(ghInst,MAKEINTRESOURCE(DLG_SHOWLISTBOX),hParent,
ShowListboxDlgProc,(LPARAM) &ListboxDlgInfo);
}
VOID ListboxAdd(HWND hwndListbox, BOOL fExplicitValName,BOOL fValuePrefix)
{
ADDITEMINFO AddItemInfo;
LV_ITEM lvi;
memset(&AddItemInfo,0,sizeof(AddItemInfo));
AddItemInfo.fExplicitValName = fExplicitValName;
AddItemInfo.fValPrefix = fValuePrefix;
AddItemInfo.hwndListbox = hwndListbox;
// bring up the appropriate add dialog-- one edit field ("type the thing
// to add") normally, two edit fields ("type the name of the thing, type
// the value of the thing") if the explicit value style is used
if (!DialogBoxParam(ghInst,MAKEINTRESOURCE((fExplicitValName ? DLG_LBADD2 :
DLG_LBADD)),hwndListbox,ListboxAddDlgProc,(LPARAM) &AddItemInfo))
return; // user cancelled
// add the item to the listbox
lvi.mask = LVIF_TEXT;
lvi.iItem=lvi.iSubItem=0;
lvi.pszText=(fExplicitValName ? AddItemInfo.szValueName :
AddItemInfo.szValueData);
lvi.cchTextMax = lstrlen(lvi.pszText)+1;
if ((lvi.iItem=ListView_InsertItem(hwndListbox,&lvi))<0) {
// if add fails, display out of memory error
MsgBox(hwndListbox,IDS_ErrOUTOFMEMORY,MB_ICONEXCLAMATION,MB_OK);
return;
}
if (fExplicitValName) {
lvi.iSubItem=1;
lvi.pszText=AddItemInfo.szValueData;
lvi.cchTextMax = lstrlen(lvi.pszText)+1;
if (ListView_SetItem(hwndListbox,&lvi) < 0) {
MsgBox(hwndListbox,IDS_ErrOUTOFMEMORY,MB_ICONEXCLAMATION,MB_OK);
return;
}
}
}
VOID ListboxRemove(HWND hDlg,HWND hwndListbox)
{
int nItem;
while ( (nItem=ListView_GetNextItem(hwndListbox,-1,LVNI_SELECTED))
>= 0) {
ListView_DeleteItem(hwndListbox,nItem);
}
EnableShowListboxButtons(hDlg);
}
INT_PTR CALLBACK ShowListboxDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,
LPARAM lParam)
{
switch (uMsg) {
case WM_INITDIALOG:
// store away pointer to ListboxDlgInfo in window data
SetWindowLongPtr(hDlg,DWLP_USER,lParam);
if (!InitShowlistboxDlg(hDlg,(LISTBOXDLGINFO *) lParam)) {
MsgBox(hDlg,IDS_ErrOUTOFMEMORY,MB_ICONEXCLAMATION,MB_OK);
EndDialog(hDlg,FALSE);
}
return TRUE;
break;
case WM_COMMAND:
switch (wParam) {
case IDOK:
if (!ProcessShowlistboxDlg(hDlg)) {
MsgBox(hDlg,IDS_ErrOUTOFMEMORY,MB_ICONEXCLAMATION,MB_OK);
return FALSE;
}
EndDialog(hDlg,TRUE);
break;
case IDCANCEL:
EndDialog(hDlg,FALSE);
break;
case IDD_ADD:
{
LISTBOXDLGINFO * pListboxDlgInfo =
(LISTBOXDLGINFO *) GetWindowLongPtr(hDlg,DWLP_USER);
ListboxAdd(GetDlgItem(hDlg,uListboxID), (BOOL)
pListboxDlgInfo->pSettings->dwFlags & DF_EXPLICITVALNAME,
(BOOL)( ((LISTBOXINFO *)
GETOBJECTDATAPTR(pListboxDlgInfo->pSettings))->
uOffsetPrefix));
}
break;
case IDD_REMOVE:
ListboxRemove(hDlg,GetDlgItem(hDlg,uListboxID));
break;
}
case WM_NOTIFY:
if (wParam == uListboxID) {
if (((NMHDR FAR*)lParam)->code == LVN_ITEMCHANGED) {
EnableShowListboxButtons(hDlg);
}
}
break;
break;
}
return FALSE;
}
BOOL InitShowlistboxDlg(HWND hDlg,LISTBOXDLGINFO * pListboxDlgInfo)
{
HGLOBAL hUser = pListboxDlgInfo->hUser;
SETTINGS * pSettings = pListboxDlgInfo->pSettings;
LV_COLUMN lvc;
RECT rcListbox;
UINT uColWidth,uOffsetData;
HWND hwndListbox;
USERDATA * pUserData;
BOOL fSuccess=TRUE;
// there are 2 listview controls in dialog, 1 with header bar
// and one without; hide the control we aren't going to use
if (pSettings->dwFlags & DF_EXPLICITVALNAME) {
uListboxID = IDD_LISTBOX;
ShowWindow(GetDlgItem(hDlg,IDD_LISTBOX1),SW_HIDE);
} else {
uListboxID = IDD_LISTBOX1;
ShowWindow(GetDlgItem(hDlg,IDD_LISTBOX),SW_HIDE);
}
hwndListbox = GetDlgItem(hDlg,uListboxID);
// set the setting title in the dialog
SetDlgItemText(hDlg,IDD_TITLE,GETNAMEPTR(pSettings));
GetClientRect(hwndListbox,&rcListbox);
uColWidth = rcListbox.right-rcListbox.left;
if (pSettings->dwFlags & DF_EXPLICITVALNAME)
uColWidth /= 2;
if (pSettings->dwFlags & DF_EXPLICITVALNAME) {
// add a 2nd column to the listview control
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
lvc.fmt = LVCFMT_LEFT;
lvc.cx = uColWidth-1;
lvc.pszText = LoadSz(IDS_VALUENAME,szSmallBuf,ARRAYSIZE(szSmallBuf));
lvc.cchTextMax = lstrlen(lvc.pszText)+1;
lvc.iSubItem = 0;
ListView_InsertColumn(hwndListbox,0,&lvc);
}
// add a column to the listview control
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
lvc.fmt = LVCFMT_LEFT;
lvc.cx = uColWidth;
lvc.pszText = LoadSz(IDS_VALUE,szSmallBuf,ARRAYSIZE(szSmallBuf));
lvc.cchTextMax = lstrlen(lvc.pszText)+1;
lvc.iSubItem = (pSettings->dwFlags & DF_EXPLICITVALNAME ? 1 : 0);
ListView_InsertColumn(hwndListbox,lvc.iSubItem,&lvc);
SetWindowLong(hwndListbox,GWL_EXSTYLE,WS_EX_CLIENTEDGE);
SetScrollRange(hwndListbox,SB_VERT,0,100,TRUE);
SetScrollRange(hwndListbox,SB_VERT,0,0,TRUE);
EnableShowListboxButtons(hDlg);
// insert the items from user's data buffer into the listbox
if (!(pUserData = (USERDATA *) GlobalLock(hUser)))
return FALSE;
uOffsetData=pUserData->SettingData[pListboxDlgInfo->uDataIndex].uOffsetData;
if (uOffsetData) {
TCHAR * pszData =((STRDATA *)((LPBYTE) pUserData + uOffsetData))->szData;
while (*pszData && fSuccess) {
LV_ITEM lvi;
lvi.pszText=pszData;
lvi.mask = LVIF_TEXT;
lvi.iItem=-1;
lvi.iSubItem=0;
lvi.cchTextMax = lstrlen(pszData)+1;
// if explicit valuename flag set, entries are stored
// <value name>\0<value>\0....<value name>\0<value>\0\0
// otherwise, entries are stored
// <value>\0<value>\0....<value>\0
if (pSettings->dwFlags & DF_EXPLICITVALNAME) {
fSuccess=((lvi.iItem=ListView_InsertItem(hwndListbox,&lvi)) >= 0);
pszData += lstrlen(pszData) +1;
if (fSuccess && *pszData) {
lvi.iSubItem=1;
lvi.pszText=pszData;
lvi.cchTextMax = lstrlen(pszData)+1;
fSuccess=(ListView_SetItem(hwndListbox,&lvi) >= 0);
pszData += lstrlen(pszData) +1;
}
} else {
fSuccess=((lvi.iItem=ListView_InsertItem(hwndListbox,&lvi)) >= 0);
pszData += lstrlen(pszData) +1;
}
}
}
GlobalUnlock(hUser);
return fSuccess;
}
BOOL ProcessShowlistboxDlg(HWND hDlg)
{
LISTBOXDLGINFO * pListboxDlgInfo = (LISTBOXDLGINFO *)
GetWindowLongPtr(hDlg,DWLP_USER); // get pointer to struct from window data
DWORD dwAlloc=1024,dwUsed=0;
HGLOBAL hBuf;
TCHAR * pBuf;
HWND hwndListbox = GetDlgItem(hDlg,uListboxID);
LV_ITEM lvi;
UINT nLen;
int nCount;
BOOL fSuccess;
TCHAR pszText[MAX_PATH+1];
// allocate a temp buffer to read entries into
if (!(hBuf = GlobalAlloc(GHND,dwAlloc * sizeof(TCHAR))) ||
!(pBuf = (TCHAR *) GlobalLock(hBuf))) {
if (hBuf)
GlobalFree(hBuf);
return FALSE;
}
lvi.mask = LVIF_TEXT;
lvi.iItem=0;
lvi.pszText = pszText;
lvi.cchTextMax = ARRAYSIZE(pszText);
nCount = ListView_GetItemCount(hwndListbox);
// retrieve the items out of listbox, pack into temp buffer
for (;lvi.iItem<nCount;lvi.iItem ++) {
lvi.iSubItem = 0;
if (ListView_GetItem(hwndListbox,&lvi)) {
nLen = lstrlen(lvi.pszText) + 1;
if (!(pBuf=ResizeBuffer(pBuf,hBuf,dwUsed+nLen+4,&dwAlloc)))
return ERROR_NOT_ENOUGH_MEMORY;
lstrcpy(pBuf+dwUsed,lvi.pszText);
dwUsed += nLen;
}
if (pListboxDlgInfo->pSettings->dwFlags & DF_EXPLICITVALNAME) {
lvi.iSubItem = 1;
if (ListView_GetItem(hwndListbox,&lvi)) {
nLen = lstrlen(lvi.pszText) + 1;
if (!(pBuf=ResizeBuffer(pBuf,hBuf,dwUsed+nLen+4,&dwAlloc)))
return ERROR_NOT_ENOUGH_MEMORY;
lstrcpy(pBuf+dwUsed,lvi.pszText);
dwUsed += nLen;
}
}
}
// doubly null-terminate the buffer... safe to do this because we
// tacked on the extra "+4" in the ResizeBuffer calls above
*(pBuf+dwUsed) = TEXT('\0');
dwUsed ++;
fSuccess=SetVariableLengthData(pListboxDlgInfo->hUser,
pListboxDlgInfo->uDataIndex,pBuf,dwUsed);
GlobalUnlock(hBuf);
GlobalFree(hBuf);
return fSuccess;
}
VOID EnableShowListboxButtons(HWND hDlg)
{
BOOL fEnable;
// enable Remove button if there are any items selected
fEnable = (ListView_GetNextItem(GetDlgItem(hDlg,uListboxID),
-1,LVNI_SELECTED) >= 0);
EnableDlgItem(hDlg,IDD_REMOVE,fEnable);
}
INT_PTR CALLBACK ListboxAddDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,
LPARAM lParam)
{
switch (uMsg) {
case WM_INITDIALOG:
{
ADDITEMINFO * pAddItemInfo = (ADDITEMINFO *)lParam;
// store away pointer to additeminfo in window data
SetWindowLongPtr(hDlg,DWLP_USER,lParam);
SendDlgItemMessage(hDlg,IDD_VALUENAME,EM_LIMITTEXT,MAX_PATH,0L);
SendDlgItemMessage(hDlg,IDD_VALUEDATA,EM_LIMITTEXT,MAX_PATH,0L);
if (!pAddItemInfo->fExplicitValName) {
ShowWindow (GetDlgItem (hDlg, IDD_VALUENAME), SW_HIDE);
}
}
break;
case WM_COMMAND:
switch (wParam) {
case IDOK:
{
ADDITEMINFO * pAddItemInfo = (ADDITEMINFO *)
GetWindowLongPtr(hDlg,DWLP_USER);
GetDlgItemText(hDlg,IDD_VALUENAME,
pAddItemInfo->szValueName,
ARRAYSIZE(pAddItemInfo->szValueName));
GetDlgItemText(hDlg,IDD_VALUEDATA,
pAddItemInfo->szValueData,
ARRAYSIZE(pAddItemInfo->szValueData));
// if explicit value names used, value name must
// not be empty, and it must be unique
if (pAddItemInfo->fExplicitValName) {
LV_FINDINFO lvfi;
int iSel;
if (!lstrlen(pAddItemInfo->szValueName)) {
// can't be empty
MsgBox(hDlg,IDS_EMPTYVALUENAME,
MB_ICONINFORMATION,MB_OK);
SetFocus(GetDlgItem(hDlg,IDD_VALUENAME));
return FALSE;
}
lvfi.flags = LVFI_STRING | LVFI_NOCASE;
lvfi.psz = pAddItemInfo->szValueName;
iSel=ListView_FindItem(pAddItemInfo->hwndListbox,
-1,&lvfi);
if (iSel >= 0) {
// value name already used
MsgBox(hDlg,IDS_VALUENAMENOTUNIQUE,
MB_ICONINFORMATION,MB_OK);
SetFocus(GetDlgItem(hDlg,IDD_VALUENAME));
SendDlgItemMessage(hDlg,IDD_VALUENAME,
EM_SETSEL,0,-1);
return FALSE;
}
} else if (!pAddItemInfo->fValPrefix) {
// if value name == value data, then value data
// must be unique
LV_FINDINFO lvfi;
int iSel;
if (!lstrlen(pAddItemInfo->szValueData)) {
// can't be empty
MsgBox(hDlg,IDS_EMPTYVALUEDATA,
MB_ICONINFORMATION,MB_OK);
SetFocus(GetDlgItem(hDlg,IDD_VALUEDATA));
return FALSE;
}
lvfi.flags = LVFI_STRING | LVFI_NOCASE;
lvfi.psz = pAddItemInfo->szValueData;
iSel=ListView_FindItem(pAddItemInfo->hwndListbox,
-1,&lvfi);
if (iSel >= 0) {
// value name already used
MsgBox(hDlg,IDS_VALUEDATANOTUNIQUE,
MB_ICONINFORMATION,MB_OK);
SetFocus(GetDlgItem(hDlg,IDD_VALUEDATA));
SendDlgItemMessage(hDlg,IDD_VALUEDATA,
EM_SETSEL,0,-1);
return FALSE;
}
}
EndDialog(hDlg,TRUE);
}
break;
case IDCANCEL:
EndDialog(hDlg,FALSE);
break;
}
break;
}
return FALSE;
}