[1/2] user32: msgbox: Make buttons an own control group.

Joachim Priesner joachim.priesner at web.de
Mon Oct 12 09:57:49 CDT 2015


Currently, focus switching using the arrow keys focuses the label as well,
which does not conform to Windows' behavior.

Arrow focus switching uses GetNextDlgGroupItem, so the buttons need to be
a control group. The first button of the group needs to have the WS_GROUP style,
and the group needs to be delimited by a control with the WS_GROUP style.

Note: I see no sane way of unit testing this. I manually verified that the
behavior matches that of Windows 8.1.

Signed-off-by: Joachim Priesner <joachim.priesner at web.de>
---
 dlls/user32/msgbox.c  | 17 ++++++++++++++++-
 dlls/user32/user32.rc |  2 +-
 2 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/dlls/user32/msgbox.c b/dlls/user32/msgbox.c
index 7fb17bd..afe23b5 100644
--- a/dlls/user32/msgbox.c
+++ b/dlls/user32/msgbox.c
@@ -74,6 +74,7 @@ static void MSGBOX_OnInit(HWND hwnd, LPMSGBOXPARAMSW lpmb)
     HMONITOR monitor = 0;
     MONITORINFO mon_info;
     LPCWSTR lpszText;
+    LONG windowStyle;
     WCHAR *buffer = NULL;
     const WCHAR *ptr;
 
@@ -115,12 +116,14 @@ static void MSGBOX_OnInit(HWND hwnd, LPMSGBOXPARAMSW lpmb)
     TRACE_(msgbox)("%s\n", debugstr_w(lpszText));
     SetWindowTextW(GetDlgItem(hwnd, MSGBOX_IDTEXT), lpszText);
 
-    /* Remove not selected buttons */
+    /* Remove not selected buttons and assign the WS_GROUP style to the first button */
+    hItem = 0;
     switch(lpmb->dwStyle & MB_TYPEMASK) {
     case MB_OK:
 	DestroyWindow(GetDlgItem(hwnd, IDCANCEL));
 	/* fall through */
     case MB_OKCANCEL:
+	hItem = GetDlgItem(hwnd, IDOK);
 	DestroyWindow(GetDlgItem(hwnd, IDABORT));
 	DestroyWindow(GetDlgItem(hwnd, IDRETRY));
 	DestroyWindow(GetDlgItem(hwnd, IDIGNORE));
@@ -130,6 +133,7 @@ static void MSGBOX_OnInit(HWND hwnd, LPMSGBOXPARAMSW lpmb)
 	DestroyWindow(GetDlgItem(hwnd, IDCONTINUE));
 	break;
     case MB_ABORTRETRYIGNORE:
+	hItem = GetDlgItem(hwnd, IDABORT);
 	DestroyWindow(GetDlgItem(hwnd, IDOK));
 	DestroyWindow(GetDlgItem(hwnd, IDCANCEL));
 	DestroyWindow(GetDlgItem(hwnd, IDYES));
@@ -141,6 +145,7 @@ static void MSGBOX_OnInit(HWND hwnd, LPMSGBOXPARAMSW lpmb)
 	DestroyWindow(GetDlgItem(hwnd, IDCANCEL));
 	/* fall through */
     case MB_YESNOCANCEL:
+	hItem = GetDlgItem(hwnd, IDYES);
 	DestroyWindow(GetDlgItem(hwnd, IDOK));
 	DestroyWindow(GetDlgItem(hwnd, IDABORT));
 	DestroyWindow(GetDlgItem(hwnd, IDRETRY));
@@ -149,6 +154,7 @@ static void MSGBOX_OnInit(HWND hwnd, LPMSGBOXPARAMSW lpmb)
 	DestroyWindow(GetDlgItem(hwnd, IDTRYAGAIN));
 	break;
     case MB_RETRYCANCEL:
+	hItem = GetDlgItem(hwnd, IDRETRY);
 	DestroyWindow(GetDlgItem(hwnd, IDOK));
 	DestroyWindow(GetDlgItem(hwnd, IDABORT));
 	DestroyWindow(GetDlgItem(hwnd, IDIGNORE));
@@ -158,6 +164,7 @@ static void MSGBOX_OnInit(HWND hwnd, LPMSGBOXPARAMSW lpmb)
 	DestroyWindow(GetDlgItem(hwnd, IDTRYAGAIN));
 	break;
     case MB_CANCELTRYCONTINUE:
+	hItem = GetDlgItem(hwnd, IDCANCEL);
 	DestroyWindow(GetDlgItem(hwnd, IDOK));
 	DestroyWindow(GetDlgItem(hwnd, IDABORT));
 	DestroyWindow(GetDlgItem(hwnd, IDIGNORE));
@@ -165,6 +172,14 @@ static void MSGBOX_OnInit(HWND hwnd, LPMSGBOXPARAMSW lpmb)
 	DestroyWindow(GetDlgItem(hwnd, IDNO));
 	DestroyWindow(GetDlgItem(hwnd, IDRETRY));
     }
+
+    if (hItem) {
+        windowStyle = GetWindowLongW(hItem, GWL_STYLE);
+        if (windowStyle) {
+            SetWindowLongW(hItem, GWL_STYLE, windowStyle | WS_GROUP);
+        }
+    }
+
     /* Set the icon */
     switch(lpmb->dwStyle & MB_ICONMASK) {
     case MB_ICONEXCLAMATION:
diff --git a/dlls/user32/user32.rc b/dlls/user32/user32.rc
index d281d53..5c67585 100644
--- a/dlls/user32/user32.rc
+++ b/dlls/user32/user32.rc
@@ -75,7 +75,6 @@ MSGBOX DIALOG 100, 80, 216, 168
 STYLE DS_MODALFRAME | DS_NOIDLEMSG | DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
 BEGIN
     ICON "", MSGBOX_IDICON, 8, 20, 16, 16, WS_CHILD | WS_VISIBLE
-    LTEXT "", MSGBOX_IDTEXT, 32, 4, 176, 48, WS_CHILD | WS_VISIBLE | WS_GROUP | SS_NOPREFIX
     PUSHBUTTON "OK", IDOK, 16, 56, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
     PUSHBUTTON "Cancel", IDCANCEL, 74, 56, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
     PUSHBUTTON "&Abort", IDABORT, 132, 56, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
@@ -86,6 +85,7 @@ BEGIN
     PUSHBUTTON "&Try Again", IDTRYAGAIN, 422, 56, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
     PUSHBUTTON "&Continue", IDCONTINUE, 480, 56, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
     PUSHBUTTON "Help", IDHELP, 538, 56, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+    LTEXT "", MSGBOX_IDTEXT, 32, 4, 176, 48, WS_CHILD | WS_VISIBLE | WS_GROUP | SS_NOPREFIX
 END
 
 MDI_MOREWINDOWS DIALOG 20, 20, 232, 122
-- 
2.1.4




More information about the wine-patches mailing list