Implement LBS_COMBOBOX, and make use of it.
Better separation between the Listbox and Combobox. Have a single set of wndprocs, just like Windows.
This commit is contained in:
parent
823c418d8e
commit
134560e9e5
|
@ -70,6 +70,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(combo);
|
||||||
#define CB_OWNERDRAWN( lphc ) ((lphc)->dwStyle & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE))
|
#define CB_OWNERDRAWN( lphc ) ((lphc)->dwStyle & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE))
|
||||||
#define CB_HASSTRINGS( lphc ) ((lphc)->dwStyle & CBS_HASSTRINGS)
|
#define CB_HASSTRINGS( lphc ) ((lphc)->dwStyle & CBS_HASSTRINGS)
|
||||||
#define CB_HWND( lphc ) ((lphc)->self)
|
#define CB_HWND( lphc ) ((lphc)->self)
|
||||||
|
#define CB_GETTYPE( lphc ) ((lphc)->dwStyle & (CBS_DROPDOWNLIST))
|
||||||
|
|
||||||
#define ISWIN31 (LOWORD(GetVersion()) == 0x0a03)
|
#define ISWIN31 (LOWORD(GetVersion()) == 0x0a03)
|
||||||
|
|
||||||
|
@ -566,7 +567,7 @@ static LRESULT COMBO_Create( HWND hwnd, LPHEADCOMBO lphc, HWND hwndParent, LONG
|
||||||
|
|
||||||
/* create listbox popup */
|
/* create listbox popup */
|
||||||
|
|
||||||
lbeStyle = (LBS_NOTIFY | WS_BORDER | WS_CLIPSIBLINGS | WS_CHILD) |
|
lbeStyle = (LBS_NOTIFY | LBS_COMBOBOX | WS_BORDER | WS_CLIPSIBLINGS | WS_CHILD) |
|
||||||
(style & (WS_VSCROLL | CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE));
|
(style & (WS_VSCROLL | CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE));
|
||||||
|
|
||||||
if( lphc->dwStyle & CBS_SORT )
|
if( lphc->dwStyle & CBS_SORT )
|
||||||
|
|
|
@ -113,9 +113,6 @@ typedef struct
|
||||||
INT editHeight; /* explicitly */
|
INT editHeight; /* explicitly */
|
||||||
} HEADCOMBO,*LPHEADCOMBO;
|
} HEADCOMBO,*LPHEADCOMBO;
|
||||||
|
|
||||||
/* Note, that CBS_DROPDOWNLIST style is actually (CBS_SIMPLE | CBS_DROPDOWN) */
|
|
||||||
#define CB_GETTYPE( lphc ) ((lphc)->dwStyle & (CBS_DROPDOWNLIST))
|
|
||||||
|
|
||||||
extern BOOL COMBO_FlipListbox( LPHEADCOMBO, BOOL, BOOL );
|
extern BOOL COMBO_FlipListbox( LPHEADCOMBO, BOOL, BOOL );
|
||||||
|
|
||||||
/* Dialog info structure */
|
/* Dialog info structure */
|
||||||
|
|
|
@ -29,9 +29,7 @@
|
||||||
* TODO:
|
* TODO:
|
||||||
* - GetListBoxInfo()
|
* - GetListBoxInfo()
|
||||||
* - LB_GETLISTBOXINFO
|
* - LB_GETLISTBOXINFO
|
||||||
* - LBS_COMBOBOX
|
|
||||||
* - LBS_NODATA
|
* - LBS_NODATA
|
||||||
* - LBS_STANDARD
|
|
||||||
* - LB_SETLOCALE: some FIXMEs remain
|
* - LB_SETLOCALE: some FIXMEs remain
|
||||||
* - LBS_USETABSTOPS: some FIXMEs remain
|
* - LBS_USETABSTOPS: some FIXMEs remain
|
||||||
*/
|
*/
|
||||||
|
@ -56,7 +54,6 @@
|
||||||
#include "win.h"
|
#include "win.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(listbox);
|
WINE_DEFAULT_DEBUG_CHANNEL(listbox);
|
||||||
WINE_DECLARE_DEBUG_CHANNEL(combo);
|
|
||||||
|
|
||||||
/* Items array granularity */
|
/* Items array granularity */
|
||||||
#define LB_ARRAY_GRANULARITY 16
|
#define LB_ARRAY_GRANULARITY 16
|
||||||
|
@ -137,8 +134,6 @@ typedef enum
|
||||||
|
|
||||||
static TIMER_DIRECTION LISTBOX_Timer = LB_TIMER_NONE;
|
static TIMER_DIRECTION LISTBOX_Timer = LB_TIMER_NONE;
|
||||||
|
|
||||||
static LRESULT WINAPI ComboLBWndProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam );
|
|
||||||
static LRESULT WINAPI ComboLBWndProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam );
|
|
||||||
static LRESULT WINAPI ListBoxWndProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam );
|
static LRESULT WINAPI ListBoxWndProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam );
|
||||||
static LRESULT WINAPI ListBoxWndProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam );
|
static LRESULT WINAPI ListBoxWndProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam );
|
||||||
|
|
||||||
|
@ -166,8 +161,8 @@ const struct builtin_class_descr COMBOLBOX_builtin_class =
|
||||||
{
|
{
|
||||||
"ComboLBox", /* name */
|
"ComboLBox", /* name */
|
||||||
CS_DBLCLKS | CS_SAVEBITS, /* style */
|
CS_DBLCLKS | CS_SAVEBITS, /* style */
|
||||||
ComboLBWndProcA, /* procA */
|
ListBoxWndProcA, /* procA */
|
||||||
ComboLBWndProcW, /* procW */
|
ListBoxWndProcW, /* procW */
|
||||||
sizeof(LB_DESCR *), /* extra */
|
sizeof(LB_DESCR *), /* extra */
|
||||||
IDC_ARROW, /* cursor */
|
IDC_ARROW, /* cursor */
|
||||||
0 /* brush */
|
0 /* brush */
|
||||||
|
@ -2494,7 +2489,7 @@ static BOOL LISTBOX_Create( HWND hwnd, LPHEADCOMBO lphc )
|
||||||
|
|
||||||
if( lphc )
|
if( lphc )
|
||||||
{
|
{
|
||||||
TRACE_(combo)("[%p]: resetting owner %p -> %p\n", hwnd, descr->owner, lphc->self );
|
TRACE("[%p]: resetting owner %p -> %p\n", hwnd, descr->owner, lphc->self );
|
||||||
descr->owner = lphc->self;
|
descr->owner = lphc->self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2553,23 +2548,29 @@ static LRESULT WINAPI ListBoxWndProc_common( HWND hwnd, UINT msg,
|
||||||
{
|
{
|
||||||
LRESULT ret;
|
LRESULT ret;
|
||||||
LB_DESCR *descr;
|
LB_DESCR *descr;
|
||||||
|
LPHEADCOMBO lphc = 0;
|
||||||
|
|
||||||
if (!(descr = (LB_DESCR *)GetWindowLongA( hwnd, 0 )))
|
if (!IsWindow(hwnd)) return 0;
|
||||||
|
|
||||||
|
if (!(descr = (LB_DESCR *)GetWindowLongW( hwnd, 0 )))
|
||||||
{
|
{
|
||||||
if (msg == WM_CREATE)
|
if (msg == WM_CREATE)
|
||||||
{
|
{
|
||||||
if (!LISTBOX_Create( hwnd, NULL ))
|
CREATESTRUCTW *lpcs = (CREATESTRUCTW *)lParam;
|
||||||
return -1;
|
if (lpcs->style & LBS_COMBOBOX) lphc = (LPHEADCOMBO)lpcs->lpCreateParams;
|
||||||
TRACE("creating wnd=%p descr=%lx\n", hwnd, GetWindowLongA( hwnd, 0 ) );
|
if (!LISTBOX_Create( hwnd, lphc )) return -1;
|
||||||
|
TRACE("creating wnd=%p descr=%lx\n", hwnd, GetWindowLongW( hwnd, 0 ) );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* Ignore all other messages before we get a WM_CREATE */
|
/* Ignore all other messages before we get a WM_CREATE */
|
||||||
return unicode ? DefWindowProcW( hwnd, msg, wParam, lParam ) :
|
return unicode ? DefWindowProcW( hwnd, msg, wParam, lParam ) :
|
||||||
DefWindowProcA( hwnd, msg, wParam, lParam );
|
DefWindowProcA( hwnd, msg, wParam, lParam );
|
||||||
}
|
}
|
||||||
|
if (descr->style & LBS_COMBOBOX) lphc = descr->lphc;
|
||||||
|
|
||||||
TRACE("[%p]: msg %s wp %08x lp %08lx\n",
|
TRACE("[%p]: msg %s wp %08x lp %08lx\n",
|
||||||
hwnd, SPY_GetMsgName(msg, hwnd), wParam, lParam );
|
hwnd, SPY_GetMsgName(msg, hwnd), wParam, lParam );
|
||||||
|
|
||||||
switch(msg)
|
switch(msg)
|
||||||
{
|
{
|
||||||
case LB_RESETCONTENT16:
|
case LB_RESETCONTENT16:
|
||||||
|
@ -2864,7 +2865,9 @@ static LRESULT WINAPI ListBoxWndProc_common( HWND hwnd, UINT msg,
|
||||||
case LB_SETCURSEL:
|
case LB_SETCURSEL:
|
||||||
if (IS_MULTISELECT(descr)) return LB_ERR;
|
if (IS_MULTISELECT(descr)) return LB_ERR;
|
||||||
LISTBOX_SetCaretIndex( hwnd, descr, wParam, TRUE );
|
LISTBOX_SetCaretIndex( hwnd, descr, wParam, TRUE );
|
||||||
return LISTBOX_SetSelection( hwnd, descr, wParam, TRUE, FALSE );
|
ret = LISTBOX_SetSelection( hwnd, descr, wParam, TRUE, FALSE );
|
||||||
|
if (lphc && ret != LB_ERR) ret = descr->selected_item;
|
||||||
|
return ret;
|
||||||
|
|
||||||
case LB_GETSELCOUNT16:
|
case LB_GETSELCOUNT16:
|
||||||
case LB_GETSELCOUNT:
|
case LB_GETSELCOUNT:
|
||||||
|
@ -3028,21 +3031,88 @@ static LRESULT WINAPI ListBoxWndProc_common( HWND hwnd, UINT msg,
|
||||||
return DefWindowProcW( hwnd, msg, wParam, lParam );
|
return DefWindowProcW( hwnd, msg, wParam, lParam );
|
||||||
return LISTBOX_HandleMouseWheel( hwnd, descr, wParam );
|
return LISTBOX_HandleMouseWheel( hwnd, descr, wParam );
|
||||||
case WM_LBUTTONDOWN:
|
case WM_LBUTTONDOWN:
|
||||||
|
if (lphc)
|
||||||
|
return LISTBOX_HandleLButtonDownCombo(hwnd, descr, msg, wParam,
|
||||||
|
(INT16)LOWORD(lParam),
|
||||||
|
(INT16)HIWORD(lParam) );
|
||||||
return LISTBOX_HandleLButtonDown( hwnd, descr, wParam,
|
return LISTBOX_HandleLButtonDown( hwnd, descr, wParam,
|
||||||
(INT16)LOWORD(lParam),
|
(INT16)LOWORD(lParam),
|
||||||
(INT16)HIWORD(lParam) );
|
(INT16)HIWORD(lParam) );
|
||||||
case WM_LBUTTONDBLCLK:
|
case WM_LBUTTONDBLCLK:
|
||||||
|
if (lphc)
|
||||||
|
return LISTBOX_HandleLButtonDownCombo(hwnd, descr, msg, wParam,
|
||||||
|
(INT16)LOWORD(lParam),
|
||||||
|
(INT16)HIWORD(lParam) );
|
||||||
if (descr->style & LBS_NOTIFY)
|
if (descr->style & LBS_NOTIFY)
|
||||||
SEND_NOTIFICATION( hwnd, descr, LBN_DBLCLK );
|
SEND_NOTIFICATION( hwnd, descr, LBN_DBLCLK );
|
||||||
return 0;
|
return 0;
|
||||||
case WM_MOUSEMOVE:
|
case WM_MOUSEMOVE:
|
||||||
if (GetCapture() == hwnd)
|
if ( lphc && ((lphc->dwStyle & CBS_DROPDOWNLIST) != CBS_SIMPLE) )
|
||||||
|
{
|
||||||
|
BOOL captured = descr->captured;
|
||||||
|
POINT mousePos;
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
if (GetClientRect(hwnd, &clientRect) && PtInRect( &clientRect, mousePos ))
|
||||||
|
descr->captured = TRUE;
|
||||||
|
|
||||||
|
LISTBOX_HandleMouseMove( hwnd, descr, mousePos.x, mousePos.y);
|
||||||
|
|
||||||
|
descr->captured = captured;
|
||||||
|
}
|
||||||
|
else if (GetCapture() == hwnd)
|
||||||
|
{
|
||||||
LISTBOX_HandleMouseMove( hwnd, descr, (INT16)LOWORD(lParam),
|
LISTBOX_HandleMouseMove( hwnd, descr, (INT16)LOWORD(lParam),
|
||||||
(INT16)HIWORD(lParam) );
|
(INT16)HIWORD(lParam) );
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
case WM_LBUTTONUP:
|
case WM_LBUTTONUP:
|
||||||
|
if (lphc)
|
||||||
|
{
|
||||||
|
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 == (LPARAM)-1) || (!PtInRect( &clientRect, mousePos )) )
|
||||||
|
LISTBOX_MoveCaret( hwnd, descr, lphc->droppedIndex, FALSE );
|
||||||
|
}
|
||||||
return LISTBOX_HandleLButtonUp( hwnd, descr );
|
return LISTBOX_HandleLButtonUp( hwnd, descr );
|
||||||
case WM_KEYDOWN:
|
case WM_KEYDOWN:
|
||||||
|
if( lphc && (lphc->dwStyle & CBS_DROPDOWNLIST) != CBS_SIMPLE )
|
||||||
|
{
|
||||||
|
/* for some reason Windows makes it possible to
|
||||||
|
* show/hide ComboLBox by sending it WM_KEYDOWNs */
|
||||||
|
|
||||||
|
if( (!(lphc->wState & CBF_EUI) && wParam == VK_F4) ||
|
||||||
|
( (lphc->wState & CBF_EUI) && !(lphc->wState & CBF_DROPPED)
|
||||||
|
&& (wParam == VK_DOWN || wParam == VK_UP)) )
|
||||||
|
{
|
||||||
|
COMBO_FlipListbox( lphc, FALSE, FALSE );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
return LISTBOX_HandleKeyDown( hwnd, descr, wParam );
|
return LISTBOX_HandleKeyDown( hwnd, descr, wParam );
|
||||||
case WM_CHAR:
|
case WM_CHAR:
|
||||||
{
|
{
|
||||||
|
@ -3075,30 +3145,34 @@ static LRESULT WINAPI ListBoxWndProc_common( HWND hwnd, UINT msg,
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
case WM_DROPFILES:
|
case WM_DROPFILES:
|
||||||
if( !descr->lphc )
|
if( lphc ) return 0;
|
||||||
return unicode ? SendMessageW( descr->owner, msg, wParam, lParam ) :
|
return unicode ? SendMessageW( descr->owner, msg, wParam, lParam ) :
|
||||||
SendMessageA( descr->owner, msg, wParam, lParam );
|
SendMessageA( descr->owner, msg, wParam, lParam );
|
||||||
|
|
||||||
|
case WM_NCDESTROY:
|
||||||
|
if( lphc && (lphc->dwStyle & CBS_DROPDOWNLIST) != CBS_SIMPLE )
|
||||||
|
lphc->hWndLBox = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case WM_NCACTIVATE:
|
||||||
|
if (lphc) return 0;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if ((msg >= WM_USER) && (msg < 0xc000))
|
if ((msg >= WM_USER) && (msg < 0xc000))
|
||||||
WARN("[%p]: unknown msg %04x wp %08x lp %08lx\n",
|
WARN("[%p]: unknown msg %04x wp %08x lp %08lx\n",
|
||||||
hwnd, msg, wParam, lParam );
|
hwnd, msg, wParam, lParam );
|
||||||
return unicode ? DefWindowProcW( hwnd, msg, wParam, lParam ) :
|
|
||||||
DefWindowProcA( hwnd, msg, wParam, lParam );
|
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
|
return unicode ? DefWindowProcW( hwnd, msg, wParam, lParam ) :
|
||||||
|
DefWindowProcA( hwnd, msg, wParam, lParam );
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* ListBoxWndProcA
|
* ListBoxWndProcA
|
||||||
*
|
|
||||||
* This is just a wrapper for the real wndproc, it only does window locking
|
|
||||||
* and unlocking.
|
|
||||||
*/
|
*/
|
||||||
static LRESULT WINAPI ListBoxWndProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
|
static LRESULT WINAPI ListBoxWndProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
|
||||||
{
|
{
|
||||||
if (!IsWindow(hwnd)) return 0;
|
|
||||||
return ListBoxWndProc_common( hwnd, msg, wParam, lParam, FALSE );
|
return ListBoxWndProc_common( hwnd, msg, wParam, lParam, FALSE );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3107,171 +3181,5 @@ static LRESULT WINAPI ListBoxWndProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARA
|
||||||
*/
|
*/
|
||||||
static LRESULT WINAPI ListBoxWndProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
|
static LRESULT WINAPI ListBoxWndProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
|
||||||
{
|
{
|
||||||
if (!IsWindow(hwnd)) return 0;
|
|
||||||
return ListBoxWndProc_common( hwnd, msg, wParam, lParam, TRUE );
|
return ListBoxWndProc_common( hwnd, msg, wParam, lParam, TRUE );
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* ComboLBWndProc_common
|
|
||||||
*
|
|
||||||
* The real combo listbox wndproc
|
|
||||||
*/
|
|
||||||
static LRESULT WINAPI ComboLBWndProc_common( HWND hwnd, UINT msg,
|
|
||||||
WPARAM wParam, LPARAM lParam, BOOL unicode )
|
|
||||||
{
|
|
||||||
LRESULT lRet = 0;
|
|
||||||
LB_DESCR *descr;
|
|
||||||
LPHEADCOMBO lphc;
|
|
||||||
|
|
||||||
if (!(descr = (LB_DESCR *)GetWindowLongA( hwnd, 0 )))
|
|
||||||
{
|
|
||||||
if (msg == WM_CREATE)
|
|
||||||
{
|
|
||||||
CREATESTRUCTA *lpcs = (CREATESTRUCTA *)lParam;
|
|
||||||
TRACE_(combo)("\tpassed parent handle = %p\n",lpcs->lpCreateParams);
|
|
||||||
lphc = (LPHEADCOMBO)(lpcs->lpCreateParams);
|
|
||||||
return LISTBOX_Create( hwnd, lphc );
|
|
||||||
}
|
|
||||||
/* Ignore all other messages before we get a WM_CREATE */
|
|
||||||
return unicode ? DefWindowProcW( hwnd, msg, wParam, lParam ) :
|
|
||||||
DefWindowProcA( hwnd, msg, wParam, lParam );
|
|
||||||
}
|
|
||||||
|
|
||||||
TRACE_(combo)("[%p]: msg %s wp %08x lp %08lx\n",
|
|
||||||
hwnd, SPY_GetMsgName(msg, hwnd), wParam, lParam );
|
|
||||||
|
|
||||||
if ((lphc = descr->lphc) != NULL)
|
|
||||||
{
|
|
||||||
switch( msg )
|
|
||||||
{
|
|
||||||
case WM_MOUSEMOVE:
|
|
||||||
if ( (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.
|
|
||||||
*/
|
|
||||||
GetClientRect(hwnd, &clientRect);
|
|
||||||
|
|
||||||
if (PtInRect( &clientRect, mousePos ))
|
|
||||||
{
|
|
||||||
captured = descr->captured;
|
|
||||||
descr->captured = TRUE;
|
|
||||||
|
|
||||||
LISTBOX_HandleMouseMove( hwnd, descr,
|
|
||||||
mousePos.x, mousePos.y);
|
|
||||||
|
|
||||||
descr->captured = captured;
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LISTBOX_HandleMouseMove( hwnd, descr,
|
|
||||||
mousePos.x, mousePos.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WM_LBUTTONUP:
|
|
||||||
{
|
|
||||||
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 == (LPARAM)-1) ||
|
|
||||||
(!PtInRect( &clientRect, mousePos )) )
|
|
||||||
{
|
|
||||||
LISTBOX_MoveCaret( hwnd, descr, lphc->droppedIndex, FALSE );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return LISTBOX_HandleLButtonUp( hwnd, descr );
|
|
||||||
case WM_LBUTTONDBLCLK:
|
|
||||||
case WM_LBUTTONDOWN:
|
|
||||||
return LISTBOX_HandleLButtonDownCombo(hwnd, descr, msg, wParam,
|
|
||||||
(INT16)LOWORD(lParam),
|
|
||||||
(INT16)HIWORD(lParam) );
|
|
||||||
case WM_NCACTIVATE:
|
|
||||||
return FALSE;
|
|
||||||
case WM_KEYDOWN:
|
|
||||||
if( CB_GETTYPE(lphc) != CBS_SIMPLE )
|
|
||||||
{
|
|
||||||
/* for some reason(?) Windows makes it possible to
|
|
||||||
* show/hide ComboLBox by sending it WM_KEYDOWNs */
|
|
||||||
|
|
||||||
if( (!(lphc->wState & CBF_EUI) && wParam == VK_F4) ||
|
|
||||||
( (lphc->wState & CBF_EUI) && !(lphc->wState & CBF_DROPPED)
|
|
||||||
&& (wParam == VK_DOWN || wParam == VK_UP)) )
|
|
||||||
{
|
|
||||||
COMBO_FlipListbox( lphc, FALSE, FALSE );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return LISTBOX_HandleKeyDown( hwnd, descr, wParam );
|
|
||||||
|
|
||||||
case LB_SETCURSEL16:
|
|
||||||
case LB_SETCURSEL:
|
|
||||||
lRet = unicode ? ListBoxWndProcW( hwnd, msg, wParam, lParam ) :
|
|
||||||
ListBoxWndProcA( hwnd, msg, wParam, lParam );
|
|
||||||
lRet =(lRet == LB_ERR) ? lRet : descr->selected_item;
|
|
||||||
return lRet;
|
|
||||||
case WM_NCDESTROY:
|
|
||||||
if( CB_GETTYPE(lphc) != CBS_SIMPLE )
|
|
||||||
lphc->hWndLBox = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* default handling: call listbox wnd proc */
|
|
||||||
lRet = unicode ? ListBoxWndProcW( hwnd, msg, wParam, lParam ) :
|
|
||||||
ListBoxWndProcA( hwnd, msg, wParam, lParam );
|
|
||||||
|
|
||||||
TRACE_(combo)("\t default on msg [%04x]\n", (UINT16)msg );
|
|
||||||
|
|
||||||
return lRet;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* ComboLBWndProcA
|
|
||||||
*
|
|
||||||
* NOTE: in Windows, winproc address of the ComboLBox is the same
|
|
||||||
* as that of the Listbox.
|
|
||||||
*/
|
|
||||||
LRESULT WINAPI ComboLBWndProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
|
|
||||||
{
|
|
||||||
if (!IsWindow(hwnd)) return 0;
|
|
||||||
return ComboLBWndProc_common( hwnd, msg, wParam, lParam, FALSE );
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* ComboLBWndProcW
|
|
||||||
*/
|
|
||||||
LRESULT WINAPI ComboLBWndProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
|
|
||||||
{
|
|
||||||
if (!IsWindow(hwnd)) return 0;
|
|
||||||
return ComboLBWndProc_common( hwnd, msg, wParam, lParam, TRUE );
|
|
||||||
}
|
|
||||||
|
|
|
@ -2164,6 +2164,7 @@ typedef const SCROLLINFO *LPCSCROLLINFO;
|
||||||
#define LBS_DISABLENOSCROLL 0x1000
|
#define LBS_DISABLENOSCROLL 0x1000
|
||||||
#define LBS_NODATA 0x2000
|
#define LBS_NODATA 0x2000
|
||||||
#define LBS_NOSEL 0x4000
|
#define LBS_NOSEL 0x4000
|
||||||
|
#define LBS_COMBOBOX 0x8000
|
||||||
#define LBS_STANDARD (LBS_NOTIFY | LBS_SORT | WS_VSCROLL | WS_BORDER)
|
#define LBS_STANDARD (LBS_NOTIFY | LBS_SORT | WS_VSCROLL | WS_BORDER)
|
||||||
|
|
||||||
/* Listbox messages */
|
/* Listbox messages */
|
||||||
|
|
Loading…
Reference in New Issue