comboex.c 18.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/* Unit test suite for comboex control.
 *
 * Copyright 2005 Jason Edmeades
 *
 * 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
17
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 19 20 21 22 23 24
 */

#include <assert.h>
#include <windows.h>
#include <commctrl.h>

#include "wine/test.h"
25 26 27 28 29 30 31
#include "msg.h"

#define EDITBOX_SEQ_INDEX  0
#define NUM_MSG_SEQUENCES  1

#define EDITBOX_ID         0

32 33
#define expect(expected, got) ok(got == expected, "Expected %d, got %d\n", expected, got)

34
static struct msg_sequence *sequences[NUM_MSG_SEQUENCES];
35 36 37

static HWND hComboExParentWnd;
static HINSTANCE hMainHinst;
38
static const char ComboExTestClass[] = "ComboExTestClass";
39

40 41
static BOOL (WINAPI *pSetWindowSubclass)(HWND, SUBCLASSPROC, UINT_PTR, DWORD_PTR);

42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
#define MAX_CHARS 100
static char *textBuffer = NULL;

static HWND createComboEx(DWORD style) {
   return CreateWindowExA(0, WC_COMBOBOXEXA, NULL, style, 0, 0, 300, 300,
            hComboExParentWnd, NULL, hMainHinst, NULL);
}

static LONG addItem(HWND cbex, int idx, LPTSTR text) {
    COMBOBOXEXITEM cbexItem;
    memset(&cbexItem, 0x00, sizeof(cbexItem));
    cbexItem.mask = CBEIF_TEXT;
    cbexItem.iItem = idx;
    cbexItem.pszText    = text;
    cbexItem.cchTextMax = 0;
57
    return SendMessage(cbex, CBEM_INSERTITEM, 0, (LPARAM)&cbexItem);
58 59 60 61 62 63 64 65 66
}

static LONG setItem(HWND cbex, int idx, LPTSTR text) {
    COMBOBOXEXITEM cbexItem;
    memset(&cbexItem, 0x00, sizeof(cbexItem));
    cbexItem.mask = CBEIF_TEXT;
    cbexItem.iItem = idx;
    cbexItem.pszText    = text;
    cbexItem.cchTextMax = 0;
67
    return SendMessage(cbex, CBEM_SETITEM, 0, (LPARAM)&cbexItem);
68 69 70
}

static LONG delItem(HWND cbex, int idx) {
71
    return SendMessage(cbex, CBEM_DELETEITEM, idx, 0);
72 73 74 75 76 77 78 79
}

static LONG getItem(HWND cbex, int idx, COMBOBOXEXITEM *cbItem) {
    memset(cbItem, 0x00, sizeof(COMBOBOXEXITEM));
    cbItem->mask = CBEIF_TEXT;
    cbItem->pszText      = textBuffer;
    cbItem->iItem        = idx;
    cbItem->cchTextMax   = 100;
80
    return SendMessage(cbex, CBEM_GETITEM, 0, (LPARAM)cbItem);
81 82
}

83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
static LRESULT WINAPI editbox_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
    static LONG defwndproc_counter = 0;
    LRESULT ret;
    struct message msg;

    msg.message = message;
    msg.flags = sent|wparam|lparam;
    if (defwndproc_counter) msg.flags |= defwinproc;
    msg.wParam = wParam;
    msg.lParam = lParam;
    msg.id     = EDITBOX_ID;

    if (message != WM_PAINT &&
        message != WM_ERASEBKGND &&
        message != WM_NCPAINT &&
        message != WM_NCHITTEST &&
        message != WM_GETTEXT &&
        message != WM_GETICON &&
        message != WM_DEVICECHANGE)
    {
        add_message(sequences, EDITBOX_SEQ_INDEX, &msg);
    }

    defwndproc_counter++;
    ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam);
    defwndproc_counter--;
    return ret;
}

static HWND subclass_editbox(HWND hwndComboEx)
{
    WNDPROC oldproc;
    HWND hwnd;

    hwnd = (HWND)SendMessage(hwndComboEx, CBEM_GETEDITCONTROL, 0, 0);
    oldproc = (WNDPROC)SetWindowLongPtrA(hwnd, GWLP_WNDPROC,
                                         (LONG_PTR)editbox_subclass_proc);
    SetWindowLongPtrA(hwnd, GWLP_USERDATA, (LONG_PTR)oldproc);

    return hwnd;
}

