
Доступность legacy-приложений на WinForms, VB6 и Web Forms: аудит по WCAG 2.2 и ГОСТ и план исправлений
Старое приложение на WinForms, VB6 или Web Forms внезапно должно соответствовать ГОСТ Р 52872-2019 или WCAG: этого требует тендер, сотрудник со скринридером или клиент из ЕС. Разбираем, какие стандарты применимы к десктопу и вебу, как провести аудит за несколько дней, что исправляется свойствами и разметкой, а что придётся перепроектировать.
Старое корпоративное приложение на WinForms, VB6 или ASP.NET Web Forms обычно писали под одного «среднего» пользователя: мышь, обычное зрение, стандартная тема Windows. Пока программа работала внутри компании, вопрос доступности не поднимался. Он возникает внезапно: в тендере появляется требование соответствия ГОСТ Р 52872-2019 или WCAG, в компанию приходит сотрудник со скринридером или европейский клиент ссылается на European Accessibility Act.
Хорошая новость: большую часть проблем в legacy-приложении можно исправить без переписывания, свойствами контролов и правкой разметки. Плохая: аудит почти всегда находит экраны, которые нужно перепроектировать, а не подкрасить. Здесь нужен взгляд дизайнера, и если своего в команде нет, разумно отдать UX-аудит и проектирование доступных интерфейсов внешней команде, а за разработчиками оставить исправления в коде и регрессионные проверки.
Ниже — какие стандарты применимы к десктопному и веб-приложению, как провести аудит своими силами за несколько дней, что конкретно исправлять в WinForms, VB6 и Web Forms и как встроить доступность в план модернизации. Общие вопросы обновления интерфейса разобраны в статье о редизайне WinForms- и VB6-приложения, здесь фокус только на доступности.
Что такое доступность приложения и кому она нужна?
Доступность (accessibility, a11y) — это возможность пользоваться программой людям с нарушениями зрения, слуха, моторики и когнитивных функций, а также всем, кто работает в неудобных условиях: без мыши, на мониторе с высоким масштабом, при ярком солнце. На практике это сводится к четырём проверяемым вещам: программу можно полностью пройти с клавиатуры, скринридер правильно называет каждый элемент, текст читается при высоком контрасте и увеличении, а важная информация не передаётся только цветом или звуком.
Кому это нужно в мире legacy-систем:
- Госзаказчикам и подрядчикам. В технических заданиях на доработку систем для госорганов всё чаще встречается ссылка на ГОСТ Р 52872-2019 или уровень WCAG AA.
- Экспортёрам ПО и сервисов в ЕС. С 28 июня 2025 года действует European Accessibility Act, требования детализирует стандарт EN 301 549, и он распространяется не только на сайты, но и на программное обеспечение.
- Работодателям. Сотрудник с нарушением зрения не сможет вести учёт в программе, где половина полей для скринридера безымянна.
- Всем пользователям. Полная клавиатурная навигация ускоряет работу операторов, которые вводят сотни документов в день, а корректный масштаб нужен любому, у кого 4K-монитор.
Какие стандарты применяются: WCAG 2.2, ГОСТ Р 52872-2019, EN 301 549, Section 508
Все действующие стандарты так или иначе опираются на WCAG — руководство W3C с тремя уровнями соответствия: A (минимум), AA (рабочая цель почти всех требований) и AAA (максимум, целиком почти недостижим). Различаются они редакцией WCAG и тем, как переносят веб-критерии на десктоп.
| Стандарт | Где применяется | Основа | Десктопные приложения |
|---|---|---|---|
| WCAG 2.2 | Международная рекомендация W3C, октябрь 2023 года | Сама является основой | Написан для веба, но критерии применимы к любому интерфейсу |
| ГОСТ Р 52872-2019 | Россия, национальный стандарт | WCAG 2.1 | Да: в названии прямо указаны приложения для стационарных и мобильных устройств и иные интерфейсы |
| EN 301 549 | Евросоюз, гармонизированный стандарт к European Accessibility Act | WCAG 2.1 AA плюс свои разделы | Да, отдельная глава о программном обеспечении, не относящемся к вебу |
| Section 508 | США, федеральные закупки ИТ | WCAG 2.0 AA | Да, критерии WCAG применяются и к не-веб ПО |
Практический вывод: если требование сформулировано как «соответствие ГОСТ» или «WCAG AA», ориентируйтесь на WCAG 2.2 уровня AA — он включает требования 2.1 и добавляет несколько новых. Полный перечень критериев с пояснениями есть в официальном тексте WCAG 2.2. Для legacy-интерфейсов из новых критериев 2.2 чаще всего «стреляют» три:
- 2.5.8 Размер цели. Кликабельный элемент не меньше 24×24 пикселей или с достаточным отступом от соседей. Мелкие иконки в тулбарах старых программ и крошечные чекбоксы в гридах обычно не проходят.
- 2.4.11 Фокус не перекрыт. Элемент в фокусе не должен целиком прятаться под закреплённой панелью, всплывающим окном или шапкой страницы.
- 3.3.7 Повторный ввод. Данные, которые пользователь уже вводил в этом же процессе, не надо требовать заново — типичная боль многошаговых мастеров в учётных системах.
Как провести аудит доступности legacy-приложения своими силами?
Полный экспертный аудит занимает недели, но первичную картину команда получает за 2–5 дней. Автоматические инструменты находят только часть проблем, поэтому аудит всегда комбинированный: сканер плюс ручные сценарии.
- Выберите 5–10 ключевых сценариев. Не экраны, а задачи: «создать счёт», «найти клиента и изменить контакт», «выгрузить отчёт за месяц». Аудит по сценариям сразу показывает, где пользователь застрянет.
- Пройдите каждый сценарий только с клавиатуры. Отключите мышь. Фиксируйте, куда не попадает фокус, где его не видно, где порядок табуляции прыгает по форме и где нельзя закрыть диалог.
- Пройдите сценарии со скринридером. Встроенный «Экранный диктор» Windows включается сочетанием Win + Ctrl + Enter, бесплатный NVDA ставится за пять минут. Слушайте, называет ли он поля, кнопки и состояние флажков.
- Проверьте отображение. Включите высококонтрастную тему Windows и масштаб 150–200 %. Ищите обрезанный текст, исчезнувшие рамки, жёстко заданные цвета, которые не меняются вместе с темой.
- Запустите автоматическую проверку. Для десктопа — Accessibility Insights for Windows (режим FastPass) или Inspect из Windows SDK, для веба — Accessibility Insights for Web, axe DevTools или проверка доступности в Lighthouse.
- Сведите находки в реестр. По каждой проблеме — сценарий, экран, критерий WCAG, серьёзность (блокирует задачу или мешает) и оценка: исправляется свойством, правкой разметки или требует перепроектирования экрана.
Последняя колонка реестра определяет бюджет. Свойства и разметку правят разработчики за дни, а экраны, которые невозможно пройти без мыши или где смысл передаётся только цветом, нужно проектировать заново. Такой реестр удобно вести рядом с техническим аудитом кода — см. чек-лист аудита legacy-кодовой базы на VB.NET: часть проблем доступности упирается в те же самописные контролы и сторонние компоненты.
Типичные проблемы доступности в WinForms, VB6 и Web Forms
У каждой технологии свой набор «родовых травм». Таблица поможет быстро понять, что искать в первую очередь.
| Проблема | WinForms | VB6 | ASP.NET Web Forms |
|---|---|---|---|
| Поля без имени для скринридера | Не заполнен AccessibleName, подпись не стоит перед полем в порядке табуляции | Label — безоконный контрол, скринридер его не видит и часто объявляет поле без имени | asp:Label без AssociatedControlID рендерится в span, а не в label |
| Клавиатурная навигация | Хаотичный TabIndex, контролы с TabStop = False, действия только по двойному щелчку | То же плюс действия в событиях MouseDown и Click на картинках | Ссылки-кнопки на JavaScript без href, ловушки фокуса в модальных окнах |
| Цвет и контраст | Жёстко заданные BackColor и ForeColor, игнорирование высококонтрастной темы | То же, плюс фоновые картинки форм | Серый текст на сером, ошибки валидации только красным цветом |
| Самописные и сторонние контролы | Owner-draw контролы без AccessibleObject невидимы для вспомогательных технологий | OCX-гриды и календари почти не поддерживают MSAA | Старые версии сторонних наборов контролов с табличной вёрсткой |
| Динамические изменения | Статус в строке состояния не озвучивается | Сообщения только звуком Beep | Обновления UpdatePanel не объявляются скринридеру |
| Масштаб | Обрезанный текст при 150–200 %, если режим DPI не настроен | Приложение не DPI-aware, Windows растягивает его картинкой | Фиксированная ширина в пикселях, горизонтальная прокрутка |
Как исправить доступность в WinForms на VB.NET?
WinForms даёт для доступности почти всё необходимое: стандартные контролы поддерживают Microsoft UI Automation, а недостающее дописывается свойствами. Список свойств и их назначение есть в документации Microsoft по свойствам доступности контролов. Порядок работ обычно такой.
- Имена и описания. Для каждого поля, кнопки-иконки и картинки заполните
AccessibleName, при необходимостиAccessibleDescription. Подпись Label ставьте непосредственно перед полем в порядке табуляции. - Клавиши доступа. Символ
&в тексте подписи и кнопки задаёт сочетание Alt + буква; у Label включитеUseMnemonic, чтобы фокус переходил к следующему полю. - Порядок табуляции. В дизайнере Visual Studio включите режим «Порядок перехода по Tab» и выстройте его по смыслу формы, сверху вниз и слева направо.
- Системные цвета. Не задавайте цвета жёстко либо переключайтесь на
SystemColors, когда включена высококонтрастная тема. - Самописные контролы. Для owner-draw контрола переопределите
CreateAccessibilityInstanceи верните наследникаAccessibleObjectс корректными именем, ролью и состоянием.
Минимальный пример: имена для полей и реакция на смену контрастной темы без перезапуска программы.
Imports Microsoft.Win32
Public Class frmCustomer
Public Sub New()
InitializeComponent()
' Имена для скринридера: кнопка-иконка и поле без видимой подписи
btnFind.AccessibleName = "Найти клиента"
txtInn.AccessibleName = "ИНН клиента"
txtInn.AccessibleDescription = "10 или 12 цифр"
lblName.Text = "&Наименование" ' Alt+Н переводит фокус в поле
lblName.UseMnemonic = True
ApplyColors()
AddHandler SystemEvents.UserPreferenceChanged, AddressOf OnPrefsChanged
End Sub
Private Sub ApplyColors()
If SystemInformation.HighContrast Then
pnlHeader.BackColor = SystemColors.Window
pnlHeader.ForeColor = SystemColors.WindowText
Else
pnlHeader.BackColor = Color.FromArgb(0, 64, 128)
pnlHeader.ForeColor = Color.White
End If
End Sub
Private Sub OnPrefsChanged(sender As Object, e As UserPreferenceChangedEventArgs)
ApplyColors()
End Sub
Protected Overrides Sub OnFormClosed(e As FormClosedEventArgs)
' Системное событие статическое: без отписки форма не освободится
RemoveHandler SystemEvents.UserPreferenceChanged, AddressOf OnPrefsChanged
MyBase.OnFormClosed(e)
End Sub
End ClassОтдельно о версии платформы. Если приложение остаётся на .NET Framework, улучшения доступности WinForms из версий 4.7.1, 4.7.2 и 4.8 (подсказки при навигации с клавиатуры, LiveRegion, события уведомлений, исправления в DataGridView и ToolStrip) включаются переключателями в конфигурации. Без них даже правильно заполненные свойства работают по старым правилам.
<configuration>
<runtime>
<AppContextSwitchOverrides value="Switch.UseLegacyAccessibilityFeatures=false;Switch.UseLegacyAccessibilityFeatures.2=false;Switch.UseLegacyAccessibilityFeatures.3=false;Switch.System.Windows.Forms.UseLegacyToolTipDisplay=false" />
</runtime>
</configuration>Подробности по каждому переключателю — в обзоре нововведений доступности в .NET Framework. В WinForms на современном .NET эти улучшения включены всегда, и это ещё один аргумент за переход; как его пройти, описано в статье о переносе WinForms на VB.NET на новый .NET.
Что можно сделать с доступностью VB6-приложения?
Здесь честный ответ скромнее. VB6 опирается на старый интерфейс Microsoft Active Accessibility, и возможности влиять на то, что «видит» скринридер, у него ограничены. Стандартные контролы вроде TextBox и CommandButton — это обычные окна Windows, их вспомогательные технологии понимают. Безоконные Label, Image, Shape и Line для них не существуют, а большинство OCX-гридов и календарей поддерживают MSAA плохо или никак.
Что реально сделать без переписывания:
- выстроить
TabIndexпо смыслу формы и убрать действия, доступные только мышью; - добавить клавиши доступа через
&в подписях и пунктах меню; - заменить важные картинки-кнопки на CommandButton с текстом;
- убрать жёсткие цвета там, где они не несут смысла, и продублировать цветовые статусы текстом;
- заменить сообщения звуком на видимые сообщения в окне или строке состояния;
- проверить работу при масштабе 150 % с манифестом DPI-awareness или без него — что для конкретной программы меньшее зло.
Если по требованиям нужен уровень AA, а ключевые экраны построены на OCX-гридах, доработками VB6 его не достичь. Тогда доступность становится ещё одним аргументом в решении о миграции — вместе с поддержкой платформы и безопасностью.
Как исправить доступность в ASP.NET Web Forms?
Web Forms генерирует HTML, а значит, к нему применимы все веб-инструменты проверки. Большинство проблем решается правкой разметки страниц и шаблонов, без изменения логики.
<%-- Подпись связана с полем: рендерится <label for="..."> --%>
<asp:Label runat="server" AssociatedControlID="txtCustomer" Text="Клиент" />
<asp:TextBox runat="server" ID="txtCustomer" aria-describedby="custHint" />
<span id="custHint">Название или ИНН</span>
<%-- Таблица с настоящими заголовками столбцов (th scope="col") --%>
<asp:GridView runat="server" ID="gvOrders" UseAccessibleHeader="true"
Caption="Заказы за выбранный период" OnPreRender="gvOrders_PreRender" />
<%-- Результат частичного обновления объявляется скринридеру --%>
<div aria-live="polite">
<asp:UpdatePanel runat="server" ID="upTotals">...</asp:UpdatePanel>
</div>Чтобы заголовок GridView попал в thead, в обработчике PreRender выставьте gvOrders.HeaderRow.TableSection = TableRowSection.TableHeader. Ещё несколько пунктов, которые закрывают большую часть находок сканера:
- Режим рендеринга. Атрибут
controlRenderingCompatibilityVersion="4.0"вweb.configубирает часть устаревшей разметки, аRenderingMode="List"уasp:Menuвыводит меню списком вместо таблиц. - Альтернативный текст. У
asp:Imageиasp:ImageButtonзаполнитеAlternateText; декоративным картинкам — пустой, чтобы скринридер их пропускал. - Ошибки валидации. Текст ошибки должен быть рядом с полем и связан с ним через
aria-describedby, а не только подсвечен красным;ValidationSummaryвыводите в начале формы. - Язык и заголовки. Атрибут
langуhtml, уникальныйtitleна каждой странице и логичная иерархия заголовков в мастер-странице. - Кнопки и ссылки.
LinkButton, работающий через__doPostBack, с клавиатуры доступен, но для скринридера это ссылка; там, где действие меняет данные, используйтеasp:Button.
Если Web Forms всё равно предстоит переносить, доступность лучше заложить в требования к новому интерфейсу сразу: исправлять её после переезда дороже. Порядок миграции разобран в пошаговом плане перехода с Web Forms на ASP.NET Core и Blazor.
Исправлять старое приложение или закладывать доступность в новое?
Решение зависит от того, сколько находок закрывается свойствами и разметкой, а сколько требует перепроектирования экранов.
| Ситуация | Рекомендация |
|---|---|
| WinForms или Web Forms, проблемы в основном в именах, порядке табуляции и контрасте | Исправлять в текущем приложении: обычно это недели работы разработчика |
| Ключевые сценарии завязаны на самописные или сторонние контролы без поддержки доступности | Заменить контролы поэкранно, начиная с самых используемых сценариев |
| VB6 с OCX-гридами и требование уровня AA | Закладывать доступность в новое приложение, в старом — только клавиатура и контраст |
| Миграция уже запланирована | Внести WCAG 2.2 AA в требования к новому интерфейсу и проверять каждый модуль при приёмке |
Во всех случаях полезно, чтобы доступность проверял не только разработчик. Дизайнер видит то, что не ловит сканер: перегруженные формы, неочевидный порядок действий, статусы, понятные только по цвету. Именно эти находки чаще всего и требуют перепроектирования, а не правки свойств.
Чек-лист доступности перед релизом
- каждый ключевой сценарий проходится только с клавиатуры, фокус всегда виден;
- скринридер называет все поля, кнопки, флажки и их состояние;
- контраст текста не ниже 4,5:1, крупного текста и элементов интерфейса — не ниже 3:1;
- в высококонтрастной теме Windows и при масштабе 200 % ничего не исчезает и не обрезается;
- ошибки ввода описаны текстом рядом с полем, а не только цветом;
- кликабельные элементы не меньше 24×24 пикселей или разнесены друг от друга;
- важные события не передаются только звуком;
- реестр находок с критериями WCAG обновлён, нерешённые пункты внесены в план.
Как это делают сегодня
Вопросы и ответы
Обязательно ли соблюдать ГОСТ Р 52872-2019 для внутреннего корпоративного приложения?
Национальный стандарт сам по себе применяется добровольно. Обязательным его делают требования заказчика: техническое задание госоргана, условия тендера или договор. Для внутреннего приложения это решение компании, но если в ней работают сотрудники с нарушениями зрения или моторики, базовые требования стоит выполнить в любом случае.
Применим ли WCAG к десктопным приложениям, а не только к сайтам?
Да. WCAG написан для веба, но его критерии описывают интерфейс в целом: клавиатуру, имена элементов, контраст, масштаб. ГОСТ Р 52872-2019, EN 301 549 и Section 508 прямо распространяют эти требования на приложения для стационарных устройств, включая десктопные программы.
Какими инструментами проверить доступность WinForms-приложения?
Accessibility Insights for Windows в режиме FastPass и утилитой Inspect из Windows SDK, плюс ручной проход ключевых сценариев с клавиатуры и со скринридером: встроенным «Экранным диктором» или бесплатным NVDA. Автоматические проверки находят только часть проблем, поэтому ручные сценарии обязательны.
Можно ли сделать VB6-приложение полностью доступным?
Как правило, нет. VB6 опирается на старый Microsoft Active Accessibility, безоконные контролы вроде Label для скринридеров невидимы, а OCX-гриды поддерживают его слабо. Реально улучшить клавиатурную навигацию, клавиши доступа, контраст и сообщения. Для уровня AA ключевые экраны придётся переносить на современную платформу.
Сколько времени занимает аудит и исправление доступности?
Первичный аудит по 5–10 ключевым сценариям занимает 2–5 дней. Исправления свойствами и разметкой в WinForms и Web Forms обычно укладываются в несколько недель. Срок сильно растёт, если ключевые сценарии построены на самописных или сторонних контролах: их приходится заменять или перепроектировать экраны.
Что изменилось в WCAG 2.2 по сравнению с WCAG 2.1?
Добавлено девять критериев и снят устаревший критерий о синтаксическом разборе разметки. Для старых интерфейсов важнее всего минимальный размер кликабельной цели 24×24 пикселя, требование не перекрывать элемент в фокусе и запрет заставлять пользователя повторно вводить уже введённые данные в том же процессе.