מבוא לנגישות יישומי Windows — הכנה לאוטומציית UI ולדרישות התאמות סבירות

· · נגישות, UI Automation, Windows, WinForms, WPF, התאמה סבירה, קוראי מסך, חוק אפליית מוגבלות, יישומים עסקיים

“עובד באמצע הקריירה עם לקות ראייה לא יכול להשתמש ביישום הזנת ההזמנות המרכזי עם קורא מסך. הוא משתמש בדפדפן ובדואר בלי בעיה, אבל רק הקריאה של היישום העסקי שלנו לא עובדת כמו שצריך. אפשר לעשות משהו?” — ייעוצים מהסוג הזה ממחלקות IT של לקוחות הולכים וגדלים.

רקע אחד הוא המסגרת החוקית. תיקון 2021 לחוק ביטול האפליה נגד אנשים עם מוגבלות נכנס לתוקף ב-1 באפריל 2024, ו”מתן התאמה סבירה” לאנשים עם מוגבלות הפך לחובה גם לעסקים.1 יתרה מזו, יחס עובד–חברה כמו בפתיחה (תחום התעסוקה) הוא תחום חוק קידום תעסוקת אנשים עם מוגבלות, שחייב מעסיקים לספק התאמה סבירה מאז אפריל 2016.2 הרעיון ש”נגישות היא נושא של אתרים ואין לה קשר ליישומי Windows פנימיים” כבר לא מחזיק, לא בחוק ולא בפועל.

מצד שני, מרצפת הפיתוח, “אין לנו מושג מה לעשות” הוא מקום כנה. לנגישות של יישומי שולחן עבודה של Windows יש פחות מידע מאשר לאינטרנט, ואין פתרון קסם בדיעבד. גם אין צורך להיות פסימיים. אם מבינים את המנגנון שבו קורא מסך קורא יישום (UI Automation) וקולטים את היסודות של שם, מקלדת וצבע, השימושיות של יישום עסקי משתפרת מהותית. והרבה מזה הוא שיפור שמעלה את הפרודוקטיביות של כל משתמש, עם מוגבלות או בלי.

מיועד למפתחי יישומים עסקיים יפניים ולאנשי IT, המאמר הזה מחבר במעבר אחד ממיון מינימלי של המסגרת החוקית והתקנים, דרך מנגנון UI Automation, מימוש ב-WinForms/WPF, הפעלת מקלדת, צבע וניגודיות וכלי אימות, ועד דרך מציאותית לקביעת סדרי עדיפות.

זרימת המאמר הזהמבנה המאמר, המחבר בסדר ממיון המסגרת החוקית והתקנים דרך מנגנון UI Automation, מימוש ב-WinForms וב-WPF, הפעלת מקלדת, צבע וניגודיות, כלי אימות ואופן קביעת סדרי עדיפותמיון המסגרת החוקית והתקניםמנגנון UI Automationמימוש ב-WinForms/WPFהפעלת מקלדתצבע וניגודיותכלי אימותאופן קביעת סדרי עדיפות

איור 1: המאמר מחבר את המסגרת החוקית דרך מנגנון, מימוש, אימות וסדרי עדיפות בזרימה אחת.

1. השורה התחתונה קודם

  • מתן התאמה סבירה הוא חובה גם לעסקים מאז 1 באפריל 2024. כשאדם עם מוגבלות מביע כוונה להסרת מחסום, נדרשת תגובה בטווח שאינו נטל מופרז. תחום התעסוקה הוא תחת חוק קידום תעסוקת אנשים עם מוגבלות, וזו חובת מעסיק מאז אפריל 2016.12
  • התאמה סבירה היא תהליך של “תגובה לבקשה אישית דרך דיאלוג בונה”; הפיכת היישום לקל יותר לשימוש מראש היא “שיפור סביבתי” (חובת מאמץ). תמיכה מוקדמת מושלמת אינה החובה; מה שחשוב הוא לא לסרב לדיאלוג באופן חד-צדדי.1
  • הקריטריונים הטכניים לנגישות מרוכזים ב-WCAG ‏(JIS X 8341-3:2016). JIS X 8341-3:2016 הוא תקן מקביל באותו תוכן ל-WCAG 2.0, ו-WCAG2ICT של W3C נותן הנחיה ליישום על תוכנה שאינה-רשת. אפשר לבדוק יישום שולחן עבודה באותה חשיבה.34
  • קורא מסך קורא יישום דרך UI Automation ‏(UIA). המאפיינים שכל רכיב בעץ UIA מחזיק — Name, ControlType וכדומה — ודפוסי בקרה כמו Invoke, Value ו-SelectionItem הם החומר להכרזה ולהפעלה.5
  • כפתור ש-Name שלו ריק מוכרז רק כ”כפתור”. התיקון בעדיפות הגבוהה ביותר הוא מתן שמות. WinForms משתמש ב-AccessibleName ובשיוך Label לסדר Tab; WPF משתמש ב-AutomationProperties.Name/LabeledBy.67
  • היכולת להגיע לכל פונקציה מהמקלדת בלבד היא קריטריון הצלחה של WCAG ‏(2.1.1) ובאותו זמן מהירות הקלט של מפעיל מיומן עצמה. הצבת סדר Tab, מקשי גישה וסימן מיקוד מתחברת ישירות ליעילות של כל משתמש.8
  • לוקחים יחס ניגודיות טקסט 4.5:1 או יותר כמדריך, ולא מעבירים מידע בצבע בלבד. בערכת נושא ניגודיות (ניגודיות גבוהה), מכבדים צבעי מערכת ולא צבעים מקודדים בקשיחות.89
  • משלבים אימות עם FastPass ב-Accessibility Insights for Windows ועם בדיקה מעשית עם קורא מסך. כי הם יושבים על אותה תשתית UIA, העבודה הזאת גם משתלמת הדדית עם נכסי בדיקות UI אוטומטיות כמו FlaUI.10
  • אין צורך לתקן כל מסך בבת אחת. הסדר המציאותי הוא (1) מהמסכים שהמשתמש ההוא משתמש בהם, (2) פיתוח חדש תואם-תקן, (3) גלגול הצידה בתיקון פקדים משותפים.

במשפט אחד: תמיכת נגישות היא “חשיפת השם והפעולות הנכונים בעץ UIA, והחזקת היסודות של מקלדת וצבע”.

2. מיון המסגרת החוקית והתקנים — מה ש”הפך לחובה” השתנה

2.1. חוק ביטול האפליה נגד אנשים עם מוגבלות — מאפריל 2024, גם עסקים חייבים לספק התאמה סבירה

חוק ביטול האפליה נגד אנשים עם מוגבלות הוא חוק שאוסר “יחס מפלה בלתי-צודק” לאנשים עם מוגבלות מצד גופים מינהליים ועסקים, ודורש “מתן התאמה סבירה”. בתיקון 2021 (ריווה 3), מתן התאמה סבירה על ידי עסקים, שהיה חובת מאמץ, הפך לחובה, והחוק המתוקן נכנס לתוקף ב-1 באפריל 2024 (ריווה 6).1

לפי עלון משרד הקבינט, מתן התאמה סבירה הוא תגובה, בטווח שאינו נטל מופרז, כשאדם עם מוגבלות מביע כוונה שתגובה כלשהי נדרשת להסרת מחסום בחברה. וכי התוכן שונה לפי מאפיין מוגבלות, סצנה ומצב, מודגש “דיאלוג בונה” שבו האדם עם המוגבלות והעסק עורמים דיאלוג ושוקלים תגובה יחד. סירוב חד-צדדי לדיאלוג בונה מצוין כעלול להוות הפרה של חובת מתן התאמה סבירה.1

