| /* |
| * Tests for autocomplete |
| * |
| * Copyright 2008 Jan de Mooij |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
| */ |
| |
| #define COBJMACROS |
| |
| #include <wine/test.h> |
| #include <stdarg.h> |
| |
| #include "windows.h" |
| #include "shobjidl.h" |
| #include "shlguid.h" |
| #include "initguid.h" |
| #include "shldisp.h" |
| |
| static HWND hMainWnd, hEdit; |
| static HINSTANCE hinst; |
| static int killfocus_count; |
| |
| static void test_invalid_init(void) |
| { |
| HRESULT hr; |
| IAutoComplete *ac; |
| IUnknown *acSource; |
| HWND edit_control; |
| |
| /* AutoComplete instance */ |
| hr = CoCreateInstance(&CLSID_AutoComplete, NULL, CLSCTX_INPROC_SERVER, |
| &IID_IAutoComplete, (void **)&ac); |
| if (hr == REGDB_E_CLASSNOTREG) |
| { |
| win_skip("CLSID_AutoComplete is not registered\n"); |
| return; |
| } |
| ok(hr == S_OK, "no IID_IAutoComplete (0x%08x)\n", hr); |
| |
| /* AutoComplete source */ |
| hr = CoCreateInstance(&CLSID_ACLMulti, NULL, CLSCTX_INPROC_SERVER, |
| &IID_IACList, (void **)&acSource); |
| if (hr == REGDB_E_CLASSNOTREG) |
| { |
| win_skip("CLSID_ACLMulti is not registered\n"); |
| IAutoComplete_Release(ac); |
| return; |
| } |
| ok(hr == S_OK, "no IID_IACList (0x%08x)\n", hr); |
| |
| edit_control = CreateWindowExA(0, "EDIT", "Some text", 0, 10, 10, 300, 300, |
| hMainWnd, NULL, hinst, NULL); |
| ok(edit_control != NULL, "Can't create edit control\n"); |
| |
| /* The refcount of acSource would be incremented on older Windows. */ |
| hr = IAutoComplete_Init(ac, NULL, acSource, NULL, NULL); |
| ok(hr == E_INVALIDARG || |
| broken(hr == S_OK), /* Win2k/XP/Win2k3 */ |
| "Init returned 0x%08x\n", hr); |
| if (hr == E_INVALIDARG) |
| { |
| LONG ref; |
| |
| IUnknown_AddRef(acSource); |
| ref = IUnknown_Release(acSource); |
| ok(ref == 1, "Expected AutoComplete source refcount to be 1, got %d\n", ref); |
| } |
| |
| if (0) |
| { |
| /* Older Windows versions never check the window handle, while newer |
| * versions only check for NULL. Subsequent attempts to initialize the |
| * object after this call succeeds would fail, because initialization |
| * state is determined by whether a non-NULL window handle is stored. */ |
| hr = IAutoComplete_Init(ac, (HWND)0xdeadbeef, acSource, NULL, NULL); |
| ok(hr == S_OK, "Init returned 0x%08x\n", hr); |
| |
| /* Tests crash on older Windows. */ |
| hr = IAutoComplete_Init(ac, NULL, NULL, NULL, NULL); |
| ok(hr == E_INVALIDARG, "Init returned 0x%08x\n", hr); |
| |
| hr = IAutoComplete_Init(ac, edit_control, NULL, NULL, NULL); |
| ok(hr == E_INVALIDARG, "Init returned 0x%08x\n", hr); |
| } |
| |
| /* bind to edit control */ |
| hr = IAutoComplete_Init(ac, edit_control, acSource, NULL, NULL); |
| ok(hr == S_OK, "Init returned 0x%08x\n", hr); |
| |
| /* try invalid parameters after successful initialization .*/ |
| hr = IAutoComplete_Init(ac, NULL, NULL, NULL, NULL); |
| ok(hr == E_INVALIDARG || |
| hr == E_FAIL, /* Win2k/XP/Win2k3 */ |
| "Init returned 0x%08x\n", hr); |
| |
| hr = IAutoComplete_Init(ac, NULL, acSource, NULL, NULL); |
| ok(hr == E_INVALIDARG || |
| hr == E_FAIL, /* Win2k/XP/Win2k3 */ |
| "Init returned 0x%08x\n", hr); |
| |
| hr = IAutoComplete_Init(ac, edit_control, NULL, NULL, NULL); |
| ok(hr == E_INVALIDARG || |
| hr == E_FAIL, /* Win2k/XP/Win2k3 */ |
| "Init returned 0x%08x\n", hr); |
| |
| /* try initializing twice on the same control */ |
| hr = IAutoComplete_Init(ac, edit_control, acSource, NULL, NULL); |
| ok(hr == E_FAIL, "Init returned 0x%08x\n", hr); |
| |
| /* try initializing with a different control */ |
| hr = IAutoComplete_Init(ac, hEdit, acSource, NULL, NULL); |
| ok(hr == E_FAIL, "Init returned 0x%08x\n", hr); |
| |
| DestroyWindow(edit_control); |
| |
| /* try initializing with a different control after |
| * destroying the original initialization control */ |
| hr = IAutoComplete_Init(ac, hEdit, acSource, NULL, NULL); |
| ok(hr == E_UNEXPECTED || |
| hr == E_FAIL, /* Win2k/XP/Win2k3 */ |
| "Init returned 0x%08x\n", hr); |
| |
| IUnknown_Release(acSource); |
| IAutoComplete_Release(ac); |
| } |
| static IAutoComplete *test_init(void) |
| { |
| HRESULT r; |
| IAutoComplete *ac; |
| IUnknown *acSource; |
| LONG_PTR user_data; |
| |
| /* AutoComplete instance */ |
| r = CoCreateInstance(&CLSID_AutoComplete, NULL, CLSCTX_INPROC_SERVER, |
| &IID_IAutoComplete, (LPVOID*)&ac); |
| if (r == REGDB_E_CLASSNOTREG) |
| { |
| win_skip("CLSID_AutoComplete is not registered\n"); |
| return NULL; |
| } |
| ok(r == S_OK, "no IID_IAutoComplete (0x%08x)\n", r); |
| |
| /* AutoComplete source */ |
| r = CoCreateInstance(&CLSID_ACLMulti, NULL, CLSCTX_INPROC_SERVER, |
| &IID_IACList, (LPVOID*)&acSource); |
| if (r == REGDB_E_CLASSNOTREG) |
| { |
| win_skip("CLSID_ACLMulti is not registered\n"); |
| IAutoComplete_Release(ac); |
| return NULL; |
| } |
| ok(r == S_OK, "no IID_IACList (0x%08x)\n", r); |
| |
| user_data = GetWindowLongPtrA(hEdit, GWLP_USERDATA); |
| ok(user_data == 0, "Expected the edit control user data to be zero\n"); |
| |
| /* bind to edit control */ |
| r = IAutoComplete_Init(ac, hEdit, acSource, NULL, NULL); |
| ok(r == S_OK, "Init returned 0x%08x\n", r); |
| |
| user_data = GetWindowLongPtrA(hEdit, GWLP_USERDATA); |
| ok(user_data == 0, "Expected the edit control user data to be zero\n"); |
| |
| IUnknown_Release(acSource); |
| |
| return ac; |
| } |
| |
| static void test_killfocus(void) |
| { |
| /* Test if WM_KILLFOCUS messages are handled properly by checking if |
| * the parent receives an EN_KILLFOCUS message. */ |
| SetFocus(hEdit); |
| killfocus_count = 0; |
| SetFocus(0); |
| ok(killfocus_count == 1, "Expected one EN_KILLFOCUS message, got: %d\n", killfocus_count); |
| } |
| |
| static LRESULT CALLBACK MyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) |
| { |
| switch(msg) { |
| case WM_CREATE: |
| /* create edit control */ |
| hEdit = CreateWindowEx(0, "EDIT", "Some text", 0, 10, 10, 300, 300, |
| hWnd, NULL, hinst, NULL); |
| ok(hEdit != NULL, "Can't create edit control\n"); |
| break; |
| case WM_COMMAND: |
| if(HIWORD(wParam) == EN_KILLFOCUS) |
| killfocus_count++; |
| break; |
| } |
| return DefWindowProcA(hWnd, msg, wParam, lParam); |
| } |
| |
| static void createMainWnd(void) |
| { |
| WNDCLASSA wc; |
| wc.style = CS_HREDRAW | CS_VREDRAW; |
| wc.cbClsExtra = 0; |
| wc.cbWndExtra = 0; |
| wc.hInstance = GetModuleHandleA(NULL); |
| wc.hIcon = NULL; |
| wc.hCursor = LoadCursorA(NULL, IDC_IBEAM); |
| wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW); |
| wc.lpszMenuName = NULL; |
| wc.lpszClassName = "MyTestWnd"; |
| wc.lpfnWndProc = MyWndProc; |
| RegisterClassA(&wc); |
| |
| hMainWnd = CreateWindowExA(0, "MyTestWnd", "Blah", WS_OVERLAPPEDWINDOW, |
| CW_USEDEFAULT, CW_USEDEFAULT, 130, 105, NULL, NULL, GetModuleHandleA(NULL), 0); |
| } |
| |
| START_TEST(autocomplete) |
| { |
| HRESULT r; |
| MSG msg; |
| IAutoComplete* ac; |
| |
| r = CoInitialize(NULL); |
| ok(r == S_OK, "CoInitialize failed (0x%08x). Tests aborted.\n", r); |
| if (r != S_OK) |
| return; |
| |
| createMainWnd(); |
| ok(hMainWnd != NULL, "Failed to create parent window. Tests aborted.\n"); |
| if (!hMainWnd) return; |
| |
| test_invalid_init(); |
| ac = test_init(); |
| if (!ac) |
| goto cleanup; |
| test_killfocus(); |
| |
| PostQuitMessage(0); |
| while(GetMessageA(&msg,0,0,0)) { |
| TranslateMessage(&msg); |
| DispatchMessageA(&msg); |
| } |
| |
| IAutoComplete_Release(ac); |
| |
| cleanup: |
| DestroyWindow(hEdit); |
| DestroyWindow(hMainWnd); |
| |
| CoUninitialize(); |
| } |