1 /*
2 * PROJECT: ReactOS api tests
3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
4 * PURPOSE: Test for SHLimitInputEdit
5 * PROGRAMMER: Katayama Hirofumi MZ
6 */
7
8 #include "shelltest.h"
9 #include <shobjidl.h>
10 #include <shlwapi.h>
11
12 class CShellFolder
13 : public IShellFolder
14 , public IItemNameLimits
15 {
16 public:
17 LONG m_cRefs;
18
CShellFolder(INT iMaxNameLen=0,BOOL bDisabled=FALSE)19 CShellFolder(INT iMaxNameLen = 0, BOOL bDisabled = FALSE)
20 : m_cRefs(1)
21 , m_iMaxNameLen(iMaxNameLen)
22 , m_bDisabled(bDisabled)
23 {
24 trace("CShellFolder\n");
25 }
26
~CShellFolder()27 virtual ~CShellFolder()
28 {
29 trace("~CShellFolder\n");
30 }
31
32 /*** IUnknown methods ***/
33
34 STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject);
35 STDMETHODIMP_(ULONG) AddRef();
36 STDMETHODIMP_(ULONG) Release();
37
38 /*** IShellFolder methods ***/
39
ParseDisplayName(HWND hwnd,IBindCtx * pbc,LPWSTR pszDisplayName,ULONG * pchEaten,PIDLIST_RELATIVE * ppidl,ULONG * pdwAttributes)40 STDMETHODIMP ParseDisplayName(
41 HWND hwnd,
42 IBindCtx *pbc,
43 LPWSTR pszDisplayName,
44 ULONG *pchEaten,
45 PIDLIST_RELATIVE *ppidl,
46 ULONG *pdwAttributes)
47 {
48 trace("ParseDisplayName\n");
49 return E_NOTIMPL;
50 }
51
EnumObjects(HWND hwnd,SHCONTF grfFlags,IEnumIDList ** ppenumIDList)52 STDMETHODIMP EnumObjects(
53 HWND hwnd,
54 SHCONTF grfFlags,
55 IEnumIDList **ppenumIDList)
56 {
57 trace("EnumObjects\n");
58 return E_NOTIMPL;
59 }
60
BindToObject(PCUIDLIST_RELATIVE pidl,IBindCtx * pbc,REFIID riid,void ** ppv)61 STDMETHODIMP BindToObject(
62 PCUIDLIST_RELATIVE pidl,
63 IBindCtx *pbc,
64 REFIID riid,
65 void **ppv)
66 {
67 trace("BindToObject\n");
68 return E_NOTIMPL;
69 }
70
BindToStorage(PCUIDLIST_RELATIVE pidl,IBindCtx * pbc,REFIID riid,void ** ppv)71 STDMETHODIMP BindToStorage(
72 PCUIDLIST_RELATIVE pidl,
73 IBindCtx *pbc,
74 REFIID riid,
75 void **ppv)
76 {
77 trace("BindToStorage\n");
78 return E_NOTIMPL;
79 }
80
CompareIDs(LPARAM lParam,PCUIDLIST_RELATIVE pidl1,PCUIDLIST_RELATIVE pidl2)81 STDMETHODIMP CompareIDs(
82 LPARAM lParam,
83 PCUIDLIST_RELATIVE pidl1,
84 PCUIDLIST_RELATIVE pidl2)
85 {
86 trace("CompareIDs\n");
87 return E_NOTIMPL;
88 }
89
CreateViewObject(HWND hwndOwner,REFIID riid,void ** ppv)90 STDMETHODIMP CreateViewObject(
91 HWND hwndOwner,
92 REFIID riid,
93 void **ppv)
94 {
95 trace("CreateViewObject\n");
96 return E_NOTIMPL;
97 }
98
GetAttributesOf(UINT cidl,PCUITEMID_CHILD_ARRAY apidl,SFGAOF * rgfInOut)99 STDMETHODIMP GetAttributesOf(
100 UINT cidl,
101 PCUITEMID_CHILD_ARRAY apidl,
102 SFGAOF *rgfInOut)
103 {
104 trace("GetAttributesOf\n");
105 return E_NOTIMPL;
106 }
107
GetUIObjectOf(HWND hwndOwner,UINT cidl,PCUITEMID_CHILD_ARRAY apidl,REFIID riid,UINT * rgfReserved,void ** ppv)108 STDMETHODIMP GetUIObjectOf(
109 HWND hwndOwner,
110 UINT cidl,
111 PCUITEMID_CHILD_ARRAY apidl,
112 REFIID riid,
113 UINT *rgfReserved,
114 void **ppv)
115 {
116 trace("GetUIObjectOf\n");
117 return E_NOTIMPL;
118 }
119
GetDisplayNameOf(PCUITEMID_CHILD pidl,SHGDNF uFlags,STRRET * pName)120 STDMETHODIMP GetDisplayNameOf(
121 PCUITEMID_CHILD pidl,
122 SHGDNF uFlags,
123 STRRET *pName)
124 {
125 trace("GetDisplayNameOf\n");
126 return E_NOTIMPL;
127 }
128
SetNameOf(HWND hwnd,PCUITEMID_CHILD pidl,LPCWSTR pszName,SHGDNF uFlags,PITEMID_CHILD * ppidlOut)129 STDMETHODIMP SetNameOf(
130 HWND hwnd,
131 PCUITEMID_CHILD pidl,
132 LPCWSTR pszName,
133 SHGDNF uFlags,
134 PITEMID_CHILD *ppidlOut)
135 {
136 trace("SetNameOf\n");
137 return E_NOTIMPL;
138 }
139
140 /*** IItemNameLimits methods ***/
141
142 STDMETHODIMP GetMaxLength(
143 LPCWSTR pszName,
144 int *piMaxNameLen);
145
146 STDMETHODIMP GetValidCharacters(
147 LPWSTR *ppwszValidChars,
148 LPWSTR *ppwszInvalidChars);
149
150 protected:
151 INT m_iMaxNameLen;
152 BOOL m_bDisabled;
153 };
154
QueryInterface(REFIID riid,void ** ppvObject)155 STDMETHODIMP CShellFolder::QueryInterface(REFIID riid, void **ppvObject)
156 {
157 trace("QueryInterface\n");
158
159 if (!ppvObject)
160 return E_POINTER;
161
162 if (IsEqualIID(riid, IID_IShellFolder) || IsEqualIID(riid, IID_IUnknown))
163 {
164 trace("IID_IShellFolder\n");
165 *ppvObject = static_cast<IShellFolder *>(this);
166 AddRef();
167 return S_OK;
168 }
169 if (IsEqualIID(riid, IID_IItemNameLimits))
170 {
171 trace("IID_IItemNameLimits\n");
172 *ppvObject = static_cast<IItemNameLimits *>(this);
173 AddRef();
174 return S_OK;
175 }
176
177 return E_NOINTERFACE;
178 }
179
STDMETHODIMP_(ULONG)180 STDMETHODIMP_(ULONG) CShellFolder::AddRef()
181 {
182 trace("AddRef\n");
183 return ++m_cRefs;
184 }
185
STDMETHODIMP_(ULONG)186 STDMETHODIMP_(ULONG) CShellFolder::Release()
187 {
188 trace("Release\n");
189
190 if (--m_cRefs == 0)
191 {
192 //delete this;
193 return 0;
194 }
195 return m_cRefs;
196 }
197
GetMaxLength(LPCWSTR pszName,int * piMaxNameLen)198 STDMETHODIMP CShellFolder::GetMaxLength(
199 LPCWSTR pszName,
200 int *piMaxNameLen)
201 {
202 trace("GetMaxLength('%S', %p (%d))\n", pszName, piMaxNameLen, *piMaxNameLen);
203
204 if (!piMaxNameLen)
205 return E_POINTER;
206
207 *piMaxNameLen = m_iMaxNameLen;
208 return S_OK;
209 }
210
GetValidCharacters(LPWSTR * ppwszValidChars,LPWSTR * ppwszInvalidChars)211 STDMETHODIMP CShellFolder::GetValidCharacters(
212 LPWSTR *ppwszValidChars,
213 LPWSTR *ppwszInvalidChars)
214 {
215 trace("GetValidCharacters(%p, %p)\n", ppwszValidChars, ppwszInvalidChars);
216
217 if (m_bDisabled)
218 return E_NOTIMPL;
219
220 if (ppwszInvalidChars)
221 {
222 SHStrDupW(L"/:*?\"<>|", ppwszInvalidChars);
223 }
224 if (ppwszValidChars)
225 {
226 *ppwszValidChars = NULL;
227 }
228 return S_OK;
229 }
230
231 static BOOL CALLBACK
PropEnumProc(HWND hwnd,LPCWSTR lpszString,HANDLE hData)232 PropEnumProc(
233 HWND hwnd,
234 LPCWSTR lpszString,
235 HANDLE hData)
236 {
237 trace("PropEnumProc: '%S' --> %p\n", lpszString, hData);
238 return TRUE;
239 }
240
241 static void
DoNullFolderTest(HWND hEdt1)242 DoNullFolderTest(HWND hEdt1)
243 {
244 HRESULT hr;
245
246 _SEH2_TRY
247 {
248 hr = SHLimitInputEdit(hEdt1, NULL);
249 }
250 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
251 {
252 hr = 0xDEAD;
253 }
254 _SEH2_END;
255
256 ok_int(hr, 0xDEAD);
257 }
258
259 static INT_PTR CALLBACK
DialogProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)260 DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
261 {
262 if (uMsg != WM_INITDIALOG)
263 return FALSE;
264
265 HWND hEdt1 = GetDlgItem(hwnd, edt1);
266 INT n;
267 HRESULT hr;
268 WCHAR szText[64];
269
270 DoNullFolderTest(hEdt1);
271
272 {
273 CShellFolder sf(123, FALSE);
274
275 ok_long(sf.m_cRefs, 1);
276
277 SendMessageW(hEdt1, EM_LIMITTEXT, 234, 0);
278
279 trace("GWLP_WNDPROC: %p\n", (void *)GetWindowLongPtr(hEdt1, GWLP_WNDPROC));
280
281 hr = SHLimitInputEdit(hEdt1, &sf);
282 ok_int(hr, S_OK);
283
284 ok_long(sf.m_cRefs, 1);
285
286 trace("GWLP_WNDPROC: %p\n", (void *)GetWindowLongPtr(hEdt1, GWLP_WNDPROC));
287
288 EnumPropsW(hEdt1, PropEnumProc);
289
290 n = (INT)SendMessageW(hEdt1, EM_GETLIMITTEXT, 0, 0);
291 ok_int(n, 234);
292 }
293
294 {
295 CShellFolder sf(345, TRUE);
296
297 hr = SHLimitInputEdit(hEdt1, &sf);
298 ok_int(hr, E_NOTIMPL);
299
300 n = (INT)SendMessageW(hEdt1, EM_GETLIMITTEXT, 0, 0);
301 ok_int(n, 234);
302 }
303
304 {
305 CShellFolder sf(999, FALSE);
306
307 ok_long(sf.m_cRefs, 1);
308
309 SetWindowTextW(hEdt1, L"TEST/TEST");
310 hr = SHLimitInputEdit(hEdt1, &sf);
311 ok_int(hr, S_OK);
312 GetWindowTextW(hEdt1, szText, _countof(szText));
313 ok_wstr(szText, L"TEST/TEST");
314
315 ok_long(sf.m_cRefs, 1);
316
317 n = (INT)SendMessageW(hEdt1, EM_GETLIMITTEXT, 0, 0);
318 ok_int(n, 234);
319
320 SetWindowTextW(hEdt1, L"");
321 SendMessageW(hEdt1, WM_CHAR, L'A', 1);
322 GetWindowTextW(hEdt1, szText, _countof(szText));
323 ok_wstr(szText, L"A");
324
325 SendMessageW(hEdt1, WM_CHAR, L'/', 1);
326 GetWindowTextW(hEdt1, szText, _countof(szText));
327 ok_wstr(szText, L"A");
328
329 SendMessageW(hEdt1, WM_CHAR, L'/', 1);
330 GetWindowTextW(hEdt1, szText, _countof(szText));
331 ok_wstr(szText, L"A");
332
333 SendMessageW(hEdt1, WM_CHAR, L'A', 1);
334 GetWindowTextW(hEdt1, szText, _countof(szText));
335 ok_wstr(szText, L"AA");
336 }
337
338 {
339 CShellFolder sf(4, FALSE);
340
341 ok_long(sf.m_cRefs, 1);
342
343 SetWindowTextW(hEdt1, L"ABC");
344 hr = SHLimitInputEdit(hEdt1, &sf);
345
346 SendMessageW(hEdt1, WM_CHAR, L'D', 1);
347 GetWindowTextW(hEdt1, szText, _countof(szText));
348 ok_wstr(szText, L"DABC");
349
350 SendMessageW(hEdt1, WM_CHAR, L'E', 1);
351 GetWindowTextW(hEdt1, szText, _countof(szText));
352 ok_wstr(szText, L"DEABC");
353
354 ok_long(sf.m_cRefs, 1);
355 }
356
357 EndDialog(hwnd, IDABORT);
358 return TRUE;
359 }
360
START_TEST(SHLimitInputEdit)361 START_TEST(SHLimitInputEdit)
362 {
363 HRESULT hr;
364
365 _SEH2_TRY
366 {
367 hr = SHLimitInputEdit(NULL, NULL);
368 }
369 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
370 {
371 hr = 0xDEAD;
372 }
373 _SEH2_END;
374 ok_int(hr, 0xDEAD);
375
376 _SEH2_TRY
377 {
378 hr = SHLimitInputEdit((HWND)0xDEAD, NULL);
379 }
380 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
381 {
382 hr = 0xDEAD;
383 }
384 _SEH2_END;
385 ok_int(hr, 0xDEAD);
386
387 DialogBoxW(GetModuleHandleW(NULL), L"SHLIMIT", NULL, DialogProc);
388 }
389