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