127
static void test_comboboxex(void) {
128 129 130
    HWND myHwnd = 0;
    LONG res = -1;
    COMBOBOXEXITEM cbexItem;
131 132 133 134 135 136 137 138
    static TCHAR first_item[]        = {'F','i','r','s','t',' ','I','t','e','m',0},
                 second_item[]       = {'S','e','c','o','n','d',' ','I','t','e','m',0},
                 third_item[]        = {'T','h','i','r','d',' ','I','t','e','m',0},
                 middle_item[]       = {'B','e','t','w','e','e','n',' ','F','i','r','s','t',' ','a','n','d',' ',
                                        'S','e','c','o','n','d',' ','I','t','e','m','s',0},
                 replacement_item[]  = {'B','e','t','w','e','e','n',' ','F','i','r','s','t',' ','a','n','d',' ',
                                        'S','e','c','o','n','d',' ','I','t','e','m','s',0},
                 out_of_range_item[] = {'O','u','t',' ','o','f',' ','R','a','n','g','e',' ','I','t','e','m',0};
139 140

    /* Allocate space for result */
141
    textBuffer = HeapAlloc(GetProcessHeap(), 0, MAX_CHARS);
142 143 144 145 146

    /* Basic comboboxex test */
    myHwnd = createComboEx(WS_BORDER | WS_VISIBLE | WS_CHILD | CBS_DROPDOWN);

    /* Add items onto the end of the combobox */
147
    res = addItem(myHwnd, -1, first_item);
148
    ok(res == 0, "Adding simple item failed (%d)\n", res);
149
    res = addItem(myHwnd, -1, second_item);
150
    ok(res == 1, "Adding simple item failed (%d)\n", res);
151
    res = addItem(myHwnd, 2, third_item);
152
    ok(res == 2, "Adding simple item failed (%d)\n", res);
153
    res = addItem(myHwnd, 1, middle_item);
154
    ok(res == 1, "Inserting simple item failed (%d)\n", res);
155 156

    /* Add an item completely out of range */
157
    res = addItem(myHwnd, 99, out_of_range_item);
158
    ok(res == -1, "Adding using out of range index worked unexpectedly (%d)\n", res);
159
    res = addItem(myHwnd, 5, out_of_range_item);
160
    ok(res == -1, "Adding using out of range index worked unexpectedly (%d)\n", res);
161 162 163 164 165 166 167
    /* Removed: Causes traps on Windows XP
       res = addItem(myHwnd, -2, "Out Of Range Item");
       ok(res == -1, "Adding out of range worked unexpectedly (%ld)\n", res);
     */

    /* Get an item completely out of range */ 
    res = getItem(myHwnd, 99, &cbexItem); 
168
    ok(res == 0, "Getting item using out of range index worked unexpectedly (%d, %s)\n", res, cbexItem.pszText);
169
    res = getItem(myHwnd, 4, &cbexItem); 
170
    ok(res == 0, "Getting item using out of range index worked unexpectedly (%d, %s)\n", res, cbexItem.pszText);
171
    res = getItem(myHwnd, -2, &cbexItem); 
172
    ok(res == 0, "Getting item using out of range index worked unexpectedly (%d, %s)\n", res, cbexItem.pszText);
173 174 175

    /* Get an item in range */ 
    res = getItem(myHwnd, 0, &cbexItem); 
176
    ok(res != 0, "Getting item using valid index failed unexpectedly (%d)\n", res);
177
    ok(strcmp(first_item, cbexItem.pszText) == 0, "Getting item returned wrong string (%s)\n", cbexItem.pszText);
178 179

    res = getItem(myHwnd, 1, &cbexItem); 
180
    ok(res != 0, "Getting item using valid index failed unexpectedly (%d)\n", res);
181
    ok(strcmp(middle_item, cbexItem.pszText) == 0, "Getting item returned wrong string (%s)\n", cbexItem.pszText);
182 183

    res = getItem(myHwnd, 2, &cbexItem); 
184
    ok(res != 0, "Getting item using valid index failed unexpectedly (%d)\n", res);
185
    ok(strcmp(second_item, cbexItem.pszText) == 0, "Getting item returned wrong string (%s)\n", cbexItem.pszText);
186 187

    res = getItem(myHwnd, 3, &cbexItem); 
188
    ok(res != 0, "Getting item using valid index failed unexpectedly (%d)\n", res);
189
    ok(strcmp(third_item, cbexItem.pszText) == 0, "Getting item returned wrong string (%s)\n", cbexItem.pszText);
190 191

    /* Set an item completely out of range */ 
192
    res = setItem(myHwnd, 99, replacement_item); 
193
    ok(res == 0, "Setting item using out of range index worked unexpectedly (%d)\n", res);
194
    res = setItem(myHwnd, 4, replacement_item); 
195
    ok(res == 0, "Setting item using out of range index worked unexpectedly (%d)\n", res);
196
    res = setItem(myHwnd, -2, replacement_item); 
197
    ok(res == 0, "Setting item using out of range index worked unexpectedly (%d)\n", res);
198 199

    /* Set an item in range */ 
200
    res = setItem(myHwnd, 0, replacement_item);
201
    ok(res != 0, "Setting first item failed (%d)\n", res);
202
    res = setItem(myHwnd, 3, replacement_item);
203
    ok(res != 0, "Setting last item failed (%d)\n", res);
204 205 206

    /* Remove items completely out of range (4 items in control at this point) */
    res = delItem(myHwnd, -1);
207
    ok(res == CB_ERR, "Deleting using out of range index worked unexpectedly (%d)\n", res);
208
    res = delItem(myHwnd, 4);
209
    ok(res == CB_ERR, "Deleting using out of range index worked unexpectedly (%d)\n", res);
210 211 212

    /* Remove items in range (4 items in control at this point) */
    res = delItem(myHwnd, 3);
213
    ok(res == 3, "Deleting using out of range index failed (%d)\n", res);
214
    res = delItem(myHwnd, 0);
215
    ok(res == 2, "Deleting using out of range index failed (%d)\n", res);
216
    res = delItem(myHwnd, 0);
217
    ok(res == 1, "Deleting using out of range index failed (%d)\n", res);
218
    res = delItem(myHwnd, 0);
219
    ok(res == 0, "Deleting using out of range index failed (%d)\n", res);
220 221 222

    /* Remove from an empty box */
    res = delItem(myHwnd, 0);
223
    ok(res == CB_ERR, "Deleting using out of range index worked unexpectedly (%d)\n", res);
224 225 226


    /* Cleanup */
227
    HeapFree(GetProcessHeap(), 0, textBuffer);
228 229 230 231 232 233 234 235 236 237 238 239 240 241
    DestroyWindow(myHwnd);
}