שתי הבחנות מעשיות חשובות כאן.

  1. “שיש הכול במקום מראש” אינו מה שהפך לחובה. אמצעי שיפור מוקדמים שמכוונים למספר לא מוגדר של אנשים עם מוגבלות — הצד הרך כמו סקירת מדריך והכשרה, הצד הקשה כמו הפיכת מתקן נגיש — נקראים “שיפור סביבתי”, וזו חובת מאמץ.1 הצבת יישום עסקי במצב שמיש עם קורא מסך מראש אפשר לחשוב עליה כמאמץ של שיפור סביבתי. ככל ששיפור הסביבה התקדם יותר, הנטל של מתן התאמה סבירה אישית קל יותר.
  2. תחום התעסוקה אינו תחת חוק ביטול האפליה אלא תחת חוק קידום תעסוקת אנשים עם מוגבלות. אותו עלון גם קובע שתעסוקה ועבודה עוקבות אחר הוראות חוק קידום התעסוקה.1 ותחת החוק ההוא, בתיקון שנכנס לתוקף באפריל 2016 (הייסיי 28), איסור אפליה בשל מוגבלות בתעסוקה ומתן התאמה סבירה בטווח שאינו נטל מופרז חויבו על מעסיקים.2 הייעוץ בפתיחה של “עובד לא יכול להשתמש ביישום העסקי” היה, למעשה, בתחום החובה הרבה לפני 2024.
המיקום של התאמה סבירה ושיפור סביבתיהיחס בין עסק כללי לאדם עם מוגבלות הוא תחת חוק ביטול האפליה, ומתן התאמה סבירה בתגובה לבקשה אישית דרך דיאלוג בונה הוא חובה מאפריל 2024; תחום התעסוקה הוא חובת מעסיק מאפריל 2016 תחת חוק קידום התעסוקה; הפיכת היישום לקל יותר לשימוש מראש היא שיפור סביבתי, חובת מאמץעסק + מוגבלותתעסוקה / עבודהאיזו סצנה?חוק האפליהחוק התעסוקהבקשה דרך דיאלוגמתן התאמהחובה מאז 2024מתן התאמהחובה מאז 2016יישום קל יותר מראששיפור סביבתיחובת מאמץ

איור 2: החוק השולט מתפצל לפי סצנה; התאמה סבירה היא חובה, ותיקונים מוקדמים הם שיפור סביבתי, חובת מאמץ.

איך מקרה אישי מטופל בחוק תלוי במצב. המאמר הזה לא נכנס לפרשנות משפטית; הוא ממשיך מנקודת המבט של מה מהנדס יכול לעשות כשמבקשים תגובה. למקורות ראשוניים, ראו חומרי משרד הקבינט ומשרד הבריאות, העבודה והרווחה.12

2.2. JIS X 8341-3 ו-WCAG — “קריטריוני הרשת” מתרחבים גם לתוכנה

בצד הקריטריונים הטכניים, הם מרוכזים ב-JIS X 8341-3:2016. התקן הזה הוא תקן מקביל של ISO/IEC 40500:2012, וגוף התקן הוא אותו תוכן כמו WCAG 2.0 של W3C.3 אם רוצים לדעת באופן מוחשי ממה מורכבת “תמיכת נגישות”, קריאת קריטריוני הצלחה של WCAG (כעת מורחבים ב-WCAG 2.1/2.2) היא הנתיב הקצר, ותרגום יפני של WAIC גם מפורסם.8

השאלה “האם WCAG הוא קריטריון לתוכן רשת?” הוגנת, אבל W3C ארגן, ב-Group Note שנקרא WCAG2ICT (Guidance on Applying WCAG 2 to Non-Web Information and Communications Technologies), איך ליישם קריטריוני הצלחה של WCAG 2.0/2.1/2.2 על מסמכים ותוכנה שאינם-רשת.4 במילים אחרות, חשיבה כמו “חלופות טקסט”, “ניגודיות”, “הפעלת מקלדת” ו”צבע אינו האמצעי היחיד” אפשר ליישם על יישום שולחן עבודה של Windows באותה מסגרת כמו הרשת. פרקים 3 ואילך של המאמר מורידים את החשיבה הזאת למימוש WinForms/WPF מוחשי.

היחס בין JIS X 8341-3 ל-WCAGJIS X 8341-3:2016 הוא תקן מקביל באותו תוכן ל-WCAG 2.0, ו-WCAG2ICT מראה איך ליישם קריטריוני הצלחה של WCAG על תוכנה שאינה-רשת, כך שאפשר לבדוק יישום שולחן עבודה של Windows באותה מסגרתתקן מקביל באותו תוכןWCAG 2.0(W3C)JIS X 8341-3:2016WCAG2ICTיישום על תוכנה שאינה-רשתיישום שולחן עבודה של Windows

איור 3: JIS X 8341-3:2016 הוא תקן מקביל של WCAG 2.0, ו-WCAG2ICT מרחיב את אותם קריטריונים ליישומי שולחן עבודה.

3. איך טכנולוגיה מסייעת קוראת יישום — שלישיית UI Automation

3.1. עץ UIA, מאפיינים ודפוסי בקרה

ל-Windows יש תשתית נגישות שנקראת UI Automation ‏(UIA) מובנית. UIA הוא מנגנון שמאפשר לטכנולוגיה מסייעת כמו קורא מסך להשיג מידע UI ולהפעיל את הממשק באמצעים שאינם קלט סטנדרטי, והוא מתווך בין צד היישום (הספק) לצד הטכנולוגיה המסייעת (הלקוח).5

את עולם UIA אפשר להבין כשלישייה הבאה.5

רכיב תפקיד דוגמאות מייצגות
עץ UIA עץ שמתחיל משולחן העבודה כשורש וממשיך חלון ← פקד. טכנולוגיה מסייעת הולכת בעץ הזה כדי לתפוס את הממשק חלון, חלונית, כפתור, תיבת עריכה
מאפיינים ערכים שמייצגים את אופי כל רכיב Name (מטרה), ControlType (סוג), AutomationId (מזהה), IsEnabled, IsKeyboardFocusable
דפוסי בקרה אוצר מילים של “פעולות שאפשר לעשות” לפי סוג Invoke (לחיצה), Value (קריאה/כתיבת ערך), SelectionItem (בחירה), Toggle (הפעלה/כיבוי), ExpandCollapse (הרחבה/כיווץ)

כשקורא מסך ממקד כפתור, ההכרזה “כפתור אישור הזמנה” היא, בגסות, השילוב של Name + סוג בקרה. כשהמשתמש מבצע פעולת “ביצוע”, הטכנולוגיה המסייעת לוחצת על הכפתור דרך דפוס Invoke. במילים אחרות, אם Name והדפוסים נחשפים נכון אפשר לקרוא ולהפעיל; אם הם לא נחשפים, זה כמו לא קיים גם אם זה נראה על המסך.

שלישיית UI Automationהיישום, כספק, חושף מאפיינים ודפוסי בקרה של כל רכיב בעץ UIA; קורא המסך, כלקוח, מכריז Name ו-ControlType ופועל דרך דפוסים כמו Invokeמכריזמפעיליישום(ספק)עץ UIAמאפיינים(Name, ControlType וכדומה)דפוסים(Invoke, Value וכדומה)קורא מסך(לקוח)

איור 4: קורא המסך משתמש במאפיינים ובדפוסים שהיישום חשף בעץ UIA להכרזה ולהפעלה.

3.2. קורא מסך הוא לקוח UIA

קוראי המסך העיקריים בשימוש ב-Windows כוללים את Narrator, המובנה ב-Windows; את NVDA,11 החינמי וקוד פתוח; ואת PC-Talker, מוצר מסחרי בשימוש נרחב ביפן. סגנון ההכרזה שונה ביניהם, אבל הנתיב העיקרי לקריאת ממשק יישום שולחן עבודה הוא UIA בכל מקרה. לכן התגובה בצד היישום אינה “תמיכה לקורא מסך מסוים” אלא מתרכזת בחשיפת המידע הנכון ל-UIA.

