Piotr Caban : user32/tests: Add initial out of window procedure slots test.
Alexandre Julliard
julliard at wine.codeweavers.com
Mon Mar 14 09:05:21 CDT 2016
Module: wine
Branch: master
Commit: 55a5bac50037cd0f31c084d6e0898fcd8ccfb2be
URL: http://source.winehq.org/git/wine.git/?a=commit;h=55a5bac50037cd0f31c084d6e0898fcd8ccfb2be
Author: Piotr Caban <piotr at codeweavers.com>
Date: Wed Mar 9 13:51:31 2016 +0100
user32/tests: Add initial out of window procedure slots test.
Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/user32/tests/win.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 115 insertions(+)
diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c
index 44f0557..e121809 100644
--- a/dlls/user32/tests/win.c
+++ b/dlls/user32/tests/win.c
@@ -8677,6 +8677,114 @@ static void test_activateapp(HWND window1)
DestroyWindow(window2);
}
+static LRESULT WINAPI winproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
+{
+ if(!hwnd) {
+ int *count = (int*)lparam;
+ (*count)++;
+ }
+ return 0;
+}
+
+static LRESULT WINAPI winproc2(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
+{
+ return 0;
+}
+
+static void test_winproc_handles(const char *argv0)
+{
+ static const WCHAR winproc_testW[] = {'w','i','n','p','r','o','c','_','t','e','s','t',0};
+
+ HINSTANCE hinst = GetModuleHandleA(NULL);
+ WNDCLASSA wnd_classA;
+ WNDCLASSW wnd_classW;
+ int count;
+ PROCESS_INFORMATION info;
+ STARTUPINFOA startup;
+ char cmd[MAX_PATH];
+
+ memset(&wnd_classA, 0, sizeof(wnd_classA));
+ wnd_classA.lpszClassName = "winproc_test";
+ wnd_classA.lpfnWndProc = winproc;
+ ok(RegisterClassA(&wnd_classA),
+ "RegisterClass failed with error %d\n", GetLastError());
+
+ ok(GetClassInfoW(hinst, winproc_testW, &wnd_classW),
+ "GetClassInfoW failed with error %d\n", GetLastError());
+ ok(wnd_classA.lpfnWndProc != wnd_classW.lpfnWndProc,
+ "winproc pointers should not be identical\n");
+
+ count = 0;
+ CallWindowProcA(wnd_classW.lpfnWndProc, 0, 0, 0, (LPARAM)&count);
+ ok(count == 1, "winproc should be called once (%d)\n", count);
+ count = 0;
+ CallWindowProcW(wnd_classW.lpfnWndProc, 0, 0, 0, (LPARAM)&count);
+ ok(count == 1, "winproc should be called once (%d)\n", count);
+
+ ok(UnregisterClassW(winproc_testW, hinst),
+ "UnregisterClass failed with error %d\n", GetLastError());
+ /* crashes on 64-bit windows because lpfnWndProc handle is already freed */
+ if (sizeof(void*) == 4)
+ {
+ count = 0;
+ CallWindowProcA(wnd_classW.lpfnWndProc, 0, 0, 0, (LPARAM)&count);
+ todo_wine ok(!count, "winproc should not be called (%d)\n", count);
+ CallWindowProcW(wnd_classW.lpfnWndProc, 0, 0, 0, (LPARAM)&count);
+ todo_wine ok(!count, "winproc should not be called (%d)\n", count);
+ }
+
+ sprintf(cmd, "%s win winproc_limit", argv0);
+ memset(&startup, 0, sizeof(startup));
+ startup.cb = sizeof(startup);
+ ok(CreateProcessA(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL,
+ &startup, &info), "CreateProcess failed.\n");
+ winetest_wait_child_process(info.hProcess);
+ CloseHandle(info.hProcess);
+ CloseHandle(info.hThread);
+}
+
+static void test_winproc_limit(void)
+{
+ WNDPROC winproc_handle;
+ HWND hwnd;
+ int i;
+
+ hwnd = CreateWindowExA(0, "static", "test", WS_POPUP, 0, 0, 0, 0, 0, 0, 0, 0);
+ ok(hwnd != 0, "CreateWindowEx failed\n");
+
+ ok(SetWindowLongPtrA(hwnd, GWLP_WNDPROC, (LONG_PTR)winproc),
+ "SetWindowLongPtr failed\n");
+ winproc_handle = (WNDPROC)GetWindowLongPtrW(hwnd, GWLP_WNDPROC);
+ ok(winproc_handle != winproc, "winproc pointers should not be identical\n");
+
+ /* run out of winproc slots */
+ for(i = 2; i<0xffff; i++)
+ {
+ ok(SetWindowLongPtrA(hwnd, GWLP_WNDPROC, i), "SetWindowLongPtr failed (%d)\n", i);
+ if(GetWindowLongPtrW(hwnd, GWLP_WNDPROC) == i)
+ break;
+ }
+ ok(i != 0xffff, "unable to run out of winproc slots\n");
+ ok(SetWindowLongPtrA(hwnd, GWLP_WNDPROC, (LONG_PTR)winproc2),
+ "SetWindowLongPtr failed with error %d\n", GetLastError());
+
+ i = 0;
+ CallWindowProcA(winproc_handle, 0, 0, 0, (LPARAM)&i);
+ ok(i == 1, "winproc should be called once (%d)\n", i);
+ i = 0;
+ CallWindowProcW(winproc_handle, 0, 0, 0, (LPARAM)&i);
+ ok(i == 1, "winproc should be called once (%d)\n", i);
+
+ DestroyWindow(hwnd);
+
+ i = 0;
+ CallWindowProcA(winproc_handle, 0, 0, 0, (LPARAM)&i);
+ ok(i == 1, "winproc should be called once (%d)\n", i);
+ i = 0;
+ CallWindowProcW(winproc_handle, 0, 0, 0, (LPARAM)&i);
+ ok(i == 1, "winproc should be called once (%d)\n", i);
+}
+
START_TEST(win)
{
char **argv;
@@ -8711,6 +8819,12 @@ START_TEST(win)
return;
}
+ if (argc==3 && !strcmp(argv[2], "winproc_limit"))
+ {
+ test_winproc_limit();
+ return;
+ }
+
if (!RegisterWindowClasses()) assert(0);
hwndMain = CreateWindowExA(/*WS_EX_TOOLWINDOW*/ 0, "MainWindowClass", "Main window",
@@ -8812,6 +8926,7 @@ START_TEST(win)
test_smresult();
test_GetMessagePos();
test_activateapp(hwndMain);
+ test_winproc_handles(argv[0]);
/* add the tests above this line */
if (hhook) UnhookWindowsHookEx(hhook);
More information about the wine-cvs
mailing list