10d320bc2SAmine Khaldi /* Unit test suite for ComboBox and ComboBoxEx32 controls.
20d320bc2SAmine Khaldi  *
30d320bc2SAmine Khaldi  * Copyright 2005 Jason Edmeades
40d320bc2SAmine Khaldi  * Copyright 2007 Mikolaj Zalewski
50d320bc2SAmine Khaldi  *
60d320bc2SAmine Khaldi  * This library is free software; you can redistribute it and/or
70d320bc2SAmine Khaldi  * modify it under the terms of the GNU Lesser General Public
80d320bc2SAmine Khaldi  * License as published by the Free Software Foundation; either
90d320bc2SAmine Khaldi  * version 2.1 of the License, or (at your option) any later version.
100d320bc2SAmine Khaldi  *
110d320bc2SAmine Khaldi  * This library is distributed in the hope that it will be useful,
120d320bc2SAmine Khaldi  * but WITHOUT ANY WARRANTY; without even the implied warranty of
130d320bc2SAmine Khaldi  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
140d320bc2SAmine Khaldi  * Lesser General Public License for more details.
150d320bc2SAmine Khaldi  *
160d320bc2SAmine Khaldi  * You should have received a copy of the GNU Lesser General Public
170d320bc2SAmine Khaldi  * License along with this library; if not, write to the Free Software
180d320bc2SAmine Khaldi  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
190d320bc2SAmine Khaldi  */
200d320bc2SAmine Khaldi 
21f37104daSAmine Khaldi #include <limits.h>
22f37104daSAmine Khaldi #include <stdio.h>
23f37104daSAmine Khaldi #include <windows.h>
24f37104daSAmine Khaldi #include <commctrl.h>
25f37104daSAmine Khaldi 
26f37104daSAmine Khaldi #include "wine/test.h"
27f37104daSAmine Khaldi #include "v6util.h"
28f37104daSAmine Khaldi #include "msg.h"
290d320bc2SAmine Khaldi 
30*0707475fSJustin Miller #ifdef __REACTOS__
31*0707475fSJustin Miller #define WM_CTLCOLOR 0x0019
32*0707475fSJustin Miller #endif
33*0707475fSJustin Miller 
340d320bc2SAmine Khaldi #define EDITBOX_SEQ_INDEX  0
350d320bc2SAmine Khaldi #define NUM_MSG_SEQUENCES  1
360d320bc2SAmine Khaldi 
370d320bc2SAmine Khaldi #define EDITBOX_ID         0
380d320bc2SAmine Khaldi #define COMBO_ID           1995
390d320bc2SAmine Khaldi 
400d320bc2SAmine Khaldi #define expect(expected, got) ok(got == expected, "Expected %d, got %d\n", expected, got)
410d320bc2SAmine Khaldi 
420d320bc2SAmine Khaldi #define expect_rect(r, _left, _top, _right, _bottom) ok(r.left == _left && r.top == _top && \
430d320bc2SAmine Khaldi     r.bottom == _bottom && r.right == _right, "Invalid rect %s vs (%d,%d)-(%d,%d)\n", \
440d320bc2SAmine Khaldi     wine_dbgstr_rect(&r), _left, _top, _right, _bottom);
450d320bc2SAmine Khaldi 
460d320bc2SAmine Khaldi 
470d320bc2SAmine Khaldi static struct msg_sequence *sequences[NUM_MSG_SEQUENCES];
480d320bc2SAmine Khaldi 
490d320bc2SAmine Khaldi static HWND hComboExParentWnd, hMainWnd;
500d320bc2SAmine Khaldi static HINSTANCE hMainHinst;
510d320bc2SAmine Khaldi static const char ComboExTestClass[] = "ComboExTestClass";
520d320bc2SAmine Khaldi 
53*0707475fSJustin Miller static HBRUSH brush_red;
54*0707475fSJustin Miller 
550d320bc2SAmine Khaldi static BOOL (WINAPI *pSetWindowSubclass)(HWND, SUBCLASSPROC, UINT_PTR, DWORD_PTR);
560d320bc2SAmine Khaldi 
570d320bc2SAmine Khaldi #define MAX_CHARS 100
580d320bc2SAmine Khaldi static char *textBuffer = NULL;
590d320bc2SAmine Khaldi 
600d320bc2SAmine Khaldi static BOOL received_end_edit = FALSE;
610d320bc2SAmine Khaldi 
get_combobox_info(HWND hwnd,COMBOBOXINFO * info)620d320bc2SAmine Khaldi static void get_combobox_info(HWND hwnd, COMBOBOXINFO *info)
630d320bc2SAmine Khaldi {
640d320bc2SAmine Khaldi     BOOL ret;
650d320bc2SAmine Khaldi 
660d320bc2SAmine Khaldi     info->cbSize = sizeof(*info);
670d320bc2SAmine Khaldi     ret = GetComboBoxInfo(hwnd, info);
680d320bc2SAmine Khaldi     ok(ret, "Failed to get combobox info structure, error %d\n", GetLastError());
690d320bc2SAmine Khaldi }
700d320bc2SAmine Khaldi 
createComboEx(DWORD style)710d320bc2SAmine Khaldi static HWND createComboEx(DWORD style) {
720d320bc2SAmine Khaldi    return CreateWindowExA(0, WC_COMBOBOXEXA, NULL, style, 0, 0, 300, 300,
730d320bc2SAmine Khaldi             hComboExParentWnd, NULL, hMainHinst, NULL);
740d320bc2SAmine Khaldi }
750d320bc2SAmine Khaldi 
addItem(HWND cbex,int idx,const char * text)760d320bc2SAmine Khaldi static LONG addItem(HWND cbex, int idx, const char *text) {
770d320bc2SAmine Khaldi     COMBOBOXEXITEMA cbexItem;
780d320bc2SAmine Khaldi     memset(&cbexItem, 0x00, sizeof(cbexItem));
790d320bc2SAmine Khaldi     cbexItem.mask = CBEIF_TEXT;
800d320bc2SAmine Khaldi     cbexItem.iItem = idx;
810d320bc2SAmine Khaldi     cbexItem.pszText    = (char*)text;
820d320bc2SAmine Khaldi     cbexItem.cchTextMax = 0;
830d320bc2SAmine Khaldi     return SendMessageA(cbex, CBEM_INSERTITEMA, 0, (LPARAM)&cbexItem);
840d320bc2SAmine Khaldi }
850d320bc2SAmine Khaldi 
setItem(HWND cbex,int idx,const char * text)860d320bc2SAmine Khaldi static LONG setItem(HWND cbex, int idx, const char *text) {
870d320bc2SAmine Khaldi     COMBOBOXEXITEMA cbexItem;
880d320bc2SAmine Khaldi     memset(&cbexItem, 0x00, sizeof(cbexItem));
890d320bc2SAmine Khaldi     cbexItem.mask = CBEIF_TEXT;
900d320bc2SAmine Khaldi     cbexItem.iItem = idx;
910d320bc2SAmine Khaldi     cbexItem.pszText    = (char*)text;
920d320bc2SAmine Khaldi     cbexItem.cchTextMax = 0;
930d320bc2SAmine Khaldi     return SendMessageA(cbex, CBEM_SETITEMA, 0, (LPARAM)&cbexItem);
940d320bc2SAmine Khaldi }
950d320bc2SAmine Khaldi 
delItem(HWND cbex,int idx)960d320bc2SAmine Khaldi static LONG delItem(HWND cbex, int idx) {
970d320bc2SAmine Khaldi     return SendMessageA(cbex, CBEM_DELETEITEM, idx, 0);
980d320bc2SAmine Khaldi }
990d320bc2SAmine Khaldi 
getItem(HWND cbex,int idx,COMBOBOXEXITEMA * cbItem)1000d320bc2SAmine Khaldi static LONG getItem(HWND cbex, int idx, COMBOBOXEXITEMA *cbItem) {
1010d320bc2SAmine Khaldi     memset(cbItem, 0x00, sizeof(COMBOBOXEXITEMA));
1020d320bc2SAmine Khaldi     cbItem->mask = CBEIF_TEXT;
1030d320bc2SAmine Khaldi     cbItem->pszText      = textBuffer;
1040d320bc2SAmine Khaldi     cbItem->iItem        = idx;
1050d320bc2SAmine Khaldi     cbItem->cchTextMax   = 100;
1060d320bc2SAmine Khaldi     return SendMessageA(cbex, CBEM_GETITEMA, 0, (LPARAM)cbItem);
1070d320bc2SAmine Khaldi }
1080d320bc2SAmine Khaldi 
editbox_subclass_proc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)1090d320bc2SAmine Khaldi static LRESULT WINAPI editbox_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
1100d320bc2SAmine Khaldi {
1110d320bc2SAmine Khaldi     WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
1120d320bc2SAmine Khaldi     static LONG defwndproc_counter = 0;
1130d320bc2SAmine Khaldi     struct message msg = { 0 };
1140d320bc2SAmine Khaldi     LRESULT ret;
1150d320bc2SAmine Khaldi 
1160d320bc2SAmine Khaldi     msg.message = message;
1170d320bc2SAmine Khaldi     msg.flags = sent|wparam|lparam;
1180d320bc2SAmine Khaldi     if (defwndproc_counter) msg.flags |= defwinproc;
1190d320bc2SAmine Khaldi     msg.wParam = wParam;
1200d320bc2SAmine Khaldi     msg.lParam = lParam;
1210d320bc2SAmine Khaldi     msg.id     = EDITBOX_ID;
1220d320bc2SAmine Khaldi 
1230d320bc2SAmine Khaldi     if (message != WM_PAINT &&
1240d320bc2SAmine Khaldi         message != WM_ERASEBKGND &&
1250d320bc2SAmine Khaldi         message != WM_NCPAINT &&
1260d320bc2SAmine Khaldi         message != WM_NCHITTEST &&
1270d320bc2SAmine Khaldi         message != WM_GETTEXT &&
1280d320bc2SAmine Khaldi         message != WM_GETICON &&
1290d320bc2SAmine Khaldi         message != WM_DEVICECHANGE)
1300d320bc2SAmine Khaldi     {
1310d320bc2SAmine Khaldi         add_message(sequences, EDITBOX_SEQ_INDEX, &msg);
1320d320bc2SAmine Khaldi     }
1330d320bc2SAmine Khaldi 
1340d320bc2SAmine Khaldi     defwndproc_counter++;
1350d320bc2SAmine Khaldi     ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam);
1360d320bc2SAmine Khaldi     defwndproc_counter--;
1370d320bc2SAmine Khaldi     return ret;
1380d320bc2SAmine Khaldi }
1390d320bc2SAmine Khaldi 
subclass_editbox(HWND hwndComboEx)1400d320bc2SAmine Khaldi static HWND subclass_editbox(HWND hwndComboEx)
1410d320bc2SAmine Khaldi {
1420d320bc2SAmine Khaldi     WNDPROC oldproc;
1430d320bc2SAmine Khaldi     HWND hwnd;
1440d320bc2SAmine Khaldi 
1450d320bc2SAmine Khaldi     hwnd = (HWND)SendMessageA(hwndComboEx, CBEM_GETEDITCONTROL, 0, 0);
1460d320bc2SAmine Khaldi     oldproc = (WNDPROC)SetWindowLongPtrA(hwnd, GWLP_WNDPROC,
1470d320bc2SAmine Khaldi                                          (LONG_PTR)editbox_subclass_proc);
1480d320bc2SAmine Khaldi     SetWindowLongPtrA(hwnd, GWLP_USERDATA, (LONG_PTR)oldproc);
1490d320bc2SAmine Khaldi 
1500d320bc2SAmine Khaldi     return hwnd;
1510d320bc2SAmine Khaldi }
1520d320bc2SAmine Khaldi 
test_comboex(void)1530d320bc2SAmine Khaldi static void test_comboex(void)
1540d320bc2SAmine Khaldi {
1550d320bc2SAmine Khaldi     HWND myHwnd = 0;
1560d320bc2SAmine Khaldi     LONG res;
1570d320bc2SAmine Khaldi     COMBOBOXEXITEMA cbexItem;
1580d320bc2SAmine Khaldi     static const char *first_item  = "First Item",
1590d320bc2SAmine Khaldi                 *second_item = "Second Item",
1600d320bc2SAmine Khaldi                 *third_item  = "Third Item",
1610d320bc2SAmine Khaldi                 *middle_item = "Between First and Second Items",
1620d320bc2SAmine Khaldi                 *replacement_item = "Between First and Second Items",
1630d320bc2SAmine Khaldi                 *out_of_range_item = "Out of Range Item";
1640d320bc2SAmine Khaldi 
1650d320bc2SAmine Khaldi     /* Allocate space for result */
166f37104daSAmine Khaldi     textBuffer = heap_alloc(MAX_CHARS);
1670d320bc2SAmine Khaldi 
1680d320bc2SAmine Khaldi     /* Basic comboboxex test */
1690d320bc2SAmine Khaldi     myHwnd = createComboEx(WS_BORDER | WS_VISIBLE | WS_CHILD | CBS_DROPDOWN);
1700d320bc2SAmine Khaldi 
1710d320bc2SAmine Khaldi     /* Add items onto the end of the combobox */
1720d320bc2SAmine Khaldi     res = addItem(myHwnd, -1, first_item);
1730d320bc2SAmine Khaldi     ok(res == 0, "Adding simple item failed (%d)\n", res);
1740d320bc2SAmine Khaldi     res = addItem(myHwnd, -1, second_item);
1750d320bc2SAmine Khaldi     ok(res == 1, "Adding simple item failed (%d)\n", res);
1760d320bc2SAmine Khaldi     res = addItem(myHwnd, 2, third_item);
1770d320bc2SAmine Khaldi     ok(res == 2, "Adding simple item failed (%d)\n", res);
1780d320bc2SAmine Khaldi     res = addItem(myHwnd, 1, middle_item);
1790d320bc2SAmine Khaldi     ok(res == 1, "Inserting simple item failed (%d)\n", res);
1800d320bc2SAmine Khaldi 
1810d320bc2SAmine Khaldi     /* Add an item completely out of range */
1820d320bc2SAmine Khaldi     res = addItem(myHwnd, 99, out_of_range_item);
1830d320bc2SAmine Khaldi     ok(res == -1, "Adding using out of range index worked unexpectedly (%d)\n", res);
1840d320bc2SAmine Khaldi     res = addItem(myHwnd, 5, out_of_range_item);
1850d320bc2SAmine Khaldi     ok(res == -1, "Adding using out of range index worked unexpectedly (%d)\n", res);
1860d320bc2SAmine Khaldi     /* Removed: Causes traps on Windows XP
1870d320bc2SAmine Khaldi        res = addItem(myHwnd, -2, "Out Of Range Item");
1880d320bc2SAmine Khaldi        ok(res == -1, "Adding out of range worked unexpectedly (%ld)\n", res);
1890d320bc2SAmine Khaldi      */
1900d320bc2SAmine Khaldi 
1910d320bc2SAmine Khaldi     /* Get an item completely out of range */
1920d320bc2SAmine Khaldi     res = getItem(myHwnd, 99, &cbexItem);
1930d320bc2SAmine Khaldi     ok(res == 0, "Getting item using out of range index worked unexpectedly (%d, %s)\n", res, cbexItem.pszText);
1940d320bc2SAmine Khaldi     res = getItem(myHwnd, 4, &cbexItem);
1950d320bc2SAmine Khaldi     ok(res == 0, "Getting item using out of range index worked unexpectedly (%d, %s)\n", res, cbexItem.pszText);
1960d320bc2SAmine Khaldi     res = getItem(myHwnd, -2, &cbexItem);
1970d320bc2SAmine Khaldi     ok(res == 0, "Getting item using out of range index worked unexpectedly (%d, %s)\n", res, cbexItem.pszText);
1980d320bc2SAmine Khaldi 
1990d320bc2SAmine Khaldi     /* Get an item in range */
2000d320bc2SAmine Khaldi     res = getItem(myHwnd, 0, &cbexItem);
2010d320bc2SAmine Khaldi     ok(res != 0, "Getting item using valid index failed unexpectedly (%d)\n", res);
2020d320bc2SAmine Khaldi     ok(strcmp(first_item, cbexItem.pszText) == 0, "Getting item returned wrong string (%s)\n", cbexItem.pszText);
2030d320bc2SAmine Khaldi 
2040d320bc2SAmine Khaldi     res = getItem(myHwnd, 1, &cbexItem);
2050d320bc2SAmine Khaldi     ok(res != 0, "Getting item using valid index failed unexpectedly (%d)\n", res);
2060d320bc2SAmine Khaldi     ok(strcmp(middle_item, cbexItem.pszText) == 0, "Getting item returned wrong string (%s)\n", cbexItem.pszText);
2070d320bc2SAmine Khaldi 
2080d320bc2SAmine Khaldi     res = getItem(myHwnd, 2, &cbexItem);
2090d320bc2SAmine Khaldi     ok(res != 0, "Getting item using valid index failed unexpectedly (%d)\n", res);
2100d320bc2SAmine Khaldi     ok(strcmp(second_item, cbexItem.pszText) == 0, "Getting item returned wrong string (%s)\n", cbexItem.pszText);
2110d320bc2SAmine Khaldi 
2120d320bc2SAmine Khaldi     res = getItem(myHwnd, 3, &cbexItem);
2130d320bc2SAmine Khaldi     ok(res != 0, "Getting item using valid index failed unexpectedly (%d)\n", res);
2140d320bc2SAmine Khaldi     ok(strcmp(third_item, cbexItem.pszText) == 0, "Getting item returned wrong string (%s)\n", cbexItem.pszText);
2150d320bc2SAmine Khaldi 
2160d320bc2SAmine Khaldi     /* Set an item completely out of range */
2170d320bc2SAmine Khaldi     res = setItem(myHwnd, 99, replacement_item);
2180d320bc2SAmine Khaldi     ok(res == 0, "Setting item using out of range index worked unexpectedly (%d)\n", res);
2190d320bc2SAmine Khaldi     res = setItem(myHwnd, 4, replacement_item);
2200d320bc2SAmine Khaldi     ok(res == 0, "Setting item using out of range index worked unexpectedly (%d)\n", res);
2210d320bc2SAmine Khaldi     res = setItem(myHwnd, -2, replacement_item);
2220d320bc2SAmine Khaldi     ok(res == 0, "Setting item using out of range index worked unexpectedly (%d)\n", res);
2230d320bc2SAmine Khaldi 
2240d320bc2SAmine Khaldi     /* Set an item in range */
2250d320bc2SAmine Khaldi     res = setItem(myHwnd, 0, replacement_item);
2260d320bc2SAmine Khaldi     ok(res != 0, "Setting first item failed (%d)\n", res);
2270d320bc2SAmine Khaldi     res = setItem(myHwnd, 3, replacement_item);
2280d320bc2SAmine Khaldi     ok(res != 0, "Setting last item failed (%d)\n", res);
2290d320bc2SAmine Khaldi 
2300d320bc2SAmine Khaldi     /* Remove items completely out of range (4 items in control at this point) */
2310d320bc2SAmine Khaldi     res = delItem(myHwnd, -1);
2320d320bc2SAmine Khaldi     ok(res == CB_ERR, "Deleting using out of range index worked unexpectedly (%d)\n", res);
2330d320bc2SAmine Khaldi     res = delItem(myHwnd, 4);
2340d320bc2SAmine Khaldi     ok(res == CB_ERR, "Deleting using out of range index worked unexpectedly (%d)\n", res);
2350d320bc2SAmine Khaldi 
2360d320bc2SAmine Khaldi     /* Remove items in range (4 items in control at this point) */
2370d320bc2SAmine Khaldi     res = delItem(myHwnd, 3);
2380d320bc2SAmine Khaldi     ok(res == 3, "Deleting using out of range index failed (%d)\n", res);
2390d320bc2SAmine Khaldi     res = delItem(myHwnd, 0);
2400d320bc2SAmine Khaldi     ok(res == 2, "Deleting using out of range index failed (%d)\n", res);
2410d320bc2SAmine Khaldi     res = delItem(myHwnd, 0);
2420d320bc2SAmine Khaldi     ok(res == 1, "Deleting using out of range index failed (%d)\n", res);
2430d320bc2SAmine Khaldi     res = delItem(myHwnd, 0);
2440d320bc2SAmine Khaldi     ok(res == 0, "Deleting using out of range index failed (%d)\n", res);
2450d320bc2SAmine Khaldi 
2460d320bc2SAmine Khaldi     /* Remove from an empty box */
2470d320bc2SAmine Khaldi     res = delItem(myHwnd, 0);
2480d320bc2SAmine Khaldi     ok(res == CB_ERR, "Deleting using out of range index worked unexpectedly (%d)\n", res);
2490d320bc2SAmine Khaldi 
2500d320bc2SAmine Khaldi 
2510d320bc2SAmine Khaldi     /* Cleanup */
252f37104daSAmine Khaldi     heap_free(textBuffer);
2530d320bc2SAmine Khaldi     DestroyWindow(myHwnd);
2540d320bc2SAmine Khaldi }
2550d320bc2SAmine Khaldi 
test_comboex_WM_LBUTTONDOWN(void)2560d320bc2SAmine Khaldi static void test_comboex_WM_LBUTTONDOWN(void)
2570d320bc2SAmine Khaldi {
2580d320bc2SAmine Khaldi     HWND hComboEx, hCombo, hEdit, hList;
2590d320bc2SAmine Khaldi     COMBOBOXINFO cbInfo;
2600d320bc2SAmine Khaldi     UINT x, y, item_height;
2610d320bc2SAmine Khaldi     LRESULT result;
2620d320bc2SAmine Khaldi     UINT i;
2630d320bc2SAmine Khaldi     int idx;
2640d320bc2SAmine Khaldi     RECT rect;
2650d320bc2SAmine Khaldi     WCHAR buffer[3];
2660d320bc2SAmine Khaldi     static const UINT choices[] = {8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72};
2670d320bc2SAmine Khaldi     static const WCHAR stringFormat[] = {'%','2','d','\0'};
2680d320bc2SAmine Khaldi 
2690d320bc2SAmine Khaldi     hComboEx = CreateWindowExA(0, WC_COMBOBOXEXA, NULL,
2700d320bc2SAmine Khaldi             WS_VISIBLE|WS_CHILD|CBS_DROPDOWN, 0, 0, 200, 150,
2710d320bc2SAmine Khaldi             hComboExParentWnd, NULL, hMainHinst, NULL);
2720d320bc2SAmine Khaldi 
2735f7243b5SAmine Khaldi     for (i = 0; i < ARRAY_SIZE(choices); i++){
2740d320bc2SAmine Khaldi         COMBOBOXEXITEMW cbexItem;
2750d320bc2SAmine Khaldi         wsprintfW(buffer, stringFormat, choices[i]);
2760d320bc2SAmine Khaldi 
2770d320bc2SAmine Khaldi         memset(&cbexItem, 0x00, sizeof(cbexItem));
2780d320bc2SAmine Khaldi         cbexItem.mask = CBEIF_TEXT;
2790d320bc2SAmine Khaldi         cbexItem.iItem = i;
2800d320bc2SAmine Khaldi         cbexItem.pszText = buffer;
2810d320bc2SAmine Khaldi         cbexItem.cchTextMax = 0;
2820d320bc2SAmine Khaldi         ok(SendMessageW(hComboEx, CBEM_INSERTITEMW, 0, (LPARAM)&cbexItem) >= 0,
2830d320bc2SAmine Khaldi            "Failed to add item %d\n", i);
2840d320bc2SAmine Khaldi     }
2850d320bc2SAmine Khaldi 
2860d320bc2SAmine Khaldi     hCombo = (HWND)SendMessageA(hComboEx, CBEM_GETCOMBOCONTROL, 0, 0);
2870d320bc2SAmine Khaldi     hEdit = (HWND)SendMessageA(hComboEx, CBEM_GETEDITCONTROL, 0, 0);
2880d320bc2SAmine Khaldi 
2890d320bc2SAmine Khaldi     get_combobox_info(hCombo, &cbInfo);
2900d320bc2SAmine Khaldi     hList = cbInfo.hwndList;
2910d320bc2SAmine Khaldi 
2920d320bc2SAmine Khaldi     ok(GetFocus() == hComboExParentWnd,
2930d320bc2SAmine Khaldi        "Focus not on Main Window, instead on %p\n", GetFocus());
2940d320bc2SAmine Khaldi 
2950d320bc2SAmine Khaldi     /* Click on the button to drop down the list */
2960d320bc2SAmine Khaldi     x = cbInfo.rcButton.left + (cbInfo.rcButton.right-cbInfo.rcButton.left)/2;
2970d320bc2SAmine Khaldi     y = cbInfo.rcButton.top + (cbInfo.rcButton.bottom-cbInfo.rcButton.top)/2;
2980d320bc2SAmine Khaldi     result = SendMessageA(hCombo, WM_LBUTTONDOWN, 0, MAKELPARAM(x, y));
2990d320bc2SAmine Khaldi     ok(result, "WM_LBUTTONDOWN was not processed. LastError=%d\n",
3000d320bc2SAmine Khaldi        GetLastError());
3010d320bc2SAmine Khaldi     ok(GetFocus() == hCombo ||
3020d320bc2SAmine Khaldi        broken(GetFocus() != hCombo), /* win98 */
3030d320bc2SAmine Khaldi        "Focus not on ComboBoxEx's ComboBox Control, instead on %p\n",
3040d320bc2SAmine Khaldi        GetFocus());
3050d320bc2SAmine Khaldi     ok(SendMessageA(hComboEx, CB_GETDROPPEDSTATE, 0, 0),
3060d320bc2SAmine Khaldi        "The dropdown list should have appeared after clicking the button.\n");
3070d320bc2SAmine Khaldi     idx = SendMessageA(hCombo, CB_GETTOPINDEX, 0, 0);
3080d320bc2SAmine Khaldi     ok(idx == 0, "For TopIndex expected %d, got %d\n", 0, idx);
3090d320bc2SAmine Khaldi 
3100d320bc2SAmine Khaldi     result = SendMessageA(hCombo, WM_LBUTTONUP, 0, MAKELPARAM(x, y));
3110d320bc2SAmine Khaldi     ok(result, "WM_LBUTTONUP was not processed. LastError=%d\n",
3120d320bc2SAmine Khaldi        GetLastError());
3130d320bc2SAmine Khaldi     ok(GetFocus() == hCombo ||
3140d320bc2SAmine Khaldi        broken(GetFocus() != hCombo), /* win98 */
3150d320bc2SAmine Khaldi        "Focus not on ComboBoxEx's ComboBox Control, instead on %p\n",
3160d320bc2SAmine Khaldi        GetFocus());
3170d320bc2SAmine Khaldi 
3180d320bc2SAmine Khaldi     /* Click on the 5th item in the list */
3190d320bc2SAmine Khaldi     item_height = SendMessageA(hCombo, CB_GETITEMHEIGHT, 0, 0);
3200d320bc2SAmine Khaldi     ok(GetClientRect(hList, &rect), "Failed to get list's client rect.\n");
3210d320bc2SAmine Khaldi     x = rect.left + (rect.right-rect.left)/2;
3220d320bc2SAmine Khaldi     y = item_height/2 + item_height*4;
3230d320bc2SAmine Khaldi     result = SendMessageA(hList, WM_MOUSEMOVE, 0, MAKELPARAM(x, y));
3240d320bc2SAmine Khaldi     ok(!result, "WM_MOUSEMOVE was not processed. LastError=%d\n",
3250d320bc2SAmine Khaldi        GetLastError());
3260d320bc2SAmine Khaldi     ok(GetFocus() == hCombo ||
3270d320bc2SAmine Khaldi        broken(GetFocus() != hCombo), /* win98 */
3280d320bc2SAmine Khaldi        "Focus not on ComboBoxEx's ComboBox Control, instead on %p\n",
3290d320bc2SAmine Khaldi        GetFocus());
3300d320bc2SAmine Khaldi 
3310d320bc2SAmine Khaldi     result = SendMessageA(hList, WM_LBUTTONDOWN, 0, MAKELPARAM(x, y));
3320d320bc2SAmine Khaldi     ok(!result, "WM_LBUTTONDOWN was not processed. LastError=%d\n",
3330d320bc2SAmine Khaldi        GetLastError());
3340d320bc2SAmine Khaldi     ok(GetFocus() == hCombo ||
3350d320bc2SAmine Khaldi        broken(GetFocus() != hCombo), /* win98 */
3360d320bc2SAmine Khaldi        "Focus not on ComboBoxEx's ComboBox Control, instead on %p\n",
3370d320bc2SAmine Khaldi        GetFocus());
3380d320bc2SAmine Khaldi     ok(SendMessageA(hComboEx, CB_GETDROPPEDSTATE, 0, 0),
3390d320bc2SAmine Khaldi        "The dropdown list should still be visible.\n");
3400d320bc2SAmine Khaldi 
3410d320bc2SAmine Khaldi     result = SendMessageA(hList, WM_LBUTTONUP, 0, MAKELPARAM(x, y));
3420d320bc2SAmine Khaldi     ok(!result, "WM_LBUTTONUP was not processed. LastError=%d\n",
3430d320bc2SAmine Khaldi        GetLastError());
3440d320bc2SAmine Khaldi     todo_wine ok(GetFocus() == hEdit ||
3450d320bc2SAmine Khaldi        broken(GetFocus() == hCombo), /* win98 */
3460d320bc2SAmine Khaldi        "Focus not on ComboBoxEx's Edit Control, instead on %p\n",
3470d320bc2SAmine Khaldi        GetFocus());
3480d320bc2SAmine Khaldi 
3490d320bc2SAmine Khaldi     result = SendMessageA(hCombo, CB_GETDROPPEDSTATE, 0, 0);
3500d320bc2SAmine Khaldi     ok(!result ||
3510d320bc2SAmine Khaldi        broken(result != 0), /* win98 */
3520d320bc2SAmine Khaldi        "The dropdown list should have been rolled up.\n");
3530d320bc2SAmine Khaldi     idx = SendMessageA(hComboEx, CB_GETCURSEL, 0, 0);
3540d320bc2SAmine Khaldi     ok(idx == 4 ||
3550d320bc2SAmine Khaldi        broken(idx == -1), /* win98 */
3560d320bc2SAmine Khaldi        "Current Selection: expected %d, got %d\n", 4, idx);
3570d320bc2SAmine Khaldi     ok(received_end_edit, "Expected to receive a CBEN_ENDEDIT message\n");
3580d320bc2SAmine Khaldi 
3590d320bc2SAmine Khaldi     SetFocus( hComboExParentWnd );
3600d320bc2SAmine Khaldi     ok( GetFocus() == hComboExParentWnd, "got %p\n", GetFocus() );
3610d320bc2SAmine Khaldi     SetFocus( hComboEx );
3620d320bc2SAmine Khaldi     ok( GetFocus() == hEdit, "got %p\n", GetFocus() );
3630d320bc2SAmine Khaldi 
3640d320bc2SAmine Khaldi     DestroyWindow(hComboEx);
3650d320bc2SAmine Khaldi }
3660d320bc2SAmine Khaldi 
test_comboex_CB_GETLBTEXT(void)3670d320bc2SAmine Khaldi static void test_comboex_CB_GETLBTEXT(void)
3680d320bc2SAmine Khaldi {
3690d320bc2SAmine Khaldi     HWND hCombo;
3700d320bc2SAmine Khaldi     CHAR buff[1];
3710d320bc2SAmine Khaldi     COMBOBOXEXITEMA item;
3720d320bc2SAmine Khaldi     LRESULT ret;
3730d320bc2SAmine Khaldi 
3740d320bc2SAmine Khaldi     hCombo = createComboEx(WS_BORDER | WS_VISIBLE | WS_CHILD | CBS_DROPDOWN);
3750d320bc2SAmine Khaldi 
3760d320bc2SAmine Khaldi     /* set text to null */
3770d320bc2SAmine Khaldi     addItem(hCombo, 0, NULL);
3780d320bc2SAmine Khaldi 
3790d320bc2SAmine Khaldi     buff[0] = 'a';
3800d320bc2SAmine Khaldi     item.mask = CBEIF_TEXT;
3810d320bc2SAmine Khaldi     item.iItem = 0;
3820d320bc2SAmine Khaldi     item.pszText = buff;
3830d320bc2SAmine Khaldi     item.cchTextMax = 1;
3840d320bc2SAmine Khaldi     ret = SendMessageA(hCombo, CBEM_GETITEMA, 0, (LPARAM)&item);
3850d320bc2SAmine Khaldi     ok(ret != 0, "CBEM_GETITEM failed\n");
3860d320bc2SAmine Khaldi     ok(buff[0] == 0, "\n");
3870d320bc2SAmine Khaldi 
3880d320bc2SAmine Khaldi     ret = SendMessageA(hCombo, CB_GETLBTEXTLEN, 0, 0);
3890d320bc2SAmine Khaldi     ok(ret == 0, "Expected zero length\n");
3900d320bc2SAmine Khaldi 
3910d320bc2SAmine Khaldi     ret = SendMessageA(hCombo, CB_GETLBTEXTLEN, 0, 0);
3920d320bc2SAmine Khaldi     ok(ret == 0, "Expected zero length\n");
3930d320bc2SAmine Khaldi 
3940d320bc2SAmine Khaldi     buff[0] = 'a';
3950d320bc2SAmine Khaldi     ret = SendMessageA(hCombo, CB_GETLBTEXT, 0, (LPARAM)buff);
3960d320bc2SAmine Khaldi     ok(ret == 0, "Expected zero length\n");
3970d320bc2SAmine Khaldi     ok(buff[0] == 0, "Expected null terminator as a string, got %s\n", buff);
3980d320bc2SAmine Khaldi 
3990d320bc2SAmine Khaldi     DestroyWindow(hCombo);
4000d320bc2SAmine Khaldi }
4010d320bc2SAmine Khaldi 
test_comboex_WM_WINDOWPOSCHANGING(void)4020d320bc2SAmine Khaldi static void test_comboex_WM_WINDOWPOSCHANGING(void)
4030d320bc2SAmine Khaldi {
4040d320bc2SAmine Khaldi     HWND hCombo;
4050d320bc2SAmine Khaldi     WINDOWPOS wp;
4060d320bc2SAmine Khaldi     RECT rect;
4070d320bc2SAmine Khaldi     int combo_height;
4080d320bc2SAmine Khaldi     int ret;
4090d320bc2SAmine Khaldi 
4100d320bc2SAmine Khaldi     hCombo = createComboEx(WS_BORDER | WS_VISIBLE | WS_CHILD | CBS_DROPDOWN);
4110d320bc2SAmine Khaldi     ok(hCombo != NULL, "createComboEx failed\n");
4120d320bc2SAmine Khaldi     ret = GetWindowRect(hCombo, &rect);
4130d320bc2SAmine Khaldi     ok(ret, "GetWindowRect failed\n");
4140d320bc2SAmine Khaldi     combo_height = rect.bottom - rect.top;
4150d320bc2SAmine Khaldi     ok(combo_height > 0, "wrong combo height\n");
4160d320bc2SAmine Khaldi 
4170d320bc2SAmine Khaldi     /* Test height > combo_height */
4180d320bc2SAmine Khaldi     wp.x = rect.left;
4190d320bc2SAmine Khaldi     wp.y = rect.top;
4200d320bc2SAmine Khaldi     wp.cx = (rect.right - rect.left);
4210d320bc2SAmine Khaldi     wp.cy = combo_height * 2;
4220d320bc2SAmine Khaldi     wp.flags = 0;
4230d320bc2SAmine Khaldi     wp.hwnd = hCombo;
4240d320bc2SAmine Khaldi     wp.hwndInsertAfter = NULL;
4250d320bc2SAmine Khaldi 
4260d320bc2SAmine Khaldi     ret = SendMessageA(hCombo, WM_WINDOWPOSCHANGING, 0, (LPARAM)&wp);
4270d320bc2SAmine Khaldi     ok(ret == 0, "expected 0, got %x\n", ret);
4280d320bc2SAmine Khaldi     ok(wp.cy == combo_height,
4290d320bc2SAmine Khaldi             "Expected height %d, got %d\n", combo_height, wp.cy);
4300d320bc2SAmine Khaldi 
4310d320bc2SAmine Khaldi     /* Test height < combo_height */
4320d320bc2SAmine Khaldi     wp.x = rect.left;
4330d320bc2SAmine Khaldi     wp.y = rect.top;
4340d320bc2SAmine Khaldi     wp.cx = (rect.right - rect.left);
4350d320bc2SAmine Khaldi     wp.cy = combo_height / 2;
4360d320bc2SAmine Khaldi     wp.flags = 0;
4370d320bc2SAmine Khaldi     wp.hwnd = hCombo;
4380d320bc2SAmine Khaldi     wp.hwndInsertAfter = NULL;
4390d320bc2SAmine Khaldi 
4400d320bc2SAmine Khaldi     ret = SendMessageA(hCombo, WM_WINDOWPOSCHANGING, 0, (LPARAM)&wp);
4410d320bc2SAmine Khaldi     ok(ret == 0, "expected 0, got %x\n", ret);
4420d320bc2SAmine Khaldi     ok(wp.cy == combo_height,
4430d320bc2SAmine Khaldi             "Expected height %d, got %d\n", combo_height, wp.cy);
4440d320bc2SAmine Khaldi 
4450d320bc2SAmine Khaldi     ret = DestroyWindow(hCombo);
4460d320bc2SAmine Khaldi     ok(ret, "DestroyWindow failed\n");
4470d320bc2SAmine Khaldi }
4480d320bc2SAmine Khaldi 
ComboExTestOnNotify(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)4490d320bc2SAmine Khaldi static LRESULT ComboExTestOnNotify(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
4500d320bc2SAmine Khaldi {
4510d320bc2SAmine Khaldi     NMHDR *hdr = (NMHDR*)lParam;
4520d320bc2SAmine Khaldi     switch(hdr->code){
4530d320bc2SAmine Khaldi     case CBEN_ENDEDITA:
4540d320bc2SAmine Khaldi         {
4550d320bc2SAmine Khaldi             NMCBEENDEDITA *edit_info = (NMCBEENDEDITA*)hdr;
4560d320bc2SAmine Khaldi             if(edit_info->iWhy==CBENF_DROPDOWN){
4570d320bc2SAmine Khaldi                 received_end_edit = TRUE;
4580d320bc2SAmine Khaldi             }
4590d320bc2SAmine Khaldi             break;
4600d320bc2SAmine Khaldi         }
4610d320bc2SAmine Khaldi     case CBEN_ENDEDITW:
4620d320bc2SAmine Khaldi         {
4630d320bc2SAmine Khaldi             NMCBEENDEDITW *edit_info = (NMCBEENDEDITW*)hdr;
4640d320bc2SAmine Khaldi             if(edit_info->iWhy==CBENF_DROPDOWN){
4650d320bc2SAmine Khaldi                 received_end_edit = TRUE;
4660d320bc2SAmine Khaldi             }
4670d320bc2SAmine Khaldi             break;
4680d320bc2SAmine Khaldi         }
4690d320bc2SAmine Khaldi     }
4700d320bc2SAmine Khaldi     return 0;
4710d320bc2SAmine Khaldi }
4720d320bc2SAmine Khaldi 
ComboExTestWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)4730d320bc2SAmine Khaldi static LRESULT CALLBACK ComboExTestWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
4740d320bc2SAmine Khaldi {
4750d320bc2SAmine Khaldi     switch(msg) {
4760d320bc2SAmine Khaldi 
4770d320bc2SAmine Khaldi     case WM_DESTROY:
4780d320bc2SAmine Khaldi         PostQuitMessage(0);
4790d320bc2SAmine Khaldi         break;
4800d320bc2SAmine Khaldi     case WM_NOTIFY:
4810d320bc2SAmine Khaldi         return ComboExTestOnNotify(hWnd,msg,wParam,lParam);
4820d320bc2SAmine Khaldi     default:
4830d320bc2SAmine Khaldi         return DefWindowProcA(hWnd, msg, wParam, lParam);
4840d320bc2SAmine Khaldi     }
4850d320bc2SAmine Khaldi 
4860d320bc2SAmine Khaldi     return 0L;
4870d320bc2SAmine Khaldi }
4880d320bc2SAmine Khaldi 
init_functions(void)489f37104daSAmine Khaldi static void init_functions(void)
490f37104daSAmine Khaldi {
491f37104daSAmine Khaldi     HMODULE hComCtl32 = LoadLibraryA("comctl32.dll");
492f37104daSAmine Khaldi 
493f37104daSAmine Khaldi #define X(f) p##f = (void*)GetProcAddress(hComCtl32, #f);
494f37104daSAmine Khaldi #define X2(f, ord) p##f = (void*)GetProcAddress(hComCtl32, (const char *)ord);
495f37104daSAmine Khaldi     X2(SetWindowSubclass, 410);
496f37104daSAmine Khaldi #undef X
497f37104daSAmine Khaldi #undef X2
498f37104daSAmine Khaldi }
499f37104daSAmine Khaldi 
init(void)5000d320bc2SAmine Khaldi static BOOL init(void)
5010d320bc2SAmine Khaldi {
5020d320bc2SAmine Khaldi     WNDCLASSA wc;
5030d320bc2SAmine Khaldi 
5040d320bc2SAmine Khaldi     wc.style = CS_HREDRAW | CS_VREDRAW;
5050d320bc2SAmine Khaldi     wc.cbClsExtra = 0;
5060d320bc2SAmine Khaldi     wc.cbWndExtra = 0;
5070d320bc2SAmine Khaldi     wc.hInstance = GetModuleHandleA(NULL);
5080d320bc2SAmine Khaldi     wc.hIcon = NULL;
5090d320bc2SAmine Khaldi     wc.hCursor = LoadCursorA(NULL, (LPCSTR)IDC_ARROW);
5100d320bc2SAmine Khaldi     wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW);
5110d320bc2SAmine Khaldi     wc.lpszMenuName = NULL;
5120d320bc2SAmine Khaldi     wc.lpszClassName = ComboExTestClass;
5130d320bc2SAmine Khaldi     wc.lpfnWndProc = ComboExTestWndProc;
5140d320bc2SAmine Khaldi     RegisterClassA(&wc);
5150d320bc2SAmine Khaldi 
516*0707475fSJustin Miller     brush_red = CreateSolidBrush(RGB(255, 0, 0));
517*0707475fSJustin Miller 
518f37104daSAmine Khaldi     hMainWnd = CreateWindowA(WC_STATICA, "Test", WS_OVERLAPPEDWINDOW, 10, 10, 300, 300, NULL, NULL, NULL, 0);
5190d320bc2SAmine Khaldi     ShowWindow(hMainWnd, SW_SHOW);
5200d320bc2SAmine Khaldi 
5210d320bc2SAmine Khaldi     hComboExParentWnd = CreateWindowExA(0, ComboExTestClass, "ComboEx test", WS_OVERLAPPEDWINDOW|WS_VISIBLE,
5220d320bc2SAmine Khaldi       CW_USEDEFAULT, CW_USEDEFAULT, 680, 260, NULL, NULL, GetModuleHandleA(NULL), 0);
5230d320bc2SAmine Khaldi     ok(hComboExParentWnd != NULL, "failed to create parent window\n");
5240d320bc2SAmine Khaldi 
5250d320bc2SAmine Khaldi     hMainHinst = GetModuleHandleA(NULL);
5260d320bc2SAmine Khaldi 
5270d320bc2SAmine Khaldi     return hComboExParentWnd != NULL;
5280d320bc2SAmine Khaldi }
5290d320bc2SAmine Khaldi 
cleanup(void)5300d320bc2SAmine Khaldi static void cleanup(void)
5310d320bc2SAmine Khaldi {
5320d320bc2SAmine Khaldi     MSG msg;
5330d320bc2SAmine Khaldi 
5340d320bc2SAmine Khaldi     PostMessageA(hComboExParentWnd, WM_CLOSE, 0, 0);
5350d320bc2SAmine Khaldi     while (GetMessageA(&msg,0,0,0)) {
5360d320bc2SAmine Khaldi         TranslateMessage(&msg);
5370d320bc2SAmine Khaldi         DispatchMessageA(&msg);
5380d320bc2SAmine Khaldi     }
5390d320bc2SAmine Khaldi 
5400d320bc2SAmine Khaldi     DestroyWindow(hComboExParentWnd);
5410d320bc2SAmine Khaldi     UnregisterClassA(ComboExTestClass, GetModuleHandleA(NULL));
5420d320bc2SAmine Khaldi 
5430d320bc2SAmine Khaldi     DestroyWindow(hMainWnd);
544*0707475fSJustin Miller     DeleteObject(brush_red);
5450d320bc2SAmine Khaldi }
5460d320bc2SAmine Khaldi 
test_comboex_subclass(void)5470d320bc2SAmine Khaldi static void test_comboex_subclass(void)
5480d320bc2SAmine Khaldi {
5490d320bc2SAmine Khaldi     HWND hComboEx, hCombo, hEdit;
5500d320bc2SAmine Khaldi 
5510d320bc2SAmine Khaldi     hComboEx = createComboEx(WS_BORDER | WS_VISIBLE | WS_CHILD | CBS_DROPDOWN);
5520d320bc2SAmine Khaldi 
5530d320bc2SAmine Khaldi     hCombo = (HWND)SendMessageA(hComboEx, CBEM_GETCOMBOCONTROL, 0, 0);
5540d320bc2SAmine Khaldi     ok(hCombo != NULL, "Failed to get internal combo\n");
5550d320bc2SAmine Khaldi     hEdit = (HWND)SendMessageA(hComboEx, CBEM_GETEDITCONTROL, 0, 0);
5560d320bc2SAmine Khaldi     ok(hEdit != NULL, "Failed to get internal edit\n");
5570d320bc2SAmine Khaldi 
5580d320bc2SAmine Khaldi     if (pSetWindowSubclass)
5590d320bc2SAmine Khaldi     {
5600d320bc2SAmine Khaldi         ok(GetPropA(hCombo, "CC32SubclassInfo") != NULL, "Expected CC32SubclassInfo property\n");
5610d320bc2SAmine Khaldi         ok(GetPropA(hEdit, "CC32SubclassInfo") != NULL, "Expected CC32SubclassInfo property\n");
5620d320bc2SAmine Khaldi     }
5630d320bc2SAmine Khaldi 
5640d320bc2SAmine Khaldi     DestroyWindow(hComboEx);
5650d320bc2SAmine Khaldi }
5660d320bc2SAmine Khaldi 
5670d320bc2SAmine Khaldi static const struct message test_setitem_edit_seq[] = {
5680d320bc2SAmine Khaldi     { WM_SETTEXT, sent|id, 0, 0, EDITBOX_ID },
5690d320bc2SAmine Khaldi     { EM_SETSEL, sent|id|wparam|lparam, 0,  0, EDITBOX_ID },
5700d320bc2SAmine Khaldi     { EM_SETSEL, sent|id|wparam|lparam, 0, -1, EDITBOX_ID },
5710d320bc2SAmine Khaldi     { 0 }
5720d320bc2SAmine Khaldi };
5730d320bc2SAmine Khaldi 
test_comboex_get_set_item(void)5740d320bc2SAmine Khaldi static void test_comboex_get_set_item(void)
5750d320bc2SAmine Khaldi {
5760d320bc2SAmine Khaldi     char textA[] = "test";
5770d320bc2SAmine Khaldi     HWND hComboEx;
5780d320bc2SAmine Khaldi     COMBOBOXEXITEMA item;
5790d320bc2SAmine Khaldi     BOOL ret;
5800d320bc2SAmine Khaldi 
5810d320bc2SAmine Khaldi     hComboEx = createComboEx(WS_BORDER | WS_VISIBLE | WS_CHILD | CBS_DROPDOWN);
5820d320bc2SAmine Khaldi 
5830d320bc2SAmine Khaldi     subclass_editbox(hComboEx);
5840d320bc2SAmine Khaldi 
5850d320bc2SAmine Khaldi     flush_sequences(sequences, NUM_MSG_SEQUENCES);
5860d320bc2SAmine Khaldi 
5870d320bc2SAmine Khaldi     memset(&item, 0, sizeof(item));
5880d320bc2SAmine Khaldi     item.mask = CBEIF_TEXT;
5890d320bc2SAmine Khaldi     item.pszText = textA;
5900d320bc2SAmine Khaldi     item.iItem = -1;
5910d320bc2SAmine Khaldi     ret = SendMessageA(hComboEx, CBEM_SETITEMA, 0, (LPARAM)&item);
5920d320bc2SAmine Khaldi     expect(TRUE, ret);
5930d320bc2SAmine Khaldi 
5940d320bc2SAmine Khaldi     ok_sequence(sequences, EDITBOX_SEQ_INDEX, test_setitem_edit_seq, "set item data for edit", FALSE);
5950d320bc2SAmine Khaldi 
5960d320bc2SAmine Khaldi     /* get/set lParam */
5970d320bc2SAmine Khaldi     item.mask = CBEIF_LPARAM;
5980d320bc2SAmine Khaldi     item.iItem = -1;
5990d320bc2SAmine Khaldi     item.lParam = 0xdeadbeef;
6000d320bc2SAmine Khaldi     ret = SendMessageA(hComboEx, CBEM_GETITEMA, 0, (LPARAM)&item);
6010d320bc2SAmine Khaldi     expect(TRUE, ret);
6020d320bc2SAmine Khaldi     ok(item.lParam == 0, "Expected zero, got %lx\n", item.lParam);
6030d320bc2SAmine Khaldi 
6040d320bc2SAmine Khaldi     item.lParam = 0x1abe11ed;
6050d320bc2SAmine Khaldi     ret = SendMessageA(hComboEx, CBEM_SETITEMA, 0, (LPARAM)&item);
6060d320bc2SAmine Khaldi     expect(TRUE, ret);
6070d320bc2SAmine Khaldi 
6080d320bc2SAmine Khaldi     item.lParam = 0;
6090d320bc2SAmine Khaldi     ret = SendMessageA(hComboEx, CBEM_GETITEMA, 0, (LPARAM)&item);
6100d320bc2SAmine Khaldi     expect(TRUE, ret);
6110d320bc2SAmine Khaldi     ok(item.lParam == 0x1abe11ed, "Expected 0x1abe11ed, got %lx\n", item.lParam);
6120d320bc2SAmine Khaldi 
6130d320bc2SAmine Khaldi     DestroyWindow(hComboEx);
6140d320bc2SAmine Khaldi }
6150d320bc2SAmine Khaldi 
create_combobox(DWORD style)6160d320bc2SAmine Khaldi static HWND create_combobox(DWORD style)
6170d320bc2SAmine Khaldi {
618f37104daSAmine Khaldi     return CreateWindowA(WC_COMBOBOXA, "Combo", WS_VISIBLE|WS_CHILD|style, 5, 5, 100, 100, hMainWnd, (HMENU)COMBO_ID, NULL, 0);
6190d320bc2SAmine Khaldi }
6200d320bc2SAmine Khaldi 
get_font_height(HFONT hFont)621*0707475fSJustin Miller static int get_font_height(HFONT hFont)
6220d320bc2SAmine Khaldi {
6230d320bc2SAmine Khaldi     TEXTMETRICA tm;
6240d320bc2SAmine Khaldi     HFONT hFontOld;
6250d320bc2SAmine Khaldi     HDC hDC;
6260d320bc2SAmine Khaldi 
6270d320bc2SAmine Khaldi     hDC = CreateCompatibleDC(NULL);
6280d320bc2SAmine Khaldi     hFontOld = SelectObject(hDC, hFont);
6290d320bc2SAmine Khaldi     GetTextMetricsA(hDC, &tm);
6300d320bc2SAmine Khaldi     SelectObject(hDC, hFontOld);
6310d320bc2SAmine Khaldi     DeleteDC(hDC);
6320d320bc2SAmine Khaldi 
6330d320bc2SAmine Khaldi     return tm.tmHeight;
6340d320bc2SAmine Khaldi }
6350d320bc2SAmine Khaldi 
test_combo_setitemheight(DWORD style)6360d320bc2SAmine Khaldi static void test_combo_setitemheight(DWORD style)
6370d320bc2SAmine Khaldi {
6380d320bc2SAmine Khaldi     HWND hCombo = create_combobox(style);
639*0707475fSJustin Miller     int i, font_height, height;
640*0707475fSJustin Miller     HFONT hFont;
6410d320bc2SAmine Khaldi     RECT r;
6420d320bc2SAmine Khaldi 
6430d320bc2SAmine Khaldi     GetClientRect(hCombo, &r);
644*0707475fSJustin Miller     expect_rect(r, 0, 0, 100, get_font_height(GetStockObject(SYSTEM_FONT)) + 8);
6450d320bc2SAmine Khaldi     SendMessageA(hCombo, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)&r);
6460d320bc2SAmine Khaldi     MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2);
6470d320bc2SAmine Khaldi     todo_wine expect_rect(r, 5, 5, 105, 105);
6480d320bc2SAmine Khaldi 
6490d320bc2SAmine Khaldi     for (i = 1; i < 30; i++)
6500d320bc2SAmine Khaldi     {
6510d320bc2SAmine Khaldi         SendMessageA(hCombo, CB_SETITEMHEIGHT, -1, i);
6520d320bc2SAmine Khaldi         GetClientRect(hCombo, &r);
6530d320bc2SAmine Khaldi         ok((r.bottom - r.top) == (i + 6), "Unexpected client rect height.\n");
6540d320bc2SAmine Khaldi     }
6550d320bc2SAmine Khaldi 
6560d320bc2SAmine Khaldi     DestroyWindow(hCombo);
657*0707475fSJustin Miller 
658*0707475fSJustin Miller     /* Set item height below text height, force resize. */
659*0707475fSJustin Miller     hCombo = create_combobox(style);
660*0707475fSJustin Miller 
661*0707475fSJustin Miller     hFont = (HFONT)SendMessageA(hCombo, WM_GETFONT, 0, 0);
662*0707475fSJustin Miller     font_height = get_font_height(hFont);
663*0707475fSJustin Miller     SendMessageA(hCombo, CB_SETITEMHEIGHT, -1, font_height / 2);
664*0707475fSJustin Miller     height = SendMessageA(hCombo, CB_GETITEMHEIGHT, -1, 0);
665*0707475fSJustin Miller todo_wine
666*0707475fSJustin Miller     ok(height == font_height / 2, "Unexpected item height %d, expected %d.\n", height, font_height / 2);
667*0707475fSJustin Miller 
668*0707475fSJustin Miller     SetWindowPos(hCombo, NULL, 10, 10, 150, 5 * font_height, SWP_SHOWWINDOW);
669*0707475fSJustin Miller     height = SendMessageA(hCombo, CB_GETITEMHEIGHT, -1, 0);
670*0707475fSJustin Miller     ok(height > font_height, "Unexpected item height %d, font height %d.\n", height, font_height);
671*0707475fSJustin Miller 
672*0707475fSJustin Miller     DestroyWindow(hCombo);
6730d320bc2SAmine Khaldi }
6740d320bc2SAmine Khaldi 
test_combo_setfont(DWORD style)6750d320bc2SAmine Khaldi static void test_combo_setfont(DWORD style)
6760d320bc2SAmine Khaldi {
6770d320bc2SAmine Khaldi     HFONT hFont1, hFont2;
6780d320bc2SAmine Khaldi     HWND hCombo;
6790d320bc2SAmine Khaldi     RECT r;
6800d320bc2SAmine Khaldi     int i;
6810d320bc2SAmine Khaldi 
6820d320bc2SAmine Khaldi     hCombo = create_combobox(style);
6830d320bc2SAmine Khaldi     hFont1 = CreateFontA(10, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, SYMBOL_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH|FF_DONTCARE, "Marlett");
6840d320bc2SAmine Khaldi     hFont2 = CreateFontA(8, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, SYMBOL_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH|FF_DONTCARE, "Marlett");
6850d320bc2SAmine Khaldi 
6860d320bc2SAmine Khaldi     GetClientRect(hCombo, &r);
687*0707475fSJustin Miller     expect_rect(r, 0, 0, 100, get_font_height(GetStockObject(SYSTEM_FONT)) + 8);
6880d320bc2SAmine Khaldi     SendMessageA(hCombo, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)&r);
6890d320bc2SAmine Khaldi     MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2);
6900d320bc2SAmine Khaldi     todo_wine expect_rect(r, 5, 5, 105, 105);
6910d320bc2SAmine Khaldi 
6920d320bc2SAmine Khaldi     /* The size of the dropped control is initially equal to the size
6930d320bc2SAmine Khaldi        of the window when it was created.  The size of the calculated
6940d320bc2SAmine Khaldi        dropped area changes only by how much the selection area
6950d320bc2SAmine Khaldi        changes, not by how much the list area changes.  */
696*0707475fSJustin Miller     if (get_font_height(hFont1) == 10 && get_font_height(hFont2) == 8)
6970d320bc2SAmine Khaldi     {
6980d320bc2SAmine Khaldi         SendMessageA(hCombo, WM_SETFONT, (WPARAM)hFont1, FALSE);
6990d320bc2SAmine Khaldi         GetClientRect(hCombo, &r);
7000d320bc2SAmine Khaldi         expect_rect(r, 0, 0, 100, 18);
7010d320bc2SAmine Khaldi         SendMessageA(hCombo, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)&r);
7020d320bc2SAmine Khaldi         MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2);
703*0707475fSJustin Miller         todo_wine expect_rect(r, 5, 5, 105, 105 - (get_font_height(GetStockObject(SYSTEM_FONT)) - get_font_height(hFont1)));
7040d320bc2SAmine Khaldi 
7050d320bc2SAmine Khaldi         SendMessageA(hCombo, WM_SETFONT, (WPARAM)hFont2, FALSE);
7060d320bc2SAmine Khaldi         GetClientRect(hCombo, &r);
7070d320bc2SAmine Khaldi         expect_rect(r, 0, 0, 100, 16);
7080d320bc2SAmine Khaldi         SendMessageA(hCombo, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)&r);
7090d320bc2SAmine Khaldi         MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2);
710*0707475fSJustin Miller         todo_wine expect_rect(r, 5, 5, 105, 105 - (get_font_height(GetStockObject(SYSTEM_FONT)) - get_font_height(hFont2)));
7110d320bc2SAmine Khaldi 
7120d320bc2SAmine Khaldi         SendMessageA(hCombo, WM_SETFONT, (WPARAM)hFont1, FALSE);
7130d320bc2SAmine Khaldi         GetClientRect(hCombo, &r);
7140d320bc2SAmine Khaldi         expect_rect(r, 0, 0, 100, 18);
7150d320bc2SAmine Khaldi         SendMessageA(hCombo, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)&r);
7160d320bc2SAmine Khaldi         MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2);
717*0707475fSJustin Miller         todo_wine expect_rect(r, 5, 5, 105, 105 - (get_font_height(GetStockObject(SYSTEM_FONT)) - get_font_height(hFont1)));
7180d320bc2SAmine Khaldi     }
7190d320bc2SAmine Khaldi     else
7200d320bc2SAmine Khaldi     {
7210d320bc2SAmine Khaldi         ok(0, "Expected Marlett font heights 10/8, got %d/%d\n",
722*0707475fSJustin Miller            get_font_height(hFont1), get_font_height(hFont2));
7230d320bc2SAmine Khaldi     }
7240d320bc2SAmine Khaldi 
7250d320bc2SAmine Khaldi     for (i = 1; i < 30; i++)
7260d320bc2SAmine Khaldi     {
7270d320bc2SAmine Khaldi         HFONT hFont = CreateFontA(i, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, SYMBOL_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH|FF_DONTCARE, "Marlett");
728*0707475fSJustin Miller         int height = get_font_height(hFont);
7290d320bc2SAmine Khaldi 
7300d320bc2SAmine Khaldi         SendMessageA(hCombo, WM_SETFONT, (WPARAM)hFont, FALSE);
7310d320bc2SAmine Khaldi         GetClientRect(hCombo, &r);
7320d320bc2SAmine Khaldi         ok((r.bottom - r.top) == (height + 8), "Unexpected client rect height.\n");
7330d320bc2SAmine Khaldi         SendMessageA(hCombo, WM_SETFONT, 0, FALSE);
7340d320bc2SAmine Khaldi         DeleteObject(hFont);
7350d320bc2SAmine Khaldi     }
7360d320bc2SAmine Khaldi 
7370d320bc2SAmine Khaldi     DestroyWindow(hCombo);
7380d320bc2SAmine Khaldi     DeleteObject(hFont1);
7390d320bc2SAmine Khaldi     DeleteObject(hFont2);
7400d320bc2SAmine Khaldi }
7410d320bc2SAmine Khaldi 
7420d320bc2SAmine Khaldi static LRESULT (CALLBACK *old_parent_proc)(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
7430d320bc2SAmine Khaldi static LPCSTR expected_edit_text;
7440d320bc2SAmine Khaldi static LPCSTR expected_list_text;
7450d320bc2SAmine Khaldi static BOOL selchange_fired;
746*0707475fSJustin Miller static HWND lparam_for_WM_CTLCOLOR;
7470d320bc2SAmine Khaldi 
parent_wnd_proc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)7480d320bc2SAmine Khaldi static LRESULT CALLBACK parent_wnd_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
7490d320bc2SAmine Khaldi {
7500d320bc2SAmine Khaldi     switch (msg)
7510d320bc2SAmine Khaldi     {
7520d320bc2SAmine Khaldi     case WM_COMMAND:
7530d320bc2SAmine Khaldi         switch (wparam)
7540d320bc2SAmine Khaldi         {
7550d320bc2SAmine Khaldi             case MAKEWPARAM(COMBO_ID, CBN_SELCHANGE):
7560d320bc2SAmine Khaldi             {
7570d320bc2SAmine Khaldi                 HWND hCombo = (HWND)lparam;
7580d320bc2SAmine Khaldi                 char list[20], edit[20];
7590d320bc2SAmine Khaldi                 int idx;
7600d320bc2SAmine Khaldi 
7610d320bc2SAmine Khaldi                 memset(list, 0, sizeof(list));
7620d320bc2SAmine Khaldi                 memset(edit, 0, sizeof(edit));
7630d320bc2SAmine Khaldi 
7640d320bc2SAmine Khaldi                 idx = SendMessageA(hCombo, CB_GETCURSEL, 0, 0);
7650d320bc2SAmine Khaldi                 SendMessageA(hCombo, CB_GETLBTEXT, idx, (LPARAM)list);
7660d320bc2SAmine Khaldi                 SendMessageA(hCombo, WM_GETTEXT, sizeof(edit), (LPARAM)edit);
7670d320bc2SAmine Khaldi 
7680d320bc2SAmine Khaldi                 ok(!strcmp(edit, expected_edit_text), "edit: got %s, expected %s\n",
7690d320bc2SAmine Khaldi                     edit, expected_edit_text);
7700d320bc2SAmine Khaldi                 ok(!strcmp(list, expected_list_text), "list: got %s, expected %s\n",
7710d320bc2SAmine Khaldi                     list, expected_list_text);
7720d320bc2SAmine Khaldi 
7730d320bc2SAmine Khaldi                 selchange_fired = TRUE;
7740d320bc2SAmine Khaldi             }
7750d320bc2SAmine Khaldi             break;
7760d320bc2SAmine Khaldi         }
7770d320bc2SAmine Khaldi         break;
778*0707475fSJustin Miller     case WM_CTLCOLOR:
779*0707475fSJustin Miller     case WM_CTLCOLORMSGBOX:
780*0707475fSJustin Miller     case WM_CTLCOLOREDIT:
781*0707475fSJustin Miller     case WM_CTLCOLORLISTBOX:
782*0707475fSJustin Miller     case WM_CTLCOLORBTN:
783*0707475fSJustin Miller     case WM_CTLCOLORDLG:
784*0707475fSJustin Miller     case WM_CTLCOLORSCROLLBAR:
785*0707475fSJustin Miller     case WM_CTLCOLORSTATIC:
786*0707475fSJustin Miller         if (lparam_for_WM_CTLCOLOR)
787*0707475fSJustin Miller         {
788*0707475fSJustin Miller             ok(lparam_for_WM_CTLCOLOR == (HWND)lparam, "Expected %p, got %p\n", lparam_for_WM_CTLCOLOR, (HWND)lparam);
789*0707475fSJustin Miller             return (LRESULT) brush_red;
790*0707475fSJustin Miller         }
791*0707475fSJustin Miller         break;
7920d320bc2SAmine Khaldi     }
7930d320bc2SAmine Khaldi 
7940d320bc2SAmine Khaldi     return CallWindowProcA(old_parent_proc, hwnd, msg, wparam, lparam);
7950d320bc2SAmine Khaldi }
7960d320bc2SAmine Khaldi 
test_selection(DWORD style,const char * const text[],const int * edit,const int * list)7970d320bc2SAmine Khaldi static void test_selection(DWORD style, const char * const text[], const int *edit, const int *list)
7980d320bc2SAmine Khaldi {
7990d320bc2SAmine Khaldi     HWND hCombo;
8000d320bc2SAmine Khaldi     INT idx;
8010d320bc2SAmine Khaldi 
8020d320bc2SAmine Khaldi     hCombo = create_combobox(style);
8030d320bc2SAmine Khaldi 
8040d320bc2SAmine Khaldi     SendMessageA(hCombo, CB_ADDSTRING, 0, (LPARAM)text[0]);
8050d320bc2SAmine Khaldi     SendMessageA(hCombo, CB_ADDSTRING, 0, (LPARAM)text[1]);
8060d320bc2SAmine Khaldi     SendMessageA(hCombo, CB_SETCURSEL, -1, 0);
8070d320bc2SAmine Khaldi 
8080d320bc2SAmine Khaldi     old_parent_proc = (void *)SetWindowLongPtrA(hMainWnd, GWLP_WNDPROC, (ULONG_PTR)parent_wnd_proc);
8090d320bc2SAmine Khaldi 
8100d320bc2SAmine Khaldi     idx = SendMessageA(hCombo, CB_GETCURSEL, 0, 0);
8110d320bc2SAmine Khaldi     ok(idx == -1, "expected selection -1, got %d\n", idx);
8120d320bc2SAmine Khaldi 
8130d320bc2SAmine Khaldi     /* keyboard navigation */
8140d320bc2SAmine Khaldi 
8150d320bc2SAmine Khaldi     expected_list_text = text[list[0]];
8160d320bc2SAmine Khaldi     expected_edit_text = text[edit[0]];
8170d320bc2SAmine Khaldi     selchange_fired = FALSE;
8180d320bc2SAmine Khaldi     SendMessageA(hCombo, WM_KEYDOWN, VK_DOWN, 0);
8190d320bc2SAmine Khaldi     ok(selchange_fired, "CBN_SELCHANGE not sent!\n");
8200d320bc2SAmine Khaldi 
8210d320bc2SAmine Khaldi     expected_list_text = text[list[1]];
8220d320bc2SAmine Khaldi     expected_edit_text = text[edit[1]];
8230d320bc2SAmine Khaldi     selchange_fired = FALSE;
8240d320bc2SAmine Khaldi     SendMessageA(hCombo, WM_KEYDOWN, VK_DOWN, 0);
8250d320bc2SAmine Khaldi     ok(selchange_fired, "CBN_SELCHANGE not sent!\n");
8260d320bc2SAmine Khaldi 
8270d320bc2SAmine Khaldi     expected_list_text = text[list[2]];
8280d320bc2SAmine Khaldi     expected_edit_text = text[edit[2]];
8290d320bc2SAmine Khaldi     selchange_fired = FALSE;
8300d320bc2SAmine Khaldi     SendMessageA(hCombo, WM_KEYDOWN, VK_UP, 0);
8310d320bc2SAmine Khaldi     ok(selchange_fired, "CBN_SELCHANGE not sent!\n");
8320d320bc2SAmine Khaldi 
8330d320bc2SAmine Khaldi     /* programmatic navigation */
8340d320bc2SAmine Khaldi 
8350d320bc2SAmine Khaldi     expected_list_text = text[list[3]];
8360d320bc2SAmine Khaldi     expected_edit_text = text[edit[3]];
8370d320bc2SAmine Khaldi     selchange_fired = FALSE;
8380d320bc2SAmine Khaldi     SendMessageA(hCombo, CB_SETCURSEL, list[3], 0);
8390d320bc2SAmine Khaldi     ok(!selchange_fired, "CBN_SELCHANGE sent!\n");
8400d320bc2SAmine Khaldi 
8410d320bc2SAmine Khaldi     expected_list_text = text[list[4]];
8420d320bc2SAmine Khaldi     expected_edit_text = text[edit[4]];
8430d320bc2SAmine Khaldi     selchange_fired = FALSE;
8440d320bc2SAmine Khaldi     SendMessageA(hCombo, CB_SETCURSEL, list[4], 0);
8450d320bc2SAmine Khaldi     ok(!selchange_fired, "CBN_SELCHANGE sent!\n");
8460d320bc2SAmine Khaldi 
8470d320bc2SAmine Khaldi     SetWindowLongPtrA(hMainWnd, GWLP_WNDPROC, (ULONG_PTR)old_parent_proc);
8480d320bc2SAmine Khaldi     DestroyWindow(hCombo);
8490d320bc2SAmine Khaldi }
8500d320bc2SAmine Khaldi 
test_combo_CBN_SELCHANGE(void)8510d320bc2SAmine Khaldi static void test_combo_CBN_SELCHANGE(void)
8520d320bc2SAmine Khaldi {
8530d320bc2SAmine Khaldi     static const char * const text[] = { "alpha", "beta", "" };
8540d320bc2SAmine Khaldi     static const int sel_1[] = { 2, 0, 1, 0, 1 };
8550d320bc2SAmine Khaldi     static const int sel_2[] = { 0, 1, 0, 0, 1 };
8560d320bc2SAmine Khaldi 
8570d320bc2SAmine Khaldi     test_selection(CBS_SIMPLE, text, sel_1, sel_2);
8580d320bc2SAmine Khaldi     test_selection(CBS_DROPDOWN, text, sel_1, sel_2);
8590d320bc2SAmine Khaldi     test_selection(CBS_DROPDOWNLIST, text, sel_2, sel_2);
8600d320bc2SAmine Khaldi }
8610d320bc2SAmine Khaldi 
test_combo_changesize(DWORD style)8620d320bc2SAmine Khaldi static void test_combo_changesize(DWORD style)
8630d320bc2SAmine Khaldi {
8640d320bc2SAmine Khaldi     INT ddheight, clheight, ddwidth, clwidth;
8650d320bc2SAmine Khaldi     HWND hCombo;
8660d320bc2SAmine Khaldi     RECT rc;
8670d320bc2SAmine Khaldi 
8680d320bc2SAmine Khaldi     hCombo = create_combobox(style);
8690d320bc2SAmine Khaldi 
8700d320bc2SAmine Khaldi     /* get initial measurements */
8710d320bc2SAmine Khaldi     GetClientRect( hCombo, &rc);
8720d320bc2SAmine Khaldi     clheight = rc.bottom - rc.top;
8730d320bc2SAmine Khaldi     clwidth = rc.right - rc.left;
8740d320bc2SAmine Khaldi     SendMessageA(hCombo, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)&rc);
8750d320bc2SAmine Khaldi     ddheight = rc.bottom - rc.top;
8760d320bc2SAmine Khaldi     ddwidth = rc.right - rc.left;
8770d320bc2SAmine Khaldi     /* use MoveWindow to move & resize the combo */
8780d320bc2SAmine Khaldi     /* first make it slightly smaller */
8790d320bc2SAmine Khaldi     MoveWindow( hCombo, 10, 10, clwidth - 2, clheight - 2, TRUE);
8800d320bc2SAmine Khaldi     GetClientRect( hCombo, &rc);
8810d320bc2SAmine Khaldi     ok( rc.right - rc.left == clwidth - 2, "clientrect width is %d vs %d\n",
8820d320bc2SAmine Khaldi             rc.right - rc.left, clwidth - 2);
8830d320bc2SAmine Khaldi     ok( rc.bottom - rc.top == clheight, "clientrect height is %d vs %d\n",
8840d320bc2SAmine Khaldi                 rc.bottom - rc.top, clheight);
8850d320bc2SAmine Khaldi     SendMessageA(hCombo, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)&rc);
8860d320bc2SAmine Khaldi     ok( rc.right - rc.left == clwidth - 2, "drop-down rect width is %d vs %d\n",
8870d320bc2SAmine Khaldi             rc.right - rc.left, clwidth - 2);
8880d320bc2SAmine Khaldi     ok( rc.bottom - rc.top == ddheight, "drop-down rect height is %d vs %d\n",
8890d320bc2SAmine Khaldi             rc.bottom - rc.top, ddheight);
8900d320bc2SAmine Khaldi     ok( rc.right - rc.left == ddwidth -2, "drop-down rect width is %d vs %d\n",
8910d320bc2SAmine Khaldi             rc.right - rc.left, ddwidth - 2);
8920d320bc2SAmine Khaldi     /* new cx, cy is slightly bigger than the initial values */
8930d320bc2SAmine Khaldi     MoveWindow( hCombo, 10, 10, clwidth + 2, clheight + 2, TRUE);
8940d320bc2SAmine Khaldi     GetClientRect( hCombo, &rc);
8950d320bc2SAmine Khaldi     ok( rc.right - rc.left == clwidth + 2, "clientrect width is %d vs %d\n",
8960d320bc2SAmine Khaldi             rc.right - rc.left, clwidth + 2);
8970d320bc2SAmine Khaldi     ok( rc.bottom - rc.top == clheight, "clientrect height is %d vs %d\n",
8980d320bc2SAmine Khaldi             rc.bottom - rc.top, clheight);
8990d320bc2SAmine Khaldi     SendMessageA(hCombo, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)&rc);
9000d320bc2SAmine Khaldi     ok( rc.right - rc.left == clwidth + 2, "drop-down rect width is %d vs %d\n",
9010d320bc2SAmine Khaldi             rc.right - rc.left, clwidth + 2);
9020d320bc2SAmine Khaldi     todo_wine {
9030d320bc2SAmine Khaldi         ok( rc.bottom - rc.top == clheight + 2, "drop-down rect height is %d vs %d\n",
9040d320bc2SAmine Khaldi                 rc.bottom - rc.top, clheight + 2);
9050d320bc2SAmine Khaldi     }
9060d320bc2SAmine Khaldi 
9070d320bc2SAmine Khaldi     ddwidth = SendMessageA(hCombo, CB_SETDROPPEDWIDTH, -1, 0);
9080d320bc2SAmine Khaldi     ok( ddwidth == clwidth + 2, "drop-width is %d vs %d\n", ddwidth, clwidth + 2);
9090d320bc2SAmine Khaldi     ddwidth = SendMessageA(hCombo, CB_GETDROPPEDWIDTH, 0, 0);
9100d320bc2SAmine Khaldi     ok( ddwidth == clwidth + 2, "drop-width is %d vs %d\n", ddwidth, clwidth + 2);
9110d320bc2SAmine Khaldi 
9120d320bc2SAmine Khaldi     ddwidth = SendMessageA(hCombo, CB_SETDROPPEDWIDTH, 0, 0);
9130d320bc2SAmine Khaldi     ok( ddwidth == clwidth + 2, "drop-width is %d vs %d\n", ddwidth, clwidth + 2);
9140d320bc2SAmine Khaldi     ddwidth = SendMessageA(hCombo, CB_GETDROPPEDWIDTH, 0, 0);
9150d320bc2SAmine Khaldi     ok( ddwidth == clwidth + 2, "drop-width is %d vs %d\n", ddwidth, clwidth + 2);
9160d320bc2SAmine Khaldi 
9170d320bc2SAmine Khaldi     ddwidth = SendMessageA(hCombo, CB_SETDROPPEDWIDTH, clwidth - 1, 0);
9180d320bc2SAmine Khaldi     ok( ddwidth == clwidth + 2, "drop-width is %d vs %d\n", ddwidth, clwidth + 2);
9190d320bc2SAmine Khaldi     ddwidth = SendMessageA(hCombo, CB_GETDROPPEDWIDTH, 0, 0);
9200d320bc2SAmine Khaldi     ok( ddwidth == clwidth + 2, "drop-width is %d vs %d\n", ddwidth, clwidth + 2);
9210d320bc2SAmine Khaldi 
9220d320bc2SAmine Khaldi     ddwidth = SendMessageA(hCombo, CB_SETDROPPEDWIDTH, clwidth << 1, 0);
9230d320bc2SAmine Khaldi     ok( ddwidth == (clwidth << 1), "drop-width is %d vs %d\n", ddwidth, clwidth << 1);
9240d320bc2SAmine Khaldi     ddwidth = SendMessageA(hCombo, CB_GETDROPPEDWIDTH, 0, 0);
9250d320bc2SAmine Khaldi     ok( ddwidth == (clwidth << 1), "drop-width is %d vs %d\n", ddwidth, clwidth << 1);
9260d320bc2SAmine Khaldi 
9270d320bc2SAmine Khaldi     ddwidth = SendMessageA(hCombo, CB_SETDROPPEDWIDTH, 0, 0);
9280d320bc2SAmine Khaldi     ok( ddwidth == (clwidth << 1), "drop-width is %d vs %d\n", ddwidth, clwidth << 1);
9290d320bc2SAmine Khaldi     ddwidth = SendMessageA(hCombo, CB_GETDROPPEDWIDTH, 0, 0);
9300d320bc2SAmine Khaldi     ok( ddwidth == (clwidth << 1), "drop-width is %d vs %d\n", ddwidth, clwidth << 1);
9310d320bc2SAmine Khaldi 
9320d320bc2SAmine Khaldi     ddwidth = SendMessageA(hCombo, CB_SETDROPPEDWIDTH, 1, 0);
9330d320bc2SAmine Khaldi     ok( ddwidth == clwidth + 2, "drop-width is %d vs %d\n", ddwidth, clwidth + 2);
9340d320bc2SAmine Khaldi     ddwidth = SendMessageA(hCombo, CB_GETDROPPEDWIDTH, 0, 0);
9350d320bc2SAmine Khaldi     ok( ddwidth == clwidth + 2, "drop-width is %d vs %d\n", ddwidth, clwidth + 2);
9360d320bc2SAmine Khaldi 
9370d320bc2SAmine Khaldi     DestroyWindow(hCombo);
9380d320bc2SAmine Khaldi }
9390d320bc2SAmine Khaldi 
test_combo_editselection(void)9400d320bc2SAmine Khaldi static void test_combo_editselection(void)
9410d320bc2SAmine Khaldi {
9420d320bc2SAmine Khaldi     COMBOBOXINFO cbInfo;
9430d320bc2SAmine Khaldi     INT start, end;
9440d320bc2SAmine Khaldi     char edit[20];
9450d320bc2SAmine Khaldi     HWND hCombo;
9460d320bc2SAmine Khaldi     HWND hEdit;
9470d320bc2SAmine Khaldi     DWORD len;
9480d320bc2SAmine Khaldi 
9490d320bc2SAmine Khaldi     /* Build a combo */
9500d320bc2SAmine Khaldi     hCombo = create_combobox(CBS_SIMPLE);
9510d320bc2SAmine Khaldi 
9520d320bc2SAmine Khaldi     get_combobox_info(hCombo, &cbInfo);
9530d320bc2SAmine Khaldi     hEdit = cbInfo.hwndItem;
9540d320bc2SAmine Khaldi 
9550d320bc2SAmine Khaldi     /* Initially combo selection is empty*/
9560d320bc2SAmine Khaldi     len = SendMessageA(hCombo, CB_GETEDITSEL, 0,0);
9570d320bc2SAmine Khaldi     ok(LOWORD(len)==0, "Unexpected start position for selection %d\n", LOWORD(len));
9580d320bc2SAmine Khaldi     ok(HIWORD(len)==0, "Unexpected end position for selection %d\n", HIWORD(len));
9590d320bc2SAmine Khaldi 
9600d320bc2SAmine Khaldi     /* Set some text, and press a key to replace it */
9610d320bc2SAmine Khaldi     edit[0] = 0x00;
9620d320bc2SAmine Khaldi     SendMessageA(hCombo, WM_SETTEXT, 0, (LPARAM)"Jason1");
9630d320bc2SAmine Khaldi     SendMessageA(hCombo, WM_GETTEXT, sizeof(edit), (LPARAM)edit);
9640d320bc2SAmine Khaldi     ok(strcmp(edit, "Jason1")==0, "Unexpected text retrieved %s\n", edit);
9650d320bc2SAmine Khaldi 
9660d320bc2SAmine Khaldi     /* Now what is the selection - still empty */
9670d320bc2SAmine Khaldi     SendMessageA(hCombo, CB_GETEDITSEL, (WPARAM)&start, (WPARAM)&end);
9680d320bc2SAmine Khaldi     ok(start==0, "Unexpected start position for selection %d\n", start);
9690d320bc2SAmine Khaldi     ok(end==0, "Unexpected end position for selection %d\n", end);
9700d320bc2SAmine Khaldi     len = SendMessageA(hCombo, CB_GETEDITSEL, 0,0);
9710d320bc2SAmine Khaldi     ok(LOWORD(len)==0, "Unexpected start position for selection %d\n", LOWORD(len));
9720d320bc2SAmine Khaldi     ok(HIWORD(len)==0, "Unexpected end position for selection %d\n", HIWORD(len));
9730d320bc2SAmine Khaldi 
9740d320bc2SAmine Khaldi     /* Give it focus, and it gets selected */
9750d320bc2SAmine Khaldi     SendMessageA(hCombo, WM_SETFOCUS, 0, (LPARAM)hEdit);
9760d320bc2SAmine Khaldi     SendMessageA(hCombo, CB_GETEDITSEL, (WPARAM)&start, (WPARAM)&end);
9770d320bc2SAmine Khaldi     ok(start==0, "Unexpected start position for selection %d\n", start);
9780d320bc2SAmine Khaldi     ok(end==6, "Unexpected end position for selection %d\n", end);
9790d320bc2SAmine Khaldi     len = SendMessageA(hCombo, CB_GETEDITSEL, 0,0);
9800d320bc2SAmine Khaldi     ok(LOWORD(len)==0, "Unexpected start position for selection %d\n", LOWORD(len));
9810d320bc2SAmine Khaldi     ok(HIWORD(len)==6, "Unexpected end position for selection %d\n", HIWORD(len));
9820d320bc2SAmine Khaldi 
9830d320bc2SAmine Khaldi     /* Now emulate a key press */
9840d320bc2SAmine Khaldi     edit[0] = 0x00;
9850d320bc2SAmine Khaldi     SendMessageA(hCombo, WM_CHAR, 'A', 0x1c0001);
9860d320bc2SAmine Khaldi     SendMessageA(hCombo, WM_GETTEXT, sizeof(edit), (LPARAM)edit);
9870d320bc2SAmine Khaldi     ok(strcmp(edit, "A")==0, "Unexpected text retrieved %s\n", edit);
9880d320bc2SAmine Khaldi 
9890d320bc2SAmine Khaldi     len = SendMessageA(hCombo, CB_GETEDITSEL, 0,0);
9900d320bc2SAmine Khaldi     ok(LOWORD(len)==1, "Unexpected start position for selection %d\n", LOWORD(len));
9910d320bc2SAmine Khaldi     ok(HIWORD(len)==1, "Unexpected end position for selection %d\n", HIWORD(len));
9920d320bc2SAmine Khaldi 
9930d320bc2SAmine Khaldi     /* Now what happens when it gets more focus a second time - it doesn't reselect */
9940d320bc2SAmine Khaldi     SendMessageA(hCombo, WM_SETFOCUS, 0, (LPARAM)hEdit);
9950d320bc2SAmine Khaldi     len = SendMessageA(hCombo, CB_GETEDITSEL, 0,0);
9960d320bc2SAmine Khaldi     ok(LOWORD(len)==1, "Unexpected start position for selection %d\n", LOWORD(len));
9970d320bc2SAmine Khaldi     ok(HIWORD(len)==1, "Unexpected end position for selection %d\n", HIWORD(len));
9980d320bc2SAmine Khaldi     DestroyWindow(hCombo);
9990d320bc2SAmine Khaldi 
10000d320bc2SAmine Khaldi     /* Start again - Build a combo */
10010d320bc2SAmine Khaldi     hCombo = create_combobox(CBS_SIMPLE);
10020d320bc2SAmine Khaldi     get_combobox_info(hCombo, &cbInfo);
10030d320bc2SAmine Khaldi     hEdit = cbInfo.hwndItem;
10040d320bc2SAmine Khaldi 
10050d320bc2SAmine Khaldi     /* Set some text and give focus so it gets selected */
10060d320bc2SAmine Khaldi     edit[0] = 0x00;
10070d320bc2SAmine Khaldi     SendMessageA(hCombo, WM_SETTEXT, 0, (LPARAM)"Jason2");
10080d320bc2SAmine Khaldi     SendMessageA(hCombo, WM_GETTEXT, sizeof(edit), (LPARAM)edit);
10090d320bc2SAmine Khaldi     ok(strcmp(edit, "Jason2")==0, "Unexpected text retrieved %s\n", edit);
10100d320bc2SAmine Khaldi 
10110d320bc2SAmine Khaldi     SendMessageA(hCombo, WM_SETFOCUS, 0, (LPARAM)hEdit);
10120d320bc2SAmine Khaldi 
10130d320bc2SAmine Khaldi     /* Now what is the selection */
10140d320bc2SAmine Khaldi     SendMessageA(hCombo, CB_GETEDITSEL, (WPARAM)&start, (WPARAM)&end);
10150d320bc2SAmine Khaldi     ok(start==0, "Unexpected start position for selection %d\n", start);
10160d320bc2SAmine Khaldi     ok(end==6, "Unexpected end position for selection %d\n", end);
10170d320bc2SAmine Khaldi     len = SendMessageA(hCombo, CB_GETEDITSEL, 0,0);
10180d320bc2SAmine Khaldi     ok(LOWORD(len)==0, "Unexpected start position for selection %d\n", LOWORD(len));
10190d320bc2SAmine Khaldi     ok(HIWORD(len)==6, "Unexpected end position for selection %d\n", HIWORD(len));
10200d320bc2SAmine Khaldi 
10210d320bc2SAmine Khaldi     /* Now change the selection to the apparently invalid start -1, end -1 and
10220d320bc2SAmine Khaldi        show it means no selection (ie start -1) but cursor at end              */
10230d320bc2SAmine Khaldi     SendMessageA(hCombo, CB_SETEDITSEL, 0, -1);
10240d320bc2SAmine Khaldi     edit[0] = 0x00;
10250d320bc2SAmine Khaldi     SendMessageA(hCombo, WM_CHAR, 'A', 0x1c0001);
10260d320bc2SAmine Khaldi     SendMessageA(hCombo, WM_GETTEXT, sizeof(edit), (LPARAM)edit);
10270d320bc2SAmine Khaldi     ok(strcmp(edit, "Jason2A")==0, "Unexpected text retrieved %s\n", edit);
10280d320bc2SAmine Khaldi     DestroyWindow(hCombo);
10290d320bc2SAmine Khaldi }
10300d320bc2SAmine Khaldi 
10310d320bc2SAmine Khaldi static WNDPROC edit_window_proc;
10320d320bc2SAmine Khaldi static long setsel_start = 1, setsel_end = 1;
10330d320bc2SAmine Khaldi static HWND hCBN_SetFocus, hCBN_KillFocus;
10340d320bc2SAmine Khaldi 
combobox_subclass_proc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)10350d320bc2SAmine Khaldi static LRESULT CALLBACK combobox_subclass_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
10360d320bc2SAmine Khaldi {
10370d320bc2SAmine Khaldi     if (msg == EM_SETSEL)
10380d320bc2SAmine Khaldi     {
10390d320bc2SAmine Khaldi         setsel_start = wParam;
10400d320bc2SAmine Khaldi         setsel_end = lParam;
10410d320bc2SAmine Khaldi     }
10420d320bc2SAmine Khaldi     return CallWindowProcA(edit_window_proc, hwnd, msg, wParam, lParam);
10430d320bc2SAmine Khaldi }
10440d320bc2SAmine Khaldi 
test_window_proc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)10450d320bc2SAmine Khaldi static LRESULT CALLBACK test_window_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
10460d320bc2SAmine Khaldi {
10470d320bc2SAmine Khaldi     switch (msg)
10480d320bc2SAmine Khaldi     {
10490d320bc2SAmine Khaldi     case WM_COMMAND:
10500d320bc2SAmine Khaldi         switch (HIWORD(wParam))
10510d320bc2SAmine Khaldi         {
10520d320bc2SAmine Khaldi         case CBN_SETFOCUS:
10530d320bc2SAmine Khaldi             hCBN_SetFocus = (HWND)lParam;
10540d320bc2SAmine Khaldi             break;
10550d320bc2SAmine Khaldi         case CBN_KILLFOCUS:
10560d320bc2SAmine Khaldi             hCBN_KillFocus = (HWND)lParam;
10570d320bc2SAmine Khaldi             break;
10580d320bc2SAmine Khaldi         }
10590d320bc2SAmine Khaldi         break;
10600d320bc2SAmine Khaldi     case WM_NEXTDLGCTL:
10610d320bc2SAmine Khaldi         SetFocus((HWND)wParam);
10620d320bc2SAmine Khaldi         break;
10630d320bc2SAmine Khaldi     }
10640d320bc2SAmine Khaldi     return CallWindowProcA(old_parent_proc, hwnd, msg, wParam, lParam);
10650d320bc2SAmine Khaldi }
10660d320bc2SAmine Khaldi 
test_combo_editselection_focus(DWORD style)10670d320bc2SAmine Khaldi static void test_combo_editselection_focus(DWORD style)
10680d320bc2SAmine Khaldi {
10690d320bc2SAmine Khaldi     static const char wine_test[] = "Wine Test";
10700d320bc2SAmine Khaldi     HWND hCombo, hEdit, hButton;
10710d320bc2SAmine Khaldi     char buffer[16] = {0};
10720d320bc2SAmine Khaldi     COMBOBOXINFO cbInfo;
10730d320bc2SAmine Khaldi     DWORD len;
10740d320bc2SAmine Khaldi 
10750d320bc2SAmine Khaldi     hCombo = create_combobox(style);
10760d320bc2SAmine Khaldi     get_combobox_info(hCombo, &cbInfo);
10770d320bc2SAmine Khaldi     hEdit = cbInfo.hwndItem;
10780d320bc2SAmine Khaldi 
1079f37104daSAmine Khaldi     hButton = CreateWindowA(WC_BUTTONA, "OK", WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON,
10800d320bc2SAmine Khaldi                             5, 50, 100, 20, hMainWnd, NULL,
10810d320bc2SAmine Khaldi                             (HINSTANCE)GetWindowLongPtrA(hMainWnd, GWLP_HINSTANCE), NULL);
10820d320bc2SAmine Khaldi 
10830d320bc2SAmine Khaldi     old_parent_proc = (WNDPROC)SetWindowLongPtrA(hMainWnd, GWLP_WNDPROC, (ULONG_PTR)test_window_proc);
10840d320bc2SAmine Khaldi     edit_window_proc = (WNDPROC)SetWindowLongPtrA(hEdit, GWLP_WNDPROC, (ULONG_PTR)combobox_subclass_proc);
10850d320bc2SAmine Khaldi 
10860d320bc2SAmine Khaldi     SendMessageA(hCombo, WM_SETFOCUS, 0, (LPARAM)hEdit);
10870d320bc2SAmine Khaldi     ok(setsel_start == 0, "Unexpected EM_SETSEL start value; got %ld\n", setsel_start);
10880d320bc2SAmine Khaldi     todo_wine ok(setsel_end == INT_MAX, "Unexpected EM_SETSEL end value; got %ld\n", setsel_end);
10890d320bc2SAmine Khaldi     ok(hCBN_SetFocus == hCombo, "Wrong handle set by CBN_SETFOCUS; got %p\n", hCBN_SetFocus);
10900d320bc2SAmine Khaldi     ok(GetFocus() == hEdit, "hEdit should have keyboard focus\n");
10910d320bc2SAmine Khaldi 
10920d320bc2SAmine Khaldi     SendMessageA(hMainWnd, WM_NEXTDLGCTL, (WPARAM)hButton, TRUE);
10930d320bc2SAmine Khaldi     ok(setsel_start == 0, "Unexpected EM_SETSEL start value; got %ld\n", setsel_start);
10940d320bc2SAmine Khaldi     todo_wine ok(setsel_end == 0, "Unexpected EM_SETSEL end value; got %ld\n", setsel_end);
10950d320bc2SAmine Khaldi     ok(hCBN_KillFocus == hCombo, "Wrong handle set by CBN_KILLFOCUS; got %p\n", hCBN_KillFocus);
10960d320bc2SAmine Khaldi     ok(GetFocus() == hButton, "hButton should have keyboard focus\n");
10970d320bc2SAmine Khaldi 
10980d320bc2SAmine Khaldi     SendMessageA(hCombo, WM_SETTEXT, 0, (LPARAM)wine_test);
10990d320bc2SAmine Khaldi     SendMessageA(hMainWnd, WM_NEXTDLGCTL, (WPARAM)hCombo, TRUE);
11000d320bc2SAmine Khaldi     ok(setsel_start == 0, "Unexpected EM_SETSEL start value; got %ld\n", setsel_start);
11010d320bc2SAmine Khaldi     todo_wine ok(setsel_end == INT_MAX, "Unexpected EM_SETSEL end value; got %ld\n", setsel_end);
11020d320bc2SAmine Khaldi     ok(hCBN_SetFocus == hCombo, "Wrong handle set by CBN_SETFOCUS; got %p\n", hCBN_SetFocus);
11030d320bc2SAmine Khaldi     ok(GetFocus() == hEdit, "hEdit should have keyboard focus\n");
11040d320bc2SAmine Khaldi     SendMessageA(hCombo, WM_GETTEXT, sizeof(buffer), (LPARAM)buffer);
11050d320bc2SAmine Khaldi     ok(!strcmp(buffer, wine_test), "Unexpected text in edit control; got '%s'\n", buffer);
11060d320bc2SAmine Khaldi 
11070d320bc2SAmine Khaldi     SendMessageA(hMainWnd, WM_NEXTDLGCTL, (WPARAM)hButton, TRUE);
11080d320bc2SAmine Khaldi     ok(setsel_start == 0, "Unexpected EM_SETSEL start value; got %ld\n", setsel_start);
11090d320bc2SAmine Khaldi     todo_wine ok(setsel_end == 0, "Unexpected EM_SETSEL end value; got %ld\n", setsel_end);
11100d320bc2SAmine Khaldi     ok(hCBN_KillFocus == hCombo, "Wrong handle set by CBN_KILLFOCUS; got %p\n", hCBN_KillFocus);
11110d320bc2SAmine Khaldi     ok(GetFocus() == hButton, "hButton should have keyboard focus\n");
11120d320bc2SAmine Khaldi     len = SendMessageA(hCombo, CB_GETEDITSEL, 0, 0);
11130d320bc2SAmine Khaldi     ok(len == 0, "Unexpected text selection; start: %u, end: %u\n", LOWORD(len), HIWORD(len));
11140d320bc2SAmine Khaldi 
11150d320bc2SAmine Khaldi     SetWindowLongPtrA(hMainWnd, GWLP_WNDPROC, (ULONG_PTR)old_parent_proc);
11160d320bc2SAmine Khaldi     DestroyWindow(hButton);
11170d320bc2SAmine Khaldi     DestroyWindow(hCombo);
11180d320bc2SAmine Khaldi }
11190d320bc2SAmine Khaldi 
test_combo_listbox_styles(DWORD cb_style)11200d320bc2SAmine Khaldi static void test_combo_listbox_styles(DWORD cb_style)
11210d320bc2SAmine Khaldi {
11220d320bc2SAmine Khaldi     DWORD style, exstyle, expect_style, expect_exstyle;
11230d320bc2SAmine Khaldi     COMBOBOXINFO info;
11240d320bc2SAmine Khaldi     HWND combo;
11250d320bc2SAmine Khaldi 
11260d320bc2SAmine Khaldi     expect_style = WS_CHILD|WS_CLIPSIBLINGS|LBS_COMBOBOX|LBS_HASSTRINGS|LBS_NOTIFY;
11270d320bc2SAmine Khaldi     if (cb_style == CBS_SIMPLE)
11280d320bc2SAmine Khaldi     {
11290d320bc2SAmine Khaldi         expect_style |= WS_VISIBLE;
11300d320bc2SAmine Khaldi         expect_exstyle = WS_EX_CLIENTEDGE;
11310d320bc2SAmine Khaldi     }
11320d320bc2SAmine Khaldi     else
11330d320bc2SAmine Khaldi     {
11340d320bc2SAmine Khaldi         expect_style |= WS_BORDER;
11350d320bc2SAmine Khaldi         expect_exstyle = WS_EX_TOOLWINDOW;
11360d320bc2SAmine Khaldi     }
11370d320bc2SAmine Khaldi 
11380d320bc2SAmine Khaldi     combo = create_combobox(cb_style);
11390d320bc2SAmine Khaldi     get_combobox_info(combo, &info);
11400d320bc2SAmine Khaldi 
11410d320bc2SAmine Khaldi     style = GetWindowLongW( info.hwndList, GWL_STYLE );
11420d320bc2SAmine Khaldi     exstyle = GetWindowLongW( info.hwndList, GWL_EXSTYLE );
11430d320bc2SAmine Khaldi     ok(style == expect_style, "%08x: got %08x\n", cb_style, style);
11440d320bc2SAmine Khaldi     ok(exstyle == expect_exstyle, "%08x: got %08x\n", cb_style, exstyle);
11450d320bc2SAmine Khaldi 
11460d320bc2SAmine Khaldi     if (cb_style != CBS_SIMPLE)
11470d320bc2SAmine Khaldi         expect_exstyle |= WS_EX_TOPMOST;
11480d320bc2SAmine Khaldi 
11490d320bc2SAmine Khaldi     SendMessageW(combo, CB_SHOWDROPDOWN, TRUE, 0 );
11500d320bc2SAmine Khaldi     style = GetWindowLongW( info.hwndList, GWL_STYLE );
11510d320bc2SAmine Khaldi     exstyle = GetWindowLongW( info.hwndList, GWL_EXSTYLE );
11520d320bc2SAmine Khaldi     ok(style == (expect_style | WS_VISIBLE), "%08x: got %08x\n", cb_style, style);
11530d320bc2SAmine Khaldi     ok(exstyle == expect_exstyle, "%08x: got %08x\n", cb_style, exstyle);
11540d320bc2SAmine Khaldi 
11550d320bc2SAmine Khaldi     SendMessageW(combo, CB_SHOWDROPDOWN, FALSE, 0 );
11560d320bc2SAmine Khaldi     style = GetWindowLongW( info.hwndList, GWL_STYLE );
11570d320bc2SAmine Khaldi     exstyle = GetWindowLongW( info.hwndList, GWL_EXSTYLE );
11580d320bc2SAmine Khaldi     ok(style == expect_style, "%08x: got %08x\n", cb_style, style);
11590d320bc2SAmine Khaldi     ok(exstyle == expect_exstyle, "%08x: got %08x\n", cb_style, exstyle);
11600d320bc2SAmine Khaldi 
11610d320bc2SAmine Khaldi     DestroyWindow(combo);
11620d320bc2SAmine Khaldi }
11630d320bc2SAmine Khaldi 
test_combo_WS_VSCROLL(void)11640d320bc2SAmine Khaldi static void test_combo_WS_VSCROLL(void)
11650d320bc2SAmine Khaldi {
11660d320bc2SAmine Khaldi     HWND hCombo, hList;
11670d320bc2SAmine Khaldi     COMBOBOXINFO info;
11680d320bc2SAmine Khaldi     DWORD style;
11690d320bc2SAmine Khaldi     int i;
11700d320bc2SAmine Khaldi 
11710d320bc2SAmine Khaldi     hCombo = create_combobox(CBS_DROPDOWNLIST);
11720d320bc2SAmine Khaldi 
11730d320bc2SAmine Khaldi     get_combobox_info(hCombo, &info);
11740d320bc2SAmine Khaldi     hList = info.hwndList;
11750d320bc2SAmine Khaldi 
11760d320bc2SAmine Khaldi     for (i = 0; i < 3; i++)
11770d320bc2SAmine Khaldi     {
11780d320bc2SAmine Khaldi         char buffer[2];
11790d320bc2SAmine Khaldi         sprintf(buffer, "%d", i);
11800d320bc2SAmine Khaldi         SendMessageA(hCombo, CB_ADDSTRING, 0, (LPARAM)buffer);
11810d320bc2SAmine Khaldi     }
11820d320bc2SAmine Khaldi 
11830d320bc2SAmine Khaldi     style = GetWindowLongA(info.hwndList, GWL_STYLE);
11840d320bc2SAmine Khaldi     SetWindowLongA(hList, GWL_STYLE, style | WS_VSCROLL);
11850d320bc2SAmine Khaldi 
11860d320bc2SAmine Khaldi     SendMessageA(hCombo, CB_SHOWDROPDOWN, TRUE, 0);
11870d320bc2SAmine Khaldi     SendMessageA(hCombo, CB_SHOWDROPDOWN, FALSE, 0);
11880d320bc2SAmine Khaldi 
11890d320bc2SAmine Khaldi     style = GetWindowLongA(hList, GWL_STYLE);
11900d320bc2SAmine Khaldi     ok((style & WS_VSCROLL) != 0, "Style does not include WS_VSCROLL\n");
11910d320bc2SAmine Khaldi 
11920d320bc2SAmine Khaldi     DestroyWindow(hCombo);
11930d320bc2SAmine Khaldi }
11940d320bc2SAmine Khaldi 
test_combo_dropdown_size(DWORD style)1195f37104daSAmine Khaldi static void test_combo_dropdown_size(DWORD style)
1196f37104daSAmine Khaldi {
1197f37104daSAmine Khaldi     static const char wine_test[] = "Wine Test";
1198f37104daSAmine Khaldi     HWND hCombo, hList;
1199f37104daSAmine Khaldi     COMBOBOXINFO cbInfo;
1200f37104daSAmine Khaldi     int i, test, ret;
1201f37104daSAmine Khaldi 
1202f37104daSAmine Khaldi     static const struct list_size_info
1203f37104daSAmine Khaldi     {
1204f37104daSAmine Khaldi         int num_items;
1205f37104daSAmine Khaldi         int height_combo;
1206f37104daSAmine Khaldi         int limit;
1207f37104daSAmine Khaldi     } info_height[] = {
1208f37104daSAmine Khaldi         {33, 50, -1},
12095f7243b5SAmine Khaldi         {35, 100, 40},
1210f37104daSAmine Khaldi         {15, 50, 3},
1211f37104daSAmine Khaldi     };
1212f37104daSAmine Khaldi 
12135f7243b5SAmine Khaldi     for (test = 0; test < ARRAY_SIZE(info_height); test++)
1214f37104daSAmine Khaldi     {
1215f37104daSAmine Khaldi         const struct list_size_info *info_test = &info_height[test];
1216f37104daSAmine Khaldi         int height_item; /* Height of a list item */
1217f37104daSAmine Khaldi         int height_list; /* Height of the list we got */
1218f37104daSAmine Khaldi         int expected_height_list;
1219f37104daSAmine Khaldi         RECT rect_list_client;
1220f37104daSAmine Khaldi         int min_visible_expected;
1221f37104daSAmine Khaldi 
1222f37104daSAmine Khaldi         hCombo = CreateWindowA(WC_COMBOBOXA, "Combo", CBS_DROPDOWN | WS_VISIBLE | WS_CHILD | style, 5, 5, 100,
1223f37104daSAmine Khaldi                 info_test->height_combo, hMainWnd, (HMENU)COMBO_ID, NULL, 0);
1224f37104daSAmine Khaldi 
1225f37104daSAmine Khaldi         min_visible_expected = SendMessageA(hCombo, CB_GETMINVISIBLE, 0, 0);
1226f37104daSAmine Khaldi         ok(min_visible_expected == 30, "Unexpected number of items %d.\n", min_visible_expected);
1227f37104daSAmine Khaldi 
1228f37104daSAmine Khaldi         cbInfo.cbSize = sizeof(COMBOBOXINFO);
1229f37104daSAmine Khaldi         ret = SendMessageA(hCombo, CB_GETCOMBOBOXINFO, 0, (LPARAM)&cbInfo);
1230f37104daSAmine Khaldi         ok(ret, "Failed to get combo info, %d\n", ret);
1231f37104daSAmine Khaldi 
1232f37104daSAmine Khaldi         hList = cbInfo.hwndList;
1233f37104daSAmine Khaldi         for (i = 0; i < info_test->num_items; i++)
1234f37104daSAmine Khaldi         {
1235f37104daSAmine Khaldi             ret = SendMessageA(hCombo, CB_ADDSTRING, 0, (LPARAM) wine_test);
1236f37104daSAmine Khaldi             ok(ret == i, "Failed to add string %d, returned %d.\n", i, ret);
1237f37104daSAmine Khaldi         }
1238f37104daSAmine Khaldi 
1239f37104daSAmine Khaldi         if (info_test->limit != -1)
1240f37104daSAmine Khaldi         {
1241f37104daSAmine Khaldi             int min_visible_actual;
1242f37104daSAmine Khaldi             min_visible_expected = info_test->limit;
1243f37104daSAmine Khaldi 
1244f37104daSAmine Khaldi             ret = SendMessageA(hCombo, CB_SETMINVISIBLE, min_visible_expected, 0);
1245f37104daSAmine Khaldi             ok(ret, "Failed to set visible limit.\n");
1246f37104daSAmine Khaldi             min_visible_actual = SendMessageA(hCombo, CB_GETMINVISIBLE, 0, 0);
1247f37104daSAmine Khaldi             ok(min_visible_expected == min_visible_actual, "test %d: unexpected number of items %d.\n",
1248f37104daSAmine Khaldi                     test, min_visible_actual);
1249f37104daSAmine Khaldi         }
1250f37104daSAmine Khaldi 
1251f37104daSAmine Khaldi         ret = SendMessageA(hCombo, CB_SHOWDROPDOWN, TRUE,0);
1252f37104daSAmine Khaldi         ok(ret, "Failed to show dropdown.\n");
1253f37104daSAmine Khaldi         ret = SendMessageA(hCombo, CB_GETDROPPEDSTATE, 0, 0);
1254f37104daSAmine Khaldi         ok(ret, "Unexpected dropped state.\n");
1255f37104daSAmine Khaldi 
1256f37104daSAmine Khaldi         GetClientRect(hList, &rect_list_client);
1257f37104daSAmine Khaldi         height_list = rect_list_client.bottom - rect_list_client.top;
1258f37104daSAmine Khaldi         height_item = (int)SendMessageA(hList, LB_GETITEMHEIGHT, 0, 0);
1259f37104daSAmine Khaldi 
1260f37104daSAmine Khaldi         if (style & CBS_NOINTEGRALHEIGHT)
1261f37104daSAmine Khaldi         {
1262f37104daSAmine Khaldi             RECT rect_list_complete;
1263f37104daSAmine Khaldi             int list_height_nonclient;
1264f37104daSAmine Khaldi             int list_height_calculated;
1265f37104daSAmine Khaldi             int edit_padding_size = cbInfo.rcItem.top; /* edit client rect top is the padding it has to its parent
1266f37104daSAmine Khaldi                                                           We assume it's the same on the bottom */
1267f37104daSAmine Khaldi 
1268f37104daSAmine Khaldi             GetWindowRect(hList, &rect_list_complete);
1269f37104daSAmine Khaldi 
1270f37104daSAmine Khaldi             list_height_nonclient = (rect_list_complete.bottom - rect_list_complete.top)
1271f37104daSAmine Khaldi                                     - (rect_list_client.bottom - rect_list_client.top);
1272f37104daSAmine Khaldi 
1273f37104daSAmine Khaldi             /* Calculate the expected client size of the listbox popup from the size of the combobox. */
1274f37104daSAmine Khaldi             list_height_calculated = info_test->height_combo      /* Take height we created combobox with */
1275f37104daSAmine Khaldi                     - (cbInfo.rcItem.bottom - cbInfo.rcItem.top)  /* Subtract size of edit control */
1276f37104daSAmine Khaldi                     - list_height_nonclient                       /* Subtract list nonclient area */
1277f37104daSAmine Khaldi                     - edit_padding_size * 2;                      /* subtract space around the edit control */
1278f37104daSAmine Khaldi 
1279f37104daSAmine Khaldi             expected_height_list = min(list_height_calculated, height_item * info_test->num_items);
1280f37104daSAmine Khaldi             if (expected_height_list < 0)
1281f37104daSAmine Khaldi                 expected_height_list = 0;
1282f37104daSAmine Khaldi 
1283f37104daSAmine Khaldi             ok(expected_height_list == height_list, "Test %d, expected list height to be %d, got %d\n",
1284f37104daSAmine Khaldi                     test, expected_height_list, height_list);
1285f37104daSAmine Khaldi         }
1286f37104daSAmine Khaldi         else
1287f37104daSAmine Khaldi         {
1288f37104daSAmine Khaldi             expected_height_list = min(info_test->num_items, min_visible_expected) * height_item;
1289f37104daSAmine Khaldi 
1290f37104daSAmine Khaldi             ok(expected_height_list == height_list, "Test %d, expected list height to be %d, got %d\n",
1291f37104daSAmine Khaldi                     test, expected_height_list, height_list);
1292f37104daSAmine Khaldi         }
1293f37104daSAmine Khaldi 
1294f37104daSAmine Khaldi         DestroyWindow(hCombo);
1295f37104daSAmine Khaldi     }
1296f37104daSAmine Khaldi }
1297f37104daSAmine Khaldi 
test_combo_ctlcolor(void)1298*0707475fSJustin Miller static void test_combo_ctlcolor(void)
1299*0707475fSJustin Miller {
1300*0707475fSJustin Miller     static const int messages[] =
1301*0707475fSJustin Miller     {
1302*0707475fSJustin Miller         WM_CTLCOLOR,
1303*0707475fSJustin Miller         WM_CTLCOLORMSGBOX,
1304*0707475fSJustin Miller         WM_CTLCOLOREDIT,
1305*0707475fSJustin Miller         WM_CTLCOLORLISTBOX,
1306*0707475fSJustin Miller         WM_CTLCOLORBTN,
1307*0707475fSJustin Miller         WM_CTLCOLORDLG,
1308*0707475fSJustin Miller         WM_CTLCOLORSCROLLBAR,
1309*0707475fSJustin Miller         WM_CTLCOLORSTATIC,
1310*0707475fSJustin Miller     };
1311*0707475fSJustin Miller 
1312*0707475fSJustin Miller     HBRUSH brush, global_brush;
1313*0707475fSJustin Miller     COMBOBOXINFO info;
1314*0707475fSJustin Miller     unsigned int i;
1315*0707475fSJustin Miller     HWND combo;
1316*0707475fSJustin Miller 
1317*0707475fSJustin Miller     combo = create_combobox(CBS_DROPDOWN);
1318*0707475fSJustin Miller     ok(!!combo, "Failed to create combo window.\n");
1319*0707475fSJustin Miller 
1320*0707475fSJustin Miller     old_parent_proc = (void *)SetWindowLongPtrA(hMainWnd, GWLP_WNDPROC, (ULONG_PTR)parent_wnd_proc);
1321*0707475fSJustin Miller 
1322*0707475fSJustin Miller     get_combobox_info(combo, &info);
1323*0707475fSJustin Miller 
1324*0707475fSJustin Miller     lparam_for_WM_CTLCOLOR = info.hwndItem;
1325*0707475fSJustin Miller 
1326*0707475fSJustin Miller     /* Parent returns valid brush handle. */
1327*0707475fSJustin Miller     for (i = 0; i < ARRAY_SIZE(messages); ++i)
1328*0707475fSJustin Miller     {
1329*0707475fSJustin Miller         brush = (HBRUSH)SendMessageA(combo, messages[i], 0, (LPARAM)info.hwndItem);
1330*0707475fSJustin Miller         ok(brush == brush_red, "%u: unexpected brush %p, expected got %p.\n", i, brush, brush_red);
1331*0707475fSJustin Miller     }
1332*0707475fSJustin Miller 
1333*0707475fSJustin Miller     /* Parent returns NULL brush. */
1334*0707475fSJustin Miller     global_brush = brush_red;
1335*0707475fSJustin Miller     brush_red = NULL;
1336*0707475fSJustin Miller 
1337*0707475fSJustin Miller     for (i = 0; i < ARRAY_SIZE(messages); ++i)
1338*0707475fSJustin Miller     {
1339*0707475fSJustin Miller         brush = (HBRUSH)SendMessageA(combo, messages[i], 0, (LPARAM)info.hwndItem);
1340*0707475fSJustin Miller         ok(!brush, "%u: unexpected brush %p.\n", i, brush);
1341*0707475fSJustin Miller     }
1342*0707475fSJustin Miller 
1343*0707475fSJustin Miller     brush_red = global_brush;
1344*0707475fSJustin Miller 
1345*0707475fSJustin Miller     lparam_for_WM_CTLCOLOR = 0;
1346*0707475fSJustin Miller 
1347*0707475fSJustin Miller     /* Parent does default processing. */
1348*0707475fSJustin Miller     for (i = 0; i < ARRAY_SIZE(messages); ++i)
1349*0707475fSJustin Miller     {
1350*0707475fSJustin Miller         brush = (HBRUSH)SendMessageA(combo, messages[i], 0, (LPARAM)info.hwndItem);
1351*0707475fSJustin Miller         ok(!!brush && brush != brush_red, "%u: unexpected brush %p.\n", i, brush);
1352*0707475fSJustin Miller     }
1353*0707475fSJustin Miller 
1354*0707475fSJustin Miller     SetWindowLongPtrA(hMainWnd, GWLP_WNDPROC, (ULONG_PTR)old_parent_proc);
1355*0707475fSJustin Miller     DestroyWindow(combo);
1356*0707475fSJustin Miller 
1357*0707475fSJustin Miller     /* Combo without a parent. */
1358*0707475fSJustin Miller     combo = CreateWindowA(WC_COMBOBOXA, "Combo", CBS_DROPDOWN, 5, 5, 100, 100, NULL, NULL, NULL, 0);
1359*0707475fSJustin Miller     ok(!!combo, "Failed to create combo window.\n");
1360*0707475fSJustin Miller 
1361*0707475fSJustin Miller     get_combobox_info(combo, &info);
1362*0707475fSJustin Miller 
1363*0707475fSJustin Miller     for (i = 0; i < ARRAY_SIZE(messages); ++i)
1364*0707475fSJustin Miller     {
1365*0707475fSJustin Miller         brush = (HBRUSH)SendMessageA(combo, messages[i], 0, (LPARAM)info.hwndItem);
1366*0707475fSJustin Miller         ok(!brush, "%u: unexpected brush %p.\n", i, brush);
1367*0707475fSJustin Miller     }
1368*0707475fSJustin Miller 
1369*0707475fSJustin Miller     DestroyWindow(combo);
1370*0707475fSJustin Miller }
1371*0707475fSJustin Miller 
START_TEST(combo)13720d320bc2SAmine Khaldi START_TEST(combo)
13730d320bc2SAmine Khaldi {
13740d320bc2SAmine Khaldi     ULONG_PTR ctx_cookie;
13750d320bc2SAmine Khaldi     HANDLE hCtx;
13760d320bc2SAmine Khaldi 
1377f37104daSAmine Khaldi     init_functions();
1378f37104daSAmine Khaldi 
13790d320bc2SAmine Khaldi     if (!init())
13800d320bc2SAmine Khaldi         return;
13810d320bc2SAmine Khaldi 
13820d320bc2SAmine Khaldi     init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
13830d320bc2SAmine Khaldi 
13840d320bc2SAmine Khaldi     /* ComboBoxEx32 tests. */
13850d320bc2SAmine Khaldi     test_comboex();
13860d320bc2SAmine Khaldi     test_comboex_WM_LBUTTONDOWN();
13870d320bc2SAmine Khaldi     test_comboex_CB_GETLBTEXT();
13880d320bc2SAmine Khaldi     test_comboex_WM_WINDOWPOSCHANGING();
13890d320bc2SAmine Khaldi     test_comboex_subclass();
13900d320bc2SAmine Khaldi     test_comboex_get_set_item();
13910d320bc2SAmine Khaldi 
13920d320bc2SAmine Khaldi     if (!load_v6_module(&ctx_cookie, &hCtx))
13930d320bc2SAmine Khaldi     {
13940d320bc2SAmine Khaldi         cleanup();
13950d320bc2SAmine Khaldi         return;
13960d320bc2SAmine Khaldi     }
13970d320bc2SAmine Khaldi 
13980d320bc2SAmine Khaldi     /* ComboBox control tests. */
13990d320bc2SAmine Khaldi     test_combo_WS_VSCROLL();
14000d320bc2SAmine Khaldi     test_combo_setfont(CBS_DROPDOWN);
14010d320bc2SAmine Khaldi     test_combo_setfont(CBS_DROPDOWNLIST);
14020d320bc2SAmine Khaldi     test_combo_setitemheight(CBS_DROPDOWN);
14030d320bc2SAmine Khaldi     test_combo_setitemheight(CBS_DROPDOWNLIST);
14040d320bc2SAmine Khaldi     test_combo_CBN_SELCHANGE();
14050d320bc2SAmine Khaldi     test_combo_changesize(CBS_DROPDOWN);
14060d320bc2SAmine Khaldi     test_combo_changesize(CBS_DROPDOWNLIST);
14070d320bc2SAmine Khaldi     test_combo_editselection();
14080d320bc2SAmine Khaldi     test_combo_editselection_focus(CBS_SIMPLE);
14090d320bc2SAmine Khaldi     test_combo_editselection_focus(CBS_DROPDOWN);
14100d320bc2SAmine Khaldi     test_combo_listbox_styles(CBS_SIMPLE);
14110d320bc2SAmine Khaldi     test_combo_listbox_styles(CBS_DROPDOWN);
14120d320bc2SAmine Khaldi     test_combo_listbox_styles(CBS_DROPDOWNLIST);
1413f37104daSAmine Khaldi     test_combo_dropdown_size(0);
1414f37104daSAmine Khaldi     test_combo_dropdown_size(CBS_NOINTEGRALHEIGHT);
1415*0707475fSJustin Miller     test_combo_ctlcolor();
14160d320bc2SAmine Khaldi 
14170d320bc2SAmine Khaldi     cleanup();
14180d320bc2SAmine Khaldi     unload_v6_module(ctx_cookie, hCtx);
14190d320bc2SAmine Khaldi }
1420