comctl32/tab: Handle item focusing better (including keyboard support).
This commit is contained in:
parent
64945b2779
commit
64102f5f71
|
@ -161,6 +161,7 @@ static void TAB_InvalidateTabArea(const TAB_INFO *);
|
||||||
static void TAB_EnsureSelectionVisible(TAB_INFO *);
|
static void TAB_EnsureSelectionVisible(TAB_INFO *);
|
||||||
static void TAB_DrawItemInterior(const TAB_INFO *, HDC, INT, RECT*);
|
static void TAB_DrawItemInterior(const TAB_INFO *, HDC, INT, RECT*);
|
||||||
static LRESULT TAB_DeselectAll(TAB_INFO *, BOOL);
|
static LRESULT TAB_DeselectAll(TAB_INFO *, BOOL);
|
||||||
|
static BOOL TAB_InternalGetItemRect(const TAB_INFO *, INT, RECT*, RECT*);
|
||||||
|
|
||||||
static BOOL
|
static BOOL
|
||||||
TAB_SendSimpleNotify (const TAB_INFO *infoPtr, UINT code)
|
TAB_SendSimpleNotify (const TAB_INFO *infoPtr, UINT code)
|
||||||
|
@ -272,9 +273,25 @@ static LRESULT TAB_SetCurFocus (TAB_INFO *infoPtr, INT iItem)
|
||||||
infoPtr->uFocus = -1;
|
infoPtr->uFocus = -1;
|
||||||
else if (iItem < infoPtr->uNumItem) {
|
else if (iItem < infoPtr->uNumItem) {
|
||||||
if (infoPtr->dwStyle & TCS_BUTTONS) {
|
if (infoPtr->dwStyle & TCS_BUTTONS) {
|
||||||
FIXME("Should set input focus\n");
|
/* set focus to new item, leave selection as is */
|
||||||
|
if (infoPtr->uFocus != iItem) {
|
||||||
|
INT prev_focus = infoPtr->uFocus;
|
||||||
|
RECT r;
|
||||||
|
|
||||||
|
infoPtr->uFocus = iItem;
|
||||||
|
|
||||||
|
if (prev_focus != infoPtr->iSelected) {
|
||||||
|
if (TAB_InternalGetItemRect(infoPtr, prev_focus, &r, NULL))
|
||||||
|
InvalidateRect(infoPtr->hwnd, &r, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TAB_InternalGetItemRect(infoPtr, iItem, &r, NULL))
|
||||||
|
InvalidateRect(infoPtr->hwnd, &r, FALSE);
|
||||||
|
|
||||||
|
TAB_SendSimpleNotify(infoPtr, TCN_FOCUSCHANGE);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
int oldFocus = infoPtr->uFocus;
|
INT oldFocus = infoPtr->uFocus;
|
||||||
if (infoPtr->iSelected != iItem || oldFocus == -1 ) {
|
if (infoPtr->iSelected != iItem || oldFocus == -1 ) {
|
||||||
infoPtr->uFocus = iItem;
|
infoPtr->uFocus = iItem;
|
||||||
if (oldFocus != -1) {
|
if (oldFocus != -1) {
|
||||||
|
@ -467,13 +484,13 @@ TAB_GetItemRect(const TAB_INFO *infoPtr, INT item, RECT *rect)
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* TAB_KeyUp
|
* TAB_KeyDown
|
||||||
*
|
*
|
||||||
* This method is called to handle keyboard input
|
* This method is called to handle keyboard input
|
||||||
*/
|
*/
|
||||||
static LRESULT TAB_KeyUp(TAB_INFO* infoPtr, WPARAM keyCode)
|
static LRESULT TAB_KeyDown(TAB_INFO* infoPtr, WPARAM keyCode)
|
||||||
{
|
{
|
||||||
int newItem = -1;
|
INT newItem = -1;
|
||||||
|
|
||||||
switch (keyCode)
|
switch (keyCode)
|
||||||
{
|
{
|
||||||
|
@ -485,23 +502,30 @@ static LRESULT TAB_KeyUp(TAB_INFO* infoPtr, WPARAM keyCode)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* If we changed to a valid item, change focused item */
|
||||||
* If we changed to a valid item, change the selection
|
if (newItem >= 0 && newItem < infoPtr->uNumItem && infoPtr->uFocus != newItem)
|
||||||
*/
|
TAB_SetCurFocus(infoPtr, newItem);
|
||||||
if (newItem >= 0 &&
|
|
||||||
newItem < infoPtr->uNumItem &&
|
|
||||||
infoPtr->uFocus != newItem)
|
|
||||||
{
|
|
||||||
if (!TAB_SendSimpleNotify(infoPtr, TCN_SELCHANGING))
|
|
||||||
{
|
|
||||||
TAB_SetCurSel(infoPtr, newItem);
|
|
||||||
TAB_SendSimpleNotify(infoPtr, TCN_SELCHANGE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* WM_KILLFOCUS handler
|
||||||
|
*/
|
||||||
|
static void TAB_KillFocus(TAB_INFO *infoPtr)
|
||||||
|
{
|
||||||
|
/* clear current focused item back to selected for TCS_BUTTONS */
|
||||||
|
if ((infoPtr->dwStyle & TCS_BUTTONS) && (infoPtr->uFocus != infoPtr->iSelected))
|
||||||
|
{
|
||||||
|
RECT r;
|
||||||
|
|
||||||
|
if (TAB_InternalGetItemRect(infoPtr, infoPtr->uFocus, &r, NULL))
|
||||||
|
InvalidateRect(infoPtr->hwnd, &r, FALSE);
|
||||||
|
|
||||||
|
infoPtr->uFocus = infoPtr->iSelected;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* TAB_FocusChanging
|
* TAB_FocusChanging
|
||||||
*
|
*
|
||||||
|
@ -598,7 +622,7 @@ TAB_LButtonDown (TAB_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
|
||||||
TAB_RelayEvent (infoPtr->hwndToolTip, infoPtr->hwnd,
|
TAB_RelayEvent (infoPtr->hwndToolTip, infoPtr->hwnd,
|
||||||
WM_LBUTTONDOWN, wParam, lParam);
|
WM_LBUTTONDOWN, wParam, lParam);
|
||||||
|
|
||||||
if (infoPtr->dwStyle & TCS_FOCUSONBUTTONDOWN) {
|
if (!(infoPtr->dwStyle & TCS_FOCUSNEVER)) {
|
||||||
SetFocus (infoPtr->hwnd);
|
SetFocus (infoPtr->hwnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1482,7 +1506,8 @@ TAB_EraseTabInterior(const TAB_INFO *infoPtr, HDC hdc, INT iItem, const RECT *dr
|
||||||
{
|
{
|
||||||
InflateRect(&rTemp, 2, 2);
|
InflateRect(&rTemp, 2, 2);
|
||||||
FillRect(hdc, &rTemp, hbr);
|
FillRect(hdc, &rTemp, hbr);
|
||||||
if (iItem == infoPtr->iHotTracked)
|
if (iItem == infoPtr->iHotTracked ||
|
||||||
|
(iItem != infoPtr->iSelected && iItem == infoPtr->uFocus))
|
||||||
DrawEdge(hdc, &rTemp, BDR_RAISEDINNER, BF_RECT);
|
DrawEdge(hdc, &rTemp, BDR_RAISEDINNER, BF_RECT);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1651,15 +1676,13 @@ TAB_DrawItemInterior(const TAB_INFO *infoPtr, HDC hdc, INT iItem, RECT *drawRect
|
||||||
(iItem == infoPtr->uFocus) )
|
(iItem == infoPtr->uFocus) )
|
||||||
{
|
{
|
||||||
RECT rFocus = *drawRect;
|
RECT rFocus = *drawRect;
|
||||||
InflateRect(&rFocus, -3, -3);
|
|
||||||
|
if (!(infoPtr->dwStyle & TCS_BUTTONS)) InflateRect(&rFocus, -3, -3);
|
||||||
if (infoPtr->dwStyle & TCS_BOTTOM && !(infoPtr->dwStyle & TCS_VERTICAL))
|
if (infoPtr->dwStyle & TCS_BOTTOM && !(infoPtr->dwStyle & TCS_VERTICAL))
|
||||||
rFocus.top -= 3;
|
rFocus.top -= 3;
|
||||||
if (infoPtr->dwStyle & TCS_BUTTONS)
|
|
||||||
{
|
|
||||||
rFocus.left -= 3;
|
|
||||||
rFocus.top -= 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* focus should stay on selected item for TCS_BUTTONS style */
|
||||||
|
if (!((infoPtr->dwStyle & TCS_BUTTONS) && (infoPtr->iSelected != iItem)))
|
||||||
DrawFocusRect(hdc, &rFocus);
|
DrawFocusRect(hdc, &rFocus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2013,7 +2036,7 @@ static void TAB_DrawItem(const TAB_INFO *infoPtr, HDC hdc, INT iItem)
|
||||||
{
|
{
|
||||||
DWORD state = TAB_GetItem(infoPtr, iItem)->dwState;
|
DWORD state = TAB_GetItem(infoPtr, iItem)->dwState;
|
||||||
|
|
||||||
if (state & TCIS_BUTTONPRESSED)
|
if ((state & TCIS_BUTTONPRESSED) || (iItem == infoPtr->uFocus))
|
||||||
DrawEdge(hdc, &r, EDGE_SUNKEN, BF_SOFT|BF_RECT);
|
DrawEdge(hdc, &r, EDGE_SUNKEN, BF_SOFT|BF_RECT);
|
||||||
else
|
else
|
||||||
if (!(infoPtr->dwStyle & TCS_FLATBUTTONS))
|
if (!(infoPtr->dwStyle & TCS_FLATBUTTONS))
|
||||||
|
@ -3444,12 +3467,14 @@ TAB_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
return theme_changed (infoPtr);
|
return theme_changed (infoPtr);
|
||||||
|
|
||||||
case WM_KILLFOCUS:
|
case WM_KILLFOCUS:
|
||||||
|
TAB_KillFocus(infoPtr);
|
||||||
case WM_SETFOCUS:
|
case WM_SETFOCUS:
|
||||||
TAB_FocusChanging(infoPtr);
|
TAB_FocusChanging(infoPtr);
|
||||||
break; /* Don't disturb normal focus behavior */
|
break; /* Don't disturb normal focus behavior */
|
||||||
|
|
||||||
case WM_KEYUP:
|
case WM_KEYDOWN:
|
||||||
return TAB_KeyUp(infoPtr, wParam);
|
return TAB_KeyDown(infoPtr, wParam);
|
||||||
|
|
||||||
case WM_NCHITTEST:
|
case WM_NCHITTEST:
|
||||||
return TAB_NCHitTest(infoPtr, lParam);
|
return TAB_NCHitTest(infoPtr, lParam);
|
||||||
|
|
||||||
|
|
|
@ -4265,6 +4265,7 @@ typedef struct tagTCITEMW
|
||||||
#define TCN_SELCHANGE (TCN_FIRST - 1)
|
#define TCN_SELCHANGE (TCN_FIRST - 1)
|
||||||
#define TCN_SELCHANGING (TCN_FIRST - 2)
|
#define TCN_SELCHANGING (TCN_FIRST - 2)
|
||||||
#define TCN_GETOBJECT (TCN_FIRST - 3)
|
#define TCN_GETOBJECT (TCN_FIRST - 3)
|
||||||
|
#define TCN_FOCUSCHANGE (TCN_FIRST - 4)
|
||||||
|
|
||||||
#include <pshpack1.h>
|
#include <pshpack1.h>
|
||||||
typedef struct tagTCKEYDOWN
|
typedef struct tagTCKEYDOWN
|
||||||
|
|
Loading…
Reference in New Issue