エディットコントロールの入力禁止文字を設定する

test67.gif
エディットコントロールに入力したくない文字を設定するときは、Windows2000以降に備わっているSHLimitInputEditを利用すると簡単に実装できる。
この関数はエクスプローラなどでファイル名をユーザーに入力させるときの注意用に作られたもので、図のようなバルーンで入力禁止文字が表示される。このとき表示される「ファイル名に次の文字は使えません:」という文字列は変更することができない(少なくとも私はその方法を知らない)。そのため簡単に入力禁止文字の設定はできるが使用範囲が限られてしまうのが残念な点だ。

実装ではIShellFolderとIItemNameLimitsを備えたCOMインターフェースを作成し、それを引数としてSHLimitInputEditに渡せばいい。

ここでは以下のようにプロジェクトを作成した。

1.WTLのアプリケーションウイザードでダイアログアプリケーションを作成
2.リソースエディタでエディットコントロールを追加(コントロールIDはIDC_EDIT1)
3.MainDlg.hにCOMインターフェースを追加
4.MainDlg.hのOnInitDialog内でSHLimitInputEditを実行


依存環境:ATL/WTL

■MainDlg.hのダイアログ定義の前に追加
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 * sizeof(WCHAR),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("設定に失敗しました"));

プロジェクトファイルをダウンロード


カテゴリー「コントロール」 のエントリー