
エディットコントロールに入力したくない文字を設定するときは、Windows2000以降に備わっているSHLimitInputEditを利用すると簡単に実装できる。
この関数はエクスプローラなどでファイル名をユーザーに入力させるときの注意用に作られたもので、図のようなバルーンで入力禁止文字が表示される。このとき表示される「ファイル名に次の文字は使えません:」という文字列は変更することができない(少なくとも私はその方法を知らない)。そのため簡単に入力禁止文字の設定はできるが使用範囲が限られてしまうのが残念な点だ。
実装ではIShellFolderとIItemNameLimitsを備えたCOMインターフェースを作成し、それを引数としてSHLimitInputEditに渡せばいい。
ここでは以下のようにプロジェクトを作成した。
1.WTLのアプリケーションウイザードでダイアログアプリケーションを作成
2.リソースエディタでエディットコントロールを追加(コントロールIDはIDC_EDIT1)
3.MainDlg.hにCOMインターフェースを追加
4.MainDlg.hのOnInitDialog内でSHLimitInputEditを実行
依存環境:ATL/WTL
MIDL_INTERFACE("28997A04-63A4-421d-BF58-154F7BD82E8A")
IDnpEditChars : public IUnknown
{
public:
};
class ATL_NO_VTABLE CDnpEditChars :
public CComObjectRootEx<CComSingleThreadModel>,
public IShellFolder,
public IItemNameLimits,
public IDnpEditChars
{
public:
CDnpEditChars()
{
}
BEGIN_COM_MAP(CDnpEditChars)
COM_INTERFACE_ENTRY(IDnpEditChars)
COM_INTERFACE_ENTRY(IShellFolder)
COM_INTERFACE_ENTRY(IItemNameLimits)
END_COM_MAP()
DECLARE_PROTECT_FINAL_CONSTRUCT()
//IItemNameLimits
STDMETHOD(GetMaxLength)(LPCWSTR pszName,int *piMaxNameLen)
{
return E_NOTIMPL;
}
STDMETHOD(GetValidCharacters)(LPWSTR *ppwszValidChars,LPWSTR *ppwszInvalidChars)
{
//「?」と「*」を入力不可能な文字にする
*ppwszValidChars = NULL;
*ppwszInvalidChars = (WCHAR*)::CoTaskMemAlloc(sizeof(WCHAR) * 20);
if(*ppwszInvalidChars == NULL)
return E_FAIL;
::wcscpy_s(*ppwszInvalidChars,20,L"?*");
return S_OK;
}
//IShellFolder
STDMETHOD(BindToObject)(LPCITEMIDLIST pidl,LPBC pbc,REFIID riid,VOID **ppvOut)
{
return E_NOTIMPL;
}
STDMETHOD(BindToStorage)(LPCITEMIDLIST pidl,LPBC pbc,REFIID riid,VOID **ppvOut)
{
return E_NOTIMPL;
}
STDMETHOD(CompareIDs)(LPARAM lParam,LPCITEMIDLIST pidl1,LPCITEMIDLIST pidl2)
{
return E_NOTIMPL;
}
STDMETHOD(CreateViewObject)(HWND hwndOwner,REFIID riid,VOID **ppvOut)
{
return E_NOTIMPL;
}
STDMETHOD(EnumObjects)(HWND hwndOwner,SHCONTF grfFlags,IEnumIDList **ppenumIDList)
{
return E_NOTIMPL;
}
STDMETHOD(GetAttributesOf)(UINT cidl,LPCITEMIDLIST *apidl,SFGAOF *rgfInOut)
{
return E_NOTIMPL;
}
STDMETHOD(GetDisplayNameOf)(LPCITEMIDLIST pidl,DWORD uFlags,LPSTRRET lpName)
{
return E_NOTIMPL;
}
STDMETHOD(GetUIObjectOf)(HWND hwndOwner,UINT cidl,LPCITEMIDLIST *apidl,REFIID riid,UINT *rgfReserved,VOID **ppv)
{
return E_NOTIMPL;
}
STDMETHOD(ParseDisplayName)(HWND hwnd,LPBC pbc,LPOLESTR pwszDisplayName,ULONG *pchEaten,LPITEMIDLIST *ppidl,ULONG *pdwAttributes)
{
return E_NOTIMPL;
}
STDMETHOD(SetNameOf)(HWND hwndOwner,LPCITEMIDLIST pidl,LPCOLESTR lpszName,DWORD uFlags,LPITEMIDLIST *ppidlOut)
{
return E_NOTIMPL;
}
};
■MainDlg.hのOnInitDialog()内に追加
HRESULT hr;
CComPtr<IDnpEditChars> pIDnpEditChars;
pIDnpEditChars = new CComObject<CDnpEditChars>;
hr = ::SHLimitInputEdit(GetDlgItem(IDC_EDIT1).m_hWnd,(IShellFolder*)(IDnpEditChars*)pIDnpEditChars);
if(FAILED(hr))
MessageBox(_T("設定に失敗しました"));