static void test_WM_LBUTTONDOWN(void)
{
    HWND hComboEx, hCombo, hEdit, hList;
    COMBOBOXINFO cbInfo;
    UINT x, y, item_height;
    LRESULT result;
    int i, idx;
    RECT rect;
    WCHAR buffer[3];
    static const UINT choices[] = {8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72};
    static const WCHAR stringFormat[] = {'%','2','d','\0'};
242 243 244 245
    BOOL (WINAPI *pGetComboBoxInfo)(HWND, PCOMBOBOXINFO);

    pGetComboBoxInfo = (void*)GetProcAddress(GetModuleHandleA("user32.dll"), "GetComboBoxInfo");
    if (!pGetComboBoxInfo){
246
        win_skip("GetComboBoxInfo is not available\n");
247 248
        return;
    }
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265

    hComboEx = CreateWindowExA(0, WC_COMBOBOXEXA, NULL,
            WS_VISIBLE|WS_CHILD|CBS_DROPDOWN, 0, 0, 200, 150,
            hComboExParentWnd, NULL, hMainHinst, NULL);

    for (i = 0; i < sizeof(choices)/sizeof(UINT); i++){
        COMBOBOXEXITEMW cbexItem;
        wsprintfW(buffer, stringFormat, choices[i]);

        memset(&cbexItem, 0x00, sizeof(cbexItem));
        cbexItem.mask = CBEIF_TEXT;
        cbexItem.iItem = i;
        cbexItem.pszText = buffer;
        cbexItem.cchTextMax = 0;
        ok(SendMessageW(hComboEx, CBEM_INSERTITEMW, 0, (LPARAM)&cbexItem) >= 0,
           "Failed to add item %d\n", i);
    }
266

267 268 269 270
    hCombo = (HWND)SendMessage(hComboEx, CBEM_GETCOMBOCONTROL, 0, 0);
    hEdit = (HWND)SendMessage(hComboEx, CBEM_GETEDITCONTROL, 0, 0);

    cbInfo.cbSize = sizeof(COMBOBOXINFO);
271
    result = pGetComboBoxInfo(hCombo, &cbInfo);
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
    ok(result, "Failed to get combobox info structure. LastError=%d\n",
       GetLastError());
    hList = cbInfo.hwndList;

    trace("hWnd=%p, hComboEx=%p, hCombo=%p, hList=%p, hEdit=%p\n",
         hComboExParentWnd, hComboEx, hCombo, hList, hEdit);
    ok(GetFocus() == hComboExParentWnd,
       "Focus not on Main Window, instead on %p\n", GetFocus());

    /* Click on the button to drop down the list */
    x = cbInfo.rcButton.left + (cbInfo.rcButton.right-cbInfo.rcButton.left)/2;
    y = cbInfo.rcButton.top + (cbInfo.rcButton.bottom-cbInfo.rcButton.top)/2;
    result = SendMessage(hCombo, WM_LBUTTONDOWN, 0, MAKELPARAM(x, y));
    ok(result, "WM_LBUTTONDOWN was not processed. LastError=%d\n",
       GetLastError());
287 288
    ok(GetFocus() == hCombo ||
       broken(GetFocus() != hCombo), /* win98 */
289 290 291 292 293 294 295 296 297 298
       "Focus not on ComboBoxEx's ComboBox Control, instead on %p\n",
       GetFocus());
    ok(SendMessage(hComboEx, CB_GETDROPPEDSTATE, 0, 0),
       "The dropdown list should have appeared after clicking the button.\n");
    idx = SendMessage(hCombo, CB_GETTOPINDEX, 0, 0);
    ok(idx == 0, "For TopIndex expected %d, got %d\n", 0, idx);

    result = SendMessage(hCombo, WM_LBUTTONUP, 0, MAKELPARAM(x, y));
    ok(result, "WM_LBUTTONUP was not processed. LastError=%d\n",
       GetLastError());
299 300
    ok(GetFocus() == hCombo ||
       broken(GetFocus() != hCombo), /* win98 */
301 302 303 304 305 306 307 308 309 310 311
       "Focus not on ComboBoxEx's ComboBox Control, instead on %p\n",
       GetFocus());

    /* Click on the 5th item in the list */
    item_height = SendMessage(hCombo, CB_GETITEMHEIGHT, 0, 0);
    ok(GetClientRect(hList, &rect), "Failed to get list's client rect.\n");
    x = rect.left + (rect.right-rect.left)/2;
    y = item_height/2 + item_height*4;
    result = SendMessage(hList, WM_MOUSEMOVE, 0, MAKELPARAM(x, y));
    ok(!result, "WM_MOUSEMOVE was not processed. LastError=%d\n",
       GetLastError());
312 313
    ok(GetFocus() == hCombo ||
       broken(GetFocus() != hCombo), /* win98 */
314 315 316 317 318 319
       "Focus not on ComboBoxEx's ComboBox Control, instead on %p\n",
       GetFocus());

    result = SendMessage(hList, WM_LBUTTONDOWN, 0, MAKELPARAM(x, y));
    ok(!result, "WM_LBUTTONDOWN was not processed. LastError=%d\n",
       GetLastError());
320 321
    ok(GetFocus() == hCombo ||
       broken(GetFocus() != hCombo), /* win98 */
322 323
       "Focus not on ComboBoxEx's ComboBox Control, instead on %p\n",
       GetFocus());
324
    ok(SendMessage(hComboEx, CB_GETDROPPEDSTATE, 0, 0),
325 326 327 328 329
       "The dropdown list should still be visible.\n");

    result = SendMessage(hList, WM_LBUTTONUP, 0, MAKELPARAM(x, y));
    ok(!result, "WM_LBUTTONUP was not processed. LastError=%d\n",
       GetLastError());
330 331
    todo_wine ok(GetFocus() == hEdit ||
       broken(GetFocus() == hCombo), /* win98 */
332 333
       "Focus not on ComboBoxEx's Edit Control, instead on %p\n",
       GetFocus());
334 335 336 337

    result = SendMessage(hCombo, CB_GETDROPPEDSTATE, 0, 0);
    ok(!result ||
       broken(result != 0), /* win98 */
338 339
       "The dropdown list should have been rolled up.\n");
    idx = SendMessage(hComboEx, CB_GETCURSEL, 0, 0);
340 341 342
    ok(idx == 4 ||
       broken(idx == -1), /* win98 */
       "Current Selection: expected %d, got %d\n", 4, idx);
343 344

    DestroyWindow(hComboEx);
345 346
}

