Support hiding keyboard cues and focus rectangles

See issue #2839 for more details.

svn path=/trunk/; revision=30727
This commit is contained in:
Thomas Bluemel 2007-11-24 20:49:20 +00:00
parent 5e4658d7a9
commit 9e8530d01a
5 changed files with 183 additions and 15 deletions

View file

@ -72,7 +72,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(button);
#define STATE_GWL_OFFSET 0 #define STATE_GWL_OFFSET 0
#define HFONT_GWL_OFFSET (sizeof(LONG)) #define HFONT_GWL_OFFSET (sizeof(LONG))
#define HIMAGE_GWL_OFFSET (HFONT_GWL_OFFSET+sizeof(HFONT)) #define HIMAGE_GWL_OFFSET (HFONT_GWL_OFFSET+sizeof(HFONT))
#define NB_EXTRA_BYTES (HIMAGE_GWL_OFFSET+sizeof(HANDLE)) #define UISTATE_GWL_OFFSET (HIMAGE_GWL_OFFSET+sizeof(HFONT))
#define NB_EXTRA_BYTES (UISTATE_GWL_OFFSET+sizeof(LONG))
/* Button state values */ /* Button state values */
#define BUTTON_UNCHECKED 0x00 #define BUTTON_UNCHECKED 0x00
@ -179,6 +180,16 @@ __inline static void set_button_state( HWND hwnd, LONG state )
SetWindowLongW( hwnd, STATE_GWL_OFFSET, state ); SetWindowLongW( hwnd, STATE_GWL_OFFSET, state );
} }
static __inline void set_ui_state( HWND hwnd, LONG flags )
{
SetWindowLongW( hwnd, UISTATE_GWL_OFFSET, flags );
}
static __inline LONG get_ui_state( HWND hwnd )
{
return GetWindowLongPtrW( hwnd, UISTATE_GWL_OFFSET );
}
__inline static HFONT get_button_font( HWND hwnd ) __inline static HFONT get_button_font( HWND hwnd )
{ {
return (HFONT)GetWindowLongPtrW( hwnd, HFONT_GWL_OFFSET ); return (HFONT)GetWindowLongPtrW( hwnd, HFONT_GWL_OFFSET );
@ -214,6 +225,27 @@ __inline static WCHAR *get_button_text( HWND hwnd )
return buffer; return buffer;
} }
/* Retrieve the UI state for the control */
static BOOL button_update_uistate(HWND hwnd, BOOL unicode)
{
LONG flags, prevflags;
if (unicode)
flags = DefWindowProcW(hwnd, WM_QUERYUISTATE, 0, 0);
else
flags = DefWindowProcA(hwnd, WM_QUERYUISTATE, 0, 0);
prevflags = get_ui_state(hwnd);
if (prevflags != flags)
{
set_ui_state(hwnd, flags);
return TRUE;
}
return FALSE;
}
/*********************************************************************** /***********************************************************************
* ButtonWndProc_common * ButtonWndProc_common
*/ */
@ -260,6 +292,7 @@ static LRESULT WINAPI ButtonWndProc_common(HWND hWnd, UINT uMsg,
if (btn_type >= MAX_BTN_TYPE) if (btn_type >= MAX_BTN_TYPE)
return -1; /* abort */ return -1; /* abort */
set_button_state( hWnd, BUTTON_UNCHECKED ); set_button_state( hWnd, BUTTON_UNCHECKED );
button_update_uistate( hWnd, unicode );
return 0; return 0;
case WM_ERASEBKGND: case WM_ERASEBKGND:
@ -530,6 +563,16 @@ static LRESULT WINAPI ButtonWndProc_common(HWND hWnd, UINT uMsg,
paint_button( hWnd, btn_type, ODA_SELECT ); paint_button( hWnd, btn_type, ODA_SELECT );
break; break;
case WM_UPDATEUISTATE:
if (unicode)
DefWindowProcW(hWnd, uMsg, wParam, lParam);
else
DefWindowProcA(hWnd, uMsg, wParam, lParam);
if (button_update_uistate(hWnd, unicode))
paint_button( hWnd, btn_type, ODA_DRAWENTIRE );
break;
case WM_NCHITTEST: case WM_NCHITTEST:
if(btn_type == BS_GROUPBOX) return HTTRANSPARENT; if(btn_type == BS_GROUPBOX) return HTTRANSPARENT;
/* fall through */ /* fall through */
@ -540,6 +583,7 @@ static LRESULT WINAPI ButtonWndProc_common(HWND hWnd, UINT uMsg,
return 0; return 0;
} }
/*********************************************************************** /***********************************************************************
* ButtonWndProcW * ButtonWndProcW
* The button window procedure. This is just a wrapper which locks * The button window procedure. This is just a wrapper which locks
@ -643,6 +687,9 @@ static UINT BUTTON_CalcLabelRect(HWND hwnd, HDC hdc, RECT *rc)
} }
DrawTextW(hdc, text, -1, &r, dtStyle | DT_CALCRECT); DrawTextW(hdc, text, -1, &r, dtStyle | DT_CALCRECT);
HeapFree( GetProcessHeap(), 0, text ); HeapFree( GetProcessHeap(), 0, text );
if (get_ui_state( hwnd ) & UISF_HIDEACCEL)
dtStyle |= DT_HIDEPREFIX;
break; break;
case BS_ICON: case BS_ICON:
@ -760,6 +807,9 @@ static void BUTTON_DrawLabel(HWND hwnd, HDC hdc, UINT dtFlags, RECT *rc)
if (!(text = get_button_text( hwnd ))) return; if (!(text = get_button_text( hwnd ))) return;
lp = (LPARAM)text; lp = (LPARAM)text;
wp = (WPARAM)dtFlags; wp = (WPARAM)dtFlags;
if (dtFlags & DT_HIDEPREFIX)
flags |= DSS_HIDEPREFIX;
break; break;
case BS_ICON: case BS_ICON:
@ -858,9 +908,12 @@ static void PB_Paint( HWND hwnd, HDC hDC, UINT action )
if (state & BUTTON_HASFOCUS) if (state & BUTTON_HASFOCUS)
{ {
InflateRect( &focus_rect, -1, -1 ); if (!(get_ui_state(hwnd) & UISF_HIDEFOCUS))
IntersectRect(&focus_rect, &focus_rect, &rc); {
DrawFocusRect( hDC, &focus_rect ); InflateRect( &focus_rect, -1, -1 );
IntersectRect(&focus_rect, &focus_rect, &rc);
DrawFocusRect( hDC, &focus_rect );
}
} }
cleanup: cleanup:
@ -990,10 +1043,13 @@ static void CB_Paint( HWND hwnd, HDC hDC, UINT action )
if ((action == ODA_FOCUS) || if ((action == ODA_FOCUS) ||
((action == ODA_DRAWENTIRE) && (state & BUTTON_HASFOCUS))) ((action == ODA_DRAWENTIRE) && (state & BUTTON_HASFOCUS)))
{ {
rtext.left--; if (!(get_ui_state(hwnd) & UISF_HIDEFOCUS))
rtext.right++; {
IntersectRect(&rtext, &rtext, &client); rtext.left--;
DrawFocusRect( hDC, &rtext ); rtext.right++;
IntersectRect(&rtext, &rtext, &client);
DrawFocusRect( hDC, &rtext );
}
} }
} }
@ -1099,7 +1155,10 @@ static void UB_Paint( HWND hwnd, HDC hDC, UINT action )
FillRect( hDC, &rc, hBrush ); FillRect( hDC, &rc, hBrush );
if ((action == ODA_FOCUS) || if ((action == ODA_FOCUS) ||
((action == ODA_DRAWENTIRE) && (state & BUTTON_HASFOCUS))) ((action == ODA_DRAWENTIRE) && (state & BUTTON_HASFOCUS)))
DrawFocusRect( hDC, &rc ); {
if (!(get_ui_state(hwnd) & UISF_HIDEFOCUS))
DrawFocusRect( hDC, &rc );
}
} }

View file

@ -139,6 +139,17 @@ static BOOL COMBO_Init()
return FALSE; return FALSE;
} }
/* Retrieve the UI state for the control */
static BOOL COMBO_update_uistate(LPHEADCOMBO lphc)
{
LONG prev_flags;
prev_flags = lphc->UIState;
lphc->UIState = DefWindowProcW(lphc->self, WM_QUERYUISTATE, 0, 0);
return prev_flags != lphc->UIState;
}
/*********************************************************************** /***********************************************************************
* COMBO_NCCreate * COMBO_NCCreate
*/ */
@ -151,6 +162,8 @@ static LRESULT COMBO_NCCreate(HWND hwnd, LONG style)
lphc->self = hwnd; lphc->self = hwnd;
SetWindowLongPtrW( hwnd, 0, (LONG_PTR)lphc ); SetWindowLongPtrW( hwnd, 0, (LONG_PTR)lphc );
COMBO_update_uistate(lphc);
/* some braindead apps do try to use scrollbar/border flags */ /* some braindead apps do try to use scrollbar/border flags */
lphc->dwStyle = style & ~(WS_BORDER | WS_HSCROLL | WS_VSCROLL); lphc->dwStyle = style & ~(WS_BORDER | WS_HSCROLL | WS_VSCROLL);
@ -817,7 +830,8 @@ static void CBPaintText(
&rectEdit, &rectEdit,
pText ? pText : empty_stringW , size, NULL ); pText ? pText : empty_stringW , size, NULL );
if(lphc->wState & CBF_FOCUSED && !(lphc->wState & CBF_DROPPED)) if(lphc->wState & CBF_FOCUSED && !(lphc->wState & CBF_DROPPED) &&
!(lphc->UIState & UISF_HIDEFOCUS))
DrawFocusRect( hdc, &rectEdit ); DrawFocusRect( hdc, &rectEdit );
} }
@ -2337,6 +2351,21 @@ static LRESULT ComboWndProc_common( HWND hwnd, UINT message,
if( lphc->wState & CBF_EDIT ) if( lphc->wState & CBF_EDIT )
return SendMessageW(lphc->hWndEdit, EM_LIMITTEXT, wParam, lParam); return SendMessageW(lphc->hWndEdit, EM_LIMITTEXT, wParam, lParam);
break; break;
case WM_UPDATEUISTATE:
if (unicode)
DefWindowProcW(lphc->self, message, wParam, lParam);
else
DefWindowProcA(lphc->self, message, wParam, lParam);
if (COMBO_update_uistate(lphc))
{
/* redraw text */
if( !(lphc->wState & CBF_EDIT) )
NtUserInvalidateRect(lphc->self, &lphc->textRect, TRUE);
}
break;
default: default:
if (message >= WM_USER) if (message >= WM_USER)
WARN("unknown msg WM_USER+%04x wp=%04x lp=%08lx\n", WARN("unknown msg WM_USER+%04x wp=%04x lp=%08lx\n",

View file

@ -106,6 +106,7 @@ typedef struct
HFONT font; /* Current font */ HFONT font; /* Current font */
LCID locale; /* Current locale for string comparisons */ LCID locale; /* Current locale for string comparisons */
LPHEADCOMBO lphc; /* ComboLBox */ LPHEADCOMBO lphc; /* ComboLBox */
LONG UIState;
} LB_DESCR; } LB_DESCR;
@ -603,7 +604,10 @@ static void LISTBOX_PaintItem( LB_DESCR *descr, HDC hdc,
if (!item) if (!item)
{ {
if (action == ODA_FOCUS) if (action == ODA_FOCUS)
DrawFocusRect( hdc, rect ); {
if (!(descr->UIState & UISF_HIDEFOCUS))
DrawFocusRect( hdc, rect );
}
else else
FIXME("called with an out of bounds index %d(%d) in owner draw, Not good.\n",index,descr->nb_items); FIXME("called with an out of bounds index %d(%d) in owner draw, Not good.\n",index,descr->nb_items);
return; return;
@ -643,7 +647,8 @@ static void LISTBOX_PaintItem( LB_DESCR *descr, HDC hdc,
if (action == ODA_FOCUS) if (action == ODA_FOCUS)
{ {
DrawFocusRect( hdc, rect ); if (!(descr->UIState & UISF_HIDEFOCUS))
DrawFocusRect( hdc, rect );
return; return;
} }
if (item && item->selected) if (item && item->selected)
@ -678,7 +683,8 @@ static void LISTBOX_PaintItem( LB_DESCR *descr, HDC hdc,
} }
if (!ignoreFocus && (descr->focus_item == index) && if (!ignoreFocus && (descr->focus_item == index) &&
(descr->caret_on) && (descr->caret_on) &&
(descr->in_focus)) DrawFocusRect( hdc, rect ); (descr->in_focus) &&
!(descr->UIState & UISF_HIDEFOCUS)) DrawFocusRect( hdc, rect );
} }
} }
@ -2545,6 +2551,16 @@ static LRESULT LISTBOX_HandleChar( LB_DESCR *descr, WCHAR charW )
return 0; return 0;
} }
/* Retrieve the UI state for the control */
static BOOL LISTBOX_update_uistate(LB_DESCR *descr)
{
LONG prev_flags;
prev_flags = descr->UIState;
descr->UIState = DefWindowProcW(descr->self, WM_QUERYUISTATE, 0, 0);
return prev_flags != descr->UIState;
}
/*********************************************************************** /***********************************************************************
* LISTBOX_Create * LISTBOX_Create
@ -2605,6 +2621,8 @@ static BOOL LISTBOX_Create( HWND hwnd, LPHEADCOMBO lphc )
SetWindowLongPtrW( descr->self, 0, (LONG_PTR)descr ); SetWindowLongPtrW( descr->self, 0, (LONG_PTR)descr );
LISTBOX_update_uistate(descr);
/* if (wnd->dwExStyle & WS_EX_NOPARENTNOTIFY) descr->style &= ~LBS_NOTIFY; /* if (wnd->dwExStyle & WS_EX_NOPARENTNOTIFY) descr->style &= ~LBS_NOTIFY;
*/ */
if (descr->style & LBS_EXTENDEDSEL) descr->style |= LBS_MULTIPLESEL; if (descr->style & LBS_EXTENDEDSEL) descr->style |= LBS_MULTIPLESEL;
@ -3405,6 +3423,20 @@ static LRESULT WINAPI ListBoxWndProc_common( HWND hwnd, UINT msg,
if (lphc) return 0; if (lphc) return 0;
break; break;
case WM_UPDATEUISTATE:
if (unicode)
DefWindowProcW(descr->self, msg, wParam, lParam);
else
DefWindowProcA(descr->self, msg, wParam, lParam);
if (LISTBOX_update_uistate(descr))
{
/* redraw text */
if (descr->focus_item != -1)
LISTBOX_DrawFocusRect( descr, descr->in_focus );
}
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",

View file

@ -63,7 +63,8 @@ static COLORREF color_3dshadow, color_3ddkshadow, color_3dhighlight;
/* offsets for GetWindowLong for static private information */ /* offsets for GetWindowLong for static private information */
#define HFONT_GWL_OFFSET 0 #define HFONT_GWL_OFFSET 0
#define HICON_GWL_OFFSET (sizeof(HFONT)) #define HICON_GWL_OFFSET (sizeof(HFONT))
#define STATIC_EXTRA_BYTES (HICON_GWL_OFFSET + sizeof(HICON)) #define UISTATE_GWL_OFFSET (HICON_GWL_OFFSET+sizeof(HICON))
#define STATIC_EXTRA_BYTES (UISTATE_GWL_OFFSET + sizeof(LONG))
typedef void (*pfPaint)( HWND hwnd, HDC hdc, DWORD style ); typedef void (*pfPaint)( HWND hwnd, HDC hdc, DWORD style );
@ -115,6 +116,16 @@ const struct builtin_class_descr STATIC_builtin_class =
#endif #endif
}; };
static __inline void set_ui_state( HWND hwnd, LONG flags )
{
SetWindowLongW( hwnd, UISTATE_GWL_OFFSET, flags );
}
static __inline LONG get_ui_state( HWND hwnd )
{
return GetWindowLongPtrW( hwnd, UISTATE_GWL_OFFSET );
}
static void setup_clipping(HWND hwnd, HDC hdc, HRGN *orig) static void setup_clipping(HWND hwnd, HDC hdc, HRGN *orig)
{ {
RECT rc; RECT rc;
@ -143,6 +154,27 @@ static void restore_clipping(HDC hdc, HRGN hrgn)
DeleteObject(hrgn); DeleteObject(hrgn);
} }
/* Retrieve the UI state for the control */
static BOOL STATIC_update_uistate(HWND hwnd, BOOL unicode)
{
LONG flags, prevflags;
if (unicode)
flags = DefWindowProcW(hwnd, WM_QUERYUISTATE, 0, 0);
else
flags = DefWindowProcA(hwnd, WM_QUERYUISTATE, 0, 0);
prevflags = get_ui_state(hwnd);
if (prevflags != flags)
{
set_ui_state(hwnd, flags);
return TRUE;
}
return FALSE;
}
/*********************************************************************** /***********************************************************************
* STATIC_SetIcon * STATIC_SetIcon
* *
@ -424,6 +456,7 @@ static LRESULT StaticWndProc_common( HWND hwnd, UINT uMsg, WPARAM wParam,
ERR("Unknown style 0x%02lx\n", style ); ERR("Unknown style 0x%02lx\n", style );
return -1; return -1;
} }
STATIC_update_uistate(hwnd, unicode);
STATIC_InitColours(); STATIC_InitColours();
break; break;
@ -613,6 +646,18 @@ static LRESULT StaticWndProc_common( HWND hwnd, UINT uMsg, WPARAM wParam,
STATIC_TryPaintFcn( hwnd, full_style ); STATIC_TryPaintFcn( hwnd, full_style );
break; break;
case WM_UPDATEUISTATE:
if (unicode)
DefWindowProcW(hwnd, uMsg, wParam, lParam);
else
DefWindowProcA(hwnd, uMsg, wParam, lParam);
if (STATIC_update_uistate(hwnd, unicode) && hasTextStyle( full_style ))
{
RedrawWindow( hwnd, NULL, 0, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_ALLCHILDREN );
}
break;
default: default:
return unicode ? DefWindowProcW(hwnd, uMsg, wParam, lParam) : return unicode ? DefWindowProcW(hwnd, uMsg, wParam, lParam) :
DefWindowProcA(hwnd, uMsg, wParam, lParam); DefWindowProcA(hwnd, uMsg, wParam, lParam);
@ -666,7 +711,7 @@ static void STATIC_PaintTextfn( HWND hwnd, HDC hdc, DWORD style )
RECT rc; RECT rc;
HBRUSH hBrush; HBRUSH hBrush;
HFONT hFont, hOldFont = NULL; HFONT hFont, hOldFont = NULL;
WORD wFormat; DWORD wFormat;
INT len, buf_size; INT len, buf_size;
WCHAR *text; WCHAR *text;
@ -700,6 +745,8 @@ static void STATIC_PaintTextfn( HWND hwnd, HDC hdc, DWORD style )
if (style & SS_NOPREFIX) if (style & SS_NOPREFIX)
wFormat |= DT_NOPREFIX; wFormat |= DT_NOPREFIX;
else if (get_ui_state(hwnd) & UISF_HIDEACCEL)
wFormat |= DT_HIDEPREFIX;
if ((style & SS_TYPEMASK) != SS_SIMPLE) if ((style & SS_TYPEMASK) != SS_SIMPLE)
{ {

View file

@ -103,6 +103,7 @@ typedef struct
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 */
LONG UIState;
} HEADCOMBO,*LPHEADCOMBO; } HEADCOMBO,*LPHEADCOMBO;
/* Note, that CBS_DROPDOWNLIST style is actually (CBS_SIMPLE | CBS_DROPDOWN) */ /* Note, that CBS_DROPDOWNLIST style is actually (CBS_SIMPLE | CBS_DROPDOWN) */