ايران ويج

نسخه‌ی کامل: وارد کردن مستقیم تگ های Html در Microsoft Internet Control
شما در حال مشاهده‌ی نسخه‌ی متنی این صفحه می‌باشید. مشاهده‌ی نسخه‌ی کامل با قالب بندی مناسب.
جمیعاً سلام
داشتم اینجا میگشتم که تایپیکی رو دیدم که دنبال استفاده از Html در برنامه بود ، خودمم یه مدتی بدجوری کارم روش لنگ بود و مدت زیادی برد تا راه حلش رو فهمیدمCool ؛ از اونجایی که مشکل خود من با Microsoft Internet Control حل شد و توی این تایپیکه هم نمایش مستقیم تگ های html خواسته شده پس از همین کنترل استفاده میکنم.

در مجموع سه راه برای نمایش تگ های html با کنترل Web browser مایکروسافت معموله و استفاده میشه :

1 - ذخیره تگ ها توی یه فایل با فرمت htm یا html و نمایش دادن این فایل با دستور Navigate کنترل Web browser

کد:
Option Explicit

Private Sub Form_Load()
Text1.Text = "<html><head><title>New Page 1</title></head><body><p>Hello World</p></body></html>"
Command1.Caption = "Save"
Command2.Caption = "Open in Browser"
End Sub

Private Sub Command1_Click()
'save textbox code to harddrive
'to view in WebBrowser1
Dim FF
FF = FreeFile
Open "c:\test.html" For Output As #FF
Print #FF, Text1.Text
Close #FF
End Sub

Private Sub Command2_Click()
WebBrowser1.Navigate "c:\test.html"
End Sub

2 - استفاده از متد Write شیء Document ، به این صورت که ما مستقیم کد رو برای پارس کردن به کنترل میفرستیم (نیازی نیست که متن وارد شده حتماً Html Tag باشه میتونید متن معمولی هم وارد کنید)

کد:
WebBrowser1.Document.write ("hello")

ولی این روش مشکلاتی داره
* باید حتماً کنترل مرورگر یک بار Navigate شده باشه چرا که در اولین اجرا این کانتینر (کنترل مرورگر) به چیزی اشاره ندارد و در نتیجه شیء ای هم وجود ندارد ، اگه بخوام واضح تر بگم هر صفحه وبی یک سری اصول و قواعدی داره که بهش ستون فقرات اون صفحه میگن (همون اشیاء و متدهای شیء Document) حالا این کنترل مایکروسافت اینطوریه که در اولین اجرا خام هستش و خودش خودکار ستون فقراتی که برای همه صفحات وب لازمه رو درست نمیکنه و حتماً باید یک بار Navigate بشه تا موتورش روشن بشهAmaze و بعد از اینکه موتورش روشن شد میتونیم از متد Write شیء Document استفاده بکنیم .

کد:
Private Sub Form_Load()
WebBrowser1.Navigate "google.com"
End Sub

Private Sub Command1_Click()
Dim HTMLCode As String
HTMLCode = "<HTML>" & _
"<TITLE>Page On Load</TITLE>" & _
"<BODY>" & _
"<FONT COLOR = BLUE>" & _
"This is a " & _
"<FONT SIZE = 5>" & _
"<B>" & _
"programmatically " & _
"</B>" & _
"</FONT SIZE>" & _
"made page" & _
"</FONT>" & _
"</BODY>" & _
"</HTML>"
WebBrowser1.Document.Write HTMLCode
End Sub

* اما مشکل بعدی اینه که حالا که ساختار اصلی کانتینر موتورش روشن شده ، باید حواسمون باشه وقتی از دستور Write استفاده کنیم که کنترل مرورگر آخرین Navigate خودشو تموم کرده باشه یعنی پروسه لود کردن اون صفحه تموم شده باشه حالا چه میخواد خطایی وجود داشته باشه و چه بدون خطا باشه اصل اینه که دیگه پردازشی برای دریافت و پارس کردن اون صفحه وب در حال اجرا نباشه تا مطمئن باشیم که تمام اشیاء صفحه (منظورم همون element های توی صفحه وب هستش) آزاد هستن و این آزاد بودن به این معنی هستش که محتوایی در حال جابه جایی بر روی ساختار کانتینر نیست و این هم به معنی آمادگی کانتینر برای Navigate کردن یه آدرس جدید هستش ؛ البته اینم بگم که میشه وسط یه پردازش ، Navigate جدیدی بزنیم ولی دیگه بشینید با خودتونو و وجدانتونو و cpu سیستمتون مثل دو تا مرد حرف بزنید ببینید به چه نتیجه ای میرسیدWhistle بعد اینکه اکثر موارد هم در همچین شرایطی یه دست غیب از تو سیستم میاد بیرون و طوری میزنه پس کلت که نفهمی از کجا خوردیTongue ؛ حالا برای اینکه بفهمیم پردازش این کانتینر وامونده تموم شده یا نه میتونیم دو کار کنیم :