347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381
static void test_CB_GETLBTEXT(void)
{
    HWND hCombo;
    CHAR buff[1];
    COMBOBOXEXITEMA item;
    LRESULT ret;

    hCombo = createComboEx(WS_BORDER | WS_VISIBLE | WS_CHILD | CBS_DROPDOWN);

    /* set text to null */
    addItem(hCombo, 0, NULL);

    buff[0] = 'a';
    item.mask = CBEIF_TEXT;
    item.iItem = 0;
    item.pszText = buff;
    item.cchTextMax = 1;
    ret = SendMessage(hCombo, CBEM_GETITEMA, 0, (LPARAM)&item);
    ok(ret != 0, "CBEM_GETITEM failed\n");
    ok(buff[0] == 0, "\n");

    ret = SendMessage(hCombo, CB_GETLBTEXTLEN, 0, 0);
    ok(ret == 0, "Expected zero length\n");

    ret = SendMessage(hCombo, CB_GETLBTEXTLEN, 0, 0);
    ok(ret == 0, "Expected zero length\n");

    buff[0] = 'a';
    ret = SendMessage(hCombo, CB_GETLBTEXT, 0, (LPARAM)buff);
    ok(ret == 0, "Expected zero length\n");
    ok(buff[0] == 0, "Expected null terminator as a string, got %s\n", buff);

    DestroyWindow(hCombo);
}

