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

1309 lines
32 KiB
C

/* Copyright (c) 1995, Microsoft Corporation, all rights reserved
**
** edit.c
** Remote Access Common Dialog APIs
** List editor, string editor dialog routines
**
** 08/28/95 Steve Cobb
*/
#include "rasdlgp.h"
/*----------------------------------------------------------------------------
** Local datatypes (alphabetically)
**----------------------------------------------------------------------------
*/
/* List editor dialog argument block.
*/
#define LEARGS struct tagLEARGS
LEARGS
{
/* Caller's arguments to the stub API.
*/
DTLLIST* pList;
BOOL* pfCheck;
DWORD dwMaxItemLen;
TCHAR* pszTitle;
TCHAR* pszItemLabel;
TCHAR* pszListLabel;
TCHAR* pszCheckLabel;
TCHAR* pszDefaultItem;
INT iSelInitial;
DWORD* pdwHelp;
DWORD dwfFlags;
PDESTROYNODE pDestroyId;
};
/* List editor dialog context block.
*/
#define LEINFO struct tagLEINFO
LEINFO
{
/* Caller's arguments to the dialog.
*/
LEARGS* pArgs;
/* Handle of this dialog and some of it's controls.
*/
HWND hwndDlg;
HWND hwndStItem;
HWND hwndStList;
HWND hwndPbAdd;
HWND hwndPbReplace;
HWND hwndPbUp;
HWND hwndPbDown;
HWND hwndPbDelete;
HWND hwndPbOk;
HWND hwndEb;
HWND hwndLb;
HWND hwndCb;
/* Convenient alternatives to (pInfo->pArgs->dwFlags & LEDFLAG_Sorted) and
** (pInfo->pArgs->dwFlags & LEDFLAG_NoDeleteLastItem).
*/
BOOL fSorted;
BOOL fNoDeleteLast;
/* Button bitmaps.
*/
HBITMAP hbmUp;
HBITMAP hbmDown;
/* List of empty nodes whose node-IDs should be 'pDestroyId'ed if user
** presses OK.
*/
DTLLIST* pListDeletes;
};
/* String Editor dialog arument block.
*/
#define ZEARGS struct tagZEARGS
ZEARGS
{
/* Caller's aruments to the stub API.
*/
TCHAR* pszIn;
DWORD dwSidTitle;
DWORD dwSidLabel;
DWORD cbMax;
DWORD dwHelpId;
TCHAR** ppszOut;
};
/* String Editor dialog context block.
*/
#define ZEINFO struct tagZEINFO
ZEINFO
{
/* Caller's arguments to the stub API.
*/
ZEARGS* pArgs;
/* Dialog and control handles.
*/
HWND hwndDlg;
HWND hwndEb;
};
/*----------------------------------------------------------------------------
** Local prototypes (alphabetically)
**----------------------------------------------------------------------------
*/
INT_PTR CALLBACK
LeDlgProc(
IN HWND hwnd,
IN UINT unMsg,
IN WPARAM wparam,
IN LPARAM lparam );
VOID
LeAdd(
IN LEINFO* pInfo );
BOOL
LeCommand(
IN LEINFO* pInfo,
IN WORD wNotification,
IN WORD wId,
IN HWND hwndCtrl );
VOID
LeDelete(
IN LEINFO* pInfo );
VOID
LeDown(
IN LEINFO* pInfo );
VOID
LeEnableUpAndDownButtons(
IN LEINFO* pInfo );
VOID
LeExitNoMemory(
IN LEINFO* pInfo );
BOOL
LeInit(
IN HWND hwndDlg,
IN LEARGS* pArgs );
VOID
LeItemTextFromListSelection(
IN LEINFO* pInfo );
VOID
LeReplace(
IN LEINFO* pInfo );
BOOL
LeSaveSettings(
IN LEINFO* pInfo );
VOID
LeTerm(
IN HWND hwndDlg );
VOID
LeUp(
IN LEINFO* pInfo );
INT_PTR CALLBACK
ZeDlgProc(
IN HWND hwnd,
IN UINT unMsg,
IN WPARAM wparam,
IN LPARAM lparam );
BOOL
ZeCommand(
IN ZEINFO* pInfo,
IN WORD wNotification,
IN WORD wId,
IN HWND hwndCtrl );
BOOL
ZeInit(
IN HWND hwndDlg,
IN ZEARGS* pArgs );
VOID
ZeTerm(
IN HWND hwndDlg );
/*----------------------------------------------------------------------------
** List Editor dialog entry point
**----------------------------------------------------------------------------
*/
BOOL
ListEditorDlg(
IN HWND hwndOwner,
IN OUT DTLLIST* pList,
IN OUT BOOL* pfCheck,
IN DWORD dwMaxItemLen,
IN TCHAR* pszTitle,
IN TCHAR* pszItemLabel,
IN TCHAR* pszListLabel,
IN TCHAR* pszCheckLabel,
IN TCHAR* pszDefaultItem,
IN INT iSelInitial,
IN DWORD* pdwHelp,
IN DWORD dwfFlags,
IN PDESTROYNODE pDestroyId )
/* Pops-up the List Editor dialog.
**
** 'HwndOwner' is the owner of the dialog. 'PList' is, on entry, the Psz
** list to display initially, and on successful exit, the result list.
** 'PfCheck' is the state of the check box or NULL for the non-checkbox
** style. 'DwMaxItemLen' is the maximum length of an individual list
** item. 'PszTitle' is the dialog title. 'PszItemLabel' is the label
** (and hotkey) associated with the item box. 'PszListLabel' is the label
** (and hotkey) associated with the list. 'PszCheckLabel' is the label
** (and hotkey) associated with the checkbox. 'PszDefaultItem' is the
** default contents of the edit box or for the selected list text.
** 'ISelInitial' is the item the list to initally select. 'PdwHelp' is
** the array of CID_LE_* help contexts to use. 'DwfFlags' indicates
** LEDFLAG_* behavior options. 'PDestroyId' is the routine to use to
** destroy node IDs when they are deleted or NULL if none.
**
** Returns true if user pressed OK and succeeded, false if he pressed
** Cancel or encountered an error.
*/
{
int nStatus;
LEARGS args;
TRACE("ListEditorDlg");
args.pList = pList;
args.pfCheck = pfCheck;
args.dwMaxItemLen = dwMaxItemLen;
args.pszTitle = pszTitle;
args.pszItemLabel = pszItemLabel;
args.pszListLabel = pszListLabel;
args.pszCheckLabel = pszCheckLabel;
args.pszDefaultItem = pszDefaultItem;
args.iSelInitial = iSelInitial;
args.pdwHelp = pdwHelp;
args.dwfFlags = dwfFlags;
args.pDestroyId = pDestroyId;
nStatus =
(BOOL )DialogBoxParam(
g_hinstDll,
(pfCheck)
? MAKEINTRESOURCE( DID_LE_ListEditor2 )
: ((dwfFlags & LEDFLAG_Sorted)
? MAKEINTRESOURCE( DID_LE_ListEditor3 )
: MAKEINTRESOURCE( DID_LE_ListEditor )),
hwndOwner,
LeDlgProc,
(LPARAM )&args );
if (nStatus == -1)
{
ErrorDlg( hwndOwner, SID_OP_LoadDlg, ERROR_UNKNOWN, NULL );
nStatus = FALSE;
}
return (BOOL )nStatus;
}
/*----------------------------------------------------------------------------
** List Editor dialog routines
** Listed alphabetically following dialog proc
**----------------------------------------------------------------------------
*/
INT_PTR CALLBACK
LeDlgProc(
IN HWND hwnd,
IN UINT unMsg,
IN WPARAM wparam,
IN LPARAM lparam )
/* DialogProc callback for the List Editor dialog. Parameters and return
** value are as described for standard windows 'DialogProc's.
*/
{
#if 0
TRACE4("LeDlgProc(h=$%x,m=$%x,w=$%x,l=$%x)",
(DWORD)hwnd,(DWORD)unMsg,(DWORD)wparam,(DWORD)lparam);
#endif
switch (unMsg)
{
case WM_INITDIALOG:
return LeInit( hwnd, (LEARGS* )lparam );
case WM_HELP:
case WM_CONTEXTMENU:
{
LEINFO* pInfo = (LEINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
ASSERT(pInfo);
ContextHelp( pInfo->pArgs->pdwHelp, hwnd, unMsg, wparam, lparam );
break;
}
case WM_COMMAND:
{
LEINFO* pInfo = (LEINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
ASSERT(pInfo);
return LeCommand(
pInfo, HIWORD( wparam ), LOWORD( wparam ), (HWND )lparam );
}
case WM_DESTROY:
{
LeTerm( hwnd );
break;
}
}
return FALSE;
}
VOID
LeAdd(
IN LEINFO* pInfo )
/* Add button click handler. 'PInfo' is the dialog context.
*/
{
TCHAR* psz;
psz = GetText( pInfo->hwndEb );
if (!psz)
{
LeExitNoMemory( pInfo );
return;
}
if (pInfo->pArgs->dwfFlags & LEDFLAG_Unique)
{
if (ListBox_IndexFromString( pInfo->hwndLb, psz ) >= 0)
{
MSGARGS msgargs;
ZeroMemory( &msgargs, sizeof(msgargs) );
msgargs.apszArgs[ 0 ] = psz;
MsgDlg( pInfo->hwndDlg, SID_NotUnique, &msgargs );
Edit_SetSel( pInfo->hwndEb, 0, -1 );
SetFocus( pInfo->hwndEb );
Free( psz );
return;
}
}
ListBox_SetCurSel( pInfo->hwndLb,
ListBox_AddItem( pInfo->hwndLb, psz, 0 ) );
Free( psz );
LeEnableUpAndDownButtons( pInfo );
EnableWindow( pInfo->hwndPbReplace, FALSE );
if (!pInfo->fNoDeleteLast || ListBox_GetCount( pInfo->hwndLb ) > 1)
EnableWindow( pInfo->hwndPbDelete, TRUE );
SetWindowText( pInfo->hwndEb, TEXT("") );
SetFocus( pInfo->hwndEb );
}
BOOL
LeCommand(
IN LEINFO* pInfo,
IN WORD wNotification,
IN WORD wId,
IN HWND hwndCtrl )
/* Called on WM_COMMAND. 'PInfo' is the dialog context. 'WNotification'
** is the notification code of the command. 'wId' is the control/menu
** identifier of the command. 'HwndCtrl' is the control window handle of
** the command.
**
** Returns true if processed message, false otherwise.
*/
{
TRACE2("LeCommand(n=%d,i=%d)",
(DWORD)wNotification,(DWORD)wId);
switch (wId)
{
case CID_LE_PB_Add:
LeAdd( pInfo );
return TRUE;
case CID_LE_PB_Replace:
LeReplace( pInfo );
return TRUE;
case CID_LE_PB_Up:
LeUp( pInfo );
return TRUE;
case CID_LE_PB_Down:
LeDown( pInfo );
return TRUE;
case CID_LE_PB_Delete:
LeDelete( pInfo );
return TRUE;
case CID_LE_EB_Item:
{
if (wNotification == EN_SETFOCUS || wNotification == EN_UPDATE)
{
TCHAR* psz = GetText( pInfo->hwndEb );
if (psz && lstrlen( psz ) > 0 && !IsAllWhite( psz ))
{
EnableWindow( pInfo->hwndPbAdd, TRUE );
EnableWindow( pInfo->hwndPbReplace, TRUE );
Button_MakeDefault( pInfo->hwndDlg, pInfo->hwndPbAdd );
}
else
{
EnableWindow( pInfo->hwndPbAdd, FALSE );
EnableWindow( pInfo->hwndPbReplace, FALSE );
Button_MakeDefault( pInfo->hwndDlg, pInfo->hwndPbOk );
}
Free0( psz );
}
return TRUE;
}
case CID_LE_LB_List:
{
if (wNotification == LBN_SELCHANGE)
{
LeEnableUpAndDownButtons( pInfo );
if (ListBox_GetCurSel( pInfo->hwndLb ) >= 0)
LeItemTextFromListSelection( pInfo );
}
return TRUE;
}
case CID_LE_CB_Promote:
{
if (wNotification == BN_SETFOCUS)
Button_MakeDefault( pInfo->hwndDlg, pInfo->hwndPbOk );
return TRUE;
}
case IDOK:
EndDialog( pInfo->hwndDlg, LeSaveSettings( pInfo ) );
return TRUE;
case IDCANCEL:
{
DTLLIST* pList;
DTLNODE* pNode;
TRACE("Cancel pressed");
EndDialog( pInfo->hwndDlg, FALSE );
return TRUE;
}
}
return FALSE;
}
VOID
LeDelete(
IN LEINFO* pInfo )
/* Delete button click handler. 'PInfo' is the dialog context.
*/
{
INT i;
INT c;
i = ListBox_GetCurSel( pInfo->hwndLb );
if (pInfo->pArgs->pDestroyId)
{
INT_PTR lId = ListBox_GetItemData( pInfo->hwndLb, i );
if (lId != 0)
{
DTLNODE* pNode;
pNode = DtlCreateNode( NULL, (DWORD)lId );
if (!pNode)
{
ErrorDlg( pInfo->hwndDlg, SID_OP_DisplayData,
ERROR_NOT_ENOUGH_MEMORY, NULL );
EndDialog( pInfo->hwndDlg, FALSE );
return;
}
DtlAddNodeFirst( pInfo->pListDeletes, pNode );
}
}
ListBox_DeleteString( pInfo->hwndLb, i );
c = ListBox_GetCount( pInfo->hwndLb );
if (c == 0)
{
EnableWindow( pInfo->hwndPbReplace, FALSE );
EnableWindow( pInfo->hwndPbDelete, FALSE );
SetFocus( pInfo->hwndEb );
Edit_SetSel( pInfo->hwndEb, 0, -1 );
}
else
{
if (c == 1 && pInfo->fNoDeleteLast)
EnableWindow( pInfo->hwndPbDelete, FALSE );
if (i >= c)
i = c - 1;
ListBox_SetCurSel( pInfo->hwndLb, i );
}
LeEnableUpAndDownButtons( pInfo );
if (IsWindowEnabled( GetFocus() ))
{
SetFocus( pInfo->hwndEb );
Edit_SetSel( pInfo->hwndEb, 0, -1 );
}
}
VOID
LeDown(
IN LEINFO* pInfo )
/* Down button click handler. 'PInfo' is the dialog context.
*/
{
TCHAR* psz;
INT i;
INT_PTR lId;
ASSERT(!pInfo->fSorted);
i = ListBox_GetCurSel( pInfo->hwndLb );
psz = ListBox_GetPsz( pInfo->hwndLb, i );
if (!psz)
{
LeExitNoMemory( pInfo );
return;
}
lId = ListBox_GetItemData( pInfo->hwndLb, i );
ListBox_InsertString( pInfo->hwndLb, i + 2, psz );
ListBox_SetItemData( pInfo->hwndLb, i + 2, lId );
Free( psz );
ListBox_DeleteString( pInfo->hwndLb, i );
ListBox_SetCurSel( pInfo->hwndLb, i + 1 );
if (i == ListBox_GetCount( pInfo->hwndLb ))
{
Button_MakeDefault( pInfo->hwndDlg, pInfo->hwndPbUp );
SetFocus( pInfo->hwndPbUp );
}
LeEnableUpAndDownButtons( pInfo );
}
VOID
LeEnableUpAndDownButtons(
IN LEINFO* pInfo )
/* Determine if the Up and Down operations make sense and enable/disable
** the buttons as appropriate. 'PInfo' is the dialog context.
*/
{
INT i;
INT c;
if (pInfo->fSorted)
return;
i = ListBox_GetCurSel( pInfo->hwndLb );
c = ListBox_GetCount( pInfo->hwndLb );
EnableWindow( pInfo->hwndPbDown, (i < c - 1 ) );
EnableWindow( pInfo->hwndPbUp, (i > 0) );
}
VOID
LeExitNoMemory(
IN LEINFO* pInfo )
/* End the dialog reporting a memory. 'PInfo' is the dialog context.
*/
{
ErrorDlg( pInfo->hwndDlg,
SID_OP_DisplayData, ERROR_NOT_ENOUGH_MEMORY, NULL );
EndDialog( pInfo->hwndDlg, FALSE );
}
BOOL
LeInit(
IN HWND hwndDlg,
IN LEARGS* pArgs )
/* Called on WM_INITDIALOG. 'HwndDlg' is the handle of the phonebook
** dialog window. 'PArgs' is caller's arguments as passed to the stub
** API.
**
** Return false if focus was set, true otherwise, i.e. as defined for
** WM_INITDIALOG.
*/
{
DWORD dwErr;
LEINFO* pInfo;
DTLNODE* pNode;
INT c;
TRACE("LeInit");
/* Allocate the dialog context block. Initialize minimally for proper
** cleanup, then attach to the dialog window.
*/
{
pInfo = Malloc( sizeof(*pInfo) );
if (!pInfo)
{
ErrorDlg( hwndDlg, SID_OP_LoadDlg, ERROR_NOT_ENOUGH_MEMORY, NULL );
EndDialog( hwndDlg, FALSE );
return TRUE;
}
ZeroMemory( pInfo, sizeof(*pInfo) );
pInfo->pArgs = pArgs;
pInfo->hwndDlg = hwndDlg;
SetWindowLongPtr( hwndDlg, DWLP_USER, (LONG_PTR)pInfo );
TRACE("Context set");
}
/* Set up convenient shortcuts.
*/
if (pArgs->dwfFlags & LEDFLAG_Sorted)
pInfo->fSorted = TRUE;
if (pArgs->dwfFlags & LEDFLAG_NoDeleteLastItem)
pInfo->fNoDeleteLast = TRUE;
pInfo->hwndStItem = GetDlgItem( hwndDlg, CID_LE_ST_Item );
ASSERT(pInfo->hwndStItem);
pInfo->hwndStList = GetDlgItem( hwndDlg, CID_LE_ST_List );
ASSERT(pInfo->hwndStList);
pInfo->hwndPbAdd = GetDlgItem( hwndDlg, CID_LE_PB_Add );
ASSERT(pInfo->hwndPbAdd);
pInfo->hwndPbReplace = GetDlgItem( hwndDlg, CID_LE_PB_Replace );
ASSERT(pInfo->hwndPbReplace);
pInfo->hwndPbDelete = GetDlgItem( hwndDlg, CID_LE_PB_Delete );
ASSERT(pInfo->hwndPbDelete);
pInfo->hwndPbOk = GetDlgItem( hwndDlg, IDOK );
ASSERT(pInfo->hwndPbOk);
pInfo->hwndEb = GetDlgItem( hwndDlg, CID_LE_EB_Item );
ASSERT(pInfo->hwndEb);
pInfo->hwndLb = GetDlgItem( hwndDlg, CID_LE_LB_List );
ASSERT(pInfo->hwndLb);
if (pArgs->pDestroyId)
{
/* Create the empty list of deletions.
*/
pInfo->pListDeletes = DtlCreateList( 0L );
if (!pInfo->pListDeletes)
{
ErrorDlg( hwndDlg, SID_OP_LoadDlg, ERROR_NOT_ENOUGH_MEMORY, NULL );
EndDialog( hwndDlg, FALSE );
return TRUE;
}
}
if (!pInfo->fSorted)
{
pInfo->hwndPbUp = GetDlgItem( hwndDlg, CID_LE_PB_Up );
ASSERT(pInfo->hwndPbUp);
pInfo->hwndPbDown = GetDlgItem( hwndDlg, CID_LE_PB_Down );
ASSERT(pInfo->hwndPbDown);
/* Draw the graphical up and down arrow indicators.
*/
pInfo->hbmUp = Button_CreateBitmap(
pInfo->hwndPbUp, BMS_UpArrowOnRight );
if (pInfo->hbmUp)
{
SendMessage( pInfo->hwndPbUp, BM_SETIMAGE, 0,
(LPARAM )pInfo->hbmUp );
}
pInfo->hbmDown = Button_CreateBitmap(
pInfo->hwndPbDown, BMS_DownArrowOnRight );
if (pInfo->hbmDown)
{
SendMessage( pInfo->hwndPbDown, BM_SETIMAGE, 0,
(LPARAM )pInfo->hbmDown );
}
}
if (pArgs->pfCheck)
{
pInfo->hwndCb = GetDlgItem( hwndDlg, CID_LE_CB_Promote );
ASSERT(pInfo->hwndCb);
SetWindowText( pInfo->hwndCb, pArgs->pszCheckLabel );
Button_SetCheck( pInfo->hwndCb, *pArgs->pfCheck );
}
Edit_LimitText( pInfo->hwndEb, pArgs->dwMaxItemLen );
/* Set caller-defined dialog title and labels.
*/
SetWindowText( pInfo->hwndDlg, pArgs->pszTitle );
SetWindowText( pInfo->hwndStItem, pArgs->pszItemLabel );
SetWindowText( pInfo->hwndStList, pArgs->pszListLabel );
/* Fill the listbox.
*/
for (pNode = DtlGetFirstNode( pArgs->pList );
pNode;
pNode = DtlGetNextNode( pNode ))
{
TCHAR* psz = (TCHAR* )DtlGetData( pNode );
ASSERT(psz);
ListBox_AddItem( pInfo->hwndLb, psz, (VOID* )UlongToPtr(DtlGetNodeId( pNode ) ));
}
c = ListBox_GetCount( pInfo->hwndLb );
if (c > 0)
{
/* Select item selected by caller.
*/
ListBox_SetCurSelNotify( pInfo->hwndLb, pArgs->iSelInitial );
LeEnableUpAndDownButtons( pInfo );
if (c == 1 && pInfo->fNoDeleteLast)
EnableWindow( pInfo->hwndPbDelete, FALSE );
}
else
{
/* Empty list.
*/
if (!pInfo->fSorted)
{
EnableWindow( pInfo->hwndPbUp, FALSE );
EnableWindow( pInfo->hwndPbDown, FALSE );
}
EnableWindow( pInfo->hwndPbDelete, FALSE );
}
/* Set default edit box contents, if any.
*/
if (pArgs->pszDefaultItem)
{
SetWindowText( pInfo->hwndEb, pArgs->pszDefaultItem );
Edit_SetSel( pInfo->hwndEb, 0, -1 );
}
else
{
EnableWindow( pInfo->hwndPbAdd, FALSE );
EnableWindow( pInfo->hwndPbReplace, FALSE );
}
/* Center dialog on the owner window.
*/
CenterWindow( hwndDlg, GetParent( hwndDlg ) );
/* Add context help button to title bar. Dlgedit.exe doesn't currently
** support this at resource edit time. When that's fixed set
** DS_CONTEXTHELP there and remove this call.
*/
AddContextHelpButton( hwndDlg );
return TRUE;
}
VOID
LeItemTextFromListSelection(
IN LEINFO* pInfo )
/* Copies the currently selected item in the list to the edit box.
** 'PInfo' is the dialog context.
*/
{
TCHAR* psz;
INT iSel;
iSel = ListBox_GetCurSel( pInfo->hwndLb );
if (iSel >= 0)
{
psz = ListBox_GetPsz( pInfo->hwndLb, iSel );
if (psz)
{
SetWindowText( pInfo->hwndEb, psz );
Free( psz );
return;
}
}
SetWindowText( pInfo->hwndEb, TEXT("") );
}
VOID
LeReplace(
IN LEINFO* pInfo )
/* Replace button click handler. 'PInfo' is the dialog context.
*/
{
TCHAR* psz;
INT i;
INT_PTR lId;
psz = GetText( pInfo->hwndEb );
if (!psz)
{
LeExitNoMemory( pInfo );
return;
}
if (pInfo->pArgs->dwfFlags & LEDFLAG_Unique)
{
if (ListBox_IndexFromString( pInfo->hwndLb, psz ) >= 0)
{
MSGARGS msgargs;
ZeroMemory( &msgargs, sizeof(msgargs) );
msgargs.apszArgs[ 0 ] = psz;
MsgDlg( pInfo->hwndDlg, SID_NotUnique, &msgargs );
Edit_SetSel( pInfo->hwndEb, 0, -1 );
SetFocus( pInfo->hwndEb );
Free( psz );
return;
}
}
i = ListBox_GetCurSel( pInfo->hwndLb );
lId = ListBox_GetItemData( pInfo->hwndLb, i );
ListBox_DeleteString( pInfo->hwndLb, i );
if (pInfo->fSorted)
{
i = ListBox_AddItem( pInfo->hwndLb, psz, (VOID* )lId );
}
else
{
ListBox_InsertString( pInfo->hwndLb, i, psz );
ListBox_SetItemData( pInfo->hwndLb, i, lId );
}
Free( psz );
ListBox_SetCurSel( pInfo->hwndLb, i );
SetFocus( pInfo->hwndEb );
SetWindowText( pInfo->hwndEb, TEXT("") );
}
BOOL
LeSaveSettings(
IN LEINFO* pInfo )
/* Saves dialog settings in the stub API caller's list. 'PInfo' is the
** dialog context.
**
** Returns true if successful, false if does not validate.
*/
{
DWORD dwErr;
DTLNODE* pNode;
DTLLIST* pList;
DTLLIST* pListNew;
TCHAR* psz;
INT_PTR lId;
INT c;
INT i;
/* Make new list from list box contents.
*/
do
{
pListNew = DtlCreateList( 0L );
if (!pListNew)
{
dwErr = ERROR_NOT_ENOUGH_MEMORY;
break;
}
dwErr = 0;
c = ListBox_GetCount( pInfo->hwndLb );
for (i = 0; i < c; ++i)
{
psz = ListBox_GetPsz( pInfo->hwndLb, i );
if (!psz)
{
dwErr = ERROR_NOT_ENOUGH_MEMORY;
break;
}
lId = ListBox_GetItemData( pInfo->hwndLb, i );
ASSERT(lId>=0);
pNode = DtlCreateNode( psz, (DWORD)lId );
if (!pNode)
{
Free( psz );
dwErr = ERROR_NOT_ENOUGH_MEMORY;
break;
}
DtlAddNodeLast( pListNew, pNode );
}
}
while (FALSE);
if (dwErr != 0)
{
ErrorDlg( pInfo->hwndDlg, SID_OP_DisplayData, dwErr, NULL );
DtlDestroyList( pListNew, DestroyPszNode );
return FALSE;
}
/* Free all data in the old list.
*/
while (pNode = DtlGetFirstNode( pInfo->pArgs->pList ))
{
Free( (TCHAR* )DtlGetData( pNode ) );
DtlDeleteNode( pInfo->pArgs->pList, pNode );
}
/* Free the node-IDs in the list of deletions.
*/
if (pInfo->pListDeletes)
{
while (pNode = DtlGetFirstNode( pInfo->pListDeletes ))
{
pInfo->pArgs->pDestroyId( (DTLNODE* )UlongToPtr(DtlGetNodeId( pNode ) ));
DtlDeleteNode( pInfo->pListDeletes, pNode );
}
}
/* Move the new list onto caller's list.
*/
while (pNode = DtlGetFirstNode( pListNew ))
{
DtlRemoveNode( pListNew, pNode );
DtlAddNodeLast( pInfo->pArgs->pList, pNode );
}
DtlDestroyList( pListNew, DestroyPszNode );
/* Tell caller what the checkbox setting is.
*/
if (pInfo->pArgs->pfCheck)
*pInfo->pArgs->pfCheck = Button_GetCheck( pInfo->hwndCb );
return TRUE;
}
VOID
LeTerm(
IN HWND hwndDlg )
/* Called on WM_DESTROY. 'HwndDlg' is that handle of the dialog window.
*/
{
LEINFO* pInfo = (LEINFO* )GetWindowLongPtr( hwndDlg, DWLP_USER );
TRACE("LeTerm");
if (pInfo)
{
if (pInfo->hbmUp)
DeleteObject( pInfo->hbmUp );
if (pInfo->hbmDown)
DeleteObject( pInfo->hbmDown );
DtlDestroyList( pInfo->pListDeletes, NULL );
Free( pInfo );
}
}
VOID
LeUp(
IN LEINFO* pInfo )
/* Up button click handler. 'PInfo' is the dialog context.
*/
{
TCHAR* psz;
INT i;
LONG_PTR lId;
ASSERT(!pInfo->fSorted);
i = ListBox_GetCurSel( pInfo->hwndLb );
psz = ListBox_GetPsz( pInfo->hwndLb, i );
if (!psz)
{
LeExitNoMemory( pInfo );
return;
}
ListBox_InsertString( pInfo->hwndLb, i - 1, psz );
Free( psz );
lId = ListBox_GetItemData( pInfo->hwndLb, i + 1 );
ListBox_DeleteString( pInfo->hwndLb, i + 1 );
ListBox_SetItemData( pInfo->hwndLb, i - 1, lId );
ListBox_SetCurSel( pInfo->hwndLb, i - 1 );
if (i == 1)
{
Button_MakeDefault( pInfo->hwndDlg, pInfo->hwndPbDown );
SetFocus( pInfo->hwndPbDown );
}
LeEnableUpAndDownButtons( pInfo );
}
/*----------------------------------------------------------------------------
** String Editor dialog entry point
**----------------------------------------------------------------------------
*/
BOOL
StringEditorDlg(
IN HWND hwndOwner,
IN TCHAR* pszIn,
IN DWORD dwSidTitle,
IN DWORD dwSidLabel,
IN DWORD cbMax,
IN DWORD dwHelpId,
IN OUT TCHAR** ppszOut )
/* Pops-up the String Editor dialog. 'PszIn' is the initial setting of
** the edit box or NULL for blank. 'DwSidTitle' and 'dwSidLabel' are the
** string resource IDs of the dialog title and edit box label. 'CbMax' is
** the maximum length of the to allow or 0 for no limit. 'DwHelpId' is
** the HID_* constant to associate with the label and edit field or -1 if
** none.
**
** Returns true if user pressed OK and succeeded, false if he pressed
** Cancel or encountered an error. If true, '*ppszNumber' is a heap block
** with the edited result. It is caller's responsibility to Free the
** returned block.
*/
{
int nStatus;
ZEARGS args;
TRACE("StringEditorDlg");
args.pszIn = pszIn;
args.dwSidTitle = dwSidTitle;
args.dwSidLabel = dwSidLabel;
args.cbMax = cbMax;
args.dwHelpId = dwHelpId;
args.ppszOut = ppszOut;
nStatus =
(BOOL )DialogBoxParam(
g_hinstDll,
MAKEINTRESOURCE( DID_ZE_StringEditor ),
hwndOwner,
ZeDlgProc,
(LPARAM )&args );
if (nStatus == -1)
{
ErrorDlg( hwndOwner, SID_OP_LoadDlg, ERROR_UNKNOWN, NULL );
nStatus = FALSE;
}
return (BOOL )nStatus;
}
/*----------------------------------------------------------------------------
** String Editor dialog routines
** Listed alphabetically following dialog proc
**----------------------------------------------------------------------------
*/
INT_PTR CALLBACK
ZeDlgProc(
IN HWND hwnd,
IN UINT unMsg,
IN WPARAM wparam,
IN LPARAM lparam )
/* DialogProc callback for the Edit Phone Number dialog. Parameters and
** return value are as described for standard windows 'DialogProc's.
FastRight:right */
{
#if 0
TRACE4("ZeDlgProc(h=$%x,m=$%x,w=$%x,l=$%x)",
(DWORD)hwnd,(DWORD)unMsg,(DWORD)wparam,(DWORD)lparam);
#endif
switch (unMsg)
{
case WM_INITDIALOG:
return ZeInit( hwnd, (ZEARGS* )lparam );
case WM_HELP:
case WM_CONTEXTMENU:
{
ZEINFO* pInfo;
pInfo = (ZEINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
if (pInfo && pInfo->pArgs->dwHelpId != (DWORD )-1)
{
DWORD adwZeHelp[ (2 + 1) * 2 ];
ZeroMemory( adwZeHelp, sizeof(adwZeHelp) );
adwZeHelp[ 0 ] = CID_ZE_ST_String;
adwZeHelp[ 2 ] = CID_ZE_EB_String;
adwZeHelp[ 1 ] = adwZeHelp[ 3 ] = pInfo->pArgs->dwHelpId;
ContextHelp( adwZeHelp, hwnd, unMsg, wparam, lparam );
break;
}
}
case WM_COMMAND:
{
ZEINFO* pInfo = (ZEINFO* )GetWindowLongPtr( hwnd, DWLP_USER );
ASSERT(pInfo);
return ZeCommand(
pInfo, HIWORD( wparam ), LOWORD( wparam ), (HWND )lparam );
}
case WM_DESTROY:
{
ZeTerm( hwnd );
break;
}
}
return FALSE;
}
BOOL
ZeCommand(
IN ZEINFO* pInfo,
IN WORD wNotification,
IN WORD wId,
IN HWND hwndCtrl )
/* Called on WM_COMMAND. 'PInfo' is the dialog context. 'WNotification'
** is the notification code of the command. 'wId' is the control/menu
** identifier of the command. 'HwndCtrl' is the control window handle of
** the command.
**
** Returns true if processed message, false otherwise.
*/
{
TRACE2("ZeCommand(n=%d,i=%d)",
(DWORD)wNotification,(DWORD)wId);
switch (wId)
{
case IDOK:
{
TRACE("OK pressed");
*pInfo->pArgs->ppszOut = GetText( pInfo->hwndEb );
EndDialog( pInfo->hwndDlg, (*pInfo->pArgs->ppszOut != NULL) );
return TRUE;
}
case IDCANCEL:
{
TRACE("Cancel pressed");
EndDialog( pInfo->hwndDlg, FALSE );
return TRUE;
}
}
return FALSE;
}
BOOL
ZeInit(
IN HWND hwndDlg,
IN ZEARGS* pArgs )
/* Called on WM_INITDIALOG. 'hwndDlg' is the handle of the owning window.
** 'PArgs' is caller's arguments as passed to the stub API.
**
** Return false if focus was set, true otherwise, i.e. as defined for
** WM_INITDIALOG.
*/
{
DWORD dwErr;
TCHAR* psz;
ZEINFO* pInfo;
TRACE("ZeInit");
/* Allocate the dialog context block. Initialize minimally for proper
** cleanup, then attach to the dialog window.
*/
{
pInfo = Malloc( sizeof(*pInfo) );
if (!pInfo)
{
ErrorDlg( hwndDlg, SID_OP_LoadDlg, ERROR_NOT_ENOUGH_MEMORY, NULL );
EndDialog( hwndDlg, FALSE );
return TRUE;
}
ZeroMemory( pInfo, sizeof(*pInfo) );
pInfo->pArgs = pArgs;
pInfo->hwndDlg = hwndDlg;
SetWindowLongPtr( hwndDlg, DWLP_USER, (LONG_PTR)pInfo );
TRACE("Context set");
}
pInfo->hwndEb = GetDlgItem( hwndDlg, CID_ZE_EB_String );
ASSERT(pInfo->hwndEb);
if (pArgs->cbMax > 0)
Edit_LimitText( pInfo->hwndEb, pArgs->cbMax );
psz = PszFromId( g_hinstDll, pArgs->dwSidTitle );
if (psz)
{
SetWindowText( hwndDlg, psz );
Free( psz );
}
psz = PszFromId( g_hinstDll, pArgs->dwSidLabel );
if (psz)
{
HWND hwndSt = GetDlgItem( hwndDlg, CID_ZE_ST_String );
ASSERT(hwndSt);
SetWindowText( hwndSt, psz );
Free( psz );
}
if (pArgs->pszIn)
{
SetWindowText( pInfo->hwndEb, pArgs->pszIn );
Edit_SetSel( pInfo->hwndEb, 0, -1 );
}
/* Center dialog on the owner window.
*/
CenterWindow( hwndDlg, GetParent( hwndDlg ) );
/* Add context help button to title bar. Dlgedit.exe doesn't currently
** support this at resource edit time. When that's fixed set
** DS_CONTEXTHELP there and remove this call.
*/
AddContextHelpButton( hwndDlg );
return TRUE;
}
VOID
ZeTerm(
IN HWND hwndDlg )
/* Called on WM_DESTROY. 'HwndDlg' is that handle of the dialog window.
*/
{
ZEINFO* pInfo = (ZEINFO* )GetWindowLongPtr( hwndDlg, DWLP_USER );
TRACE("ZeTerm");
if (pInfo)
Free( pInfo );
}