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