- 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.
This commit is contained in:
Serge Ivanov 2000-06-07 03:47:34 +00:00 committed by Alexandre Julliard
parent 07917e40e8
commit 9eedcf5852

View file

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