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 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 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 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 52 STDMETHODIMP EnumObjects( 53 HWND hwnd, 54 SHCONTF grfFlags, 55 IEnumIDList **ppenumIDList) 56 { 57 trace("EnumObjects\n"); 58 return E_NOTIMPL; 59 } 60 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 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 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 90 STDMETHODIMP CreateViewObject( 91 HWND hwndOwner, 92 REFIID riid, 93 void **ppv) 94 { 95 trace("CreateViewObject\n"); 96 return E_NOTIMPL; 97 } 98 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 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 120 STDMETHODIMP GetDisplayNameOf( 121 PCUITEMID_CHILD pidl, 122 SHGDNF uFlags, 123 STRRET *pName) 124 { 125 trace("GetDisplayNameOf\n"); 126 return E_NOTIMPL; 127 } 128 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 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 180 STDMETHODIMP_(ULONG) CShellFolder::AddRef() 181 { 182 trace("AddRef\n"); 183 return ++m_cRefs; 184 } 185 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 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 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 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 INT_PTR CALLBACK 242 DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 243 { 244 if (uMsg != WM_INITDIALOG) 245 return FALSE; 246 247 HWND hEdt1 = GetDlgItem(hwnd, edt1); 248 INT n; 249 HRESULT hr; 250 WCHAR szText[64]; 251 252 _SEH2_TRY 253 { 254 hr = SHLimitInputEdit(hEdt1, NULL); 255 } 256 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 257 { 258 hr = 0xDEAD; 259 } 260 _SEH2_END; 261 ok_int(hr, 0xDEAD); 262 263 { 264 CShellFolder sf(123, FALSE); 265 266 ok_long(sf.m_cRefs, 1); 267 268 SendMessageW(hEdt1, EM_LIMITTEXT, 234, 0); 269 270 trace("GWLP_WNDPROC: %p\n", (void *)GetWindowLongPtr(hEdt1, GWLP_WNDPROC)); 271 272 hr = SHLimitInputEdit(hEdt1, &sf); 273 ok_int(hr, S_OK); 274 275 ok_long(sf.m_cRefs, 1); 276 277 trace("GWLP_WNDPROC: %p\n", (void *)GetWindowLongPtr(hEdt1, GWLP_WNDPROC)); 278 279 EnumPropsW(hEdt1, PropEnumProc); 280 281 n = (INT)SendMessageW(hEdt1, EM_GETLIMITTEXT, 0, 0); 282 ok_int(n, 234); 283 } 284 285 { 286 CShellFolder sf(345, TRUE); 287 288 hr = SHLimitInputEdit(hEdt1, &sf); 289 ok_int(hr, E_NOTIMPL); 290 291 n = (INT)SendMessageW(hEdt1, EM_GETLIMITTEXT, 0, 0); 292 ok_int(n, 234); 293 } 294 295 { 296 CShellFolder sf(999, FALSE); 297 298 ok_long(sf.m_cRefs, 1); 299 300 SetWindowTextW(hEdt1, L"TEST/TEST"); 301 hr = SHLimitInputEdit(hEdt1, &sf); 302 ok_int(hr, S_OK); 303 GetWindowTextW(hEdt1, szText, _countof(szText)); 304 ok_wstr(szText, L"TEST/TEST"); 305 306 ok_long(sf.m_cRefs, 1); 307 308 n = (INT)SendMessageW(hEdt1, EM_GETLIMITTEXT, 0, 0); 309 ok_int(n, 234); 310 311 SetWindowTextW(hEdt1, L""); 312 SendMessageW(hEdt1, WM_CHAR, L'A', 1); 313 GetWindowTextW(hEdt1, szText, _countof(szText)); 314 ok_wstr(szText, L"A"); 315 316 SendMessageW(hEdt1, WM_CHAR, L'/', 1); 317 GetWindowTextW(hEdt1, szText, _countof(szText)); 318 ok_wstr(szText, L"A"); 319 320 SendMessageW(hEdt1, WM_CHAR, L'/', 1); 321 GetWindowTextW(hEdt1, szText, _countof(szText)); 322 ok_wstr(szText, L"A"); 323 324 SendMessageW(hEdt1, WM_CHAR, L'A', 1); 325 GetWindowTextW(hEdt1, szText, _countof(szText)); 326 ok_wstr(szText, L"AA"); 327 } 328 329 { 330 CShellFolder sf(4, FALSE); 331 332 ok_long(sf.m_cRefs, 1); 333 334 SetWindowTextW(hEdt1, L"ABC"); 335 hr = SHLimitInputEdit(hEdt1, &sf); 336 337 SendMessageW(hEdt1, WM_CHAR, L'D', 1); 338 GetWindowTextW(hEdt1, szText, _countof(szText)); 339 ok_wstr(szText, L"DABC"); 340 341 SendMessageW(hEdt1, WM_CHAR, L'E', 1); 342 GetWindowTextW(hEdt1, szText, _countof(szText)); 343 ok_wstr(szText, L"DEABC"); 344 345 ok_long(sf.m_cRefs, 1); 346 } 347 348 EndDialog(hwnd, IDABORT); 349 return TRUE; 350 } 351 352 START_TEST(SHLimitInputEdit) 353 { 354 HRESULT hr; 355 356 _SEH2_TRY 357 { 358 hr = SHLimitInputEdit(NULL, NULL); 359 } 360 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 361 { 362 hr = 0xDEAD; 363 } 364 _SEH2_END; 365 ok_int(hr, 0xDEAD); 366 367 _SEH2_TRY 368 { 369 hr = SHLimitInputEdit((HWND)0xDEAD, NULL); 370 } 371 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 372 { 373 hr = 0xDEAD; 374 } 375 _SEH2_END; 376 ok_int(hr, 0xDEAD); 377 378 DialogBoxW(GetModuleHandleW(NULL), L"SHLIMIT", NULL, DialogProc); 379 } 380