<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-18847389</id><updated>2012-01-19T13:56:23.205-08:00</updated><category term='tetris'/><category term='VBScript'/><category term='RB_SETPARENT'/><category term='jscript'/><category term='IHTMLElementCollection'/><category term='SQL'/><category term='encoding'/><category term='cpptohtml'/><category term='Active Accessibility'/><category term='applet'/><category term='MSI'/><category term='Security'/><category term='http'/><category term='LEX'/><category term='help'/><category term='context menu'/><category term='C++'/><category term='E_ACCESSDENIED'/><category term='test'/><category term='reflector'/><category term='IHTMLDocument2'/><category term='js'/><category term='extension'/><category term='web automation'/><category term='IWebBrowser2'/><category term='script'/><category term='IServiceProvider'/><category term='automate'/><category term='repair'/><category term='.net'/><category term='internet explorer automation'/><category term='macro'/><category term='windows mobile'/><category term='Spell'/><category term='Twebst'/><category term='web macro'/><category term='IAccessible'/><category term='web recorder'/><category term='tab'/><category term='NUnit'/><category term='IE7'/><category term='decoding'/><category term='java'/><category term='tool'/><category term='IE tool'/><category term='IHTMLElement'/><category term='toolbar'/><category term='COM'/><category term='syntax highlighting'/><category term='IHTMLWindow2'/><category term='IE automation'/><category term='rebar'/><category term='game'/><category term='WSH'/><category term='RBN_CHEVRONPUSHED'/><category term='C#'/><category term='VBA'/><category term='garbage collector'/><category term='ATL'/><category term='TextRange'/><category term='regsvr32'/><category term='STL'/><category term='menuArguments'/><category term='IE8'/><category term='selection'/><category term='HTML'/><category term='browser automation'/><category term='regtlib'/><category term='IE'/><category term='Internet Explorer'/><category term='automation'/><category term='cpp2html'/><category term='WorkerW'/><category term='Excel'/><title type='text'>IE Automation Library and Web Macro Recorder</title><subtitle type='html'>&lt;i&gt;Twebst Automation Studio&lt;/i&gt;: browser macros, web scraping, web testing and automation for Internet Explorer.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>44</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-18847389.post-5083600344430661758</id><published>2011-05-12T01:27:00.000-07:00</published><updated>2011-05-13T13:41:55.715-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web macro'/><category scheme='http://www.blogger.com/atom/ns#' term='Twebst'/><category scheme='http://www.blogger.com/atom/ns#' term='IE automation'/><category scheme='http://www.blogger.com/atom/ns#' term='IE9'/><title type='text'>IE9 Automation and Web Macros</title><content type='html'>&lt;span style="font-size:130%;"&gt;Twebst Automation Studio 2.6 - New Release!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I am once again happy to announce a new version of &lt;span style="font-style: italic;"&gt;Twebst Automation Studio&lt;/span&gt;. What's new:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;IE9&lt;/span&gt; web automation and macro support.&lt;/li&gt;&lt;li&gt;custom DLL injection instead of BHO browser extension (which in &lt;span style="font-style: italic;"&gt;IE9&lt;/span&gt; generates security warnings).&lt;/li&gt;&lt;li&gt;TwebstBHOps.dll is no longer needed.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codecentrix.com/help/HTML/LnkFindBrowser.htm"&gt;FindBrowser &lt;/a&gt;and &lt;a href="http://www.codecentrix.com/help/HTML/LnkFindAllBrowsers.htm"&gt;FindAllBrowsers&lt;/a&gt; now work with any application that embeds &lt;span style="font-style: italic;"&gt;Internet Explorer&lt;/span&gt; web control.&lt;/li&gt;&lt;li&gt;Bug fixes and enhancements.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://www.codecentrix.com/download.html"&gt;&lt;span style="font-size:130%;"&gt;Download Twebst 2.6&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-5083600344430661758?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/5083600344430661758/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=5083600344430661758' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/5083600344430661758'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/5083600344430661758'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2011/05/ie9-automation-and-web-macros.html' title='IE9 Automation and Web Macros'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-5439042095263267767</id><published>2010-07-08T01:00:00.000-07:00</published><updated>2010-07-08T02:35:20.510-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web macro'/><category scheme='http://www.blogger.com/atom/ns#' term='IE8'/><category scheme='http://www.blogger.com/atom/ns#' term='tab'/><category scheme='http://www.blogger.com/atom/ns#' term='web automation'/><title type='text'>IE8 close tab programmatically</title><content type='html'>Sometimes you may wish to close a &lt;strong&gt;browser instance&lt;/strong&gt; and &lt;a href="http://www.codecentrix.com/" target="_blank"&gt;Twebst Library&lt;/a&gt; has support for that. You just have to call &lt;a href="http://www.codecentrix.com/help/HTML/LnkClose.htm" target="_blank"&gt;Close&lt;/a&gt; method against the &lt;a href="http://www.codecentrix.com/help/HTML/LnkBrowser.htm" target="_blank"&gt;Browser&lt;/a&gt; &lt;strong&gt;web automation object&lt;/strong&gt; you want to close.&lt;br /&gt;&lt;br /&gt;Let's see a short &lt;em&gt;JScript&lt;/em&gt; &lt;strong&gt;web automation macro &lt;/strong&gt;that closes the first &lt;strong&gt;IE8 tab&lt;/strong&gt; loaded from &lt;em&gt;google.com&lt;/em&gt; domain. If the closing tab is the last tab inside the &lt;em&gt;IE frame&lt;/em&gt; then the whole browser will be closed.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="color:#009900;"&gt;// Create core object.&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;var&lt;/span&gt; core = &lt;span style="color:#3366ff;"&gt;new&lt;/span&gt; ActiveXObject(&lt;span style="color:#cc0000;"&gt;"Twebst.Core"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#009900;"&gt;// Find a browser for which the displayed URL contains "google.com".&lt;/span&gt;&lt;br /&gt;core.useRegExp = &lt;span style="color:#3366ff;"&gt;true&lt;/span&gt;;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;var&lt;/span&gt; b = core.FindBrowser(&lt;span style="color:#cc0000;"&gt;"url=.*google.com"&lt;/span&gt;);&lt;br /&gt;b.Close();&lt;/code&gt;&lt;/pre&gt;There are more Twebst methods for &lt;strong&gt;automating IE7 and IE8 tabs&lt;/strong&gt; that I'll talk about in future articles: &lt;a href="http://www.codecentrix.com/help/HTML/LnkOpenNewTab.htm"&gt;OpenNewTab&lt;/a&gt;, &lt;a href="http://www.codecentrix.com/help/HTML/LnkactiveTab.htm"&gt;activeTab&lt;/a&gt;, &lt;a href="http://www.codecentrix.com/help/HTML/LnkisTabActive.htm"&gt;isTabActive&lt;/a&gt;, &lt;a href="http://www.codecentrix.com/help/HTML/LnktabList.htm"&gt;tabList&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-5439042095263267767?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/5439042095263267767/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=5439042095263267767' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/5439042095263267767'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/5439042095263267767'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2010/07/ie8-close-tab-programmatically.html' title='IE8 close tab programmatically'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-2602836789611748439</id><published>2010-07-07T09:30:00.000-07:00</published><updated>2010-07-07T09:44:33.086-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Twebst'/><category scheme='http://www.blogger.com/atom/ns#' term='web automation'/><category scheme='http://www.blogger.com/atom/ns#' term='web recorder'/><category scheme='http://www.blogger.com/atom/ns#' term='IE automation'/><category scheme='http://www.blogger.com/atom/ns#' term='IE tool'/><title type='text'>Twebst Automation Studio 2.5 - New Release!</title><content type='html'>This blog was too quiet for some time but after another development cycle I am happy to announce a new release: &lt;em&gt;&lt;strong&gt;Twebst Automation Studio&lt;/strong&gt;&lt;/em&gt; version &lt;strong&gt;2.5&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;New features:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.codecentrix.com/help/HTML/LnkClosePopup.htm"&gt;ClosePopup&lt;/a&gt; web automation method&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codecentrix.com/help/HTML/LnkClosePrompt.htm"&gt;ClosePrompt&lt;/a&gt; web automation method&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codecentrix.com/help/HTML/LnkcloseBrowserPopups.htm"&gt;closeBrowserPopups&lt;/a&gt; web automation property&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codecentrix.com/help/HTML/LnkOpenNewTab.htm"&gt;OpenNewTab&lt;/a&gt; web automation method&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codecentrix.com/help/HTML/LnktabList.htm"&gt;tabList&lt;/a&gt; web automation property&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codecentrix.com/help/HTML/LnkactiveTab.htm"&gt;activeTab&lt;/a&gt; web automation property&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codecentrix.com/help/HTML/LnkisTabActive.htm"&gt;isTabActive&lt;/a&gt; web automation property&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codecentrix.com/help/HTML/LnkasyncHtmlEvents.htm"&gt;asyncHtmlEvents&lt;/a&gt; web automation property&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codecentrix.com/help/HTML/LnkRightClick.htm"&gt;RightClick&lt;/a&gt; support added in &lt;strong&gt;web recorder&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;index attribute added to &lt;a href="http://www.codecentrix.com/help/HTML/LnkFindFrame.htm"&gt;FindFrame&lt;/a&gt; method&lt;/li&gt;&lt;li&gt;minor bug fixes in &lt;strong&gt;web automation library&lt;/strong&gt;, &lt;strong&gt;web recorder&lt;/strong&gt; and help system &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p align="center"&gt;&lt;span style="font-size:180%;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p align="center"&gt;&lt;span style="font-size:180%;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p align="center"&gt;&lt;span style="font-size:180%;"&gt;.&lt;/span&gt;&lt;/p&gt;&lt;p align="center"&gt;&lt;span style="font-size:180%;"&gt;&lt;a href="http://www.codecentrix.com/"&gt;Download Twebst - IE Automation Software&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;div align="center"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-2602836789611748439?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/2602836789611748439/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=2602836789611748439' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/2602836789611748439'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/2602836789611748439'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2010/07/twebst-automation-studio-25-new-release.html' title='Twebst Automation Studio 2.5 - New Release!'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-7954004716578360199</id><published>2010-03-07T07:42:00.000-08:00</published><updated>2010-03-08T04:52:25.909-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='internet explorer automation'/><category scheme='http://www.blogger.com/atom/ns#' term='web macro'/><category scheme='http://www.blogger.com/atom/ns#' term='VBA'/><category scheme='http://www.blogger.com/atom/ns#' term='Internet Explorer'/><category scheme='http://www.blogger.com/atom/ns#' term='Excel'/><category scheme='http://www.blogger.com/atom/ns#' term='browser automation'/><category scheme='http://www.blogger.com/atom/ns#' term='web automation'/><category scheme='http://www.blogger.com/atom/ns#' term='web recorder'/><title type='text'>Move data from Excel to IE and back with VBA web macros</title><content type='html'>Let's continue my previous post (&lt;a href="http://codecentrix.blogspot.com/2010/03/ie8-automation-using-excel-vba-macro.html"&gt;IE8 Automation using Excel VBA Macro&lt;/a&gt;) with some &lt;span style="font-weight: bold;"&gt;VBA Internet Explorer automation&lt;/span&gt; code:&lt;code&gt;&lt;/code&gt;&lt;pre&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;' Don't forget to add reference to TwebstLib from menu Tools/References&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;Dim&lt;/span&gt; core &lt;span style="color: rgb(51, 51, 255);"&gt;As&lt;/span&gt; TwebstLib.ICoreVba&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;Set&lt;/span&gt; core = &lt;span style="color: rgb(51, 51, 255);"&gt;New&lt;/span&gt; TwebstLib.core&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;Dim&lt;/span&gt; browser &lt;span style="color: rgb(51, 51, 255);"&gt;As&lt;/span&gt; TwebstLib.IBrowserVba&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;Set&lt;/span&gt; browser = core.StartBrowserVba(&lt;span style="color: rgb(204, 0, 0);"&gt;"http://www.google.com/"&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;For&lt;/span&gt; i = 1 &lt;span style="color: rgb(51, 51, 255);"&gt;To&lt;/span&gt; 5&lt;br /&gt;   &lt;span style="color: rgb(0, 102, 0);"&gt;' Get the current text to be translated&lt;/span&gt;&lt;br /&gt;   &lt;span style="color: rgb(51, 51, 255);"&gt;Dim&lt;/span&gt; textToTranslate &lt;span style="color: rgb(51, 51, 255);"&gt;As&lt;/span&gt; String&lt;br /&gt;   textToTranslate = ActiveSheet.Cells(i, 1).Formula&lt;br /&gt;&lt;br /&gt;   &lt;span style="color: rgb(0, 102, 0);"&gt;' Twebst web automation part&lt;/span&gt;&lt;br /&gt;   &lt;span style="color: rgb(51, 51, 255);"&gt;Call&lt;/span&gt; browser.Navigate(&lt;span style="color: rgb(204, 0, 0);"&gt;"http://www.google.com/language_tools?hl=en"&lt;/span&gt;)&lt;br /&gt;   &lt;span style="color: rgb(51, 51, 255);"&gt;Call&lt;/span&gt; browser.FindElementVba(&lt;span style="color: rgb(204, 0, 0);"&gt;"textarea"&lt;/span&gt;, &lt;span style="color: rgb(204, 0, 0);"&gt;"id=source"&lt;/span&gt;).InputText(textToTranslate)&lt;br /&gt;   &lt;span style="color: rgb(51, 51, 255);"&gt;Call&lt;/span&gt; browser.FindElementVba(&lt;span style="color: rgb(204, 0, 0);"&gt;"select"&lt;/span&gt;, &lt;span style="color: rgb(204, 0, 0);"&gt;"name=sl"&lt;/span&gt;).Select(&lt;span style="color: rgb(204, 0, 0);"&gt;"English"&lt;/span&gt;)&lt;br /&gt;   &lt;span style="color: rgb(51, 51, 255);"&gt;Call&lt;/span&gt; browser.FindElementVba(&lt;span style="color: rgb(204, 0, 0);"&gt;"select"&lt;/span&gt;, &lt;span style="color: rgb(204, 0, 0);"&gt;"name=tl"&lt;/span&gt;).Select(&lt;span style="color: rgb(204, 0, 0);"&gt;"French"&lt;/span&gt;)&lt;br /&gt;   &lt;span style="color: rgb(51, 51, 255);"&gt;Call&lt;/span&gt; browser.FindElementVba(&lt;span style="color: rgb(204, 0, 0);"&gt;"input submit"&lt;/span&gt;, &lt;span style="color: rgb(204, 0, 0);"&gt;"text=Translate"&lt;/span&gt;).Click&lt;br /&gt;&lt;br /&gt;   &lt;span style="color: rgb(0, 102, 0);"&gt;' Find result span object&lt;/span&gt;&lt;br /&gt;   &lt;span style="color: rgb(51, 51, 255);"&gt;Dim&lt;/span&gt; resultObj &lt;span style="color: rgb(51, 51, 255);"&gt;As&lt;/span&gt; TwebstLib.IElementVba&lt;br /&gt;   &lt;span style="color: rgb(51, 51, 255);"&gt;Set&lt;/span&gt; resultObj = browser.FindElementVba(&lt;span style="color: rgb(204, 0, 0);"&gt;"span"&lt;/span&gt;, &lt;span style="color: rgb(204, 0, 0);"&gt;"id=result_box"&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;   &lt;span style="color: rgb(0, 102, 0);"&gt;' Get the text result&lt;/span&gt;&lt;br /&gt;   &lt;span style="color: rgb(51, 51, 255);"&gt;Dim&lt;/span&gt; translatedText &lt;span style="color: rgb(51, 51, 255);"&gt;As&lt;/span&gt; String&lt;br /&gt;   translatedText = resultObj.Text&lt;br /&gt;&lt;br /&gt;   &lt;span style="color: rgb(0, 102, 0);"&gt;' Save the result into Excel sheet&lt;/span&gt;&lt;br /&gt;   ActiveSheet.Cells(i, 2).Formula = translatedText&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;Next&lt;/span&gt;&lt;/pre&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;Points of interest:&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;in &lt;span style="font-weight: bold;"&gt;VBA web macro&lt;/span&gt; new methods are used (see &lt;a href="http://www.codecentrix.com/help/HTML/LnkFindElement.htm"&gt;FindElementVba&lt;/a&gt;). The newly added methods (&lt;a href="http://codecentrix.blogspot.com/2010/02/ie8-automation-with-excel-vba-macro.html"&gt;from version 2.1&lt;/a&gt;) are especially designed for &lt;span style="font-weight: bold;"&gt;VBA language&lt;/span&gt; and they work the same as they non-VBA counterparts except the fact no variable number of &lt;a href="http://www.codecentrix.com/help/HTML/SearchCondition.htm"&gt;search conditions&lt;/a&gt; are supported.&lt;/li&gt;&lt;li&gt;Twebst &lt;span style="font-weight: bold;"&gt;web recorder&lt;/span&gt; was updated to &lt;span style="font-weight: bold;"&gt;automatically generate VBA macro code&lt;/span&gt; against the newly added methods.&lt;/li&gt;&lt;li&gt;all &lt;span style="font-weight: bold;"&gt;web page loading&lt;/span&gt; synchronization is provided by default by the library.&lt;/li&gt;&lt;li&gt;when &lt;span style="font-weight: bold;"&gt;automating web controls&lt;/span&gt; all necessary &lt;span style="font-weight: bold;"&gt;HTML events&lt;/span&gt; are fired up against target object (see &lt;a href="http://msdn.microsoft.com/en-us/library/ms536423%28VS.85%29.aspx"&gt;fireEvent&lt;/a&gt;) to &lt;span style="font-weight: bold;"&gt;simulate user's web action&lt;/span&gt;.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:130%;"&gt;Downloads:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.codecentrix.com/download.html"&gt;Twebst Automation Studio PRO&lt;/a&gt; you'll need this installed before running the sample &lt;span style="font-weight: bold;"&gt;VBA macro&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codecentrix.com/blog/TwebstVBA.zip"&gt;TwebstVBA.zip&lt;/a&gt;  containing sample Excel and BAS files.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-7954004716578360199?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/7954004716578360199/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=7954004716578360199' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/7954004716578360199'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/7954004716578360199'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2010/03/move-data-from-excel-to-ie-and-back.html' title='Move data from Excel to IE and back with VBA web macros'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-2529129418620813951</id><published>2010-03-03T05:18:00.000-08:00</published><updated>2010-03-08T04:54:02.098-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='internet explorer automation'/><category scheme='http://www.blogger.com/atom/ns#' term='web macro'/><category scheme='http://www.blogger.com/atom/ns#' term='VBA'/><category scheme='http://www.blogger.com/atom/ns#' term='Internet Explorer'/><category scheme='http://www.blogger.com/atom/ns#' term='Excel'/><category scheme='http://www.blogger.com/atom/ns#' term='browser automation'/><category scheme='http://www.blogger.com/atom/ns#' term='web automation'/><category scheme='http://www.blogger.com/atom/ns#' term='web recorder'/><title type='text'>IE8 Automation using Excel VBA Macro</title><content type='html'>In my previous posts (&lt;a href="http://codecentrix.blogspot.com/2010/02/excel-and-ie-automation-wsh-way.html"&gt;Excel and IE automation - the WSH way&lt;/a&gt;, &lt;a href="http://codecentrix.blogspot.com/2010/02/extract-web-data-into-excelapplication.html"&gt;Extract web data into Excel.Application with browser macro&lt;/a&gt;) I automated both &lt;strong&gt;IE and Excel&lt;/strong&gt; using WSH. Now I'm going to &lt;strong&gt;automate &lt;em&gt;Internet Explorer&lt;/em&gt;&lt;/strong&gt; directly from an &lt;strong&gt;Excel macro&lt;/strong&gt; using the &lt;strong&gt;VBA language&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;The &lt;strong&gt;VBA macro&lt;/strong&gt; will work against a sheet containing phrases to be translated using &lt;em&gt;Google Translate&lt;/em&gt; tool. It automatically gets each phrase, &lt;strong&gt;opens IE browser&lt;/strong&gt;, navigates to translation page, &lt;strong&gt;waits the web page to complete loading&lt;/strong&gt;, fills out the text to be translated into &lt;strong&gt;HTML web controls&lt;/strong&gt;, &lt;strong&gt;press submit button&lt;/strong&gt;, gets back the result and saves it into the same Excel sheet.&lt;br /&gt;&lt;br /&gt;It is possible to directly automate IE browser from VBA macro but it is not always as simple as it should be. (see my older post: &lt;a href="http://codecentrix.blogspot.com/2008/12/whats-wrong-with-internet-explorer.html"&gt;What's wrong with Internet Explorer Automation?&lt;/a&gt;) Using &lt;em&gt;&lt;a href="http://www.codecentrix.com/"&gt;Twebst Automation Studio&lt;/a&gt;&lt;/em&gt; when &lt;strong&gt;automating IE from VBA&lt;/strong&gt; has some advangates:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;it works with all Internet Explorer versions: IE6, IE7, IE8 and with &lt;strong&gt;IE protected mode.&lt;/strong&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;it works on all Windows versions: XP, Vista, Win7&lt;/li&gt;&lt;br /&gt;&lt;li&gt;easily search of elements across all sub-documents inside &lt;strong&gt;frames/iframes hierarchy&lt;/strong&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;search HTML elements using &lt;strong&gt;regular expressions&lt;/strong&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;simulate user actions on all HTML controls (button, combo-box, list-box, edit-box, upload control) and &lt;strong&gt;fire all necessary HTML events&lt;/strong&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;auto-generate VBA code with powerful web recorder&lt;/li&gt;&lt;br /&gt;&lt;li&gt;much more (see &lt;a href="http://www.codecentrix.com/ie_automation.html"&gt;Twebst Automation Studio website&lt;/a&gt;)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;That's all for now. Until our &lt;a href="http://codecentrix.blogspot.com/2010/03/move-data-from-excel-to-ie-and-back.html"&gt;next encounter&lt;/a&gt;, check the download section below and have fun with the &lt;strong&gt;Excel VBA macro&lt;/strong&gt; code.&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:180%;"&gt;Downloads:&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.codecentrix.com/download.html"&gt;Twebst Automation Studio PRO&lt;/a&gt; this &lt;strong&gt;web automation tool&lt;/strong&gt; is used in VBA maro so you have to install it first.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.codecentrix.com/blog/TwebstVBA.zip"&gt;TwebstVBA.zip&lt;/a&gt; containing sample XLS and BAS files.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-2529129418620813951?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/2529129418620813951/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=2529129418620813951' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/2529129418620813951'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/2529129418620813951'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2010/03/ie8-automation-using-excel-vba-macro.html' title='IE8 Automation using Excel VBA Macro'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-8119209555014135201</id><published>2010-02-25T04:44:00.000-08:00</published><updated>2010-02-25T07:27:49.349-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='internet explorer automation'/><category scheme='http://www.blogger.com/atom/ns#' term='web macro'/><category scheme='http://www.blogger.com/atom/ns#' term='VBA'/><category scheme='http://www.blogger.com/atom/ns#' term='WSH'/><category scheme='http://www.blogger.com/atom/ns#' term='Excel'/><category scheme='http://www.blogger.com/atom/ns#' term='browser automation'/><category scheme='http://www.blogger.com/atom/ns#' term='web automation'/><category scheme='http://www.blogger.com/atom/ns#' term='web recorder'/><title type='text'>Extract web data into Excel.Application with browser macro</title><content type='html'>Let's continue my &lt;a href="http://codecentrix.blogspot.com/2010/02/excel-and-ie-automation-wsh-way.html"&gt;previous post&lt;/a&gt; where I presented a &lt;strong&gt;browser macro&lt;/strong&gt; that automatically translates phrases in an &lt;strong&gt;Excel document&lt;/strong&gt; using Google Translate tool. As you cand see in code, the &lt;strong&gt;WSH script&lt;/strong&gt; performs the following steps:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;instantiate "&lt;em&gt;Twebst.Core&lt;/em&gt;" &lt;strong&gt;web automation&lt;/strong&gt; object and &lt;strong&gt;start an IE browser&lt;/strong&gt;.&lt;/li&gt;&lt;li&gt;instantiate "&lt;em&gt;Excel.Application&lt;/em&gt;" automation object and open XLS document.&lt;/li&gt;&lt;li&gt;get a phrase to be translated from Excel document.&lt;/li&gt;&lt;li&gt;navigate to Google translate tool web page.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;fill out web controls&lt;/strong&gt; (the text to be translated, source and target language combo-boxes) and then &lt;strong&gt;automatically press submit button&lt;/strong&gt;.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;wait the web page to load&lt;/strong&gt;, get the translated text and save it into Excel document.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Let's see some code. I will skip the initial setup phase and go directly to &lt;strong&gt;web automation&lt;/strong&gt; part which is more interesting:&lt;/p&gt;&lt;code&gt;&lt;pre&gt;&lt;span style="color:#3333ff;"&gt;for&lt;/span&gt; (&lt;span style="color:#3333ff;"&gt;var&lt;/span&gt; i = 1; i &amp;lt;= 5; ++i)&lt;br /&gt;{&lt;br /&gt; &lt;span style="color:#006600;"&gt;// Get current text to translate from XLS document.&lt;/span&gt;&lt;br /&gt; &lt;span style="color:#3333ff;"&gt;var&lt;/span&gt; textToTranslate = excelApp.ActiveSheet.Cells(i, 1).Formula;&lt;br /&gt;&lt;br /&gt; &lt;span style="color:#006600;"&gt;// Web automation part implemented with Twebst Automatio Studio.&lt;/span&gt;&lt;br /&gt; browser.Navigate(&lt;span style="color:#cc0000;"&gt;'http://www.google.com/language_tools?hl=en'&lt;/span&gt;);&lt;br /&gt; browser.FindElement(&lt;span style="color:#cc0000;"&gt;'textarea'&lt;/span&gt;, &lt;span style="color:#cc0000;"&gt;'id=source'&lt;/span&gt;).InputText(textToTranslate);&lt;br /&gt; browser.FindElement(&lt;span style="color:#cc0000;"&gt;'select'&lt;/span&gt;, &lt;span style="color:#cc0000;"&gt;'name=sl'&lt;/span&gt;).Select(&lt;span style="color:#cc0000;"&gt;'English'&lt;/span&gt;);&lt;br /&gt; browser.FindElement(&lt;span style="color:#cc0000;"&gt;'select'&lt;/span&gt;, &lt;span style="color:#cc0000;"&gt;'name=tl'&lt;/span&gt;).Select(&lt;span style="color:#cc0000;"&gt;'French'&lt;/span&gt;);&lt;br /&gt; browser.FindElement(&lt;span style="color:#cc0000;"&gt;'input submit'&lt;/span&gt;, &lt;span style="color:#cc0000;"&gt;'text=Translate'&lt;/span&gt;).Click();&lt;br /&gt;&lt;br /&gt; &lt;span style="color:#006600;"&gt;// Get the reszult and save it into XLS document.&lt;/span&gt;&lt;br /&gt; &lt;span style="color:#3333ff;"&gt;var&lt;/span&gt; translatedText = browser.FindElement(&lt;span style="color:#cc0000;"&gt;'span'&lt;/span&gt;, &lt;span style="color:#cc0000;"&gt;'id=result_box'&lt;/span&gt;).text;&lt;br /&gt; excelApp.ActiveSheet.Cells(i, 2).Formula = translatedText;&lt;br /&gt;}&lt;/pre&gt;&lt;/code&gt;&lt;p&gt;&lt;strong&gt;Points of interest:&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.codecentrix.com/help/HTML/LnkFindElement.htm"&gt;FindElement&lt;/a&gt; method waits for the IE web page to be completely loaded before searching the element. The timeout value can be changed programatically (see &lt;a href="http://www.codecentrix.com/help/HTML/LnkloadTimeout.htm"&gt;loadTimeout&lt;/a&gt;, &lt;a href="http://www.codecentrix.com/help/HTML/LnksearchTimeout.htm"&gt;searchTimeout&lt;/a&gt; properties).&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codecentrix.com/help/HTML/LnkInputText.htm"&gt;InputText&lt;/a&gt; method sets the specified value in edit/password web controls and fires all necessary HTML events (&lt;em&gt;onkeydown&lt;/em&gt;, &lt;em&gt;onkeypress&lt;/em&gt;, &lt;em&gt;onkeyup&lt;/em&gt;, &lt;em&gt;onchange, &lt;/em&gt;etc).&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codecentrix.com/help/HTML/LnkSelect.htm"&gt;Select&lt;/a&gt; method fully automates combo-boxes and list-boxes web control and fires all necessary HTML events (like &lt;em&gt;onchange).&lt;/em&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Downloads:&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.codecentrix.com/"&gt;Twebst Automation Studio&lt;/a&gt; - you need to install this &lt;strong&gt;web automation tool &lt;/strong&gt;before running the demo WSH script below.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codecentrix.com/blog/xlsiewsh/excel_ie_wsh.zip"&gt;ExcelToWebMacro.zip&lt;/a&gt; - &lt;strong&gt;web scraping&lt;/strong&gt; demo script that saves results into Excel file.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-8119209555014135201?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/8119209555014135201/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=8119209555014135201' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/8119209555014135201'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/8119209555014135201'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2010/02/extract-web-data-into-excelapplication.html' title='Extract web data into Excel.Application with browser macro'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-5046579148341956726</id><published>2010-02-24T01:32:00.000-08:00</published><updated>2010-02-25T07:32:51.359-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='internet explorer automation'/><category scheme='http://www.blogger.com/atom/ns#' term='web macro'/><category scheme='http://www.blogger.com/atom/ns#' term='VBA'/><category scheme='http://www.blogger.com/atom/ns#' term='WSH'/><category scheme='http://www.blogger.com/atom/ns#' term='Excel'/><title type='text'>Excel and IE automation - the WSH way</title><content type='html'>I can think of two possible scenarios when &lt;strong&gt;automating&lt;/strong&gt; &lt;strong&gt;Excel&lt;/strong&gt; and &lt;strong&gt;Internet Explorer&lt;/strong&gt; makes any sense:&lt;br /&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;you have data stored in Excel sheets and you want to&lt;strong&gt; push data into online web forms&lt;/strong&gt;. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;you need to &lt;strong&gt;extract data from web&lt;/strong&gt; and save them into Excel xls file.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;There are two ways to implement this:&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;automate Internet Explorer&lt;/strong&gt; browser from &lt;strong&gt;Excel VBA macro&lt;/strong&gt;.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;automate both IE and Excel from an external process using &lt;a href="http://en.wikipedia.org/wiki/OLE_Automation"&gt;OLE automation&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Today I will talk about the second option; I will automate both &lt;em&gt;Internet Explorer&lt;/em&gt; and &lt;em&gt;Excel&lt;/em&gt; application from a &lt;a href="http://en.wikipedia.org/wiki/WSH"&gt;WSH&lt;/a&gt; script using &lt;a href="http://www.codecentrix.com/"&gt;Twebst Automation Studio&lt;/a&gt;. Here's a diagram showing the work-flow:&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;a href="http://1.bp.blogspot.com/_b7z9mi4EOXE/S4KmwnQOKoI/AAAAAAAAA2g/v_zsHBRJ-JM/s1600-h/excel_to_web.png"&gt;&lt;img style="WIDTH: 400px; HEIGHT: 307px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5441094653917932162" title="Fill out web forms with Excel data" border="0" alt="Fill out web forms with Excel data" src="http://1.bp.blogspot.com/_b7z9mi4EOXE/S4KmwnQOKoI/AAAAAAAAA2g/v_zsHBRJ-JM/s400/excel_to_web.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The &lt;strong&gt;WSH&lt;/strong&gt; &lt;strong&gt;web macro&lt;/strong&gt; in this tutorial opens an &lt;strong&gt;XLS&lt;/strong&gt; file containing phrases to be translated using Google Translate tool. It then automatically gets each phrase, opens an &lt;strong&gt;IE browser&lt;/strong&gt;, navigates to translation page, &lt;strong&gt;fills out the text&lt;/strong&gt; to be translated, &lt;strong&gt;press submit button&lt;/strong&gt;, gets back the result and saves it into the same XLS file.&lt;/p&gt;&lt;p&gt;That's all for now! (as I try to keep articles relatively short) Meanwhile, you should download &lt;a href="http://www.codecentrix.com/"&gt;Twebst Automation Studio&lt;/a&gt; and the web macro sample to see it at work. Then, you can continue with the next article explaining the web macro code and comments: &lt;a href="http://codecentrix.blogspot.com/2010/02/extract-web-data-into-excelapplication.html"&gt;Extract web data into Excel.Application with browser macro&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;span style="font-size:180%;"&gt;Downloads:&lt;/span&gt;&lt;/p&gt;&lt;p align="center"&gt;&lt;a href="http://www.codecentrix.com/blog/xlsiewsh/excel_ie_wsh.zip"&gt;ExcelToWebMacro.zip&lt;/a&gt;&lt;/p&gt;&lt;p align="center"&gt;&lt;a href="http://www.codecentrix.com/download.html"&gt;Twebst Automation Studio&lt;/a&gt; (FREE edition available btw)&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-5046579148341956726?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/5046579148341956726/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=5046579148341956726' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/5046579148341956726'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/5046579148341956726'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2010/02/excel-and-ie-automation-wsh-way.html' title='Excel and IE automation - the WSH way'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_b7z9mi4EOXE/S4KmwnQOKoI/AAAAAAAAA2g/v_zsHBRJ-JM/s72-c/excel_to_web.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-7797552780214300418</id><published>2010-02-05T00:58:00.000-08:00</published><updated>2010-02-05T03:00:13.510-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='internet explorer automation'/><category scheme='http://www.blogger.com/atom/ns#' term='web macro'/><category scheme='http://www.blogger.com/atom/ns#' term='VBA'/><category scheme='http://www.blogger.com/atom/ns#' term='Internet Explorer'/><category scheme='http://www.blogger.com/atom/ns#' term='Excel'/><category scheme='http://www.blogger.com/atom/ns#' term='web recorder'/><title type='text'>IE8 automation with Excel VBA macro</title><content type='html'>&lt;span style="font-size:130%;"&gt;Twebst Automation Studio Ver 2.1 New Release!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;Many people requested for &lt;span style="font-weight: bold;"&gt;VBA (Excel, Word)&lt;/span&gt; direct &lt;span style="font-weight: bold;"&gt;web automation&lt;/span&gt; support in Twebst Library. T&lt;/span&gt;he previous version could not be easily used from VBA because of the way Excel works with methods with variable number of parameters (which is the case for many Twebst methods like: &lt;a href="http://www.codecentrix.com/help/HTML/LnkFindElement.htm"&gt;FindElement&lt;/a&gt;, &lt;a href="http://www.codecentrix.com/help/HTML/LnkFindBrowser.htm"&gt;FindBrowser&lt;/a&gt;, etc).&lt;br /&gt;&lt;br /&gt;The new Twebst 2.1 version includes a new full set of interfaces and methods specially designed for &lt;span style="font-weight: bold;"&gt;Excel VBA&lt;/span&gt;. The web recorder was also updated to generate VBA code that you can easily include in your &lt;span style="font-weight: bold;"&gt;Excel macro&lt;/span&gt;. To see what's new in Twebst ver 2.1 check &lt;a href="http://www.codecentrix.com/files/changelog.txt"&gt;changelog.txt&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Automating Internet Explorer&lt;/span&gt; from &lt;span style="font-weight: bold;"&gt;Excel VBA macro&lt;/span&gt; is now possible with Twebst Automation Studio 2.1.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://www.codecentrix.com/download.html"&gt;&lt;span style="font-size:130%;"&gt;Get It While it's Hot!&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-7797552780214300418?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/7797552780214300418/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=7797552780214300418' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/7797552780214300418'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/7797552780214300418'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2010/02/ie8-automation-with-excel-vba-macro.html' title='IE8 automation with Excel VBA macro'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-7479934163757203177</id><published>2009-12-21T00:03:00.000-08:00</published><updated>2009-12-21T09:13:07.663-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='internet explorer automation'/><category scheme='http://www.blogger.com/atom/ns#' term='web macro'/><category scheme='http://www.blogger.com/atom/ns#' term='jscript'/><category scheme='http://www.blogger.com/atom/ns#' term='Internet Explorer'/><category scheme='http://www.blogger.com/atom/ns#' term='IE'/><category scheme='http://www.blogger.com/atom/ns#' term='WSH'/><category scheme='http://www.blogger.com/atom/ns#' term='web recorder'/><category scheme='http://www.blogger.com/atom/ns#' term='macro'/><title type='text'>How to automate existing instances of Internet Explorer - Tutorial(4)</title><content type='html'>As explained in a &lt;a href="http://codecentrix.blogspot.com/2009/12/ie8-automation-how-to-programatically.html"&gt;previous tutorial&lt;/a&gt;, a &lt;strong&gt;web macro&lt;/strong&gt; can start by connecting to an already running instance of &lt;strong&gt;Internet Explorer&lt;/strong&gt; browser. A web macro usually starts a new Internet Explorer page and then navigates to a URL to begin with. There are times when automating an existing &lt;strong&gt;IE window&lt;/strong&gt; is a more natural alternative. Let's start with a &lt;strong&gt;JScript/WSH&lt;/strong&gt; simple &lt;strong&gt;web macro&lt;/strong&gt;:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span style="color:#009900;"&gt;// Create core object.&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;var&lt;/span&gt; core = &lt;span style="color:#3366ff;"&gt;new&lt;/span&gt; ActiveXObject(&lt;span style="color:#cc0000;"&gt;"Twebst.Core"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#009900;"&gt;// Find a browser for which the displayed URL contains "yahoo".&lt;/span&gt;&lt;br /&gt;core.useRegExp = &lt;span style="color:#3366ff;"&gt;true&lt;/span&gt;;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;var&lt;/span&gt; b1 = core.FindBrowser(&lt;span style="color:#cc0000;"&gt;"url=.*yahoo.*"&lt;/span&gt;);&lt;br /&gt;b1.Navigate("www.google.com");&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#009900;"&gt;// Find a browser for which the title is "Google" (exact match).&lt;/span&gt;&lt;br /&gt;core.useRegExp = &lt;span style="color:#3366ff;"&gt;false&lt;/span&gt;;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;var&lt;/span&gt; b2 = core.FindBrowser(&lt;span style="color:#cc0000;"&gt;"title=Google"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;b2.Close();&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Basically &lt;a href="http://www.codecentrix.com/help/HTML/LnkFindBrowser.htm" target="_blank"&gt;FindBrowser&lt;/a&gt; method searches for a browser page based on TITLE and/or URL. If &lt;a href="http://www.codecentrix.com/help/HTML/LnkuseRegExp.htm" target="_blank"&gt;core.useRegExp&lt;/a&gt; is false then an exact search is used. If &lt;a href="http://www.codecentrix.com/help/HTML/LnkuseRegExp.htm" target="_blank"&gt;core.useRegExp&lt;/a&gt; is true then the search uses regular expressions. Once connected to a &lt;strong&gt;IE browser&lt;/strong&gt; instance, you get a &lt;a href="http://www.codecentrix.com/help/HTML/LnkBrowser.htm" target="_blank"&gt;Browser&lt;/a&gt; object to play with.&lt;br /&gt;&lt;br /&gt;Of course, this works for &lt;strong&gt;IE6&lt;/strong&gt;, &lt;strong&gt;IE7&lt;/strong&gt;, &lt;strong&gt;IE8&lt;/strong&gt; on Windows XP, Vista and Windows 7 (32 and 64 bit) and it's compatible with &lt;strong&gt;Internet Explorer Protected Mode&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;What can you do with a &lt;a href="http://www.codecentrix.com/help/HTML/LnkBrowser.htm" target="_blank"&gt;Browser&lt;/a&gt; object? Quite a lot of things: &lt;a href="http://www.codecentrix.com/help/HTML/LnkNavigate.htm" target="_blank"&gt;Navigate&lt;/a&gt; to a URL, &lt;a href="http://www.codecentrix.com/help/HTML/LnkFindElement.htm" target="_blank"&gt;FindElement&lt;/a&gt; and &lt;a href="http://www.codecentrix.com/help/HTML/LnkFindFrame.htm" target="_blank"&gt;FindFrame&lt;/a&gt; inside it, &lt;a href="http://www.codecentrix.com/help/HTML/LnkClose.htm" target="_blank"&gt;Close&lt;/a&gt; the browser, get information about the browser, &lt;strong&gt;automate modal and modeless HTML dialgos&lt;/strong&gt; and wait to complete navigation and loading.&lt;br /&gt;&lt;br /&gt;Enough talk! It's time to &lt;a href="http://www.codecentrix.com/download.html"&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Download Twebst Automation Studio&lt;/strong&gt;&lt;/span&gt;&lt;/a&gt; and see it for yourself.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p align="center"&gt;.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-7479934163757203177?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/7479934163757203177/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=7479934163757203177' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/7479934163757203177'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/7479934163757203177'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2009/12/how-to-automate-existing-instances-of.html' title='How to automate existing instances of Internet Explorer - Tutorial(4)'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-3516230735009121135</id><published>2009-12-14T08:01:00.000-08:00</published><updated>2009-12-14T10:06:39.211-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='internet explorer automation'/><category scheme='http://www.blogger.com/atom/ns#' term='web macro'/><category scheme='http://www.blogger.com/atom/ns#' term='VBScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Internet Explorer'/><category scheme='http://www.blogger.com/atom/ns#' term='IE'/><category scheme='http://www.blogger.com/atom/ns#' term='WSH'/><category scheme='http://www.blogger.com/atom/ns#' term='automation'/><category scheme='http://www.blogger.com/atom/ns#' term='web recorder'/><category scheme='http://www.blogger.com/atom/ns#' term='automate'/><title type='text'>IE macro - how to get programmatic control over HTML elements - Tutorial(3)</title><content type='html'>&lt;div align="left"&gt;&lt;strong&gt;Finding elements inside HTML frames/iframes hierarchy with &lt;/strong&gt;&lt;a href="http://www.codecentrix.com/" target="_blank"&gt;&lt;strong&gt;Twebst Web Automation Library&lt;/strong&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;/span&gt;&lt;br /&gt;Once you have &lt;a href="http://codecentrix.blogspot.com/2009/12/ie8-automation-how-to-programatically.html"&gt;started a web macro&lt;/a&gt; and you've got a &lt;a href="http://www.codecentrix.com/help/HTML/LnkBrowser.htm" target="_blank"&gt;Browser&lt;/a&gt; object to play with, it's time to get programmatic access HTML controls inside the web page. As any web developer should know, you can easily find elements inside a document using &lt;strong&gt;document.getElementById&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;In the world of &lt;strong&gt;web automation&lt;/strong&gt; things are a bit different; &lt;strong&gt;web macros&lt;/strong&gt; need to access HTML elements in any web document and at any level of &lt;strong&gt;DOM hierarchy&lt;/strong&gt;. The target HTML element can be inside &lt;strong&gt;frames/iframes&lt;/strong&gt; loaded from various domains, subject of &lt;strong&gt;cross-frame scripting security restrictions&lt;/strong&gt; (see my older posts: &lt;a href="http://codecentrix.blogspot.com/2007/10/when-ihtmlwindow2getdocument-returns.html"&gt;"When IHTMLWindow2::get_document returns E_ACCESSDENIED"&lt;/a&gt; and &lt;a href="http://codecentrix.blogspot.com/2008/02/when-ihtmlwindow2document-throws.html"&gt;"When IHTMLWindow2.document throws UnauthorizedAccessException"&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Here's a simple &lt;strong&gt;VBscript web macro&lt;/strong&gt; that automates a Google search in &lt;em&gt;Internet Explorer&lt;/em&gt;:&lt;/div&gt;&lt;code&gt;&lt;pre&gt;&lt;span style="color:#3333ff;"&gt;Dim&lt;/span&gt; core&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Dim&lt;/span&gt; browser&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Set&lt;/span&gt; core    = CreateObject(&lt;span style="color:#cc0000;"&gt;"Twebst.Core"&lt;/span&gt;)&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Set&lt;/span&gt; browser = core.StartBrowser(&lt;span style="color:#cc0000;"&gt;"http://www.google.com/"&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;Call&lt;/span&gt; browser.FindElement(&lt;span style="color:#cc0000;"&gt;"input text"&lt;/span&gt;,   &lt;span style="color:#cc0000;"&gt;"name=q"&lt;/span&gt;).InputText(&lt;span style="color:#cc0000;"&gt;"codecentrix"&lt;/span&gt;)&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;Call&lt;/span&gt; browser.FindElement(&lt;span style="color:#cc0000;"&gt;"input submit"&lt;/span&gt;, &lt;span style="color:#cc0000;"&gt;"name=btnG"&lt;/span&gt;).Click()&lt;/pre&gt;&lt;p&gt;&lt;/code&gt;What is so great about the code above is the way &lt;a href="http://www.codecentrix.com/help/HTML/LnkFindElement.htm" target="_blank"&gt;FindElement&lt;/a&gt; method works: first it waits for the browser to load the HTML document then it searches for the element thru all &lt;strong&gt;frame/iframe hierarchy&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;Once an &lt;a href="http://www.codecentrix.com/help/HTML/LnkElement.htm"&gt;Element&lt;/a&gt; is found you can perform actions on it like: &lt;a href="http://www.codecentrix.com/help/HTML/LnkClick.htm"&gt;Click&lt;/a&gt;, &lt;a href="http://www.codecentrix.com/help/HTML/LnkRightClick.htm"&gt;RightClick&lt;/a&gt;, &lt;a href="http://www.codecentrix.com/help/HTML/LnkInputText.htm"&gt;InputText&lt;/a&gt;, &lt;a href="http://www.codecentrix.com/help/HTML/LnkCheck.htm"&gt;Check&lt;/a&gt;, &lt;a href="http://www.codecentrix.com/help/HTML/LnkUncheck.htm"&gt;Uncheck&lt;/a&gt;, &lt;a href="http://www.codecentrix.com/help/HTML/LnkSelect.htm"&gt;Select&lt;/a&gt;, &lt;a href="http://www.codecentrix.com/help/HTML/LnkHighlight.htm"&gt;Highlight&lt;/a&gt; etc. What is even cooler than this, is that you don't have to write these statements by yourself. They will be automatically generated by &lt;strong&gt;Twebst Web Recorder&lt;/strong&gt; which you can get for free:&lt;/p&gt;&lt;p align="center"&gt;&lt;a href="http://www.codecentrix.com/"&gt;&lt;span style="font-size:130%;"&gt;Get Free Web Recorder for Internet Explorer&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p align="center"&gt;&lt;span style="font-size:180%;"&gt;.&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-3516230735009121135?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/3516230735009121135/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=3516230735009121135' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/3516230735009121135'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/3516230735009121135'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2009/12/ie-macro-how-to-get-programmatic.html' title='IE macro - how to get programmatic control over HTML elements - Tutorial(3)'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-909474389949263731</id><published>2009-12-09T00:11:00.000-08:00</published><updated>2009-12-09T07:10:45.201-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='js'/><category scheme='http://www.blogger.com/atom/ns#' term='internet explorer automation'/><category scheme='http://www.blogger.com/atom/ns#' term='web macro'/><category scheme='http://www.blogger.com/atom/ns#' term='jscript'/><category scheme='http://www.blogger.com/atom/ns#' term='automation'/><category scheme='http://www.blogger.com/atom/ns#' term='web recorder'/><category scheme='http://www.blogger.com/atom/ns#' term='macro'/><title type='text'>IE8 automation: How to programatically open an URL - Tutorial (2)</title><content type='html'>&lt;div&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Get started with web macros in IE&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Every &lt;strong&gt;web macro&lt;/strong&gt; has to start somewhere, has to start somehow. There are basically two scenarios of &lt;strong&gt;automating Internet Explorer&lt;/strong&gt; browser:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;start a new &lt;strong&gt;IE browser&lt;/strong&gt; and navigate to a URL to begin with&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;connect to an existing instance of &lt;strong&gt;Internet Explorer browser&lt;/strong&gt; and continue automation&lt;/li&gt;&lt;/ul&gt;In this short tutorial I'll show you how to open a new &lt;strong&gt;Internet Explorer&lt;/strong&gt; browser and open an URL with &lt;a href="http://www.codecentrix.com/" target="_blank"&gt;Twebst Automation Studio&lt;/a&gt;. Let's start with a short &lt;strong&gt;JScript web macro&lt;/strong&gt;.&lt;pre&gt;&lt;code&gt;&lt;span style="color:#3366ff;"&gt;var&lt;/span&gt; core    = &lt;span style="color:#3366ff;"&gt;new&lt;/span&gt; ActiveXObject(&lt;span style="color:#cc0000;"&gt;'Twebst.Core'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;var&lt;/span&gt; browser = core.StartBrowser(&lt;span style="color:#cc0000;"&gt;'http://www.google.com/'&lt;/span&gt;);&lt;/code&gt;&lt;/pre&gt;The code is quite self-explaining. It creates a Twebst object and then opens a given URL in a new IE browser instance. What you get back from &lt;a href="http://www.codecentrix.com/help/HTML/LnkStartBrowser.htm" target="_blank"&gt;StartBrowser&lt;/a&gt; call is a &lt;a href="http://www.codecentrix.com/help/HTML/LnkBrowser.htm" target="_blank"&gt;Browser&lt;/a&gt; object that can be used to further &lt;strong&gt;automate Internet Explorer&lt;/strong&gt;.&lt;br /&gt;&lt;div align="justify"&gt; &lt;/div&gt;&lt;br /&gt;What can you do with a browser object? Quite a lot of things: navigate to a URL, find HTML elements and frames inside it, close the browser, get information about the browser, &lt;strong&gt;automate modal and modeless HTML dialgos&lt;/strong&gt; and wait to complete navigation and loading.&lt;br /&gt;&lt;div align="justify"&gt; &lt;/div&gt;&lt;br /&gt;&lt;div align="justify"&gt;&lt;/div&gt;That's all for now, but these feature will be covered in next tutorials!&lt;br /&gt;&lt;br /&gt;&lt;div align="center"&gt;&lt;span style="font-size:180%;"&gt;&lt;a target="_blank" href="http://www.codecentrix.com/download.html"&gt;Get Twebst Automation Studio Free Edition&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-size:85%;"&gt;(Automation Library and Macro Recorder for Internet Explorer)&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-909474389949263731?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/909474389949263731/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=909474389949263731' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/909474389949263731'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/909474389949263731'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2009/12/ie8-automation-how-to-programatically.html' title='IE8 automation: How to programatically open an URL - Tutorial (2)'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-552773835496237868</id><published>2009-11-08T17:45:00.000-08:00</published><updated>2009-11-12T09:13:30.335-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='internet explorer automation'/><category scheme='http://www.blogger.com/atom/ns#' term='web macro'/><category scheme='http://www.blogger.com/atom/ns#' term='IWebBrowser2'/><category scheme='http://www.blogger.com/atom/ns#' term='web recorder'/><category scheme='http://www.blogger.com/atom/ns#' term='IHTMLDocument2'/><title type='text'>Automate HTML File Upload Control - Tutorial (1)</title><content type='html'>If you ever tried to programatically change the value of a &lt;span style="FONT-WEIGHT: bold"&gt;HTML File Upload Control&lt;/span&gt; you probably noticed that &lt;span style="FONT-WEIGHT: bold"&gt;&amp;lt;input type="file" /&amp;gt;&lt;/span&gt; element is read-only! This happens for good security reasons: web pages scripts should not be able to upload random files without user consent. Unfortunatelly the control is read-only for browser extensions and add-ons too (BHO, toolbars, side bars, etc).&lt;br /&gt;&lt;br /&gt;For &lt;strong&gt;IE6&lt;/strong&gt; and &lt;strong&gt;IE7&lt;/strong&gt; the upload control may be automated by setting the focus to "Internet &lt;em&gt;Explorer_Server&lt;/em&gt;" window and generating Win32 keyboard events. For &lt;strong&gt;IE8&lt;/strong&gt;, the upload control is read-only, the user can only set a value by pressing "Browse" button and choosing a file.&lt;br /&gt;&lt;br /&gt;With &lt;a href="http://www.codecentrix.com/" target="_blank"&gt;Twebst Automation Studio&lt;/a&gt;, automating HTML File Upload Control can't be easier. Here's a short VBScript sample of doing it:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;Option Explicit&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;Dim&lt;/span&gt; core&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;Dim&lt;/span&gt; browser&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;Set&lt;/span&gt; core = CreateObject(&lt;span style="color:#cc0000;"&gt;"Twebst.Core"&lt;/span&gt;)&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;Set&lt;/span&gt; browser = core.StartBrowser(&lt;span style="color:#cc0000;"&gt;"http://www.2shared.com/"&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;Call&lt;/span&gt; browser.FindElement(&lt;span style="color:#cc0000;"&gt;"input file"&lt;/span&gt;, &lt;span style="color:#cc0000;"&gt;"id=upField"&lt;/span&gt;).InputText(&lt;span style="color:#cc0000;"&gt;"C:\somepath\photo1.jpg"&lt;/span&gt;)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div align="center"&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;&lt;a href="http://www.codecentrix.com/download.html" target="_blank"&gt;Get Twebst Automation Studio Free Edition!&lt;/a&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/div&gt;&lt;div align="center"&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/div&gt;&lt;div align="center"&gt;&lt;span style="font-size:130%;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-552773835496237868?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/552773835496237868/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=552773835496237868' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/552773835496237868'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/552773835496237868'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2009/11/automate-html-file-upload-control.html' title='Automate HTML File Upload Control - Tutorial (1)'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-6947031825577179214</id><published>2009-11-03T09:19:00.000-08:00</published><updated>2009-11-03T09:46:13.321-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='internet explorer automation'/><category scheme='http://www.blogger.com/atom/ns#' term='web macro'/><category scheme='http://www.blogger.com/atom/ns#' term='web recorder'/><title type='text'>New Web Macro Recorder released!</title><content type='html'>&lt;p&gt;After several months of complete radio silence, things have been moving forward for &lt;em&gt;Twebst Library&lt;/em&gt; which turned into a more powerful and mature product.&lt;br /&gt;Please welcome &lt;strong&gt;&lt;a href="http://www.codecentrix.com/" target="_blank"&gt;Twebst Web Automation Studio&lt;/a&gt;&lt;/strong&gt;!&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Twebst Automation Studio&lt;/em&gt; is an advanced &lt;strong&gt;web automation framework&lt;/strong&gt; for &lt;em&gt;Internet Explorer&lt;/em&gt; that can be used within any environment that supports COM, from scripting languages (&lt;strong&gt;JScript&lt;/strong&gt;, &lt;strong&gt;VBScript&lt;/strong&gt;) to high level programming languages (&lt;strong&gt;C#,&lt;/strong&gt; &lt;strong&gt;VB.Net&lt;/strong&gt;, &lt;strong&gt;C++&lt;/strong&gt;).&lt;br /&gt;&lt;br /&gt;The framework includes two components: &lt;strong&gt;Twebst Web Recorder&lt;/strong&gt; that automatically generates most of the automation code and &lt;strong&gt;Twebst Library&lt;/strong&gt; which is a collection of programable objects that creates a &lt;strong&gt;web automation API&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;But one image is better than thousand words... &lt;/p&gt;&lt;p&gt;&lt;a title="Twebst Automation Studio - Web Macro Recorder" href="http://4.bp.blogspot.com/_b7z9mi4EOXE/SvBpj4KOIcI/AAAAAAAAA1c/pLnwEXiAB0k/s1600-h/webrecorder.png"&gt;&lt;img style="WIDTH: 400px; HEIGHT: 332px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5399932018308817346" border="0" alt="Web Macro Recorder in Action" src="http://4.bp.blogspot.com/_b7z9mi4EOXE/SvBpj4KOIcI/AAAAAAAAA1c/pLnwEXiAB0k/s400/webrecorder.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;p&gt;&lt;strong&gt;Twebst Web Recorder&lt;/strong&gt; features:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Easily create web macros through an intuitive graphical interface.&lt;/li&gt;&lt;li&gt;Generate web automation code using the language of your choice: JScript, VBScript, C#, VB.Net, C++&lt;/li&gt;&lt;li&gt;Record web actions on all HTML controls (button, combo-box, list-box, edit-box) &lt;/li&gt;&lt;/ul&gt;&lt;div align="center"&gt;And one more thing: &lt;strong&gt;FREE&lt;/strong&gt; version available!&lt;/div&gt;&lt;div align="center"&gt;&lt;a href="http://www.codecentrix.com/download.html" target="_blank"&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Download Twebst Automation Studio&lt;/strong&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;div align="center"&gt;&lt;/div&gt;&lt;div align="center"&gt;&lt;/div&gt;&lt;div align="center"&gt;&lt;/div&gt;&lt;div align="center"&gt; &lt;/div&gt;&lt;div align="center"&gt; &lt;/div&gt;&lt;div align="center"&gt; &lt;/div&gt;&lt;div align="center"&gt;.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-6947031825577179214?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/6947031825577179214/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=6947031825577179214' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/6947031825577179214'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/6947031825577179214'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2009/11/new-web-macro-recorder-released.html' title='New Web Macro Recorder released!'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_b7z9mi4EOXE/SvBpj4KOIcI/AAAAAAAAA1c/pLnwEXiAB0k/s72-c/webrecorder.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-3521843954332674424</id><published>2009-05-26T20:05:00.000-07:00</published><updated>2009-06-02T12:15:46.858-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='COM'/><category scheme='http://www.blogger.com/atom/ns#' term='Internet Explorer'/><category scheme='http://www.blogger.com/atom/ns#' term='automation'/><category scheme='http://www.blogger.com/atom/ns#' term='IHTMLElementCollection'/><category scheme='http://www.blogger.com/atom/ns#' term='macro'/><category scheme='http://www.blogger.com/atom/ns#' term='IHTMLElement'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML'/><title type='text'>Web Data Extraction with C++ Web Macro</title><content type='html'>Web data extraction or &lt;a href="http://en.wikipedia.org/wiki/Web_scraping" target="_blank"&gt;web scraping&lt;/a&gt; can be implemented in various ways. Today I will use &lt;a href="http://www.codecentrix.com/download.html" target="_blank"&gt;Twebst Web Automation Library&lt;/a&gt; to extract search results from Google using DOM parsing method and &lt;em&gt;Internet Explorer&lt;/em&gt; automation (you need to install Twebst Library first).&lt;br /&gt;&lt;br /&gt;Here are the steps that C++ web macro will perform in order to extract results from Google search: &lt;ul&gt;&lt;li&gt;Open an &lt;em&gt;Internet Explorer&lt;/em&gt; browser and navigate to Google site.&lt;/li&gt;&lt;li&gt;Find the search edit box and fill out the word to search.&lt;/li&gt;&lt;li&gt;Find the submit button and click it.&lt;/li&gt;&lt;li&gt;Wait until the page is loaded and find a DIV with &lt;em&gt;id=res&lt;/em&gt;&lt;/li&gt;&lt;li&gt;Find the collection of all H3 elements inside the DIV element.&lt;/li&gt;&lt;li&gt;Extract the text and URL and display it.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Enough talk! Let the code speak for itself.&lt;/p&gt;&lt;code&gt;&lt;span style="color:#008000;"&gt;// Start a new Internet Explorer instance and navigate to a given URL.&lt;/span&gt;&lt;br /&gt;IBrowserPtr pBrowser = pCore-&amp;gt;StartBrowser(&lt;span style="color:#ff0000;"&gt;"http://www.google.com/"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#008000;"&gt;// Find search edit box in page and type some text into it.&lt;br /&gt;&lt;/span&gt;IElementPtr pSearchEdit = pBrowser-&amp;gt;FindElement(&lt;span style="color:#ff0000;"&gt;"input text"&lt;/span&gt;, SearchCondition(&lt;span style="color:#ff0000;"&gt;"name=q"&lt;/span&gt;));&lt;br /&gt;pSearchEdit-&amp;gt;InputText(&lt;span style="color:#ff0000;"&gt;"codecentrix"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#008000;"&gt;// Find search button and click it.&lt;br /&gt;&lt;/span&gt;IElementPtr pSearchBtn = pBrowser-&amp;gt;FindElement(&lt;span style="color:#ff0000;"&gt;"input submit"&lt;/span&gt;, SearchCondition(&lt;span style="color:#ff0000;"&gt;"text=Google Search"&lt;/span&gt;));&lt;br /&gt;pSearchBtn-&amp;gt;Click();&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#008000;"&gt;// Find the DIV element where the result are displayed.&lt;br /&gt;&lt;/span&gt;IElementPtr pResultDiv = pBrowser-&amp;gt;FindElement(&lt;span style="color:#ff0000;"&gt;"div"&lt;/span&gt;, SearchCondition(&lt;span style="color:#ff0000;"&gt;"id=res"&lt;/span&gt;));&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#008000;"&gt;// Get all found results and print them in console.&lt;br /&gt;&lt;/span&gt;IElementListPtr pResultList = pResultDiv-&amp;gt;FindAllElements(&lt;span style="color:#ff0000;"&gt;"h3"&lt;/span&gt;, SearchCondition());&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#008000;"&gt;// Display only the header result (text and url).&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; i = 0; i &amp;lt; pResultList-&amp;gt;length; ++i)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#008000;"&gt;// Get current H3 in the list.&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IElementPtr pCrntResult = pResultList-&amp;gt;Getitem(i);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#008000;"&gt;// Find first and only anchor inside H3&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IElementPtr pCrntAnchor = pCrntResult-&amp;gt;FindElement(&lt;span style="color:#ff0000;"&gt;"a"&lt;/span&gt;, SearchCondition());&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CComQIPtr&amp;lt;IHTMLAnchorElement&amp;gt; spCrntAnchor = pCrntAnchor-&amp;gt;nativeElement;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#008000;"&gt;// Get URL from IHTMLAnchorElement.&lt;br /&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CComBSTR bstrURL = &lt;span style="color:#ff0000;"&gt;""&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;spCrntAnchor-&amp;gt;get_href(&amp;amp;bstrURL);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#008000;"&gt;// Display results.&lt;br /&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;wcout &amp;lt;&amp;lt; pCrntResult-&amp;gt;text &amp;lt;&amp;lt; L&lt;span style="color:#ff0000;"&gt;"\n"&lt;/span&gt; &amp;lt;&amp;lt; bstrURL.m_str &amp;lt;&amp;lt; L&lt;span style="color:#ff0000;"&gt;"\n\n"&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Download:&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.codecentrix.com/blog/cppmacro/CppMacro.zip" target="_blank"&gt;CppMacro.zip&lt;/a&gt; (full source code and exe)&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codecentrix.com/download.html" target="_blank"&gt;Twebst Web Automation Library&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-3521843954332674424?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/3521843954332674424/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=3521843954332674424' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/3521843954332674424'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/3521843954332674424'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2009/02/web-data-extraction-with-c-web-macro.html' title='Web Data Extraction with C++ Web Macro'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-8135893866376860713</id><published>2009-05-19T21:03:00.000-07:00</published><updated>2009-06-02T12:16:19.350-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='js'/><category scheme='http://www.blogger.com/atom/ns#' term='jscript'/><category scheme='http://www.blogger.com/atom/ns#' term='Internet Explorer'/><category scheme='http://www.blogger.com/atom/ns#' term='WSH'/><category scheme='http://www.blogger.com/atom/ns#' term='automation'/><category scheme='http://www.blogger.com/atom/ns#' term='macro'/><category scheme='http://www.blogger.com/atom/ns#' term='script'/><title type='text'>IE Web Login Automation</title><content type='html'>One highly repetitive web task is the logon to a web site. This is a common scenario where &lt;a href="http://www.codecentrix.com/twebst.html" target="_blank"&gt;Twebst Web Automation Library&lt;/a&gt; really shines. Here is a short &lt;strong&gt;web macro&lt;/strong&gt; written in JScript language that automatically logs you on Yahoo Mail site. All you have to do is to replace "UUUUUUUUUU" and "PPPPPPPPPP" with your user name and password in the code below.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;span style="color:#009900;"&gt;// Open a browser and navigate to yahoo mail login page.&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;var&lt;/span&gt; core = &lt;span style="color:#3333ff;"&gt;new&lt;/span&gt; ActiveXObject(&lt;span style="color:#cc0000;"&gt;"Twebst.Core"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;var&lt;/span&gt; browser = core.StartBrowser(&lt;span style="color:#cc0000;"&gt;"https://login.yahoo.com/config/mail?.intl=us"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#009900;"&gt;// Find login fields.&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;var&lt;/span&gt; u = browser.FindElement(&lt;span style="color:#cc0000;"&gt;"input text"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;var&lt;/span&gt; p = browser.FindElement(&lt;span style="color:#cc0000;"&gt;"input password"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;var&lt;/span&gt; s = browser.FindElement(&lt;span style="color:#cc0000;"&gt;"input submit"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#009900;"&gt;// Log on to site by filling the user-name and password fileds and then click submit boutton.&lt;/span&gt;&lt;br /&gt;u.InputText(&lt;span style="color:#cc0000;"&gt;"UUUUUUUUUU"&lt;/span&gt;);&lt;br /&gt;p.InputText(&lt;span style="color:#cc0000;"&gt;"PPPPPPPPPP"&lt;/span&gt;);&lt;br /&gt;s.Click();&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;strong&gt;FindElement&lt;/strong&gt; searches thru all frames/iframes hierarchy for the first input element of type text/password/submit. Additional conditions can be specified for search (like searching an element by id/name or any other HTML attribute). Search conditions can make use of &lt;strong&gt;regular expressions&lt;/strong&gt; if needed.&lt;br /&gt;&lt;br /&gt;One more important thing is that &lt;strong&gt;FindElement&lt;/strong&gt; method waits for the web page to be completely loaded before searching the element (the timeout can be specified by using &lt;strong&gt;core.loadTimeout&lt;/strong&gt; property). &lt;a href="http://www.codecentrix.com/help/HTML/HelpIndex.htm" target="_blank"&gt;Read more about Twebst Library...&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Download:&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.codecentrix.com/download.html" target="_blank"&gt;Twebst Library Pro&lt;/a&gt; (it must be installed for the macro to work).&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.codecentrix.com/blog/logonyahoo/YahooMail.zip" target="_blank"&gt;YahooMail.js&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.codecentrix.com/scripts.html" target="_blank"&gt;Script Of The Day&lt;/a&gt; system if you want to easily install more login templates.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-8135893866376860713?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/8135893866376860713/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=8135893866376860713' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/8135893866376860713'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/8135893866376860713'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2009/05/ie-web-login-automation.html' title='IE Web Login Automation'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-6118223982348264312</id><published>2009-05-18T20:05:00.000-07:00</published><updated>2009-05-23T08:24:23.552-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Internet Explorer'/><category scheme='http://www.blogger.com/atom/ns#' term='automation'/><category scheme='http://www.blogger.com/atom/ns#' term='macro'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML'/><category scheme='http://www.blogger.com/atom/ns#' term='script'/><title type='text'>Twebst Web Automation Library v1.40 released</title><content type='html'>Twebst version 1.40 is launched!&lt;br /&gt;Main changes include IE8 compatibility, better support for working with embeded IE browser control, support for modal and modeless HTML dialogs and functions for clipboard access.&lt;br /&gt;&lt;br /&gt;Here is the list of new features and enhancements:&lt;br /&gt;- NEW: IE8 is now supported&lt;br /&gt;- ENH: core.AttachToNative* methods work now with hosted IE browser control&lt;br /&gt;- BUG: various fixes&lt;br /&gt;- NEW: core.foregroundBrowser property&lt;br /&gt;- NEW: core.productName property&lt;br /&gt;- NEW: core.productVersion property&lt;br /&gt;- NEW: core.GetClipboardText method&lt;br /&gt;- NEW: core.SetClipboardText method&lt;br /&gt;- NEW: core.AttachToWnd method&lt;br /&gt;- NEW: core.NativeWindowToNativeBrowser method&lt;br /&gt;- NEW: core.NativeWindowToNativeDocument method&lt;br /&gt;- NEW: core.NativeWindowToNativeDocument&lt;br /&gt;- NEW: browser.FindModalHtmlDialog method&lt;br /&gt;- NEW: browser.FindModelessHtmlDialog method&lt;br /&gt;- NEW: element.GetAttribute method&lt;br /&gt;- NEW: element.SetAttribute method&lt;br /&gt;- NEW: element.RemoveAttribute method&lt;br /&gt;- NEW: element.tagName property&lt;br /&gt;- NEW: element.FindParentElement method&lt;br /&gt;- NEW: core.RightClick method-&lt;br /&gt;- &lt;a href="http://www.codecentrix.com/help/HTML/HelpIndex.htm" target="_blank"&gt;&lt;span style="font-size:130%;"&gt;Find more ...&lt;/span&gt;&lt;br /&gt;&lt;/a&gt;&lt;div align="center"&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;strong&gt;Free Download&lt;/strong&gt; &lt;/span&gt;&lt;a href="http://www.codecentrix.com/" target="_blank"&gt;&lt;strong&gt;&lt;span style="font-size:180%;"&gt;Twebst Library 1.40&lt;/span&gt;&lt;/strong&gt;&lt;/a&gt;&lt;span style="font-size:130%;"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div align="center"&gt;&lt;span style="font-size:130%;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div align="center"&gt;&lt;span style="font-size:130%;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-6118223982348264312?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/6118223982348264312/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=6118223982348264312' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/6118223982348264312'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/6118223982348264312'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2009/05/twebst-web-automation-library-v140.html' title='Twebst Web Automation Library v1.40 released'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-2332199532573996718</id><published>2009-04-29T11:15:00.000-07:00</published><updated>2009-06-02T12:16:04.828-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='js'/><category scheme='http://www.blogger.com/atom/ns#' term='jscript'/><category scheme='http://www.blogger.com/atom/ns#' term='help'/><category scheme='http://www.blogger.com/atom/ns#' term='WSH'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML'/><category scheme='http://www.blogger.com/atom/ns#' term='script'/><category scheme='http://www.blogger.com/atom/ns#' term='automate'/><title type='text'>Homemade Handcrafted Help System</title><content type='html'>&lt;div style="TEXT-ALIGN: justify"&gt;A good documentation is very important for any serious project. It comes a moment in life, when programmers find themselves working on the help system. That is what happened to me during the later stages of &lt;a href="http://www.codecentrix.com/" target="_blank"&gt;Twebst Web Automation Library&lt;/a&gt; project. Even though this project is not open source, I try to make public as many parts of it as possible. Today I will present &lt;a href="http://www.codecentrix.com/help/HTML/HelpIndex.htm" target="_blank"&gt;Twebst Help System&lt;/a&gt; and how this tedious and annoying task of creating it, was automated.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="TEXT-ALIGN: justify"&gt;Twebst is a library of COM objects used to automate &lt;span style="FONT-STYLE: italic"&gt;Internet Explorer&lt;/span&gt; browser. The objects and the supported properties and methods have to be documented . The page structure is the same for every object/method/property and it also contains code samples that need syntax highlighting. This is good news because it leaves a lot of place for templates and automation.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Here is the solution:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The template is an XML document. When documenting an object/method or property the focus is on the content rather than on formatting the text. There is one XML file for each object/method/property.&lt;/li&gt;&lt;li&gt;A &lt;a href="http://en.wikipedia.org/wiki/WSH" target="_blank"&gt;WSH&lt;/a&gt; script written in jscript parses the XML document and adds syntax highlighting to sample code in the documentation page. Regular expression are used for parsing.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;cross references are added automatically by the same script.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;then a &lt;a href="http://en.wikipedia.org/wiki/Xsl" target="_blank"&gt;XSL&lt;/a&gt; transformation is applied to convert XML source to a HTML document that will be eventually written to disk.&lt;/li&gt;&lt;li&gt;The whole process is optimized by removing unnecessary operations like generating the HTML when it already exists and is newer than its XML source.&lt;/li&gt;&lt;li&gt;Finally the HTML documents refers a CSS style sheet to easily change the look.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;It goes like this:&lt;br /&gt;XML + JScript-&gt; XML with &lt;span style="FONT-STYLE: italic"&gt;color syntax &lt;/span&gt;and &lt;span style="FONT-STYLE: italic"&gt;cross references &lt;/span&gt;+ XSL -&gt; HTML + CSS -&gt; CHM&lt;br /&gt;&lt;br /&gt;For local help, the CHM compiler is invoked as a final step and a &lt;a href="http://www.codecentrix.com/files/Twebst.chm" target="_blank"&gt;CHM Help File&lt;/a&gt; is generated. All you have to do is launching &lt;strong&gt;Build.js&lt;/strong&gt; script you may find in the archive below.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Downloads: &lt;/span&gt;&lt;/strong&gt;&lt;a href="http://www.codecentrix.com/blog/hhlpsys/TwebstHelp.zip"&gt;TwebstHelp.zip&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;: &lt;/span&gt;In order to build the CHM file you'll need &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=00535334-c8a6-452f-9aa0-d597d16580cc&amp;amp;displaylang=en" target="_blank"&gt;HTML Help Workshop&lt;/a&gt; from Microsoft.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-2332199532573996718?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/2332199532573996718/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=2332199532573996718' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/2332199532573996718'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/2332199532573996718'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2009/04/homemade-handcrafted-help-system.html' title='Homemade Handcrafted Help System'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-6390674870508615254</id><published>2009-03-18T11:18:00.000-07:00</published><updated>2009-06-02T12:19:48.686-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MSI'/><category scheme='http://www.blogger.com/atom/ns#' term='macro'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><title type='text'>SQL CE 3.5 SP1 and MSVCR80</title><content type='html'>I am involved in &lt;a href="http://www.deskperience.com/web-replay-password-manager/web-replay.html"&gt;Web Replay&lt;/a&gt; (the best password manager on the market) development from its inception. Recently, we have upgraded SQL CE engine to the latest 3.5 SP1 version. Web Replay is built against Visual C++ runtime version 9 which is deployed by including &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=9b2da534-3e03-4391-8a4d-074b9f2bc1bf&amp;amp;displaylang=en"&gt;Microsoft Visual C++ 2008 Redistributable Package (x86)&lt;/a&gt; in the setup. But that was not enough because &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=DC614AEE-7E1C-4881-9C32-3A6CE53384D9&amp;amp;displaylang=en"&gt;Microsoft SQL CE 3.5 SP1&lt;/a&gt; depends on Visual C++ runtime version 8.0 which is NOT included in the redistributable kit!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If you encounter this problem you have no option but to include vc2005 redist in your setup. You could think that giving up the upgrade to 3.5 version and continuing using SQL CE 3.1 is an option. Well, it isn't! SQL CE 3.1 is crashing randomly on Windows XP SP3 (even &lt;em&gt;Microsoft SQL Server Management Studio &lt;/em&gt;is reporting some memory corruption error before completely freezing).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-6390674870508615254?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/6390674870508615254/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=6390674870508615254' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/6390674870508615254'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/6390674870508615254'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2009/04/sql-ce-35-sp1-and-msvcr80.html' title='SQL CE 3.5 SP1 and MSVCR80'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-2243655780721180890</id><published>2009-02-20T06:43:00.000-08:00</published><updated>2009-06-02T12:19:59.308-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>RegisterHotKey in C#</title><content type='html'>I like .Net framework for its huge class library covering almost anything you'll ever need. One thing I could not find was registering a windows hot-key in C#. It seems the framework does not provide a solution for system-wide hot keys. So I had to use the good old &lt;a href="http://msdn.microsoft.com/en-us/library/ms646309%28VS.85%29.aspx"&gt;RegisterHotKey&lt;/a&gt; Win32 function.&lt;br /&gt;&lt;br /&gt;To call it from C#, you need to use &lt;span style="font-weight: bold;"&gt;P/Invoke&lt;/span&gt; service to invoke the unmanaged function residing in &lt;span style="font-weight: bold;"&gt;user32.dll&lt;/span&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;using System.Runtime.InteropServices;&lt;br /&gt;&lt;br /&gt;[DllImport("user32.dll")]&lt;br /&gt;private static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vk);&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;The hWnd parameter is the handle of a form that will receive &lt;span style="font-weight: bold;"&gt;WM_HOTKEY&lt;/span&gt; message. To get the handle of a &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.form.aspx"&gt;Form&lt;/a&gt; simply use &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.control.handle.aspx"&gt;Handle&lt;/a&gt; property. In order to process &lt;span style="font-weight: bold;"&gt;WM_HOTKEY&lt;/span&gt; message, your form needs to override &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.control.wndproc.aspx"&gt;WndProc&lt;/a&gt; method.&lt;br /&gt;&lt;br /&gt;Just one more thing you should know: &lt;span style="font-weight: bold;"&gt;RegisterHotKey&lt;/span&gt; and &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.form.showintaskbar.aspx"&gt;ShowInTaskBar&lt;/a&gt; property don't mix well. It seems that a new window is created each time &lt;span style="font-weight: bold;"&gt;ShowInTaskBar&lt;/span&gt; property is called so your WndProc mehod will stop recieving hot-keys. You need to &lt;span style="font-weight: bold;"&gt;RegisterHotKey &lt;/span&gt;again because &lt;span style="font-weight: bold;"&gt;Handle&lt;/span&gt; property returns a new window handle after &lt;span style="font-weight: bold;"&gt;ShowInTaskBar&lt;/span&gt; was called.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-2243655780721180890?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/2243655780721180890/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=2243655780721180890' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/2243655780721180890'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/2243655780721180890'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2009/03/registerhotkey-in-c.html' title='RegisterHotKey in C#'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-3287733562084739461</id><published>2009-01-05T02:37:00.000-08:00</published><updated>2009-06-02T12:20:18.527-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jscript'/><category scheme='http://www.blogger.com/atom/ns#' term='ATL'/><category scheme='http://www.blogger.com/atom/ns#' term='IE'/><category scheme='http://www.blogger.com/atom/ns#' term='WSH'/><category scheme='http://www.blogger.com/atom/ns#' term='automation'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>WSH and clipboard access</title><content type='html'>I did some &lt;a target="_blank" href="http://en.wikipedia.org/wiki/Windows_Script_Host"&gt;Windows Script Host&lt;/a&gt; programming recently and I was pleasantly surprised by its power, features and flexibility. One thing that I couldn't accomplish was accessing the clipboard from &lt;span style="font-weight: bold;"&gt;WSH&lt;/span&gt;. Digging the internet I found some solutions like &lt;a target="_blank" href="http://www.nilpo.com/2007/08/windows-xp/scripting-the-clipboard-contents-in-wsh/"&gt;this one&lt;/a&gt; based on &lt;span style="font-style: italic;"&gt;Internet Explorer Automation&lt;/span&gt;. There are several problems with this approach as you can read in my article about &lt;span style="font-style: italic;"&gt;Internet Explorer Automation&lt;/span&gt;: &lt;a target="_blank" href="http://codecentrix.blogspot.com/2008/12/whats-wrong-with-internet-explorer.html"&gt;What's wrong with Internet Explorer Automation?&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;My solution for scripting the clipboard content in &lt;span style="font-weight: bold;"&gt;WSH&lt;/span&gt; is a regular &lt;span style="font-weight: bold;"&gt;COM&lt;/span&gt; object created with &lt;span style="font-weight: bold;"&gt;VC++&lt;/span&gt; and &lt;span style="font-weight: bold;"&gt;ATL&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Download full source code and compiled DLL: &lt;a href="http://www.codecentrix.com/blog/wshclip/WSH_clipboard.zip"&gt;WSH_clipboard.zip&lt;/a&gt;&lt;br /&gt;To install the COM object run &lt;span style="font-weight: bold;"&gt;register.bat&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I found scripting the clipboard useful enough to add this feature to the next release of &lt;a target="_blank" href="http://www.codecentrix.com/"&gt;Twebst Web Automation Library&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-3287733562084739461?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/3287733562084739461/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=3287733562084739461' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/3287733562084739461'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/3287733562084739461'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2009/01/wsh-and-clipboard-access.html' title='WSH and clipboard access'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-1934668164836997486</id><published>2008-12-15T19:09:00.000-08:00</published><updated>2008-12-20T06:23:49.836-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='COM'/><category scheme='http://www.blogger.com/atom/ns#' term='Internet Explorer'/><category scheme='http://www.blogger.com/atom/ns#' term='IE'/><category scheme='http://www.blogger.com/atom/ns#' term='automation'/><category scheme='http://www.blogger.com/atom/ns#' term='IE7'/><category scheme='http://www.blogger.com/atom/ns#' term='macro'/><title type='text'>Free Web Macros for Internet Explorer</title><content type='html'>As I presented in my &lt;a href="http://codecentrix.blogspot.com/2008/12/whats-wrong-with-internet-explorer.html"&gt;previous post&lt;/a&gt;, automating &lt;span style="font-style: italic;"&gt;Internet Explorer&lt;/span&gt; can be a difficult task.&lt;br /&gt;&lt;a target="_blank" href="http://codecentrix.com/download.html"&gt;Twebst Web Automation Library&lt;/a&gt; can make things easier. &lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;It gives full programmatic control over the &lt;span style="font-style: italic;"&gt;Internet Explorer&lt;/span&gt; browser. Twebst is a library of &lt;span style="font-weight: bold;"&gt;COM&lt;/span&gt; object that can be used within any environment that supports &lt;span style="font-weight: bold;"&gt;COM&lt;/span&gt;, from scripting languages (&lt;span style="font-weight: bold;"&gt;JScript&lt;/span&gt;, &lt;span style="font-weight: bold;"&gt;VB Script&lt;/span&gt;) to high level programming languages (&lt;span style="font-weight: bold;"&gt;C#&lt;/span&gt;, &lt;span style="font-weight: bold;"&gt;C++&lt;/span&gt;). For more information, see &lt;a target="_blank" href="http://codecentrix.com/help/HTML/HelpIndex.htm"&gt;Twebst Libray Online Documentation&lt;/a&gt;. And yes, it's free!&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;h2 style="text-align: center;"&gt;&lt;a target="_blank" title="Web Automation Library" href="http://www.codecentrix.com/download.html"&gt;Get it FREE!&lt;/a&gt;&lt;/h2&gt;&lt;h4&gt;What Twebst can do?&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;increase productivity by automating repetitive web tasks&lt;/li&gt;&lt;li&gt;automate regression testing of web applications&lt;/li&gt;&lt;li&gt;automate web actions and data-entry&lt;/li&gt;&lt;li&gt;automatically log in to different web sites&lt;/li&gt;&lt;li&gt;fill out web-forms automatically&lt;/li&gt;&lt;li&gt;extract data from web pages (web scraping).&lt;/li&gt;&lt;li&gt;monitor web pages&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;Twebst features&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;Start new browsers and navigate to a specified URL.&lt;/li&gt;&lt;li&gt;Connect to existing browsers.&lt;/li&gt;&lt;li&gt;Search and access HTML elements and frames inside browsers.&lt;/li&gt;&lt;li&gt;Intuitive names for HTML elements using the text that appears on the screen.&lt;/li&gt;&lt;li&gt;Advanced search of browsers and HTML elements using regular expressions.&lt;/li&gt;&lt;li&gt;Perform actions on all HTML controls (button, combo-box, list-box, edit-box etc).&lt;/li&gt;&lt;li&gt;Simulates user behavior generating hardware or browser events.&lt;/li&gt;&lt;li&gt;Get access to native interfaces exposed by Internet Explorer so you don't need to learn new things if you already know IE web programming.&lt;/li&gt;&lt;li&gt;Synchronize web actions and navigation by waiting the page to complete in a specified timeout.&lt;/li&gt;&lt;li&gt;Available from any programming or script language that supports COM&lt;/li&gt;&lt;li&gt;Optimized search methods and collections.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-1934668164836997486?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/1934668164836997486/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=1934668164836997486' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/1934668164836997486'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/1934668164836997486'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2008/12/web-macros-for-internet-explorer.html' title='Free Web Macros for Internet Explorer'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-6180404187156119223</id><published>2008-12-10T09:54:00.000-08:00</published><updated>2009-06-02T12:16:54.191-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='js'/><category scheme='http://www.blogger.com/atom/ns#' term='jscript'/><category scheme='http://www.blogger.com/atom/ns#' term='COM'/><category scheme='http://www.blogger.com/atom/ns#' term='IE'/><category scheme='http://www.blogger.com/atom/ns#' term='automation'/><category scheme='http://www.blogger.com/atom/ns#' term='IE7'/><category scheme='http://www.blogger.com/atom/ns#' term='macro'/><category scheme='http://www.blogger.com/atom/ns#' term='IHTMLElement'/><title type='text'>What's wrong with Internet Explorer Automation?</title><content type='html'>&lt;div style="text-align: justify;"&gt;The Microsoft Office products (Word, Excel, Power Point, Access, Outlook) allow their users to manipulate Office documents from Visual Basic or Visual Basic for Applications (VBA) code. It is possible to write a VBA macro in Excel that initializes a series of cells, and uses the cells to display a chart for instance.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;a href="http://en.wikipedia.org/wiki/OLE_Automation" target="_blank"&gt;Automation&lt;/a&gt; is the process of controlling one product from another product with the result that the client product can use the objects, methods, and properties of the server product. The client has access to the object model of the server.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Though Internet Explorer browser is not part of the Office suite, it supports automation. Here is a short sample:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// Create an IE automation object.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;var&lt;/span&gt; ie = new ActiveXObject("InternetExplorer.Application");&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// Make it visible and navigate to a given URL.&lt;/span&gt;&lt;br /&gt;ie.Visible = true;&lt;br /&gt;ie.Navigate(&lt;span style="color: rgb(255, 0, 0);"&gt;"&lt;a class="linkification-ext" href="http://www.google.com/" title="Linkification: http://www.google.com/"&gt;http://www.google.com/&lt;/a&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// Give it some time to load the page and then get the document.&lt;/span&gt;&lt;br /&gt;WScript.Sleep(3000);&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;var&lt;/span&gt; doc = ie.Document;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// Fill out search field.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;var&lt;/span&gt; edit = doc.getElementsByName(&lt;span style="color: rgb(255, 0, 0);"&gt;"q"&lt;/span&gt;).item(0);&lt;br /&gt;edit.value = "codecentrix";&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// ... and press the submit button.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;var&lt;/span&gt; submit = doc.getElementsByName(&lt;span style="color: rgb(255, 0, 0);"&gt;"btnG"&lt;/span&gt;).item(0);&lt;br /&gt;submit.click();&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Here is &lt;a href="http://www.codecentrix.com/blog/wrong_ie/ie_auto.js"&gt;ie_auto.js&lt;/a&gt; file for &lt;a href="http://www.codecentrix.com/blog/wrong_ie/ie_auto.js"&gt;download&lt;/a&gt;.&lt;br /&gt;However there are problems with Internet Explorer automation:&lt;br /&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;it may not work at all on &lt;span style="font-weight: bold;"&gt;Windows Vista&lt;/span&gt; unless the script is running at the same &lt;span style="font-weight: bold;"&gt;integrity level&lt;/span&gt; as &lt;span style="font-weight: bold;"&gt;iexplore.exe&lt;/span&gt; process. Simply clicking the js file won't do it. The script will run at &lt;span style="font-weight: bold;"&gt;medium integrity level&lt;/span&gt; and Internet Explorer has &lt;span style="font-weight: bold;"&gt;low integrity level&lt;/span&gt; and as result the script fails. If you run the script at &lt;span style="font-weight: bold;"&gt;high integrity level&lt;/span&gt; the newly started IE instance will have the same high integrity level and the script works (but this is not the best option from a security point of view). Changing the integrity level of the running script (or application) is not always the most desirable or easiest thing to do.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;no support to "connect" to already existing IE documents.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;sub-documents in different domains are not accessible for scripting due to cross scripting security issues (see my older posts: "&lt;a href="http://codecentrix.blogspot.com/2007/10/when-ihtmlwindow2getdocument-returns.html"&gt;When IHTMLWindow2::get_document returns E_ACCESSDENIED&lt;/a&gt;" and "&lt;a href="http://codecentrix.blogspot.com/2008/02/when-ihtmlwindow2document-throws.html"&gt;When IHTMLWindow2.document throws UnauthorizedAccessException&lt;/a&gt;").&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;difficult search of elements across all sub-documents inside &lt;span style="font-weight: bold;"&gt;frames&lt;/span&gt;/&lt;span style="font-weight: bold;"&gt;iframes&lt;/span&gt; (and sometimes impossible, see the point above).&lt;/li&gt;&lt;/ul&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;difficult and time consuming search of HTML elements on attributes other than id or name (&lt;span style="font-weight: bold;"&gt;getElementById&lt;/span&gt; and &lt;span style="font-weight: bold;"&gt;getElementsByName&lt;/span&gt; are the only methods I know that search elements directly wihtout browsing element collections which might be very slow when performed out of process).&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;no &lt;span style="font-weight: bold;"&gt;tab&lt;/span&gt; support (&lt;a href="http://blogs.msdn.com/tonyschr/archive/2007/01/19/ie-automation-amp-tabs.aspx" target="_blank"&gt;only launch a new tab&lt;/a&gt;).&lt;/li&gt;&lt;/ul&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;no direct support for synchronizing input actions (clicks, keys) with the HTML document loading (it could be implemented by registering to IE events like document complete or looping while the browser becomes ready to accept inputs).&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;no advanced search criteria like &lt;span style="font-weight: bold;"&gt;regular expression&lt;/span&gt; or searching on multiple attributes.&lt;/li&gt;&lt;/ul&gt;If you are interested in solving the issues above, let me introduce a project I've been working on for some time now. Here's &lt;a style="font-weight: bold;" href="http://www.codecentrix.com/download.html" target="_blank"&gt;Twebst&lt;/a&gt;, web automation library for &lt;span style="font-weight: bold;"&gt;Internet Explorer&lt;/span&gt;!&lt;br /&gt;&lt;br /&gt;&lt;h2 style="text-align: center;"&gt;&lt;a target="_blank" title="Web Automation Library" href="http://www.codecentrix.com/download.html"&gt;Get it FREE!&lt;/a&gt;&lt;/h2&gt;&lt;br /&gt;(&lt;span style="font-style: italic;"&gt;&lt;a href="http://codecentrix.blogspot.com/2008/12/web-macros-for-internet-explorer.html"&gt;to be continued&lt;/a&gt;&lt;/span&gt;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-6180404187156119223?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/6180404187156119223/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=6180404187156119223' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/6180404187156119223'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/6180404187156119223'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2008/12/whats-wrong-with-internet-explorer.html' title='What&apos;s wrong with Internet Explorer Automation?'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-7155820348681504282</id><published>2008-11-25T16:20:00.000-08:00</published><updated>2009-06-02T08:59:06.582-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='js'/><category scheme='http://www.blogger.com/atom/ns#' term='jscript'/><category scheme='http://www.blogger.com/atom/ns#' term='WSH'/><category scheme='http://www.blogger.com/atom/ns#' term='toolbar'/><title type='text'>Creating shortcuts to Quick Launch Toolbar with WSH</title><content type='html'>&lt;div&gt;I had this problem of creating shortcuts to &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Quick Launch Tollbar&lt;/span&gt; while working on&lt;a href="http://www.codecentrix.com/scripts.html"&gt; Script Of The Day&lt;/a&gt; application. This small product is almost entirely created using &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;JScript&lt;/span&gt; and &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Windows Scripting Host&lt;/span&gt; (&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;WSH&lt;/span&gt;).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;SpecialFolders&lt;/span&gt; method of &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;WScript.Shell&lt;/span&gt; object provides the full path for some special folders like &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Desktop&lt;/span&gt; and &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Favorites&lt;/span&gt; but the directory for &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Quick Launch Toolbar&lt;/span&gt; is not supported. To get it I used &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;%userprofile%&lt;/span&gt; env var like this:&lt;/div&gt;&lt;pre&gt;&lt;span class="Apple-style-span" style="color: rgb(51, 51, 255);"&gt;var&lt;/span&gt; shell          = WScript.CreateObject(&lt;span class="Apple-style-span" style="color: rgb(255, 0, 0);"&gt;"WScript.Shell"&lt;/span&gt;);&lt;br /&gt;&lt;span class="Apple-style-span" style="color: rgb(51, 51, 255);"&gt;var&lt;/span&gt; quickLaunchDir = shell.ExpandEnvironmentStrings(&lt;span class="Apple-style-span" style="color: rgb(255, 0, 0);"&gt;"%userprofile%"&lt;/span&gt;) +&lt;br /&gt;                     &lt;span class="Apple-style-span" style="color: rgb(255, 0, 0);"&gt;"\\Application Data\\Microsoft\\Internet Explorer\\Quick Launch"&lt;/span&gt;;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: rgb(51, 51, 255);"&gt;var&lt;/span&gt; oShellLink     = shell.CreateShortcut(quickLaunchDir + &lt;span class="Apple-style-span" style="color: rgb(255, 0, 0);"&gt;"\\Codecentrix.lnk"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;oShellLink.TargetPath   = &lt;span class="Apple-style-span" style="color: rgb(255, 0, 0);"&gt;"http://www.codecentrix.com/"&lt;/span&gt;;&lt;br /&gt;oShellLink.IconLocation = &lt;span class="Apple-style-span" style="color: rgb(255, 0, 0);"&gt;"http://www.codecentrix.com/favicon.ico"&lt;/span&gt;;&lt;br /&gt;oShellLink.WindowStyle  = 1;&lt;br /&gt;oShellLink.Description  = &lt;span class="Apple-style-span" style="color: rgb(255, 0, 0);"&gt;"Web Site"&lt;/span&gt;;&lt;br /&gt;oShellLink.Save();&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;Downloads:&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.codecentrix.com/blog/quicklaunch/QuickLaunch.js"&gt;QuickLaunch.js&lt;/a&gt; sample file&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a target="_blank" href="http://www.codecentrix.com/scripts.html"&gt;Script Of The Day&lt;/a&gt; application (&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;FREE&lt;/span&gt;)&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;a href="http://www.codeproject.com/script/Articles/BlogArticleList.aspx?amid=2505056" rel="tag" style="display:none"&gt; codeproject &lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-7155820348681504282?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/7155820348681504282/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=7155820348681504282' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/7155820348681504282'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/7155820348681504282'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2008/11/creating-shortcuts-to-quick-launch.html' title='Creating shortcuts to Quick Launch Toolbar with WSH'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-1137544621754955367</id><published>2008-08-09T10:18:00.000-07:00</published><updated>2009-06-02T08:59:12.651-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='js'/><category scheme='http://www.blogger.com/atom/ns#' term='jscript'/><category scheme='http://www.blogger.com/atom/ns#' term='IE'/><category scheme='http://www.blogger.com/atom/ns#' term='IE7'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML'/><category scheme='http://www.blogger.com/atom/ns#' term='script'/><category scheme='http://www.blogger.com/atom/ns#' term='automate'/><title type='text'>focus vs fireEvent("onfocus")</title><content type='html'>&lt;p&gt;While working on &lt;a href="http://www.codecentrix.com/"&gt;Twebst web automation library&lt;/a&gt; I encountered this problem: how to simulate setting the focus on HTML edit controls in Internet Explorer? There are two ways to do this.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Call &lt;a href="http://msdn.microsoft.com/en-us/library/aa703985(VS.85).aspx" target="_blank"&gt;IHTMLElement2::focus()&lt;/a&gt; method on target element that &amp;quot;causes the element to receive the focus and executes the code specified by the &lt;em&gt;onfocus&lt;/em&gt; event&amp;quot;. &lt;/li&gt;    &lt;li&gt;Rise &lt;em&gt;onfocus&lt;/em&gt; event on target element by calling &lt;a href="http://msdn.microsoft.com/en-us/library/aa703947(VS.85).aspx" target="_blank"&gt;IHTMLElement3::fireEvent()&lt;/a&gt; method. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;The two approaches are quite similar but there are some interesting differences.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;fireEvent(&amp;quot;&lt;em&gt;onfocus&lt;/em&gt;&amp;quot;) does not actually set the focus on the element, it just executes the code of the &lt;em&gt;onfocus&lt;/em&gt; handler event. &lt;/li&gt;    &lt;li&gt;Calling &lt;em&gt;focus&lt;/em&gt; method sets the focus on target element and call the &lt;em&gt;onfocus&lt;/em&gt; event handler but not immediately. The &lt;em&gt;onfocus&lt;/em&gt; event seems to be inserted in a queue and its handler is executed asynchronously after the current handler is finished. &lt;/li&gt;    &lt;li&gt;If &lt;em&gt;focus&lt;/em&gt; method is called from inside the &lt;em&gt;onfocus&lt;/em&gt; handler nothing happens if the control already has the focus (that prevents an infinite recursion). &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Example:&lt;/p&gt;  &lt;p&gt;&lt;code&gt;     &lt;br /&gt;&lt;font color="#0000ff"&gt;&amp;lt;html&amp;gt;&lt;/font&gt;      &lt;br /&gt;&lt;font color="#0000ff"&gt;&amp;lt;script&lt;/font&gt; type=&lt;font color="#ff0000"&gt;&amp;quot;text/javascript&amp;quot;&lt;/font&gt; language=&lt;font color="#ff0000"&gt;&amp;quot;javascript&amp;quot;&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;      &lt;br /&gt;&lt;font color="#0000ff"&gt;function&lt;/font&gt; BtnFocusClick()      &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; document.getElementById('editTest').focus();      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; window.status += &lt;font color="#ff0000"&gt;&amp;quot;b&amp;quot;&lt;/font&gt;;      &lt;br /&gt;}      &lt;br /&gt;      &lt;br /&gt;&lt;font color="#0000ff"&gt;function&lt;/font&gt; BtnOnFocusClick()      &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; document.getElementById('editTest').fireEvent('onfocus');      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; window.status += &lt;font color="#ff0000"&gt;&amp;quot;c&amp;quot;&lt;/font&gt;;      &lt;br /&gt;}      &lt;br /&gt;      &lt;br /&gt;&lt;font color="#0000ff"&gt;function&lt;/font&gt; EditOnFocus()      &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; window.status += &lt;font color="#ff0000"&gt;&amp;quot;a&amp;quot;&lt;/font&gt;;      &lt;br /&gt;}      &lt;br /&gt;&lt;font color="#0000ff"&gt;&amp;lt;/script&amp;gt;       &lt;br /&gt;&lt;/font&gt;      &lt;br /&gt;&lt;font color="#0000ff"&gt;&amp;lt;body&amp;gt;&lt;/font&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#0000ff"&gt;&amp;lt;input&lt;/font&gt; type=&lt;font color="#ff0000"&gt;&amp;quot;text&amp;quot;&lt;/font&gt; onfocus=&lt;font color="#ff0000"&gt;&amp;quot;EditOnFocus()&amp;quot;&lt;/font&gt;; id=&lt;font color="#ff0000"&gt;&amp;quot;editTest&amp;quot;&lt;/font&gt;&lt;font color="#0000ff"&gt;/&amp;gt;&amp;lt;br/&amp;gt;&lt;/font&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#0000ff"&gt;&amp;lt;input&lt;/font&gt; type=&lt;font color="#ff0000"&gt;&amp;quot;button&amp;quot;&lt;/font&gt; value=&lt;font color="#ff0000"&gt;&amp;quot;focus&amp;quot;&lt;/font&gt; id=&lt;font color="#ff0000"&gt;&amp;quot;btnFocus&amp;quot;&lt;/font&gt; onclick=&lt;font color="#ff0000"&gt;&amp;quot;BtnFocusClick();&amp;quot;&lt;/font&gt;&lt;font color="#0000ff"&gt;/&amp;gt;&lt;/font&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#0000ff"&gt;&amp;lt;input&lt;/font&gt; type=&lt;font color="#ff0000"&gt;&amp;quot;button&amp;quot;&lt;/font&gt; value=&lt;font color="#ff0000"&gt;&amp;quot;fire onfocus&amp;quot;&lt;/font&gt; id=&lt;font color="#ff0000"&gt;&amp;quot;btnOnFocus&amp;quot;&lt;/font&gt; onclick=&lt;font color="#ff0000"&gt;&amp;quot;BtnOnFocusClick();&amp;quot;&lt;/font&gt;&lt;font color="#0000ff"&gt;/&amp;gt;&lt;/font&gt;      &lt;br /&gt;&lt;font color="#0000ff"&gt;&amp;lt;/body&amp;gt;&lt;/font&gt;      &lt;br /&gt;&lt;font color="#0000ff"&gt;&amp;lt;/html&amp;gt;&lt;/font&gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;If pressing the button &amp;quot;&lt;em&gt;fire onfocus&lt;/em&gt;&amp;quot; button the message in the Internet Explorer status bar is the expected one &amp;quot;&lt;strong&gt;ac&lt;/strong&gt;&amp;quot;. If pressing the &amp;quot;&lt;em&gt;focus&lt;/em&gt;&amp;quot; button, the message is in reverse order than expected: &amp;quot;&lt;strong&gt;ba&lt;/strong&gt;&amp;quot;. That suggests that EditOnFocus handler is called &lt;strong&gt;after &lt;/strong&gt;BtnFocusClick exit.&lt;/p&gt;&lt;br /&gt;&lt;a href="http://www.codeproject.com/script/Articles/BlogArticleList.aspx?amid=2505056" rel="tag" style="display:none"&gt; codeproject &lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-1137544621754955367?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/1137544621754955367/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=1137544621754955367' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/1137544621754955367'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/1137544621754955367'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2008/08/focus-vs-fireevent.html' title='focus vs fireEvent(&amp;quot;onfocus&amp;quot;)'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-8827930078063444863</id><published>2008-06-19T02:22:00.000-07:00</published><updated>2009-06-03T01:38:27.517-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ATL'/><category scheme='http://www.blogger.com/atom/ns#' term='Internet Explorer'/><category scheme='http://www.blogger.com/atom/ns#' term='IE'/><category scheme='http://www.blogger.com/atom/ns#' term='IHTMLElementCollection'/><category scheme='http://www.blogger.com/atom/ns#' term='IE7'/><category scheme='http://www.blogger.com/atom/ns#' term='IHTMLDocument2'/><title type='text'>IHTMLDocument3::getElementsByTagName and IHTMLElementCollection</title><content type='html'>&lt;div&gt;A common task when writing Internet Explorer extensions is to browse a collection of objects based on a specified element tag-name. To work with collections IE provides &lt;a href="http://msdn.microsoft.com/en-us/library/aa703928%28VS.85%29.aspx"&gt;IHTMLElementCollection&lt;/a&gt; interface that represents a collection of elements in an HTML document.&lt;br /&gt;&lt;br /&gt;Usually a collection is retrieved by calling methods of &lt;a href="http://msdn.microsoft.com/en-us/library/aa752574%28VS.85%29.aspx"&gt;IHTMLDocument2&lt;/a&gt; interface. For some tag-names there specialized methods to retrieve collection (&lt;a href="http://msdn.microsoft.com/en-us/library/aa752583%28VS.85%29.aspx"&gt;IHTMLDocument2::get_anchors&lt;/a&gt; , &lt;a href="http://msdn.microsoft.com/en-us/library/aa752584%28VS.85%29.aspx"&gt;IHTMLDocument2::get_applets&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/en-us/library/aa752591%28VS.85%29.aspx"&gt;IHTMLDocument2::get_forms&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/en-us/library/aa752593%28VS.85%29.aspx"&gt;IHTMLDocument2::get_images&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/en-us/library/aa752595%28VS.85%29.aspx"&gt;IHTMLDocument2::get_links&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/en-us/library/aa752604%28VS.85%29.aspx"&gt;IHTMLDocument2::get_scripts&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;To get all elements collection there is &lt;a href="http://msdn.microsoft.com/en-us/library/aa752582%28VS.85%29.aspx"&gt;IHTMLDocument2::get_all.&lt;/a&gt;&lt;br /&gt;One way to get a collection of elements having a specified tag-name is:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// CComQIPt&amp;lt;IHTMLDocument2&amp;gt; spDocument is a document object.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;CComQIPtr&amp;lt;IHTMLElementCollection&amp;gt; spAllCollection;&lt;br /&gt;HRESULT hRes = spDocument-&gt;get_all(&amp;amp;spAllCollection);&lt;br /&gt;_ASSERTE(SUCCEDED(hRes) &amp;amp;&amp;amp; (spAllCollection != NULL));&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// Get the sub-collection of elements that have the "input" tag name.&lt;/span&gt;&lt;br /&gt;CComVariant varTagName(CComBSTR(&lt;span style="color: rgb(255, 0, 0);"&gt;"input"&lt;/span&gt;));&lt;br /&gt;CComQIPtr&amp;lt;IDispatch&amp;gt; spDispCollection;&lt;br /&gt;hRes = spAllCollection-&amp;gt;tags(varTagName, &amp;amp;spDispCollection);&lt;br /&gt;&lt;br /&gt;CComQIPtr&amp;lt;IHTMLElementCollection&amp;gt; spInputCollection = spDispCollection;&lt;br /&gt;_ASSERTE(spInputCollection != NULL);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// Now you can browse spInputCollection using&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// IHTMLElementCollection::item and IHTMLElementCollection::get_length methods.&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;The second method is:&lt;br /&gt;&lt;CODE&gt;&lt;PRE&gt;&lt;FONT COLOR="#008000"&gt;// CComQIPt&lt;IHTMLDocument2&gt; spDocument is a document object.&lt;/FONT&gt;&lt;br /&gt;&lt;FONT COLOR="#008000"&gt;// Query for IHTMLDocument3 interface&lt;/FONT&gt;&lt;br /&gt;CComQIPtr&amp;lt;IHTMLDocument3&amp;gt; spDoc3 = spDocument;&lt;br /&gt;_ASSERTE(spDoc3 != NULL);&lt;br /&gt;&lt;br /&gt;&lt;FONT COLOR="#008000"&gt;// Get the collection of elements that have the "input" tag name.&lt;/FONT&gt;&lt;br /&gt;CComQIPtr&amp;lt;IHTMLElementCollection&amp;gt spInputCollection;&lt;br /&gt;HRESULT hRes = spDoc3-&amp;gt;getElementsByTagName(CComBSTR(&lt;FONT COLOR="#ff0000"&gt;"input"&lt;/FONT&gt;), &amp;amp;spInputCollection);&lt;br /&gt;_ASSERTE(SUCCEDEED(hRes));&lt;br /&gt;&lt;br /&gt;&lt;FONT COLOR="#008000"&gt;// Now you can browse spInputCollection using&lt;/FONT&gt;&lt;br /&gt;&lt;FONT COLOR="#008000"&gt;// IHTMLElementCollection::item and IHTMLElementCollection::get_length methods.&lt;/FONT&gt;&lt;br /&gt;&lt;/PRE&gt;&lt;/CODE&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-8827930078063444863?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/8827930078063444863/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=8827930078063444863' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/8827930078063444863'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/8827930078063444863'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2008/04/ihtmldocument3getelementsbytagname-and.html' title='IHTMLDocument3::getElementsByTagName and IHTMLElementCollection'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-354893813203016407</id><published>2008-05-19T14:00:00.000-07:00</published><updated>2008-06-10T12:25:09.320-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ATL'/><category scheme='http://www.blogger.com/atom/ns#' term='IE'/><category scheme='http://www.blogger.com/atom/ns#' term='IE7'/><title type='text'>ATL thunks and Windows DEP story</title><content type='html'>When using older ATL versions the program may generate an access violation due to &lt;a href="http://msdn.microsoft.com/en-us/library/aa366553.aspx"&gt;Data Execution Prevention&lt;/a&gt;. This is basically a memory protection feature that prevents executing code from memory pages marked as non-executable.&lt;br /&gt;&lt;br /&gt;The ATL implementation of CWindow class uses a technique called &lt;a href="http://www.codeproject.com/KB/atl/atl_underthehood_5.aspx"&gt;thunk&lt;/a&gt;. A thunk is a small piece of code that ATL generates in a region of memory allocated on the heap. Older versions of ATL did not set the execution flag on the allocated memory pages and that generates a crash on Windows machines where DEP is enabled.&lt;br /&gt;&lt;br /&gt;Usually ATL is used in Internet Explorer extensions. If DEP is enabled then the result is a browser crash. This is a good reason to upgrade to Visual Studio 2005 or later. Find more on how to activate DEP in IE7 &lt;a href="http://blogs.msdn.com/michael_howard/archive/2006/12/12/update-on-internet-explorer-7-dep-and-adobe-software.aspx"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-354893813203016407?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/354893813203016407/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=354893813203016407' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/354893813203016407'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/354893813203016407'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2008/05/atl-thunks-and-windows-dep-story.html' title='ATL thunks and Windows DEP story'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-7763423521535606573</id><published>2008-04-21T02:36:00.000-07:00</published><updated>2009-06-02T12:20:46.872-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ATL'/><category scheme='http://www.blogger.com/atom/ns#' term='STL'/><category scheme='http://www.blogger.com/atom/ns#' term='IHTMLElement'/><title type='text'>ATL + STL = CAdapt</title><content type='html'>&lt;div align="justify"&gt;I didn't know about &lt;span style="FONT-STYLE: italic"&gt;CAdapt&lt;/span&gt; class until I tried to convert a VS2003 project to VS2005. Everything worked OK but I couldn't compile it! The compiler complained about:&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="font-family:courier new;"&gt;std::list&amp;lt;CComQIPtr&amp;lt;IHTMLElement&amp;gt; &amp;gt;&lt;/span&gt;.&lt;/div&gt;&lt;div align="justify"&gt;I found that what was accepted by VC++ 2003 compiler is not accepted by VC++ 2005 compiler. The reason of for is the address operator overloaded by &lt;span style="font-family:courier new;"&gt;CComQIPtr&lt;/span&gt; class. &lt;span style="font-family:courier new;"&gt;std::list&lt;/span&gt; class needs the address of a &lt;span style="font-family:courier new;"&gt;CComQIPtr&lt;/span&gt; object but &lt;span style="font-family:courier new;"&gt;&amp;amp;&lt;/span&gt; operator returns a &lt;span style="font-family:courier new;"&gt;IHTMLElement&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;*&lt;/span&gt; address.&lt;br /&gt;&lt;br /&gt;Here's where &lt;span style="font-family:courier new;"&gt;CAdapt&lt;/span&gt; class comes to save us. The list of smart pointers becomes: &lt;span style="font-family:courier new;"&gt;std::list&amp;lt;CAdapt&amp;lt;CComQIPtr&amp;lt;IHTMLElement&amp;gt; &amp;gt; &amp;gt;&lt;/span&gt;&lt;br /&gt;Also you need to use &lt;span style="font-family:courier new;"&gt;m_T&lt;/span&gt; member where needed.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-7763423521535606573?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/7763423521535606573/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=7763423521535606573' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/7763423521535606573'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/7763423521535606573'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2008/04/atl-stl-cadapt.html' title='ATL + STL = CAdapt'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-4740371654670667784</id><published>2008-04-15T04:17:00.001-07:00</published><updated>2008-05-04T10:56:39.468-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>Did you know that ? fatal error C1091: compiler limit</title><content type='html'>It doesn't happen every day to find a new compiler error message. Here's one I didn't expect: &lt;span style="font-style: italic; font-family: courier new;"&gt;&lt;br /&gt;&lt;br /&gt;fatal error C1091: compiler limit: string exceeds 65535 bytes in length&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: courier new;"&gt;&lt;/span&gt;I was about to complete my programming task when this error struck and I really needed a very long string. On VC++ 2003 compiler the limit is even smaller, &lt;span style="font-style: italic;"&gt;16 &lt;/span&gt;Kb.&lt;br /&gt;&lt;br /&gt;The conclusion of this story: don't put the whole story of your life inside a C++ string constant!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-4740371654670667784?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/4740371654670667784/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=4740371654670667784' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/4740371654670667784'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/4740371654670667784'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2008/04/did-you-know-that-fatal-error-c1091.html' title='Did you know that ? fatal error C1091: compiler limit'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-3946074591005766868</id><published>2008-03-31T01:16:00.000-07:00</published><updated>2009-06-02T12:18:05.946-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='COM'/><category scheme='http://www.blogger.com/atom/ns#' term='garbage collector'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='IHTMLElement'/><category scheme='http://www.blogger.com/atom/ns#' term='IHTMLDocument2'/><title type='text'>.Net and COM interop story</title><content type='html'>&lt;div style="text-align: justify;"&gt;.Net allows programmers to reuse COM components in their managed code. To make this possible a managed wrapper object around the native object is needed. Besides that, one can use the COM object like any other managed object. Even if it sounds simple, you have to be aware of the differences between the CLR's object lifetime management and the COM version of object lifetime management.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;COM programmers have to call &lt;span style="font-style: italic;"&gt;Release &lt;/span&gt;on every interface that has been &lt;span style="font-style: italic;"&gt;AddRef&lt;/span&gt;'ed. For C# programmers using COM objects that means &lt;span style="font-style: italic;"&gt;AddRef&lt;/span&gt; is called when:&lt;br /&gt;- a COM object is created.&lt;br /&gt;- a COM object is returned by calling a method or a property.&lt;br /&gt;- a COM object is &lt;span style="font-style: italic;"&gt;cast'&lt;/span&gt;ed to another COM interface type.&lt;br /&gt;&lt;br /&gt;To release a COM object in C# there are two options:&lt;br /&gt;- leave the GC to collect managed wrappers and to call their finalizers that will call &lt;span style="font-style: italic;"&gt;Release&lt;/span&gt; on native COM object.&lt;br /&gt;- manually call &lt;span style="font-style: italic;"&gt;Marshal.ReleaseComObject&lt;/span&gt; on every interface used in the code.&lt;br /&gt;&lt;br /&gt;Let's see a short example using COM objects exposed by IE. The code bellow changes the color of every link in a HTML document.&lt;br /&gt;&lt;code&gt;&lt;/code&gt;&lt;pre&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// IHTMLDocument2 doc;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;foreach&lt;/span&gt; (IHTMLElement elem &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; doc.all)&lt;br /&gt;{&lt;br /&gt;    IHTMLAnchorElement anchor = elem &lt;span style="color: rgb(0, 0, 255);"&gt;as&lt;/span&gt; IHTMLAnchorElement;&lt;br /&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (anchor != null)&lt;br /&gt;    {&lt;br /&gt;        elem.style.color = &lt;span style="color: rgb(255, 0, 0);"&gt;"red"&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;This first approach leaves the task of releasing COM objects to garbage collector. Let's manually release COM objects now:&lt;br /&gt;&lt;code&gt;&lt;/code&gt;&lt;br /&gt;&lt;pre&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// IHTMLDocument2 doc;&lt;/span&gt;&lt;br /&gt;IHTMLElementCollection allCollection = doc.all;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;foreach&lt;/span&gt; (IHTMLElement crntElem &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; allCollection)&lt;br /&gt;{&lt;br /&gt;   IHTMLAnchorElement anchor = crntElem &lt;span style="color: rgb(0, 0, 255);"&gt;as&lt;/span&gt; IHTMLAnchorElement;&lt;br /&gt;   &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (anchor != null)&lt;br /&gt;   {&lt;br /&gt;       IHTMLStyle style = crntElem.style;&lt;br /&gt;       style.color = &lt;span style="color: rgb(255, 0, 0);"&gt;"red"&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;       Marshal.ReleaseComObject(style);&lt;br /&gt;       Marshal.ReleaseComObject(anchor);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   Marshal.ReleaseComObject(crntElem);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Marshal.ReleaseComObject(allCollection);&lt;/pre&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;As you can see the number of code lines doubles! I personally prefer to leave the task of releasing COM objects to GC even if they will be eventually released after some time when GC comes into action.&lt;br /&gt;&lt;br /&gt;Some might be tempted to call &lt;span style="font-style: italic;"&gt;GC.Collect&lt;/span&gt; after a large chunk of code that work with COM objects but this could be even worse because other managed objects could be promoted to next GC generation and their lifespan is therefore longer than necessary.&lt;br /&gt;&lt;br /&gt;In theory it is possible to create a lot of large COM objects that will exceed the native heap while the managed heap has a lot of available memory because managed wrappers are smaller in size. GC won't be called in this scenario so the native heap won't be freed.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;If your application suffers from this kind of memory allocation problem, maybe using COM objects from managed code is not the best approach for you.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-3946074591005766868?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/3946074591005766868/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=3946074591005766868' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/3946074591005766868'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/3946074591005766868'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2008/03/net-and-com-interop-story.html' title='.Net and COM interop story'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-7074897983954088698</id><published>2008-02-25T20:07:00.000-08:00</published><updated>2009-06-02T12:17:15.139-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='applet'/><category scheme='http://www.blogger.com/atom/ns#' term='tetris'/><category scheme='http://www.blogger.com/atom/ns#' term='game'/><title type='text'>The game of programming. Programming the game.</title><content type='html'>&lt;div style="TEXT-ALIGN: justify"&gt;The first computer I've ever seen was a &lt;span style="FONT-STYLE: italic"&gt;Z80 Spectrum&lt;/span&gt;. That was back in 1988. Like any kid of my age I was amazed by computer games. I started to learn programming with the hope that one day I will create my own game.&lt;br /&gt;&lt;br /&gt;&lt;div style="TEXT-ALIGN: justify"&gt;That happened after many years, in 1999 and here's the result. I wrote these two little games just to learn some &lt;span style="FONT-STYLE: italic"&gt;Java&lt;/span&gt; language. Now looking back at this old code of mine, it's nice to see that I wasn't that bad after all :-)&lt;br /&gt;&lt;br /&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Source code&lt;/span&gt;:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.codecentrix.com/blog/game_of_programming/tetris.zip"&gt;tetris.zip&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codecentrix.com/blog/game_of_programming/black.zip"&gt;black.zip&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Click on images below to play!&lt;/span&gt; &lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;iframe marginwidth="0" marginheight="0" src="http://www.codecentrix.com/blog/game_of_programming/tetrisImg.htm" width="304" scrolling="no" height="296"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;iframe marginwidth="0" marginheight="0" src="http://www.codecentrix.com/blog/game_of_programming/blackImg.htm" width="411" scrolling="no" height="283"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-7074897983954088698?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/7074897983954088698/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=7074897983954088698' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/7074897983954088698'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/7074897983954088698'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2007/11/game-of-programming-programming-game.html' title='The game of programming. Programming the game.'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-1113107271224669864</id><published>2008-02-02T03:46:00.000-08:00</published><updated>2009-06-03T01:39:00.594-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IHTMLWindow2'/><category scheme='http://www.blogger.com/atom/ns#' term='E_ACCESSDENIED'/><category scheme='http://www.blogger.com/atom/ns#' term='COM'/><category scheme='http://www.blogger.com/atom/ns#' term='ATL'/><category scheme='http://www.blogger.com/atom/ns#' term='IWebBrowser2'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='IServiceProvider'/><category scheme='http://www.blogger.com/atom/ns#' term='IHTMLElement'/><category scheme='http://www.blogger.com/atom/ns#' term='IHTMLDocument2'/><title type='text'>When IHTMLWindow2.document throws UnauthorizedAccessException</title><content type='html'>This is basically a C# translation  of one of my older articles "&lt;a href="http://codecentrix.blogspot.com/2007/10/when-ihtmlwindow2getdocument-returns.html"&gt;When  IHTMLWindow2::get_document returns E_ACCESSDENIED&lt;/a&gt;". Some .Net people encountered difficulties to use it, so I decided to make their life easier.&lt;br /&gt;&lt;br /&gt;The main problem is the confusion created by &lt;span style="font-family:courier new;"&gt;System.IServiceProvider&lt;/span&gt; &lt;span style="font-style: italic;"&gt;.Net&lt;/span&gt; interface because it has the same name as the COM interface. Once this issue is passed the code translation is straightforward. Here's the interop code to declare the COM interface &lt;span style="font-family:courier new;"&gt;IServiceProvider&lt;/span&gt;.&lt;br /&gt;&lt;pre&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// This is the COM IServiceProvider interface, not System.IServiceProvider .Net interface!&lt;br /&gt;&lt;/span&gt;[ComImport(), ComVisible(&lt;span style="color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;), Guid(&lt;span style="color: rgb(255, 0, 0);"&gt;"6D5140C1-7436-11CE-8034-00AA006009FA"&lt;/span&gt;),&lt;br /&gt;InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public interface&lt;/span&gt; IServiceProvider&lt;br /&gt;{&lt;br /&gt;   [&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;: MarshalAs(UnmanagedType.I4)][PreserveSig]&lt;br /&gt;   &lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt; QueryService(&lt;span style="color: rgb(0, 0, 255);"&gt;ref&lt;/span&gt; Guid guidService, &lt;span style="color: rgb(0, 0, 255);"&gt;ref&lt;/span&gt; Guid riid, [MarshalAs(UnmanagedType.Interface)] &lt;span style="color: rgb(0, 0, 255);"&gt;out object&lt;/span&gt; ppvObject);&lt;br /&gt;}&lt;/pre&gt;You find &lt;a href="http://www.codecentrix.com/blog/wnd2doc_csharp/GetDocumentFromWindowCsharp.zip"&gt;here&lt;/a&gt; full source code of the sample assembly.&lt;br/&gt;&lt;br /&gt;This technique was successfully implemented and tested in &lt;a href="http://www.codecentrix.com" target="_blank"&gt;Twebst web automation library&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-1113107271224669864?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/1113107271224669864/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=1113107271224669864' title='39 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/1113107271224669864'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/1113107271224669864'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2008/02/when-ihtmlwindow2document-throws.html' title='When IHTMLWindow2.document throws UnauthorizedAccessException'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>39</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-3630036469806246169</id><published>2008-01-09T16:10:00.000-08:00</published><updated>2008-02-07T23:08:11.425-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='COM'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='test'/><category scheme='http://www.blogger.com/atom/ns#' term='NUnit'/><title type='text'>Nunit and STAThread story</title><content type='html'>I use &lt;a href="http://www.nunit.com/index.php"&gt;NUnit&lt;/a&gt; unit-testing framework to test my pet project &lt;a href="http://www.codecentrix.com/"&gt;Twebst&lt;/a&gt;. Being a collection of &lt;span style="font-weight: bold;"&gt;COM&lt;/span&gt; objects, &lt;span style="font-style: italic;"&gt;Twebst&lt;/span&gt; can be used within any environment that supports &lt;span style="font-weight: bold;"&gt;COM&lt;/span&gt;. That means it can be used from &lt;span style="font-style: italic;"&gt;.Net&lt;/span&gt; languages like &lt;span style="font-weight: bold;"&gt;C#&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;First I started by creating an assembly to be used from &lt;span style="font-weight: bold;"&gt;NUnit&lt;/span&gt; GUI. Some tests failed without an obvious reason. After some research I understood that the &lt;span style="font-weight: bold;"&gt;COM&lt;/span&gt; apartment must be &lt;span style="font-weight: bold;"&gt;STAThread. &lt;/span&gt;The threading model must be set before the thread is started but I don't have access to &lt;span style="font-weight: bold;"&gt;NUnit&lt;/span&gt; GUI main thread from my assembly.&lt;br /&gt;&lt;br /&gt;One possible solution to this problem is to transform the assembly into an EXE application that uses the &lt;span style="font-weight: bold;"&gt;NUnit&lt;/span&gt; framework like this:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;/code&gt;&lt;pre&gt;[STAThread]&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; Main(string[] args)&lt;br /&gt;{&lt;br /&gt;NUnit.ConsoleRunner.Runner.Main(&lt;br /&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; string[] { System.AppDomain.CurrentDomain.BaseDirectory + &lt;span style="color: rgb(255, 0, 0);"&gt;"MyExe.exe"&lt;/span&gt;, &lt;span style="color: rgb(255, 0, 0);"&gt;"/nothread"&lt;/span&gt; });&lt;br /&gt;}&lt;/pre&gt;When &lt;span style="font-weight: bold;"&gt;/nothread &lt;/span&gt;command line flag is used the tests are executed by the main thread which already has the right &lt;span style="font-weight: bold;"&gt;COM&lt;/span&gt; apartment properly set.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-3630036469806246169?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/3630036469806246169/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=3630036469806246169' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/3630036469806246169'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/3630036469806246169'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2007/12/nunit-and-stathread-story.html' title='Nunit and STAThread story'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-1376360355495112371</id><published>2007-12-20T04:06:00.001-08:00</published><updated>2008-02-21T23:54:27.827-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='repair'/><category scheme='http://www.blogger.com/atom/ns#' term='regtlib'/><category scheme='http://www.blogger.com/atom/ns#' term='Internet Explorer'/><category scheme='http://www.blogger.com/atom/ns#' term='IE'/><category scheme='http://www.blogger.com/atom/ns#' term='regsvr32'/><category scheme='http://www.blogger.com/atom/ns#' term='IE7'/><title type='text'>Repairing Internet Explorer</title><content type='html'>&lt;div style="text-align: justify;"&gt;Creating Internet Explorer extensions is not always an easy task. Erroneous extensions can make your IE to crash, become unstable or to behave unpredictably.&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Even worse, uninstalling extensions can leave IE in a broken state, some things stop working properly. This usually happens when IE components are unregistered and IE registry keys are altered and not properly restored on uninstall. Here's a short list of damages I personally encountered:&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;1). &lt;a href="http://support.microsoft.com/kb/q180176/"&gt;'Open in New Window' Command Does Not Work in Internet Explorer&lt;/a&gt;&lt;br /&gt;&lt;div&gt;2). &lt;a href="http://www.winhelponline.com/articles/122/1/Error-Element-not-found-when-attempting-to-add-a-Search-Provider-in-Internet-Explorer-7.html"&gt;When you try to add a Search Provider in Internet Explorer 7, a script error occurs, and the provider is not added successfully.&lt;/a&gt;&lt;br /&gt;3). &lt;a href="http://www.winhelponline.com/blogs/43/Why-doesnt-the-quotYouve-opened-a-new-tabquot-message-go-away.html"&gt;When you open a new tab in Internet Explorer 7, does the &lt;span style="font-weight: bold;"&gt;You've opened a new tab&lt;/span&gt; message appear every time, and are you unable to turn off this option&lt;/a&gt;&lt;br /&gt;4). Open a link in a new tab takes forever to load.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt; &lt;/div&gt;I'll come later with examples of how an extension can break IE and how to avoid it. For now let's concentrate on how we can fix it. Download &lt;a href="http://www.codecentrix.com/blog/repairie/RepairIE.zip"&gt;RepairIE.zip&lt;/a&gt; file, extract files inside and run &lt;span style="font-style: italic;"&gt;"&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;fixie.cmd&lt;/span&gt;&lt;span style="font-style: italic;"&gt;"&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;Points of interest:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Internet Explorer components are registered using &lt;span style="font-weight: bold;font-family:courier new;" &gt;regsvr32.exe&lt;/span&gt; tool.&lt;/li&gt;&lt;li&gt;For IE7 &lt;span style="font-weight: bold;font-family:courier new;" &gt;mshtml.dll&lt;/span&gt; can not be registered as explained above; instead &lt;span style="font-weight: bold;font-family:courier new;" &gt;mshtml.tlb&lt;/span&gt; is registered using &lt;span style="font-weight: bold;font-family:courier new;" &gt;regtlib.exe&lt;/span&gt; tool.&lt;/li&gt;&lt;li&gt;Registering &lt;span style="font-weight: bold;font-family:courier new;" &gt;shdocvw.dll&lt;/span&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt; &lt;/span&gt;using &lt;span style="font-family:courier new;"&gt;regsvr32.exe&lt;/span&gt; is not a good idea on IE7 because it damages &lt;span style="font-family:courier new;"&gt;[HKEY_CLASSES_ROOT\Typelib\{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}\1.1\0\win32&lt;/span&gt; registry key.&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;reg_ieframe.reg&lt;/span&gt; file fixes the broken key above.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-1376360355495112371?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/1376360355495112371/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=1376360355495112371' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/1376360355495112371'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/1376360355495112371'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2007/12/repairing-internet-explorer.html' title='Repairing Internet Explorer'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-331749814881278676</id><published>2007-12-09T02:11:00.000-08:00</published><updated>2008-12-11T07:54:15.145-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Security'/><category scheme='http://www.blogger.com/atom/ns#' term='IE7'/><title type='text'>Allow local scripted HTML files to run in IE7</title><content type='html'>During automatically testing &lt;em&gt;&lt;a href="http://www.codecentrix.com/"&gt;Twebst&lt;/a&gt;&lt;/em&gt; library I was very annoyed about IE7 refusing to properly open local HTML files that contains scripts. The following message is displayed:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;"To help protect your security, Internet Explorer has restricted this web page from running scripts or ActiveX controls that could access your computer. Click here for options..."&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;It took me several minutes to find the hidden option that turns off this warning. First I looked for it in &lt;span style="font-style: italic;"&gt;Security&lt;/span&gt; tab options but it was actually in &lt;span style="font-style: italic;"&gt;Advanced&lt;/span&gt; tab. Here's how you find it:&lt;br /&gt;&lt;br /&gt;1). Go to:&lt;br /&gt;&lt;span style="font-style: italic;"&gt;        Tools &gt; Internet Options &gt; Advanced &gt; Security&lt;/span&gt;&lt;br /&gt;2). Check:&lt;br /&gt;       &lt;span style="font-style: italic;"&gt;Allow active content to run in files on My computer&lt;/span&gt;&lt;br /&gt;3). Restart IE&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_b7z9mi4EOXE/R1vHQ-R5_zI/AAAAAAAAABU/eHMnujYdXG8/s1600-h/IEsecurity.JPG"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_b7z9mi4EOXE/R1vHQ-R5_zI/AAAAAAAAABU/eHMnujYdXG8/s400/IEsecurity.JPG" alt="" id="BLOGGER_PHOTO_ID_5141922493983489842" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-331749814881278676?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/331749814881278676/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=331749814881278676' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/331749814881278676'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/331749814881278676'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2007/12/allow-local-scripted-html-files-to-run.html' title='Allow local scripted HTML files to run in IE7'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_b7z9mi4EOXE/R1vHQ-R5_zI/AAAAAAAAABU/eHMnujYdXG8/s72-c/IEsecurity.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-1779983645330380258</id><published>2007-11-14T08:43:00.000-08:00</published><updated>2009-06-02T12:21:37.142-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='COM'/><category scheme='http://www.blogger.com/atom/ns#' term='ATL'/><category scheme='http://www.blogger.com/atom/ns#' term='IWebBrowser2'/><category scheme='http://www.blogger.com/atom/ns#' term='IE7'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>How to get a handle to current TabWindowClass tab in IE7</title><content type='html'>&lt;strong&gt;IWebBrowser2::get_HWND&lt;/strong&gt; method gets the handle of the Internet Explorer 7 main window. Sometimes the tab window handle is needed. Here's a sample code that I recently found in &lt;a href="http://msdn2.microsoft.com/en-us/library/aa752126.aspx"&gt;MSDN&lt;/a&gt;. It shows how to get the handle of the tab window starting from a &lt;strong&gt;IWebBrowser2&lt;/strong&gt; object.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;span style="color:#0000ff;"&gt;#include&lt;/span&gt; &amp;lt;shlguid.h&amp;gt;&lt;br /&gt;&lt;br /&gt;HWND GetTabWnd(CComQIPtr&amp;lt;IWebBrowser2&amp;gt; spBrowser)&lt;br /&gt;{&lt;br /&gt;     HWND hwndTab = NULL;&lt;br /&gt;     CComQIPtr&amp;lt;IServiceProvider&amp;gt; spServiceProvider = spBrowser;&lt;br /&gt;&lt;br /&gt;     &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (spServiceProvider != NULL)&lt;br /&gt;     {&lt;br /&gt;          CComQIPtr&amp;lt;IOleWindow&amp;gt; spWindow;&lt;br /&gt;          &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (SUCCEEDED(spServiceProvider-&amp;gt;QueryService(&lt;br /&gt;                         SID_SShellBrowser,&lt;br /&gt;                              IID_IOleWindow,&lt;br /&gt;                              (&lt;span style="color:#0000ff;"&gt;void&lt;/span&gt;**)&amp;amp;spWindow)))&lt;br /&gt;          {&lt;br /&gt;             &lt;br /&gt;               spWindow-&amp;gt;GetWindow(&amp;amp;hwndTab));&lt;br /&gt;          }&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; hwndTab;&lt;br /&gt;}&lt;/pre&gt;&lt;/code&gt;I think the code is supposed to work on top level &lt;b&gt;IWebBrowser2&lt;/b&gt; objects. You can read more about top browser objects in &lt;a href="http://codecentrix.blogspot.com/2007/11/when-iwebbrowser2gethwnd-returns-efail.html"&gt;my previous article&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;This technique was successfully implemented and tested in &lt;a href="http://www.codecentrix.com" target="_blank"&gt;Twebst web automation library&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-1779983645330380258?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/1779983645330380258/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=1779983645330380258' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/1779983645330380258'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/1779983645330380258'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2007/11/how-to-get-handle-to-current.html' title='How to get a handle to current TabWindowClass tab in IE7'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-5813489489806559650</id><published>2007-11-12T06:14:00.000-08:00</published><updated>2009-06-03T01:41:20.156-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IHTMLWindow2'/><category scheme='http://www.blogger.com/atom/ns#' term='COM'/><category scheme='http://www.blogger.com/atom/ns#' term='ATL'/><category scheme='http://www.blogger.com/atom/ns#' term='IWebBrowser2'/><category scheme='http://www.blogger.com/atom/ns#' term='context menu'/><category scheme='http://www.blogger.com/atom/ns#' term='IServiceProvider'/><category scheme='http://www.blogger.com/atom/ns#' term='IHTMLDocument2'/><title type='text'>When IWebBrowser2::get_HWND returns E_FAIL</title><content type='html'>&lt;span style="FONT-WEIGHT: bold"&gt;IWebBrowser2::get_HWND&lt;/span&gt;&lt;span style="FONT-STYLE: italic"&gt;&lt;span style="FONT-STYLE: italic"&gt;&lt;span style="FONT-STYLE: italic"&gt;&lt;span style="FONT-STYLE: italic"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;"g&lt;/span&gt;&lt;span style="FONT-STYLE: italic"&gt;ets the handle of the Microsoft Internet Explorer main window&lt;/span&gt;". As any COM method &lt;span style="FONT-WEIGHT: bold"&gt;get_HWND &lt;/span&gt;returns a &lt;span style="FONT-WEIGHT: bold"&gt;HRESULT&lt;/span&gt; value. According to MSDN, the method "&lt;span style="FONT-STYLE: italic"&gt;returns S_OK if successful, or an error value otherwise".&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;It was hard for me to imagine how this method could fail but I still got an &lt;span style="FONT-WEIGHT: bold"&gt;E_FAIL&lt;/span&gt; return value. This happened because the &lt;span style="FONT-WEIGHT: bold"&gt;IWebBrowser2&lt;/span&gt; object was not the top level browser. A web page containing frames/iframes is represented by a hierarchy of &lt;span style="FONT-WEIGHT: bold"&gt;IHTMLWindow&lt;/span&gt; objects. Each window has an associated &lt;span style="FONT-WEIGHT: bold"&gt;IHTMLDocument2&lt;/span&gt; object exposed by &lt;span style="FONT-WEIGHT: bold"&gt;IHTMLWindow2::get_document&lt;/span&gt;. An &lt;span style="FONT-WEIGHT: bold"&gt;IHTMLWindow&lt;/span&gt; can be also converted to a &lt;span style="FONT-WEIGHT: bold"&gt;IWebBrowser2&lt;/span&gt; object. Here's my solution to get the main window handle starting from a non-top level browser object (this is a common scenario when adding your custom menu item in the IE context menu).&lt;strong&gt;&lt;span style="FONT-WEIGHT: bold"&gt;&lt;span style="FONT-WEIGHT: bold"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;span style="color:#008000;"&gt;// IHTMLWindow2 to IWebBrowser2&lt;/span&gt;&lt;br /&gt;CComQIPtr&amp;lt;IWebBrowser2&amp;gt; IHTMLWindow2ToIWebBrowser2(CComQIPtr&amp;lt;IHTMLWindow2&amp;gt; spHTMLWindow)&lt;br /&gt;{&lt;br /&gt;     ATLASSERT(spHTMLWindow != NULL);&lt;br /&gt;&lt;br /&gt;     &lt;span style="color:#008000;"&gt;// Query for a service provider.&lt;/span&gt;&lt;br /&gt;     CComQIPtr&amp;lt;IWebBrowser2&amp;gt;     spBrowser;&lt;br /&gt;     CComQIPtr&amp;lt;IServiceProvider&amp;gt; spServiceProvider = spHTMLWindow;&lt;br /&gt;&lt;br /&gt;     &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (spServiceProvider != NULL)&lt;br /&gt;     {&lt;br /&gt;          &lt;span style="color:#008000;"&gt;// Ask the service provider for a IWebBrowser2 object.&lt;/span&gt;&lt;br /&gt;          spServiceProvider-&amp;gt;QueryService(IID_IWebBrowserApp, IID_IWebBrowser2, (&lt;span style="color:#0000ff;"&gt;void&lt;/span&gt;**)&amp;amp;spBrowser);&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; spBrowser;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#008000;"&gt;// IWebBrowser2 to IHTMLWindow2&lt;/span&gt;&lt;br /&gt;CComQIPtr&amp;lt;IHTMLWindow2&amp;gt; IWebBrowserToIHTMLWindow(CComQIPtr&amp;lt;IWebBrowser2&amp;gt; spBrowser)&lt;br /&gt;{&lt;br /&gt;     ATLASSERT(spBrowser != NULL);&lt;br /&gt;     CComQIPtr&amp;lt;IHTMLWindow2&amp;gt; spWindow;&lt;br /&gt;&lt;br /&gt;     &lt;span style="color:#008000;"&gt;// Get the document of the browser.&lt;/span&gt;&lt;br /&gt;     CComQIPtr&amp;lt;IDispatch&amp;gt; spDisp;&lt;br /&gt;     spBrowser-&amp;gt;get_Document(&amp;amp;spDisp);&lt;br /&gt;&lt;br /&gt;     &lt;span style="color:#008000;"&gt;// Get the window of the document.&lt;/span&gt;&lt;br /&gt;     CComQIPtr&amp;lt;IHTMLDocument2&amp;gt; spDoc = spDisp;&lt;br /&gt;     &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (spDoc != NULL)&lt;br /&gt;     {&lt;br /&gt;          spDoc-&amp;gt;get_parentWindow(&amp;amp;spWindow);&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; spWindow;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;CComQIPtr&amp;lt;IWebBrowser2&amp;gt; TopBrowser(CComQIPtr&amp;lt;IWebBrowser2&amp;gt; spBrowser)&lt;br /&gt;{&lt;br /&gt;     ATLASSERT(spBrowser != NULL);&lt;br /&gt;&lt;br /&gt;     &lt;span style="color:#008000;"&gt;// Retrieve IHTMLWindow2 from browser.&lt;/span&gt;&lt;br /&gt;     CComQIPtr&amp;lt;IHTMLWindow2&amp;gt; spHTMLWnd = IWebBrowserToIHTMLWindow(spBrowser);&lt;br /&gt;     &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (spHTMLWnd != NULL)&lt;br /&gt;     {&lt;br /&gt;          &lt;span style="color:#008000;"&gt;// Find top window.&lt;/span&gt;&lt;br /&gt;          CComQIPtr&amp;lt;IHTMLWindow2&amp;gt; spTopWindow;&lt;br /&gt;          HRESULT hResult = spHTMLWnd-&amp;gt;get_top(&amp;amp;spTopWindow);&lt;br /&gt;&lt;br /&gt;          &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (SUCCEEDED(hResult) &amp;amp;&amp;amp; (spTopWindow != NULL))&lt;br /&gt;          {&lt;br /&gt;               &lt;span style="color:#008000;"&gt;// Convert the browser object to window.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;               &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; IHTMLWindow2ToIWebBrowser2(spTopWindow);&lt;br /&gt;          }&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; CComQIPtr&amp;lt;IWebBrowser2&amp;gt;();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;This technique was successfully implemented and tested in &lt;a href="http://www.codecentrix.com" target="_blank"&gt;My web automation library&lt;/a&gt;.&lt;br /&gt;&lt;a href="http://www.codeproject.com/script/Articles/BlogArticleList.aspx?amid=2505056" rel="tag" style="display:none"&gt; codeproject &lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-5813489489806559650?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/5813489489806559650/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=5813489489806559650' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/5813489489806559650'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/5813489489806559650'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2007/11/when-iwebbrowser2gethwnd-returns-efail.html' title='When IWebBrowser2::get_HWND returns E_FAIL'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-6133219977115357130</id><published>2007-11-05T04:25:00.000-08:00</published><updated>2007-11-05T04:30:56.837-08:00</updated><title type='text'>How to programmatically find if XP theme is active?</title><content type='html'>&lt;span style="font-family:arial;"&gt;Registry key:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\ThemeManager&lt;br /&gt;&lt;br /&gt;Value:&lt;br /&gt;ThemeActive is "1" if Windows XP, "0" if Windows Classic.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-6133219977115357130?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/6133219977115357130/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=6133219977115357130' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/6133219977115357130'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/6133219977115357130'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2007/11/how-to-programmatically-find-if-xp.html' title='How to programmatically find if XP theme is active?'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-5562627562402606995</id><published>2007-10-28T12:20:00.000-07:00</published><updated>2008-12-11T07:54:15.517-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='js'/><category scheme='http://www.blogger.com/atom/ns#' term='jscript'/><category scheme='http://www.blogger.com/atom/ns#' term='extension'/><category scheme='http://www.blogger.com/atom/ns#' term='IE'/><category scheme='http://www.blogger.com/atom/ns#' term='context menu'/><category scheme='http://www.blogger.com/atom/ns#' term='menuArguments'/><category scheme='http://www.blogger.com/atom/ns#' term='TextRange'/><category scheme='http://www.blogger.com/atom/ns#' term='selection'/><title type='text'>Open TextRange selection as URL</title><content type='html'>On many forums, people post URLs as plain text and this forces me to:&lt;br /&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;select the text URL&lt;/li&gt;&lt;li&gt;ctrl+C to copy it in the clipboard&lt;/li&gt;&lt;li&gt;ctrl+T to open a new tab&lt;/li&gt;&lt;li&gt;paste the URL in the address bar of the newly created tab&lt;/li&gt;&lt;li&gt;press "Enter" key to start navigation&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;p align="justify"&gt;I found this whole process very annoying and it seems I have to go through this many times a day. Here's my attempt to automate it by creating an extension for "Internet Explorer" similar to &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/190"&gt;Linkification&lt;/a&gt; extension (for "Fire Fox" browser). I called my extension: "&lt;strong&gt;Make Link&lt;/strong&gt;".&lt;/p&gt;&lt;p&gt;&lt;strong&gt;How it works:&lt;/strong&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;right click on text URL&lt;/li&gt;&lt;li&gt;choose "&lt;strong&gt;MakeLink: use clicked text as link&lt;/strong&gt;" menu item (the URL is open in a new tab automatically)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;or you can&lt;/p&gt;&lt;ul&gt;&lt;li&gt;fully select the URL text or &lt;strong&gt;only a part of it&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;right click on selected text&lt;/li&gt;&lt;li&gt;choose "&lt;strong&gt;MakeLink: use clicked text as link&lt;/strong&gt;" menu item (text link is open in a new tab automatically)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;DOWNLOADS:&lt;/strong&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.codecentrix.com/blog/make_link/MakeLink.msi"&gt;MSI setup file&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codecentrix.com/blog/make_link/setup.exe"&gt;EXE setup file&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codecentrix.com/blog/make_link/MakeLink.html"&gt;extension source code&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Points of interests:&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt&lt;/strong&gt; registry key to add a item in the IE context menu&lt;/li&gt;&lt;li&gt;gain access to window object passed in &lt;strong&gt;external.menuArguments&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;document.selection&lt;/strong&gt; property to get the selected &lt;strong&gt;TextRange&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;TextRange &lt;/strong&gt;methods: &lt;strong&gt;moveStart&lt;/strong&gt;, &lt;strong&gt;moveEnd&lt;/strong&gt;, &lt;strong&gt;moveToPoint&lt;/strong&gt;, &lt;strong&gt;select&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;The extension is entirely written in JScript (no BHO, no COM).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Known issues:&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;on some web pages with horizontal scroll simply right click a text URL won't work. You need to select a part of the URL and then right click it.&lt;/li&gt;&lt;/ul&gt;&lt;a href="http://2.bp.blogspot.com/_b7z9mi4EOXE/RyTy3JUrPvI/AAAAAAAAAAs/B4t7Hqmtu70/s1600-h/demo.JPG"&gt;&lt;/a&gt;&lt;a href="http://2.bp.blogspot.com/_b7z9mi4EOXE/RyTy3JUrPvI/AAAAAAAAAAs/B4t7Hqmtu70/s1600-h/demo.JPG"&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_b7z9mi4EOXE/RyTzzJUrPxI/AAAAAAAAAA8/hGnjQBN2jCk/s1600-h/demo.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_5126490335855984402" style="CURSOR: hand" alt="" src="http://2.bp.blogspot.com/_b7z9mi4EOXE/RyTzzJUrPxI/AAAAAAAAAA8/hGnjQBN2jCk/s320/demo.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-5562627562402606995?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/5562627562402606995/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=5562627562402606995' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/5562627562402606995'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/5562627562402606995'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2007/10/open-textrange-selection-as-url.html' title='Open TextRange selection as URL'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_b7z9mi4EOXE/RyTzzJUrPxI/AAAAAAAAAA8/hGnjQBN2jCk/s72-c/demo.JPG' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-34196632359426695</id><published>2007-10-17T08:35:00.000-07:00</published><updated>2009-06-02T12:22:51.103-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='COM'/><category scheme='http://www.blogger.com/atom/ns#' term='IWebBrowser2'/><category scheme='http://www.blogger.com/atom/ns#' term='IE'/><category scheme='http://www.blogger.com/atom/ns#' term='WorkerW'/><category scheme='http://www.blogger.com/atom/ns#' term='rebar'/><category scheme='http://www.blogger.com/atom/ns#' term='RBN_CHEVRONPUSHED'/><category scheme='http://www.blogger.com/atom/ns#' term='toolbar'/><category scheme='http://www.blogger.com/atom/ns#' term='RB_SETPARENT'/><title type='text'>How to properly catch RBN_CHEVRONPUSHED notification?</title><content type='html'>This is actually a &lt;a href="http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2250966&amp;amp;SiteID=1"&gt;thread&lt;/a&gt; I started on MSDN forum but unfortunately it remained unanswered:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Virtually any IE toolbar needs a chevron to happily live along with other toolbars in the same re-bar. So does my toolbar. To implement chevron functionality in IE toolbars I need to handle &lt;span style="font-weight: bold;"&gt;RBN_CHEVRONPUSHED&lt;/span&gt;. According to MSDN, when the chevron button is pushed, the notification is sent by the rebar in the form of &lt;span style="font-weight: bold;"&gt;WM_NOTIFY&lt;/span&gt; message to its parent. Here is the windows hierarchy in IE7:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:courier new;" &gt;WorkerW &lt;- ReBarWindow32 &lt;- ToolbarWindow32&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;where the last toolbar window is my toolbar. So I need to catch notifications from &lt;span style="font-weight: bold;"&gt;ReBarWindow32&lt;/span&gt; that are sent to &lt;span style="font-weight: bold;"&gt;WorkerW&lt;/span&gt; window. To do that the first idea that came to my mind was to subclass the &lt;span style="font-weight: bold;"&gt;WorkerW&lt;/span&gt; window. I don’t like this idea because:&lt;br /&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;I subclass a window that does not belong to me, it was created by IE.     &lt;/li&gt;&lt;li&gt;I don’t know what is the best time to subclass it: on &lt;span style="font-weight: bold;"&gt;IObjectWithSite.SetSite&lt;/span&gt; or on &lt;span style="font-weight: bold;"&gt;IDockingWindow.ShowDW&lt;/span&gt; ? (Those functions are implemented by my toolbar component)     &lt;/li&gt;&lt;li&gt;I don’t know what is the best time to un-subclass it.     &lt;/li&gt;&lt;li&gt;I don’t know when other toolbar might subclass/un-subclass the same window (I actually got a conflict with other toolbar resulting in IE stack overflow crash because of the order of subclassing/unsubclassing).  &lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: justify;"&gt;My second approach uses &lt;span style="font-weight: bold;"&gt;RB_SETPARENT&lt;/span&gt; to modify the parent of &lt;span style="font-weight: bold;"&gt;ReBarWindow32&lt;/span&gt; window to be one of my windows. I process the &lt;span style="font-weight: bold;"&gt;RBN_CHEVRONPUSHED&lt;/span&gt; notification for my chevron button and send the other notifications to the original parent window (that is &lt;span style="font-weight: bold;"&gt;WorkerW&lt;/span&gt;). I change the parent on toolbar initialization/un-init (&lt;span style="font-weight: bold;"&gt;IObjectWithSite.SetSite&lt;/span&gt;). It seems a safer approach but I’m still worried about other toolbars using the same technique and the possibility of conflicts.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Take care of standard IE "Links" toolbar that also sends &lt;span style="font-weight: bold;"&gt;WM_COMMAND&lt;/span&gt;, &lt;span style="font-weight: bold;"&gt;WM_DRAWITEM&lt;/span&gt; and &lt;span style="font-weight: bold;"&gt;WM_MEASUREITEM&lt;/span&gt; messages to &lt;span style="font-weight: bold;"&gt;WorkerW&lt;/span&gt; window (and now you'll get those messages too). On IE6, "Go" button also do the same.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;So the question remains: what is the best way to catch &lt;span style="font-weight: bold;"&gt;RBN_CHEVRONPUSHED&lt;/span&gt; notification when creating an IE toolbar extension?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-34196632359426695?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/34196632359426695/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=34196632359426695' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/34196632359426695'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/34196632359426695'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2007/10/how-to-properly-catch-rbnchevronpushed.html' title='How to properly catch RBN_CHEVRONPUSHED notification?'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-6481703992556159129</id><published>2007-10-10T07:01:00.000-07:00</published><updated>2009-06-03T01:42:19.654-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IHTMLWindow2'/><category scheme='http://www.blogger.com/atom/ns#' term='E_ACCESSDENIED'/><category scheme='http://www.blogger.com/atom/ns#' term='COM'/><category scheme='http://www.blogger.com/atom/ns#' term='ATL'/><category scheme='http://www.blogger.com/atom/ns#' term='IWebBrowser2'/><category scheme='http://www.blogger.com/atom/ns#' term='IServiceProvider'/><category scheme='http://www.blogger.com/atom/ns#' term='IHTMLElement'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><category scheme='http://www.blogger.com/atom/ns#' term='IHTMLDocument2'/><title type='text'>When IHTMLWindow2::get_document returns E_ACCESSDENIED</title><content type='html'>Internet Explorer extensions usually needs to access HTML elements. When extensions are initialized they get a &lt;strong&gt;IWebBrowser2&lt;/strong&gt; pointer representing the browser. Starting with this pointer one can get any HTML element in the web page but to do that we need to browse a hierarchy of frames first. The simplest web pages only have one frame and one document. Web pages containing &lt;strong&gt;&amp;lt;frame&amp;gt;&lt;/strong&gt; or &lt;strong&gt;&amp;lt;iframe&amp;gt;&lt;/strong&gt; have a hierarchy of frames, each frame having its own document.&lt;br /&gt;&lt;br /&gt;Here are the objects involved and the corresponding interfaces:&lt;br /&gt;&lt;pre&gt;browser      - IWebBrowser2&lt;br /&gt;frame/iframe - IHTMLWindow2&lt;br /&gt;document     - IHTMLDocument2&lt;br /&gt;element      - IHTMLElement&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The list bellow shows what method to call to get one object from another:&lt;br /&gt;&lt;pre&gt;browser      -&gt; document        IWebBrowser2::get_Document&lt;br /&gt;document     -&gt; frame           IHTMLDocument2::get_parentWindow&lt;br /&gt;frame        -&gt; document        IHTMLWindow2::get_document&lt;br /&gt;frame        -&gt; parent frame    IHTMLWindow2::get_parent&lt;br /&gt;frame        -&gt; children frames IHTMLWindow2::get_frames&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A normal call chain to get a HTML element is:&lt;br /&gt;&lt;pre&gt;browser -&gt; document -&gt; frame -&gt; child frame -&gt; ... -&gt; child frame -&gt; document -&gt; element&lt;/pre&gt;&lt;br /&gt;This will work almost all the time. The problems arise when different frames contain documents loaded from different internet domains. In this case &lt;b&gt;IHTMLWindow2::get_document&lt;/b&gt; returns &lt;b&gt;E_ACCESSDENIED&lt;/b&gt; when trying to get the document from the frame object. I think this happens to prevent cross frame scripting atacks.&lt;br /&gt;&lt;br /&gt;Here is &lt;b&gt;HtmlWindowToHtmlDocument&lt;/b&gt; function I wrote to be used instead IHTMLWindow2::get_document to bypass the restriction:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;/code&gt;&lt;pre&gt;&lt;br /&gt;&lt;span style="color:#008000;"&gt;// Converts a IHTMLWindow2 object to a IHTMLDocument2. Returns NULL in case of failure.&lt;br /&gt;// It takes into account accessing the DOM across frames loaded from different domains.&lt;/span&gt;&lt;br /&gt;CComQIPtr&amp;lt;IHTMLDocument2&amp;gt; HtmlWindowToHtmlDocument(CComQIPtr&amp;lt;IHTMLWindow2&amp;gt; spWindow)&lt;br /&gt;{&lt;br /&gt;     ATLASSERT(spWindow != NULL);&lt;br /&gt;&lt;br /&gt;     CComQIPtr&amp;lt;IHTMLDocument2&amp;gt; spDocument;&lt;br /&gt;     HRESULT hRes = spWindow-&amp;gt;get_document(&amp;amp;spDocument);&lt;br /&gt;    &lt;br /&gt;     &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; ((S_OK == hRes) &amp;amp;&amp;amp; (spDocument != NULL))&lt;br /&gt;     {&lt;br /&gt;          &lt;span style="color:#008000;"&gt;// The html document was properly retrieved.&lt;/span&gt;&lt;br /&gt;          &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; spDocument;&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     &lt;span style="color:#008000;"&gt;// hRes could be E_ACCESSDENIED that means a security restriction that&lt;br /&gt;     // prevents scripting across frames that loads documents from different internet domains.&lt;/span&gt;&lt;br /&gt;     CComQIPtr&amp;lt;IWebBrowser2&amp;gt;  spBrws = HtmlWindowToHtmlWebBrowser(spWindow);&lt;br /&gt;     &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (spBrws == NULL)&lt;br /&gt;     {&lt;br /&gt;          &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; CComQIPtr&amp;lt;IHTMLDocument2&amp;gt;();&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     &lt;span style="color:#008000;"&gt;// Get the document object from the IWebBrowser2 object.&lt;/span&gt;&lt;br /&gt;     CComQIPtr&amp;lt;IDispatch&amp;gt; spDisp;&lt;br /&gt;     hRes = spBrws-&amp;gt;get_Document(&amp;amp;spDisp);&lt;br /&gt;     spDocument = spDisp;&lt;br /&gt;&lt;br /&gt;     &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; spDocument;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#008000;"&gt;// Converts a IHTMLWindow2 object to a IWebBrowser2. Returns NULL in case of failure.&lt;/span&gt;&lt;br /&gt;CComQIPtr&amp;lt;IWebBrowser2&amp;gt; HtmlWindowToHtmlWebBrowser(CComQIPtr&amp;lt;IHTMLWindow2&amp;gt; spWindow)&lt;br /&gt;{&lt;br /&gt;     ATLASSERT(spWindow != NULL);&lt;br /&gt;&lt;br /&gt;     CComQIPtr&amp;lt;IServiceProvider&amp;gt;  spServiceProvider = spWindow;&lt;br /&gt;     &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (spServiceProvider == NULL)&lt;br /&gt;     {&lt;br /&gt;          &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; CComQIPtr&amp;lt;IWebBrowser2&amp;gt;();&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     CComQIPtr&amp;lt;IWebBrowser2&amp;gt; spWebBrws;&lt;br /&gt;     HRESULT hRes = spServiceProvider-&amp;gt;QueryService(IID_IWebBrowserApp, IID_IWebBrowser2, (&lt;span style="color:#0000ff;"&gt;void&lt;/span&gt;**)&amp;amp;spWebBrws);&lt;br /&gt;     &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (hRes != S_OK)&lt;br /&gt;     {&lt;br /&gt;          &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; CComQIPtr&amp;lt;IWebBrowser2&amp;gt;();&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; spWebBrws;&lt;br /&gt;}&lt;/pre&gt;Here is the C# version of the code: "&lt;a href="http://codecentrix.blogspot.com/2008/02/when-ihtmlwindow2document-throws.html"&gt;When IHTMLWindow2.document throws UnauthorizedAccessException&lt;/a&gt;".&lt;br/&gt;&lt;br /&gt;This technique was successfully implemented and tested in &lt;a href="http://www.codecentrix.com" target="_blank"&gt;My web automation library&lt;/a&gt;.&lt;br /&gt;&lt;a href="http://www.codeproject.com/script/Articles/BlogArticleList.aspx?amid=2505056" rel="tag" style="display:none"&gt; codeproject &lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-6481703992556159129?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/6481703992556159129/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=6481703992556159129' title='18 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/6481703992556159129'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/6481703992556159129'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2007/10/when-ihtmlwindow2getdocument-returns.html' title='When IHTMLWindow2::get_document returns E_ACCESSDENIED'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>18</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-4041312196508412146</id><published>2007-10-05T06:44:00.000-07:00</published><updated>2009-06-02T12:24:15.318-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='http'/><category scheme='http://www.blogger.com/atom/ns#' term='windows mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='tool'/><category scheme='http://www.blogger.com/atom/ns#' term='encoding'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='reflector'/><category scheme='http://www.blogger.com/atom/ns#' term='decoding'/><title type='text'>Quick and dirty</title><content type='html'>One of the most interesting comments I ever found in source code is&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);font-family:courier new;" &gt;&lt;span style="font-weight: bold;"&gt;//QD:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div style="text-align: justify;"&gt;I am familiar with the well known &lt;span style="color: rgb(0, 153, 0); font-weight: bold;"&gt;//TODO:&lt;/span&gt; style of comment used by Visual Studio, but QD was new to me. As I found later, QD stands for "quick and dirty" and it is basically a low quality piece of code that will cause you a lot of trouble in the future. A quick search throughout the sources revealed plenty of QD comments. It seemed someone made a way of living out of this.&lt;br /&gt;But sometimes programmers gotta do what programmers gotta do and even if I don't like it, I have to be quick and dirty.&lt;br /&gt;&lt;br /&gt;Few days ago I was working on Windows mobile and I needed to decode a string that was HTTP posted to a web server.  This is best accomplished by &lt;a style="font-family: courier new;" href="http://msdn2.microsoft.com/en-us/library/adwtk1fy.aspx"&gt;HttpUtility.UrlDecode&lt;/a&gt; method. Out of luck! &lt;span style="font-family:courier new;"&gt;HTTPUtility&lt;/span&gt; class is not available on .Net Compact Framework.&lt;br /&gt;&lt;br /&gt;Here is where &lt;a href="http://www.aisto.com/roeder/dotnet/"&gt;.Net Reflector&lt;/a&gt; came to help. I simply decompiled &lt;span style="font-family:courier new;"&gt;UrlDecode&lt;/span&gt; method in .Net Framework and copy-pasted the code to mobile project. Luckily, the generated code was short and it doesn't reference a lot of other classes. I was amazed by the quality of the decompiled code. Reflector did a great job!&lt;br /&gt;&lt;br /&gt;Yes, it was quick, it was dirty but also it was very effective. As a bonus, the code is better than any code I can possibly produce in this very short time. After all, it was tested by Microsoft QA team!&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-4041312196508412146?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/4041312196508412146/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=4041312196508412146' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/4041312196508412146'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/4041312196508412146'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2007/10/quick-and-dirty.html' title='Quick and dirty'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-3641308424417455694</id><published>2007-10-03T06:20:00.000-07:00</published><updated>2009-06-03T01:41:54.114-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IAccessible'/><category scheme='http://www.blogger.com/atom/ns#' term='Active Accessibility'/><category scheme='http://www.blogger.com/atom/ns#' term='COM'/><category scheme='http://www.blogger.com/atom/ns#' term='IE'/><category scheme='http://www.blogger.com/atom/ns#' term='IHTMLElement'/><title type='text'>From IAccessible to IHTMLElement and back</title><content type='html'>When developing Internet Explorer plug-ins you might want to take advantage of the dual nature of the browser objects. Internet Explorer exposes the DOM (document object model) using &lt;span style="FONT-WEIGHT: bold"&gt;IHTMLElement&lt;/span&gt; interface as the building block of the hierarchy. It also offers accessible objects through Active Accessibility &lt;span style="FONT-WEIGHT: bold"&gt;&lt;span style="FONT-WEIGHT: bold"&gt;&lt;/span&gt;IAccessible&lt;/span&gt; interface.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span style="color:#008000;"&gt;// From IAccessible to IHTMLElement.&lt;/span&gt;&lt;br /&gt;CComQIPtr&amp;lt;IHTMLElement&amp;gt; AccessibleToHTMLElement(IAccessible* pAccessible)&lt;br /&gt;{&lt;br /&gt;     ATLASSERT(pAccessible != NULL);&lt;br /&gt;&lt;br /&gt;     &lt;span style="color:#008000;"&gt;// Query for IServiceProvider interface.&lt;/span&gt;&lt;br /&gt;     CComQIPtr&amp;lt;IServiceProvider&amp;gt; spServProvider = pAccessible;&lt;br /&gt;     &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (spServProvider != NULL)&lt;br /&gt;     {&lt;br /&gt;         &lt;span style="color:#008000;"&gt;// Ask the service for a IHTMLElement object.&lt;/span&gt;&lt;br /&gt;         CComQIPtr&amp;lt;IHTMLElement&amp;gt; spHtmlElement;&lt;br /&gt;         HRESULT hRes = spServProvider-&amp;gt;QueryService(IID_IHTMLElement, IID_IHTMLElement,&lt;br /&gt;                                                      (&lt;span style="color:#0000ff;"&gt;void&lt;/span&gt;**)&amp;amp;spHtmlElement);&lt;br /&gt;&lt;br /&gt;         &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; spHtmlElement;&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; CComQIPtr&amp;lt;IHTMLElement&amp;gt;();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#008000;"&gt;// From IHTMLElement to IAccessible.&lt;/span&gt;&lt;br /&gt;CComQIPtr&amp;lt;IAccessible&amp;gt; HTMLElementToAccessible(IHTMLElement* pHtmlElement)&lt;br /&gt;{&lt;br /&gt;     ATLASSERT(pHtmlElement != NULL);&lt;br /&gt;&lt;br /&gt;     &lt;span style="color:#008000;"&gt;// Query for IServiceProvider interface.&lt;/span&gt;&lt;br /&gt;     CComQIPtr&amp;lt;IServiceProvider&amp;gt; spServProvider = pHtmlElement;&lt;br /&gt;     &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (spServProvider != NULL)&lt;br /&gt;     {&lt;br /&gt;         &lt;span style="color:#008000;"&gt;// Ask the service for a IAccessible object.&lt;/span&gt;&lt;br /&gt;         CComQIPtr&amp;lt;IAccessible&amp;gt; spAccessible;&lt;br /&gt;         HRESULT hRes = spServProvider-&amp;gt;QueryService(IID_IAccessible, IID_IAccessible,&lt;br /&gt;                                                      (&lt;span style="color:#0000ff;"&gt;void&lt;/span&gt;**)&amp;amp;spAccessible);&lt;br /&gt;&lt;br /&gt;         &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; spAccessible;&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; CComQIPtr&amp;lt;IAccessible&amp;gt;();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Not all &lt;span style="FONT-WEIGHT: bold"&gt;IHTMLElement&lt;/span&gt; objects support Active Accessibility. Here is the list of the HTML elements that are also accessible elements:&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;A, AREA, BUTTON, INPUT type=BUTTON, INPUT type=RESET, INPUT type=SUBMIT, FRAME, IMG, INPUT type=checkbox, INPUT type=image, INPUT type=password, INPUT type=radio, MARQUEE, OBJECT, APPLET, EMBED, SELECT, TABLE, TD, TH, TEXTAREA, INPUT type=TEXT.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;This technique was successfully implemented and tested in &lt;a href="http://www.codecentrix.com" target="_blank"&gt;My web automation library&lt;/a&gt;.&lt;br /&gt;&lt;a href="http://www.codeproject.com/script/Articles/BlogArticleList.aspx?amid=2505056" rel="tag" style="display:none"&gt; codeproject &lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-3641308424417455694?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/3641308424417455694/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=3641308424417455694' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/3641308424417455694'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/3641308424417455694'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2007/10/from-iaccessible-to-ihtmlelement-and.html' title='From IAccessible to IHTMLElement and back'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-6817594607656315175</id><published>2007-07-17T12:08:00.000-07:00</published><updated>2009-06-02T12:24:02.115-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='js'/><category scheme='http://www.blogger.com/atom/ns#' term='Spell'/><category scheme='http://www.blogger.com/atom/ns#' term='COM'/><category scheme='http://www.blogger.com/atom/ns#' term='ATL'/><category scheme='http://www.blogger.com/atom/ns#' term='Excel'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><category scheme='http://www.blogger.com/atom/ns#' term='script'/><title type='text'>COM number speller</title><content type='html'>&lt;span style="font-family:arial;"&gt;Some time ago, I was asked to provide a way to print numbers as text in Romanian language. Interestingly, I couldn't find an easy way to do this in Excel (Office 2003 as far as I remember). Searching the internet, I found other people having the same problem. Microsoft provides a &lt;/span&gt;&lt;a target="_blank" style="font-family: arial;" href="http://support.microsoft.com/kb/213360"&gt;solution&lt;/a&gt;&lt;span style="font-family:arial;"&gt; for English language, but not for Romanian.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;I decided to create a reusable piece of code that will be easily used in as many environments as possible. I chose COM and ATL to be the solution to my problem. This is also a good programming exercise for my rusty COM / C++ skills and I plan to use it as a template for all my future COM objects.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Points of interest:&lt;/span&gt;&lt;br /&gt;&lt;ul style="font-family: arial;"&gt;&lt;li&gt;error info support by implementing IErrorInfo interface.&lt;/li&gt;&lt;li&gt;Help in CHM format and context identifiers specified in MIDL source file.&lt;/li&gt;&lt;li&gt;BSTR manipulation using CComBSTR class provided by ATL.&lt;/li&gt;&lt;li&gt;IDispatch support, so the component can be used from scripting environments.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Spelling implementation itself and support for multiple languages (only Romanian and English for now).&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;To install the COM object just simply run &lt;/span&gt;&lt;span style="font-style: italic;font-family:arial;" &gt;Install.bat&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Here is the Excel macro that makes use of &lt;/span&gt;&lt;span style="font-style: italic;font-family:arial;" &gt;NumberSpeller&lt;/span&gt;&lt;span style="font-family:arial;"&gt; COM object:&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;Function Spell(n As Currency) As String&lt;br /&gt;'Create the speller object.&lt;br /&gt;Dim s As NumberSpellerLib.speller&lt;br /&gt;Set s = New NumberSpellerLib.speller&lt;br /&gt;&lt;br /&gt;Dim o As Object&lt;br /&gt;Set o = s&lt;br /&gt;o.Language = "ro"&lt;br /&gt;Spell = o.Translate(n)&lt;br /&gt;End Function&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;span style="font-weight: bold;"&gt;Downloads:&lt;/span&gt;&lt;ul&gt;&lt;li&gt;full source code, compiled DLL &lt;span style="font-family:arial;"&gt; and CHM help&lt;/span&gt;: &lt;a href="http://codecentrix.com/blog/com_number_speller/NumberSpeller.zip"&gt;NumberSpeller.zip&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;C++ sample code: &lt;a href="http://codecentrix.com/blog/com_number_speller/NumberSpellerSample1.zip"&gt;NumberSpellerSample1.zip&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Excel sample file: &lt;a href="http://codecentrix.com/blog/com_number_speller/NumberSpellerSample2.zip"&gt;NumberSpellerSample2.zip&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;JS sample file: &lt;a href="http://codecentrix.com/blog/com_number_speller/NumberSpellerSample3.zip"&gt;NumberSpellerSample3.zip&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-6817594607656315175?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/6817594607656315175/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=6817594607656315175' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/6817594607656315175'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/6817594607656315175'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2007/07/com-number-speller.html' title='COM number speller'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18847389.post-4365285149856828888</id><published>2007-05-27T09:26:00.000-07:00</published><updated>2009-06-02T12:23:37.448-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='LEX'/><category scheme='http://www.blogger.com/atom/ns#' term='js'/><category scheme='http://www.blogger.com/atom/ns#' term='tool'/><category scheme='http://www.blogger.com/atom/ns#' term='cpp2html'/><category scheme='http://www.blogger.com/atom/ns#' term='syntax highlighting'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><category scheme='http://www.blogger.com/atom/ns#' term='cpptohtml'/><category scheme='http://www.blogger.com/atom/ns#' term='automate'/><title type='text'>Blogs and C++ syntax highlighting</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-family:arial;"&gt;This wasn't supposed to be my first post. I wanted to start my blogging existence writing about something else. It proved that being a blogger is not as easy as it should be, especially when trying to post some C++ code.&lt;/span&gt; &lt;span style="font-family:arial;"&gt;&lt;span style="font-family:arial;"&gt;The online editor allows to directly modify the HTML code but this is not the simplest or most enjoyable thing to do. &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;span style="font-family:arial;"&gt;Because I wanted C++ syntax highlighting so hard I decided to create a little tool to automate this task as much as possible and to allow me to focus on the real subject.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The result is &lt;span style="font-family:courier new;"&gt;cpptohtml.exe &lt;span style="font-family:arial;"&gt;that takes a &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:arial;"&gt;.cpp &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:arial;"&gt;file as a command line argument and generates a .html file. If no file name is provided as argument, a standard "file open" dialog allows the user to specify the source .cpp file. The tool also accepts &lt;span style="font-family:courier new;"&gt;/C&lt;/span&gt; as command line arguments. When used the source code is taken from clipboard and the HTML result is put also in clipboard.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-family:arial;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:arial;"&gt;I found creating a windows shortcut to &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;span style="font-family:courier new;"&gt;cpptohtml.exe&lt;span style="font-family:arial;"&gt; very useful. This way I can launch the tool by pressing a shortcut key combination (CTR+ALT+T).&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:arial;"&gt;I'm gonna use this tool like this:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;ul style="font-family: arial; text-align: justify;"&gt;&lt;li&gt;open preferred IDE and copy the C++ source code into the clipboard.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;launch the tool using the shortcut key combination. The HTML result is in the clipboard.&lt;/li&gt;&lt;li&gt;paste the formated HTML in the online blog editor.&lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-family:arial;"&gt;&lt;span style="font-weight: bold;"&gt;Download:&lt;/span&gt;&lt;br /&gt;You can find &lt;a href="http://codecentrix.com/blog/blogs_and_cpp_syntax_highlight/CppToHtml.zip"&gt;here&lt;/a&gt; the full source code and the executable. I used Visual C++ and LEX. The archive also contains a &lt;span style="font-family:courier new;"&gt;.js&lt;/span&gt; script to automate the shortcut creation. &lt;/span&gt;&lt;span style="font-family:arial;"&gt;I am pretty happy with the final result and how C++, LEX and JScript combines to automate a boring repetitive task.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Beautiful the technology is!&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18847389-4365285149856828888?l=codecentrix.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codecentrix.blogspot.com/feeds/4365285149856828888/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18847389&amp;postID=4365285149856828888' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/4365285149856828888'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18847389/posts/default/4365285149856828888'/><link rel='alternate' type='text/html' href='http://codecentrix.blogspot.com/2007/05/blogs-and-c-syntax-highlighting.html' title='Blogs and C++ syntax highlighting'/><author><name>CodeCentrix</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://3.bp.blogspot.com/_b7z9mi4EOXE/SNSSnx59mWI/AAAAAAAAAcs/AycJN1Nqz1E/S220/eu3.JPG'/></author><thr:total>12</thr:total></entry></feed>