הנתיב המשותף של קוראי המסך העיקרייםאם היישום חושף את המידע הנכון ל-UIA, Narrator, NVDA ו-PC-Talker כולם יכולים לקרוא את הממשק באותו נתיב, ולכן התגובה בצד היישום אינה מכוונת לקורא מסך מסוים אלא מתרכזת בחשיפה ל-UIAחושף מידעיישוםUI Automation(UIA)NarratorNVDAPC-Talkerהתגובה מתרכזת בחשיפה ל-UIA

איור 5: קוראי המסך העיקריים כולם לוקחים את UIA כנתיב, ולכן תגובת היישום מתרכזת בחשיפה ל-UIA.

3.3. כ”כפתור ש-Name שלו ריק” מוכרז כ?

דוגמה אחת מוחשית. נניח שלסרגל כלים יש כפתור שמירה שמציג רק אייקון דיסקט. למשתמש רואה האייקון מעביר את המשמעות, אבל אם Name נשאר ריק, קורא מסך מכריז על הכפתור הזה רק כ”כפתור”. אם “פתח” ו”הדפס” השכנים זהים, המשתמש שומע רק “כפתור, כפתור, כפתור” ואין לו אמצעי לדעת מי זה מי. מדריך תיקון הנגישות של Microsoft גם מונה כפתור בלי Name, ותמונה שמוכרזת רק כ-“Image”, כבעיות מייצגות שעוצרות את עבודת המשתמש.7

למרבה המזל, לפקדי WinForms ו-WPF סטנדרטיים יש תמיכת UIA מההתחלה, וברבים מהמקרים Name נקבע אוטומטית מטקסט או תווית. מה שנשבר בדרך כלל הוא אחד מ-(1) אייקון בלבד, בלי חומר לשם, (2) אין שיוך לתווית, או (3) ציור מותאם שלא שם מידע על עץ UIA. שני הפרקים הבאים מסתכלים איך לתקן לפי מסגרת.

שלוש דרכים טיפוסיות שבהן הכרזה נשברתהכרזה נשברת כשאין חומר לשם כי זה אייקון בלבד, כשאין שיוך לתווית, או כשציור מותאם לא שם מידע על עץ UIA, וזה נגמר מוכרז רק ככפתוראייקון בלבד, בלי חומרName הופך לריקאין שיוך לתוויתציור מותאם לא מוציא מידעמוכרז רק ככפתור

איור 6: שבירת הכרזה בדרך כלל מתכנסת לאחד משלושה דפוסים: חומר שם לא מספיק, שיוך לא מספיק, או ציור מותאם.

4. מימוש ב-WinForms — AccessibleName וסדר Tab

4.1. פקדים ש-Text שלהם הופך ל-Name אוטומטית, ופקדים שלא

ב-WinForms, פקד שמציג טקסט, כמו Button או CheckBox, משתמש בערך מאפיין Text כ-UIA Name. לעומת זאת, ComboBox, ListBox, ListView, PictureBox, ProgressBar, TabControl, TextBox, TreeView וכדומה לא הופכים את Text ל-Name. אלה צריכים שם באמצעי אחר.6

הדרך הכי ניתנת לתחזוקה היא להניח Label תיאורי בסדר ה-Tab הקודם מיד של פקד היעד. אם מגדירים את TabIndex של פקד היעד לבוא מיד אחרי TabIndex של ה-Label, הטקסט של אותו Label משמש אוטומטית כ-UIA Name. התווית הנראית על המסך וההכרזה תואמות, ואין צורך לנהל את הניסוח פעמיים.612

אם אי אפשר להניח Label, מגדירים AccessibleName במפורש. אפשר גם להגדיר AccessibleDescription אם נדרש הסבר משלים, ו-AccessibleRole אם התפקיד שונה מהמראה.13

איך נקבע שם של פקד WinFormsל-Button וכדומה, Text הופך ל-UIA Name כמו שהוא; לפקדים כמו TextBox ש-Text שלהם לא ממוחזר, משתמשים בטקסט של Label שהונח בסדר ה-Tab הקודם מיד; אם אי אפשר להניח Label, מגדירים AccessibleName במפורשכןלאכןלאפקדסוג ש-Text שלו הופך ל-Name?Text הופך ל-Name כמו שהואLabel בסדר ה-Tab הקודם מיד?טקסט ה-Label משמש כ-Nameמגדירים AccessibleName במפורש

איור 7: ל-Name ב-WinForms, בוחרים איך לקבוע אותו בסדר Text, Label בסדר ה-Tab הקודם מיד, AccessibleName.

// An icon-only toolbar button: state the name for announcement explicitly
saveToolStripButton.AccessibleName = "Save";

// An image-only button: name + a supplementary explanation
btnSearchCustomer.AccessibleName = "Search customer";
btnSearchCustomer.AccessibleDescription = "Search the customer master by customer code or name";

// Set it directly on an input field where you cannot place a Label in the immediately preceding tab order
txtOrderNo.AccessibleName = "Order number";

// A PictureBox reused as a chart display: match the role to the reality as well
pictureBoxChart.AccessibleRole = AccessibleRole.Chart;
pictureBoxChart.AccessibleName = "Monthly order-count chart";

כזהירות, אם מגדירים AccessibleName פעם אחת בחלונית המאפיינים של Visual Studio ואז מנקים אותו, הגדרת מחרוזת ריקה יכולה להישאר בקובץ המעצב ולהפריע לפתרון השם כברירת מחדל. מוחקים את השורה המתאימה מקובץ המעצב.6

בעיית AccessibleName מחרוזת ריקה שנשארתאם מגדירים AccessibleName פעם אחת בחלונית המאפיינים ואז מנקים אותו, הגדרת מחרוזת ריקה נשארת בקובץ המעצב ומפריעה לפתרון השם כברירת מחדל, ולכן מתקנים במחיקת השורה המתאימה מקובץ המעצבהגדרת AccessibleNameניקוי בחלונית המאפייניםהגדרת מחרוזת ריקה נשארתמפריעה לפתרון השם כברירת מחדלמחיקת השורה מקובץ המעצב

איור 8: ניקוי בחלונית המאפיינים עדיין משאיר מחרוזת ריקה, ולכן מתקנים במחיקת השורה המתאימה מקובץ המעצב.

4.2. שיפורים נפוצים במסך הזנת הזמנות

המקומות שבאמת מתקנים הרבה ביישומים עסקיים מסוכמים כרשימת בדיקה.

מצב נפוץ בעיה איך מתקנים
ToolStripButton אייקון בלבד מוכרז רק כ”כפתור” מגדירים AccessibleName
יש Label ליד TextBox אבל סדר ה-Tab מפוזר שם שדה הקלט ריק, או הופך לשם לא קשור מניחים את שדה הקלט מיד אחרי TabIndex של ה-Label
PictureBox בשימוש ככפתור דרך Click התפקיד לא מועבר ככפתור, ואי אפשר ללחוץ מהמקלדת מחליפים ב-Button, או מגדירים AccessibleRole/AccessibleName פלוס תמיכת מקלדת
כותרת עמודת DataGridView ריקה או סמלים בלבד משמעות העמודה לא ברורה כשתא מוכרז מגדירים שם עמודה משמעותי ב-HeaderText
רק Panel משמש לקיבוץ תוכן, והכותרת היא תמונה אי אפשר לדעת איזו קבוצת קלט זו משתמשים ב-GroupBox, או הופכים את הכותרת ל-Label

כל אחד הוא תיקון של כמה שורות, אבל למשתמש קורא מסך זה הפיצול בין “מסך שאי אפשר להשתמש בו” ל”מסך שאפשר להשתמש בו”.

5. מימוש ב-WPF — AutomationProperties ו-AutomationPeer

5.1. AutomationProperties.Name / LabeledBy / HelpText

ב-WPF, פקד ש-Content שלו הוא מחרוזת, כמו Button, משתמש בתוכן הזה כ-UIA Name. כפתור אייקון בלבד (Image או Path) אין לו חומר ל-Name, לכן מציינים אותו עם AutomationProperties.Name, או אם יש טקסט תצוגה קרוב משייכים אותו עם AutomationProperties.LabeledBy.7