382
static LRESULT CALLBACK ComboExTestWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
383 384
{
    switch(msg) {
385

386 387 388 389 390 391 392 393 394 395 396
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
  
    default:
        return DefWindowProcA(hWnd, msg, wParam, lParam);
    }
    
    return 0L;
}

397 398 399 400
static int init(void)
{
    HMODULE hComctl32;
    BOOL (WINAPI *pInitCommonControlsEx)(const INITCOMMONCONTROLSEX*);
401
    WNDCLASSA wc;
402 403 404 405 406 407
    INITCOMMONCONTROLSEX iccex;

    hComctl32 = GetModuleHandleA("comctl32.dll");
    pInitCommonControlsEx = (void*)GetProcAddress(hComctl32, "InitCommonControlsEx");
    if (!pInitCommonControlsEx)
    {
408
        win_skip("InitCommonControlsEx() is missing. Skipping the tests\n");
409 410 411 412 413
        return 0;
    }
    iccex.dwSize = sizeof(iccex);
    iccex.dwICC  = ICC_USEREX_CLASSES;
    pInitCommonControlsEx(&iccex);
414

415 416
    pSetWindowSubclass = (void*)GetProcAddress(hComctl32, (LPSTR)410);

417 418 419 420 421
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = GetModuleHandleA(NULL);
    wc.hIcon = NULL;
422
    wc.hCursor = LoadCursorA(NULL, IDC_ARROW);
423 424 425 426 427 428
    wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = ComboExTestClass;
    wc.lpfnWndProc = ComboExTestWndProc;
    RegisterClassA(&wc);

429
    hComboExParentWnd = CreateWindowExA(0, ComboExTestClass, "ComboEx test", WS_OVERLAPPEDWINDOW|WS_VISIBLE,
430 431 432 433
      CW_USEDEFAULT, CW_USEDEFAULT, 680, 260, NULL, NULL, GetModuleHandleA(NULL), 0);
    assert(hComboExParentWnd != NULL);

    hMainHinst = GetModuleHandleA(NULL);
434
    return 1;
435 436 437 438 439 440 441 442 443 444 445 446
}

