Question from .Net Tapuz forum: Winforms WebBrowser invoking Javascript and Javascript invoking Winforms
שאלה:
יש לנו טופס Winforms שפותח דף Web (שהוא HTML קלאסי) שאנחנו פיתחנו.
היינו רוצים שה-Javascript בדף HTML יוכל להעביר מסרים לטופס Winforms ושזה יגיב.
אנחנו גם צריכים שה-Winforms יעביר ל-Javascript נתונים נוספים.
יש כלי מובנה ב-Framework לזה?
תשובה:
נחדד את נושא השאלה: תקשורת Winforms בין Javascript.
לתקשורת הזו יש שני כיוונים: Javascript שמדבר עם Winforms והכיוון השני הוא Winforms שמדבר עם Javascript.
נשתמש בפקד ה-WebBrowser שבה כברירת מחדל עם דוט נט 2.0.
ניצור טופס חדש ונגרור WebBrowser לטופס.
בנוסף, ניצור קובץ HTML בסיסי.
נשנה את ה-URL של ה-WebBrowser שלנו שיצביע לקובץ HTML שלנו.
נריץ את האפליקציה המפוארת שבנינו וקיבלנו:
מדהים.
עכשיו נהפוך את הדוגמה הזו מ"גן ילדים" לאפליקציה של העולם האמיתי.
נרצה שבדף HTML שלנו יהיה רשימה של כוננים קשיחים (Hard Drives) אפשריים במחשב, בלחיצה על כונן מסויים, הדף HTML יתמלא ברשימת הקבצים והתיקיות בספרייה הראשית של הכונן.
בואו גם נחשוב ביחד על למה לא מספיק כאן ג'אווה סקריפט.
ג'אווה סקריפט רץ דרך Sand-Box של הדפדפן ולמרות שיש לו יכולות אי-אלו ויכולות גרפיות מרשימות, הדפדפן מוגבל מבחינת אבטחה.
למרות שאפשר לעשות הרבה עם ג'אווה סקריפט, כיווני הברירת מחדל של הדפדפנים מונעים דברים כמו הרצת תוכניות על מחשב הלקוח, סריקת הקבצים על מחשב הלקוח, גישה ישירה למדפסת וכך הלאה.
אז נאלץ לחזור לאפליקציית Winforms שאם תרוץ עם ההרשאות המתאימות תוכל כן לבצע דברים אלו.
הנה דף ה-HTML שלנו:
סה"כ span עם קצת עיצוב שיראה כמו קישור. וככה זה נראה.
עכשיו מגיע החלק המעניין, נרצה שבלחיצה על כונן מסויים ה-Winforms יקבל "הודעה" שנלחץ הכונן המסויים וירשום בטופס את רשימת הקבצים.
מסתבר שעל ה-WebBrowser יש מאפיין (גם באנגלית: Property) מעניין בשם WebBrowser.ObjectForScripting.
המאפיין המוזר הזה מאפשר לנו לגשת מתוך הדפדפן לממשק חלונאי.
נגדיר מתודה (גם באנגלית: Method) בשם myMethod על האלמנט החלונאי שמכוון ל-ObjectForScripting, ודרך גישה ל-window.external.myMethod בג'אווה סקריפט נוכל לקרוא למתודה הזו.
נתחיל בלקבוע את האלמנט החלונאי שלנו כטופס עצמו שעליו ישבו המתודות.
בנוסף, אותו אלמנט חלונאי חייב להיות מסומן עם ComVisiableAttribute.
נגדיר על הטופס (שהוא ה-ObjectForScripting שלנו) מתודה בשם ListFilesOnHardDrive שמקבלת את אות הכונן ורושמת את הקבצים בתקייה הראשית של הכונן.
אין במתודה הזו שום דבר מעניין מדי, אנחנו מקבלים את אות הכונן הרלוונטי, מקבלים את ה-DriveInfo שלה, עוברים על הקבצים בספריית שורש של הכונן ונדפיס כל שם קובץ לתיבת טקסט חלונאית.
אם למשל היינו רוצים לקרוא למתודה הזו מתוך קוד דוט-נטי היינו עושים את זה ככה:
וזה היה נראה ככה.
עכשיו בא החלק המעניין. נקרא למתודה הזו מג'אווה סקריפט.
השתמשנו ב-window.external וקראנו למתודה דוט-נטית לחלוטין!
עכשיו נרצה במקום להדפיס לתיבת טקסט דוט-נטית את רשימת הקבצים, נרצה להדפיס אותה בדף ה-HTML שלנו.
נוסיף מתודת ג'אווה סקריפט שמקבלת שם קובץ ומדפיסה אותו לתוך תגית <div> עם רשימת הקבצים.
אם היינו רוצים לקרוא למתודת ג'אווה סקריפט הזו מתוך ה-HTML היינו עושים משהו כזה:
אז עכשיו נשאלת השאלה איך נקרא למתודת ג'אווה סקריפט הזו מתוך הטופס החלונאי שלנו?
נשתמש ב-WebBrowser.Document.InvokeScript שמקבל את שם הפונקציה בג'אווה-סקריפט שנרצה להריץ ומערך ערכים שנשלח לפונקציה. נשכתב את ListFilesOnHardDrive.
נריץ את האפליקציה ונבחר את כונן C.
אז מה יש לנו כאן?
קוד ג'אווה סקריפט שקורא למתודה בדוט-נט,
וקוד בדוט-נט שקורא לקוד ג'אווה סקריפט.
הקוד שעבדנו עליו זמין להורדה כאן - http://www.JustinAngel.Net/files/Blog-JavaScriptWinformsInterop.zip.