ל-TextBox יש זהירות חשובה. Text של TextBlock ממוחזר כ-Name, אבל Text של TextBox נחשף בצד מאפיין UIA Value ולא הופך ל-Name. לשדה קלט, שיוך TextBlock תווית התצוגה עם LabeledBy הוא המועמד הראשון. הכרזה ותצוגה על המסך תואמות, וגם נמנעים מניהול הניסוח פעמיים.14

<!-- An input field: associate the display label with LabeledBy -->
<TextBlock x:Name="OrderNoLabel" Text="Order number" />
<TextBox
    AutomationProperties.LabeledBy="{Binding ElementName=OrderNoLabel}"
    AutomationProperties.AutomationId="OrderNoTextBox" />

<!-- An icon-only button: state the name, and a supplement if needed -->
<Button
    AutomationProperties.Name="Confirm order"
    AutomationProperties.HelpText="Confirm the order being entered and allocate inventory">
    <Path Data="{StaticResource CheckIconGeometry}" Width="16" Height="16" />
</Button>
איך נקבע שם של פקד WPFפקד ש-Content שלו מחרוזת משתמש בתוכן כ-Name; אחרת שיוך תווית תצוגה קרובה עם LabeledBy הוא המועמד הראשון; אם גם זה חסר, מציינים AutomationProperties.Name; Text של TextBox נחשף בצד Value, לא כ-Nameכןלאכןלאפקדהאם Content מחרוזת?התוכן הופך ל-Nameתווית תצוגה קרובה?שיוך עם LabeledByהגדרת Name במפורשText של TextBoxנחשף כ-Value, לא Name

איור 9: ל-Name ב-WPF, מחליטים בסדר מחרוזת Content, LabeledBy, הגדרה מפורשת; Text של TextBox לא הופך ל-Name.

מידע משלים שלא נכנס ב-Name אפשר לחשוף עם AutomationProperties.HelpText.7 גם, AutomationId הוא מזהה לזיהוי רכיבים בבדיקות UI אוטומטיות, ולכן החלטת מוסכמת שמות בזמן עיצוב המסך משתלמת אחר כך (מכוסה לעומק ב”בדיקות UI אוטומטיות ליישומי שולחן עבודה של Windows”).

5.2. פקד מותאם צריך AutomationPeer

פקד מותאם שמציירים בעצמכם לא יכול, כמו שהוא, לחשוף מידע משמעותי בעץ UIA. ב-WPF דורסים OnCreateAutomationPeer במחלקה נגזרת מ-UIElement ומחזירים מחלקה נגזרת מ-AutomationPeer כדי לחשוף שם, סוג ודפוסים. אם יורשים פקד קיים, ירושת ה-Peer המתאים (ButtonBaseAutomationPeer ל-ButtonBase) מאפשרת לקחת התנהגות שכבר מומשה.15

איך מידע נחשף דרך AutomationPeerפקד מותאם חושף שם, סוג ודפוסים בדריסת OnCreateAutomationPeer והחזרת מחלקה נגזרת מ-AutomationPeer; אם יורשים פקד קיים, יורשים את ה-Peer המתאים ולוקחים התנהגות שכבר מומשהפקד מותאםOnCreateAutomationPeerהחזרת מחלקה נגזרת מ-Peerחשיפת שם, סוג ודפוסיםירושת פקד קייםירושת ה-Peer המתאיםלקיחת התנהגות שכבר מומשה

איור 10: פקד מותאם מחזיר Peer מ-OnCreateAutomationPeer וחושף מידע ל-UIA.

// An example of a control that custom-draws line status as a coloured lamp
public class StatusLamp : Control
{
    public static readonly DependencyProperty IsOnlineProperty =
        DependencyProperty.Register(nameof(IsOnline), typeof(bool), typeof(StatusLamp),
            new FrameworkPropertyMetadata(false,
                FrameworkPropertyMetadataOptions.AffectsRender, OnIsOnlineChanged));

    public bool IsOnline
    {
        get => (bool)GetValue(IsOnlineProperty);
        set => SetValue(IsOnlineProperty, value);
    }

    internal static string NameFor(bool isOnline)
        => isOnline ? "Line status: online" : "Line status: offline";

    private static void OnIsOnlineChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        // Raise a UIA property-changed event the moment the value changes. Without this,
        // a screen reader keeps the old name and cannot notice the change of state
        if (UIElementAutomationPeer.FromElement((UIElement)d) is AutomationPeer peer)
        {
            peer.RaisePropertyChangedEvent(
                AutomationElementIdentifiers.NameProperty,
                NameFor((bool)e.OldValue), NameFor((bool)e.NewValue));
        }
    }

    protected override AutomationPeer OnCreateAutomationPeer()
        => new StatusLampAutomationPeer(this);
}

public class StatusLampAutomationPeer : FrameworkElementAutomationPeer
{
    public StatusLampAutomationPeer(StatusLamp owner) : base(owner) { }

    protected override AutomationControlType GetAutomationControlTypeCore()
        => AutomationControlType.Text; // Text-equivalent if it is a status display with no operation

    protected override string GetNameCore()
        => StatusLamp.NameFor(((StatusLamp)Owner).IsOnline);
}

החזרת שם אינה מספיקה; לספר לו באירוע ברגע שהוא משתנה גם היא עבודת ה-Peer. לטכנולוגיה מסייעת אין תזמון משלה לשליפה מחדש של ערך, ולכן מימוש שלא מרים אירוע שינוי נמצא במצב של “נכון רק כששואלים שוב”, ומשתמש קורא מסך לא מקבל הודעה על שינוי המצב.

זרימת סיפור לקורא מסך על שינוי מצבברגע שערך הפקד משתנה, ה-AutomationPeer מרים אירוע שינוי מאפיין Name; טכנולוגיה מסייעת לא שולפת מחדש מעצמה, ולכן בלי האירוע היא נשארת על השם הישן ולא יכולה להבחין בשינויקורא מסךAutomationPeerפקדקורא מסךAutomationPeerפקדבלי האירוע נשארים על השם הישןערך IsOnline משתנההרמת אירוע שינוי מאפיין Nameהכרזת המצב החדש

איור 11: שינוי ערך מגיע לקורא מסך רק כשה-AutomationPeer מספר לו באירוע שינוי.

אם לפקד המותאם יש פעולה (אפשר ללחוץ, אפשר לשנות ערך, אפשר לבחור), דורסים GetPattern ומספקים ממשק דפוס כמו IInvokeProvider או IRangeValueProvider.15 הנקודה היא שאם בונים את ה-Peer גם בצד ספריית הפקדים המשותפת, כל מסך שמשתמש בו הופך נתמך אוטומטית. זו התשתית של “גלגול הצידה” בפרק 9.

6. אפשר להגיע לכל פונקציה מהמקלדת בלבד?

קריטריון הצלחה WCAG 2.1.1 (Keyboard) דורש שכל הפונקציונליות של התוכן תהיה ניתנת להפעלה דרך ממשק מקלדת.8 משתמש קורא מסך כעיקרון לא משתמש בעכבר, ולכן פונקציה שאי אפשר להגיע אליה מהמקלדת היא כמו פונקציה שלא קיימת. נקודות המבט לבדיקה הן כדלקמן.

נקודת מבט מה לאשר האמצעים העיקריים ב-WinForms / WPF
סדר Tab האם סדר תנועת מקש Tab תואם לסדר החזותי (שמאל-עליון ← ימין-תחתון)? סידור TabIndex, הגדרת TabStop
מקש גישה אפשר לעבור ישירות לפריט ראשי עם Alt+אות? ב-WinForms, & ב-Text; ב-WPF, _ בכותרת
קיצור יש מקש עצמאי לפעולות תכופות (שמירה, חיפוש, אישור)? הקצאת Ctrl+S וכדומה, הצגה בתפריט
סימן מיקוד אפשר לעקוב בעיניים איפה המיקוד עכשיו? לא מסירים את מלבן המיקוד; מציירים אותו בעצמכם כשמציירים מותאם
פונקציות עכבר בלבד יש פונקציה שמישה רק בלחיצה כפולה, לחיצה ימנית, גרירה או ריחוף? מציעים את אותה פונקציה גם מתפריט או ממקש
דיאלוג Enter = כפתור ברירת מחדל ו-Esc = ביטול עובדים? AcceptButton/CancelButton, IsDefault/IsCancel

