Dylan Smith : comctl32: Added tests to show a ComboBoxEx bug caused by incorrect focus change.
Alexandre Julliard
julliard at winehq.org
Fri Jul 4 13:59:13 CDT 2008
Module: wine
Branch: master
Commit: da0175ba71062a6963b53df3de4bbd1a1e3dd9c5
URL: http://source.winehq.org/git/wine.git/?a=commit;h=da0175ba71062a6963b53df3de4bbd1a1e3dd9c5
Author: Dylan Smith <dylan.ah.smith at gmail.com>
Date: Thu Jul 3 11:37:10 2008 -0400
comctl32: Added tests to show a ComboBoxEx bug caused by incorrect focus change.
Certain WM_LBUTTONDOWN & WM_LBUTTONUP events should change focus to the
ComboBox (a child of ComboBoxEx), but instead the focus was set to the
Edit control.
---
dlls/comctl32/tests/comboex.c | 102 ++++++++++++++++++++++++++++++++++++++++-
dlls/user32/tests/combo.c | 88 +++++++++++++++++++++++++++++++++++
2 files changed, 189 insertions(+), 1 deletions(-)
diff --git a/dlls/comctl32/tests/comboex.c b/dlls/comctl32/tests/comboex.c
index ad58643..dbd9c6e 100644
--- a/dlls/comctl32/tests/comboex.c
+++ b/dlls/comctl32/tests/comboex.c
@@ -169,7 +169,106 @@ static void test_comboboxex(void) {
/* Cleanup */
HeapFree(GetProcessHeap(), 0, textBuffer);
+ DestroyWindow(myHwnd);
+}
+
+static void test_WM_LBUTTONDOWN(void)
+{
+ HWND hComboEx, hCombo, hEdit, hList;
+ COMBOBOXINFO cbInfo;
+ UINT x, y, item_height;
+ LRESULT result;
+ int i, idx;
+ RECT rect;
+ WCHAR buffer[3];
+ static const UINT choices[] = {8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72};
+ static const WCHAR stringFormat[] = {'%','2','d','\0'};
+
+ hComboEx = CreateWindowExA(0, WC_COMBOBOXEXA, NULL,
+ WS_VISIBLE|WS_CHILD|CBS_DROPDOWN, 0, 0, 200, 150,
+ hComboExParentWnd, NULL, hMainHinst, NULL);
+
+ for (i = 0; i < sizeof(choices)/sizeof(UINT); i++){
+ COMBOBOXEXITEMW cbexItem;
+ wsprintfW(buffer, stringFormat, choices[i]);
+
+ memset(&cbexItem, 0x00, sizeof(cbexItem));
+ cbexItem.mask = CBEIF_TEXT;
+ cbexItem.iItem = i;
+ cbexItem.pszText = buffer;
+ cbexItem.cchTextMax = 0;
+ ok(SendMessageW(hComboEx, CBEM_INSERTITEMW, 0, (LPARAM)&cbexItem) >= 0,
+ "Failed to add item %d\n", i);
+ }
+ hCombo = (HWND)SendMessage(hComboEx, CBEM_GETCOMBOCONTROL, 0, 0);
+ hEdit = (HWND)SendMessage(hComboEx, CBEM_GETEDITCONTROL, 0, 0);
+
+ cbInfo.cbSize = sizeof(COMBOBOXINFO);
+ result = SendMessage(hCombo, CB_GETCOMBOBOXINFO, 0, (LPARAM)&cbInfo);
+ ok(result, "Failed to get combobox info structure. LastError=%d\n",
+ GetLastError());
+ hList = cbInfo.hwndList;
+
+ trace("hWnd=%p, hComboEx=%p, hCombo=%p, hList=%p, hEdit=%p\n",
+ hComboExParentWnd, hComboEx, hCombo, hList, hEdit);
+ ok(GetFocus() == hComboExParentWnd,
+ "Focus not on Main Window, instead on %p\n", GetFocus());
+
+ /* Click on the button to drop down the list */
+ x = cbInfo.rcButton.left + (cbInfo.rcButton.right-cbInfo.rcButton.left)/2;
+ y = cbInfo.rcButton.top + (cbInfo.rcButton.bottom-cbInfo.rcButton.top)/2;
+ result = SendMessage(hCombo, WM_LBUTTONDOWN, 0, MAKELPARAM(x, y));
+ ok(result, "WM_LBUTTONDOWN was not processed. LastError=%d\n",
+ GetLastError());
+ todo_wine ok(GetFocus() == hCombo,
+ "Focus not on ComboBoxEx's ComboBox Control, instead on %p\n",
+ GetFocus());
+ ok(SendMessage(hComboEx, CB_GETDROPPEDSTATE, 0, 0),
+ "The dropdown list should have appeared after clicking the button.\n");
+ idx = SendMessage(hCombo, CB_GETTOPINDEX, 0, 0);
+ ok(idx == 0, "For TopIndex expected %d, got %d\n", 0, idx);
+
+ result = SendMessage(hCombo, WM_LBUTTONUP, 0, MAKELPARAM(x, y));
+ ok(result, "WM_LBUTTONUP was not processed. LastError=%d\n",
+ GetLastError());
+ todo_wine ok(GetFocus() == hCombo,
+ "Focus not on ComboBoxEx's ComboBox Control, instead on %p\n",
+ GetFocus());
+
+ /* Click on the 5th item in the list */
+ item_height = SendMessage(hCombo, CB_GETITEMHEIGHT, 0, 0);
+ ok(GetClientRect(hList, &rect), "Failed to get list's client rect.\n");
+ x = rect.left + (rect.right-rect.left)/2;
+ y = item_height/2 + item_height*4;
+ result = SendMessage(hList, WM_MOUSEMOVE, 0, MAKELPARAM(x, y));
+ ok(!result, "WM_MOUSEMOVE was not processed. LastError=%d\n",
+ GetLastError());
+ todo_wine ok(GetFocus() == hCombo,
+ "Focus not on ComboBoxEx's ComboBox Control, instead on %p\n",
+ GetFocus());
+
+ result = SendMessage(hList, WM_LBUTTONDOWN, 0, MAKELPARAM(x, y));
+ ok(!result, "WM_LBUTTONDOWN was not processed. LastError=%d\n",
+ GetLastError());
+ todo_wine ok(GetFocus() == hCombo,
+ "Focus not on ComboBoxEx's ComboBox Control, instead on %p\n",
+ GetFocus());
+ todo_wine ok(SendMessage(hComboEx, CB_GETDROPPEDSTATE, 0, 0),
+ "The dropdown list should still be visible.\n");
+
+ result = SendMessage(hList, WM_LBUTTONUP, 0, MAKELPARAM(x, y));
+ ok(!result, "WM_LBUTTONUP was not processed. LastError=%d\n",
+ GetLastError());
+ ok(GetFocus() == hEdit,
+ "Focus not on ComboBoxEx's Edit Control, instead on %p\n",
+ GetFocus());
+ ok(!SendMessage(hCombo, CB_GETDROPPEDSTATE, 0, 0),
+ "The dropdown list should have been rolled up.\n");
+ idx = SendMessage(hComboEx, CB_GETCURSEL, 0, 0);
+ ok(idx == 4, "Current Selection: expected %d, got %d\n", 4, idx);
+
+ DestroyWindow(hComboEx);
}
static LRESULT CALLBACK ComboExTestWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
@@ -217,7 +316,7 @@ static int init(void)
wc.lpfnWndProc = ComboExTestWndProc;
RegisterClassA(&wc);
- hComboExParentWnd = CreateWindowExA(0, ComboExTestClass, "ComboEx test", WS_OVERLAPPEDWINDOW,
+ hComboExParentWnd = CreateWindowExA(0, ComboExTestClass, "ComboEx test", WS_OVERLAPPEDWINDOW|WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, 680, 260, NULL, NULL, GetModuleHandleA(NULL), 0);
assert(hComboExParentWnd != NULL);
@@ -244,6 +343,7 @@ START_TEST(comboex)
return;
test_comboboxex();
+ test_WM_LBUTTONDOWN();
cleanup();
}
diff --git a/dlls/user32/tests/combo.c b/dlls/user32/tests/combo.c
index 34d8c7a..d47ff20 100644
--- a/dlls/user32/tests/combo.c
+++ b/dlls/user32/tests/combo.c
@@ -265,6 +265,93 @@ static void test_CBN_SELCHANGE(void)
test_selection(CBS_DROPDOWNLIST, text, sel_2, sel_2);
}
+static void test_WM_LBUTTONDOWN(void)
+{
+ HWND hCombo, hEdit, hList;
+ COMBOBOXINFO cbInfo;
+ UINT x, y, item_height;
+ LRESULT result;
+ int i, idx;
+ RECT rect;
+ WCHAR buffer[3];
+ static const UINT choices[] = {8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72};
+ static const WCHAR stringFormat[] = {'%','2','d','\0'};
+
+ hCombo = CreateWindow("ComboBox", "Combo", WS_VISIBLE|WS_CHILD|CBS_DROPDOWN,
+ 0, 0, 200, 150, hMainWnd, (HMENU)COMBO_ID, NULL, 0);
+
+ for (i = 0; i < sizeof(choices)/sizeof(UINT); i++){
+ wsprintfW(buffer, stringFormat, choices[i]);
+ ok(SendMessageW(hCombo, CB_ADDSTRING, 0, (LPARAM)&buffer) != CB_ERR,
+ "Failed to add item %d\n", i);
+ }
+
+ cbInfo.cbSize = sizeof(COMBOBOXINFO);
+ result = SendMessage(hCombo, CB_GETCOMBOBOXINFO, 0, (LPARAM)&cbInfo);
+ ok(result, "Failed to get combobox info structure. LastError=%d\n",
+ GetLastError());
+ hEdit = cbInfo.hwndItem;
+ hList = cbInfo.hwndList;
+
+ trace("hMainWnd=%x, hCombo=%x, hList=%x, hEdit=%x\n",
+ (UINT)hMainWnd, (UINT)hCombo, (UINT)hList, (UINT)hEdit);
+ ok(GetFocus() == hMainWnd, "Focus not on Main Window, instead on %x\n",
+ (UINT)GetFocus());
+
+ /* Click on the button to drop down the list */
+ x = cbInfo.rcButton.left + (cbInfo.rcButton.right-cbInfo.rcButton.left)/2;
+ y = cbInfo.rcButton.top + (cbInfo.rcButton.bottom-cbInfo.rcButton.top)/2;
+ result = SendMessage(hCombo, WM_LBUTTONDOWN, 0, MAKELPARAM(x, y));
+ ok(result, "WM_LBUTTONDOWN was not processed. LastError=%d\n",
+ GetLastError());
+ ok(SendMessage(hCombo, CB_GETDROPPEDSTATE, 0, 0),
+ "The dropdown list should have appeared after clicking the button.\n");
+
+ ok(GetFocus() == hEdit,
+ "Focus not on ComboBox's Edit Control, instead on %x\n",
+ (UINT)GetFocus());
+ result = SendMessage(hCombo, WM_LBUTTONUP, 0, MAKELPARAM(x, y));
+ ok(result, "WM_LBUTTONUP was not processed. LastError=%d\n",
+ GetLastError());
+ ok(GetFocus() == hEdit,
+ "Focus not on ComboBox's Edit Control, instead on %x\n",
+ (UINT)GetFocus());
+
+ /* Click on the 5th item in the list */
+ item_height = SendMessage(hCombo, CB_GETITEMHEIGHT, 0, 0);
+ ok(GetClientRect(hList, &rect), "Failed to get list's client rect.\n");
+ x = rect.left + (rect.right-rect.left)/2;
+ y = item_height/2 + item_height*4;
+ result = SendMessage(hList, WM_LBUTTONDOWN, 0, MAKELPARAM(x, y));
+ ok(!result, "WM_LBUTTONDOWN was not processed. LastError=%d\n",
+ GetLastError());
+ ok(GetFocus() == hEdit,
+ "Focus not on ComboBox's Edit Control, instead on %x\n",
+ (UINT)GetFocus());
+
+ result = SendMessage(hList, WM_MOUSEMOVE, 0, MAKELPARAM(x, y));
+ ok(!result, "WM_MOUSEMOVE was not processed. LastError=%d\n",
+ GetLastError());
+ ok(GetFocus() == hEdit,
+ "Focus not on ComboBox's Edit Control, instead on %x\n",
+ (UINT)GetFocus());
+ ok(SendMessage(hCombo, CB_GETDROPPEDSTATE, 0, 0),
+ "The dropdown list should still be visible.\n");
+
+ result = SendMessage(hList, WM_LBUTTONUP, 0, MAKELPARAM(x, y));
+ ok(!result, "WM_LBUTTONUP was not processed. LastError=%d\n",
+ GetLastError());
+ ok(GetFocus() == hEdit,
+ "Focus not on ComboBox's Edit Control, instead on %x\n",
+ (UINT)GetFocus());
+ ok(!SendMessage(hCombo, CB_GETDROPPEDSTATE, 0, 0),
+ "The dropdown list should have been rolled up.\n");
+ idx = SendMessage(hCombo, CB_GETCURSEL, 0, 0);
+ ok(idx, "Current Selection: expected %d, got %d\n", 4, idx);
+
+ DestroyWindow(hCombo);
+}
+
START_TEST(combo)
{
hMainWnd = CreateWindow("static", "Test", WS_OVERLAPPEDWINDOW, 10, 10, 300, 300, NULL, NULL, NULL, 0);
@@ -275,6 +362,7 @@ START_TEST(combo)
test_setitemheight(CBS_DROPDOWN);
test_setitemheight(CBS_DROPDOWNLIST);
test_CBN_SELCHANGE();
+ test_WM_LBUTTONDOWN();
DestroyWindow(hMainWnd);
}
More information about the wine-cvs
mailing list