שלאה בקוד C#: איך לעשות חיפוש בתוך מסמך html שהוא פתוח בwebbrowser
-
שלאה בקוד C#: איך לעשות חיפוש בתוך מסמך html שהוא פתוח בwebbrowser
אז יש לי את הקוד הזה:
public void searchNext(string searchText) { if (!string.IsNullOrEmpty(searchText)) { // Ensure the webBrowser1 control is not null and has a valid document loaded. if (webBrowser1.Document != null) { IHTMLDocument2 doc = webBrowser1.Document.DomDocument as IHTMLDocument2; if (doc != null) { IHTMLSelectionObject sel = (IHTMLSelectionObject)doc.selection; IHTMLTxtRange rng = (IHTMLTxtRange)sel.createRange(); rng.collapse(false); // collapse the current selection so we start from the end of the previous range if (rng.findText(searchText, 1000000000, 0)) { rng.select(); } else { if (webBrowser1.Document != null) { IHTMLDocument2 myDoc = webBrowser1.Document.DomDocument as IHTMLDocument2; if (doc != null) { IHTMLBodyElement body = myDoc.body as IHTMLBodyElement; if (body != null) { IHTMLTxtRange docRange = body.createTextRange(); docRange.collapse(true); if (docRange.findText(searchText, 1000000000, 0)) { docRange.select(); } } } } } } } else { // Handle the case when the webBrowser1.Document.DomDocument cannot be cast to IHTMLDocument2. MessageBox.Show("Could not access the document."); } } }
השאלה היא - איך אני עושה שיחפש רק בכותרות ולא בגוף הטקסט
-
@dovid כתב בשלאה בקוד C#: איך לעשות חיפוש בתוך מסמך html שהוא פתוח בwebbrowser:
אני חושב שהכי טוב זה לכתוב את הקוד בJS, ולשים בדף פונקציית find שעושה את העבודה
יש בעיה עם כל קוד JS כאשר משתמשים עם פקד WebBrowser בC# מכיון שהוא בעצם בנוי על אינטרנט אקספלורר - אז מה שקורה שהוא חוסם כל קוד jS (זוכרים את הימים ההם של הודעות ACTIVEX ?)
הייתי משתמש עם פקדים יותר מתקדמים אבל דא עקא בVSTO למיטב הבנתי הם לא זמינים. -
@pcinfogmach בWinForms יש לזה פתרון, אבל סביר שהוא לא עובד בVSTO (אולי כן, תבדוק)
var appName = System.Diagnostics.Process.GetCurrentProcess().ProcessName + ".exe"; using (var Key = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION", true)) Key.SetValue(appName, 99999, RegistryValueKind.DWord);
הנה פונקציה מוכנה לJS:
function find(term) { term = term.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); var elements = document.querySelectorAll(""p,span""); for (var i = 0; i < elements.length; i++) for (var j = 0; j < elements[i].childNodes.length; j++) { var node = elements[i].childNodes[j]; if (node.nodeType === Node.TEXT_NODE && node.textContent.indexOf(term) !== -1) { var newText = node.textContent.replace(new RegExp(term, 'g'), '<span class=""result"">' + term + '</span>'); if (node.textContent !== newText) node.parentNode.innerHTML = newText; } } }
הקוד מניח שיש כבר סטייל למחלקה result.
-
@dovid
ממש תודה! פשוט אין מילים@dovid כתב בשלאה בקוד C#: איך לעשות חיפוש בתוך מסמך html שהוא פתוח בwebbrowser:
בWinForms יש לזה פתרון, אבל סביר שהוא לא עובד בVSTO (אולי כן, תבדוק)
לבינתיים הקוד הזה עשה את העבודה וגם אין צורך לשחק ברגסטרי
<meta http-equiv='X-UA-Compatible' content='IE=10'>
ושוב תודה
-
מסתבר שטעיתי הקוד שהבאתי לא עשה כלום - הסיבה שלא היה את הבעיה כי במקום לטעון מסמך html עשיתי הזרקה של טקסט לתוך עמוד about:blank
ניסיתי את הקוד שלך וגם לא עזר - אז עכשיו שוב אני תקוע.
(ולעשות כל פעם הזרקה של טקסט במקום טעינת עמוד זה קצת בעייתי מכיון שאני צריך את הפונקציונליות של תנועה קדימה ואחורה בדפים שהמשתמש פתח).
-
@dovid
תודה על ההיענותצור חלונית צד בvsto
הוסף פקד webbrowser
ועוד כפתור
הזן קוד זה עבור הכפתורprivate void button1_Click(object sender, EventArgs e) { // Generate a temporary file name string tempHtmlFile = Path.GetTempFileName() + ".html"; // Create and write the HTML content to the temporary file File.WriteAllText(tempHtmlFile, @" <!DOCTYPE html> <html> <head> <meta http-equiv='X-UA-Compatible' content='IE=10'> <script> function showMessage() { alert('Button clicked!'); } </script> </head> <body> <button onclick='showMessage()'>Click Me</button> </body> </html> "); // Load the temporary HTML file into the WebBrowser control webBrowser1.Navigate(tempHtmlFile); } }
וכך זה נראה
-
@dovid
אולי זה יהיה שימושי
https://codereview.stackexchange.com/questions/126540/extended-webbrowser-control
אבל זה מעשבר לרמה שלי אין לי מושג איך להשתמש עם זה -
@pcinfogmach אמאלה, באמת חשבת לשמור כל הזמן לקובץ מקומי, רק בשביל להרויח את הback+forward?
זה גם הסיבה שלא עובד לך JS, כי זה קובץ מקומי ומטעמי אבטחה זה חסום, לא בגלל שזה WebBrowser ישן (אפשר כמדומני לשנות זאת בהגדרות אינטרנט גלובלית לכל המחשב, אבל לא כדאי).
אתה צריך להקים פשוט שרת אינטרנט' ככה תיתן טקסט עם כתובות בלי בעיה.
זה מתחיל להסתבך... אבל אתה זה שהעזת לעשות בוורד ככל העולה על רוחך -
@dovid כתב בשלאה בקוד C#: איך לעשות חיפוש בתוך מסמך html שהוא פתוח בwebbrowser:
אתה צריך להקים פשוט שרת אינטרנט
אני לא בטוח מה כוונתך - התוסף בנוי בשביל אברכים שרוב הזמן אין להם חיבור לאינטרנט.
@dovid כתב בשלאה בקוד C#: איך לעשות חיפוש בתוך מסמך html שהוא פתוח בwebbrowser:
אמאלה, באמת חשבת לשמור כל הזמן לקובץ מקומי, רק בשביל להרויח את הback+forward?
נשמע שיש לך רעיון אחר איך לעשות back+forward??? או שלא הבנתי נכון
-
@pcinfogmach כתב בשלאה בקוד C#: איך לעשות חיפוש בתוך מסמך html שהוא פתוח בwebbrowser:
אני לא בטוח מה כוונתך - התוסף בנוי בשביל אברכים שרוב הזמן אין להם חיבור לאינטרנט.
שרת אינטרנט מקומי לא דורש חיבור לאינטרנט, הכוונה היא לתוכנה שמארחת אתרים כאילו היא אתר (ובמקרה זה באמת יהיה אתר שאתה תבחר), אבל בגלל שזה במחשב המקומי היחיד שיכול לגשת לאתר הזה הוא מי שגולש מהמחשב המקומי.
-
כוונתי שרת אינטרנט מקומי.
אתה פשוט מאזין לבקשות לכתובת מקומית כמו localhost:1234 ואז אתה מגיש את הדף לא בצורה יזומה אלא בצורה מגיבה.
(אתה יכול ליזום את הnavigate כמובן בדיוק כפי שעשית עם הקבצים).
הנה דוגמת קוד:public partial class UserControl1 : UserControl { public UserControl1() { InitializeComponent(); Disposed += (s,e) => server?.Close(); } static UserControl1() { serverThread = new Thread(StartServer); serverThread.Start(); } static Dictionary<string, string> dataHtmls = new Dictionary<string, string>(); const string host = "http://localhost:8180/"; static Thread serverThread; static HttpListener server; static void StartServer() { server = new HttpListener(); server.Prefixes.Add(host); server.Start(); while (true) { var context = server.GetContext(); var request = context.Request; var response = context.Response; if (!dataHtmls.TryGetValue(request.Url.PathAndQuery, out var responseString)) responseString = "Not Found."; var buffer = Encoding.UTF8.GetBytes(responseString); response.ContentLength64 = buffer.Length; var output = response.OutputStream; output.Write(buffer, 0, buffer.Length); output.Close(); } } private void button1_Click(object sender, EventArgs e) { dataHtmls["/"] = $@" <html> <head> <meta name=""content-type"" content=""text/html; charset=UTF-8"" /> <script> function showMessage() {{ alert('Button clicked!'); }} </script> </head> <body> <button onclick='showMessage()'>Click Me</button> </body> </html>"; webBrowser1.Navigate(host); } }
-
@dovid כתב בשלאה בקוד C#: איך לעשות חיפוש בתוך מסמך html שהוא פתוח בwebbrowser:
אולי הHttpListener של מקרוסופט בזבזני, ואם כן תשלב משהו אחר, אולי נוד...
או TcpListener שמקבל הודעה (כמעט קבועה) ומחזיר הודעה, לא צריך פה מנגנון סנכרון, במקום להחזיר רק את הHTML בתוך המשתנה, להחזיק את כל התשובת HTTP.
אבל זה בהנחה ובאמת HttpListener בזבזני, מה שגם אם הוא נכון לא נראה לי בעל משמעות רבה כל כך שצריך להתקמצן עליו.
-
@dovid
איפה אפשר לקרוא קצת על הנושא הזה של שרת אינטרנט מקומי. (ומה בדיוק להזין בחיפוש גוגל) אני רוצה קצת לחקור את העניין לפני שאני משתמש בזה.
תודה -
אין הבדל בין שרת אינטרנט מקומי ללא מקומי, גם השרת שהראיתי יכול לתת תשובה לכל בקשה מבחוץ אם יגדירו למחשב דומיין וישנו את הlocalhost ל127.0.0.1. כל אתר ודף באינטרנט מקבלים את תוכן הדף שהם מציגים כטקסט שבא כתשובה מתוכנה דמויית הHttpListener.
ולכן בעצם אתה רוצה לקרוא על שרת אינטרנט, HTTP Server.
כיון שזה תחום רחב מידי קשה לדעת לאן להפנות אותך, אשמח לענות לך על שאלות סביב זה בנושא נפרד.