ה-walkthrough של נגישות WinForms גם מונה, כיסודות, הנחת תווית בסדר ה-Tab הקודם מיד של שדה קלט, והנחת מקשי גישה על הפקדים והתפריטים שהמשתמש רוצה לעבור אליהם.12

מה שרוצים להדגיש הוא שזה אינו “עלות נוספת לתמיכת מוגבלות”. בעבודה שגרתית כמו הזנת הזמנות, האם אפשר להשלים קלט בלי להרים ידיים ממיקום הבית הוא מה שמחליט את התפוקה של המפעיל כמו שהיא. סדר Tab מבולגן או פעולה שדורשת עכבר הוא פגם שמגלח קצת מפרודוקטיביות כל משתמש כל יום. תמיכת נגישות ויעילות מקלדת הם רק שני שמות לאותה עבודה (לסדרי עדיפות לפי סביבת שימוש, ראו גם “עיצוב UX ליישומי Windows”).

האפקט הכפול של סידור המקלדתהצבת סדר Tab, מקשי גישה וסימן מיקוד מייצרת שני אפקטים בבת אחת — משתמש טכנולוגיה מסייעת יכול להגיע לפונקציה, ומהירות הקלט של כל מפעיל — ופונקציה שמישה רק בעכבר היא כמו פונקציה שלא קיימתסידור מקלדתמשתמשי טכנולוגיה מסייעתמהירות כל מפעילפונקציית עכבר בלבדכמו לא קיימת

איור 12: סידור הפעלת מקלדת מממש תמיכת טכנולוגיה מסייעת ויעילות לכל משתמש באותו זמן; פונקציית עכבר בלבד היא כמו לא קיימת.

7. צבע וניגודיות — 4.5:1 ו”צבע אינו האמצעי היחיד”

7.1. המדריך ליחס ניגודיות הוא 4.5:1

קריטריון הצלחה WCAG 1.4.3 (Contrast (Minimum)) דורש יחס ניגודיות של לפחות 4.5:1 לטקסט ולתמונות של טקסט, ולפחות 3:1 לטקסט גדול.8 עיצוב מודרני שמניח טקסט אפור בהיר על רקע לבן אינו נדיר בנפילה מתחת לקריטריון הזה. משתמשי יישום עסקי כוללים אנשים שראייתם וראיית הצבע שלהם השתנו עם הגיל, ואנשים שמשתמשים בו בסביבה חשוכה כמו מפעל. מתרגלים מדידה עם בודק ניגודיות בסקירת עיצוב.

7.2. לא מעבירים מידע בצבע בלבד

קריטריון הצלחה 1.4.1 (Use of Color) הוא שצבע לא חייב להיות האמצעי החזותי היחיד להעברת מידע.8 דוגמאות טיפוסיות ביישום עסקי הן כדלקמן.

  • הצגת שורת שגיאה בטקסט אדום בלבד ← מספקים גם אייקון שגיאה ועמודת הודעה
  • הצגת שדה חובה בצבע התווית בלבד ← מוסיפים “*” או את הניסוח “חובה”
  • הצגת מצב בצבע המנורה בלבד ← הופכים לצבע + צורה, או ניסוח (“רץ”, “עצור”)

בהינתן הגיוון של ראיית צבע, גם זה אינו “תגובה מיוחדת” אלא יסוד של עיצוב תצוגה.

החלפת מידע שמועבר בצבע בלבדתצוגה שמראה שגיאה בטקסט אדום בלבד מוחלפת באייקון שגיאה פלוס עמודת הודעה; תצוגה שמראה שדה חובה בצבע התווית בלבד מוחלפת בהוספת הניסוח חובה; תצוגה שמראה מצב בצבע המנורה בלבד מוחלפת בשילוב צורה או ניסוחשגיאה בטקסט אדום בלבדמספקים גם אייקון וניסוחחובה בצבע התווית בלבדמוסיפים את הניסוח חובהמצב בצבע המנורה בלבדמשלבים צבע עם צורה או ניסוח

איור 13: דוגמאות טיפוסיות להעברה בצבע בלבד מוחלפות בשילוב אייקון, ניסוח וצורה או טקסט.

7.3. מעקב אחרי ערכת נושא ניגודיות (ניגודיות גבוהה)

ל-Windows יש ערכות נושא ניגודיות (לשעבר ניגודיות גבוהה) שמחליפות לסכמת צבעים עם הפרדה חזקה של קדמה ורקע; המשתמש יכול לבחור ולערוך ערכות נושא מובנות שתוכננו כך שיחס הניגודיות הוא בדרך כלל 7:1 או יותר.9 העיקרון בצד היישום פשוט: לא לקודד צבעים בקשיחות; לכבד צבעי מערכת.

  • WinForms: אם משאירים ForeColor/BackColor בברירת המחדל, משמשות הגדרות הצבע של המשתמש. במקום שהחלתם צבע משלכם, שופטים עם SystemInformation.HighContrast, מחליפים לסכמה מבוססת-SystemColors, ועוקבים אחרי שינוי הגדרות עם אירוע UserPreferenceChanged.12
  • WPF/WinUI: אם מפנים למשאבי מחלקת SystemColors, עוקבים אחרי החלפת ערכת נושא. מקומות שמילאתם במברשת משלכם הופכים לסיבת השבירה.9
מעקב אחרי ערכת נושא ניגודיותמקומות שצבע מקודד בהם בקשיחות נשברים בהחלפה לערכת נושא ניגודיות, לכן מחליפים לסכמה מבוססת-SystemColors ועוקבים עם אירוע שינוי הגדרות; אם מפנים לצבעי מערכת אפשר לעקוב אחרי צבעי המשתמש אוטומטיתמקודד בקשיחותהפניה לצבע מערכתהחלפה לערכת נושא ניגודיותאיך הצבע צוין?סכמת הצבעים נשברתעוקב אוטומטית אחרי צבעי המשתמשהחלפה ל-SystemColorsמעקב עם אירוע שינוי הגדרות

איור 14: רק מקומות שצבע מקודד בהם בקשיחות נשברים תחת ערכת נושא ניגודיות; הפניה לצבע מערכת עוקבת אוטומטית.

גם, משתמש עם ראייה ירודה לעיתים קרובות משתמש בהגדלת מערכת הפעלה גבוהה (קנה מידה DPI), ולכן תמיכת DPI גבוהה היא גם חלק מתמיכת נגישות. יישום שהפריסה שלו נשברת ב-125%–200% אינו שמיש בנקודה הזאת. ראו “תמיכת DPI גבוהה ב-WinForms” ו”תמיכת DPI גבוהה ב-WPF” לפרטים.

8. אימות בפועל — Accessibility Insights ובדיקה מעשית עם קורא מסך

8.1. Accessibility Insights for Windows

Microsoft מספקת את Accessibility Insights for Windows ככלי אימות נגישות ליישומי Windows, עם שלושה שימושים עיקריים.10

  • Live Inspect: פשוט מרחפים עם העכבר מעל רכיב או ממקדים אותו במקלדת, ואפשר לאשר את מאפייני UIA שלו (Name, ControlType, דפוסים וכדומה). האמצעי הקצר ביותר לראות “מה ה-Name של הכפתור הזה”.
  • FastPass: בדיקה קלה שמזהה בעיות נגישות בעלות השפעה גבוהה בפחות מחמש דקות. בעיות שאפשר לשפוט מכנית, כמו Name חסר, אפשר למנות לכל מסך חדש.
  • Troubleshooting: מסייע באבחון ובתיקון של בעיה מסוימת. מבעיה שזוהתה אפשר ללכת ישירות למדריכי התיקון לפי מסגרת שהמאמר גם מצטט.