** اول اینکه بیایم توی رویداد DocumentComplete کدی بزنیم که مثلاً مقدار یک متغییر عمومی یا استاتیک رو به True تغییر بده و بعداً ما ازش استفاده کنیم یا اصلاً دکمه Go یا هر چیز دیگه ای که فیتیله Navigate رو آتیش میزنه ، با شروع برنامه غیرفعال و بعد از بارگذاری کامل اولین Navigate ، فعالش کنیم.

کد:
Private Sub Form_Load()
WebBrowser1.Navigate "google.com"
Command1.Enabled = False
End Sub

Private Sub Command1_Click()
WebBrowser1.Document.write ("hello")
End Sub

Private Sub WebBrowser1_DocumentComplete(ByVal pDisp As Object, URL As Variant)
Command1.Enabled = True
End Sub

** دوم اینکه بیایم تو کد بخش Navigate کردن آدرس جدید ، وضعیت کانتینر رو بررسی کنیم ، مثلاً اینطوری :

کد:
Do Until webbrowser1.ReadyState = READYSTATE_COMPLETE
DoEvents
Loop
WebBrowser1.Document.write ("<hr>hello<hr>")

این هم بگم که حالت READYSTATE_COMPLETE فقط در اولین حرکت شما از یک صفحه وب به حالت Write شیء Document اجرا میشه یعنی اگر صفحه جاری شما متنی یا صفحه ای نمایش دهد که حاصل دستور Write است و بعد شما صفحه یا متن جدیدی رو با همین دستور نمایش بدید کنترل در تمام مدت در وضعیت READYSTATE_LOADING خواهد بود برای همین بهتره از خصیصه Busy برای چک کردن وضعیت کانتینر استفاده کنید :

کد:
Do Until WebBrowser1.Busy = False
DoEvents
Loop
WebBrowser1.Document.write ("<hr>hello<hr>")

یا میتونید از دستورات زیر استفاده کنید تا وضعیت READYSTATE_COMPLETE بودن رو فقط برای اولین Navigate بررسی بکنه :

کد:
If WebBrowser1.ReadyState = READYSTATE_UNINITIALIZED Then
Do Until WebBrowser1.ReadyState = READYSTATE_COMPLETE
DoEvents
Loop
End If
WebBrowser1.Document.write ("<hr>hello<hr>")

اما همیشه یه راه دیگه هم هست که اونایی که مخشون کار میکنه و به جای صنعت شریف رفتن آزاد میتونن پیداش کنن
اونم اینه که چه کاریه ما بیایم یه صفحه پر از المان رو که بارگذاریش طول میکشه رو بدیم به کانتینر تا موتورش روشن بشه ، بیایم یه صفحه خالی بدیم بهش ؛ اما بعضی ها هنوز داره اون مخشون ویز ویز میکنه و بهشون میگه که "یعنی دیگه راهی ساده تر نیست ؟" ، منم میگم چرا هست ؛ به جای اینکه اصلاً بیایم به خودمون زحمت نوشتن یه صفحه وب خالی بدیم مثل این

کد:
<html><head></head><body></body></html>

بعد بیایم مثل روش اول ذخیرش کنیم و اجراش کنیم تا مثلاً این موتور وامونده کنترل مرورگر مایکروسافت روشن بشه که بتونیم از دستور Write استفاده بکنیم (که میشه همون ترکیب روش اول و دوم) ، میایم دست به دست هم میدهیم و با سوزاندن انرژی کمتر و آزاد نکردن دی اکسید کربن بیشتر ، از یک فضای نام از پیش تعریف شده مرورگر explorer استفاده کنیم که همون "about:blank" هستش و موتور گازوئیلی ما رو هم روشن میکنه . 017

