Windows 修改屏幕阅读器读取模式对话框的顺序

Windows 修改屏幕阅读器读取模式对话框的顺序,windows,winapi,modal-dialog,screen-readers,Windows,Winapi,Modal Dialog,Screen Readers,有人知道屏幕阅读器和windows对话框吗?特别是如何强制屏幕阅读器以特定顺序读取对话框控件。此顺序必须在运行时确定,因为实际对话框控件是根据要显示的对话框类型动态添加的 注意 我正在使用一个简单的Win32应用程序对话框。我能够重现问题的一个小例子是一个空白的Win32应用程序,并使用默认的“关于”对话框 背景 我需要更新现有的弹出对话框,以便那些需要屏幕阅读器的用户能够正确地理解和理解它。目前,屏幕阅读器以令人困惑的顺序读取信息,这使得视障用户很难理解需要继续什么 问题细节 我似乎无法更新对

有人知道屏幕阅读器和windows对话框吗?特别是如何强制屏幕阅读器以特定顺序读取对话框控件。此顺序必须在运行时确定,因为实际对话框控件是根据要显示的对话框类型动态添加的

注意

我正在使用一个简单的Win32应用程序对话框。我能够重现问题的一个小例子是一个空白的Win32应用程序,并使用默认的“关于”对话框

背景

我需要更新现有的弹出对话框,以便那些需要屏幕阅读器的用户能够正确地理解和理解它。目前,屏幕阅读器以令人困惑的顺序读取信息,这使得视障用户很难理解需要继续什么

问题细节

我似乎无法更新对话框中控件的z顺序来更改屏幕阅读器读取它们的顺序

据我所知,我必须更新对话框上控件的制表符顺序(z顺序),因为这是屏幕阅读器读取信息的顺序(如果我偏离目标,请随时纠正我的错误)

网络上的许多建议建议要么使用函数,要么使用函数。不幸的是,我不能让这些正常工作

我的“基本”测试对话框定义了以下控件:

HWND ctrl_StaticText1 = GetDlgItem(hDlg, IDC_STATIC_1);
HWND ctrl_StaticText2 = GetDlgItem(hDlg, IDC_STATIC_2);
HWND ctrl_StaticText3 = GetDlgItem(hDlg, IDC_STATIC_3);

HWND ctrl_Edit1 = GetDlgItem(hDlg, IDC_EDIT_1);
HWND ctrl_Edit2 = GetDlgItem(hDlg, IDC_EDIT_2);

HWND ctrl_Pict1 = GetDlgItem(hDlg, IDC_PICT_1);

HWND ctrl_ButtonOk = GetDlgItem(hDlg, IDOK);
然后,我尝试如下设置z顺序

HDWP windowPos = BeginDeferWindowPos(7);

windowPos = DeferWindowPos(windowPos, ctrl_StaticText1, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
windowPos = DeferWindowPos(windowPos, ctrl_StaticText2, ctrl_StaticText1, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
windowPos = DeferWindowPos(windowPos, ctrl_StaticText3, ctrl_StaticText2, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);

windowPos = DeferWindowPos(windowPos, ctrl_Edit1, ctrl_StaticText3, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
windowPos = DeferWindowPos(windowPos, ctrl_Edit2, ctrl_Edit1, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);

windowPos = DeferWindowPos(windowPos, ctrl_Pict1, ctrl_Edit2, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);

windowPos = DeferWindowPos(windowPos, ctrl_ButtonOk, ctrl_Pict1, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);

EndDeferWindowPos(windowPos);
打开对话框时,屏幕阅读器显示“静态文本1,静态文本3,只读编辑”(只读编辑框为ctrl_Edit1,ctrl_Edit2不是只读的)

旁注

当对话框仅包含几个静态文本控件时,此功能似乎正常工作,只有当我开始添加更“复杂”的控件(如编辑框和图片控件)时,问题才会出现

谢谢你的帮助:)

编辑

根据要求,下面是.rc文件(我假设它只是感兴趣的对话框控件部分)


请注意,我在测试时做了一些更改,因此对于上面的文件,屏幕阅读器输出现在是“静态文本1、静态文本2、静态文本3、只读编辑”。我已尝试更改该文件中的顺序,编辑框之后的任何内容都不会由屏幕阅读器输出。

关键是将动态控件插入对话框中的正确位置和顺序。因此,假设控件以正确的顺序存储在数组中:创建第一个控件并使用SetWindowPos在正确的现有控件(如果有)之后定位它,然后将其用作下一个控件的位置。然后继续创建动态控件,并在运行时更新“位置”控件。如果这听起来可行,我可以生成一些示例代码。@user1793036您是否建议通过代码创建控件?不幸的是,在我的实际对话框中,所有可能的控件都已通过表单编辑器放置在对话框上,位置相对正确,然后根据需要移动和显示/隐藏它们,具体取决于需要显示的信息。@user1793036我意识到我原来的问题是这样说的“…真正的对话框控件是动态添加的…”我应该说的是“…真正的对话框控件是动态显示/隐藏的,但所有控件都是最初创建的,并事先放置在表单上…”
IDD_ABOUTBOX DIALOGEX 0, 0, 349, 190
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "About"
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
    LTEXT           "Static text 1",IDC_STATIC_1,35,25,40,8,NOT WS_GROUP
    LTEXT           "Static text 2",IDC_STATIC_2,33,55,40,8,NOT WS_GROUP
    LTEXT           "Static text 3",IDC_STATIC_3,173,52,40,8,NOT WS_VISIBLE | NOT WS_GROUP
    DEFPUSHBUTTON   "OK",IDOK,292,169,50,14
    EDITTEXT        IDC_EDIT_1, 72, 95, 55, 14, ES_AUTOHSCROLL | ES_READONLY
    CONTROL         "",IDC_PICT_1,"Static",SS_BLACKFRAME,138,92,20,20
    EDITTEXT        IDC_EDIT_2, 174, 95, 40, 14, ES_AUTOHSCROLLs
END