Andrew Eikum : shell32: Add tests for SHChangeNotify functions.
Alexandre Julliard
julliard at winehq.org
Wed Aug 4 12:27:21 CDT 2010
Module: wine
Branch: master
Commit: 9f37536d6aa9cd53a77293e3c491295b0aeeab74
URL: http://source.winehq.org/git/wine.git/?a=commit;h=9f37536d6aa9cd53a77293e3c491295b0aeeab74
Author: Andrew Eikum <aeikum at codeweavers.com>
Date: Tue Aug 3 14:23:43 2010 -0500
shell32: Add tests for SHChangeNotify functions.
---
dlls/shell32/tests/shlfolder.c | 166 ++++++++++++++++++++++++++++++++++++++++
1 files changed, 166 insertions(+), 0 deletions(-)
diff --git a/dlls/shell32/tests/shlfolder.c b/dlls/shell32/tests/shlfolder.c
index 482a31d..6c0b6f2 100644
--- a/dlls/shell32/tests/shlfolder.c
+++ b/dlls/shell32/tests/shlfolder.c
@@ -3706,6 +3706,171 @@ static void test_ParseDisplayNamePBC(void)
IShellFolder_Release(psf);
}
+static const CHAR testwindow_class[] = "testwindow";
+#define WM_USER_NOTIFY (WM_APP+1)
+
+static struct {
+ const char *id;
+ BOOL exp_notify;
+ UINT signal;
+ const WCHAR *path_1;
+ const WCHAR *path_2;
+} exp_data;
+
+static LRESULT CALLBACK testwindow_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
+{
+ UINT signal = (UINT)lparam;
+
+ switch(msg){
+ case WM_USER_NOTIFY:
+ if(exp_data.exp_notify){
+ LPCITEMIDLIST *pidls = (LPCITEMIDLIST*)wparam;
+
+ ok(exp_data.signal == signal,
+ "%s: expected notification type %x, got: %x\n",
+ exp_data.id, exp_data.signal, signal);
+
+ trace("verifying pidls for: %s\n", exp_data.id);
+ verify_pidl(pidls[0], exp_data.path_1);
+ verify_pidl(pidls[1], exp_data.path_2);
+
+ exp_data.exp_notify = FALSE;
+ }else
+ ok(exp_data.exp_notify, "Didn't expect a WM_USER_NOTIFY message (event: %x)\n", signal);
+ return 0;
+ }
+ return DefWindowProc(hwnd, msg, wparam, lparam);
+}
+
+static void register_testwindow_class(void)
+{
+ WNDCLASSEXA cls;
+ ATOM ret;
+
+ ZeroMemory(&cls, sizeof(cls));
+ cls.cbSize = sizeof(cls);
+ cls.style = 0;
+ cls.lpfnWndProc = testwindow_wndproc;
+ cls.hInstance = GetModuleHandleA(NULL);
+ cls.lpszClassName = testwindow_class;
+
+ SetLastError(0);
+ ret = RegisterClassExA(&cls);
+ ok(ret != 0, "RegisterClassExA failed: %d\n", GetLastError());
+}
+
+/* SHCNF_FLUSH doesn't seem to work as advertised for SHCNF_PATHA, so we
+ * have to poll repeatedly for the message to appear */
+static void do_events(void)
+{
+ int c = 0;
+ while (exp_data.exp_notify && (c++ < 10)){
+ MSG msg;
+ while(PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)){
+ TranslateMessage(&msg);
+ DispatchMessageA(&msg);
+ }
+ if(exp_data.exp_notify)
+ Sleep(500);
+ }
+ trace("%s: took %d tries\n", exp_data.id, c);
+}
+
+static void test_SHChangeNotify(void)
+{
+ HWND wnd;
+ ULONG notifyID;
+ HRESULT hr;
+ BOOL br, has_unicode;
+ SHChangeNotifyEntry entries[1];
+ const CHAR root_dirA[] = "C:\\shell32_cn_test";
+ const WCHAR root_dirW[] = {'C',':','\\','s','h','e','l','l','3','2','_','c','n','_','t','e','s','t',0};
+ const CHAR test_dirA[] = "C:\\shell32_cn_test\\test";
+ const WCHAR test_dirW[] = {'C',':','\\','s','h','e','l','l','3','2','_','c','n','_','t','e','s','t','\\','t','e','s','t',0};
+
+ CreateDirectoryW(NULL, NULL);
+ has_unicode = !(GetLastError() == ERROR_CALL_NOT_IMPLEMENTED);
+
+ /* set up the root directory & window */
+ br = CreateDirectoryA(root_dirA, NULL);
+ ok(br == TRUE, "CreateDirectory failed: %d\n", GetLastError());
+
+ register_testwindow_class();
+
+ wnd = CreateWindowExA(0, testwindow_class, testwindow_class, 0,
+ CW_USEDEFAULT, CW_USEDEFAULT, 130, 105,
+ NULL, NULL, GetModuleHandleA(NULL), 0);
+ ok(wnd != NULL, "Failed to make a window\n");
+
+ entries[0].pidl = NULL;
+ if(has_unicode)
+ hr = SHILCreateFromPath(root_dirW, (LPITEMIDLIST*)&entries[0].pidl, 0);
+ else
+ hr = SHILCreateFromPath((LPCVOID)root_dirA, (LPITEMIDLIST*)&entries[0].pidl, 0);
+ ok(hr == S_OK, "SHILCreateFromPath failed: 0x%08x\n", hr);
+ entries[0].fRecursive = TRUE;
+
+ notifyID = SHChangeNotifyRegister(wnd, SHCNRF_ShellLevel,
+ SHCNE_ALLEVENTS, WM_USER_NOTIFY, 1, entries);
+ ok(notifyID != 0, "Failed to register a window for change notifications\n");
+
+ /* MKDIR */
+ br = CreateDirectoryA(test_dirA, NULL);
+ ok(br == TRUE, "CreateDirectory failed: %d\n", GetLastError());
+
+ if(has_unicode){
+ exp_data.id = "MKDIR PATHW";
+ exp_data.signal = SHCNE_MKDIR;
+ exp_data.exp_notify = TRUE;
+ exp_data.path_1 = test_dirW;
+ exp_data.path_2 = NULL;
+ SHChangeNotify(SHCNE_MKDIR, SHCNF_PATHW | SHCNF_FLUSH, test_dirW, NULL);
+ do_events();
+ ok(exp_data.exp_notify == FALSE, "Expected wndproc to be called\n");
+ }else
+ win_skip("skipping WCHAR tests\n");
+
+ exp_data.id = "MKDIR PATHA";
+ exp_data.signal = SHCNE_MKDIR;
+ exp_data.exp_notify = TRUE;
+ exp_data.path_1 = test_dirW;
+ exp_data.path_2 = NULL;
+ SHChangeNotify(SHCNE_MKDIR, SHCNF_PATHA | SHCNF_FLUSH, test_dirA, NULL);
+ do_events();
+ ok(exp_data.exp_notify == FALSE, "Expected wndproc to be called\n");
+
+ /* RMDIR */
+ br = RemoveDirectoryA(test_dirA);
+ ok(br == TRUE, "RemoveDirectory failed: %d\n", GetLastError());
+
+ if(has_unicode){
+ exp_data.id = "RMDIR PATHW";
+ exp_data.signal = SHCNE_RMDIR;
+ exp_data.exp_notify = TRUE;
+ exp_data.path_1 = test_dirW;
+ exp_data.path_2 = NULL;
+ SHChangeNotify(SHCNE_RMDIR, SHCNF_PATHW | SHCNF_FLUSH, test_dirW, NULL);
+ do_events();
+ ok(exp_data.exp_notify == FALSE, "Expected wndproc to be called\n");
+ }else
+ win_skip("skipping WCHAR tests\n");
+
+ exp_data.id = "RMDIR PATHA";
+ exp_data.signal = SHCNE_RMDIR;
+ exp_data.exp_notify = TRUE;
+ exp_data.path_1 = test_dirW;
+ exp_data.path_2 = NULL;
+ SHChangeNotify(SHCNE_RMDIR, SHCNF_PATHA | SHCNF_FLUSH, test_dirA, NULL);
+ do_events();
+ ok(exp_data.exp_notify == FALSE, "Expected wndproc to be called\n");
+
+ SHChangeNotifyDeregister(notifyID);
+ DestroyWindow(wnd);
+
+ br = RemoveDirectoryA(root_dirA);
+ ok(br == TRUE, "RemoveDirectory failed: %d\n", GetLastError());
+}
+
START_TEST(shlfolder)
{
init_function_pointers();
@@ -3736,6 +3901,7 @@ START_TEST(shlfolder)
test_SHGetIDListFromObject();
test_SHGetItemFromObject();
test_ShellItemCompare();
+ test_SHChangeNotify();
OleUninitialize();
}
More information about the wine-cvs
mailing list