windows-nt/Source/XPSP1/NT/admin/snapin/dfsadmin/dfsgui/mvedit.cpp
2020-09-26 16:20:57 +08:00

401 lines
9.2 KiB
C++

/*++
Module Name:
mvEdit.cpp
Abstract:
This module contains the declaration of the CMultiValuedStringEdit.
This class displays the dialog to edit multi-valued string.
*/
#include "stdafx.h"
#include "mvEdit.h"
#include "utils.h"
#include "dfshelp.h"
/////////////////////////////////////////////////////////////////////////////
// CMultiValuedStringEdit
CMultiValuedStringEdit::CMultiValuedStringEdit(int nDlgTitle, int nText, UINT uiStringLengthLimit) :
m_nDlgTitle(nDlgTitle),
m_nText(nText)
{
m_uiStringLengthLimit = ((0 == uiStringLengthLimit) ? MAX_PATH : uiStringLengthLimit);
}
CMultiValuedStringEdit::~CMultiValuedStringEdit()
{
}
HRESULT CMultiValuedStringEdit::put_Strings(
IN BSTR i_bstrValues,
IN BSTR i_bstrSeparators
)
{
if (!i_bstrSeparators || 1 != lstrlen(i_bstrSeparators))
return E_INVALIDARG;
m_bstrValues.Empty();
if (i_bstrValues)
{
m_bstrValues = i_bstrValues;
RETURN_OUTOFMEMORY_IF_NULL((BSTR)m_bstrValues);
}
m_bstrSeparators = i_bstrSeparators;
RETURN_OUTOFMEMORY_IF_NULL((BSTR)m_bstrSeparators);
if ((BSTR)m_bstrValues)
_tcslwr((BSTR)m_bstrValues);
_tcslwr((BSTR)m_bstrSeparators);
return S_OK;
}
HRESULT CMultiValuedStringEdit::get_Strings
(
BSTR *o_pbstrValues
)
{
RETURN_INVALIDARG_IF_NULL(o_pbstrValues);
*o_pbstrValues = NULL;
if ((BSTR)m_bstrValues)
GET_BSTR(m_bstrValues, o_pbstrValues);
}
LRESULT CMultiValuedStringEdit::OnInitDialog
(
UINT uMsg,
WPARAM wParam,
LPARAM lParam,
BOOL& bHandled
)
{
HWND hwnd = GetDlgItem(IDC_MVSTRINGEDIT_LIST);
RECT rect = {0};
::GetWindowRect(hwnd, &rect);
int nControlWidth = rect.right - rect.left;
int nVScrollbarWidth = GetSystemMetrics(SM_CXVSCROLL);
int nBorderWidth = GetSystemMetrics(SM_CXBORDER);
int nControlNetWidth = nControlWidth - 4 * nBorderWidth;
LVCOLUMN lvColumn = {0};
lvColumn.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_WIDTH;
lvColumn.fmt = LVCFMT_LEFT;
lvColumn.iSubItem = 0;
lvColumn.cx = nControlNetWidth;
ListView_InsertColumn(hwnd, 0, &lvColumn);
::EnableWindow(GetDlgItem(IDC_MVSTRINGEDIT_ADD), FALSE);
::EnableWindow(GetDlgItem(IDC_MVSTRINGEDIT_REMOVE), FALSE);
if (m_nDlgTitle)
{
CComBSTR bstrTitle;
LoadStringFromResource(m_nDlgTitle, &bstrTitle);
SetWindowText(bstrTitle);
}
if (m_nText)
{
CComBSTR bstrText;
LoadStringFromResource(m_nText, &bstrText);
SetDlgItemText(IDC_MVSTRINGEDIT_TEXT, bstrText);
}
SendDlgItemMessage(IDC_MVSTRINGEDIT_STRING, EM_LIMITTEXT, m_uiStringLengthLimit, 0);
if (!m_bstrValues || !*m_bstrValues)
return TRUE;
CComBSTR bstrToken;
int index = 0;
HRESULT hr = mystrtok(m_bstrValues, &index, m_bstrSeparators, &bstrToken);
while (SUCCEEDED(hr) && (BSTR)bstrToken)
{
_tcslwr((BSTR)bstrToken);
LVITEM lvItem = {0};
lvItem.mask = LVIF_TEXT;
lvItem.pszText = bstrToken;
ListView_InsertItem(hwnd, &lvItem);
bstrToken.Empty();
hr = mystrtok(m_bstrValues, &index, m_bstrSeparators, &bstrToken);;
}
return TRUE; // Let the system set the focus
}
/*++
This function is called when a user clicks the ? in the top right of a property sheet
and then clciks a control, or when they hit F1 in a control.
--*/
LRESULT CMultiValuedStringEdit::OnCtxHelp(
IN UINT i_uMsg,
IN WPARAM i_wParam,
IN LPARAM i_lParam,
IN OUT BOOL& io_bHandled
)
{
LPHELPINFO lphi = (LPHELPINFO) i_lParam;
if (!lphi || lphi->iContextType != HELPINFO_WINDOW || lphi->iCtrlId < 0)
return FALSE;
::WinHelp((HWND)(lphi->hItemHandle),
DFS_CTX_HELP_FILE,
HELP_WM_HELP,
(DWORD_PTR)(PVOID)g_aHelpIDs_IDD_MVSTRINGEDIT);
return TRUE;
}
/*++
This function handles "What's This" help when a user right clicks the control
--*/
LRESULT CMultiValuedStringEdit::OnCtxMenuHelp(
IN UINT i_uMsg,
IN WPARAM i_wParam,
IN LPARAM i_lParam,
IN OUT BOOL& io_bHandled
)
{
::WinHelp((HWND)i_wParam,
DFS_CTX_HELP_FILE,
HELP_CONTEXTMENU,
(DWORD_PTR)(PVOID)g_aHelpIDs_IDD_MVSTRINGEDIT);
return TRUE;
}
LRESULT CMultiValuedStringEdit::OnString
(
WORD wNotifyCode,
WORD wID,
HWND hWndCtl,
BOOL& bHandled
)
{
::EnableWindow(GetDlgItem(IDC_MVSTRINGEDIT_ADD),
(0 < ::GetWindowTextLength(GetDlgItem(IDC_MVSTRINGEDIT_STRING))));
return TRUE;
}
LRESULT CMultiValuedStringEdit::OnNotify
(
IN UINT i_uMsg,
IN WPARAM i_wParam,
IN LPARAM i_lParam,
IN OUT BOOL& io_bHandled
)
{
NMHDR* pNMHDR = (NMHDR*)i_lParam;
if (IDC_MVSTRINGEDIT_LIST == pNMHDR->idFrom)
{
if (LVN_ITEMCHANGED == pNMHDR->code)
{
int nCount = ListView_GetSelectedCount(GetDlgItem(IDC_MVSTRINGEDIT_LIST));
::EnableWindow(GetDlgItem(IDC_MVSTRINGEDIT_REMOVE), (nCount >= 1));
}
}
return FALSE;
}
LRESULT CMultiValuedStringEdit::OnAdd
(
WORD wNotifyCode,
WORD wID,
HWND hWndCtl,
BOOL& bHandled
)
{
CComBSTR bstr;
DWORD dwTextLength = 0;
HRESULT hr = GetInputText(GetDlgItem(IDC_MVSTRINGEDIT_STRING), &bstr, &dwTextLength);
if (FAILED(hr))
{
DisplayMessageBoxForHR(hr);
} else if (0 < dwTextLength)
{
_tcslwr((BSTR)bstr);
if (!_tcschr(bstr, *m_bstrSeparators))
{
LVFINDINFO lvInfo = {0};
lvInfo.flags = LVFI_STRING;
lvInfo.psz = bstr;
HWND hwnd = GetDlgItem(IDC_MVSTRINGEDIT_LIST);
if (-1 == ListView_FindItem(hwnd, -1, &lvInfo))
{
LVITEM lvItem = {0};
lvItem.mask = LVIF_TEXT;
lvItem.pszText = bstr;
ListView_InsertItem(hwnd, &lvItem);
}
SetDlgItemText(IDC_MVSTRINGEDIT_STRING, _T(""));
} else
{
DisplayMessageBox(hWndCtl, MB_OK, 0, IDS_MVSTRINGEDIT_STRING_INVALID, m_bstrSeparators);
}
}
::SetFocus(GetDlgItem(IDC_MVSTRINGEDIT_STRING));
return TRUE;
}
LRESULT CMultiValuedStringEdit::OnRemove
(
WORD wNotifyCode,
WORD wID,
HWND hWndCtl,
BOOL& bHandled
)
{
HWND hwnd = GetDlgItem(IDC_MVSTRINGEDIT_LIST);
int nIndex = -1;
while (-1 != (nIndex = ListView_GetNextItem(hwnd, -1, LVNI_SELECTED)))
ListView_DeleteItem(hwnd, nIndex);
return TRUE;
}
LRESULT CMultiValuedStringEdit::OnOK
(
WORD wNotifyCode,
WORD wID,
HWND hWndCtl,
BOOL& bHandled
)
{
m_bstrValues.Empty();
HRESULT hr = S_OK;
HWND hwnd = GetDlgItem(IDC_MVSTRINGEDIT_LIST);
if (0 < ListView_GetItemCount(hwnd))
{
PTSTR pszText = (PTSTR)calloc(m_uiStringLengthLimit+1, sizeof(TCHAR));
if (pszText)
{
int nIndex = -1;
while (-1 != (nIndex = ListView_GetNextItem(hwnd, nIndex, LVNI_ALL)))
{
ListView_GetItemText(hwnd, nIndex, 0, pszText, m_uiStringLengthLimit+1);
if (!m_bstrValues || !*m_bstrValues)
{
m_bstrValues = pszText;
BREAK_OUTOFMEMORY_IF_NULL((BSTR)m_bstrValues, &hr);
} else
{
m_bstrValues += m_bstrSeparators;
BREAK_OUTOFMEMORY_IF_NULL((BSTR)m_bstrValues, &hr);
m_bstrValues += pszText;
BREAK_OUTOFMEMORY_IF_NULL((BSTR)m_bstrValues, &hr);
}
}
free(pszText);
} else
{
hr = E_OUTOFMEMORY;
}
}
if (FAILED(hr))
{
DisplayMessageBoxForHR(hr);
::SetFocus(GetDlgItem(IDC_MVSTRINGEDIT_STRING));
return FALSE;
}
EndDialog(S_OK);
return TRUE;
}
LRESULT CMultiValuedStringEdit::OnCancel
(
WORD wNotifyCode,
WORD wID,
HWND hWndCtl,
BOOL& bHandled
)
{
/*++
Routine Description:
Called OnCancel. Ends the dialog with S_FALSE;
*/
EndDialog(S_FALSE);
return TRUE;
}
//
// Invoke the dialog.
//
// S_OK: io_pbstr contains the new string
// S_FALSE: dlg cancelled, or string unchanged
// others: error occurred and reported
//
HRESULT InvokeMultiValuedStringEditDlg(
IN BSTR* io_pbstr,
IN BSTR i_bstrSeparators,
IN int i_nDlgTitle,
IN int i_nText,
IN UINT i_uiStringLengthLimit
)
{
HRESULT hr = S_OK;
CMultiValuedStringEdit editDlg(i_nDlgTitle, i_nText, i_uiStringLengthLimit);
do {
if (!io_pbstr)
{
hr = E_INVALIDARG;
break;
}
hr = editDlg.put_Strings(*io_pbstr, i_bstrSeparators);
BREAK_IF_FAILED(hr);
if (S_OK == editDlg.DoModal())
{
CComBSTR bstr;
hr = editDlg.get_Strings(&bstr);
BREAK_IF_FAILED(hr);
if (!*io_pbstr && (BSTR)bstr ||
*io_pbstr && !bstr ||
0 != lstrcmpi(*io_pbstr, bstr))
{
SysFreeString(*io_pbstr);
*io_pbstr = bstr.Detach();
hr = S_OK;
} else
{
hr = S_FALSE; // string unchanged
}
}
} while (0);
if (FAILED(hr))
DisplayMessageBoxForHR(hr);
return hr;
}