Fixed a few behaviors of the combobox that were broken.
This commit is contained in:
parent
0e65b38ff3
commit
6ec3eaf54b
|
@ -553,6 +553,23 @@ static LRESULT COMBO_Create( LPHEADCOMBO lphc, WND* wnd, LPARAM lParam)
|
|||
lphc->self->hInstance,
|
||||
(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 )
|
||||
{
|
||||
BOOL bEdit = TRUE;
|
||||
|
@ -1040,6 +1057,9 @@ static void CBUpdateEdit( LPHEADCOMBO lphc , INT index )
|
|||
{
|
||||
SendMessageA( lphc->hWndLBox, LB_GETTEXT,
|
||||
(WPARAM)index, (LPARAM)pText );
|
||||
|
||||
lphc->wState |= CBF_NOEDITNOTIFY;
|
||||
|
||||
SendMessageA( lphc->hWndEdit, WM_SETTEXT, 0, (LPARAM)pText );
|
||||
SendMessageA( lphc->hWndEdit, EM_SETSEL, 0, (LPARAM)(-1) );
|
||||
HeapFree( GetProcessHeap(), 0, pText );
|
||||
|
@ -1055,7 +1075,6 @@ static void CBUpdateEdit( LPHEADCOMBO lphc , INT index )
|
|||
*/
|
||||
static void CBDropDown( LPHEADCOMBO lphc )
|
||||
{
|
||||
INT index;
|
||||
RECT rect;
|
||||
|
||||
TRACE("[%04x]: drop down\n", CB_HWND(lphc));
|
||||
|
@ -1067,14 +1086,19 @@ static void CBDropDown( LPHEADCOMBO lphc )
|
|||
lphc->wState |= CBF_DROPPED;
|
||||
if( CB_GETTYPE(lphc) == CBS_DROPDOWN )
|
||||
{
|
||||
index = CBUpdateLBox( lphc );
|
||||
if( !(lphc->wState & CBF_CAPTURE) ) CBUpdateEdit( lphc, index );
|
||||
lphc->droppedIndex = CBUpdateLBox( lphc );
|
||||
|
||||
if( !(lphc->wState & CBF_CAPTURE) )
|
||||
CBUpdateEdit( lphc, lphc->droppedIndex );
|
||||
}
|
||||
else
|
||||
{
|
||||
index = SendMessageA( lphc->hWndLBox, LB_GETCURSEL, 0, 0 );
|
||||
if( index == LB_ERR ) index = 0;
|
||||
SendMessageA( lphc->hWndLBox, LB_SETTOPINDEX, (WPARAM)index, 0 );
|
||||
lphc->droppedIndex = SendMessageA( lphc->hWndLBox, LB_GETCURSEL, 0, 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 );
|
||||
}
|
||||
|
||||
|
@ -1116,8 +1140,11 @@ static void CBRollUp( LPHEADCOMBO lphc, BOOL ok, BOOL bButton )
|
|||
|
||||
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 )
|
||||
{
|
||||
|
@ -1252,7 +1279,7 @@ static void COMBO_KillFocus( LPHEADCOMBO lphc )
|
|||
*/
|
||||
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 */
|
||||
|
||||
|
@ -1282,7 +1309,22 @@ static LRESULT COMBO_Command( LPHEADCOMBO lphc, WPARAM wParam, HWND hWnd )
|
|||
|
||||
|
||||
case (EN_CHANGE >> 8):
|
||||
/*
|
||||
* 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 );
|
||||
break;
|
||||
|
||||
|
@ -1763,7 +1805,11 @@ static inline LRESULT WINAPI ComboWndProc_locked( WND* pWnd, UINT message,
|
|||
case WM_PASTE:
|
||||
case WM_COPY:
|
||||
if( lphc->wState & CBF_EDIT )
|
||||
{
|
||||
lphc->wState |= CBF_NOEDITNOTIFY;
|
||||
|
||||
return SendMessageA( lphc->hWndEdit, message, wParam, lParam );
|
||||
}
|
||||
return CB_ERR;
|
||||
case WM_DRAWITEM:
|
||||
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 );
|
||||
}
|
||||
}
|
||||
else if (!(descr->style & LBS_MULTIPLESEL) && (descr->selected_item != -1))
|
||||
else if (!(descr->style & LBS_MULTIPLESEL))
|
||||
{
|
||||
/* Set selection to new caret item */
|
||||
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);
|
||||
#undef lpcs
|
||||
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:
|
||||
return LISTBOX_HandleLButtonDown( wnd, descr, wParam,
|
||||
(INT16)LOWORD(lParam), (INT16)HIWORD(lParam));
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#define CBF_NOTIFY 0x0100
|
||||
#define CBF_NOREDRAW 0x0200
|
||||
#define CBF_SELCHANGE 0x0400
|
||||
#define CBF_NOEDITNOTIFY 0x1000
|
||||
#define CBF_EUI 0x8000
|
||||
|
||||
/* Combo state struct */
|
||||
|
@ -37,6 +38,7 @@ typedef struct
|
|||
RECT textRect;
|
||||
RECT buttonRect;
|
||||
RECT droppedRect;
|
||||
INT droppedIndex;
|
||||
INT fixedOwnerDrawHeight;
|
||||
INT droppedWidth; /* last two are not used unless set */
|
||||
INT editHeight; /* explicitly */
|
||||
|
|
Loading…
Reference in New Issue