کد:
Private Sub Form_Load()
WebBrowser1.Navigate "about:blank"
End Sub

Private Sub Command1_Click()
If WebBrowser1.ReadyState = READYSTATE_UNINITIALIZED Then
Do Until WebBrowser1.ReadyState = READYSTATE_COMPLETE
DoEvents
Loop
End If

WebBrowser1.Document.write ("hello")
End Sub

اما اینکه چرا باز تو این حالت که اولین Navigate ما "about:blank" هستش ، وضعیت کانتینر رو برای استفاده از متد write ، بررسی میکنم ؛ اینه که اگه یادتون باشه درسته که گفتم رفتن از حالت دستور write به حالت جدیدی از همین دستور باعث ایجاد وضعیت READYSTATE_COMPLETE نمیشه ، اما باید دقت کنید که اولین حالت کانتینر ما Null بود بعد با اولین Navigate به "about:blank" میره پس باعث ثبت وضعیت READYSTATE_COMPLETE در این فرآیند میشه و لازمه ما از تداخل چند Navigate هم زمان به خصوص در اولین راه اندازی کانتینر جلوگیری کنیم تا از خطای احتمالی در امان باشیم.

3 - اما روش سوم ، استفاده از فضای نام "about:" ؛ اینو دیگه اون کسی که کشفش کرده باید آخر کنجکاو بوده باشه که تونسته کشفش کنه ؛ نکته تو همون "about:blank" خوابیده ، چطوری ؟
اینطوری که به جای "blank" عین کد مورد نظرتونو قرار بدید و با دستور Navigate مستقیماً اجراش کنید ، بدون هیچ نیازی به ذخیره کردن کد و Navigate کردن اولیه و صبر کردن برای Navigate شدن کامل و ... ، به همین سادگی به همین خوشمزگی

کد:
WebBrowser1.Navigate "about:" & HTMLCode

اون روش های 1 و 2 رو هم گفتم که بدونید و بخوانید و ببینید که نیاز ، مادر کشف و اختراع و ابتکار و ... هستشAtCoolWhistle

کدها و توضیحات به اندازه ای هستن که بشه خیلی راحت پروژه رو ساخت ، من عمداً فایل های پروژه رو نساختم که مجبور بشید بخونید و خودتون آستین بالا بزنید چون فقط دانلود کردن و استفاده کردن فایده ای نداره ؛ ولی اگه مشکلی تو هر جای کد داشتید یا هر مشکلی با این کانتینر وامونده مرورگر مایکروسافت داشتید همین جا بگید ، ان شاء الله من در خدمتم
من از کد زیر استفاده میکردم تا الان ، ولی روش شما هم جالبه
کد:
WebBrowser1.Document.body.innerHTML = HtmlCode
(۱۱-اسفند-۱۳۹۱, ۲۱:۲۷:۲۹)mahmoodgh نوشته است: [ -> ]من از کد زیر استفاده میکردم تا الان ، ولی روش شما هم جالبه
کد:
WebBrowser1.Document.body.innerHTML = HtmlCode

استفاده از خصیصه innerHTML هم مستلزم رعایت همون شرایط دستور Write هستش چون هر دو به کلکسیون شیء Document اشاره دارن ، با این تفاوت که innerHTML ریسکش خیلی بیشتره ، چون الان ما داریم یه مجموعه تگ html رو فقط به بخش innerHTML بدنه محتوای کانتینر اختصاص میدیم در حالی که کد html ما شاید بخش head هم داشته باشه ؛ در واقع مثل مقایسه اینه که بیایم به جای دستور move اشیاء از خصیصه های top , left , Width , Height استفاده کنیم ؛ البته این مایکروسافت از بس که سیستم تف مالی برای خطاها رو استفاده کرده معمولاً تو این شرایط نه خود منبع کانتینر (ieframe و برای نسخه های بعد از ie 7 فایل shdocvw) و نه هندل کننده کانتینر (vb6) هیچ خطایی نمیدن و بی سر و صدا سر و تهش رو هم میارن :-)) ولی دیگه نمیشه اطمینان داشت که محتوای HtmlCode درست نمایش داده میشه یا نه! یا اصلاً تو اجرای بعدی همین دستور محتوایی برای کانتینر ارسال میشه یا نه!