[PATCH v4] user32/combo: Set listbox popup height correctly and add tests
Fabian Maurer
dark.shadow4 at web.de
Thu Aug 17 11:24:57 CDT 2017
v2: Calculate size instead of hardcoding it
v3: Removed debug comment
v4: Stop calling listbox listview
Signed-off-by: Fabian Maurer <dark.shadow4 at web.de>
---
dlls/user32/combo.c | 8 ----
dlls/user32/tests/combo.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 117 insertions(+), 8 deletions(-)
diff --git a/dlls/user32/combo.c b/dlls/user32/combo.c
index a2e8b3ce6c..f35e0d9296 100644
--- a/dlls/user32/combo.c
+++ b/dlls/user32/combo.c
@@ -1033,14 +1033,6 @@ static void CBDropDown( LPHEADCOMBO lphc )
if (nHeight < nDroppedHeight - COMBO_YBORDERSIZE())
nDroppedHeight = nHeight + COMBO_YBORDERSIZE();
-
- if (nDroppedHeight < nHeight)
- {
- if (nItems < 5)
- nDroppedHeight = (nItems+1)*nIHeight;
- else if (nDroppedHeight < 6*nIHeight)
- nDroppedHeight = 6*nIHeight;
- }
}
r.left = rect.left;
diff --git a/dlls/user32/tests/combo.c b/dlls/user32/tests/combo.c
index f52efae587..50c403b409 100644
--- a/dlls/user32/tests/combo.c
+++ b/dlls/user32/tests/combo.c
@@ -29,6 +29,8 @@
#define COMBO_ID 1995
+#define COMBO_YBORDERSIZE() 2
+
static HWND hMainWnd;
#define expect_eq(expr, value, type, fmt); { type val = expr; ok(val == (value), #expr " expected " #fmt " got " #fmt "\n", (value), val); }
@@ -700,6 +702,120 @@ static void test_listbox_styles(DWORD cb_style)
DestroyWindow(combo);
}
+struct list_size_info
+{
+ int num_items;
+ int height_combo;
+ BOOL todo;
+};
+
+static void test_listbox_size(DWORD style)
+{
+ BOOL (WINAPI *pGetComboBoxInfo)(HWND, PCOMBOBOXINFO);
+ HWND hCombo, hList;
+ COMBOBOXINFO cbInfo;
+ UINT x, y;
+ BOOL ret;
+ int i, test;
+ const char wine_test[] = "Wine Test";
+
+ static const struct list_size_info info_height[] = {
+ {2, 24},
+ {2, 41, TRUE},
+ {2, 42},
+ {2, 50},
+ {2, 60},
+ {2, 80},
+ {2, 89},
+ {2, 90},
+ {2, 100},
+
+ {10, 24},
+ {10, 41, TRUE},
+ {10, 42},
+ {10, 50},
+ {10, 60},
+ {10, 80},
+ {10, 89, TRUE},
+ {10, 90},
+ {10, 100},
+ };
+
+ pGetComboBoxInfo = (void *)GetProcAddress(GetModuleHandleA("user32.dll"), "GetComboBoxInfo");
+ if (!pGetComboBoxInfo)
+ {
+ win_skip("GetComboBoxInfo is not available\n");
+ return;
+ }
+
+ for(test = 0; test < sizeof(info_height) / sizeof(struct list_size_info); test++)
+ {
+ const struct list_size_info *info_test = &info_height[test];
+ int height_item; /* Height of a list item */
+ int height_list; /* Height of the list we got */
+ int expected_count_list;
+ int expected_height_list;
+ int list_height_nonclient;
+ int list_height_calculated;
+ RECT rect_list_client, rect_list_complete;
+
+ hCombo = CreateWindowA("ComboBox", "Combo", WS_VISIBLE|WS_CHILD|style, 5, 5, 100,
+ info_test->height_combo, hMainWnd, (HMENU)COMBO_ID, NULL, 0);
+
+ cbInfo.cbSize = sizeof(COMBOBOXINFO);
+ SetLastError(0xdeadbeef);
+ ret = pGetComboBoxInfo(hCombo, &cbInfo);
+ ok(ret, "Failed to get COMBOBOXINFO structure; LastError: %u\n", GetLastError());
+
+ hList = cbInfo.hwndList;
+ for (i = 0; i < info_test->num_items; i++)
+ SendMessageA(hCombo, CB_ADDSTRING, 0, (LPARAM) wine_test);
+
+ /* Click on the button to drop down the list */
+ x = cbInfo.rcButton.left + (cbInfo.rcButton.right-cbInfo.rcButton.left)/2;
+ y = cbInfo.rcButton.top + (cbInfo.rcButton.bottom-cbInfo.rcButton.top)/2;
+ ret = SendMessageA(hCombo, WM_LBUTTONDOWN, 0, MAKELPARAM(x, y));
+ ok(ret, "WM_LBUTTONDOWN was not processed. LastError=%d\n",
+ GetLastError());
+ ok(SendMessageA(hCombo, CB_GETDROPPEDSTATE, 0, 0),
+ "The dropdown list should have appeared after clicking the button.\n");
+
+ GetClientRect(hList, &rect_list_client);
+ GetWindowRect(hList, &rect_list_complete);
+ height_list = rect_list_client.bottom - rect_list_client.top;
+ height_item = (int)SendMessageA(hList, LB_GETITEMHEIGHT, 0, 0);
+
+ list_height_nonclient = (rect_list_complete.bottom - rect_list_complete.top)
+ - (rect_list_client.bottom - rect_list_client.top);
+
+ /* Calculate the expected client size of the listbox popup from the size of the combobox.
+ Calculation taken from wine, but wine doesn't pass the tests yet, so a fix is added for windows machines */
+ list_height_calculated = info_test->height_combo
+ - (cbInfo.rcItem.bottom + COMBO_YBORDERSIZE()) /* Taken from user32/combo.c:COMBO_Create */
+ - list_height_nonclient
+ - 1; /* Found through experimentation, needed to pass the tests */
+
+ expected_count_list = list_height_calculated / height_item;
+ if(expected_count_list < 0)
+ expected_count_list = 0;
+ expected_count_list = min(expected_count_list, info_test->num_items);
+ expected_height_list = expected_count_list * height_item;
+
+ if(info_test->todo)
+ {
+ todo_wine ok(expected_height_list == height_list,
+ "Test %d, expected list height to be %d, got %d\n", test, expected_height_list, height_list);
+ }
+ else
+ {
+ ok(expected_height_list == height_list,
+ "Test %d, expected list height to be %d, got %d\n", test, expected_height_list, height_list);
+ }
+
+ DestroyWindow(hCombo);
+ }
+}
+
START_TEST(combo)
{
hMainWnd = CreateWindowA("static", "Test", WS_OVERLAPPEDWINDOW, 10, 10, 300, 300, NULL, NULL, NULL, 0);
@@ -719,6 +835,7 @@ START_TEST(combo)
test_listbox_styles(CBS_SIMPLE);
test_listbox_styles(CBS_DROPDOWN);
test_listbox_styles(CBS_DROPDOWNLIST);
+ test_listbox_size(CBS_DROPDOWN);
DestroyWindow(hMainWnd);
}
--
2.14.1
More information about the wine-patches
mailing list