<?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-6942369</id><updated>2012-01-29T04:25:24.032-05:00</updated><title type='text'>Mark Finkle's Weblog</title><subtitle type='html'>Software for Fun and Profit</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>49</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6942369.post-114231323504557767</id><published>2006-03-14T00:07:00.000-05:00</published><updated>2006-03-14T00:13:55.060-05:00</updated><title type='text'>Permanent Redirect</title><content type='html'>&lt;p&gt;
I finally decided to get a host of my own. I setup a blog at &lt;a href="www.starkravingfinkle.org"&gt;www.starkravingfinkle.org&lt;/a&gt;. Blogger has been a great experience for me and I would recommend it to anyone. I just wanted more control and space for doing my own thing.
&lt;/p&gt;
&lt;p&gt;
I am updating the FeedBurner &lt;a href="http://feeds.feedburner.com/weborama"&gt;feed&lt;/a&gt;, so anyone actually subscribed should get updated without any problems.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-114231323504557767?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/114231323504557767/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=114231323504557767' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/114231323504557767'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/114231323504557767'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2006/03/permanent-redirect.html' title='Permanent Redirect'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-114188492811435435</id><published>2006-03-09T00:53:00.000-05:00</published><updated>2006-03-09T01:15:28.170-05:00</updated><title type='text'>Live Clipboard &amp; Open Laszlo</title><content type='html'>&lt;p&gt;
Two really cool announcements this week: Ray Ozzie's &lt;a href="http://spaces.msn.com/rayozzie/blog/cns!FB3017FBB9B2E142!285.entry?_c11_blogpart_blogpart=blogview&amp;_c=blogpart#permalink"&gt;Live Clipboard&lt;/a&gt; concept and &lt;a href="http://www.openlaszlo.org/"&gt;Open Laszlo&lt;/a&gt; &lt;a href="http://weblog.openlaszlo.org/archives/2006/03/openlaszlo-goes-dhtml/"&gt;running&lt;/a&gt; on DHTML. I see both announcements having long term effects.
&lt;/p&gt;
&lt;p&gt;
Live Clipboard is just so simple and useful, it has to get adopted, standardized and built into any serious web and non-web applications. That's right, desktop applications and OS shells should also support Live Clipboard. Users will love it. Moving data between web and desktop applications &lt;em&gt;should&lt;/em&gt; be as simple as copy/paste.
&lt;/p&gt;
&lt;p&gt;
Applications built using Open Laszlo can now be run using Flash or DHTML runtimes. So those Laszlo guys were serious after all. They have a demo running on both runtimes. Very nice. This goes a long way toward platform and runtime independence. A trend I'd like to see continue. Maybe a XUL based runtime could happen too.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-114188492811435435?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/114188492811435435/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=114188492811435435' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/114188492811435435'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/114188492811435435'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2006/03/live-clipboard-open-laszlo.html' title='Live Clipboard &amp; Open Laszlo'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-113917614371515151</id><published>2006-02-05T16:37:00.000-05:00</published><updated>2006-02-06T01:36:32.046-05:00</updated><title type='text'>IE7 Changes for MSHTML Embedding</title><content type='html'>&lt;p&gt;
This is post is really for me more than anything else. I have been trying to find some information on what new features IE7 offers for those embedding the WebBrowser control. In the process, I also found some stuff that came out with IE6 during the WinXP SP2 timeframe.
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/workshop/browser/hosting/reference/enum/dochostuiflag.asp"&gt;DOCHOSTUIFLAG&lt;/a&gt;: New flags for navigation and redirect control. Also flags for enabling new "windowless" SELECT elements instead of the old "windowed" versions.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/workshop/security/szone/reference/enums/INTERNETFEATURELIST.asp"&gt;INTERNETFEATURELIST&lt;/a&gt;: This enumeration of features can out in IE6, mainly for controlling security. IE7 adds a couple new features for controlling more security stuff, tabbed browsing and builtin XMLHttpRequest. Also, it provides a way to turn off the damn navigation sounds without hacking the registry. Used with &lt;a href="http://msdn.microsoft.com/workshop/security/szone/reference/functions/cointernetsetfeatureenabled.asp"&gt;CoInternetSetFeatureEnabled&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/workshop/security/szone/overview/sec_featurecontrols.asp"&gt;related API's&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/workshop/author/dhtml/overview/tab_impact.asp"&gt;Tabbed Browsing Developer Summary&lt;/a&gt;: Describes the effects on the DOM, shows how applications hosts can enable tabbed browsing shortcuts, and describes new notifications.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/workshop/essentials/whatsnew/whatsnew_70_sdk.asp"&gt;What's New in Internet Explorer 7&lt;/a&gt;: Summary of the major changes in Internet Explorer 7 of particular interest to the developers.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/workshop/browser/webbrowser/reference/events/newwindow3.asp"&gt;NewWindow3 Event&lt;/a&gt;: Showed up in IE6 XPSP2. Gives developers better control over handling new browser windows.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/feedsapi/rss/rss_entry.asp"&gt;Microsoft Feeds API&lt;/a&gt;: An API for creating, managing, and accessing Really Simple Syndication (RSS) feeds.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/workshop/security/protmode/pmie_ref_entry.asp"&gt;Protected Mode API&lt;/a&gt;: Develop extensions and add-ons for Internet Explorer that can interact with the file system and registry. Includes methods to control a "Save As" dialog and save content to file.&lt;/li&gt;
&lt;li&gt;Many URI related API's: &lt;a href="http://msdn.microsoft.com/workshop/networking/moniker/reference/functions/CreateUri.asp"&gt;CreateUri&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/workshop/networking/moniker/reference/ifaces/IUri/IUri.asp"&gt;IUri interface&lt;/a&gt; just for starters.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
I came across most of this stuff by searching the MSDN site looking for &lt;a href="http://www.google.com/search?q=site%3Amsdn.microsoft.com+%22Internet+Explorer+7+or+later%22"&gt;"Internet Explorer 7 or later"&lt;/a&gt;. I'll try to update this page as I find out more information.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-113917614371515151?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/113917614371515151/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=113917614371515151' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/113917614371515151'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/113917614371515151'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2006/02/ie7-changes-for-mshtml-embedding.html' title='IE7 Changes for MSHTML Embedding'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-113614525156965221</id><published>2006-01-01T14:43:00.000-05:00</published><updated>2006-01-01T21:53:49.966-05:00</updated><title type='text'>VML, SVG and Canvas</title><content type='html'>&lt;p&gt;
Take a couple weeks off from blogging and it's real hard to get back into it. I have been working toward a BETA at my day job, playing around with a web project at home and enjoying the end of year holidays as well.
&lt;/p&gt;
&lt;p&gt;
Anyway, the web project is a web application that makes heavy use of graphics. Started building on IE with &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/workshop/author/vml/SHAPE/introduction.asp"&gt;VML (Vector Markup Language)&lt;/a&gt;. I gained experience using VML from my day job. Had no problems putting together a pretty good vector graphic editor, complete with HTML text inside shapes. The editor would be a core component in the web application. Then I started adding in support for Firefox. The plan was to abstract the VML/SVG differences and use as much common code as possible. JavaScript libraries like &lt;a href="http://prototype.conio.net/"&gt;Prototype&lt;/a&gt; made lots of the work easy.
&lt;/p&gt;
&lt;p&gt;
The big pain was the feature differences between VML and &lt;a href="http://www.w3.org/TR/SVG/"&gt;SVG&lt;/a&gt;. Here are some of the problems:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;VML was built as an extension to HTML. SVG is a separate specification. It took a little time to figure out how to get SVG inside an HTML document (called Inline SVG) to work correctly. Also, I can mix HTML and VML together easily in any combination. SVG requires the use of &amp;lt;foreignObject&amp;gt; to mix in HTML and Firefox does not enable &amp;lt;foreignObject&amp;gt; by default.&lt;/li&gt;
&lt;li&gt;Shapes in VML (&amp;lt;rect&amp;gt;, &amp;lt;ellipse&amp;gt;, etc.) support text child elements. When I reposition the shape, the text moves with it. It appears that shapes can't hold text child elements until SVG 1.2, which supports &amp;lt;flowPara&amp;gt; child elements. For now, changes to the shape must be manually mirrored to the sibling text elements.&lt;/li&gt;
&lt;li&gt;Text in VML supports wordwrap. SVG does not and I can't believe it. Again, SVG 1.2 supports &amp;lt;flowPara&amp;gt;, but I am not sure wordwrap is part of &amp;lt;flowPara&amp;gt;. How long will it take SVG 1.2 to get implemented in Firefox, Safari and Opera?&lt;/li&gt;
&lt;li&gt;VML supports the same level of CSS attributes as HTML. SVG does not support the same level. One attribute I could not use was 'cursor'.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
My biggest problems with SVG are text related. Maybe I just don't know the right way to do it in SVG. I'm still learning.
&lt;/p&gt;
&lt;p&gt;
And then there's &lt;a href="http://www.whatwg.org/specs/web-apps/current-work/#canvas"&gt;&amp;lt;canvas&amp;gt;&lt;/a&gt;. It has good support in Firefox, Safari and Opera (soon). Along comes Emil Eklund with an implementation of &lt;a href="http://me.eae.net/archive/2005/12/29/canvas-in-ie/"&gt;&amp;lt;canvas&amp;gt; in IE&lt;/a&gt; and now I have to consider switching to &amp;lt;canvas&amp;gt; as the lowest common denominator. My biggest problem with &amp;lt;canvas&amp;gt; is text (I see a theme here). I am not sure how to handle text with &amp;lt;canvas&amp;gt;.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-113614525156965221?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/113614525156965221/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=113614525156965221' title='24 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/113614525156965221'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/113614525156965221'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2006/01/vml-svg-and-canvas.html' title='VML, SVG and Canvas'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>24</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-112940813253722754</id><published>2005-10-15T16:06:00.000-04:00</published><updated>2005-10-15T16:28:52.543-04:00</updated><title type='text'>P2P Toolkits</title><content type='html'>&lt;p&gt;
A while ago, I was looking for a P2P framework library that I could use in a software project. The only real P2P toolkits I found were the Java-based &lt;a href="http://jxta.org"&gt;JXTA&lt;/a&gt; and the Windows XP (SP1) &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/downloads/list/winxppeer.asp"&gt;Peer-to-Peer API&lt;/a&gt; from Microsoft. Neither really worked for me. I program in C++ and wanted to support older OSes.
&lt;/p&gt;
&lt;p&gt;
I was too focused on &lt;em&gt;'P2P'&lt;/em&gt; in my searches. It finally dawned on me that &lt;strong&gt;multiplayer games&lt;/strong&gt; have to solve the same problems as a P2P client. Googling turned up several interesting toolkits:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnplay/html/dpov.asp?frame=true"&gt;Microsoft DirectPlay&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.rakkarsoft.com/"&gt;RakNet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.hawksoft.com/hawknl/"&gt;HawkNL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.opentnl.org/"&gt;OpenTNL&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
After looking at all of them, I decided to start working with DirectPlay. It has the easiest API and hides all of the low level socket stuff from me. The biggest potential problem with DirectPlay is that it appears Microsoft is sunsetting it. I don't think it's a issue though. It's still in DirectX and will be for a while. It just won't be developed any further. At some point, when Windows XP is the oldest OS I need to support, I'll switch over to the XP Peer-to Peer API.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-112940813253722754?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/112940813253722754/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=112940813253722754' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/112940813253722754'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/112940813253722754'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2005/10/p2p-toolkits.html' title='P2P Toolkits'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-112758999020961745</id><published>2005-09-24T14:32:00.000-04:00</published><updated>2005-09-25T16:30:25.756-04:00</updated><title type='text'>Improvements in User Experience</title><content type='html'>&lt;h2&gt;Inductive UI in Office 12&lt;/h2&gt;
&lt;p&gt;
By now anyone interested in software user experience has &lt;a href="http://channel9.msdn.com/showpost.aspx?postid=114720"&gt;seen the video&lt;/a&gt; or &lt;a href="http://www.microsoft.com/office/preview"&gt;read the articles&lt;/a&gt; about Microsoft Office 12 getting a complete UI makeover. For an ongoing explanation of the design rationale, you should also checkout &lt;a href="http://blogs.msdn.com/jensenh"&gt;Jensen Harris' blog&lt;/a&gt;. Jensen works on the Office user experience team.
&lt;/p&gt;
&lt;p&gt;
Many people write-off the UI changes as merely a ploy to get customers to upgrade. In a way, I agree. Customers will upgrade because the new interfaces will make using Office easier and allow users to be more productive. Inductive UI's have been around for a while, but this is the first large-scale use in a major Microsoft product.
&lt;/p&gt;
&lt;p&gt;
For those of you in the back, it's not just about the menus and toolbars (or 'Ribbon' as they are calling it). It's about &lt;em&gt;why&lt;/em&gt; the menus are gone and &lt;em&gt;why&lt;/em&gt; the toolbar is separated into contextual sections and chunks. I am glad Microsoft spent the time and money to research &lt;em&gt;how&lt;/em&gt; users were interacting with Office. Since Office seems to set a UX precedent, I am hoping we see some of these new conventions trickle down into other applications as well.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Update: &lt;/strong&gt;Jeff Atwood of Coding Horror has a &lt;a href="http://www.codinghorror.com/blog/archives/000397.html"&gt;post&lt;/a&gt; about this too.
&lt;/p&gt;
&lt;h2&gt;Windows Vista User Experience Guidelines&lt;/h2&gt;
&lt;p&gt;
Microsoft has also released preliminary &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=fd380553-911e-4659-a085-4dd58ae4b9ae&amp;DisplayLang=en"&gt;Windows Vista UX Guidelines&lt;/a&gt;. Although many people are pointing to the download, few are  commenting on the information contained within. &lt;a href="http://chris.pirillo.com/blog/_archives/2005/9/12/1222464.html"&gt;Chris Pirillo&lt;/a&gt; does provide a nice list of nuggets he discovered while scanning the documentation. I'll point out some of my favorites:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Wizard pages: Remove front and back pages. Remove page header. Basically remove all redundant textual information.&lt;/li&gt;
&lt;li&gt;Help on Dialogs: 1. Make labels and controls easy to comprehend, 2. Add explanatory text sections as needed, 3. Use hyperlinks to jump into Help for specific topics which may be confusing, 4. Do not use vague or general Help buttons (users don't like vague or general help).&lt;/li&gt;
&lt;li&gt;Task dialogs: MessageBox API on steriods.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
I like this release better than previous ones (Win2K and WinXP) because it seems more focused on UX and contains some rationale as well. It's not just specs for controls, layout and themes. Some sections, such as Window and Layout sections, are not included yet (it's preliminary). You also need to wade through some Aero graphics babble (I am not impressed with 'glass' for UX).
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-112758999020961745?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/112758999020961745/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=112758999020961745' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/112758999020961745'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/112758999020961745'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2005/09/improvements-in-user-experience.html' title='Improvements in User Experience'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-112321713296742127</id><published>2005-08-05T00:27:00.000-04:00</published><updated>2005-08-05T00:45:32.973-04:00</updated><title type='text'>Jumping In</title><content type='html'>&lt;p&gt;In a rather accidental manner, I am starting up several new projects. I am really getting into &lt;a href="http://en.wikipedia.org/wiki/Wiki"&gt;Wiki's&lt;/a&gt;. I installed &lt;a href="http://www.mediawiki.org/wiki/MediaWiki"&gt;MediaWiki&lt;/a&gt; at work for internal collaboration and knowledge management. I decided to run it on Linux instead of Windows, so I installed &lt;a href="http://www.ubuntulinux.org/"&gt;Ubuntu&lt;/a&gt;. Wow! First time I have ever done anything with a *nix. It's fantastic. I am considering switching my home machine to Ubuntu as well.
&lt;/p&gt;
&lt;p&gt;
I have made many ASP-based web sites before, but now that I had a Linux server, I thought I'd try something different. I installed &lt;a href="http://www.djangoproject.com/"&gt;Django&lt;/a&gt;, mainly because I have always wanted an excuse to learn &lt;a href="http://www.python.org/"&gt;Python&lt;/a&gt;. It was much easier to get going than ASP. I had heard the same thing about Ruby On Rails for a while, but had my doubts. Those doubts are gone.
&lt;/p&gt;
&lt;p&gt;
My biggest problem now is finding the time to explore them all.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-112321713296742127?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/112321713296742127/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=112321713296742127' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/112321713296742127'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/112321713296742127'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2005/08/jumping-in.html' title='Jumping In'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-112270585959382761</id><published>2005-07-30T02:35:00.000-04:00</published><updated>2005-08-05T00:26:54.833-04:00</updated><title type='text'>Hello XUL Runner</title><content type='html'>&lt;p&gt;
I have been playing with &lt;a href="http://wiki.mozilla.org/XUL:Xul_Runner"&gt;XUL Runner&lt;/a&gt;. It feels like writing a web app, but runs on the desktop. Windows, Linux and Mac desktops. Sweet!
&lt;/p&gt;
&lt;p&gt;
Other things I like:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Nice selection of widgets and layouts&lt;/li&gt;
&lt;li&gt;XBL allows new widgets and behavior to be added.&lt;/li&gt;
&lt;li&gt;XPCOM allows calls to JavaScript and C++ non-GUI code.&lt;/li&gt;
&lt;li&gt;SVG support is builtin. (soon)&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/6942369-112270585959382761?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/112270585959382761/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=112270585959382761' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/112270585959382761'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/112270585959382761'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2005/07/hello-xul-runner.html' title='Hello XUL Runner'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-112123295925016966</id><published>2005-07-13T00:14:00.000-04:00</published><updated>2005-07-13T01:41:10.193-04:00</updated><title type='text'>UI Frameworks Are Pigs</title><content type='html'>&lt;p&gt;
Why are UI frameworks pigs? Because they don't love you back.
&lt;/p&gt;
&lt;p&gt;
You know the story: You meet this new UI framework. It seems so fresh and exciting. You start spending more time together, just doing small stuff. Things are so easy, not forced or boring like with your previous frameworks. So what if it acts a little immature. Before you know it, your writing specialized controls from scratch, embedding large amounts of business logic and enjoying every minute of it. Your head over heels. Next thing you know, your crying yourself to sleep and listening to Barry Manilow.
&lt;/p&gt;
&lt;p&gt;
Come on buddy! Snap out of it. UI frameworks don't love you back. They don't care about you. You need to watch out for yourself. Protect yourself. Isolate your code.
&lt;/p&gt;
&lt;p&gt;
If your not ready to drop your current UI framework and switch to something else right now because it could take person-years to port, you have problems. If you have team members that love your current UI framework too much to want to change, you have problems.
&lt;/p&gt;
&lt;p&gt;
They don't love you back.
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;The experiences above are not about me, but I have this friend...&lt;/em&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-112123295925016966?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/112123295925016966/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=112123295925016966' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/112123295925016966'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/112123295925016966'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2005/07/ui-frameworks-are-pigs.html' title='UI Frameworks Are Pigs'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-112122800900135391</id><published>2005-07-13T00:01:00.000-04:00</published><updated>2005-07-13T00:13:29.006-04:00</updated><title type='text'>AJAX and Rocket Science</title><content type='html'>&lt;p&gt;
Seems I am not the &lt;a href="http://weborama.blogspot.com/2005/07/scalable-user-experience.html"&gt;only&lt;/a&gt; &lt;a href="http://weborama.blogspot.com/2005/06/this-just-in-ajax-is-important.html"&gt;one&lt;/a&gt; &lt;a href="http://weborama.blogspot.com/2005/03/ajax-markets-abhor-vacuum.html"&gt;disturbed&lt;/a&gt; by the FUD some groups are pushing about AJAX being very difficult to implement. This &lt;a href="http://www.ajaxian.com/archives/2005/07/ajax_is_rocket.html"&gt;post&lt;/a&gt; has some good examples of how easy it can be.
&lt;/p&gt;
&lt;p&gt;
Writing good, quality software is non-trivial in any language. Wizards and RAD designers do not automagically generate great software.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-112122800900135391?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/112122800900135391/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=112122800900135391' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/112122800900135391'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/112122800900135391'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2005/07/ajax-and-rocket-science.html' title='AJAX and Rocket Science'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-112050725990376047</id><published>2005-07-04T15:48:00.000-04:00</published><updated>2005-07-04T16:14:11.743-04:00</updated><title type='text'>Scalable User Experience</title><content type='html'>&lt;p&gt;
John Montgomery on &lt;a href="http://blogs.msdn.com/johnmont/archive/2005/07/03/435210.aspx"&gt;Scalable User Experience&lt;/a&gt;. Although I disagree with the &lt;em&gt;rocket scientist required&lt;/em&gt; myth, I agree with John's conclusions. I especially like this quote:
&lt;/p&gt;
&lt;blockquote&gt;
Rather than trying to replace every application model in use today with one perfect model, a better solution is to let them flourish and to connect them together so that each can do what it does best. This vision, which I'd call the "Scalable User Experience," is where Atlas begins to take application models. This team is building off three tenets (even if they don't know it):
&lt;ul&gt;
&lt;li&gt;Respect the richness of the client (whatever that is) to provide the best possible user experience&lt;/li&gt;
&lt;li&gt;Contain complexity on the server to build on existing administration skills and infrastructure&lt;/li&gt;
&lt;li&gt;Leave no developer behind by using existing developer skills, code, and tools&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;
I believe that AJAX is a methodology which can help achieve scalable user experiences. I am hoping toolkits like ATLAS can help with some of the weaker aspects of web applications, mainly integration with the desktop client.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-112050725990376047?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/112050725990376047/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=112050725990376047' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/112050725990376047'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/112050725990376047'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2005/07/scalable-user-experience.html' title='Scalable User Experience'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-111998043160874566</id><published>2005-06-28T12:55:00.000-04:00</published><updated>2005-06-28T23:21:05.876-04:00</updated><title type='text'>This Just In: AJAX Is Important</title><content type='html'>&lt;p&gt;
Looks like Microsoft is getting on the AJAX bandwagon, whether they like it or not. &lt;a href="http://radio.weblogs.com/0001011/2005/06/28.html#a10497"&gt;Scoble&lt;/a&gt; mentions a Microsoft Javascript library named ATLAS. &lt;a href="http://news.com.com/Microsoft+gets+hip+to+AJAX/2100-1007_3-5765197.html"&gt;CNET&lt;/a&gt;, &lt;a href="http://www.microsoft-watch.com/article2/0,1995,1832167,00.asp"&gt;Microsoft Watch&lt;/a&gt; and &lt;a href="http://www.informationweek.com/story/showArticle.jhtml?articleID=164903218&amp;tid=5979"&gt;Information Week&lt;/a&gt; posted articles about ATLAS. Charles Fitzgerald is, &lt;a href="http://weborama.blogspot.com/2005/03/ajax-markets-abhor-vacuum.html"&gt;again&lt;/a&gt;, the MS guy involved. Reading the articles, I can't tell if Fitzgerald is excited about ATLAS/AJAX or just feels like its something MS needed to do to stay relevant in web development. Some quotes:
&lt;/p&gt;
&lt;blockquote&gt;
"People who do (AJAX development) are rocket scientists," Fitzgerald said. "In some ways, this papers over the mess that is JavaScript development. It's easy-to-build 'spaghetti' code." [CNET]
&lt;/blockquote&gt;
&lt;blockquote&gt;
"Microsoft is really the only company that spans the continuum, from the simplest Web client through he smartest client," said Fitzgerald. [Microsoft Watch]
&lt;/blockquote&gt;
&lt;blockquote&gt;
"We just needed the clever name" – like Ajax, Fitzgerald said, to explain the various things that developers have been able to do for almost a decade with Microsoft technologies. [Microsoft Watch]
&lt;/blockquote&gt;
&lt;blockquote&gt;
Using Atlas, developers will be able to write Ajax apps that contain pre-written code to smooth over technical distinctions between Web browsers, and debug those apps with Microsoft-branded tools, says Charles Fitzgerald, a general manager at Microsoft. Using Ajax today, he says, "is a little bit of a hack." [Information Week]
&lt;/blockquote&gt;
&lt;p&gt;
Here is what I think:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Microsoft invented the technologies now called AJAX, but moved away from browser based clients in favor of Windows based clients (Smart, Rich, Thick, Fat or otherwise).
&lt;/li&gt;
&lt;li&gt;The world of web development is quickly moving toward AJAX-style development. Microsoft is late and needs to make some mindshare.&lt;/li&gt;
&lt;li&gt;Microsoft is a development tool vendor. They sell tools to make development easier, therefore, current AJAX development must be hard (rocket scientists need only apply) and messy.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Seems to me that many &lt;a href="http://www.google.com/search?q=ajax+toolkits"&gt;AJAX toolkits&lt;/a&gt; already exist. Many web applications are incorporating AJAX very quickly. Examples of AJAX range from simple enhancements to full blown applications, implemented by mere mortals.
&lt;/p&gt;
&lt;p&gt;
This move does not seem in sync with Microsoft's .NET/WebForms/Smart Client agenda. Therefore, I question whether their heart is in the initiative. On the other hand, Microsoft's new &lt;a href="http://msdn.microsoft.com/longhorn/understanding/rss/simplefeedextensions/"&gt;RSS initiative&lt;/a&gt; (also connected to &lt;a href="http://www.microsoft-watch.com/article2/0,1995,1831318,00.asp"&gt;Fitzgerald&lt;/a&gt;) seems inline with current company agendas and has good backing inside and outside the company.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Update:&lt;/strong&gt; &lt;a href="http://spaces.msn.com/members/siteexperts/Blog/cns!1pNcL8JwTfkkjv4gg6LkVCpw!1084.entry"&gt;Scott Isaacs&lt;/a&gt; of MSN Spaces and &lt;a href="http://weblogs.asp.net/scottgu/archive/2005/06/28/416185.aspx"&gt;Scott Guthrie&lt;/a&gt; of ASP.NET have some good technical posts on AJAX.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-111998043160874566?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/111998043160874566/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=111998043160874566' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/111998043160874566'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/111998043160874566'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2005/06/this-just-in-ajax-is-important.html' title='This Just In: AJAX Is Important'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-111993661181675339</id><published>2005-06-27T23:56:00.000-04:00</published><updated>2005-06-29T01:33:37.206-04:00</updated><title type='text'>In Search Of: A Usable UI</title><content type='html'>&lt;p&gt;
Jeremy Zawodny's &lt;a href="http://jeremy.zawodny.com/blog/archives/004853.html"&gt;Surprising User Expectations&lt;/a&gt; post and Jeff Atwood's &lt;a href="http://www.codinghorror.com/blog/archives/000325.html"&gt;UI is Hard&lt;/a&gt; post draw attention to a big problem in software development: Developers rarely design good UI's. I have come to the conclusion that UI design should be handled by people who understand how users think, interact and model problems. This is more of a human factors problem than a coding problem.
&lt;/p&gt;
&lt;p&gt;
I am a big proponent of making usable software. It's one of my crusades. &lt;em&gt;Usability&lt;/em&gt; is not defined by developers, it is defined by users. We recently completed our second phase of usability testing on a new product. It's always a learning experience watching regular people trying to use software. It can be frustrating when it's software I helped to develop. To make better UI's, developers need to appreciate the obstacles that confront users and try remove the obstacles. Usability testing and reading people like Cooper, Nielsen and Norman can give you a better perspective.
&lt;/p&gt;
&lt;p&gt;
Here are a couple guidelines I compiled from my own experiences and from people smarter than me:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Be flexible:&lt;/strong&gt; Allow for multiple ways to get something done. Use main menus, toolbars, right-click menus, task panes and hyperlinks. This allows the user to choose the way most comfortable to them instead of forcing them to learn &lt;em&gt;your&lt;/em&gt; way. Keep in mind that for any given user, the preferred method could change over time.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Be explicit:&lt;/strong&gt; Don't force the user to guess or explore the UI. Use verbose captions, messages and explanations.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Be proactive:&lt;/strong&gt; Don't wait until the user gets into trouble, keep the user from getting into trouble in the first place. Why wait until the end of a process to inform the user they made a mistake at the beginning?&lt;/li&gt; 
&lt;li&gt;&lt;strong&gt;Be forgiving:&lt;/strong&gt; Make it possible for a user to recover from an unwanted action. People make wrong choices. Recovering from a bad choice with most of your data intact is far better than being forced to recreate something from scratch.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Be simple:&lt;/strong&gt; Simple, focused screens and dialogs are easier to learn and allow users to get things done faster.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Be consistent:&lt;/strong&gt; Make use of the fact the users can learn how to do things. Don't force them to re-learn how to do the same or similar things.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
None of these points is revolutionary or even original. But it's amazing how few applications implement them.
&lt;/p&gt;
&lt;p&gt;
Jeff's post has some good links to other articles that are worth checking out. He also brings up the concept of &lt;a href="http://www.sapdesignguild.org/resources/ui_first.asp"&gt;UI First&lt;/a&gt; development. I definitely agree that the UI should be given some focus early in the project. Unless your building an engine or library, the end-user is going to equate the UI with the software. If the UI is bad it won't matter how good the code is behind the scenes.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Update:&lt;/strong&gt; For those interested, a co-woker pointed me to another UI First design methodology at &lt;a href="http://www.humanfactors.com/about/swmethod.asp"&gt;Human Factors International (HFI)&lt;/a&gt;.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-111993661181675339?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/111993661181675339/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=111993661181675339' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/111993661181675339'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/111993661181675339'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2005/06/in-search-of-usable-ui.html' title='In Search Of: A Usable UI'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-111880940346785306</id><published>2005-06-15T00:16:00.000-04:00</published><updated>2005-06-15T00:23:23.470-04:00</updated><title type='text'>MSHTML Hosting Article Published</title><content type='html'>&lt;p&gt;
I wrote an MSHTML hosting article for the &lt;a href="http://bcbjournal.org/"&gt;C++Builder Developer's Journal&lt;/a&gt;. They decided to make the issue freely available. &lt;a href="http://bcbjournal.com/free_issue/vol9_num6.htm"&gt;HTML&lt;/a&gt; and &lt;a href="http://bcbjournal.com/free_issue/bcbj_vol9_num6.pdf"&gt;PDF&lt;/a&gt; versions are available.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-111880940346785306?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/111880940346785306/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=111880940346785306' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/111880940346785306'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/111880940346785306'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2005/06/mshtml-hosting-article-published.html' title='MSHTML Hosting Article Published'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-111880659762374845</id><published>2005-06-14T22:41:00.000-04:00</published><updated>2005-06-14T23:36:37.666-04:00</updated><title type='text'>Rich UI vs User Experience</title><content type='html'>&lt;p&gt;
&lt;a href="http://blogs.msdn.com/johnmont/default.aspx"&gt;John Montgomery&lt;/a&gt; and &lt;a href="http://weblog.infoworld.com/udell"&gt;Jon Udell&lt;/a&gt; are having a discussion about AJAX and rich internet applications. Montgomery is trying to determine what all the fuss over AJAX is about. He played with some toolkits and is unimpressed. Why? He doesn't see how AJAX can compete with Winforms/Webforms on user experience. John &lt;a href="http://blogs.msdn.com/johnmont/archive/2005/06/12/428375.aspx"&gt;says&lt;/a&gt;:
&lt;blockquote&gt;Mostly, Jon's posts got me to thinking about why we (that's you and me - Web users) are OK with degraded user experiences. I mean, for years we had great desktop applications to do things like calendaring and email and even mapping software. Then came the initial Web, where HTML 3.2 and some JavaScript meant that Web apps just couldn't be as nice as local apps. And now we're all very excited about things like Evite, Gmail, and Google maps. But compare Google Maps to Streets and Trips, which I did recently, and the experience with S&amp;T is much better. Same with Outlook vs. Gmail (usually, anyway). Heck, most people read blogs through a Web browser, not an aggregator, even though aggregators are much more efficient.

