Keyboard cues are disabled by default on newer versions of Windows. Some win32 common controls, e.g., button doesn't draw a focus rect when SystemParametersInfoW(SPI_GETKEYBOARDCUES) reports FALSE.
Drawing a focus rect when the button is really small creates an effect that makes the button look corrupted. On Windows, the focus rect is not drawn when keyboard cues are disabled, which is the default.
Other controls also have this behavior, so they're included as well. There are some exceptions, for example, SysMonthCal32 always draws a focus rect, even when keyboard cues are disabled.
From: Zhiyi Zhang zzhang@codeweavers.com
Keyboard cues are disabled by default on newer versions of Windows. Some win32 common controls, e.g., button doesn't draw a focus rect when SystemParametersInfoW(SPI_GETKEYBOARDCUES) reports FALSE. --- dlls/win32u/sysparams.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 463b6b00f68..55234fea97f 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -5262,7 +5262,7 @@ static WCHAR desk_wallpaper_path[MAX_PATH]; static PATH_ENTRY( DESKPATTERN, DESKTOP_KEY, "Pattern", desk_pattern_path ); static PATH_ENTRY( DESKWALLPAPER, DESKTOP_KEY, "Wallpaper", desk_wallpaper_path );
-static BYTE user_prefs[8] = { 0x30, 0x00, 0x00, 0x80, 0x12, 0x00, 0x00, 0x00 }; +static BYTE user_prefs[8] = { 0x10, 0x00, 0x00, 0x80, 0x12, 0x00, 0x00, 0x00 }; static BINARY_ENTRY( USERPREFERENCESMASK, user_prefs, DESKTOP_KEY, "UserPreferencesMask" );
static FONT_ENTRY( CAPTIONLOGFONT, FW_BOLD, METRICS_KEY, "CaptionFont" );
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/user32/tests/sysparams.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+)
diff --git a/dlls/user32/tests/sysparams.c b/dlls/user32/tests/sysparams.c index 870b7f1cc93..1234a4766d0 100644 --- a/dlls/user32/tests/sysparams.c +++ b/dlls/user32/tests/sysparams.c @@ -2574,6 +2574,38 @@ static void test_WM_DISPLAYCHANGE(void) displaychange_test_active = FALSE; }
+static void test_SPI_SETKEYBOARDCUES( void ) /* 0x100B */ +{ + BOOL ret, values[2], result; + unsigned int i; + + trace( "testing SPI_{GET,SET}KEYBOARDCUES\n" ); + SetLastError( 0xdeadbeef ); + ret = SystemParametersInfoA( SPI_GETKEYBOARDCUES, 0, &result, 0 ); + if (!test_error_msg( ret, "SPI_{GET,SET}KEYBOARDCUES" )) + return; + ok( result == FALSE, "Expected keyboard cues disabled by default.\n" ); + values[1] = result; + values[0] = !result; + + for (i = 0; i < ARRAY_SIZE( values ); i++) + { + ret = SystemParametersInfoA( SPI_SETKEYBOARDCUES, 0, IntToPtr(values[i]), SPIF_UPDATEINIFILE | SPIF_SENDCHANGE ); + if (!test_error_msg( ret, "SPI_SETKEYBOARDCUES" )) + break; + ok( ret, "%d: ret=%d err=%ld\n", i, ret, GetLastError() ); + test_change_message( SPI_SETKEYBOARDCUES, 1 ); + + ret = SystemParametersInfoA( SPI_GETKEYBOARDCUES, 0, &result, 0 ); + ok( ret, "%d: ret=%d err=%ld\n", i, ret, GetLastError() ); + eq( result, values[i], "SPI_GETKEYBOARDCUES", "%d" ); + } + + ret = SystemParametersInfoA( SPI_SETKEYBOARDCUES, 0, IntToPtr(values[1]), SPIF_UPDATEINIFILE ); + ok( ret, "***warning*** failed to restore the original value: ret=%d err=%ld\n", ret, GetLastError()); + flush_change_messages(); +} + /* * Registry entries for the system parameters. * Names are created by 'SET' flags names. @@ -2625,6 +2657,7 @@ static DWORD WINAPI SysParamsThreadFunc( LPVOID lpParam ) test_SPI_SETMENUSHOWDELAY(); /* 107 */ test_SPI_SETWHEELSCROLLCHARS(); /* 108 */ test_SPI_SETWALLPAPER(); /* 115 */ + test_SPI_SETKEYBOARDCUES(); /* 0x100B */
SendMessageA( ghTestWnd, WM_DESTROY, 0, 0 );
From: Zhiyi Zhang zzhang@codeweavers.com
Drawing a focus rect when the button is really small creates an effect that makes the button look corrupted. On Windows, the focus rect is not drawn when keyboard cues are disabled, which is the default. --- dlls/comctl32/button.c | 18 +++++++++--------- dlls/comctl32/comctl32.h | 1 + dlls/comctl32/commctrl.c | 3 +++ 3 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/dlls/comctl32/button.c b/dlls/comctl32/button.c index a0eb41fec20..2e009aa222d 100644 --- a/dlls/comctl32/button.c +++ b/dlls/comctl32/button.c @@ -1960,7 +1960,7 @@ static void PB_Paint( const BUTTON_INFO *infoPtr, HDC hDC, UINT action ) } if ((cdrf & CDRF_SKIPPOSTPAINT) || dtFlags == (UINT)-1L) goto cleanup;
- if (action == ODA_FOCUS || (state & BST_FOCUS)) + if (COMCTL32_keyboard_cues_enabled && (action == ODA_FOCUS || (state & BST_FOCUS))) { InflateRect( &rc, -2, -2 ); DrawFocusRect( hDC, &rc ); @@ -2133,7 +2133,7 @@ static void CB_Paint( const BUTTON_INFO *infoPtr, HDC hDC, UINT action ) if ((cdrf & CDRF_SKIPPOSTPAINT) || dtFlags == (UINT)-1L) goto cleanup;
/* ... and focus */ - if (action == ODA_FOCUS || (state & BST_FOCUS)) + if (COMCTL32_keyboard_cues_enabled && (action == ODA_FOCUS || (state & BST_FOCUS))) { labelRect.left--; labelRect.right++; @@ -2274,7 +2274,7 @@ static void UB_Paint( const BUTTON_INFO *infoPtr, HDC hDC, UINT action ) SendMessageW(parent, WM_NOTIFY, nmcd.hdr.idFrom, (LPARAM)&nmcd); }
- if (!(cdrf & CDRF_SKIPPOSTPAINT)) + if (COMCTL32_keyboard_cues_enabled && !(cdrf & CDRF_SKIPPOSTPAINT)) DrawFocusRect( hDC, &rc ); }
@@ -2459,7 +2459,7 @@ static void SB_Paint( const BUTTON_INFO *infoPtr, HDC hDC, UINT action ) } if ((cdrf & CDRF_SKIPPOSTPAINT) || dtFlags == (UINT)-1L) goto cleanup;
- if (action == ODA_FOCUS || (state & BST_FOCUS)) + if (COMCTL32_keyboard_cues_enabled && (action == ODA_FOCUS || (state & BST_FOCUS))) DrawFocusRect(hDC, &push_rect);
cleanup: @@ -2732,7 +2732,7 @@ static void CL_Paint( const BUTTON_INFO *infoPtr, HDC hDC, UINT action ) } if (cdrf & CDRF_SKIPPOSTPAINT) goto cleanup;
- if (action == ODA_FOCUS || (state & BST_FOCUS)) + if (COMCTL32_keyboard_cues_enabled && (action == ODA_FOCUS || (state & BST_FOCUS))) { InflateRect(&rc, -2, -2); DrawFocusRect(hDC, &rc); @@ -2810,7 +2810,7 @@ static void PB_ThemedPaint(HTHEME theme, const BUTTON_INFO *infoPtr, HDC hDC, in } if (cdrf & CDRF_SKIPPOSTPAINT) return;
- if (focused) DrawFocusRect(hDC, &focusRect); + if (COMCTL32_keyboard_cues_enabled && focused) DrawFocusRect(hDC, &focusRect); }
static void CB_ThemedPaint(HTHEME theme, const BUTTON_INFO *infoPtr, HDC hDC, int state, UINT dtFlags, BOOL focused) @@ -2917,7 +2917,7 @@ static void CB_ThemedPaint(HTHEME theme, const BUTTON_INFO *infoPtr, HDC hDC, in } if ((cdrf & CDRF_SKIPPOSTPAINT) || dtFlags == (UINT)-1L) goto cleanup;
- if (focused) + if (COMCTL32_keyboard_cues_enabled && focused) { label_rect.left--; label_rect.right++; @@ -3108,7 +3108,7 @@ static void SB_ThemedPaint(HTHEME theme, const BUTTON_INFO *infoPtr, HDC hDC, in } if (cdrf & CDRF_SKIPPOSTPAINT) return;
- if (focused) DrawFocusRect(hDC, &focus_rect); + if (COMCTL32_keyboard_cues_enabled && focused) DrawFocusRect(hDC, &focus_rect); }
static void CL_ThemedPaint(HTHEME theme, const BUTTON_INFO *infoPtr, HDC hDC, int state, UINT dtFlags, BOOL focused) @@ -3217,7 +3217,7 @@ static void CL_ThemedPaint(HTHEME theme, const BUTTON_INFO *infoPtr, HDC hDC, in } if (cdrf & CDRF_SKIPPOSTPAINT) return;
- if (focused) + if (COMCTL32_keyboard_cues_enabled && focused) { MARGINS margins;
diff --git a/dlls/comctl32/comctl32.h b/dlls/comctl32/comctl32.h index a9a0b44fcd1..ae65fdcd656 100644 --- a/dlls/comctl32/comctl32.h +++ b/dlls/comctl32/comctl32.h @@ -37,6 +37,7 @@
extern HMODULE COMCTL32_hModule; extern HBRUSH COMCTL32_hPattern55AABrush; +extern BOOL COMCTL32_keyboard_cues_enabled;
/* Property sheet / Wizard */ #define IDD_PROPSHEET 1006 diff --git a/dlls/comctl32/commctrl.c b/dlls/comctl32/commctrl.c index 6097b1a9735..27e58eb7ae0 100644 --- a/dlls/comctl32/commctrl.c +++ b/dlls/comctl32/commctrl.c @@ -81,6 +81,7 @@ HMODULE COMCTL32_hModule = 0; static LANGID COMCTL32_uiLang = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL); HBRUSH COMCTL32_hPattern55AABrush = NULL; COMCTL32_SysColor comctl32_color; +BOOL COMCTL32_keyboard_cues_enabled = FALSE;
static HBITMAP COMCTL32_hPattern55AABitmap = NULL;
@@ -171,6 +172,8 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
COMCTL32_hModule = hinstDLL;
+ SystemParametersInfoW (SPI_GETKEYBOARDCUES, 0, &COMCTL32_keyboard_cues_enabled, 0); + /* add global subclassing atom (used by 'tooltip' and 'updown') */ COMCTL32_wSubclass = (LPWSTR)(DWORD_PTR)GlobalAddAtomW (strCC32SubclassInfo); TRACE("Subclassing atom added: %p\n", COMCTL32_wSubclass);
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/comctl32/combo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/comctl32/combo.c b/dlls/comctl32/combo.c index 1094132826b..a984adc0d5d 100644 --- a/dlls/comctl32/combo.c +++ b/dlls/comctl32/combo.c @@ -716,7 +716,7 @@ static void CBPaintText(HEADCOMBO *lphc, HDC hdc_paint) &rectEdit, pText ? pText : L"" , size, NULL );
- if(lphc->wState & CBF_FOCUSED && !(lphc->wState & CBF_DROPPED)) + if(COMCTL32_keyboard_cues_enabled && lphc->wState & CBF_FOCUSED && !(lphc->wState & CBF_DROPPED)) DrawFocusRect( hdc, &rectEdit ); }
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/comctl32/listbox.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/dlls/comctl32/listbox.c b/dlls/comctl32/listbox.c index 3d55fc2ad83..fcdd4dc1792 100644 --- a/dlls/comctl32/listbox.c +++ b/dlls/comctl32/listbox.c @@ -624,7 +624,10 @@ static void LISTBOX_PaintItem( LB_DESCR *descr, HDC hdc, const RECT *rect, if (index >= descr->nb_items) { if (action == ODA_FOCUS) - DrawFocusRect( hdc, rect ); + { + if (COMCTL32_keyboard_cues_enabled) + DrawFocusRect( hdc, rect ); + } else ERR("called with an out of bounds index %d(%d) in owner draw, Not good.\n",index,descr->nb_items); return; @@ -664,7 +667,8 @@ static void LISTBOX_PaintItem( LB_DESCR *descr, HDC hdc, const RECT *rect,
if (action == ODA_FOCUS) { - DrawFocusRect( hdc, rect ); + if (COMCTL32_keyboard_cues_enabled) + DrawFocusRect( hdc, rect ); return; } if (selected) @@ -697,7 +701,7 @@ static void LISTBOX_PaintItem( LB_DESCR *descr, HDC hdc, const RECT *rect, SetBkColor( hdc, oldBk ); SetTextColor( hdc, oldText ); } - if (focused) + if (COMCTL32_keyboard_cues_enabled && focused) DrawFocusRect( hdc, rect ); } }
From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/comctl32/listview.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c index b2856db471c..925574d9f59 100644 --- a/dlls/comctl32/listview.c +++ b/dlls/comctl32/listview.c @@ -1738,7 +1738,7 @@ static inline BOOL LISTVIEW_GetItemW(const LISTVIEW_INFO *infoPtr, LPLVITEMW lpL /* used to handle collapse main item column case */ static inline BOOL LISTVIEW_DrawFocusRect(const LISTVIEW_INFO *infoPtr, HDC hdc) { - return (infoPtr->rcFocus.left < infoPtr->rcFocus.right) ? + return (COMCTL32_keyboard_cues_enabled && infoPtr->rcFocus.left < infoPtr->rcFocus.right) ? DrawFocusRect(hdc, &infoPtr->rcFocus) : FALSE; }
@@ -5310,7 +5310,7 @@ enddraw: LISTVIEW_RefreshReportGrid(infoPtr, hdc);
/* Draw marquee rectangle if appropriate */ - if (infoPtr->bMarqueeSelect) + if (COMCTL32_keyboard_cues_enabled && infoPtr->bMarqueeSelect) DrawFocusRect(hdc, &infoPtr->marqueeDrawRect);
if (cdmode & CDRF_NOTIFYPOSTPAINT)