Inspect.exe ו-AccEvent, הכלולים ב-Windows SDK, יכולים גם לאשר את עץ UIA ואת המאפיינים, אבל הם ממוקמים ככלים ישנים, ומעבר ל-Accessibility Insights מומלץ כעת.10

שלושה שימושים של Accessibility InsightsAccessibility Insights for Windows מספק אישור מאפייני UIA עם Live Inspect, בדיקה קלה של בעיות בעלות השפעה גבוהה עם FastPass, וסיוע באבחון ובתיקון בעיה עם Troubleshooting; מעבר מכלים ישנים כמו Inspect.exe מומלץמעבר מומלץAccessibility InsightsLive InspectFastPassTroubleshootingאישור מאפייני UIAזיהוי בעיות בעלות השפעה גבוההסיוע באבחון ובתיקוןInspect.exe וכדומה

איור 15: ל-Accessibility Insights יש את שלושת השימושים אישור, זיהוי ואבחון, והוא יעד המעבר מכלים ישנים.

8.2. בדיקה מעשית עם קורא מסך

מה שבדיקה אוטומטית של כלי יכולה לזהות הוא רק בעיות שאפשר לשפוט מכנית. בסוף, תמיד הולכים בפעולה עסקית אמיתית עם קורא מסך. אפשר להפעיל את Narrator המובנה ב-Windows מיד עם Ctrl+מקש Windows+Enter, ואת NVDA אפשר להכניס בחינם.11 התחבולה של הבדיקה היא לנסות, בלי להסתכל על המסך (או עם התצוגה כבויה), תוך הסתמכות רק על ההכרזה, האם אפשר להשלים משימה אמיתית כמו “להזין הזמנה אחת ולאשר אותה”. בעיות כמו שם שקיים אבל סדר ההכרזה לא קוהרנטי, או מיקוד שבורח מחוץ למודל, נמצאות רק בידיים.

שילוב אימות כלי ובדיקה מעשיתמה שבדיקה אוטומטית כמו FastPass יכולה לזהות הוא רק בעיות שאפשר לשפוט מכנית; השאר נמצא בידיים בהליכה בפעולה עסקית אמיתית עם קורא מסך ובמציאת בעיות סדר הכרזה ומיקודבדיקה אוטומטית של כליבעיות שאפשר לשפוט מכניתבעיות שהיא לא מזהה נשארותבדיקה מעשית עם קורא מסךהליכה בפעולה עסקיתבעיות סדר הכרזה ומיקוד

איור 16: מונים בעיות מכניות בבדיקה אוטומטית, ומוצאים את השאר בבדיקה מעשית עם קורא מסך.

8.3. בנייתו לזרימת הפיתוח, וההשתלמות ההדדית עם בדיקות UI אוטומטיות

כדי שהאימות לא יהפוך לתלוי-אדם, ממליצים לבנות את רשימת הבדיקה הבאה לפריטי סקירה של מסך חדש.

# פריט בדיקה אמצעי
1 FastPass בלי שגיאות Accessibility Insights
2 לכל שדה קלט וכפתור יש Name Live Inspect
3 אפשר להגיע לכל פונקציה במקש Tab בלבד ידני
4 Enter/Esc והקיצורים העיקריים עובדים ידני
5 יחס ניגודיות טקסט 4.5:1 או יותר בודק ניגודיות
6 לא נשבר תחת ערכת נושא ניגודיות מחליפים ערכת נושא ובודקים חזותית
7 לא נשבר ב-200% קנה מידה משנים הגדרת תצוגה ובודקים חזותית
8 אפשר להשלים משימה מייצגת עם קורא מסך Narrator/NVDA

ועוד אחד. בדיקות UI אוטומטיות עם FlaUI וכדומה בנויות על אותו UIA שקוראי מסך משתמשים בו. ה-Name והדפוסים ששמים לנגישות הופכים לחלקי קוד בדיקה, ו-AutomationId שתוכנן לבדיקות מקל על ניפוי באגים ב-Live Inspect. לעומת זאת, ממשק שלא מופיע בעץ UIA בלתי-נראה גם לבדיקות וגם לטכנולוגיה מסייעת. נגישות וניתנות לבדיקה הן שני צדדים של אותה השקעה (“בדיקות UI אוטומטיות ליישומי שולחן עבודה של Windows”).

ההשתלמות ההדדית של נגישות ובדיקות UI אוטומטיותקורא מסך ובדיקות UI אוטומטיות כמו FlaUI בנויים על אותו UIA, ולכן אפשר להשתמש ב-Name ובדפוסים ששמים משניהם, וממשק שלא מופיע בעץ UIA בלתי-נראה מכל אחדסידור עץ UIAקורא מסך יכול לקרוא אותואפשר להשתמש בבדיקות UI אוטומטיותשני צדדים של אותה השקעהממשק שלא מופיע ב-UIAבלתי-נראה מכל אחד

איור 17: כי הם יושבים על אותה תשתית UIA, סידור עץ UIA משתלם גם לטכנולוגיה מסייעת וגם לבדיקות UI אוטומטיות.

9. איך לקבוע סדרי עדיפות — לא לתקן כל מסך בבת אחת

תיקון מערכת ליבה של מאות מסכים בבת אחת אינו מציאותי לא בעלות ולא באיכות. הגישה שאנחנו ממליצים עליה היא שלוש השכבות הבאות.

  1. מתקנים מהמסכים שהמשתמש ההוא משתמש בהם בעבודה. התאמה סבירה היא תהליך של תגובה אישית לבקשה מהאדם הנוגע בדבר.1 קודם נותנים לאדם להפעיל את העבודה בפועל עם קורא מסך, ומזהים יחד איפה הוא נתקע. ברבים מהמקרים המסכים שבשימוש יומיומי מצטמצמים לכמה עד תריסר, והבעיות הקטלניות ביניהן (כפתור בלי שם, כפתור אישור שאי אפשר ללחוץ מהמקלדת) אפשר לפתור בתיקון של ימים.
  2. הופכים פיתוח חדש לתואם-תקן. מוסיפים את רשימת הבדיקה של פרק 8 להגדרת הסיום, ובונים מסכים חדשים נתמכים מההתחלה. בניגוד לתיקון בדיעבד, תוספת העלות של בנייתו בזמן עיצוב קלה.
  3. מגלגלים הצידה בתיקון פקדים משותפים. אם מממשים AccessibleName כברירת מחדל או AutomationPeer על חלקים פנימיים משותפים כמו דיאלוג חיפוש, רשת או קלט תאריך, זה נכנס לתוקף באצווה בכל מסך שמשתמש בהם. זה מהלך הרבה יותר חסכוני מלגעת במסכים בודדים אחד אחד.
שלוש שכבות עדיפות התיקוןמתקנים מהמסכים שהמשתמש משתמש בהם בעבודה, הופכים פיתוח חדש לתואם-תקן עם רשימת בדיקה, ומגלגלים לכל מסך בתיקון פקדים משותפים1. תיקון מהמסכים שהמשתמש משתמש בהם2. עבודה חדשה תואמת-תקן3. גלגול הצידה עם פקדים משותפיםנכנס לתוקף באצווה בכל מסך שמשתמש בהם

איור 18: מתקדמים לא בתיקון כל מסך בבת אחת אלא בשלוש השכבות מסכים בשימוש, עבודה חדשה וחלקים משותפים.

ורישום הדיאלוג חשוב כמו התגובה הטכנית. התאמה סבירה היא תהליך של “דיאלוג והתאמה אישית”, לא של מילוי מלא של כל בקשה. שקילת אמצעי חלופי עם האדם (לעשות את העבודה הזאת במסך אחר, להכין ייצוא CSV, לכסות בתפעול) והסכמה, לתיקון שהנטל שלו כבד מדי, גם היא תוצאה לגיטימית של דיאלוג בונה.1 רישום מה התבקש, למה הגיבו, ומה הפך לאמצעי חלופי הופך להוכחת תום הלב של הארגון.