So why do we let ourselves settle?&lt;/blockquote&gt;
&lt;/p&gt;
&lt;p&gt;
I think he is confusing &lt;em&gt;user experience&lt;/em&gt; for &lt;em&gt;rich widgets&lt;/em&gt;. Web-based applications can achieve a high level of user experience and usability without the need for complex widgets. Good web applications are simple, small and well focused to the task at hand. In fact, I always use the web versions of the applications he lists over the desktop versions.
&lt;/p&gt;
&lt;p&gt;
As John points out, the web-style hyperlink approach, with few options and everything laid out in front of the user, is easy to learn and use. To me, this increases user experience, not degrade it. John also points out that content is more plentiful in web-based applications and users like getting content. So much so that he feels users are willing to give up a great UI if they can get great content. Why does a user want a great UI at all? Seems to me that users only really care about content (or data). I think usability experts like &lt;a href="http://www.useit.com/alertbox/"&gt;Nielsen&lt;/a&gt; and &lt;a href="http://www.cooper.com/"&gt;Cooper&lt;/a&gt; would say a great UI is a UI that allows users to complete tasks without getting in the way. The UI should not be centerstage.
&lt;/p&gt;
&lt;p&gt;
Udell's &lt;a href="http://weblog.infoworld.com/udell/2005/06/14.html#a1250"&gt;posts&lt;/a&gt; point out that AJAX systems have a tendency to allow users access to content they want in ways the web-UI did not anticipate. Also seeming to confirm my suspicion that users don't care much for flashy UI's, but graviate to applications that make it easy to extract and manipulate content. WebDAV and SOAP are not low-hurdle technologies, XmlHttpRequest seems to be. AJAX is a methodology for enhancing web application functionality, not for replicating desktop applications. People don't want desktop applications running in the browser, didn't Java teach us that?
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-111880659762374845?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/111880659762374845/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=111880659762374845' title='19 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/111880659762374845'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/111880659762374845'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2005/06/rich-ui-vs-user-experience.html' title='Rich UI vs User Experience'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>19</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-111769239862853219</id><published>2005-06-02T01:15:00.000-04:00</published><updated>2005-06-02T02:10:24.856-04:00</updated><title type='text'>XML File Formats in Office 12</title><content type='html'>&lt;p&gt;
Brian Jones, program manager on the Word team &lt;a href="http://blogs.msdn.com/brian_jones/archive/2005/06/01/424085.aspx"&gt;posted&lt;/a&gt; news about the new XML file formats in Office 12. I have posted a few times on &lt;a href="http://weborama.blogspot.com/2004/05/using-xml-as-file-format.html"&gt;XML&lt;/a&gt; &lt;a href="http://weborama.blogspot.com/2004/06/high-on-xml.html"&gt;file&lt;/a&gt; &lt;a href="http://weborama.blogspot.com/2005/03/xml-vs-serialization.html"&gt;formats&lt;/a&gt;, so I am interested in what Office is doing. Some interesting points:
&lt;ul&gt;
&lt;li&gt;&lt;span style="font-weight:bold;"&gt;Full fidelity.&lt;/span&gt; As good as the binary format.&lt;/li&gt;
&lt;li&gt;&lt;span style="font-weight:bold;"&gt;Compressed.&lt;/span&gt; Lots of file parts stored in a structured ZIP archive, similar to &lt;a href="http://www.oasis-open.org/committees/office/faq.php"&gt;OpenDocument&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-weight:bold;"&gt;Fully documented.&lt;/span&gt; Whitepapers, documentation and XSD schemas.&lt;/li&gt;
&lt;li&gt;&lt;span style="font-weight:bold;"&gt;Robust.&lt;/span&gt; A lot less likely to get a corrupt file that can't have pieces recovered.&lt;/li&gt;
&lt;/ul&gt;
IMO, the above points could be true for any product using an &lt;a href="http://xml.openoffice.org"&gt;XML package format&lt;/a&gt;, but the fact that Office is doing it means millions of users can escape the data roach motel.
&lt;/p&gt;
&lt;p&gt;
Scoble has more on &lt;a href="http://channel9.msdn.com/ShowPost.aspx?PostID=73329"&gt;Channel 9&lt;/a&gt; as well as his own &lt;a href="http://radio.weblogs.com/0001011/2005/06/01.html#a10287"&gt;blog&lt;/a&gt;. Jones plans to link to whitepapers as soon as they become available on MSDN.
&lt;/p&gt;
&lt;p&gt;
Granted, Office is following OpenDocument here, but this is a really good thing.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-111769239862853219?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/111769239862853219/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=111769239862853219' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/111769239862853219'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/111769239862853219'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2005/06/xml-file-formats-in-office-12.html' title='XML File Formats in Office 12'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-111431922955009319</id><published>2005-04-24T00:42:00.000-04:00</published><updated>2005-04-24T01:20:06.123-04:00</updated><title type='text'>MSHTML Hosting - Drawing On WebBrowser</title><content type='html'>&lt;p&gt;
Hosting the WebBrowser in your application makes it easy to create slick-looking textual UI's. HTML is a fairly expressive markup language and the results can be very professional with little difficulty. The graphical side is a little less impressive. Thankfully, SVG and VML (native support in the WebBrowser control) go a long way to fill the gap. Both have capabilities that blow away good old Win32 GDI drawing. Even so, there may be times that you wish you could grab an HDC for the WebBrowser control and start drawing on it. The WebBrowser control actually has a system built into it that allows you to do just that.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://msdn.microsoft.com/workshop/browser/mshtml/reference/ifaces/painter/ihtmlpainter.asp"&gt;IHTMLPainter&lt;/a&gt; is part of a system in MSHTML called &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/behaviors/binbehaviors_node_entry.asp"&gt;Binary Behaviors&lt;/a&gt;. Behaviors can do lots of cool stuff. Painters are a special kind of behavior called a rendering behavior. IHTMLPainter::Draw is called by MSHTML before or after the HTML content is rendered allowing you to draw below or above the content. MSHTML passes an HDC into method that you can use with any GDI or GDI+ drawing function. Basically, behaviors are COM objects that you implement and are &lt;a href="http://msdn.microsoft.com/workshop/browser/editing/imprendbehav.asp#Attaching_Your_Rendering_Behavior_to_an_Element"&gt;associated &lt;/a&gt; with HTML elements, either in the HTML itself using CSS or progammatically using &lt;a href="http://msdn.microsoft.com/workshop/browser/mshtml/reference/ifaces/element2/addbehavior.asp"&gt;addBehavior&lt;/a&gt;. The MSDN has a nice &lt;a href="http://msdn.microsoft.com/workshop/browser/editing/imprendbehav.asp"&gt;tutorial&lt;/a&gt; on creating a rendering behavior that includes sample code.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-111431922955009319?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/111431922955009319/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=111431922955009319' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/111431922955009319'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/111431922955009319'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2005/04/mshtml-hosting-drawing-on-webbrowser.html' title='MSHTML Hosting - Drawing On WebBrowser'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-111371516378939831</id><published>2005-04-24T00:27:00.000-04:00</published><updated>2005-04-24T00:42:13.490-04:00</updated><title type='text'>XML Services In Desktop Applications</title><content type='html'>&lt;p&gt;
It's pretty fair to say that I'd like to change the way I write desktop applications. I am tired of the UI framework lockin that comes with traditional desktop development. I've posted a &lt;a href="http://weborama.blogspot.com/2004/12/dhtml-based-desktop-applications.html"&gt;couple&lt;/a&gt;            &lt;a href="http://weborama.blogspot.com/2005/02/svg-dhtml-applications.html"&gt;times&lt;/a&gt; about using DHTML+SVG to create a desktop application UI. I have been working on prototypes in DHTML+SVG, as well as &lt;a href="http://www.openlaszlo.org/"&gt;Laszlo&lt;/a&gt; (server-less deployment is now available) and &lt;a href="http://www.xamlon.com/"&gt;Xamlon&lt;/a&gt; (they have a cool new flash-based system in addition to the .NET system).
&lt;/p&gt;
&lt;p&gt;
I am now focusing my attention on non-UI parts of desktop applications and how Web-like techniques could be applied. Desktop applications, large ones specifically, are usually composed of subsystems that are exposed to the user via a host client. IMO, it's important to componentize these subsystems and get them to interact in a way that does not tightly couple them together. Sounds a lot like the definition of a Web service. One way of doing this in C++ is using abstract base classes as interfaces. I am beginning to find this method too object-oriented &lt;a href="http://weborama.blogspot.com/2004/11/ood-less-is-more.html"&gt;for&lt;/a&gt; &lt;a href="http://weborama.blogspot.com/2005/03/holding-state-as-objects-is-painful.html"&gt;my&lt;/a&gt; &lt;a href="http://weborama.blogspot.com/2005/03/objectrelational-mapping-no-thanks.html"&gt;tastes&lt;/a&gt;. The sheer number of interfaces required to support the subsystem can be quite large. Interfaces usually cause a language lockin as well. C++ abstract base classes cannot be used very easily by other languages, unless your willing to completely wrap your interfaces with proxy code.
&lt;/p&gt;
&lt;p&gt;
I am leaning more towards an XML services approach. Each subsystem would have a single entry point which would dispatch XML messages (in a RESTful sorta way) throughout the rest of the subsystem. This approach feels just like Web-based services and has the same kind of benefits. Just about any language can immediately start using the subsystem with minimal effort. The subsystem's dispatch entry point could be made HTTP-aware and suddenly gain the benefits of a true Web service:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Subsystems can be put on different machines.&lt;/li&gt;
&lt;li&gt;HTTP techniques can be used to increase scalability and robustness.&lt;/li&gt;
&lt;li&gt;Many different and special-use clients can be created which leverage the subsystem.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
The kind of subsystems I am referring to include parsers, graph renders, expression evaluators, report generators, data converters and data analysis systems. These are examples of systems that should be made well-defined islands and have great potential for reuse. Instead, they are locked up into the UI client and can not be integrated into other solutions.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-111371516378939831?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/111371516378939831/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=111371516378939831' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/111371516378939831'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/111371516378939831'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2005/04/xml-services-in-desktop-applications.html' title='XML Services In Desktop Applications'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-110893512831520857</id><published>2005-04-02T16:31:00.000-05:00</published><updated>2005-04-02T15:07:05.876-05:00</updated><title type='text'>MSHTML Hosting - More Tricks</title><content type='html'>&lt;p&gt;
Here are a couple miscellaneous tips for using the WebBrowser while in &lt;a href="http://weborama.blogspot.com/2004/10/mshtml-hosting-editing.html"&gt;design (edit) mode&lt;/a&gt;.
&lt;/p&gt;
&lt;strong&gt;Setting Focus In Design Mode&lt;/strong&gt;
&lt;p&gt;
With the WebBrowser control in design mode, there are times that focus (and the blinking cursor) are not set correctly. For example, with focus in the editor, ALT+TAB away from your application, and then back again. Focus may not be set back into the editor. Here is a simple way to fix it. Put this code in an event or message handler that gets called when your application is re-activated:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
IHTMLDocument2* pHTMLDoc2 = ...;
IHTMLWindow2* pWindow = 0;
pHtmlDoc2-&gt;get_parentWindow(&amp;spWindow);
if (pWindow) {
  pWindow-&gt;focus();
  pWindow-&gt;Release();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;strong&gt;Unselecting Current Selection&lt;/strong&gt;
&lt;p&gt;
IHTMLTxtRange has a method to easily select a range of text, but there is no simple method to unselect an existing text selection. Here is a simple way to do it:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
IHTMLDocument2* pHTMLDoc2 = ...;
IHTMLSelectionObject* pSelection = 0;
pHTMLDoc2-&gt;get_selection(&amp;pSelection);
if (pSelection) {
  IDispatch* pDispRange = 0;
  pSelection-&gt;createRange(&amp;pDispRange);

  IHTMLTxtRange* pTxtRange = 0;
  pDispRange-&gt;QueryInterface(IID_IHTMLTxtRange, (void**)&amp;pTxtRange);
  if (pTxtRange) {
    VARIANT_BOOL bSuccess;
    pTxtRange-&gt;execCommand(CComBSTR(L"Unselect"), VARIANT_FALSE, CComVariant(), &amp;bSuccess);
    pTxtRange-&gt;Release();
  }
  pDispRange-&gt;Release();
  pSelection-&gt;Release();
}
&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-110893512831520857?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/110893512831520857/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=110893512831520857' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/110893512831520857'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/110893512831520857'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2005/04/mshtml-hosting-more-tricks.html' title='MSHTML Hosting - More Tricks'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-111126566822476254</id><published>2005-03-19T14:45:00.000-05:00</published><updated>2005-03-19T17:08:42.546-05:00</updated><title type='text'>AJAX - Markets Abhor a Vacuum</title><content type='html'>&lt;p&gt;
If you have only recently heard of greatness of AJAX, then you have not been paying attention for the last 5 years. Not that there's anything wrong with that. Lot's of people are quite excited by the new hype over HTML + JavaScript (+ XML + SVG), myself included. The reason for this post? Just to put down in words some of my reactions to things I've seen written in regard to the new hype.
&lt;/p&gt;
&lt;p&gt;
CNET has an &lt;a href="http://news.com.com/Web+tools+blaze+trail+to+the+past/2100-1032_3-5621010-3.html?tag=st.next"&gt;article&lt;/a&gt; discussing the renaissance and how AJAX may be used in the future, leading to a possible destruction of desktop applications. I love the media. Anyway, Charles Fitzgerald of Microsoft is quoted:
&lt;/p&gt;
&lt;blockquote&gt;"It's a little depressing that developers are just now wrapping their heads around these things we shipped in the late 20th century,"&lt;/blockquote&gt;
&lt;p&gt;
I can agree with that. None of this stuff is brand new. In the same article, David Mendels of Macromedia is quoted:
&lt;/p&gt;
&lt;blockquote&gt; "It is really, really, really hard to build something like Gmail and Google Maps,"&lt;/blockquote&gt;
&lt;blockquote&gt;"Google hired rocket scientists--they hired Adam Bosworth, who invented DHTML when he was at Microsoft. Most companies can't go and repeat what Google has done."&lt;/blockquote&gt;
&lt;p&gt;
I think this is total crap. The article ends with a quote from David Temkin of Laszlo:
&lt;/p&gt;
&lt;blockquote&gt;"The successors to Word and Excel and Powerpoint are not going to be written this way. It's just not going to happen."&lt;/blockquote&gt;
&lt;p&gt;
This seems like a strange thing for a rich Internet application framework vendor like Laszlo to say. Even assuming that David was not quoted out of context, the statement is wrong.
&lt;/p&gt;
&lt;p&gt;
Software products are mainly driven by markets. Users in those markets have needs and software is created to meet those needs. If your company makes a desktop OS, you'll probably make software that runs on the OS. At least until the users' needs change and the market forces you to re-evaluate how you build your software. How quickly you change the way you build your software depends on many factors, including the strength of the market forces and the cost of rewriting your existing codebase.
&lt;/p&gt;
&lt;p&gt;
By the way, writing any kind of software application can be really, really, really hard. There is a difference between building a web-site and writing a web-application. And yes, I do have an aerospace engineering degree. Desktop or web, it's still hard.
&lt;/p&gt;
&lt;p&gt;
My point is that if there was enough of a user need for presentation software that could be run from anywhere, the next version of PowerPoint would be built using an AJAX-like framework. It probably would not be Microsoft that builds it. They have an existing codebase that makes it costly to do such a thing. If PowerPoint was a product of the MSN division, things might be different. IMO, that group is doing some of the best new work at Microsoft.
&lt;/p&gt;
&lt;p&gt;John Gossman has a &lt;a href="http://blogs.msdn.com/johngossman/archive/2005/03/19/399092.aspx"&gt;couple&lt;/a&gt; &lt;a href="http://blogs.msdn.com/johngossman/archive/2005/03/19/399101.aspx"&gt;posts&lt;/a&gt; that also stirred me up. In general, John is definitely worth reading. He agrees with Temkin that Office will not be rewritten using AJAX, but attributes some of that to  browser limitations. Many of those limitations are gone, including the advanced graphics issue he brings up. SVG and VML (in IE) do some pretty cool things. More than enough to drive a decent PowerPoint/Excel replacement.
&lt;/p&gt;
&lt;p&gt;
Robert Scoble brings up offline usage in a recent &lt;a href="http://radio.weblogs.com/0001011/2005/03/19.html#a9672"&gt;post&lt;/a&gt;. Again, this limitation can be overcome. Since IE 5, web applications could use the &lt;a href="http://msdn.microsoft.com/workshop/author/behaviors/reference/behaviors/userdata.asp"&gt;userData behavior&lt;/a&gt; to store data locally. Together with client-side XML/XSLT, its pretty effective. I am sure Mozilla/Firefox has something similar.
&lt;/p&gt;
&lt;p&gt;
The replacement does not need to have all the features of the desktop version. Successful web-based applications (like email, bug-tracking, ERP systems, RSS aggregators and blogging tools) have shown that users are willing to give up some of the "niceties" of a desktop version for the benefits of web-based deployment.
&lt;/p&gt;
&lt;p&gt;
Markets (and users) abhor vacuums. If a web-based PowerPoint vacuum exists, some software vendor will fill it.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-111126566822476254?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/111126566822476254/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=111126566822476254' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/111126566822476254'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/111126566822476254'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2005/03/ajax-markets-abhor-vacuum.html' title='AJAX - Markets Abhor a Vacuum'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-111000929834686695</id><published>2005-03-05T02:40:00.000-05:00</published><updated>2005-03-05T02:56:11.453-05:00</updated><title type='text'>XML vs Serialization</title><content type='html'>&lt;p&gt;
In this &lt;a href="http://www.xmleverywhere.com/tiki/tiki-index.php?page=XML+vs+Serialization"&gt;XML vs Serialization&lt;/a&gt; post, the author lists reasons why XML is not a good serialization format. I would turn the list around and say those are the exact reasons why XML is a good way to develop a serialization format. Even if its just an XML dump of your object model (I think we could do better than that), it's still better than a &lt;span style="font-weight:bold;"&gt;binary&lt;/span&gt; dump.  If my object model changes, and it surely will, I can always transform the older XML dump to the newer structure. Even if its by a hand-written script. You can't easily do that with binary.
&lt;/p&gt;
&lt;p&gt;
Also, I don't believe serialization implies the object model is &lt;span style="font-style:italic;"&gt;more important&lt;/span&gt; than the data. I prefer to think it means the object model &lt;span style="font-style:italic;"&gt;holds&lt;/span&gt; the data.
&lt;/p&gt;
&lt;p&gt;
Via &lt;a href="http://www.mnot.net/blog/2005/03/02/decision_tree"&gt;mnot&lt;/a&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-111000929834686695?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/111000929834686695/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=111000929834686695' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/111000929834686695'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/111000929834686695'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2005/03/xml-vs-serialization.html' title='XML vs Serialization'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-110991297217170763</id><published>2005-03-04T01:59:00.000-05:00</published><updated>2005-03-04T01:09:54.146-05:00</updated><title type='text'>Object/Relational Mapping - No Thanks</title><content type='html'>&lt;p&gt;
I have already &lt;a href="http://weborama.blogspot.com/2005/03/holding-state-as-objects-is-painful.html"&gt;posted&lt;/a&gt; some of my current feelings on using object hierarchies to hold state. It should come as no surprise then, that I am also questioning value of object-to-relational mapping systems. Why in the world would I want some system to create a multitude of objects just so I could manage state (not behavior) using those objects.
&lt;/p&gt;
&lt;p&gt;
I still end up with a brittle object model that is difficult to navigate and breaks when my state changes and exposes the rest of my code to that breakage. SQL and XML both provide simple ways to query and navigate using loosely coupled techniques.
&lt;/p&gt;
&lt;p&gt;
Fewer objects, not more. It does not matter if they are auto-generated or not. I still have to use them in my code.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-110991297217170763?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/110991297217170763/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=110991297217170763' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/110991297217170763'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/110991297217170763'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2005/03/objectrelational-mapping-no-thanks.html' title='Object/Relational Mapping - No Thanks'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-110965960427535246</id><published>2005-03-03T01:43:00.000-05:00</published><updated>2005-03-04T01:09:34.406-05:00</updated><title type='text'>Holding State as Objects is Painful</title><content type='html'>&lt;p&gt;
As a developer, I write code. Code is good. I like code. But the people who use the applications I write could care less about the &lt;span style="font-style: italic;"&gt;precious&lt;/span&gt; code. They care about.. wait for it... the data. Shocking, isn't it. I could have written the most elegant, wonderful code possible, but if I can't move their SuperApp version 1 files to SuperApp version 2, it's worthless.
&lt;/p&gt;
&lt;p&gt;
Coding usually involves either holding state or executing behavior on the state. Holding state as an object hierarchy is really painful. First, someone has to write all those damn classes that map to the state. Then, changes to the state structure break the object model and any code using the object model. Besides brittleness, object models are a pain to walk (or navigate) and difficult to query or filter. Developers usually have to write other framework objects to support parent/child object relationships. Persisting from an object model can also be a pain and increases the likelihood of problems when the state structure (and therefore object model, and therefore persistence format) changes.
&lt;/p&gt;
&lt;p&gt;
I say it's time to let it go. Focus on the data. Protect it. Ensure it's stored in a way that's robust enough to handle future changes. Think about this: MS Word 97 can &lt;a href="http://weblogs.asp.net/chris_pratley/archive/2004/04/28/122004.aspx"&gt;open&lt;/a&gt; an MS Word 2003 file. Somebody was thinking about the data.
&lt;/p&gt;
&lt;p&gt;
Use code to execute behavior on the data. Separate code from data, just like we're told to separate UI from business logic. If you've been reading my &lt;a href="http://weborama.blogspot.com/2004/11/ood-less-is-more.html"&gt;stuff&lt;/a&gt;, it should come as no surprise that I favor separating code from data by using XML to hold state. It's a means to an end. XML supports the kind of structure my state needs. It also supports standard ways to quickly walk or query for a piece of data from my state.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-110965960427535246?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/110965960427535246/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=110965960427535246' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/110965960427535246'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/110965960427535246'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2005/03/holding-state-as-objects-is-painful.html' title='Holding State as Objects is Painful'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-110703669495980953</id><published>2005-02-06T17:10:00.000-05:00</published><updated>2005-02-11T00:55:11.510-05:00</updated><title type='text'>SVG &amp; DHTML Applications</title><content type='html'>&lt;p&gt;
I have been tinkering a lot lately with the concept of writing DHTML-based desktop applications running in a custom web browser. The custom browser would be made to look like the host shell of a standard Windows application with normal menus and toolbars. One of the pieces missing from DHTML applications in the past has been the lack of a graphics rendering system. Scalable Vector Graphics (&lt;a href="http://www.w3.org/TR/SVG/"&gt;SVG&lt;/a&gt;) fills this hole nicely. In fact, SVG will create graphics that rival any graphics library, desktop or otherwise. If you have not played with SVG, you owe it to yourself to have a look.
&lt;/p&gt;
&lt;p&gt;
Besides static graphic rendering, SVG also builds on all the dynamic concepts in DHTML. SVG elements can have attached event handlers for mouse and keyboard events, among others. Javascript can be used to handle any of the events. SVG elements can also be animated very easily.
&lt;/p&gt;
&lt;p&gt;
Currently, SVG is supported in MSHTML/WebBrowser via ActiveX viewers from &lt;a href="http://www.adobe.com/svg/main.html"&gt;Adobe&lt;/a&gt; and &lt;a href="www.corel.com/svg/"&gt;Corel&lt;/a&gt;. &lt;a href="www.mozilla.org/projects/svg/"&gt;Mozilla/Firefox&lt;/a&gt; browsers will have native support sometime in 2005.
&lt;/p&gt;
&lt;p&gt;
I think it is also worth mentioning the MSHTML/WebBrowser does support a native graphic markup language called Vector Markup Language (&lt;a href="http://msdn.microsoft.com/library/default.asp?url=/workshop/author/vml/shape/introduction.asp"&gt;VML&lt;/a&gt;), which predates SVG and is very similar in design. If you want to natively support graphics (No ActiveX), you should consider VML.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-110703669495980953?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/110703669495980953/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=110703669495980953' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/110703669495980953'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/110703669495980953'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2005/02/svg-dhtml-applications.html' title='SVG &amp; DHTML Applications'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-110703636619543642</id><published>2005-02-03T16:41:00.000-05:00</published><updated>2005-02-11T00:54:01.196-05:00</updated><title type='text'>MSHTML Hosting - Editing Tricks</title><content type='html'>&lt;span style="FONT-WEIGHT: bold"&gt;Show Table Borders&lt;/span&gt;
&lt;p&gt;
This is a little feature like you find in MS Word. It will display table invisible borders in light gray color so you can see the structure of the table even if borders are turned off. The feature only works when the WebBrowser is in design mode. Since it's an &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/htm/oin_oc_9bg4.asp"&gt;IOleCommandTarget&lt;/a&gt; editing command ID, it's quite simple to use:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
IHTMLDocument2* pDoc = ...;

// Turn on editor mode
pDoc-&gt;put_designMode(CComBSTR(L"on"));

// Execute some commands
IOleCommandTarget* pCmdTarget = 0;
hr = pDoc-&gt;QueryInterface(IID_IOleCommandTarget, (void**)&amp;pCmdTarget);
if (SUCCEEDED(hr)) {
  pCmdTarget-&gt;Exec(&amp;CGID_MSHTML, &lt;a href="http://msdn.microsoft.com/workshop/browser/mshtml/reference/constants/idm_showzeroborderatdesigntime.asp"&gt;IDM_SHOWZEROBORDERATDESIGNTIME&lt;/a&gt;,
                   OLECMDEXECOPT_DONTPROMPTUSER, CComVariant(true), NULL);
  pCmdTarget-&gt;Release();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
Note the MSDN lists &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/mshtml/reference/mshtml_editing_ref_entry.asp"&gt;editing ID's&lt;/a&gt; separately from &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/mshtml/reference/commandids.asp"&gt;regular ID's&lt;/a&gt;.
&lt;/p&gt;
&lt;span style="FONT-WEIGHT: bold"&gt;Use DIV for Paragraph Breaks&lt;/span&gt;
&lt;p&gt;
Normally, when you press ENTER in design mode, WebBrowser will insert a paragraph tag, &amp;lt;P&amp;gt;, as a break. This can create large amounts whitespace between paragraphs since &amp;lt;P&amp;gt; tags are rendered with more padding than a simple line break. You can setup a CSS class or a style change the padding or you could tell WebBrowser to use &amp;lt;DIV&amp;gt; tags instead. There are two ways I know of to get WebBrowser to use &amp;lt;DIV&amp;gt; tags:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/hosting/reference/ifaces/idochostuihandler/gethostinfo.asp"&gt;IDocHostUIHandler::GetHostInfo&lt;/a&gt; interface method. Look at the &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/hosting/reference/enum/dochostuiflag.asp"&gt;DOCHOSTUIFLAG_DIV_BLOCKDEFAULT&lt;/a&gt; flag.&lt;/li&gt;
&lt;li&gt;Place an empty &amp;lt;DIV /&amp;gt; tag in the HTML you load into WebBrowser before putting it into design mode. Like this:
&lt;pre&gt;&lt;code&gt;
&amp;lt;HTML&amp;gt;
  &amp;lt;BODY&amp;gt;
    &amp;lt;DIV /&amp;gt;
  &amp;lt;/BODY&amp;gt;
&amp;lt;/HTML&amp;gt;
&lt;/code&gt;&lt;/pre&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/6942369-110703636619543642?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/110703636619543642/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=110703636619543642' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/110703636619543642'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/110703636619543642'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2005/02/mshtml-hosting-editing-tricks.html' title='MSHTML Hosting - Editing Tricks'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-110703464344566490</id><published>2005-01-29T16:00:00.000-05:00</published><updated>2005-01-29T17:08:44.746-05:00</updated><title type='text'>MSHTML Hosting - More Editing</title><content type='html'>&lt;p&gt;
&lt;a href="http://weborama.blogspot.com/2004/10/mshtml-hosting-editing.html"&gt;Previously&lt;/a&gt; I talked about exposing the HTML editor hiding inside the WebBrowser control. I also talked about &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/htm/oin_oc_9bg4.asp"&gt;IOleCommandTarget &lt;/a&gt; and how you can control formatting and layout features of the editor. It won't take long before you discover that the IOleCommandTarget command ID's are somewhat limited. At some point, you will need to insert specialized text or HTML at the current cursor location or replacing the current selection. Luckily for us, there is an easy way to do it: &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/mshtml/reference/ifaces/txtrange/txtrange.asp"&gt;IHTMLTxtRange&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
I talked about IHTMLTxtRange in a previous &lt;a href="http://weborama.blogspot.com/2004/09/mshtml-hosting-odds-ends.html"&gt;post&lt;/a&gt;. It is useful for finding text or getting the text of the current selection. It can also do the reverse: It can insert text or HTML at the current cursor location or selection using the &lt;a href="http://msdn.microsoft.com/workshop/browser/mshtml/reference/ifaces/txtrange/pastehtml.asp"&gt;pasteHTML&lt;/a&gt; method. Here's a simple example:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
IHTMLDocument2* pDoc = ...;

IHTMLSelectionObject* pSelection = 0;
HRESULT hr = pDoc-&gt;get_selection(&amp;pSelection);
if (SUCCEEDED(hr)) {
   IDispatch* pDispRange = 0;
   hr = pSelection-&gt;createRange(&amp;pDispRange);
   if (SUCCEEDED(hr)) {
      IHTMLTxtRange* pTextRange = 0;
      hr = pDispRange-&gt;QueryInterface(IID_IHTMLTxtRange, (void**)&amp;pTextRange);
      if (SUCCEEDED(hr)) {
         CComBSTR sText = L"This is &amp;lt;b&amp;gt;better&amp;lt;/b&amp;gt; text";
         pTextRange-&gt;get_pasteHTML(sText);
         pTextRange-&gt;Release();
      }
      pDispRange-&gt;Release();
   }
   pSelection-&gt;Release();
}

pDoc-&gt;Release();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
In the above example, the selection may have selected text or it may just be a cursor location. The HTML overwrites any selected text. Otherwise, it's inserted at the cursor location.
&lt;/p&gt;
&lt;p&gt;
Overall, IHTMLTxtRange is a very useful interface. I have used it for implementing spell check, find/replace and inserting complex HTML. Just to be clear, IHTMLTxtRange works when design mode is off or on. The WebBrowser control does not need to be in edit mode to call pasteHTML.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-110703464344566490?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/110703464344566490/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=110703464344566490' title='17 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/110703464344566490'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/110703464344566490'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2005/01/mshtml-hosting-more-editing.html' title='MSHTML Hosting - More Editing'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>17</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-110559455602855794</id><published>2005-01-13T01:34:00.000-05:00</published><updated>2005-01-13T00:54:52.593-05:00</updated><title type='text'>Hello JavaScript</title><content type='html'>&lt;p&gt;
Coming from a C++ background, I found JavaScript very comfortable when I started doing DHTML programming. I was impressed with some of the things it could do with properties and functions. Other dynamic languages, Python and Ruby for example, have been getting lots of press lately while JavaScript has been quietly powering the Web.
&lt;/p&gt;
&lt;p&gt;
That seems to be changing. I am reading a lot more about JavaScript. This is due in large part to Google's &lt;a href="https://gmail.google.com/"&gt;GMail&lt;/a&gt; and &lt;a href="http://www.google.com/webhp?complete=1&amp;hl=en"&gt;Suggest&lt;/a&gt; (&lt;a href="http://serversideguy.blogspot.com/2004/12/google-suggest-dissected.html"&gt;how it works&lt;/a&gt;). These are great examples of what can be done with DHTML and created a lot of buzz. The &lt;a href="http://javascript.weblogsinc.com"&gt;JavaScript Weblog&lt;/a&gt; posted a summary of &lt;a href="http://javascript.weblogsinc.com/entry/1234000597025597/"&gt;predictions&lt;/a&gt; that seem to be shared by &lt;a href="http://piecesofrakesh.blogspot.com/2005/01/web-applications-wave-of-future.html"&gt;others&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Go JavaScript!
&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-110559455602855794?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/110559455602855794/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=110559455602855794' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/110559455602855794'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/110559455602855794'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2005/01/hello-javascript.html' title='Hello JavaScript'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-110559445858228870</id><published>2005-01-12T23:51:00.000-05:00</published><updated>2005-01-13T00:34:18.583-05:00</updated><title type='text'>MSHTML Hosting - User Content</title><content type='html'>&lt;p&gt;
I have been &lt;a href="http://weborama.blogspot.com/2004/09/mshtml-hosting-building-uis.html"&gt;posting&lt;/a&gt; about using MSHTML to display HTML-based content in your Windows applications. Some of the reasons I started doing this in my own code include:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Easy way to create a modern looking task-based UI.&lt;/li&gt;
&lt;li&gt;Flexible and extensible, with a built-in script engine (JavaScript) and style system (CSS).&lt;/li&gt;
&lt;li&gt;Based on open standards&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
There is another interesting by-product:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Very easy to allow end users to add their own custom HTML.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
You're running a full-blown web browser inside your application. All you need to do is provide some way for the user to specify their own URL. It could be from within the application UI or maybe a special registry key. You pass the URL to &lt;a href="http://msdn.microsoft.com/workshop/browser/webbrowser/reference/ifaces/iwebbrowser2/navigate.asp"&gt;Navigate&lt;/a&gt; and their custom content appears in your application. What a great way to &lt;em&gt;open&lt;/em&gt; your application to your end users.
&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-110559445858228870?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/110559445858228870/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=110559445858228870' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/110559445858228870'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/110559445858228870'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2005/01/mshtml-hosting-user-content.html' title='MSHTML Hosting - User Content'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-110360692836667386</id><published>2004-12-21T01:09:00.000-05:00</published><updated>2004-12-21T00:32:21.370-05:00</updated><title type='text'>MSHTML Hosting - Calling JavaScript From Host</title><content type='html'>&lt;p&gt;
I don't know how often someone would want to call a JavaScript (JS) function in the WebBrowser control from the host application. Since the host can control many, if not more, aspects of the HTML content externally using IDocHostUIHandler or the MSHTML DOM interfaces, it seems unnecessary to implement a method in JS and call that method from the host. But, if you need to for some reason, here's how to do it:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
IHTMLDocument* pHTMLDoc = /* however you can get the IHTMLDocument */

DISPID idMethod = 0;
OLECHAR FAR* sMethod = L"DoSomething";
IDispatch* pScript = 0;
pHTMLDoc-&gt;get_Script(&amp;pScript);
HRESULT hr = pScript-&gt;GetIDsOfNames(IID_NULL, &amp;sMethod, 1, LOCALE_SYSTEM_DEFAULT,
                                    &amp;idSave);
if (SUCCEEDED(hr)) {
  // invoke assuming no method parameters
  DISPPARAMS dpNoArgs = {NULL, NULL, 0, 0};
  hr = pScript-&gt;Invoke(idSave, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD,
                       &amp;dpNoArgs, NULL, NULL, NULL);
}
pScript-&gt;Release();
pHTMLDoc-&gt;Release();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
Notice we are using the IHTMLDocument interface, not the more often used IHTMLDocument2 interface. Also note that I am assuming no arguments are passed to the JS method. Check out &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/automat/htm/chap5_78v9.asp"&gt;IDispatch&lt;/a&gt;::&lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/automat/htm/chap5_61id.asp"&gt;Invoke&lt;/a&gt; for more information on calling a method with arguments. &lt;a href="http://www.codeproject.com"&gt;CodeProject&lt;/a&gt; has a few nice &lt;a href="http://www.codeproject.com/com/TEventHandler.asp"&gt;articles&lt;/a&gt; as well.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-110360692836667386?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/110360692836667386/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=110360692836667386' title='16 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/110360692836667386'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/110360692836667386'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2004/12/mshtml-hosting-calling-javascript-from.html' title='MSHTML Hosting - Calling JavaScript From Host'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>16</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-110159396637334418</id><published>2004-12-13T16:52:00.000-05:00</published><updated>2004-12-15T00:29:36.480-05:00</updated><title type='text'>DHTML-Based Desktop Applications</title><content type='html'>&lt;p&gt;
Recently, I've had several discussions with other developers about UI frameworks. One of the more interesting outcomes is my new desire to create desktop applications using traditionally web-based frameworks. I know it sounds weird, but after looking at the current UI framework landscape and factoring in the latest directions in rich Internet applications, it may not be too crazy. People like &lt;a href="http://weblog.infoworld.com/udell/2004/12/03.html#a1126"&gt;Jon Udell&lt;/a&gt; and &lt;a href="http://www.adambosworth.net"&gt;Adam Bosworth&lt;/a&gt; have spent considerable time discussing the subject. Currently, there are several possible UI frameworks to choose from for commercial, shrink-wrapped applications (it's what I do):
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MFC (Win32)&lt;/strong&gt; - This popular framework should be avoided for new development. It's a dinosaur and will drag your application back into the stone age. It's quickly losing its leading edge status.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WTL (Win32)&lt;/strong&gt; - This framework makes good use of modern C++ techniques, but it's in somewhat of a niche. Again, I don't think it should be used for new development.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;VCL (Win32/NET)&lt;/strong&gt; - I have always liked using this framework. It's really a predecessor to WinForms and .NET libraries. Ease of use and UI productivity is definitely high. There's even a nice migration to .NET from Win32. Borland's commitment is the biggest problem with this framework.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WinForms (NET)&lt;/strong&gt; - The newest framework on block. Same RAD benefits of VCL, without the Borland problem. Well, not exactly. Microsoft is likely to moth-ball this framework before it really has a chance to succeed.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Avalon (NET)&lt;/strong&gt; - The "on-deck" framework, not exactly ready for prime time. You can bet Microsoft will throw a lot of developer support at the framework, but when will it be production ready? And why only run on WinXP and greater? Win2K will still be active for a while and in numbers that commercial applications won't be able to ignore. Perhaps the security benefits of WinXP will cause migration to occur faster.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rich Internet Apps (DHTML / &lt;a href="http://www.macromedia.com/software/flex/"&gt;FLEX&lt;/a&gt; / &lt;a href="http://www.openlaszlo.org/"&gt;Laszlo&lt;/a&gt; / &lt;a href="http://www.mozilla.org/projects/xul/"&gt;XUL&lt;/a&gt;)&lt;/strong&gt; - Not really a framework, but a new category altogether. These kinds of applications are generally browser-based and are really starting to generate a lot of interest. Providing rich applications through a browser results in a better user experience than traditional webpage applications. In addition, these applications are built on frameworks that are also enterprise-ready, with regard to deployment and scalability. However, there appears to be no traction in the desktop application area.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Overall, the UI framework landscape is in the worst shape I have seen in years. As bad as I feel about MFC, at least there was a time where it was ubiquitous, leading-edge and strongly supported. Those days are gone and no other framework has stepped up yet (in reality, not hype). WinForms is probably the safest way to go for now for the following reasons:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It exists right now. Version 2 will be delivered in 2005.&lt;/li&gt;
&lt;li&gt;It is currently built on Win32 API and support for Win32 API will not go away quickly.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Something else I think about is risk. The UI frameworks listed above all have some form of &lt;em&gt;vendor lock-in&lt;/em&gt; or &lt;em&gt;platform lock-in&lt;/em&gt;. I don't feel DHTML has lock-in. I am free to use various implementations on various platforms. It seems like less of a risk when I am not dependent on another company's UI framework. Hey, I try to separate business logic/data from UI code as much as I can, but that only helps mitigate the risk. The risk is still there, the cost of swapping UI frameworks is just smaller. Even XUL and FLEX have lock-in. Laszlo seems to have a plan for using Flash and .NET runtimes, which is a good thing.
&lt;/p&gt;
&lt;p&gt;
What I am thinking about is creating a bare-bones DHTML desktop application runtime using MSHTML (for starters). Much of the needed functionality is already there. I have already &lt;a href="http://weborama.blogspot.com/2004/09/mshtml-hosting-odds-ends.html"&gt;posted&lt;/a&gt; a &lt;a href="http://weborama.blogspot.com/2004/08/working-with-mshtml-hosting.html"&gt;couple&lt;/a&gt; &lt;a href="http://weborama.blogspot.com/2004/09/mshtml-hosting-building-uis.html"&gt;entries&lt;/a&gt; on using MSHTML to augment your Win32 or .NET application. The big difference now is that MSHTML would actual host your application. Think of it as a specialized web browser. Instead of browsing web pages, the primary function would be hosting DHTML applications. Whatever functionality is not already present could be added (generically) using MSHTML extension interfaces.
&lt;/p&gt;
&lt;p&gt;
If rich Internet applications like &lt;a href="http://www.oddpost.com/learnmore"&gt;Oddpost&lt;/a&gt; can be built, surely kick-ass desktop applications are possible as well.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-110159396637334418?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/110159396637334418/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=110159396637334418' title='23 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/110159396637334418'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/110159396637334418'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2004/12/dhtml-based-desktop-applications.html' title='DHTML-Based Desktop Applications'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>23</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-110162098647347766</id><published>2004-11-28T01:28:00.000-05:00</published><updated>2004-11-28T15:07:49.110-05:00</updated><title type='text'>OOD - Less Is More</title><content type='html'>&lt;p&gt;
My primary professional development language has been C++ for as long as I remember. It still is and I have no strong desire to move to something else. That also means that, many years ago, I embraced the Object Oriented Design (OOD) methodology.
&lt;/p&gt;
&lt;p&gt;
I have derived &lt;strong&gt;Cat&lt;/strong&gt; and &lt;strong&gt;Dog&lt;/strong&gt; from &lt;strong&gt;Animal&lt;/strong&gt; many times. At first, it took a while to see the object hierarchies, but it became easier. I loved object hierarchies. The deeper, the better.
&lt;/p&gt;
&lt;p&gt;
Then, I started COM programming and designing using interfaces (abstract base classes) seemed to free my mind of the implementation details. I was happy. I was using interfaces for non-COM code in no time.
&lt;/p&gt;
&lt;p&gt;
Then, I started using templates. First, with the help of the STL. What a concept! Later, with the help of &lt;em&gt;Modern C++ Design&lt;/em&gt; (Andrei Alexandrescu) and the Boost libraries. Implementing design patterns using templates was amazing. Templates allowed me to do things I thought only inheritance could. I am glad I was wrong. Suddenly, my object hierarchies are not as deep.
&lt;/p&gt;
&lt;p&gt;
Then, I started to learn XML and Services. Not really programming, I know, but the concept of storing all that data in a document that could be queried so easily made me question all those class getters and setters. Even some kinds of inheritance seemed overkill. Why can't classes be more behavorial and less stateful? Let XML be the state and just pass it around.
&lt;/p&gt;
&lt;p&gt;
In the end, I'm still using objects. Just less of them. I guess the &lt;strong&gt;data&lt;/strong&gt; is becoming more important than the &lt;strong&gt;code&lt;/strong&gt;.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-110162098647347766?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/110162098647347766/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=110162098647347766' title='16 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/110162098647347766'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/110162098647347766'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2004/11/ood-less-is-more.html' title='OOD - Less Is More'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>16</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-109673118918109233</id><published>2004-10-02T11:14:00.000-04:00</published><updated>2004-10-28T00:25:49.840-04:00</updated><title type='text'>MSHTML Hosting - Editing</title><content type='html'>&lt;p&gt;
Did you know that you can turn WebBrowser into a decent WYSIWYG HTML editor? It's true and it's relatively simple. There are actually two ways to turn on the editor mode: &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/properties/contenteditable.asp?frame=true"&gt;contentEditable&lt;/a&gt; markup attribute, and &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/mshtml/reference/ifaces/document2/designmode.asp?frame=true"&gt;IHTMLDocument2::designMode&lt;/a&gt; method. Since we are talking about embedding WebBrowser in an application, the IHTMLDocument2::designMode method is the most typical choice.
&lt;/p&gt;
&lt;p&gt;
The basic steps are:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="http://weborama.blogspot.com/2004/09/mshtml-hosting-building-uis.html"&gt;Navigate to "about:blank"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://weborama.blogspot.com/2004/09/mshtml-hosting-building-uis.html"&gt;Wait for the blank page to load&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;set designMode to "on"&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
At this point you should be able to type, select, cut, copy and paste into the WebBrowser. But more than that, the editor allows you to quickly add various kinds of HTML formatting markup, such as: Font (Name, Size and Style), Colors, Horizontal lines, Paragraph and line breaks, Justification, and Indenting. It does this through a nice little interface called &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/htm/oin_oc_9bg4.asp?frame=true"&gt;IOleCommandTarget&lt;/a&gt;. The interface has only two methods: QueryStatus and Exec. The interface can be used with many different OLE servers, such as Microsoft Word and Excel, but it is especially useful with WebBrowser.
&lt;/p&gt;
&lt;strong&gt;Using IOleCommandTarget&lt;/strong&gt;
&lt;p&gt;
At the heart of IOleCommandTarget is command identifiers. All commands supported by an implementer of IOleCommandTarget must have an identifier. Here is a list of &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/mshtml/reference/commandids.asp"&gt;MSHTML commands&lt;/a&gt;. Getting an instance of IOleCommandTarget is pretty simple: QueryInterface IHTMLDocument2 for it.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
IHTMLDocument2* pDoc = ...;

// Turn on editor mode
pDoc-&gt;put_designMode(CComBSTR(L"on"));

// Execute some commands
IOleCommandTarget* pCmdTarget = 0;
hr = pDoc-&gt;QueryInterface(IID_IOleCommandTarget, (void**)&amp;pCmdTarget);
if (SUCCEEDED(hr)) {
  // do commands here
  // ...
  pCmdTarget-&gt;Release();
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;QueryStatus provides a way to get the current state of a command. It is of limited value for most commands. Most uses include retreiving the current value of formatting commands. So, if you want to know if a command is supported, QueryStatus does the job. In addition, QueryStatus can be used to determine whether some toggle-type commands, such as IDM_BOLD, are "on" or "off". The following code checks to see if various Edit menu items should be enabled based on the current selection or clipboard contents:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
OLECMD Cmnds[5];
::ZeroMemory(Cmnds, sizeof(OLECMD)*5);
Cmnds[0].cmdID = IDM_COPY;
Cmnds[1].cmdID = IDM_PASTE;
Cmnds[2].cmdID = IDM_CUT;
Cmnds[3].cmdID = IDM_DELETE;
Cmnds[4].cmdID = IDM_SELECTALL;

if (SUCCEEDED(pCmdTarget-&gt;QueryStatus(&amp;CGID_MSHTML, 5, Cmnds, NULL)))
{
  bool bCanCopy = Cmnds[0].cmdf &amp; OLECMDF_ENABLED;
  bool bCanPaste = Cmnds[1].cmdf &amp; OLECMDF_ENABLED;
  bool bCanCut = Cmnds[2].cmdf &amp; OLECMDF_ENABLED;
  bool bCanDelete = Cmnds[3].cmdf &amp; OLECMDF_ENABLED;
  bool bCanSelectAll = Cmnds[4].cmdf &amp; OLECMDF_ENABLED;
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Exec is pretty simple. It provides the way to change the current value, insert a new item or perform an action. Exec allows commands to pass extra information or retrieve information via two VARIANT parameters. Some examples:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
// Set current selection to bold
pCmdTarget-&gt;Exec(&amp;CGID_MSHTML, IDM_BOLD,
                 OLECMDEXECOPT_DONTPROMPTUSER, NULL, NULL);

// Set current selection to tahoma
pCmdTarget-&gt;Exec(&amp;CGID_MSHTML, IDM_FONTNAME,
                 OLECMDEXECOPT_DONTPROMPTUSER, CComVariant("Tahoma"), NULL);

// Set current selection to font size 2 (HTML font sizes, not points)
pCmdTarget-&gt;Exec(&amp;CGID_MSHTML, IDM_FONTSIZE,
                 OLECMDEXECOPT_DONTPROMPTUSER, CComVariant(2), NULL);

// Copy current selection to clipboard
pCmdTarget-&gt;Exec(&amp;CGID_MSHTML, IDM_COPY,
                 OLECMDEXECOPT_DONTPROMPTUSER, NULL, NULL);

&lt;/code&gt;&lt;/pre&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-109673118918109233?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/109673118918109233/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=109673118918109233' title='62 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/109673118918109233'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/109673118918109233'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2004/10/mshtml-hosting-editing.html' title='MSHTML Hosting - Editing'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>62</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-109673007169654082</id><published>2004-10-02T11:11:00.000-04:00</published><updated>2004-10-27T23:57:43.603-04:00</updated><title type='text'>MSHTML Hosting - IDocHostUIHandler</title><content type='html'>&lt;p&gt;
We can't discuss embedding WebBrowser in an application without also discussing &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/hosting/reference/ifaces/idochostuihandler/idochostuihandler.asp?frame=true"&gt;IDocHostUIHandler&lt;/a&gt;. The IDocHostUIHandler (and IDocHostShowUI) interface is the standard method provided by Microsoft for customizing how WebBrowser works when hosted in an application. Some of the things you can use IDocHostUIHandler to do include:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Disable standard right-click, context menu (or provide your own version)&lt;/li&gt;
&lt;li&gt;Turn off the 3D border and scrollbars&lt;/li&gt;
&lt;li&gt;Give the WebBrowser scripting engine access to your special purpose COM methods&lt;/li&gt;
&lt;li&gt;Handle accelerator keys and URL's before MSHTML gets them&lt;/li&gt; 
&lt;/ul&gt;
&lt;p&gt;
IDocHostUIHandler is an interface that you need to implement. How you implement depends on your development language and environment. For most languages, it means deriving a class from IDocHostUIHandler, adding code to the methods you want and returning safe, default values from those you do not want.
&lt;/p&gt;
&lt;p&gt;
The next step is giving MSHTML your implementation of IDocHostUIHandler. Again, this depends on your development language and environment. The easy way is the "ICustomDoc" method. The best way is the "IOleClientSite" method. There is a nice C# &lt;a href="http://www.codeproject.com/books/0764549146_8.asp?df=100&amp;forumid=13574&amp;exp=0&amp;select=719227"&gt;article&lt;/a&gt; on &lt;a href="http://www.codeproject.com"&gt;CodeProject&lt;/a&gt; that discusses both methods (as well as some other good WebBrowser information).
&lt;/p&gt;
&lt;strong&gt;ICustomDoc&lt;/strong&gt;
&lt;p&gt;
This method requires only IDocHostUIHandler to be implemented which keeps things simpler. However, you have to give the interface to MSHTML after each page is loaded. The best way to do it is in the OnDocumentComplete or OnNavigationComplete events. This is the method I currently use in my applications. Code looks something like this:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
IHTMLDocument2* pDoc = ...;
ICustomDoc* pCustom = 0;
hr = pDoc-&gt;QueryInterface(IID_ICustomDoc, (void**)&amp;pCustom);
if (SUCCEEDED(hr)) {
  pCustom-&gt;SetUIHandler(pMyDocHostUIHandler);
  pCustom-&gt;Release();
}

&lt;/code&gt;&lt;/pre&gt;
&lt;strong&gt;IOleClientSite&lt;/strong&gt;
&lt;p&gt;
This method requires that you implement IOleClientSite, as well as IDocHostUIHandler. The benefit is that you only need to give the interfaces to MSHTML once, before any HTML is loaded. I have not used this method in my applications, so I have no code to show you. I am planning on using it soon. I'll update this post when I am finished.
&lt;/p&gt;
&lt;p&gt;
I am switching from ICustomDoc to IOleClientSite mainly because of a transient problem. When the WebBrowser control loads my custom HTML, it waits until it is completely loaded before getting my IDocHostUIHandler, so there is a split second where the borders and scrollbars are not displaying correctly. With IOleClientSite, WebBrowser asks for my IDocHostUIHandler before it loads the HTML.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-109673007169654082?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/109673007169654082/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=109673007169654082' title='24 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/109673007169654082'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/109673007169654082'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2004/10/mshtml-hosting-idochostuihandler.html' title='MSHTML Hosting - IDocHostUIHandler'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>24</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-109469015635199437</id><published>2004-09-08T20:28:00.000-04:00</published><updated>2006-02-05T00:20:07.246-05:00</updated><title type='text'>MSHTML Hosting - Odds &amp; Ends</title><content type='html'>&lt;p&gt;
In this post I wanted to cover some miscellaneous things you may want to do with your embedded WebBrowser. On its own, the IWebBrowser2 interface does not support doing much more than we already covered in previous posts. However, if you start 
using the MSHTML DOM interfaces, much more functionality is available. Here is a list of simple things you can implement without too much difficulty:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Retrieving HTML from the WebBrowser.&lt;/li&gt;
&lt;li&gt;Retrieving the HTML of the current selection.&lt;/li&gt;
&lt;li&gt;Finding text in the HTML and selecting it.&lt;/li&gt;
&lt;li&gt;Creating an image of the current HTML.&lt;/li&gt;
&lt;/ul&gt;
&lt;strong&gt;Retrieving HTML from the WebBrowser&lt;/strong&gt;
&lt;p&gt;
There are times when you might want to get the currently loaded HTML from the control. You may want to save it to a file or parse it for information. For this functionality, you have to use the IPersistXxx interfaces. These are the same we used to load HTML into the WebBrowser from memory. The same works in reverse:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
IHTMLDocument2* pDoc = ...;
IStream* pMyStream = ...;

IPersistStreamInit* pPersist = 0;
HRESULT hr = pDoc-&gt;QueryInterface(IID_IPersistStreamInit, (void**)&amp;pPersist);
if (SUCCEEDED(hr) &amp;&amp; pPersist) {
    hr = pPersist-&gt;Save(pMyStream, true);
    pPersist-&gt;Release();
}

&lt;/code&gt;&lt;/pre&gt;
&lt;strong&gt;Retrieving the HTML of the current selection&lt;/strong&gt;
&lt;p&gt;
If you want to limit the HTML to just what a user has selected, instead of the entire document, we can use the IHTMLXxx COM interfaces. The first thing you need to do is get access to the IHTMLDocument interface for the current document. IWebBrowser2 gives you access using it's Document property. The Document property returns an IDispatch interface, so we need to QueryInterface the IDispatch interface for an IHTMLDocument interface, like so (raw C++):
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
IDispatch* pDocDisp = 0;
HRESULT hr = pWebBrowser-&gt;get_Document(&amp;pDocDisp);

IHTMLDocument2* pDoc = 0;
hr = pDocDisp-&gt;QueryInterface(IID_IHTMLDocument2, (void**)&amp;pDoc);
if (SUCCEEDED(hr)) {

    //...

    pDoc-&gt;Release();
}

pDocDisp-&gt;Release();

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
The IHTMLXxx interfaces follow the W3C DOM specification used for JavaScript very closely. If your familiar with those objects, the IHTMLXxx interface will be easy to grasp. In fact, if you know how to do something using JavaScript, you can duplicate it your compiled code using the IHTMLXxx interfaces.
&lt;/p&gt;
&lt;p&gt;
That said, you can get the current selection as a IHTMLTxtRange from the document element. Once you have a text range, you can retrieve the plain text or HTML text as shown below:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
IHTMLDocument2* pDoc = ...;

IHTMLSelectionObject* pSelection = 0;
HRESULT hr = pDoc-&gt;get_selection(&amp;pSelection);
if (SUCCEEDED(hr)) {
   IDispatch* pDispRange = 0;
   hr = pSelection-&gt;createRange(&amp;pDispRange);
   if (SUCCEEDED(hr)) {
      IHTMLTxtRange* pTextRange = 0;
      hr = pDispRange-&gt;QueryInterface(IID_IHTMLTxtRange, (void**)&amp;pTextRange);
      if (SUCCEEDED(hr)) {
         CComBSTR sText;
         pTextRange-&gt;get_text(&amp;sText);
         // or
         pTextRange-&gt;get_htmlText(&amp;sText);
         //...
         pTextRange-&gt;Release();
      }
      pDispRange-&gt;Release();
   }
   pSelection-&gt;Release();
}

pDoc-&gt;Release();

&lt;/code&gt;&lt;/pre&gt;
&lt;strong&gt;Finding text in the HTML and selecting it&lt;/strong&gt;
&lt;p&gt;
The Google toolbar in IE does this to make it easy to spot keywords found in the page. We are using body and text range objects. This time we are making a IHTMLTxtRange object, not getting the current selection. IHTMLTxtRange has find and select methods that make this task easy. Be sure to check out the parameters for IHTMLTxtRange::findText as they can be used to modify how the text is searched:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
IHTMLDocument2* pDoc = ...;
IHTMLElement* pBodyElem = 0;
HRESULT hr = pDoc-&gt;get_body(&amp;pBodyElem);
if (SUCCEEDED(hr)) {
   IHTMLBodyElement* pBody = 0;
   hr = pBodyElem-&gt;QueryInterface(IID_IHTMLBodyElement, (void**)&amp;pBody);
   if (SUCCEEDED(hr)) {
      IHTMLTxtRange* pTextRange = 0;
      hr = pBody-&gt;createTextRange(&amp;pTextRange);
      if (SUCCEEDED(hr)) {
         CComBSTR sText = "findme";
         VARIANT_BOOL bSuccess;
         hr = pTextRange-&gt;findText(sText, 0, 0, &amp;bSuccess);
         if (SUCCEEDED(hr) &amp;&amp; bSuccess == VARIANT_TRUE)
            pTextRange-&gt;select();
         pTextRange-&gt;Release();
      }
      pBody-&gt;Release();
   }
   pBodyElem-&gt;Release();
}

pDoc-&gt;Release();

&lt;/code&gt;&lt;/pre&gt;
&lt;strong&gt;Creating an image of the current HTML&lt;/strong&gt;
&lt;p&gt;
Turning the contents of the WebBrowser into an image is not as straight forward as you may expect. Looking at the IHTMLXxx interfaces does turn up an IHTMLElementRenderer interface. IHTMLElementRenderer contains:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IHTMLElementRender::DrawToDC(HDC hDC);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
You can try to use this method, but I have found that it is not very reliable and reacts inconsistently depending on the type of HDC you give it. A more reliable method uses an older OLE method. IViewObject supports the ability to render to an HDC. The IWebBrowser2::Document property can be QueryInterfaced for IViewObject. Two things to note while using this method, (1) you will probably want to turn off the scrollbars and 3D border since they will show up in the image and (2) you will want to resize the WebBrowser to the size of the contained HTML if you want to capture the entire content in the image. You may want to only make these changes temporarily and change them back after the image is captured:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
IHTMLDocument2* pDoc = ...;
IHTMLElement* pBodyElem = 0;
HRESULT hr = pDoc-&gt;get_body(&amp;pBodyElem);
if (SUCCEEDED(hr)) {
   IHTMLBodyElement* pBody = 0;
   hr = pBodyElem-&gt;QueryInterface(IID_IHTMLBodyElement, (void**)&amp;pBody);
   if (SUCCEEDED(hr)) {
      // hide 3D border
      IHTMLStyle* pStyle;
      hr = pBodyElem-&gt;get_style(&amp;pStyle);
      if (SUCCEEDED(hr)) {
         pStyle-&gt;put_borderStyle(CComBSTR("none"));
         pStyle-&gt;Release();
      }

      // hide scrollbars
      pBodyElement-&gt;put_scroll(CComBSTR("no"));

      // resize the browser component to the size of the HTML content
      IHTMLElement2* pBodyElement2;
      hr = Body-&gt;QueryInterface(IID_IHTMLElement2, (void**)&amp;BodyElement2)
      if (SUCCEEDED(hr)) {
         long iScrollWidth = 0;
         pBodyElement2-&gt;get_scrollWidth(&amp;iScrollWidth);

         long iScrollHeight = 0;
         pBodyElement2-&gt;get_scrollHeight(&amp;iScrollHeight);

         // these lines depend on your WebBrowser wrapper
         pWebBrowser-&gt;SetWidth(iScrollWidth);
         pWebBrowser-&gt;SetHeight(iScrollHeight);

         pBodyElement2-&gt;Release();

         IViewObject* pViewObject;
         pDoc-&gt;QueryInterface(IID_IViewObject, (void**)&amp;pViewObject);
         if (pViewObject) {
            /* however you want to make your image HDC.
               You can size it using iScrollHeight &amp; iScrollWidth */
            HDC hImageDC = ... // could be bitmap or enhanced metafile
            HDC hScreenDC = ::GetDC(0);
            RECT rcSource = {0, 0, iScrollWidth, iScrollHeight};
            hr = pViewObject-&gt;Draw(DVASPECT_CONTENT, 1, NULL, NULL,
                                   hScreenDC, hImageDC, rcSource,
                                   NULL, NULL, 0);
            ::ReleaseDC(0, hScreenDC);
            pViewObject-&gt;Release();
         }
      }
      pBody-&gt;Release();
   }
   pBodyElem-&gt;Release();
}

pDoc-&gt;Release();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
As you can see, there is a lot of things you can do using the MSHTML object model. Some of it can be tricky. Other things just aren't supported as well as they should be for an application developer. I guess you could say that application developers have their own list of issues for IE.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-109469015635199437?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/109469015635199437/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=109469015635199437' title='261 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/109469015635199437'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/109469015635199437'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2004/09/mshtml-hosting-odds-ends.html' title='MSHTML Hosting - Odds &amp; Ends'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>261</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-109418182410023448</id><published>2004-09-06T06:00:00.000-04:00</published><updated>2004-09-02T23:23:44.100-04:00</updated><title type='text'>MSHTML Hosting - Mozilla</title><content type='html'>&lt;p&gt;
Before moving ahead with the MSHTML hosting posts, I wanted to take a moment to talk about alternatives to WebBrowser. I am sure you are familiar with the Mozilla webbrowser. Started as an open source project by Netscape, Mozilla and its suite of companion projects are quite an achievement. One of the Mozilla projects is an ActiveX wrapper around the rendering engine which conforms to the IWebBrowser2 and DWebBrowserEvents2 COM interfaces. Created and maintained by &lt;a href="http://www.iol.ie/~locka/mozilla/mozilla.htm"&gt;Adam Lock&lt;/a&gt; the project has come along way. There is even minimal support for the IHTMLDocument DOM interfaces.
&lt;/p&gt;
&lt;p&gt;
Everything we have covered in previous posts regarding WebBrowser functionality can be implemented using the Mozilla control as well. With no code changes! Just embed the Mozilla control and your application will not be dependent on Microsoft. Some of us like having choices.
&lt;/p&gt;
&lt;p&gt;
My biggest problem with the Mozilla control is that the project is not moving fast enough to implement more functionality. Honestly, if Mozilla wants to grab more market share, it should be putting more resources on the project. One or two guys is not enough. I know that some people would tell me to just use the native Mozilla C++ classes and interfaces to embed the rendering engine. I am sorry, but there is too much to learn. A very large number of people know, and are comfortable using, ActiveX controls and COM data types. Frameworks have been built to make it easy to use such controls. Why would I want to learn a niche framework? That's the main reason I have not been able to contribute to the project myself. Its a large investment.
&lt;/p&gt;
&lt;p&gt;
That said, I still love the idea of having choices. The Mozilla control is a great start and if I was writing an application that only need basic features, I would seriously consider using it. I hope very much that the project keeps progressing.
&lt;/p&gt;
&lt;strong&gt;More...&lt;/strong&gt;
&lt;p&gt;
&lt;a href="http://nick.typepad.com/blog/2003/11/feeddemon_and_m.html"&gt;Nick Bradury&lt;/a&gt; (author of FeedDemon and TopStyle) on Mozilla control.
&lt;br /&gt;
&lt;a href="http://www.joelonsoftware.com/news/20030601.html"&gt;Joel Spolsky&lt;/a&gt; (of Joel On Software) on why Mozilla should be actively building an ActiveX wrapper.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-109418182410023448?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/109418182410023448/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=109418182410023448' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/109418182410023448'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/109418182410023448'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2004/09/mshtml-hosting-mozilla.html' title='MSHTML Hosting - Mozilla'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-109409718857343616</id><published>2004-09-03T06:00:00.000-04:00</published><updated>2004-09-09T10:48:24.956-04:00</updated><title type='text'>MSHTML Hosting - Building UI's</title><content type='html'>&lt;p&gt;
My &lt;a href="http://weborama.blogspot.com/2004/08/working-with-mshtml-hosting.html"&gt;last&lt;/a&gt; &lt;a href="http://weborama.blogspot.com/2004/08/mshtml-hosting-basics.html"&gt;posts&lt;/a&gt; have dealt with using the WebBrowser component to display HTML pages inside your application. We have seen how it does not take much to embed the control to create your own little mini-webbrowser. In this post I want to go a little further than building a webbrowser. Lots of applications are using a &lt;em&gt;web-like&lt;/em&gt; UI. Applications like Intuit Quicken, Microsoft Outlook and Money actually use the WebBrowser control to achieve their web-like UI's. Microsoft Office task panes and other &lt;a href="http://weborama.blogspot.com/2004/06/task-based-ui-design.html"&gt;inductive UI's&lt;/a&gt; can be developed using the WebBrowser control.
&lt;/p&gt;
&lt;p&gt;
When using the WebBrowser control for building a UI there are a few issues to consider:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Loading the HTML into the control&lt;/strong&gt;. You most likely will not be using &lt;strong&gt;Navigate&lt;/strong&gt; to load the HTML. In most cases you are dynamically generating the HTML from scratch or from a template loaded from a resource.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Handling mouse and keyboard events&lt;/strong&gt;. Since you are building a UI, it is very likely that the content will be interactive. There may be edit boxes, push buttons and hyperlinks in the content. You will need to handle those events and respond accordingly.&lt;/li&gt;
&lt;/ol&gt;
&lt;strong&gt;Loading HTML&lt;/strong&gt;
&lt;p&gt;
The most common (but not the only) way to load HTML from a buffer to the WebBrowser is via streams. Microsoft has a nice &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/webbrowser/tutorials/webocstream.asp"&gt;example&lt;/a&gt; in the WebBrowser reference. A quick Google &lt;a href="http://www.google.com/search?sourceid=navclient&amp;ie=UTF-8&amp;q=webbrowser+load+from+stream"&gt;search&lt;/a&gt; will turn up a way to do it in your favorite tool or language. The key points here are:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Navigate to "about:blank"&lt;/li&gt;
&lt;li&gt;Wait for the blank document to finish loading&lt;/li&gt;
&lt;li&gt;Load your HTML using the IPersistStreamInit method&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Step #3 looks like this:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
IHTMLDocument2* pDoc = ...;
IStream* pMyStream = ...;

IPersistStreamInit* pPersist = 0;
HRESULT hr = pDoc-&gt;QueryInterface(IID_IPersistStreamInit, (void**)&amp;pPersist);
if (SUCCEEDED(hr) &amp;&amp; pPersist) {
    hr = pPersist-&gt;InitNew();
    if (SUCCEEDED(hr)) {
        hr = pPersist-&gt;Load(pMyStream);
    }
    pPersist-&gt;Release();
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
&lt;strong&gt;Note:&lt;/strong&gt; I would strongly recommend that any external links you have in your generated HTML (stylesheets or JavaScript) are referenced using absolute paths. Do not use relative paths. The IPersistStreamInit method does not update the control's &lt;em&gt;base URL&lt;/em&gt;. Navigate does update the base URL. Therefore, any relative path will have "about:blank" prepended to it and the control will not likely find your external link.
&lt;/p&gt;
&lt;strong&gt;Handling Events&lt;/strong&gt;
&lt;p&gt;
The ability to handle mouse and keyboard events is critical when creating an interactive UI. There are 2 basic methods to do this with WebBrowser:
&lt;ol&gt;
&lt;li&gt;Use &lt;strong&gt;&amp;lt;A&amp;gt;&lt;/strong&gt; tags to create hyperlinks with bogus &lt;strong&gt;href&lt;/strong&gt; URL's. Then use OnBeforeNavigate2 to intercept the bogus URL, cancel the navigation and respond to the mouse click.&lt;/li&gt;
&lt;li&gt;Hook your native code to the &lt;strong&gt;onclick&lt;/strong&gt;, &lt;strong&gt;onkeypress&lt;/strong&gt;, or any of the many other JavaScript events.&lt;/li&gt;
&lt;/ol&gt;
&lt;/p&gt;
&lt;p&gt;
Method #1 is cheap and easy, but really only works with hyperlinks.  In my applications, I create bogus hyperlinks that are easy to parse inside OnBeforeNavigate2 and contain breadcrumbs for me to use when responding to the click. Here is an example:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;myapp://edititem/12345&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
I can look for a constant substring to indicate its my bogus HREF (myapp://). I can figure out the type of action (edititem). I also know which item to edit (12345). The last part could be a database ID or a pointer to an object cast to a long integer. The whole thing even looks like a real URL too.
&lt;/p&gt;
&lt;p&gt;
Method #2 is much more robust, but a little more complicated to implement. There are more steps involved. You will also be working with the IHTMLDocument system and creating IDispatch wrappers. We'll cover those topics in future posts.
&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-109409718857343616?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/109409718857343616/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=109409718857343616' title='24 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/109409718857343616'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/109409718857343616'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2004/09/mshtml-hosting-building-uis.html' title='MSHTML Hosting - Building UI&apos;s'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>24</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-109366424205352691</id><published>2004-08-27T23:30:00.000-04:00</published><updated>2004-08-31T01:16:42.106-04:00</updated><title type='text'>MSHTML Hosting - The Basics</title><content type='html'>&lt;p&gt;
Hosting IE in your application is a relatively straight forward process, provided your development environment supports the use of ActiveX controls. Each language/framework has its own way of doing it: VB works directly with the WebBrowser control, MFC has its CHtmlView wrapper classes, Delphi has the TWebBrowser wrapper and C++Builder uses TCppWebBrowser. Create one of these somewhere in your application and your on your way to displaying HTML pages.
&lt;/p&gt;
&lt;p&gt;
Before I go any further, I want to point you to the MSDN documentation of &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/prog_browser_node_entry.asp?frame=true"&gt;reusing the WebBrowser control&lt;/a&gt;. It will be an invaluable reference to you.
&lt;/p&gt;
&lt;p&gt;
The WebBrowser control is really made up of a command interface (IWebBrowser2) and event interfaces (DWebBrowserEvents and DWebBrowserEvents2). Unless you are writing code against the raw control (please don't), your wrapper component will expose both of these sides to you automatically. The event names may be slightly different between components. Here are the most useful methods and events:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Document&lt;/strong&gt; - This property is your means to gain access to the IHTMLDocument2 MSHTML interface. More on this in later posts, I just wanted to point it out now.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Navigate / Navigate2&lt;/strong&gt; - Provides a simple way to tell the WebBrowser to display a page from a given file or URL. Remember to specify the full URL (including http://). Navigate is the simpler method. Both support functionality such as passing in flags to keep the page from displaying in IE's cache list.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GoHome / GoBack / GoForward / Refresh&lt;/strong&gt; - Allow you to mimic the IE functionality with the respective names.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ExecWB&lt;/strong&gt; - Provides a way to get the WebBrowser to execute commands (&lt;a href="http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/mshtml/reference/commandids.asp"&gt;listed here&lt;/a&gt;), such as Print, Print Preview, Save As, Copy and Find.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OnBeforeNavigate2&lt;/strong&gt; - Event that is called before the WebBrowser actually navigates to a given page. This event allows you to cancel or redirect the navigation. Many embedded browser applications use this event to implement "custom protocols" where clicking on a link will display your dialog, for example.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OnDocumentComplete&lt;/strong&gt; - Event that is called when a page is fully loaded into the browser. Use this event as a trigger for hooking up other functionality that can only be done after a page is completely in the browser.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OnNavigateComplete2&lt;/strong&gt; - Event that is fired as individual pieces of the page are loaded. Many people assume this event will only be called once per page load. Not true, it is called once for each frame and then for the page. It is usually safer to use OnDocumentComplete, unless you need to be notified for each frame.&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;
&lt;p&gt;
Using these methods and events, it is very easy to create a nicely featured web browser. Next time we can look at ways to make WebBrowser seem less like a web browser and more like a custom HTML display control you can use inside your application.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-109366424205352691?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/109366424205352691/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=109366424205352691' title='20 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/109366424205352691'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/109366424205352691'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2004/08/mshtml-hosting-basics.html' title='MSHTML Hosting - The Basics'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>20</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-109358210218045593</id><published>2004-08-27T00:26:00.000-04:00</published><updated>2004-08-27T00:48:22.180-04:00</updated><title type='text'>Working With MSHTML Hosting</title><content type='html'>&lt;p&gt;
On the surface it seems like a great deal. You can actually embed MSHTML, the IE HTML rendering engine, in your own application. There is a lot of cool, simple features you get out-of-the-box. As soon as you get more advanced in your features, you find things are not so simple.
&lt;/p&gt;
&lt;p&gt;
First, lets clear up some terminology:
&lt;ul&gt;
&lt;li&gt;WebBrowser - is an ActiveX control that you can embed in your applications to create a mini webbrowser. It will display HTML pages just as well as IE itself.&lt;/li&gt;
&lt;li&gt;MSHTML - is a set of COM interfaces that you can use to programmatically access the elements of an HTML page. The interfaces also allow you to take part in Dynamic HTML events as well as behind the scenes operations like editing, custom rendering and behaviors, and selection.&lt;/li&gt;
&lt;/ul&gt;

WebBrowser depends on MSHTML. In fact there is not much beyond navigating to an HTML page that you can do with WebBrowser alone.
&lt;/p&gt;
&lt;p&gt;
Myself and my team have become quite familiar with the ins and outs of MSHTML hosting. Never have I seen a more clear case of the 80/20 rule. MSHTML will get you 80% of your features very quickly and with relative ease. That last 20% will break most of you.
&lt;/p&gt;
&lt;p&gt;
By no means do I consider myself an expert on MSHTML hosting, but I have implemented some tough features. One of the hardest things about moving past the beginner level stuff is the lack of real examples. I thought I would collect some links to stuff I found useful and post some code examples as well.
&lt;/p&gt;
&lt;p&gt;
More to come
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-109358210218045593?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/109358210218045593/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=109358210218045593' title='55 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/109358210218045593'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/109358210218045593'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2004/08/working-with-mshtml-hosting.html' title='Working With MSHTML Hosting'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>55</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-109280921345691098</id><published>2004-08-18T01:34:00.000-04:00</published><updated>2004-08-27T00:26:10.556-04:00</updated><title type='text'>Mini-Milestones Can't Slip</title><content type='html'>&lt;p&gt;
I am a big proponent of the &lt;strong&gt;staged delivery&lt;/strong&gt; concept of software development. McConnell's treatment really brought it home for me when I first read &lt;a href="http://www.stevemcconnell.com/sg.htm"&gt;Software Survival Guide&lt;/a&gt;. The recent Agile methods also preach the same ideas. It's just good sense: &lt;em&gt;Always have a buildable, releasable product&lt;/em&gt;.
&lt;/p&gt;
&lt;p&gt;
The reason for this post is not to act as a cheerleader for staged delivery. It's to vent-off some steam. At work, we have created a system of mini-milestones we are using to implement staged delivery. The other day we decide to &lt;strong&gt;slip&lt;/strong&gt; a mini-milestone! Feature-creep /scope-creep caused us to miss a milestone!
&lt;/p&gt;
&lt;p&gt;
I lost it. These milestones aren't for creating releases (we are far from that). The milestones act as checkpoints during the development process. The fact that we slipped a mini-milestone tells me that our process needs to be examined. The fact that we slipped is a red flag to me. If we can't contain scope-creep now, at this early point in the process, there is no way we can contain it later.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-109280921345691098?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/109280921345691098/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=109280921345691098' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/109280921345691098'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/109280921345691098'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2004/08/mini-milestones-cant-slip.html' title='Mini-Milestones Can&apos;t Slip'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-109124973252804280</id><published>2004-07-31T00:34:00.000-04:00</published><updated>2005-03-24T02:36:20.000-05:00</updated><title type='text'>More on Task-based UI's</title><content type='html'>&lt;p&gt;
Microsoft published the first &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnforms/html/winforms07202004.asp"&gt;article&lt;/a&gt; of a two-part series on Inductive UI (IUI) design, their buzzword for Task-based UI. This one covers a couple things:
&lt;ul&gt;
&lt;li&gt;How IUI can help users get frequent tasks completed faster.&lt;/li&gt;
&lt;li&gt;What is a frequent task.&lt;/li&gt;
&lt;li&gt;How you can implement a IUI design using a .NET library.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;
If you have ever seen an IUI design (think Task Panes in MS Office 2003), you will almost immediately see Web-style similarities. The article discusses this, referring to Dialog-style versus Web-style UI's. The author does note that in many cases experienced users will prefer Dialog-style UI's over Web-style. While I can agree with the sentiment, it usually happens in cases where the Web-style UI is designed to perform a long, drawn out wizard process. In most cases, such Task Panes, Web-style UI's are just as unobtrusive and straight forward as the Dialog-style counterparts.
&lt;/p&gt;
&lt;p&gt;
Since I am working on a Task Pane infrastructure for an application at work, I was also interested in the details of the Web-style navigation library used to build Task Panes in .NET applications. The library allows programmers to create &lt;em&gt;pages&lt;/em&gt;, which appear to be frame-like surfaces you can drop controls onto.  The library manages a stack of those pages. This is different than our approach, which uses the MSHTML web browser component to host a stack of HTML pages.
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnforms/html/winforms09212004.asp"&gt;Part 2&lt;/a&gt; is available.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-109124973252804280?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/109124973252804280/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=109124973252804280' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/109124973252804280'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/109124973252804280'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2004/07/more-on-task-based-uis.html' title='More on Task-based UI&apos;s'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-108951770396632628</id><published>2004-07-10T23:09:00.000-04:00</published><updated>2004-07-18T17:49:33.013-04:00</updated><title type='text'>Getting Started With P2P</title><content type='html'>&lt;p&gt;
I finally have a reason to try to implement P2P in a development project. I have used TCP sockets on several occasions and I have played around with UDP broadcasts as well. What I am trying to do with P2P needs to be more reliable than the UDP broadcasts. 
&lt;/p&gt;
&lt;p&gt;
The first thing I did was Google for "P2P framework library". Unfortunately, not many relevant hits came back. The most popular was the Java-based &lt;a href="http://jxta.org/"&gt;JXTA&lt;/a&gt; toolkit. I work in C++, so it does not help me. Microsoft has a &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/downloads/list/winxppeer.asp"&gt;Peer-to-Peer&lt;/a&gt; toolkit, but it requires WinXP SP1 with Advanced Networking. I need to support OS's older than that. 
&lt;/p&gt;
&lt;p&gt;
However, both toolkits appear to have exactly what I would in a P2P toolkit: 
&lt;ul&gt;
&lt;li&gt;Discovery&lt;/li&gt;
&lt;li&gt;Peer Groups&lt;/li&gt;
&lt;li&gt;Messaging (including multicast)&lt;/li&gt;
&lt;/ul&gt;
Working in C++ on Win32 (Win9x/WinNT/Win2K/WinXP) keeps me from using these toolkits. 
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;
I would really like to use an existing toolkit to abstract the P2P implementation details. It's going to be hard enough to get my own data sharing protocol working on top of P2P. 
&lt;/p&gt;
&lt;p&gt;
Other toolkits I have looked at include &lt;a href="http://porchdogsoft.com/"&gt;HOWL&lt;/a&gt; (an implementation of Zeroconf/Rendezvous) and &lt;a href="http://beepcore.org/"&gt;BEEP&lt;/a&gt;. HOWL seems to only enable discovery. BEEP seems to only provide the messaging. I might look into merging the two together. I am also looking into wrappers for Multicast over Winsock. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Update:&lt;/strong&gt; I have decided to work with Multicast for now. In the end, I'll need to create some kind of message protocol at which point I'll look at the RFC for BEEP. 
&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-108951770396632628?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/108951770396632628/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=108951770396632628' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/108951770396632628'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/108951770396632628'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2004/07/getting-started-with-p2p.html' title='Getting Started With P2P'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-108701401950901335</id><published>2004-06-11T23:53:00.000-04:00</published><updated>2004-06-12T00:45:47.293-04:00</updated><title type='text'>Selling The Dream</title><content type='html'>&lt;p&gt;
It's bound to happen sooner or later. Every so often &lt;a href="http://radio.weblogs.com/0001011"&gt;Scoble&lt;/a&gt; (Microsoft blogging wunderkind) posts something that makes me question his sensibilities. One of his latest &lt;a href="http://radio.weblogs.com/0001011/2004/06/11.html#a7730"&gt;posts&lt;/a&gt; stopped me dead in my tracks. The post was a reply to a Jon Udell &lt;a href="http://weblog.infoworld.com/udell/2004/06/09.html"&gt;post&lt;/a&gt; on UI technologies in Longhorn. I thought Udell's post asked questions any professional should be asking. Scoble tries to bring it into focus by saying:
&lt;blockquote&gt;
Ahh, but Jon, the real play here is one of programmer productivity
&lt;/blockquote&gt;
Programmer productivity. As if every new technology/language introduced in the last few decades failed to deliver on that same promise. As if Longhorn and .NET are the productivity "tipping point." As if being fluent in multiple technologies/languages is a bad thing. As if being fluent in multiple technologies/languages will go away.
&lt;/p&gt;
&lt;p&gt;
Robert, your overselling the reality. I &lt;em&gt;will&lt;/em&gt; use .NET to create commercial, shrinkwrap and enterprise software someday. I &lt;em&gt;am&lt;/em&gt; becoming fluent in .NET technologies. But you should take a break from the Kool-Aid (although I hear the grape flavor is hard to put down). I see an advantage in understanding multiple technologies/languages and being able to choose the best for a particular situation. If anything, .NET will make the technology soup developers work with worse, not better. Just like every other "productivity improvement" before it.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-108701401950901335?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/108701401950901335/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=108701401950901335' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/108701401950901335'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/108701401950901335'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2004/06/selling-dream.html' title='Selling The Dream'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-108675665075924887</id><published>2004-06-09T00:38:00.000-04:00</published><updated>2004-06-09T00:53:41.006-04:00</updated><title type='text'>High on XML</title><content type='html'>&lt;p&gt;
I have &lt;a href="http://weborama.blogspot.com/2004/05/using-xml-as-file-format.html"&gt;talked&lt;/a&gt; about our experimentation with XML as a file format. This is going very well. Since we started working with XML and its related technologies, other ideas started popping up. It's not like XML is some magic concept, but it does open your mind enough to see other opportunities. Like creating a centralized Web Service to act as a repository for projects. You don't need XML to do something like that, but since XML and Web Services go together, it's easier to visualize how a service like that could be built off of (or into) our persistence system.
&lt;/p&gt;
&lt;p&gt;
I think it's because there are so many examples of XML being used for various things. Anytime you see XML being used for some purpose, you can ask yourself if your use of XML, whatever that may be, can be applied the way someone else uses XML. Another example could be syndication. RSS and Atom are XML-based syndication formats. Can I syndicate our file format? Maybe just modifications. I'll have to float that one internally...
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-108675665075924887?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/108675665075924887/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=108675665075924887' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/108675665075924887'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/108675665075924887'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2004/06/high-on-xml.html' title='High on XML'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-108675226047594950</id><published>2004-06-08T23:12:00.000-04:00</published><updated>2004-06-09T00:53:25.103-04:00</updated><title type='text'>Task-based UI Design</title><content type='html'>&lt;p&gt;
Developing new products is great for trying new things. There is no legacy and lots of freedoms. One of our areas that is screaming for experimentation is the UI. UI models have been changing in recent years. Many products are taking more of a &lt;em&gt;Web&lt;/em&gt;-look. If you start digging into the design reasons, you'll run across discussions of &lt;strong&gt;Task-based UI&lt;/strong&gt; or &lt;strong&gt;Inductive UI&lt;/strong&gt;. It's not hard to find examples, especially from Microsoft: Windows XP uses Task Panes and Web-isms in many parts of the Shell; Office XP also makes heavy use of Task Panes; Applications like Quicken and Money have very &lt;em&gt;Web&lt;/em&gt;-like UI's.
&lt;/p&gt;
&lt;p&gt;
According to &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwui/html/iuiguidelines.asp"&gt;Microsoft&lt;/a&gt;, Task-based UI's are suppose to address the following problems:
&lt;ul&gt;
&lt;li&gt;Users don't seem to construct an adequate mental model of the product.&lt;/li&gt;
&lt;li&gt;Even many long-time users never master common procedures.&lt;/li&gt;
&lt;li&gt;Users must work hard to figure out each feature or screen.&lt;/li&gt;
&lt;/ul&gt;
The solution provided by Task-based UI's is to provide simple, task oriented views that show the user what can be done now and what they can do next.
&lt;/p&gt;
&lt;p&gt;
Obviously, slapping some Task Panes in your application doesn't magically make it easier to use. This method is focused on the &lt;em&gt;User Experience&lt;/em&gt;, but I would go further and say it's &lt;em&gt;User Assistance&lt;/em&gt;. As such, we are involving our Documentation team in establishing the design and guidelines for use in the application. In addition, this method also seems to play well with the teachings of &lt;a href="http://www.cooper.com"&gt;Cooper&lt;/a&gt; and &lt;a href="http://humane.sourceforge.net/home/"&gt;Raskin&lt;/a&gt;. We are looking forward to see the effects on overall usability.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-108675226047594950?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/108675226047594950/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=108675226047594950' title='33 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/108675226047594950'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/108675226047594950'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2004/06/task-based-ui-design.html' title='Task-based UI Design'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>33</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-108572109252261929</id><published>2004-05-28T01:08:00.000-04:00</published><updated>2004-05-30T01:27:50.876-04:00</updated><title type='text'>RAD Test Scripting</title><content type='html'>&lt;p&gt;
The other day, some developer coworkers and I were talking about ways to make it easier for our Test group to create and maintain test scripts. Test scripts are a very important piece of the software development puzzle. But test scripts don't find &lt;strong&gt;new&lt;/strong&gt; defects. Test scripts are really good at finding &lt;strong&gt;breakage&lt;/strong&gt;. That's why scripts are run on new builds as BVT's or release candidates as part of a larger regression suite. For me, few things are worse than uncontrolled breakage to keep a project from hitting deadlines.
&lt;/p&gt;
&lt;p&gt;
To find new defects, you really can't beat good test cases and exploratory testing. We wanted to find ways to keep our Test group working on finding new defects, not struggling to maintain scripts. Our current test scripting tool is just what it claims to be: A scripting tool. The problem with scripting is that it's programming and programming brings a &lt;a href="http://weborama.blogspot.com/2004/05/test-scripts-source-code.htm"&gt;whole set of issues&lt;/a&gt; to the party. We'd like to hide those issues from most of the testers and only have a small team worry about them, if possible.
&lt;/p&gt;
&lt;p&gt;
The genius idea we hit upon was a sort of RAD system for creating test scripts. Ah yes, well I did say we are developers. The general idea is to componentize the creation of scripts. Testers could piece together various script components to create test cases and suites. Of course, there would be a nice Windows application to allow testers to build their projects. We would save the project in an intermediate format and "compile" to native script that our scripting tool would execute.
&lt;/p&gt;
&lt;p&gt;
We even found an additional benefit of the system: By maintaining our test suites in an intermediate format, we avoid script tool vendor lockin. When we switch to a new test scripting tool, we just need to write a new "compiler" to convert to the new script language. Vendor lockin is a real problem.  How many commerical test scripting tools do you know use a common, portable language? It can make switching vendors very costly.
&lt;/p&gt;
&lt;p&gt;
We are currently prototyping a system. I'll let you know how it goes.
&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-108572109252261929?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/108572109252261929/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=108572109252261929' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/108572109252261929'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/108572109252261929'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2004/05/rad-test-scripting.html' title='RAD Test Scripting'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-108542592324728941</id><published>2004-05-24T15:11:00.000-04:00</published><updated>2004-05-28T01:34:30.700-04:00</updated><title type='text'>Test Scripts == Source Code</title><content type='html'>&lt;p&gt;
How is it that a software development company that understands the value and importance of the code their developers write doesn't place the same value on the code their testers write? Good development processes apply to tester too. Regression test scripts are the health indicator of the development process. Build Verification Tests (BVT) or Smoke Tests are very important and, typically, rely on code written by testers.
&lt;/p&gt;
&lt;p&gt;
 Some mistakes I have seen in the past include:
&lt;ul&gt;
&lt;li&gt;Not storing scripts in a source control system&lt;/li&gt;
&lt;li&gt;Not using a common/shared framework to build scripts&lt;/li&gt;
&lt;li&gt;Not spending time to design or review scripts&lt;/li&gt;
&lt;li&gt;Not building robust scripts that can be maintained across development cycles or even within the current cycle&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;
&lt;p&gt;
There is a benefit from using test scripts. There is a cost as well. Use the same good sense you apply to your development process in your testing process.
&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-108542592324728941?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/108542592324728941/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=108542592324728941' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/108542592324728941'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/108542592324728941'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2004/05/test-scripts-source-code.html' title='Test Scripts == Source Code'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-108537515624329669</id><published>2004-05-24T00:49:00.000-04:00</published><updated>2004-05-30T01:29:39.666-04:00</updated><title type='text'>Defects Love New Code</title><content type='html'>&lt;p&gt;
People who know more about software development processes than me, and write books on the subject, frequently talk about metrics like &lt;strong&gt;Defect Density&lt;/strong&gt; (defects per thousand lines of code). Say your development team averages 10 D/KLOC. If you start working on the next version of a product with 1M LOC and eventually add 100K LOC, you could look into your crystal ball and expect 1K defects. Holy crap! Honestly, it could be worse. In my experience, adding code to a 1M line product is likely to break lots of the existing code as well.
&lt;/p&gt;
&lt;p&gt;
What if you start a product completely from scratch and end up with 1M LOC? 10K defects could give the faint of heart a reason to jump out a window. How will you ever know when to ship your product? I have written enough code in various products for various companies to know that those people writing those books know what they're talking about. I have seen it work out just like they predicted it would. Bad things happen to new code. I have come to expect it.
&lt;/p&gt;
&lt;p&gt;
Sometimes people, usually pointy-haired types, get really caught up in things like defect counts. It drives me nuts. Defects are a fact of life in software development. You need to document and prioritize the defects discovered in your products. When it gets close to ship time, look at a cost benefit analysis of each defect. Compare the cost to fix to the cost of leaving it in the product. At some point, you will have to ship your product. It will have defects in it. Knowing what they are is a Good Thing. Making sure the bad ones were fixed is a Good Thing.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.joelonsoftware.com"&gt;Joel On Software&lt;/a&gt; has a good &lt;a href="http://www.joelonsoftware.com/articles/fog0000000014.html"&gt;article&lt;/a&gt; on the cost of fixing defects. &lt;a href="http://www.stevemcconnell.com"&gt;Steve McConnell&lt;/a&gt; also has some &lt;a href="http://www.stevemcconnell.com/bp09.htm"&gt;good&lt;/a&gt; articles about when a product is ready to ship. They apply some rational thinking and decision making, instead of simply the "fix all bugs!" or "zero defect!" mantra pointy-haired types like to spout.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-108537515624329669?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/108537515624329669/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=108537515624329669' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/108537515624329669'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/108537515624329669'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2004/05/defects-love-new-code.html' title='Defects Love New Code'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-108536471316680396</id><published>2004-05-23T22:00:00.000-04:00</published><updated>2004-05-24T11:02:16.886-04:00</updated><title type='text'>Using XML As File Format</title><content type='html'>&lt;p&gt;
In my last &lt;a href="http://weborama.blogspot.com/2004/05/persisting-can-be-painful.html"&gt;post&lt;/a&gt;, I talked about some persistence issues we are working through and how persisting to XML could make things easier for us. In this post, I want to talk about using XML as a file format. Assuming we switch to an XML based file format for our products, there are questions I have regarding the &lt;em&gt;proper&lt;/em&gt; use of XML.
&lt;/p&gt;
&lt;p&gt;
Looking around, I can see at least 2 different categories:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;XML file is a dump of your in-memory state at the time of saving.&lt;/li&gt;
&lt;li&gt;XML file is a system unto itself and should be designed as a standalone deliverable of the product.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
If you read my last post, you could guess the system we built for persisting objects falls clearly in to category #1. If you were to view the resultant XML, I doubt you'd be overwhelmed by the beauty of its structure. The XML is not being used to its full potential. No namespaces, no XPointer or XInclude. Just a raw dump of state stored in XML elements, with very little use of attributes.
&lt;/p&gt;
&lt;p&gt;
On the other hand, if you were to look at the XML created by an MS Office product you would find a decent looking &lt;a href="http://www.microsoft.com/office/xml/default.mspx"&gt;XML document&lt;/a&gt;.  Namespaces are used and the XML elements don't appear to map directly to the product's underlying object model.
&lt;/p&gt;
&lt;p&gt;
Want a better example? Look at a document file created using OpenOffice.  These guys really cared about the &lt;a href="http://xml.openoffice.org/"&gt;XML file structure&lt;/a&gt; and use many XML standards (&lt;a href="http://xml.openoffice.org/xml_specification.pdf"&gt;spec&lt;/a&gt;). In fact, there isn't just a single XML file. They create a ZIP archive and place several XML files in the archive. They also include a manifest file to describe the other files contained in the archive. Whenever possible, they use or extend existing XML based specs to implement their format. Clearly not a direct mapping to their object models.
&lt;/p&gt;
&lt;p&gt;
How important is the XML structure when using XML as a native file format? We could always suggest people use XSLT to change our XML to suit their needs. That sounds reasonable, right?
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-108536471316680396?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/108536471316680396/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=108536471316680396' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/108536471316680396'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/108536471316680396'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2004/05/using-xml-as-file-format.html' title='Using XML As File Format'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6942369.post-108536469636424076</id><published>2004-05-23T21:46:00.000-04:00</published><updated>2004-05-24T00:01:42.486-04:00</updated><title type='text'>Persisting Can be Painful</title><content type='html'>&lt;p&gt;
We are considering changing from an OLE Structured Storage based file format to an XML based file format our flagship product. OLE Structured Storage has served us well, but we are starting to hit walls, especially with versioning and backward/forward compatibility. Yes, forward compatibility!
&lt;/p&gt;
&lt;p&gt;
The product, mainly C++, has objects that save and load their state using a storage system. The storage system is IStorage/IStream and all of the objects know it. That's a minor problem that can be fixed. The bigger problem is the fact that the object hierarchy &lt;strong&gt;defines&lt;/strong&gt; the structure of the file stream. That means any change to the object hierarchy changes the structure of the file stream. Or, any significant change in the object model (version 1.0 to version 2.0) makes it very painful for v2.0 to read v1.0 files. Why the headache? Since each object is responsible for saving/loading is own piece, an object in v2.0 may need to remember what it looked like in v1.0. Even worse, what if an object in v1.0 no longer exists in v2.0? It can get pretty ugly.
&lt;/p&gt;
&lt;p&gt;
A different product, still in development, uses a system that abstracts way the "how" of the persistent storage. The objects that make up the business logic can save and load their state using an abstract storage interface. It has implementations for persisting to binary streams, SQL databases and XML streams. Its not revolutionary, COM's IPersist has allowed developers to do this kind of thing for years. However, we find ourselves primarily using the XML storage more than the others. In fact, we use it for more than persisting to files. We use it for copying state to clipboard and maintaining our Undo/Redo system as well. But I am getting ahead of myself.
&lt;/p&gt;
&lt;p&gt;
I was reading a &lt;a href="http://weblogs.asp.net/chris_pratley/archive/2004/04/28/122374.aspx"&gt;post&lt;/a&gt; by &lt;a href="http://weblogs.asp.net/chris_pratley/"&gt;Chris Pratley&lt;/a&gt; where he talks about Word, RTF and XML:
&lt;/p&gt;
&lt;blockquote&gt;
RTF is used for this purpose instead since it is easier to deal with than Word binary for apps other than Word (remember that is why we created it - it stands for Rich Text interchange Format). The new XML format is designed for exactly that purpose - and it is easier to work with than RTF. You can create the WordML doc (or even a minimal subset) on a server using XML tools, then send the XML to Word on the client and Word will load it up. If you're missing a lot of the Word specific stuff, that's OK - Word will fill in the missing bits with defaults. In fact, you can skip generating the doc on the server if you want - just generate an XML data file in your own schema and provide an XSLT for Word to use when opening the file. That pushes a lot of the processing onto the client.
&lt;/blockquote&gt;
An idea for how to get past some of our versioning issues started to form:
&lt;ol&gt;
&lt;li&gt;What if our objects persisted to XML?&lt;/li&gt;
&lt;li&gt;What if each version only cared about the structure of its XML?&lt;/li&gt;
&lt;li&gt;What if we used XSLT or XQuery to convert one version's XML to another?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
In my mind, forward compatibility (an old version opening a newer version's file) would be hard. Backward compatibility would be easier.  Just transform the old XML to the current version's structure and load it. We could allow newer versions to save files in an older version's XML structure. That would be one way of handling forward compatibility. We are researching this concept to see where it can take us.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6942369-108536469636424076?l=weborama.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://weborama.blogspot.com/feeds/108536469636424076/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6942369&amp;postID=108536469636424076' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/108536469636424076'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6942369/posts/default/108536469636424076'/><link rel='alternate' type='text/html' href='http://weborama.blogspot.com/2004/05/persisting-can-be-painful.html' title='Persisting Can be Painful'/><author><name>Mark Finkle</name><uri>http://www.blogger.com/profile/17141520517633569688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry></feed>
