diff --git a/controls/edit.c b/controls/edit.c index de3b35bea0a..0ef7b08e477 100644 --- a/controls/edit.c +++ b/controls/edit.c @@ -100,6 +100,7 @@ typedef struct INT y_offset; /* scroll offset in number of lines */ BOOL bCaptureState; /* flag indicating whether mouse was captured */ BOOL bEnableState; /* flag keeping the enable state */ + HWND hwndListBox; /* handle of ComboBox's listbox or NULL */ /* * only for multi line controls */ @@ -721,16 +722,31 @@ LRESULT WINAPI EditWndProc( HWND hwnd, UINT msg, case WM_GETDLGCODE: DPRINTF_EDIT_MSG32("WM_GETDLGCODE"); result = DLGC_HASSETSEL | DLGC_WANTCHARS | DLGC_WANTARROWS; - if (wnd->dwStyle & ES_WANTRETURN) + + if (lParam && (((LPMSG)lParam)->message == WM_KEYDOWN)) { - LPMSG msg = (LPMSG)lParam; - if (msg && (msg->message == WM_KEYDOWN) && (msg->wParam == VK_RETURN)) + int vk = (int)((LPMSG)lParam)->wParam; + + if ((wnd->dwStyle & ES_WANTRETURN) && vk == VK_RETURN) + { result |= DLGC_WANTMESSAGE; + } + else if (es->hwndListBox && (vk == VK_RETURN || vk == VK_ESCAPE)) + { + if (SendMessageA(wnd->parent->hwndSelf, CB_GETDROPPEDSTATE, 0, 0)) + result |= DLGC_WANTMESSAGE; + } } break; case WM_CHAR: DPRINTF_EDIT_MSG32("WM_CHAR"); + if (((CHAR)wParam == VK_RETURN || (CHAR)wParam == VK_ESCAPE) && es->hwndListBox) + { + if (SendMessageA(wnd->parent->hwndSelf, CB_GETDROPPEDSTATE, 0, 0)) + SendMessageA(wnd->parent->hwndSelf, WM_KEYDOWN, wParam, 0); + break; + } EDIT_WM_Char(wnd, es, (CHAR)wParam, (DWORD)lParam); break; @@ -3374,63 +3390,58 @@ static LRESULT EDIT_WM_HScroll(WND *wnd, EDITSTATE *es, INT action, INT pos, HWN * EDIT_CheckCombo * */ -static BOOL EDIT_CheckCombo(WND *wnd, UINT msg, INT key, DWORD key_data) +static BOOL EDIT_CheckCombo(WND *wnd, EDITSTATE *es, UINT msg, INT key, DWORD key_data) { - HWND hLBox; + HWND hLBox = es->hwndListBox; + HWND hCombo; + BOOL bDropped; + int nEUI; - /******************************************************************** - * This if statement used to check to see if the parent of the - * edit control was a 'combobox' by comparing the ATOM of the parent - * to a table of internal window control ATOMs. However, this check - * would fail if the parent was a superclassed combobox (Although - * having the same basic functionality of a combobox, it has a - * different name and ATOM, thus defeating this check.) - * - * The safe way to determine if the parent is a combobox is to send it - * a message only a combo box would understand. I send it a message - * CB_GETCOUNT, if I get 0 then the parent is not a combobox - - * return FALSE. If I get > 0, then the parent IS a combobox - * (or sub/super classed derrivative thereof) - ********************************************************************/ - if ( - ((SendMessageA(wnd->parent->hwndSelf, CB_GETCOUNT, 0, 0)) > 0) && - (hLBox = COMBO_GetLBWindow(wnd->parent)) - ) - { - HWND hCombo = wnd->parent->hwndSelf; - BOOL bUIFlip = TRUE; + if (!hLBox) + return FALSE; - TRACE_(combo)("[%04x]: handling msg %04x (%04x)\n", - wnd->hwndSelf, (UINT16)msg, (UINT16)key); + hCombo = wnd->parent->hwndSelf; + bDropped = TRUE; + nEUI = 0; - switch (msg) { - case WM_KEYDOWN: /* Handle F4 and arrow keys */ - if (key != VK_F4) { - bUIFlip = (BOOL)SendMessageA(hCombo, CB_GETEXTENDEDUI, 0, 0); - if (SendMessageA(hCombo, CB_GETDROPPEDSTATE, 0, 0)) - bUIFlip = FALSE; - } - if (!bUIFlip) - SendMessageA(hLBox, WM_KEYDOWN, (WPARAM)key, 0); - else { - /* make sure ComboLBox pops up */ - SendMessageA(hCombo, CB_SETEXTENDEDUI, 0, 0); - SendMessageA(hLBox, WM_KEYDOWN, VK_F4, 0); - SendMessageA(hCombo, CB_SETEXTENDEDUI, 1, 0); - } - break; - case WM_SYSKEYDOWN: /* Handle Alt+up/down arrows */ - bUIFlip = (BOOL)SendMessageA(hCombo, CB_GETEXTENDEDUI, 0, 0); - if (bUIFlip) { - bUIFlip = (BOOL)SendMessageA(hCombo, CB_GETDROPPEDSTATE, 0, 0); - SendMessageA(hCombo, CB_SHOWDROPDOWN, (bUIFlip) ? FALSE : TRUE, 0); - } else - SendMessageA(hLBox, WM_KEYDOWN, VK_F4, 0); - break; - } - return TRUE; - } - return FALSE; + TRACE_(combo)("[%04x]: handling msg %04x (%04x)\n", + wnd->hwndSelf, (UINT16)msg, (UINT16)key); + + if (key == VK_UP || key == VK_DOWN) + { + if (SendMessageA(hCombo, CB_GETEXTENDEDUI, 0, 0)) + nEUI = 1; + + if (msg == WM_KEYDOWN || nEUI) + bDropped = (BOOL)SendMessageA(hCombo, CB_GETDROPPEDSTATE, 0, 0); + } + + switch (msg) + { + case WM_KEYDOWN: + if (!bDropped && nEUI && (key == VK_UP || key == VK_DOWN)) + { + /* make sure ComboLBox pops up */ + SendMessageA(hCombo, CB_SETEXTENDEDUI, FALSE, 0); + key = VK_F4; + nEUI = 2; + } + + SendMessageA(hLBox, WM_KEYDOWN, (WPARAM)key, 0); + break; + + case WM_SYSKEYDOWN: /* Handle Alt+up/down arrows */ + if (nEUI) + SendMessageA(hCombo, CB_SHOWDROPDOWN, bDropped ? FALSE : TRUE, 0); + else + SendMessageA(hLBox, WM_KEYDOWN, (WPARAM)VK_F4, 0); + break; + } + + if(nEUI == 2) + SendMessageA(hCombo, CB_SETEXTENDEDUI, TRUE, 0); + + return TRUE; } @@ -3456,10 +3467,9 @@ static LRESULT EDIT_WM_KeyDown(WND *wnd, EDITSTATE *es, INT key, DWORD key_data) switch (key) { case VK_F4: case VK_UP: - if (EDIT_CheckCombo(wnd, WM_KEYDOWN, key, key_data)) - break; - if (key == VK_F4) + if (EDIT_CheckCombo(wnd, es, WM_KEYDOWN, key, key_data) || key == VK_F4) break; + /* fall through */ case VK_LEFT: if ((es->style & ES_MULTILINE) && (key == VK_UP)) @@ -3471,7 +3481,7 @@ static LRESULT EDIT_WM_KeyDown(WND *wnd, EDITSTATE *es, INT key, DWORD key_data) EDIT_MoveBackward(wnd, es, shift); break; case VK_DOWN: - if (EDIT_CheckCombo(wnd, WM_KEYDOWN, key, key_data)) + if (EDIT_CheckCombo(wnd, es, WM_KEYDOWN, key, key_data)) break; /* fall through */ case VK_RIGHT: @@ -3491,10 +3501,14 @@ static LRESULT EDIT_WM_KeyDown(WND *wnd, EDITSTATE *es, INT key, DWORD key_data) case VK_PRIOR: if (es->style & ES_MULTILINE) EDIT_MovePageUp_ML(wnd, es, shift); + else + EDIT_CheckCombo(wnd, es, WM_KEYDOWN, key, key_data); break; case VK_NEXT: if (es->style & ES_MULTILINE) EDIT_MovePageDown_ML(wnd, es, shift); + else + EDIT_CheckCombo(wnd, es, WM_KEYDOWN, key, key_data); break; case VK_DELETE: if (!(es->style & ES_READONLY) && !(shift && control)) { @@ -3720,6 +3734,9 @@ static LRESULT EDIT_WM_NCCreate(WND *wnd, LPCREATESTRUCTA cs) wnd->dwStyle &= ~WS_BORDER; } + if (es->style & ES_COMBO) + es->hwndListBox = GetDlgItem(cs->hwndParent, ID_CB_LISTBOX); + if (es->style & ES_MULTILINE) { es->buffer_size = BUFSTART_MULTI; es->buffer_limit = BUFLIMIT_MULTI; @@ -4022,9 +4039,10 @@ static LRESULT EDIT_WM_SysKeyDown(WND *wnd, EDITSTATE *es, INT key, DWORD key_da if (EDIT_EM_CanUndo(wnd, es)) EDIT_EM_Undo(wnd, es); return 0; - } else if (key == VK_UP || key == VK_DOWN) - if (EDIT_CheckCombo(wnd, WM_SYSKEYDOWN, key, key_data)) + } else if (key == VK_UP || key == VK_DOWN) { + if (EDIT_CheckCombo(wnd, es, WM_SYSKEYDOWN, key, key_data)) return 0; + } return DefWindowProcA(wnd->hwndSelf, WM_SYSKEYDOWN, (WPARAM)key, (LPARAM)key_data); }