זרימת דיאלוג בונה ורישוםמגיבים לבקשה מאדם עם מוגבלות דרך דיאלוג בונה; מבצעים תיקון שאפשר להגיב לו; לתיקון שהנטל שלו כבד מדי, שוקלים אמצעי חלופי עם האדם ומסכימים; רושמים מה התבקש, למה הגיבו ומה הפך לאמצעי חלופילאכןבקשהדיאלוג בונההאם הנטל כבד מדי?מגיבים בתיקוןשוקלים אמצעי חלופי ומסכימיםרושמים את ההיסטוריה

איור 19: בדיאלוג בונה מסכימים עם האדם על תיקון או אמצעי חלופי, ומשאירים את ההיסטוריה הזאת ברישום.

10. סיכום

  • עם תיקון חוק ביטול האפליה שנכנס לתוקף באפריל 2024, מתן התאמה סבירה הפך לחובה גם לעסקים. תחום התעסוקה הוא חובת מעסיק מאז 2016 תחת חוק קידום תעסוקת אנשים עם מוגבלות. הפיכת היישום לקל יותר לשימוש מראש היא “שיפור סביבתי” (חובת מאמץ), וככל שהתקדם יותר התגובות האישיות נעשות קלות יותר.
  • הקריטריונים הטכניים מרוכזים ב-WCAG ‏(JIS X 8341-3:2016), ואותה חשיבה אפשר ליישם על יישום שולחן עבודה דרך WCAG2ICT.
  • קורא מסך קורא יישום דרך UI Automation. שלישיית עץ UIA, מאפיינים (Name/ControlType/AutomationId) ודפוסי בקרה היא התשתית.
  • העדיפות הגבוהה ביותר היא Name. WinForms משתמש ב-AccessibleName ובשיוך Label לסדר Tab; WPF משתמש ב-AutomationProperties.Name/LabeledBy; פקד מותאם משתמש ב-AutomationPeer.
  • היכולת להגיע לכל פונקציה מהמקלדת בלבד היא קריטריון הצלחה של WCAG ובאותו זמן הפרודוקטיביות של כל מפעיל. מסדרים סדר Tab, מקשי גישה וסימן מיקוד.
  • שלושת היסודות של צבע הם יחס ניגודיות 4.5:1, צבע אינו האמצעי היחיד, וכיבוד צבעי מערכת בערכת נושא ניגודיות.
  • משלבים אימות עם FastPass+Live Inspect ב-Accessibility Insights ועם בדיקה מעשית עם Narrator/NVDA, ובונים אותו לזרימת הפיתוח כרשימת בדיקה למסך חדש.
  • לא מתקנים כל מסך בבת אחת; מתקדמים בסדר המסכים שהמשתמש משתמש בהם ← תמיכה תקנית לעבודה חדשה ← גלגול הצידה של פקדים משותפים. התאמה סבירה היא תהליך של דיאלוג, ורישום ההיסטוריה מגן על הארגון.

כצעד ראשון ממליצים לבחור אחד מהמסכים העיקריים שלכם, להריץ FastPass ב-Accessibility Insights for Windows, ואז ללכת בעבודה במקש Tab בלבד. בשלושים דקות, המיקום הנוכחי של היישום שלכם הופך מוחשי באופן מפתיע.

מאמרים קשורים

תחומי ייעוץ קשורים

KomuraSoft LLC מטפלת בתיקוני נגישות של יישומים עסקיים WinForms/WPF (תמיכת קורא מסך, סידור הפעלת מקלדת, תמיכת ערכת נושא ניגודיות), במימוש AutomationPeer על פקדים משותפים, ובייעוצים על אבחון מצב נוכחי וקביעת סדרי עדיפות עם Accessibility Insights. בסדר להתחיל משלב של “אנחנו רוצים לאשר אם עובד יכול להשתמש ביישום שלנו עם קורא מסך”.

קישורים

  1. Cabinet Office, Leaflet “From 1 April 2024, the provision of reasonable accommodation became an obligation”. על כניסת תיקון ריווה 3 לחוק ביטול האפליה לתוקף ב-1 באפריל ריווה 6 והפיכת מתן התאמה סבירה על ידי עסקים לחובה; על כך שמתן התאמה סבירה הוא תגובה, בטווח שאינו נטל מופרז, לביטוי כוונה מאדם עם מוגבלות; על חשיבות דיאלוג בונה ועל כך שסירוב חד-צדדי עלול להוות הפרת החובה; על כך ש”שיפור סביבתי”, אמצעי שיפור מוקדמים שמכוונים למספר לא מוגדר של אנשים עם מוגבלות, הוא חובת מאמץ; ועל כך שתעסוקה ועבודה עוקבות אחר הוראות חוק קידום התעסוקה.  2 3 4 5 6 7 8 9 10

  2. Ministry of Health, Labour and Welfare, The prohibition of discrimination against persons with disabilities in employment and the obligation to provide reasonable accommodation. על כך שחוק קידום התעסוקה המתוקן שנכנס לתוקף באפריל הייסיי 28 חייב מעסיקים לאסור אפליה בשל מוגבלות בתעסוקה ולספק התאמה סבירה בטווח שאינו נטל מופרז; ועל חומרים קשורים כמו הנחיות התאמה סבירה.  2 3 4

  3. Web Accessibility Infrastructure Committee (WAIC), Understanding JIS X 8341-3:2016. על כך ש-JIS X 8341-3:2016 הוא תקן מקביל של ISO/IEC 40500:2012, וגוף התקן הוא אותו תוכן כמו WCAG 2.0; ועל היקף תוכן הרשת שהתקן מניח.  2

  4. W3C, Guidance on Applying WCAG 2 to Non-Web Information and Communications Technologies (WCAG2ICT). על ה-W3C Group Note שמראה איך ליישם את העקרונות, ההנחיות וקריטריוני ההצלחה של WCAG 2.0/2.1/2.2 על מסמכים ותוכנה שאינם-רשת.  2

  5. Microsoft Learn, UI Automation Specification. על כך ש-UI Automation מספק מידע UI לטכנולוגיה מסייעת כמו קורא מסך ומאפשר הפעלה באמצעים שאינם קלט סטנדרטי; ועל הרכב רכיבי UIA, העץ, מאפיינים, דפוסי בקרה, סוגי בקרה ואירועים.  2 3

  6. Microsoft Learn, WinForms: Setting the accessible name on a control. על כך ש-Text ממוחזר כ-UIA Name בחלק מהפקדים, בעוד ComboBox, ListBox, ListView, PictureBox, ProgressBar, TabControl, TextBox, TreeView וכדומה לא ממחזרים אותו; על הנחת פקד היעד מיד אחרי TabIndex של Label כך שטקסט ה-Label משמש כ-Name; ועל הגדרת AccessibleName במפורש ובעיית מחרוזת ריקה שנשארת בקובץ המעצב.  2 3 4

  7. Microsoft Learn, WPF: Setting the accessible name on a button. על כך ש-Content של Button ממוחזר כ-UIA Name כברירת מחדל; על כך שקורא מסך לא יכול להכריז את מטרת כפתור בלי שם; ועל שיוך TextBlock עם AutomationProperties.LabeledBy והגדרת AutomationProperties.Name במפורש.  2 3 4

  8. W3C / Web Accessibility Infrastructure Committee (WAIC) translation, Web Content Accessibility Guidelines (WCAG) 2.1 Japanese translation. על קריטריון הצלחה 1.4.3 (Contrast (Minimum)) של 4.5:1 לטקסט ו-3:1 לטקסט גדול; על קריטריון הצלחה 1.4.1 (Use of Color) של לא להפוך צבע לאמצעי החזותי היחיד; ועל קריטריון הצלחה 2.1.1 (Keyboard) של הפעלת מקלדת של כל הפונקציונליות.  2 3 4 5 6

  9. Microsoft Learn, Contrast themes. על כך שערכות נושא ניגודיות משתמשות בלוח מוגבל של יחס ניגודיות בדרך כלל 7:1 או יותר; על בחירת ערכת נושא מובנית ועריכת צבעים; ועל כך שמשאבי מחלקת SystemColor מוגדרים כזוגות קדמה/רקע ועוקבים אחרי החלפת ערכת נושא אוטומטית.  2 3

  10. Microsoft Learn, Accessibility testing. על שלושת התרחישים של Accessibility Insights for Windows — Live Inspect (אישור מאפייני UIA בריחוף/מיקוד), FastPass (זיהוי בעיות בעלות השפעה גבוהה בפחות מחמש דקות), ו-Troubleshooting — ועל ההמלצה לעבור מכלים ישנים כמו Inspect ו-AccEvent.  2 3

  11. NVDA Japanese Team, NVDA Japanese edition. על קורא המסך החינמי וקוד פתוח של Windows NVDA ועל אספקת המהדורה היפנית שלו.  2

  12. Microsoft Learn, Walkthrough: Creating an Accessible Windows-based Application. על הנחת Label תיאורי בסדר ה-Tab הקודם מיד של שדה קלט; על מקש גישה דרך & ב-Text; על שיפוט ניגודיות גבוהה עם SystemInformation.HighContrast ושימוש ב-SystemColors; על מעקב אחרי אירוע UserPreferenceChanged; ועל שילוב רמז חזותי עם מידע שמועבר בצבע.  2 3

  13. Microsoft Learn, Providing Accessibility Information for Controls. על מאפייני AccessibleName, AccessibleDescription, AccessibleRole ו-AccessibleDefaultActionDescription של פקד WinForms ואיך להגדיר אותם. 

  14. Microsoft Learn, WPF: Setting the accessible name on an edit field. על כך ש-Text של TextBlock ממוחזר כ-UIA Name, בעוד Text של TextBox נחשף כ-UIA Value; ועל שיוך TextBlock תווית ל-TextBox דרך AutomationProperties.LabeledBy, או הגדרת AutomationProperties.Name. 

  15. Microsoft Learn, UI Automation of a WPF Custom Control. על כך שפקד מותאם דורס OnCreateAutomationPeer ומחזיר מחלקה נגזרת מ-AutomationPeer; על ירושת מחלקת ה-Peer שמתאימה לפקד הבסיס; על אספקת ספק דפוס דרך GetPattern; ועל דריסה מצד XAML עם מאפייני AutomationProperties.  2

