Commit 9eedcf58 authored by Serge Ivanov's avatar Serge Ivanov Committed by Alexandre Julliard

- Removed dependency of edit control from combobox implementation.

- Edit control uses undocumented window style 0x0200 to detect is it a part of combobox. If so it calls GetDlgItem(hwndCombo, 1000) to get ComboLBox window handle (see comments for combo.c below). - EDIT_CheckCombo - modified for correct handling of keyboard messages. - Processing of WM_GETDLGCODE and WM_CHAR for VK_RETURN and VK_ESCAPE depends on whether listbox is dropped down. This prevents closing of dialog if listbox is dropped down and allows combobox to process these keyboard messages properly.
parent 07917e40
......@@ -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;
/********************************************************************
* 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;
TRACE_(combo)("[%04x]: handling msg %04x (%04x)\n",
wnd->hwndSelf, (UINT16)msg, (UINT16)key);
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;
HWND hLBox = es->hwndListBox;
HWND hCombo;
BOOL bDropped;
int nEUI;
if (!hLBox)
return FALSE;
hCombo = wnd->parent->hwndSelf;
bDropped = TRUE;
nEUI = 0;
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);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment