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.
This commit is contained in:
Dylan Smith 2008-07-03 11:37:10 -04:00 committed by Alexandre Julliard
parent f094b4332d
commit da0175ba71
2 changed files with 189 additions and 1 deletions

View File

@ -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();
}

View File

@ -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);
}