מאמרים עדכניים עם אותן תגיות, להעמקה בנושאים קרובים.

העמודים האלה ממקמים את הנושא בהקשר רחב יותר של שירותים והחלטות.

המאמר קשור ישירות לשירותים הבאים.

שאלות נפוצות

שאלות נפוצות בפניות בנושא המאמר.

האם תמיכת נגישות ליישום עסקי נדרשת בחוק?
תיקון 2021 לחוק ביטול האפליה נגד אנשים עם מוגבלות נכנס לתוקף ב-1 באפריל 2024, ומתן התאמה סבירה לאנשים עם מוגבלות הפך לחובה גם לעסקים. התאמה סבירה היא תגובה שמסירה, כשאדם עם מוגבלות מבקש, מחסום אישי בטווח שאינו נטל מופרז; הפיכת היישום לקל יותר לשימוש מראש ממוקמת כחובת מאמץ שנקראת "שיפור סביבתי". תעסוקה, כמו היחס בין עובד לחברה, אינה תחת החוק ההוא אלא תחת חוק קידום תעסוקת אנשים עם מוגבלות, שחייב מעסיקים לספק התאמה סבירה מאז התיקון שנכנס לתוקף באפריל 2016. במילים אחרות, מצב של "עובד לא יכול להשתמש ביישום העסקי" נמצא בתחום החובה כבר זמן מה. עד כמה ללכת בכל מקרה תלוי במצב האישי, לכן מאשרים מקורות ראשוניים ממשרד הקבינט ו ממשרד הבריאות, העבודה והרווחה ומחליטים דרך דיאלוג עם האדם הנוגע בדבר.
איך קורא מסך קורא יישום שולחן עבודה של Windows?
קוראי מסך כמו Narrator ו-NVDA קוראים את ממשק היישום דרך תשתית נגישות שנקראת UI Automation ‏(UIA). צד היישום חושף רכיבי מסך במבנה שנקרא עץ UIA; לכל רכיב יש מאפיינים כמו Name (מטרה) ו-ControlType (סוג), ודפוסי בקרה כמו Invoke (לחיצה) ו-Value (ערך). קורא המסך מכריז על המידע הזה כ"כפתור אישור הזמנה" ופועל דרך הדפוסים. פקדי WinForms ו-WPF סטנדרטיים יש להם את המנגנון הזה מההתחלה, ולכן העבודה העיקרית של המפתח היא לא להשאיר Name ריק, להפוך את הממשק להפעלה ממקלדת, ולממש מידע על פקדים מותאמים.
ביישום WinForms קיים, מאיפה מתחילים?
הנתיב הקצר ביותר הוא להריץ FastPass ב-Accessibility Insights for Windows מול המסך היעד ולמנות פקדים ש-Name שלהם ריק ובעיות סדר Tab. התיקונים מתחילים בהגדרת AccessibleName על כפתורי-אייקון-בלבד, בשיוך Label בסדר ה-Tab הקודם מיד של שדה קלט, ובסידור TabIndex כך שיתאים לסדר החזותי. אחר כך מפעילים Narrator או NVDA והולכים בפעולה עסקית אמיתית בלי להסתכל על המסך, ומאשרים איפה נתקעים. אין צורך לתקן כל מסך בבת אחת; התחלה ממסכים שמישהו באמת משתמש בהם, והפיכת מסכים חדשים לתואמי-תקן עם רשימת בדיקה, היא מציאותית.
מה לעשות לתמיכת ניגודיות גבוהה (ערכת נושא ניגודיות)?
הבסיס הוא לא לקודד צבעים בקשיחות ולכבד צבעי מערכת. ב-WinForms, משאירים ForeColor/BackColor בברירת המחדל או משתמשים ב-SystemColors, שופטים את המצב עם SystemInformation.HighContrast, ועוקבים אחרי החלפה עם אירוע UserPreferenceChanged. גם ב-WPF וב-WinUI, אם מפנים למשאבי מחלקת SystemColors, עוקבים אחרי החלפת ערכת נושא אוטומטית. באותו זמן, מפסיקים להעביר מידע "בצבע בלבד" — הצגת שגיאה באדום בלבד — ומשלבים עם אייקון או ניסוח. גם בערכת הנושא הרגילה, לקיחת קריטריון WCAG של יחס ניגודיות טקסט 4.5:1 או יותר כמדריך גם הופכת את הממשק לקריא יותר לרצפת מפעל חשוכה ולמשתמשים מבוגרים.
האם תמיכת נגישות עוזרת גם לבדיקות UI אוטומטיות?
כן. כלי בדיקות UI אוטומטיות כמו FlaUI בנויים על אותו UI Automation שקוראי מסך משתמשים בו. ה-Name, ControlType ודפוסי הבקרה ששמים לנגישות יכולים לשמש כמו שהם מקוד בדיקה, ו-AutomationId שתוכנן לבדיקות מייצב זיהוי רכיבים. לעומת זאת, ממשק מצויר-מותאם שלא מופיע בעץ UIA בלתי-נראה גם לקורא מסך וגם לבדיקות. נגישות ובדיקות אוטומטיות הן השקעה באותה תשתית, ולכן הצבת כל אחת מהן גם מורידה את עלות השנייה.

פרופיל הכותב

עמוד היכרות עם כותב המאמר.

Go Komura

מנהל KomuraSoft LLC

מתמחה בפיתוח תוכנה עבור Windows, ייעוץ טכני וחקירת תקלות, בעיקר בפרויקטים עם מערכות קיימות ובאגים שקשה לשחזר.

קישורים ציבוריים

חזרה לבלוג