static void cleanup(void)
{
    MSG msg;
    
    PostMessageA(hComboExParentWnd, WM_CLOSE, 0, 0);
    while (GetMessageA(&msg,0,0,0)) {
        TranslateMessage(&msg);
        DispatchMessageA(&msg);
    }
    
447
    DestroyWindow(hComboExParentWnd);
448 449 450
    UnregisterClassA(ComboExTestClass, GetModuleHandleA(NULL));
}

451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470
static void test_comboboxex_subclass(void)
{
    HWND hComboEx, hCombo, hEdit;

    hComboEx = createComboEx(WS_BORDER | WS_VISIBLE | WS_CHILD | CBS_DROPDOWN);

    hCombo = (HWND)SendMessage(hComboEx, CBEM_GETCOMBOCONTROL, 0, 0);
    ok(hCombo != NULL, "Failed to get internal combo\n");
    hEdit = (HWND)SendMessage(hComboEx, CBEM_GETEDITCONTROL, 0, 0);
    ok(hEdit != NULL, "Failed to get internal edit\n");

    if (pSetWindowSubclass)
    {
        ok(GetPropA(hCombo, "CC32SubclassInfo") != NULL, "Expected CC32SubclassInfo property\n");
        ok(GetPropA(hEdit, "CC32SubclassInfo") != NULL, "Expected CC32SubclassInfo property\n");
    }

    DestroyWindow(hComboEx);
}

471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495
static const struct message test_setitem_edit_seq[] = {
    { WM_SETTEXT, sent|id, 0, 0, EDITBOX_ID },
    { EM_SETSEL, sent|id|wparam|lparam, 0,  0, EDITBOX_ID },
    { EM_SETSEL, sent|id|wparam|lparam, 0, -1, EDITBOX_ID },
    { 0 }
};

static void test_get_set_item(void)
{
    char textA[] = "test";
    HWND hComboEx;
    COMBOBOXEXITEMA item;
    BOOL ret;

    hComboEx = createComboEx(WS_BORDER | WS_VISIBLE | WS_CHILD | CBS_DROPDOWN);

    subclass_editbox(hComboEx);

    flush_sequences(sequences, NUM_MSG_SEQUENCES);

    memset(&item, 0, sizeof(item));
    item.mask = CBEIF_TEXT;
    item.pszText = textA;
    item.iItem = -1;
    ret = SendMessage(hComboEx, CBEM_SETITEMA, 0, (LPARAM)&item);
496
    expect(TRUE, ret);
497 498 499

    ok_sequence(sequences, EDITBOX_SEQ_INDEX, test_setitem_edit_seq, "set item data for edit", FALSE);

500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516
    /* get/set lParam */
    item.mask = CBEIF_LPARAM;
    item.iItem = -1;
    item.lParam = 0xdeadbeef;
    ret = SendMessage(hComboEx, CBEM_GETITEMA, 0, (LPARAM)&item);
    expect(TRUE, ret);
    ok(item.lParam == 0, "Expected zero, got %ld\n", item.lParam);

    item.lParam = 0xdeadbeef;
    ret = SendMessage(hComboEx, CBEM_SETITEMA, 0, (LPARAM)&item);
    expect(TRUE, ret);

    item.lParam = 0;
    ret = SendMessage(hComboEx, CBEM_GETITEMA, 0, (LPARAM)&item);
    expect(TRUE, ret);
    ok(item.lParam == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", item.lParam);

517 518 519
    DestroyWindow(hComboEx);
}

520 521
START_TEST(comboex)
{
522 523
    if (!init())
        return;
524

525 526
    init_msg_sequences(sequences, NUM_MSG_SEQUENCES);

527
    test_comboboxex();
528
    test_WM_LBUTTONDOWN();
529
    test_CB_GETLBTEXT();
530
    test_comboboxex_subclass();
531
    test_get_set_item();
532 533 534

    cleanup();
}