Fixed a few behaviors of the combobox that were broken.
This commit is contained in:
parent
0e65b38ff3
commit
6ec3eaf54b
|
@ -548,11 +548,28 @@ static LRESULT COMBO_Create( LPHEADCOMBO lphc, WND* wnd, LPARAM lParam)
|
||||||
lphc->droppedRect.top,
|
lphc->droppedRect.top,
|
||||||
lphc->droppedRect.right - lphc->droppedRect.left,
|
lphc->droppedRect.right - lphc->droppedRect.left,
|
||||||
lphc->droppedRect.bottom - lphc->droppedRect.top,
|
lphc->droppedRect.bottom - lphc->droppedRect.top,
|
||||||
lphc->self->hwndSelf,
|
lphc->self->hwndSelf,
|
||||||
(lphc->dwStyle & CBS_DROPDOWN)? (HMENU)0 : (HMENU)ID_CB_LISTBOX,
|
(lphc->dwStyle & CBS_DROPDOWN)? (HMENU)0 : (HMENU)ID_CB_LISTBOX,
|
||||||
lphc->self->hInstance,
|
lphc->self->hInstance,
|
||||||
(LPVOID)lphc );
|
(LPVOID)lphc );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The ComboLBox is a strange little beast (when it's not a CBS_SIMPLE)...
|
||||||
|
* It's a popup window but, when you get the window style, you get WS_CHILD.
|
||||||
|
* When created, it's parent is the combobox but, when you ask for it's parent
|
||||||
|
* after that, you're supposed to get the desktop. (see MFC code function
|
||||||
|
* AfxCancelModes)
|
||||||
|
* To achieve this in Wine, we have to create it as a popup and change
|
||||||
|
* it's style to child after the creation.
|
||||||
|
*/
|
||||||
|
if ( (lphc->hWndLBox!= 0) &&
|
||||||
|
(CB_GETTYPE(lphc) != CBS_SIMPLE) )
|
||||||
|
{
|
||||||
|
SetWindowLongA(lphc->hWndLBox,
|
||||||
|
GWL_STYLE,
|
||||||
|
(GetWindowLongA(lphc->hWndLBox, GWL_STYLE) | WS_CHILD) & ~WS_POPUP);
|
||||||
|
}
|
||||||
|
|
||||||
if( lphc->hWndLBox )
|
if( lphc->hWndLBox )
|
||||||
{
|
{
|
||||||
BOOL bEdit = TRUE;
|
BOOL bEdit = TRUE;
|
||||||
|
@ -1040,6 +1057,9 @@ static void CBUpdateEdit( LPHEADCOMBO lphc , INT index )
|
||||||
{
|
{
|
||||||
SendMessageA( lphc->hWndLBox, LB_GETTEXT,
|
SendMessageA( lphc->hWndLBox, LB_GETTEXT,
|
||||||
(WPARAM)index, (LPARAM)pText );
|
(WPARAM)index, (LPARAM)pText );
|
||||||
|
|
||||||
|
lphc->wState |= CBF_NOEDITNOTIFY;
|
||||||
|
|
||||||
SendMessageA( lphc->hWndEdit, WM_SETTEXT, 0, (LPARAM)pText );
|
SendMessageA( lphc->hWndEdit, WM_SETTEXT, 0, (LPARAM)pText );
|
||||||
SendMessageA( lphc->hWndEdit, EM_SETSEL, 0, (LPARAM)(-1) );
|
SendMessageA( lphc->hWndEdit, EM_SETSEL, 0, (LPARAM)(-1) );
|
||||||
HeapFree( GetProcessHeap(), 0, pText );
|
HeapFree( GetProcessHeap(), 0, pText );
|
||||||
|
@ -1055,7 +1075,6 @@ static void CBUpdateEdit( LPHEADCOMBO lphc , INT index )
|
||||||
*/
|
*/
|
||||||
static void CBDropDown( LPHEADCOMBO lphc )
|
static void CBDropDown( LPHEADCOMBO lphc )
|
||||||
{
|
{
|
||||||
INT index;
|
|
||||||
RECT rect;
|
RECT rect;
|
||||||
|
|
||||||
TRACE("[%04x]: drop down\n", CB_HWND(lphc));
|
TRACE("[%04x]: drop down\n", CB_HWND(lphc));
|
||||||
|
@ -1067,14 +1086,19 @@ static void CBDropDown( LPHEADCOMBO lphc )
|
||||||
lphc->wState |= CBF_DROPPED;
|
lphc->wState |= CBF_DROPPED;
|
||||||
if( CB_GETTYPE(lphc) == CBS_DROPDOWN )
|
if( CB_GETTYPE(lphc) == CBS_DROPDOWN )
|
||||||
{
|
{
|
||||||
index = CBUpdateLBox( lphc );
|
lphc->droppedIndex = CBUpdateLBox( lphc );
|
||||||
if( !(lphc->wState & CBF_CAPTURE) ) CBUpdateEdit( lphc, index );
|
|
||||||
|
if( !(lphc->wState & CBF_CAPTURE) )
|
||||||
|
CBUpdateEdit( lphc, lphc->droppedIndex );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
index = SendMessageA( lphc->hWndLBox, LB_GETCURSEL, 0, 0 );
|
lphc->droppedIndex = SendMessageA( lphc->hWndLBox, LB_GETCURSEL, 0, 0 );
|
||||||
if( index == LB_ERR ) index = 0;
|
|
||||||
SendMessageA( lphc->hWndLBox, LB_SETTOPINDEX, (WPARAM)index, 0 );
|
if( lphc->droppedIndex == LB_ERR )
|
||||||
|
lphc->droppedIndex = 0;
|
||||||
|
|
||||||
|
SendMessageA( lphc->hWndLBox, LB_SETTOPINDEX, (WPARAM)lphc->droppedIndex, 0 );
|
||||||
SendMessageA( lphc->hWndLBox, LB_CARETON, 0, 0 );
|
SendMessageA( lphc->hWndLBox, LB_CARETON, 0, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1116,8 +1140,11 @@ static void CBRollUp( LPHEADCOMBO lphc, BOOL ok, BOOL bButton )
|
||||||
|
|
||||||
TRACE("[%04x]: roll up [%i]\n", CB_HWND(lphc), (INT)ok );
|
TRACE("[%04x]: roll up [%i]\n", CB_HWND(lphc), (INT)ok );
|
||||||
|
|
||||||
/* always send WM_LBUTTONUP? */
|
/*
|
||||||
SendMessageA( lphc->hWndLBox, WM_LBUTTONUP, 0, (LPARAM)(-1) );
|
* It seems useful to send the WM_LBUTTONUP with (-1,-1) when cancelling
|
||||||
|
* and with (0,0) (anywhere in the listbox) when Oking.
|
||||||
|
*/
|
||||||
|
SendMessageA( lphc->hWndLBox, WM_LBUTTONUP, 0, ok ? (LPARAM)0 : (LPARAM)(-1) );
|
||||||
|
|
||||||
if( lphc->wState & CBF_DROPPED )
|
if( lphc->wState & CBF_DROPPED )
|
||||||
{
|
{
|
||||||
|
@ -1252,7 +1279,7 @@ static void COMBO_KillFocus( LPHEADCOMBO lphc )
|
||||||
*/
|
*/
|
||||||
static LRESULT COMBO_Command( LPHEADCOMBO lphc, WPARAM wParam, HWND hWnd )
|
static LRESULT COMBO_Command( LPHEADCOMBO lphc, WPARAM wParam, HWND hWnd )
|
||||||
{
|
{
|
||||||
if( lphc->wState & CBF_EDIT && lphc->hWndEdit == hWnd )
|
if ( lphc->wState & CBF_EDIT && lphc->hWndEdit == hWnd )
|
||||||
{
|
{
|
||||||
/* ">> 8" makes gcc generate jump-table instead of cmp ladder */
|
/* ">> 8" makes gcc generate jump-table instead of cmp ladder */
|
||||||
|
|
||||||
|
@ -1282,7 +1309,22 @@ static LRESULT COMBO_Command( LPHEADCOMBO lphc, WPARAM wParam, HWND hWnd )
|
||||||
|
|
||||||
|
|
||||||
case (EN_CHANGE >> 8):
|
case (EN_CHANGE >> 8):
|
||||||
CB_NOTIFY( lphc, CBN_EDITCHANGE );
|
/*
|
||||||
|
* In some circumstances (when the selection of the combobox
|
||||||
|
* is changed for example) we don't wans the EN_CHANGE notification
|
||||||
|
* to be forwarded to the parent of the combobox. This code
|
||||||
|
* checks a flag that is set in these occasions and ignores the
|
||||||
|
* notification.
|
||||||
|
*/
|
||||||
|
if (lphc->wState & CBF_NOEDITNOTIFY)
|
||||||
|
{
|
||||||
|
lphc->wState &= ~CBF_NOEDITNOTIFY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CB_NOTIFY( lphc, CBN_EDITCHANGE );
|
||||||
|
}
|
||||||
|
|
||||||
CBUpdateLBox( lphc );
|
CBUpdateLBox( lphc );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1763,7 +1805,11 @@ static inline LRESULT WINAPI ComboWndProc_locked( WND* pWnd, UINT message,
|
||||||
case WM_PASTE:
|
case WM_PASTE:
|
||||||
case WM_COPY:
|
case WM_COPY:
|
||||||
if( lphc->wState & CBF_EDIT )
|
if( lphc->wState & CBF_EDIT )
|
||||||
return SendMessageA( lphc->hWndEdit, message, wParam, lParam );
|
{
|
||||||
|
lphc->wState |= CBF_NOEDITNOTIFY;
|
||||||
|
|
||||||
|
return SendMessageA( lphc->hWndEdit, message, wParam, lParam );
|
||||||
|
}
|
||||||
return CB_ERR;
|
return CB_ERR;
|
||||||
case WM_DRAWITEM:
|
case WM_DRAWITEM:
|
||||||
case WM_DELETEITEM:
|
case WM_DELETEITEM:
|
||||||
|
|
|
@ -1281,7 +1281,7 @@ static void LISTBOX_MoveCaret( WND *wnd, LB_DESCR *descr, INT index,
|
||||||
LISTBOX_SelectItemRange( wnd, descr, first, last, TRUE );
|
LISTBOX_SelectItemRange( wnd, descr, first, last, TRUE );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!(descr->style & LBS_MULTIPLESEL) && (descr->selected_item != -1))
|
else if (!(descr->style & LBS_MULTIPLESEL))
|
||||||
{
|
{
|
||||||
/* Set selection to new caret item */
|
/* Set selection to new caret item */
|
||||||
LISTBOX_SetSelection( wnd, descr, index, TRUE, FALSE );
|
LISTBOX_SetSelection( wnd, descr, index, TRUE, FALSE );
|
||||||
|
@ -2611,6 +2611,82 @@ static inline LRESULT WINAPI ComboLBWndProc_locked( WND* wnd, UINT msg,
|
||||||
lphc = (LPHEADCOMBO)(lpcs->lpCreateParams);
|
lphc = (LPHEADCOMBO)(lpcs->lpCreateParams);
|
||||||
#undef lpcs
|
#undef lpcs
|
||||||
return LISTBOX_Create( wnd, lphc );
|
return LISTBOX_Create( wnd, lphc );
|
||||||
|
case WM_MOUSEMOVE:
|
||||||
|
if ( (TWEAK_WineLook > WIN31_LOOK) &&
|
||||||
|
(CB_GETTYPE(lphc) != CBS_SIMPLE) )
|
||||||
|
{
|
||||||
|
POINT mousePos;
|
||||||
|
BOOL captured;
|
||||||
|
RECT clientRect;
|
||||||
|
|
||||||
|
mousePos.x = (INT16)LOWORD(lParam);
|
||||||
|
mousePos.y = (INT16)HIWORD(lParam);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we are in a dropdown combobox, we simulate that
|
||||||
|
* the mouse is captured to show the tracking of the item.
|
||||||
|
*/
|
||||||
|
captured = descr->captured;
|
||||||
|
descr->captured = TRUE;
|
||||||
|
|
||||||
|
LISTBOX_HandleMouseMove( wnd,
|
||||||
|
descr,
|
||||||
|
mousePos.x, mousePos.y);
|
||||||
|
|
||||||
|
descr->captured = captured;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* However, when tracking, it is important that we do not
|
||||||
|
* perform a selection if the cursor is outside the list.
|
||||||
|
*/
|
||||||
|
GetClientRect(hwnd, &clientRect);
|
||||||
|
|
||||||
|
if (!PtInRect( &clientRect, mousePos ))
|
||||||
|
{
|
||||||
|
LISTBOX_MoveCaret( wnd, descr, -1, FALSE );
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* If we are in Win3.1 look, go with the default behavior.
|
||||||
|
*/
|
||||||
|
return ListBoxWndProc( hwnd, msg, wParam, lParam );
|
||||||
|
}
|
||||||
|
case WM_LBUTTONUP:
|
||||||
|
if (TWEAK_WineLook > WIN31_LOOK)
|
||||||
|
{
|
||||||
|
POINT mousePos;
|
||||||
|
RECT clientRect;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the mouse button "up" is not in the listbox,
|
||||||
|
* we make sure there is no selection by re-selecting the
|
||||||
|
* item that was selected when the listbox was made visible.
|
||||||
|
*/
|
||||||
|
mousePos.x = (INT16)LOWORD(lParam);
|
||||||
|
mousePos.y = (INT16)HIWORD(lParam);
|
||||||
|
|
||||||
|
GetClientRect(hwnd, &clientRect);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When the user clicks outside the combobox and the focus
|
||||||
|
* is lost, the owning combobox will send a fake buttonup with
|
||||||
|
* 0xFFFFFFF as the mouse location, we must also revert the
|
||||||
|
* selection to the original selection.
|
||||||
|
*/
|
||||||
|
if ( (lParam == 0xFFFFFFFF) ||
|
||||||
|
(!PtInRect( &clientRect, mousePos )) )
|
||||||
|
{
|
||||||
|
LISTBOX_MoveCaret( wnd,
|
||||||
|
descr,
|
||||||
|
lphc->droppedIndex,
|
||||||
|
FALSE );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return LISTBOX_HandleLButtonUp( wnd, descr );
|
||||||
case WM_LBUTTONDOWN:
|
case WM_LBUTTONDOWN:
|
||||||
return LISTBOX_HandleLButtonDown( wnd, descr, wParam,
|
return LISTBOX_HandleLButtonDown( wnd, descr, wParam,
|
||||||
(INT16)LOWORD(lParam), (INT16)HIWORD(lParam));
|
(INT16)LOWORD(lParam), (INT16)HIWORD(lParam));
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#define CBF_NOTIFY 0x0100
|
#define CBF_NOTIFY 0x0100
|
||||||
#define CBF_NOREDRAW 0x0200
|
#define CBF_NOREDRAW 0x0200
|
||||||
#define CBF_SELCHANGE 0x0400
|
#define CBF_SELCHANGE 0x0400
|
||||||
|
#define CBF_NOEDITNOTIFY 0x1000
|
||||||
#define CBF_EUI 0x8000
|
#define CBF_EUI 0x8000
|
||||||
|
|
||||||
/* Combo state struct */
|
/* Combo state struct */
|
||||||
|
@ -37,6 +38,7 @@ typedef struct
|
||||||
RECT textRect;
|
RECT textRect;
|
||||||
RECT buttonRect;
|
RECT buttonRect;
|
||||||
RECT droppedRect;
|
RECT droppedRect;
|
||||||
|
INT droppedIndex;
|
||||||
INT fixedOwnerDrawHeight;
|
INT fixedOwnerDrawHeight;
|
||||||
INT droppedWidth; /* last two are not used unless set */
|
INT droppedWidth; /* last two are not used unless set */
|
||||||
INT editHeight; /* explicitly */
|
INT editHeight; /* explicitly */
|
||||||
|
|
Loading…
Reference in New Issue