- 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:
parent
07917e40e8
commit
9eedcf5852
122
controls/edit.c
122
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))
|
||||
{
|
||||
int vk = (int)((LPMSG)lParam)->wParam;
|
||||
|
||||
if ((wnd->dwStyle & ES_WANTRETURN) && vk == VK_RETURN)
|
||||
{
|
||||
LPMSG msg = (LPMSG)lParam;
|
||||
if (msg && (msg->message == WM_KEYDOWN) && (msg->wParam == 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,64 +3390,59 @@ 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;
|
||||
|
||||
hCombo = wnd->parent->hwndSelf;
|
||||
bDropped = TRUE;
|
||||
nEUI = 0;
|
||||
|
||||
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 (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);
|
||||
}
|
||||
if (!bUIFlip)
|
||||
SendMessageA(hLBox, WM_KEYDOWN, (WPARAM)key, 0);
|
||||
else {
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_KEYDOWN:
|
||||
if (!bDropped && nEUI && (key == VK_UP || key == VK_DOWN))
|
||||
{
|
||||
/* make sure ComboLBox pops up */
|
||||
SendMessageA(hCombo, CB_SETEXTENDEDUI, 0, 0);
|
||||
SendMessageA(hLBox, WM_KEYDOWN, VK_F4, 0);
|
||||
SendMessageA(hCombo, CB_SETEXTENDEDUI, 1, 0);
|
||||
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 */
|
||||
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);
|
||||
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;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue