<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>North Atlanta Web Design</title>
	<atom:link href="https://www.northatlantawebdesign.com/index.php/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.northatlantawebdesign.com</link>
	<description>Programming Examples, Samples, and Tutorials</description>
	<lastBuildDate>Mon, 15 Aug 2011 20:18:35 +0000</lastBuildDate>
	<language>en-US</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=3.7.41</generator>
	<item>
		<title>Adobe Reader X &#8211; Red X with Internet Explorer on Windows 7</title>
		<link>https://www.northatlantawebdesign.com/index.php/2011/08/15/adobe-reader-x-red-x-with-internet-explorer-on-windows-7/</link>
		<comments>https://www.northatlantawebdesign.com/index.php/2011/08/15/adobe-reader-x-red-x-with-internet-explorer-on-windows-7/#comments</comments>
		<pubDate>Mon, 15 Aug 2011 20:17:14 +0000</pubDate>
		<dc:creator><![CDATA[Jeff Gibeau]]></dc:creator>
				<category><![CDATA[Adobe Reader]]></category>
		<category><![CDATA[Adobe Reader X]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[Internet Explorer 8]]></category>
		<category><![CDATA[Windows 7]]></category>
		<category><![CDATA[Embedded PDFs]]></category>
		<category><![CDATA[Fix]]></category>
		<category><![CDATA[Fix Adobe Reader Plugin]]></category>
		<category><![CDATA[Help]]></category>
		<category><![CDATA[Internet Explorer Add-on]]></category>
		<category><![CDATA[Red X]]></category>
		<category><![CDATA[View Embedded PDFs]]></category>

		<guid isPermaLink="false">http://www.northatlantawebdesign.com/?p=225</guid>
		<description><![CDATA[I came across this issue recently while trying to install the latest version of Adobe Reader X (10.1).  Once Adobe Reader X was installed, I was unable to view embedded PDF documents in Internet Explorer 8 on Windows 7 x64.  I did a little research and found out that Adobe Reader is 32-bit only, so]]></description>
				<content:encoded><![CDATA[<p>I came across this issue recently while trying to install the latest version of Adobe Reader X (10.1).  Once Adobe Reader X was installed, I was unable to view embedded PDF documents in Internet Explorer 8 on Windows 7 x64.  I did a little research and found out that Adobe Reader is 32-bit only, so you are supposed to use Internet Explorer 8 32-bit.  No problem.  I switched over, but to my avail, I was still unable to view embedded PDF documents.  A little red x would show up in their place, meaning the Active X plugin had failed.<br />
<span id="more-225"></span><br />
I checked the DLLs loaded into  the IE process and noticed that only AcroIEHelper and  AcroIEHelperShim files had loaded.  I tested on a working machine and  there were a few more Acro dlls loaded including AcroPDF.dll.  I assumed the shim was failing  to load the correct DLL.  It turned out I was missing a registry key pointing to the AcroPDF.dll that is required by the plugin.  To  fix it, I added the following to my registry (Window 7 x64):</p>
<pre class="brush: cpp; title: ; notranslate">
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Ext\Stats\{CA8A9780-280D-11CF-A24D-444553540000}]

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Ext\Stats\{CA8A9780-280D-11CF-A24D-444553540000}\iexplore]
&quot;Type&quot;=dword:00000001
&quot;Flags&quot;=dword:00000000
&quot;Count&quot;=dword:00000003
&quot;Time&quot;=hex:db,07,08,00,01,00,0f,00,10,00,0e,00,32,00,05,02
</pre>
<p>I added the same set of keys in my HKEY_USERS section (same path, but with the user id added between HKEY_USERS and Software).</p>
<p>This fixed the issue on my machine, and it loaded the embedded pdf next time I tried opening one in IE8.</p>
<p><strong>NOTE</strong>:</p>
<p><strong>{CA8A9780-280D-11CF-A24D-444553540000}</strong> is the Class ID for my installed AcroPDF plugin.  It may be different  on your system depending on the version of Reader you have installed.   You should replace it with your Class ID which you can find with the  following method:</p>
<ul>
<li>Open IE</li>
<li>Go to &#8220;Tools&#8221;-&gt;&#8221;Manage Add-ons&#8221;</li>
<li>Change &#8220;Show:&#8221; to &#8220;Run without permission&#8221;</li>
<li>Right click on &#8220;Adobe PDF Reader&#8221;</li>
<li>Click &#8220;More Information&#8221;</li>
<li>The information is in Class ID</li>
</ul>
<p>Hopefully this will help someone.  I know I wasted nearly a day of development time trying to work through this issue.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.northatlantawebdesign.com/index.php/2011/08/15/adobe-reader-x-red-x-with-internet-explorer-on-windows-7/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Windows 7 Tip: Select a File Instead of Searching When Typing Inside of Windows Explorer</title>
		<link>https://www.northatlantawebdesign.com/index.php/2010/10/26/windows-7-tip-select-a-file-instead-of-searching-when-typing-inside-of-windows-explorer/</link>
		<comments>https://www.northatlantawebdesign.com/index.php/2010/10/26/windows-7-tip-select-a-file-instead-of-searching-when-typing-inside-of-windows-explorer/#comments</comments>
		<pubDate>Tue, 26 Oct 2010 18:39:07 +0000</pubDate>
		<dc:creator><![CDATA[Jeff Gibeau]]></dc:creator>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[Windows 7]]></category>
		<category><![CDATA[Tip]]></category>
		<category><![CDATA[Windows 7 Tips]]></category>
		<category><![CDATA[Windows Explorer]]></category>

		<guid isPermaLink="false">http://www.northatlantawebdesign.com/?p=201</guid>
		<description><![CDATA[Windows 7 contains a lot of little differences from what you might be used to in earlier versions of Windows (2000, XP, Vista). For new computer users, this is not an issue, but for those of us who have been using computers for years, they can quickly become annoying. The latest I&#8217;ve come across is [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Windows 7 contains a lot of little differences from what you might be used to in earlier versions of Windows (2000, XP, Vista).  For new computer users, this is not an issue, but for those of us who have been using computers for years, they can quickly become annoying.</p>
<p>The latest I&#8217;ve come across is how when browsing a directory in Windows Explorer in <a title="Windows 7 Home Premium" href="http://www.amazon.com/gp/product/B002DHGMK0?ie=UTF8&amp;tag=cheesymovieni-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=B002DHGMK0">Windows 7</a>, if you start typing it actually activates and starts searching the directory (and sub-directories) for what you are typing.  This is a pretty cool feature, but doing development, I usually know what file I&#8217;m looking for, and want to select the file while typing, not search.  It is easy to change this behavior, while still leaving the search option easily accessible by using the keyboard shortcut <strong>ctrl+f</strong>.</p>
<p><span id="more-201"></span></p>
<ol>
<li>Open Windows Explorer.</li>
<li>Select <em><strong>Organize</strong></em>.
<p><div id="attachment_210" style="width: 160px" class="wp-caption alignnone"><a href="http://www.northatlantawebdesign.com/wp-content/uploads/2010/10/Select-Organize.png"><img class="size-thumbnail wp-image-210 " title="Select Organize" src="http://www.northatlantawebdesign.com/wp-content/uploads/2010/10/Select-Organize-150x150.png" alt="Select Organize" width="150" height="150" /></a><p class="wp-caption-text">Select Organize</p></div></li>
<li>Select <em><strong>Folder and Search Options</strong></em>.
<p><div id="attachment_209" style="width: 160px" class="wp-caption alignnone"><a href="http://www.northatlantawebdesign.com/wp-content/uploads/2010/10/Select-Folder-and-Search-Options.png"><img class="size-thumbnail wp-image-209" title="Select Folder and Search Options" src="http://www.northatlantawebdesign.com/wp-content/uploads/2010/10/Select-Folder-and-Search-Options-150x150.png" alt="Select Folder and Search Options" width="150" height="150" /></a><p class="wp-caption-text">Select Folder and Search Options</p></div></li>
<li>Select the <em><strong>View</strong></em> Tab.</li>
<li>At the bottom of the <em><strong>Advanced Settings</strong></em> list, change the radio button under <em><strong>When typing into list view</strong></em> to <em><strong>Select the typed item in the view</strong></em>.
<p><div id="attachment_211" style="width: 160px" class="wp-caption alignnone"><a href="http://www.northatlantawebdesign.com/wp-content/uploads/2010/10/Select-the-typed-item-in-the-view.png"><img class="size-thumbnail wp-image-211" title="Select the typed item in the view" src="http://www.northatlantawebdesign.com/wp-content/uploads/2010/10/Select-the-typed-item-in-the-view-150x150.png" alt="Select the typed item in the view" width="150" height="150" /></a><p class="wp-caption-text">Select the typed item in the view</p></div></li>
</ol>
<p>Remember, after changing this setting that you can still easily access the search box by pressing <strong>Control + F</strong> on your keyboard.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.northatlantawebdesign.com/index.php/2010/10/26/windows-7-tip-select-a-file-instead-of-searching-when-typing-inside-of-windows-explorer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Publishers be Careful with Facebook Connect</title>
		<link>https://www.northatlantawebdesign.com/index.php/2009/10/21/publishers-be-careful-with-facebook-connect/</link>
		<comments>https://www.northatlantawebdesign.com/index.php/2009/10/21/publishers-be-careful-with-facebook-connect/#comments</comments>
		<pubDate>Wed, 21 Oct 2009 16:08:58 +0000</pubDate>
		<dc:creator><![CDATA[Jeff Gibeau]]></dc:creator>
				<category><![CDATA[Web Design]]></category>
		<category><![CDATA[Anonymity]]></category>
		<category><![CDATA[Anonymous]]></category>
		<category><![CDATA[CNN]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[Facebook Connect]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Publishers]]></category>
		<category><![CDATA[Web Publishers]]></category>

		<guid isPermaLink="false">http://www.northatlantawebdesign.com/?p=178</guid>
		<description><![CDATA[Web publishers are constantly looking to increase traffic, usability, and interaction with their sites. The new Facebook Connect allows for Facebook users to simply click a button to be able to comment on a site, or interact with the site. This sounds like a great idea up front. Take an extremely popular social network with [&#8230;]]]></description>
				<content:encoded><![CDATA[<p><!--6e137ad4f26c4427bd602a8e71d44c35--><br />
<span class="wp-decoratr-image"> </span></p>
<div style="width: 250px" class="wp-caption alignleft"><img title="Designing for the Social Web" src="http://farm4.static.flickr.com/3588/3394810309_19db8a7dbb_m.jpg" alt="Designing for the Social Web" width="240" height="160" /><p class="wp-caption-text">Designing for the Social Web</p></div>
<p>Web publishers are constantly looking to increase traffic, usability, and interaction with their sites.  The new Facebook Connect allows for Facebook users to simply click a button to be able to comment on a site, or interact with the site.  This sounds like a great idea up front.  Take an extremely popular social network with millions of users and hook that into your site and the possibilities are endless.</p>
<p>Publishers need to be careful though.  While the thought of adding millions of users to a site may seem good, there is a major downside to Facebook Connect that a local user system does not have.  Anonymity.<span id="more-178"></span></p>
<p>Lots of people use sites for fun, while using Facebook to connect with real people that they know and interact with daily.  They like the idea of having a separate entity where they don&#8217;t have to mix the two.  Forcing users to sign into your site and comment with their Facebook profile may, and likely will, turn some users off.  This could result in losing a solid user base, and driving away your power users as they fish for new sites that provide an anonymous shell.</p>
<p>Take CNN for example. They recently integrated with Facebook Connect replacing their old comment system.  Lots of heated political discussions take place on their stories, with lots of very opinionated users.  Being anonymous helps a person deliver their true opinion, rather than the watered down one they share with people face to face.  Can you fathom getting in a heated argument face to face with someone on how you feel about illegal immigration or health care?  Not just talking about it, but a borderline argument?  Most likely not.  With Facebook Connect on CNN you open yourself up to doing just that, which could damage someone&#8217;s real reputation because of an opinion.</p>
<p style="text-align: left;">
<div style="width: 250px" class="wp-caption alignright"><img title="Google 50 Year Lego Anniversary" src="http://farm3.static.flickr.com/2068/2226178289_3f9556c08f_m.jpg" alt="Google 50 Year Lego Anniversary" width="240" height="161" /><p class="wp-caption-text">Google 50 Year Lego Anniversary</p></div>
<p>Lets take this one step further.  A trend in hiring new employees in the past few years has been to Google them, or even check out their profiles on Facebook.  If a potential employer is able to search for comments you have made on sites with Facebook Connect integrated, that could potentially harm your chances of being hired.</p>
<p>So publishers, keep in mind, that while Facebook Connect seems like a great idea up front, the loss of anonymity may diminish your user base in the long run.  The thought of sharing opinions and information, passed along with a link into their social life may scare users away.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.northatlantawebdesign.com/index.php/2009/10/21/publishers-be-careful-with-facebook-connect/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VBScript String Methods in a Simple PHP Class</title>
		<link>https://www.northatlantawebdesign.com/index.php/2009/08/24/vbscript-string-methods-in-a-simple-php-class/</link>
		<comments>https://www.northatlantawebdesign.com/index.php/2009/08/24/vbscript-string-methods-in-a-simple-php-class/#comments</comments>
		<pubDate>Mon, 24 Aug 2009 20:42:52 +0000</pubDate>
		<dc:creator><![CDATA[Jeff Gibeau]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[VBScript]]></category>
		<category><![CDATA[Class]]></category>
		<category><![CDATA[Strings]]></category>
		<category><![CDATA[Wrapper]]></category>

		<guid isPermaLink="false">http://www.northatlantawebdesign.com/?p=172</guid>
		<description><![CDATA[When some people start out in a new language, they are in it for the long haul.  Other people sometimes just need to touch on it without getting into the details.  PHP is one of those languages where you can do things in a quick and dirty way without getting into the details.  I have [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>When some people start out in a new language, they are in it for the long haul.  Other people sometimes just need to touch on it without getting into the details.  <a type="amzn">PHP</a> is one of those languages where you can do things in a quick and dirty way without getting into the details.  I have written a simple class for the kind of person that just wants to get a few things done quickly that is familiar with VBScripting.  The class is mainly a wrapper class that allows you to perform <a type="amzn">VBScript</a> style methods on strings in PHP.  For instance, you can use VBScript::Left($string, $length) instead of using PHP&#8217;s substr($string, 0, $length).  Enjoy!<br />
<span id="more-172"></span></p>
<pre class="brush: php; title: ; notranslate">
&lt;?php
/*****************************************************************************\
Author: Jeff Gibeau
WebSite: http://www.NorthAtlantaWebDesign.com
Purpose:
A string operation wrapper class that allows you to use VBScript style methods
in place of PHP style methods.  Recreates all methods from:

http://www.w3schools.com/VBscript/vbscript_ref_functions.asp#string

\*****************************************************************************/
class VBString
{
	//Returns the position of the first occurrence of one string within another.
	//The search begins at the first character of the string.
	function InStr($haystack, $needle, $startPosition = 0)
	{
		return strpos($haystack, $needle, $startPosition);
	}
	
	//Returns the position of the first occurrence of one string within another.
	//The search begins at the last character of the string.
	function InStrRev($haystack, $needle, $startPosition = 0)
	{
		if(floatval(phpversion()) &gt;= 5)
			return strrpos($haystack, $needle, $startPosition);
		else
			return strrpos($haystack, $needle);
	}
	
	//Converts a specified string to lowercase.
	function LCase($string)
	{
		return strtolower($string);
	}
	
	//Returns a specified number of characters from the left side of a string.
	function Left($string, $length)
	{
		return substr($string, 0, $length);
	}
	
	//Returns the number of characters in a string.
	function Len($string)
	{
		return strlen($string);
	}
	
	//Removes spaces on the left side of a string.
	function LTrim($string)
	{
		return ltrim($string);
	}
	
	//Removes spaces on the right side of a string.
	function RTrim($string)
	{
		return rtrim($string);
	}
	
	//Removes spaces on both the left and the right side of a string.
	function Trim($string)
	{
		return trim($string);
	}
	
	//Returns a specified number of characters from a string.
	function Mid($string, $start, $length = &quot;&quot;)
	{
		if(!empty($length))
			return substr($string, $start, $length);
		else
			return substr($string, $start);
	}
	
	//Replaces a specified part of a string with another string a specified
	//number of times.
	function Replace($haystack, $needle, $replaceWith, $start = -1, $count = -1)
	{
		$returnVal = $haystack;
		if($start != -1)
		{
			if($count != -1 &amp;&amp; floatval(phpversion()) &gt;= 5)
			{
				$returnVal = substr($haystack, 0, $start) . str_replace($needle, $replaceWith, substr($haystack, $start), $count);
			}
			else
			{
				$returnVal = substr($haystack, 0, $start) . str_replace($needle, $replaceWith, substr($haystack, $start));
			}
		}
		else
		{
			if($count != -1 &amp;&amp; floatval(phpversion()) &gt;= 5)
			{
				$returnVal = str_replace($needle, $replaceWith, $haystack, $count);
			}
			else
			{
				$returnVal = str_replace($needle, $replaceWith, $haystack);
			}
		}
		return $returnVal;
	}
	
	//Returns a specified number of characters from the right side of a string.
	function Right($string, $count)
	{
		return substr($string, ($count * -1));
	}
	
	//Returns a string that consists of a specified number of spaces.
	function Space($numSpaces)
	{
		$returnVal = '';
		for($i = 0; $i &lt; $numSpaces; $i++)
			$returnVal .= ' ';
		return $returnVal;
	}
	
	//Compares two strings and returns a value that represents the result of
	//the comparison.
	function StrComp($string1, $string2)
	{
		return strcmp($string1, $string2);
	}
	
	//Returns a string that contains a repeating character of a specified length.
	function String($length, $character)
	{
		$returnVal = '';
		while(strlen($returnVal) &lt; $length)
			$returnVal .= $character;
		return substr($returnVal, 0, $length);
	}
	
	//Reverses a string.
	function StrReverse($string)
	{
		return strrev($string);
	}
	
	//Converts a specified string to uppercase.
	function UCase($string)
	{
		return strtoupper($string);
	}
}
?&gt;
</pre>
<p>Using this class</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php
require_once 'vbstring_class.php';
$string1 = '  The quick brown fox jumped over the lazy dog.  ';
$string2 = 'he';
$string3 = 'hat';
$nl = &quot;\n&quot;;
echo '
&lt;style&gt;
* { font-family:courier; }
span.answer { color:red; background:#eeeeee;border:1px solid #ccc; }
&lt;/style&gt;
&lt;pre&gt;
';
//VBString::InStr
echo 'VBString::InStr(&quot;'.$string1.'&quot;, &quot;'.$string2.'&quot;) -&gt; &lt;span class=&quot;answer&quot;&gt;'. VBString::InStr($string1, $string2).'&lt;/span&gt;'.$nl;

//VBString::InStrRev
echo 'VBString::InStrRev(&quot;'.$string1.'&quot;, &quot;'.$string2.'&quot;) -&gt; &lt;span class=&quot;answer&quot;&gt;'. VBString::InStrRev($string1, $string2).'&lt;/span&gt;'.$nl;

//VBString::LCase
echo 'VBString::LCase(&quot;'.$string1.'&quot;) -&gt; &lt;span class=&quot;answer&quot;&gt;&quot;'. VBString::LCase($string1).'&quot;&lt;/span&gt;'.$nl;

//VBString::Left
echo 'VBString::Left(&quot;'.$string1.'&quot;, 5) -&gt; &lt;span class=&quot;answer&quot;&gt;&quot;'.VBString::Left($string1, 5).'&quot;&lt;/span&gt;'.$nl;

//VBString::Len
echo 'VBString::Len(&quot;'.$string1.'&quot;) -&gt; &lt;span class=&quot;answer&quot;&gt;'.VBString::Len($string1).'&lt;/span&gt;'.$nl;

//VBString::LTrim
echo 'VBString::LTrim(&quot;'.$string1.'&quot;) -&gt; &lt;span class=&quot;answer&quot;&gt;&quot;'.VBString::LTrim($string1).'&quot;&lt;/span&gt;'.$nl;

//VBString::RTrim
echo 'VBString::RTrim(&quot;'.$string1.'&quot;) -&gt; &lt;span class=&quot;answer&quot;&gt;&quot;'.VBString::RTrim($string1).'&quot;&lt;/span&gt;'.$nl;

//VBString::Trim
echo 'VBString::Trim(&quot;'.$string1.'&quot;) -&gt; &lt;span class=&quot;answer&quot;&gt;&quot;'.VBString::Trim($string1).'&quot;&lt;/span&gt;'.$nl;

//VBString::Mid
echo 'VBString::Mid(&quot;'.$string1.'&quot;, 5, 5) -&gt; &lt;span class=&quot;answer&quot;&gt;&quot;'.VBString::Mid($string1, 5, 5).'&quot;&lt;/span&gt;'.$nl;

//VBString::Replace
echo 'VBString::Replace(&quot;'.$string1.'&quot;, &quot;'.$string2.'&quot;, &quot;'.$string3.'&quot;, 5) -&gt; &lt;span class=&quot;answer&quot;&gt;&quot;'.VBString::Replace($string1, $string2, $string3, 5).'&quot;&lt;/span&gt;'.$nl;

//VBString::Right
echo 'VBString::Right(&quot;'.$string1.'&quot;, 5) -&gt; &lt;span class=&quot;answer&quot;&gt;&quot;'.VBString::Right($string1, 5).'&quot;&lt;/span&gt;'.$nl;

//VBString::Space
echo 'VBString::Space(10) -&gt; &lt;span class=&quot;answer&quot;&gt;&quot;'.VBString::Space(10).'&quot;&lt;/span&gt;'.$nl;

//VBString::StrComp
echo 'VBString::StrComp(&quot;'.$string1.'&quot;, &quot;'.$string1.'&quot;) -&gt; &lt;span class=&quot;answer&quot;&gt;&quot;'.VBString::StrComp($string1, $string1).'&quot;&lt;/span&gt;'.$nl;

//VBString::String
echo 'VBString::String(10, &quot;*&quot;) -&gt; &lt;span class=&quot;answer&quot;&gt;&quot;'.VBString::String(10, &quot;*&quot;).'&quot;&lt;/span&gt;'.$nl;

//VBString::StrReverse
echo 'VBString::StrReverse(&quot;'.$string1.'&quot;) -&gt; &lt;span class=&quot;answer&quot;&gt;&quot;'.VBString::StrReverse($string1).'&quot;&lt;/span&gt;'.$nl;

//VBString::UCase
echo 'VBString::UCase(&quot;'.$string1.'&quot;) -&gt; &lt;span class=&quot;answer&quot;&gt;&quot;'. VBString::UCase($string1).'&quot;&lt;/span&gt;'.$nl;

echo '&lt;/pre&gt;';
?&gt;
</pre>
<p>Useful Links:</p>
<ul>
<li><a href="http://www.w3schools.com/VBscript/vbscript_ref_functions.asp#string">W3Schools VBScript String Methods</a></li>
<li><a href="http://us2.php.net/manual/en/book.strings.php">PHP Strings Manual</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>https://www.northatlantawebdesign.com/index.php/2009/08/24/vbscript-string-methods-in-a-simple-php-class/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Microsoft Active Accessibility Methods and Inconsistent Implementations</title>
		<link>https://www.northatlantawebdesign.com/index.php/2009/08/12/microsoft-active-accessibility-methods-and-inconsistent-implementations/</link>
		<comments>https://www.northatlantawebdesign.com/index.php/2009/08/12/microsoft-active-accessibility-methods-and-inconsistent-implementations/#comments</comments>
		<pubDate>Wed, 12 Aug 2009 21:04:32 +0000</pubDate>
		<dc:creator><![CDATA[Jeff Gibeau]]></dc:creator>
				<category><![CDATA[Accessibility]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[get_accRole]]></category>
		<category><![CDATA[get_accState]]></category>
		<category><![CDATA[IAccessible]]></category>
		<category><![CDATA[Microsoft Active Accessibility]]></category>
		<category><![CDATA[MSAA]]></category>

		<guid isPermaLink="false">http://www.northatlantawebdesign.com/?p=143</guid>
		<description><![CDATA[The C++ IAccessible interface offers a handful of methods that allow you to gather information or perform actions on an object. Each of these methods are well documented on MSDN, but it is up to the creator of an object to implement them correctly. In this article, I&#8217;ll be talking about a couple of the [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>The C++ IAccessible interface offers a handful of methods that allow you to gather information or perform actions on an object.  Each of these methods are well <a title="IAccessible Interface Documentation MSDN" href="http://msdn.microsoft.com/en-us/library/dd318466%28VS.85%29.aspx">documented on MSDN</a>, but it is up to the creator of an object to implement them correctly.  In this article, I&#8217;ll be talking about a couple of the inconsistencies you may run into when using these methods due to improper implementations and a lack of restrictions on how they should be implemented.<br />
<span id="more-143"></span></p>
<h3>IAccessible::get_accRole</h3>
<p>In the documentation for this method, it is clearly stated that it accepts two parameters.  The first is the accessible objects child id.  This variant is either equal to CHILDID_SELF, which defines that you are seeking information about the current object, or the child ID, which will get the role of the defined child.  This parameter should be of variant type VT_I4.  The second parameter is a variant pointer that will return the accessibility role of the object.  In the documentation this is stated as being an <a title="Object Role Constants MSDN" href="http://msdn.microsoft.com/en-us/library/dd373608%28VS.85%29.aspx">object role constant</a> such as ROLE_SYSTEM_WINDOW or ROLE_SYSTEM_CLIENT.  This parameter is where I have run into problems with how get_accRole has been implemented by the creator of the object.</p>
<p>In addition to stating the second parameter should return an object role constant, it also states that the variant type MUST be of type VT_I4.  This does not seem to be enforced though.  I have run into numerous situations (developing in Microsoft Office) where the variant type is VT_BSTR.  A string is considered invalid for this variant and can cause quite a headache when unexpected.  This occurs in a Microsoft product none the less, the creators of MSAA.  This is just one case that I have run into where the value is invalid, and it begs the question, what other variant types might this return?  That is totally up to the developer implemented get_accRole in his object.  The simple solution to this problem is to always check the variant type that is returned before doing any operations on it to avoid errors.</p>
<h3>IAccessible::get_accState</h3>
<p>After research into the get_accRole method, it came as no surprise the get_accState suffers from the same issues.  As with get_accRole, get_accState takes two parameters.  The first is the child id, and the second is the out variable to hold the state constant.  The <a title="IAccessible get_accState MSDN Documentation" href="http://msdn.microsoft.com/en-us/library/dd318487%28VS.85%29.aspx">documentation for get_accState</a> states that the second argument will return a variant type of VT_I4 that corresponds to one of the <a title="Object State Constants MSDN" href="http://msdn.microsoft.com/en-us/library/dd373609%28VS.85%29.aspx">object state constants</a>.  Though in using the accState with Microsoft Office and Lotus Notes I have run into times where the state is of variant type VT_BSTR (string).  Again the solution is to always check the variant type that is returned before using it in any operations.</p>
<p>&#8212;&#8211;</p>
<p>As I continue to dive deeper into the world of MSAA, I&#8217;ll keep this blog up to date with the inconsistencies I find.  If you have any that you have come across in working with MSAA tell me about them.  I&#8217;ll be glad to look into them to see if there is a workaround or a clean way to handle them.  I&#8217;ll leave with you with a code snippet that shows how to get the accRole and compare it with an object role constant.</p>
<p>Compare accessibility role:</p>
<pre class="brush: cpp; title: ; notranslate">
//Code below assumes that IAccessible object and ChildID are both passed in parameters.
bool CompareAccRole(IAccessible* pIAccessible, VARIANT childID, LONG objectRoleConstant)
{
	VARIANT accObjectRole;
	HRESULT hr = pIAccessible-&gt;get_accRole(childID, &amp;accObjectRole);
	if(hr == S_OK &amp;&amp; accObjectRole.vt == VT_I4)
	{
		if(accObjectRole.lVal &amp; objectRoleConstant)
			return true;
	}
	return false;	
}
</pre>
<p>Useful Links:</p>
<ul>
<li><a title="IAccessible MSDN Documentation" href="http://msdn.microsoft.com/en-us/library/dd318466%28VS.85%29.aspx">IAccessible MSDN Documentation</a></li>
<li><a title="IAccessible::get_accRole MSDN Documentation" href="http://msdn.microsoft.com/en-us/library/dd318485%28VS.85%29.aspx">IAccessible::get_accRole MSDN Documentation</a></li>
<li><a title="Object Role Constants MSDN" href="http://msdn.microsoft.com/en-us/library/dd373608%28VS.85%29.aspx">Object Role Constants MSDN</a></li>
<li><a title="IAccessible::get_accState MSDN Documentation" href="http://msdn.microsoft.com/en-us/library/dd318487%28VS.85%29.aspx">IAccessible::get_accState MSDN Documentation</a></li>
<li><a title="Object State Constants" href="http://msdn.microsoft.com/en-us/library/dd373609%28VS.85%29.aspx">Object State Constants MSDN</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>https://www.northatlantawebdesign.com/index.php/2009/08/12/microsoft-active-accessibility-methods-and-inconsistent-implementations/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Automating Excel 2007 in C++ by Importing the Excel 2007 Type Library</title>
		<link>https://www.northatlantawebdesign.com/index.php/2009/07/21/automating-excel-2007-in-c-by-importing-the-excel-2007-type-library/</link>
		<comments>https://www.northatlantawebdesign.com/index.php/2009/07/21/automating-excel-2007-in-c-by-importing-the-excel-2007-type-library/#comments</comments>
		<pubDate>Tue, 21 Jul 2009 16:58:51 +0000</pubDate>
		<dc:creator><![CDATA[Jeff Gibeau]]></dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Microsoft Excel 2007]]></category>
		<category><![CDATA[Microsoft Office 2007]]></category>
		<category><![CDATA[Visual Studio 2008]]></category>
		<category><![CDATA[Automating]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[Excel 2007]]></category>
		<category><![CDATA[Type Library]]></category>
		<category><![CDATA[VS2008]]></category>

		<guid isPermaLink="false">http://www.northatlantawebdesign.com/?p=119</guid>
		<description><![CDATA[When I started trying to write automations for Excel 2007 using C++, I ran into problems right up front. I was trying to use #import to get to the type library for Excel 2007, and was importing what I thought was the correct file. The following was written for a C++ application in Visual Studio [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>When I started trying to write automations for <a type="amzn">Excel 2007</a> using <a type="amzn">C++</a>, I ran into problems right up front.  I was trying to use #import to get to the type library for Excel 2007, and was importing what I thought was the correct file.  The following was written for a C++ application in <a type="amzn">Visual Studio 2008</a> (VS2008), automating Excel 2007.<br />
<span id="more-119"></span></p>
<ol>
<li>The Excel Type Library is not contained in XL5EN32.OLB as you might expect, it is contained in excel.exe</li>
<li>
Error #2: Even importing the correct file, errors were being raised.</p>
<pre class="brush: cpp; title: ; notranslate">
//The Following Import gives you the error Error	1	error C2504: '_IMsoDispObj' : base class undefined
#import &quot;C:\Program Files\Microsoft Office\Office12\EXCEL.EXE&quot;
</pre>
<p>To correctly import the Excel type library, two more references are needed: MSO.DLL and VBE6EXT.OLB</p>
<pre class="brush: cpp; title: ; notranslate">
#import &quot;C:\Program Files\Common Files\Microsoft Shared\OFFICE12\mso.dll&quot; no_implementation raw_interfaces_only
#import &quot;C:\Program Files\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB&quot; no_implementation raw_interfaces_only
#import &quot;C:\Program Files\Microsoft Office\OFFICE12\excel.exe&quot; no_implementation raw_interfaces_only
</pre>
</li>
<li>While this solved the problem of the _IMsoDispObj, it raised a few more issues.
<pre class="brush: cpp; title: ; notranslate">
warning C4003: not enough actual parameters for macro 'RGB'
warning C4003: not enough actual parameters for macro 'DialogBoxW'
</pre>
<p>Finally I had the solution, renaming the objects in question that seemed to be redefined elsewhere.</p>
<pre class="brush: cpp; title: ; notranslate">
#import &quot;C:\Program Files\Common Files\Microsoft Shared\OFFICE12\MSO.DLL&quot; no_implementation rename(&quot;RGB&quot;, &quot;ExclRGB&quot;) rename(&quot;DocumentProperties&quot;, &quot;ExclDocumentProperties&quot;) rename(&quot;SearchPath&quot;, &quot;ExclSearchPath&quot;)
#import &quot;C:\Program Files\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB&quot; no_implementation
#import &quot;D:\Program Files\Microsoft Office\OFFICE12\EXCEL.EXE&quot; rename(&quot;DialogBox&quot;, &quot;ExclDialogBox&quot;) rename(&quot;RGB&quot;, &quot;ExclRGB&quot;) rename(&quot;CopyFile&quot;, &quot;ExclCopyFile&quot;) rename(&quot;ReplaceText&quot;, &quot;ExclReplaceText&quot;)
</pre>
</li>
</ol>
<p>So in conclusion, in order to import the Excel 2007 Type Library in C++ and use it in your automations, 3 files must be imported, MSO.DLL, VBE6EXT.OLB, and EXCEL.EXE.  On top of those three files, various objects must be renamed due to already being defined.  In my case it was the DialogBox and RGB, though it may differ on each project depending on what is defined.  Here is the final code needed to import the type library.</p>
<pre class="brush: cpp; title: ; notranslate">
#import &quot;C:\Program Files\Common Files\Microsoft Shared\OFFICE12\MSO.DLL&quot; no_implementation rename(&quot;RGB&quot;, &quot;ExclRGB&quot;) rename(&quot;DocumentProperties&quot;, &quot;ExclDocumentProperties&quot;) rename(&quot;SearchPath&quot;, &quot;ExclSearchPath&quot;)
#import &quot;C:\Program Files\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB&quot; no_implementation
#import &quot;D:\Program Files\Microsoft Office\OFFICE12\EXCEL.EXE&quot; rename(&quot;DialogBox&quot;, &quot;ExclDialogBox&quot;) rename(&quot;RGB&quot;, &quot;ExclRGB&quot;) rename(&quot;CopyFile&quot;, &quot;ExclCopyFile&quot;) rename(&quot;ReplaceText&quot;, &quot;ExclReplaceText&quot;)
</pre>
<p>Useful Links:</p>
<ul>
<li><a href="http://groups.google.com/group/microsoft.public.vc.language/msg/d82ee4d7b85fbed1">Reading a cell from an Excel Worksheet</a></li>
<li><a href="http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/1de6c74f-6cf0-4d91-a5a9-e85853b867f6">Using Excel Type Library in VS 2005</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>https://www.northatlantawebdesign.com/index.php/2009/07/21/automating-excel-2007-in-c-by-importing-the-excel-2007-type-library/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Easy to use, yet powerful PHP E-mail Class</title>
		<link>https://www.northatlantawebdesign.com/index.php/2009/07/21/easy-to-use-yet-powerful-php-e-mail-class/</link>
		<comments>https://www.northatlantawebdesign.com/index.php/2009/07/21/easy-to-use-yet-powerful-php-e-mail-class/#comments</comments>
		<pubDate>Tue, 21 Jul 2009 15:34:33 +0000</pubDate>
		<dc:creator><![CDATA[Jeff Gibeau]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Class]]></category>
		<category><![CDATA[E-mail]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[email class]]></category>

		<guid isPermaLink="false">http://www.northatlantawebdesign.com/?p=111</guid>
		<description><![CDATA[This is a pretty robust PHP Email class that I wrote a few years back. Has the capability to do text or html e-mails with multiple attachments. Enjoy! Usage Examples: Useful Links: PHP Quick Reference]]></description>
				<content:encoded><![CDATA[<p>This is a pretty robust PHP Email class that I wrote a few years back.  Has the capability to do text or html e-mails with multiple attachments.  Enjoy!<br />
<span id="more-111"></span></p>
<pre class="brush: php; title: ; notranslate">
&lt;?php
/******************************************************************************\
--
--	Class Name: eMail
--		Purpose: Handles various aspects of sending/generating e-mails in PHP.
--		Current Capabilities:
			- Allows multiple &quot;To&quot; recipients
			- Allows multiple &quot;Cc&quot; recipients
			- Allows multiple &quot;Bcc&quot; recipients
			- Allows &quot;From&quot; header to be modified
			- Allows &quot;Sender&quot; header to be modified
			- Allows &quot;Content-Type&quot; for text or html
			- Allows for multiple attachments
			- Checks e-mail addresses via regular expressions to verify they
				will not cause errors
			-
--
\******************************************************************************/


	//Define class
class eMail {

/******************************************************************************\
--
--	User Specific Variables
--		Purpose: Variables which should/may be modified by the user.  This
--			defines defaults used in the program that can be changed later.
--
\******************************************************************************/
	//Set Default Variables
	var $replyTo = 'System &lt;system@example.com&gt;';	//Default reply address
	var $from = 'System &lt;system@example.com&gt;';		//Default From address
	var $sender = 'System &lt;system@example.com&gt;';	//Default Sender address
	var $isHTML = false;				//False sends e-mail in plain text by default
	var $nl = &quot;\n&quot;;						// New Line character, either \r\n or \n


/******************************************************************************\
--
--	Constant variables
--		Purpose: The constant variables should not be changed/modified unless
--			you know what you are messing with.
--
\******************************************************************************/
	//Constants
	var $errors = null;				//Array to hold any errors which may occur
	var $attachments = null;		//Array to hold attachments
 	var $mime_boundary = null;		//boundary set for using attachments
	var $to = null;					//Array to hold recipients
	var $cc = null;					//Array to hold recipients
	var $bcc = null;				//Array to hold recipients
	var $header = null;				//Header used to send e-mail
	var $subject = null;			//Subject of the e-mail
	var $body = null;				//Message portion of the e-mail
	var $message = null;			//used to build message when mail is sent


/******************************************************************************\
--
--	Regular Expressions
--		Purpose: Used in error checking e-mail addresses and various parts of
--			the emails.
--
\******************************************************************************/

 	//Regular Expressions for Error Checking
		//Email address with no name attached
	var $regex_email = '^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]{2,})+$';
		//Email address with name attached
	var $regex_email2 = '^([\._A-Za-z0-9-]+[ ]+)+[&lt;][_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]{2,})+[&gt;]$';
 		//Regular Expression for limiting body of message
 	var $regex_body = '^.*$';
 		//Regular Expression for limiting subject of message
 	var $regex_subject = '^.+$';


/******************************************************************************\
--
--	User Functions
--		Purpose: Allows user to add recipients, attachments, body, subject,etc.
--
\******************************************************************************/

		//Class Constructor, automatically called when a new object is created
	function eMail(){}

		//Adds a recipient for the e-mail
	function addTo($email_addr){
		$email_addr = $this-&gt;clean_email($email_addr);
		if($this-&gt;verify_email($email_addr)){
			$this-&gt;to[sizeOf($this-&gt;to)] = $email_addr;
			return true;
		} else{
			return false;
		}
	}

		//Adds a Carbon Copy address for the e-mail
	function addCC($email_addr){
		$email_addr = $this-&gt;clean_email($email_addr);
		if($this-&gt;verify_email($email_addr)){
			$this-&gt;cc[sizeOf($this-&gt;cc)] = $email_addr;
			return true;
		} else{
			return false;
		}
	}

		//Adds a Blind Carbon Copy address for the e-mail
	function addBCC($email_addr){
		$email_addr = $this-&gt;clean_email($email_addr);
		if($this-&gt;verify_email($email_addr)){
			$this-&gt;bcc[sizeOf($this-&gt;bcc)] = $email_addr;
			return true;
		} else{
			return false;
		}
	}

		//Sets the from header for the e-mail
	function setFrom($email_addr){
		$email_addr = $this-&gt;clean_email($email_addr);
		if($this-&gt;verify_email($email_addr)){
			$this-&gt;from = $email_addr;
			return true;
		} else{
			$this-&gt;addError(&quot;Invalid Format for FROM e-mail address&quot;);
			return false;
		}
	}

		//Sets the ReplyTo header for the e-mail
	function setReplyTo($email_addr){
		$email_addr = $this-&gt;clean_email($email_addr);
		if($this-&gt;verify_email($email_addr)){
			$this-&gt;replyTo = $email_addr;
			return true;
		} else{
			$this-&gt;addError(&quot;Invalid Format for ReplyTo e-mail address&quot;);
			return false;
		}
	}

		//Sets the Sender header for the e-mail
	function setSender($email_addr){
		$email_addr = $this-&gt;clean_email($email_addr);
		if($this-&gt;verify_email($email_addr)){
			$this-&gt;replyTo = $email_addr;
			return true;
		} else{
			$this-&gt;addError(&quot;Invalid Format for Sender e-mail address&quot;);
			return false;
		}
	}

		//Sets the From, ReplyTo, and Sender header with one e-mail
	function setSenderInfo($email_addr){
		$email_addr = $this-&gt;clean_email($email_addr);
		if($this-&gt;verify_email($email_addr)){
			$this-&gt;replyTo = $email_addr;
			$this-&gt;sender = $email_addr;
			$this-&gt;from = $email_addr;
			return true;
		} else{
			$this-&gt;addError(&quot;Invalid Format for From, Sender, and ReplyTo e-mail addresses&quot;);
			return false;
		}
	}

		//Sets the subject of the e-mail and verifies that all characters are allowed
	function setSubject($subjectIn){
		if($this-&gt;verify_subject($subjectIn)){
			$this-&gt;subject = $subjectIn;
			return true;
		} else{
			return false;
		}
	}

		//Sets the body of the e-mail and verifies that all characters in the body is allowed
	function setBody($bodyIn, $html_flag = false){
		$this-&gt;isHTML = $html_flag;
		if($this-&gt;verify_body($bodyIn)){
			$this-&gt;body = $bodyIn;
			return true;
		} else{
			return false;
		}
	}

		//Adds an attachment to be sent with the email
	function addAttachment($fileData, $fileName = &quot;unknown&quot;, $fileType = &quot;&quot;){
		$currSize = sizeOf($this-&gt;attachments);
		$this-&gt;attachments[$currSize][0] = $fileData;
		$this-&gt;attachments[$currSize][1] = $fileName;
		$this-&gt;attachments[$currSize][2] = $fileType;
	}



/******************************************************************************\
--
--	Send Mail Function
--		Purpose: Sends the e-mail after everything is setup.
--
\******************************************************************************/
		//Sets the mail headers for HTML, generates all the e-mail parameters and sends it
	function sendMail(){
			//Check body content via regular expression
		$this-&gt;verify_body($this-&gt;body);
			//Check subject content via regular expression
		$this-&gt;verify_subject($this-&gt;subject);

			//Verify at least on &quot;To&quot;,&quot;Cc&quot;, or &quot;Bcc&quot; address is contained
		if($this-&gt;to==null &amp;&amp; $this-&gt;cc==null &amp;&amp; $this-&gt;bcc==null){
			$this-&gt;addError(&quot;E-mail must contain at least one \&quot;To\&quot;,\&quot;Cc\&quot;, or \&quot;Bcc\&quot; address&quot;);
		}

			//Begin to build the header
		$this-&gt;header = &quot;&quot;;
			//Set a MIME-version
		$this-&gt;header .= &quot;MIME-version: 1.0&quot; . $this-&gt;nl;

			//Setup Sender, From, Bcc, CC, and ReplyTo regardless of mail format
		$this-&gt;replyTo = $this-&gt;clean_email($this-&gt;replyTo);
		if($this-&gt;replyTo != null){
			if($this-&gt;verify_email($this-&gt;replyTo)){
				$this-&gt;header .= &quot;Reply-To: $this-&gt;replyTo&quot; . $this-&gt;nl;
			} else{
				$this-&gt;addError(&quot;Invalid Reply-To Header: $this-&gt;replyTo&quot;);
			}
		}

			//Setup sender
		$this-&gt;sender = $this-&gt;clean_email($this-&gt;sender);
		if($this-&gt;sender != null){
			if($this-&gt;verify_email($this-&gt;sender)){
				$this-&gt;header .= &quot;Sender: $this-&gt;sender&quot; . $this-&gt;nl;
			} else{
				$this-&gt;addError(&quot;Invalid Sender Header: $this-&gt;sender&quot;);
			}
		}

			//Setup from
		$this-&gt;from = $this-&gt;clean_email($this-&gt;from);
		if($this-&gt;from != null){
			if($this-&gt;verify_email($this-&gt;from)){
				$this-&gt;header .= &quot;From: $this-&gt;from&quot; . $this-&gt;nl;
			} else{
				$this-&gt;addError(&quot;Invalid From Header: $this-&gt;from&quot;);
			}
		}

			//Verify all addresses in cc
		if($this-&gt;cc!=null){
			foreach($this-&gt;cc as $email_addr){
				$email_addr = $this-&gt;clean_email($email_addr);
				$this-&gt;verify_email($email_addr);
				$email_addr = $email_addr;
				$this-&gt;header .= &quot;Cc: $email_addr&quot; . $this-&gt;nl;
			}
		}

			//Verify all addresses in bcc
		if($this-&gt;bcc != null){
			foreach($this-&gt;bcc as $email_addr){
				$email_addr = $this-&gt;clean_email($email_addr);
				$this-&gt;verify_email($email_addr);
				$email_addr = $email_addr;
				$this-&gt;header .= &quot;Bcc: $email_addr&quot; . $this-&gt;nl;
			}
		}
			//If contains attachments, generate mail with multiple parts
		if($this-&gt;attachments!=null){
				//Generate a boundary to separate the message body
				//  and attachments
			$this-&gt;mime_boundary = &quot;==Multipart_Boundary_x{&quot;.md5(time()).&quot;}x&quot;;

				//Set Content type to multipart for attachments
			$this-&gt;header .= &quot;Content-type: multipart/mixed;&quot; . $this-&gt;nl;
				//Put boundary in header of e-mail
			$this-&gt;header .= &quot; boundary=\&quot;{$this-&gt;mime_boundary}\&quot;&quot;;

				//Setup the boundary for the body content
            $this-&gt;message .= &quot;--{$this-&gt;mime_boundary}&quot; . $this-&gt;nl;

				//If html set content type to that in message, else plain text
			if($this-&gt;isHTML){
	            $this-&gt;message .= &quot;Content-Type: text/html; charset=ISO-8859-1&quot; . $this-&gt;nl;
			} else{
				$this-&gt;message .= &quot;Content-type: text/plain; charset=ISO-8859-1&quot; . $this-&gt;nl;
			}
				//Set transfer encoding
			$this-&gt;message .= &quot;Content-Transfer-Encoding: 7bit&quot; . $this-&gt;nl . $this-&gt;nl;

				//Add the body to the message
			$this-&gt;message .= $this-&gt;body . $this-&gt;nl . $this-&gt;nl;

				//Add attachments
			for($i=0;$i&lt;sizeOf($this-&gt;attachments);$i++){
					//Put boundary before each attachment
				$this-&gt;message .= &quot;--{$this-&gt;mime_boundary}&quot; . $this-&gt;nl;
					//Set content type of attachment
				$this-&gt;message .= &quot;Content-Type: {$this-&gt;attachments[$i][2]};&quot; . $this-&gt;nl;
					//Set name for the attachment
				$this-&gt;message .= &quot; name=\&quot;&quot;.$this-&gt;attachments[$i][1].&quot;\&quot;&quot; . $this-&gt;nl;
					//Let message know this is an attachment
				$this-&gt;message .= &quot;Content-Disposition: attachment;&quot; . $this-&gt;nl;
					//Set filename for the attachment
				$this-&gt;message .= &quot; filename=\&quot;&quot;.$this-&gt;attachments[$i][1].&quot;\&quot;&quot; . $this-&gt;nl;
					//Set to base64 content encoding
				$this-&gt;message .= &quot;Content-Transfer-Encoding: base64&quot; . $this-&gt;nl . $this-&gt;nl;
					//Add attachment and encode to base64
				$this-&gt;message .= chunk_split(base64_encode($this-&gt;attachments[$i][0])) . $this-&gt;nl;
			}
				//Close off attachments
			$this-&gt;message .= &quot;--{$this-&gt;mime_boundary}--&quot; . $this-&gt;nl . $this-&gt;nl;
		}
			//Does not contain attachments, generate mail normally
		else {
				//If html set header to define it
			if($this-&gt;isHTML){
				$this-&gt;header .= &quot;Content-type: text/html; charset=iso-8859-1&quot; . $this-&gt;nl;
			} else{
				$this-&gt;header .= &quot;Content-type: text/plain; charset=ISO-8859-1&quot; . $this-&gt;nl;
			}
				//Add body to the message
			$this-&gt;message = $this-&gt;body;
		}

			//Generate To: recipients
			$to_string = &quot;&quot;;
		if($this-&gt;to!=null){
			$this-&gt;count=0;
			foreach($this-&gt;to as $email_addr){
				$email_addr = $this-&gt;clean_email($email_addr);
				if($this-&gt;verify_email($email_addr)){
					if($this-&gt;count&gt;0){
						$to_string .= ', ';
					}
					$to_string .= $email_addr;
					$this-&gt;count++;
				}
			}
		}
			//If an error has occurred, do not send the message and return the last error
		if($this-&gt;errors!=null){
			return false;
		} else{
				//Close off the header of the message
			$this-&gt;header .= $this-&gt;nl;
				//Send the message
			return mail($to_string, $this-&gt;subject, $this-&gt;message, $this-&gt;header);
		}
	}

/******************************************************************************\
--
--	Error Functions
--		Purpose: Internal functions to store errors and public ones to retrieve
--			them.
--
\******************************************************************************/
		//Returns the array of errors
	function getErrors(){
		return $this-&gt;errors;
	}

		//Returns only the last error which was logged
	function getLastError(){
		if($this-&gt;errors!=null){
			return $this-&gt;errors[sizeOf($this-&gt;errors)-1];
		} else {
			return false;
		}
	}

		//Adds an error to the error array
	function addError($errorIn){
		$this-&gt;errors[sizeOf($this-&gt;errors)] = $errorIn;
	}

/******************************************************************************\
--
--	Message Compilation Functions
--		Purpose: Functions which return different components of the message
--
\******************************************************************************/
		//Returns the message header
	function getHeader(){
		return $this-&gt;header;
	}

		//Returns the message contents, not generated until after mail is sent
	function getMessage(){
		return $this-&gt;message;
	}

		//Returns the body portion of the e-mail
	function getBody(){
		return $this-&gt;body;
	}

/******************************************************************************\
--
--	Error Checking/Cleansing Functions
--		Purpose: Functions to remove common errors from input and to verify
--			different portions of the message with regular expressions
--
\******************************************************************************/
		//Removes e-mail addresses of commas and semi-colons which may cause
		// problems in the message headers
	function clean_email($email_addr){
		if($email_addr!=null){
			$email_addr = str_replace(&quot;,&quot;,&quot; &quot;,$email_addr);
			$email_addr = str_replace(&quot;;&quot;,&quot; &quot;,$email_addr);
		}
		return $email_addr;
	}

		//Verifies that e-mail addresses in arguments match one form of
		// e-mail via regular expressions
	function verify_email($email_addr){
		if (eregi($this-&gt;regex_email, $email_addr)) return true;
		else if (eregi($this-&gt;regex_email2, $email_addr)) return true;
		else {
			$this-&gt;addError(&quot;Invalid E-mail Address: $email_addr&quot;);
			return false;
		}
	}

		//Verifies that the body portion of message matches a given
		// regular expression.  Nice for setting a minimum message length.
	function verify_body($body){
		if (eregi($this-&gt;regex_body, $body)) return true;
		else {
			$this-&gt;addError(&quot;Invalid Body Content: $body&quot;);
			return false;
		}
	}

		//Verifies that the subject portion of message matches a given
		// regular expression.  Nice for setting a minimum subject length.
	function verify_subject($subject){
		if (eregi($this-&gt;regex_subject, $subject)) return true;
		else {
			$this-&gt;addError(&quot;Invalid Subject Content: $subject&quot;);
			return false;
		}
	}

/******************************************************************************\
\******************************************************************************/


	//Close Class Definition
}
</pre>
<p>Usage Examples:</p>
<pre class="brush: php; title: ; notranslate">
/******************************************************************************\
--
--	Program Use Examples
--		Purpose: The following are a few examples on using the eMail class in
--			an application.
--
\******************************************************************************/
/******************************************************************************\

Example 1:  Basic Text E-mail
		//Initialize e-mail object
	$email = new eMail();

		//Add a To recipient
	$email-&gt;addTo(&quot;example@example.com&quot;);

		//Add a subject for the e-mail
	$email-&gt;subject = &quot;Test E-mail Subject&quot;;

		//Set the body portion of the e-mail
	$email-&gt;setBody('
	This is a text body in an e-mail.
	Nothing else is required, it can now be sent.
	');

		//Send the e-mail
	$email-&gt;sendMail();

--------------------------------------------------------------------------------

Example 2:  Basic Html E-mail
		//Initialize e-mail object
	$email = new eMail();

		//Add a To recipient
	$email-&gt;addTo(&quot;example@example.com&quot;);

		//Add a subject for the e-mail
	$email-&gt;subject = &quot;Test E-mail Subject&quot;;

		//Set the body portion of the e-mail, setting it to HTML with the
		// second parameter.
	$email-&gt;setBody('
	This is now a html body in an e-mail.&lt;HR&gt;
	Nothing else is required, it can now be sent.
	', true);

		//Send the e-mail
	$email-&gt;sendMail();

--------------------------------------------------------------------------------

Example 3:  Basic Attachment Example with an Html body
		//Initialize e-mail object
	$email = new eMail();

		//Add a To recipient
	$email-&gt;addTo(&quot;example@example.com&quot;);

		//Add a subject for the e-mail
	$email-&gt;subject = &quot;Test E-mail Subject&quot;;

		//Set the body portion of the e-mail, setting it to HTML with the
		// second parameter.
	$email-&gt;setBody('
	This is now a html body in an e-mail.&lt;HR&gt;
	Nothing else is required, it can now be sent.
	', true);

		//Add an attachment to the e-mail
	$email-&gt;addAttachment(&quot;Text in the attachment&quot;,&quot;filename.txt&quot;,&quot;text/plain&quot;);

		//Send the e-mail
	$email-&gt;sendMail();

--------------------------------------------------------------------------------

Example 4:  Multiple Attachments
		//Initialize e-mail object
	$email = new eMail();

		//Add a To recipient
	$email-&gt;addTo(&quot;example@example.com&quot;);

		//Add a subject for the e-mail
	$email-&gt;subject = &quot;Test E-mail Subject&quot;;

		//Set the body portion of the e-mail, setting it to HTML with the
		// second parameter.
	$email-&gt;setBody('
	This is now a html body in an e-mail.&lt;HR&gt;
	Nothing else is required, it can now be sent.
	', true);

		//Attach an html file containing the body of the message
	$email-&gt;addAttachment($email-&gt;body,&quot;email_body.html&quot;,&quot;text/html&quot;);

		//Attach a second file
	$email-&gt;addAttachment(&quot;File Data&quot;,&quot;Attachment01.txt&quot;);

		//Send the e-mail
	$email-&gt;sendMail();

\******************************************************************************/
?&gt;
</pre>
<p>Useful Links:</p>
<ul>
<li><a href="http://www.php.net/quickref.php">PHP Quick Reference</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>https://www.northatlantawebdesign.com/index.php/2009/07/21/easy-to-use-yet-powerful-php-e-mail-class/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTA Progress Bar using VBScript and JavaScript</title>
		<link>https://www.northatlantawebdesign.com/index.php/2009/07/17/hta-progress-bar-using-vbscript-and-javascript/</link>
		<comments>https://www.northatlantawebdesign.com/index.php/2009/07/17/hta-progress-bar-using-vbscript-and-javascript/#comments</comments>
		<pubDate>Fri, 17 Jul 2009 17:53:30 +0000</pubDate>
		<dc:creator><![CDATA[Jeff Gibeau]]></dc:creator>
				<category><![CDATA[HTML Applications]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[VBScript]]></category>
		<category><![CDATA[HTA]]></category>
		<category><![CDATA[Progress Bar]]></category>
		<category><![CDATA[Progressbar]]></category>
		<category><![CDATA[VBScript Front End]]></category>
		<category><![CDATA[VBScript GUI]]></category>

		<guid isPermaLink="false">http://www.northatlantawebdesign.com/?p=88</guid>
		<description><![CDATA[I was informed after my last post that using HTA (HTML Applications) to display a progress bar in VBScript is much more efficient than using InternetExplorer.Application within a VBScript. Having never used HTA before, I immediately set out to learn a bit and see what I could come up with. My initial thoughts are mixed, [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>I was informed after my <a href="http://www.northatlantawebdesign.com/index.php/2009/07/16/simple-vbscript-progress-bar/">last post</a> that using <a type="amzn">HTA</a> (HTML Applications) to display a progress bar in <a type="amzn">VBScript</a> is much more efficient than using InternetExplorer.Application within a VBScript.  Having never used HTA before, I immediately set out to learn a bit and see what I could come up with.</p>
<p>My initial thoughts are mixed, as <strong>you can not run and interact with an HTA from a VBScript file</strong>.  This requires you to wrap your VBScript code in whatever HTML Application you are writing.  This greatly limits re-usability, enough so that the increase in performance may not warrant using an HTA for a progress bar in most cases.<br />
<span id="more-88"></span><br />
I would like to note that this is a first draft of this script, and I may update it in the future, if I deem HTML Applications the way to go.  As for now, I am not convinced.</p>
<pre class="brush: vb; title: ; notranslate">
&lt;html&gt;
&lt;head&gt;
	&lt;title&gt;HTA Progress Bar&lt;/title&gt;
&lt;script language=&quot;vbscript&quot;&gt;
'This script resizes and moves the window to the center of the screen.
'The placement of this code above the HTA definition, moves the window
'before the script is visible. 
height = screen.height
width = screen.width
moveto width/2 - 335/2,height/2 - 200/2
resizeto 335,200
&lt;/script&gt;
	&lt;HTA:APPLICATION ID=&quot;oMyApp&quot;
		APPLICATIONNAME=&quot;monster&quot;
		SINGLEINSTANCE=&quot;yes&quot;
		BORDER=&quot;thin&quot;
		MAXIMIZEBUTTON=&quot;no&quot;
&gt;

&lt;script language=&quot;VBScript&quot; type=&quot;text/vbscript&quot;&gt;
'This is where your VBScript logic should go.
' Call OpenProgressBar to open the progressbar
' Call UpdateLog to update the logging window
' Call UpdateProgressBar to move the bar
' Call CloseProgressBar to return to your main UI window
Sub BeginImportingFiles()
	Dim i
	OpenProgressBar()
	UpdateLog &quot;Step 1 of 2&quot;, &quot;&quot;
	For i = 1 to 10
		Sleep 100
		UpdateLog &quot;Next Step&quot;, &quot;&quot; &amp; Time()
		UpdateProgressBar i*10, &quot;Step 1 of 2&quot;
	Next
	UpdateLog &quot;Step 1 of 2&quot;, &quot;Complete&quot;
	Sleep 2000
	CloseProgressBar()
End Sub

Sub Sleep(MSecs) 
	Set fso = CreateObject(&quot;Scripting.FileSystemObject&quot;)
	If Fso.FileExists(&quot;sleeper.vbs&quot;)=False Then
	Set objOutputFile = fso.CreateTextFile(&quot;sleeper.vbs&quot;, True)
	objOutputFile.Write &quot;wscript.sleep WScript.Arguments(0)&quot;
	objOutputFile.Close
	End If
	CreateObject(&quot;WScript.Shell&quot;).Run &quot;sleeper.vbs &quot; &amp; MSecs,1 , True
End Sub

&lt;/script&gt;
&lt;script language=&quot;JavaScript&quot; type=&quot;text/javascript&quot;&gt;
function OpenProgressBar()
{
	document.getElementById(&quot;gui&quot;).style.display=&quot;none&quot;;
	document.getElementById(&quot;progressbargui&quot;).style.display=&quot;block&quot;;
}

function UpdateLog(text, status)
{
	var log = document.getElementById(&quot;log&quot;);
	if(status &amp;&amp; status != &quot;&quot;)
	{
		var maxLength = 33;
		var dotlength = maxLength - (text.length + status.length);
		var dots = &quot;&quot;;
		for(i = 0;i&lt;dotlength;i++)
			dots += &quot;.&quot;;
		log.value += text + dots + &quot;[&quot; + status + &quot;]\n&quot;;
	}
	else
		log.value += &quot;[&quot; + text + &quot;]&quot; + &quot;\n&quot;;
	log.scrollTop = log.scrollHeight;
}

function UpdateProgressBar(percentComplete, title, status)
{
	for(i = 1; i &lt;= 100; i++)
	{
		if((percentComplete) &gt;= i)
			document.getElementById(&quot;pbar&quot;+i).className = &quot;pbarcomplete&quot;;
		else
			document.getElementById(&quot;pbar&quot;+i).className = &quot;pbar&quot;;
		document.title = title &amp;&amp; title != &quot;&quot; ? title : percentComplete + &quot;% Complete&quot;;
		document.getElementById(&quot;progresstitle&quot;).innerText = status &amp;&amp; status != &quot;&quot; ? status : percentComplete + &quot;% Complete&quot;;
	}
}

function CloseProgressBar()
{
	document.getElementById(&quot;gui&quot;).style.display=&quot;block&quot;;
	document.getElementById(&quot;progressbargui&quot;).style.display=&quot;none&quot;;
	UpdateProgressBar(0,&quot;&quot;,&quot;&quot;);
	document.getElementById(&quot;log&quot;).value = &quot;&quot;;
}
&lt;/script&gt;
&lt;script language=&quot;VBScript&quot; type=&quot;text/vbscript&quot;&gt;
'Progress Bar Logic
&lt;/script&gt;
&lt;style type=&quot;text/css&quot;&gt;
body,html {
	margin:auto;
}
div#progressbar{
border:1px solid #ccc;
margin:0px;padding:0px;
}
span.pbar{
	width:3px;
	margin:0px;
	padding:0px;
	border-left:1px solid #fff;
	background:#fff;
	line-height:5px;
	height:16px;
	font-size:2px;
}
span.pbarcomplete{
	width:3px;
	margin:0px;
	padding:0px;
	border-right:1px solid #ccc;
	background:green;
	line-height:5px;
	height:16px;
	font-size:2px;
	
}
table {
	width:100%;
	height:100%;
}
table td {
	text-align:center;
	vertical-align:center;
}
table td.progressbargui {
	display:none;
	vertical-align:top;
}
textarea#log{
	width:100%;
	height:100px;
	border:1px solid #aaa;
}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;table&gt;
&lt;tr&gt;
	&lt;td id=&quot;gui&quot;&gt;&lt;input type=&quot;button&quot; onclick=&quot;BeginImportingFiles()&quot; value=&quot;Begin File Import&quot;/&gt;&lt;/td&gt;
	&lt;td id=&quot;progressbargui&quot; class=&quot;progressbargui&quot;&gt;
		&lt;div id=&quot;progresstitle&quot;&gt;&amp;nbsp;&lt;/div&gt;
		&lt;div id=&quot;progressbar&quot;&gt;
		&lt;script type=&quot;text/javascript&quot;&gt;
		for(i = 1; i &lt;= 100; i++)
			document.write(&quot;&lt;span id=\&quot;pbar&quot; + i + &quot;\&quot; class=\&quot;pbar\&quot;&gt;&lt;/span&gt;&quot;);
		&lt;/script&gt;
		&lt;/div&gt;
		&lt;textarea id=&quot;log&quot;&gt;&lt;/textarea&gt;
	&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

&lt;/body&gt;
&lt;/html&gt;

</pre>
<p>Some potentially useful links dealing with HTA:</p>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/ms536496%28VS.85%29.aspx" target="_blank">HTML Applications Introduction</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/ms536473%28VS.85%29.aspx" target="_blank">HTA Reference</a></li>
<li><a href="http://www.amazon.com/gp/product/0735622442?ie=UTF8&#038;tag=cheesymovieni-20&#038;linkCode=as2&#038;camp=1789&#038;creative=390957&#038;creativeASIN=0735622442" target="_blank">Advanced VBScript for Microsoft  Windows  Administrators (Book)</a><img src="http://www.assoc-amazon.com/e/ir?t=cheesymovieni-20&#038;l=as2&#038;o=1&#038;a=0735622442" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>https://www.northatlantawebdesign.com/index.php/2009/07/17/hta-progress-bar-using-vbscript-and-javascript/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Simple VBScript Progress Bar</title>
		<link>https://www.northatlantawebdesign.com/index.php/2009/07/16/simple-vbscript-progress-bar/</link>
		<comments>https://www.northatlantawebdesign.com/index.php/2009/07/16/simple-vbscript-progress-bar/#comments</comments>
		<pubDate>Thu, 16 Jul 2009 17:26:17 +0000</pubDate>
		<dc:creator><![CDATA[Jeff Gibeau]]></dc:creator>
				<category><![CDATA[VBScript]]></category>
		<category><![CDATA[Class]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[Progress Bar]]></category>

		<guid isPermaLink="false">http://www.northatlantawebdesign.com/?p=69</guid>
		<description><![CDATA[Recently I had a need for a simple progress bar written in VBScript to let users know what was going on in a multi-step application. To my surprise, VBScript has nothing built in for a progress bar.  After much searching, I was able to find this thread that linked to yet another thread with a [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Recently I had a need for a simple progress bar written in <a type="amzn">VBScript</a> to let users know what was going on in a multi-step application.  To my surprise, VBScript has nothing built in for a progress bar.  After much searching, I was able to find <a title="Copy Files with Progress Bar" href="http://www.tek-tips.com/viewthread.cfm?qid=1196550&amp;page=1">this thread</a> that linked to yet <a title="Adding some kind of progress" href="http://www.tek-tips.com/viewthread.cfm?qid=898604">another thread</a> with a simple progress bar done in HTML using InternetExplorer.Application.  I have taken this code and modified it to show an actual progess bar, with percentages, that can be updated as desired.  I&#8217;ve wrapped it up in a nice easy-to-use class for reusability.  Enjoy!</p>
<p><span id="more-69"></span></p>
<div id="attachment_82" style="width: 322px" class="wp-caption aligncenter"><img class="size-full wp-image-82" title="Simple VBScript Progress Bar" src="http://www.northatlantawebdesign.com/wp-content/uploads/2009/07/vbscript_progress_bar.gif" alt="Simple VBScript Progress Bar" width="312" height="99" /><p class="wp-caption-text">Simple VBScript Progress Bar</p></div>
<p>VBScript Progress Bar Class:</p>
<pre class="brush: vb; title: ; notranslate">
Class ProgressBar
Private m_PercentComplete
Private m_CurrentStep
Private m_ProgressBar
Private m_Title
Private m_Text
Private m_StatusBarText

'Initialize defaults
Private Sub ProgessBar_Initialize
m_PercentComplete = 0
m_CurrentStep = 0
m_Title = &quot;Progress&quot;
m_Text = &quot;&quot;
End Sub

Public Function SetTitle(pTitle)
m_Title = pTitle
End Function

Public Function SetText(pText)
m_Text = pText
End Function

Public Function Update(percentComplete)
m_PercentComplete = percentComplete
UpdateProgressBar()
End Function

Public Function Show()
Set m_ProgressBar = CreateObject(&quot;InternetExplorer.Application&quot;)
'in code, the colon acts as a line feed
m_ProgressBar.navigate2 &quot;about:blank&quot; : m_ProgressBar.width = 315 : m_ProgressBar.height = 40 : m_ProgressBar.toolbar = false : m_ProgressBar.menubar = false : m_ProgressBar.statusbar = false : m_ProgressBar.visible = True
m_ProgressBar.document.write &quot;&lt;body Scroll=no style='margin:0px;padding:0px;'&gt;&lt;div style='text-align:center;'&gt;&lt;span name='pc' id='pc'&gt;0&lt;/span&gt;&lt;/div&gt;&quot;
m_ProgressBar.document.write &quot;&lt;div id='statusbar' name='statusbar' style='border:1px solid blue;line-height:10px;height:10px;color:blue;'&gt;&lt;/div&gt;&quot;
m_ProgressBar.document.write &quot;&lt;div style='text-align:center'&gt;&lt;span id='text' name='text'&gt;&lt;/span&gt;&lt;/div&gt;&quot;
End Function

Public Function Close()
m_ProgressBar.quit
m_ProgressBar = Nothing
End Function

Private Function UpdateProgressBar()
If m_PercentComplete = 0 Then
m_StatusBarText = &quot;&quot;
End If
For n = m_CurrentStep to m_PercentComplete - 1
m_StatusBarText = m_StatusBarText &amp; &quot;|&quot;
m_ProgressBar.Document.GetElementById(&quot;statusbar&quot;).InnerHtml = m_StatusBarText
m_ProgressBar.Document.title = n &amp; &quot;% Complete : &quot; &amp; m_Title
m_ProgressBar.Document.GetElementById(&quot;pc&quot;).InnerHtml = n &amp; &quot;% Complete : &quot; &amp; m_Title
wscript.sleep 10
Next
m_ProgressBar.Document.GetElementById(&quot;statusbar&quot;).InnerHtml = m_StatusBarText
m_ProgressBar.Document.title = m_PercentComplete &amp; &quot;% Complete : &quot; &amp; m_Title
m_ProgressBar.Document.GetElementById(&quot;pc&quot;).InnerHtml = m_PercentComplete &amp; &quot;% Complete : &quot; &amp; m_Title
m_ProgressBar.Document.GetElementById(&quot;text&quot;).InnerHtml = m_Text
m_CurrentStep = m_PercentComplete
End Function

End Class
</pre>
<p>Example of Usage:</p>
<pre class="brush: vb; title: ; notranslate">
'Declare progressbar and percentage complete
Dim pb
Dim percentComplete
'Setup the initial progress bar
Set pb = New ProgressBar
percentComplete = 0
pb.SetTitle(&quot;Step 1 of 5&quot;)
pb.SetText(&quot;Copying bin/Debug Folder&quot;)
pb.Show()

'Loop to update the percent complete of the progress bar
'Just add the pb.Update in your code to update the bar
'Text can be updated as well by pb.SetText
Do While percentComplete &lt;= 100
wscript.sleep 500
pb.Update(percentComplete)
percentComplete = percentComplete + 10
Loop
wscript.sleep 3000

'This shows how you can use the code for multiple steps
'In a future iteration I will add a second bar to measure overall progress
percentComplete = 0
pb.SetTitle(&quot;Step 2 of 5&quot;)
pb.SetText(&quot;Copying bin/Release Folder&quot;)
pb.Update(percentComplete)
Do While percentComplete &lt;= 100
wscript.sleep 500
pb.Update(percentComplete)
percentComplete = percentComplete + 10
Loop
pb.Close()
wscript.quit
</pre>
<p>In a future release, I may add another progress bar to keep track of the steps that are completed.  Feel free to use and modify this code as you desire.</p>
<p>Useful Links:</p>
<ul>
<li><a title="Microsoft VBScript Reference" href="http://msdn.microsoft.com/en-us/library/d1wf56tt%28VS.85%29.aspx">Microsoft VBScript Reference</a></li>
<li><a title="W3Schools VBScript Reference" href="http://www.w3schools.com/Vbscript/default.asp">W3Schools VBScript Reference</a></li>
<li><a title="Copy Files with a Progress Bar" href="http://www.tek-tips.com/viewthread.cfm?qid=1196550&amp;page=1">Copy Files with a Progress Bar</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>https://www.northatlantawebdesign.com/index.php/2009/07/16/simple-vbscript-progress-bar/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Access Microsoft Excel 2007 COM API through Microsoft Active Accessibility</title>
		<link>https://www.northatlantawebdesign.com/index.php/2009/07/15/access-microsoft-excel-2007-com-api-through-microsoft-active-accessibility/</link>
		<comments>https://www.northatlantawebdesign.com/index.php/2009/07/15/access-microsoft-excel-2007-com-api-through-microsoft-active-accessibility/#comments</comments>
		<pubDate>Thu, 16 Jul 2009 00:47:49 +0000</pubDate>
		<dc:creator><![CDATA[Jeff Gibeau]]></dc:creator>
				<category><![CDATA[Accessibility]]></category>
		<category><![CDATA[Microsoft Excel 2007]]></category>
		<category><![CDATA[Microsoft Office 2007]]></category>
		<category><![CDATA[AccessibleObjectFromWindow]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[Microsoft Active Accessibility]]></category>

		<guid isPermaLink="false">http://www.northatlantawebdesign.com/?p=63</guid>
		<description><![CDATA[A couple days ago I showed you how to access the Microsoft Word 2007 COM API through Microsoft Active Accessibility (MSAA). Today, I&#8217;m going to switch it up just a little bit, and use the same method to access the Microsoft Excel 2007 COM API. Again, we&#8217;ll be using AccesssibleObjectFromWindow to get at the main [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>A couple days ago I showed you how to access the <a type="amzn">Microsoft Word 2007</a> COM API through Microsoft Active Accessibility (MSAA).  Today, I&#8217;m going to switch it up just a little bit, and use the same method to access the <a type="amzn">Microsoft Excel 2007</a> COM API.  Again, we&#8217;ll be using AccesssibleObjectFromWindow to get at the main Excel::Window object.  From that object, you can obtain the Excel Application, and Excel Workbook objects.  Some documentation from Microsoft can be <a href="http://msdn.microsoft.com/en-us/library/dd317978(VS.85).aspx">found here</a>.</p>
<p><span id="more-63"></span></p>
<p>First we obtain the hwnd of the Microsoft Excel Process:</p>
<pre class="brush: cpp; title: ; notranslate">
//The main window in Microsoft Excel has a class name of XLMAIN
HWND excelWindow = FindWindow(L&quot;XLMAIN&quot;, NULL);
</pre>
<p>We can then traverse the child windows until we find the one with classname EXCEL7:</p>
<pre class="brush: cpp; title: ; notranslate">
//Use the EnumChildWindows function to iterate through all child windows until we find EXCEL7
EnumChildWindows(excelWindow, (WNDENUMPROC) EnumChildProc, (LPARAM)1);
</pre>
<pre class="brush: cpp; title: ; notranslate">
static BOOL EnumChildProc(HWND hwnd, LPARAM)
{
     WCHAR szClassName[64];
     if(GetClassNameW(hwnd, szClassName, 64))
     {
          if(_wcsicmp(szClassName, L&quot;EXCEL7&quot;) == 0)
          {
               //Get AccessibleObject
               Excel::Window* pWindow = NULL;
               HRESULT hr = AccessibleObjectFromWindow(hwnd, OBJID_NATIVEOM, __uuidof(Excel::Window), (void**)&amp;pWindow);
               if(hr == S_OK)
               {
                    //Excel object is now in pWindow pointer, from this you can obtain the document or application
                    Excel::_Application* pApp = NULL;
                    pWindow-&gt;get_Application(&amp;pApp);
                    pWindow-&gt;Release();
               }
               return false;     // Stops enumerating through children
          }
     }
     return true;
}
</pre>
<p>Next we obtain our Excel::Window object through AccessibleObjectFromWindow:</p>
<pre class="brush: cpp; title: ; notranslate">
//Get AccessibleObject
Excel::Window* pWindow = NULL;
HRESULT hr = AccessibleObjectFromWindow(hwnd, OBJID_NATIVEOM, __uuidof(Excel::Window), (void**)&amp;pWindow);
</pre>
<p>That&#8217;s it!  We now have our Excel::Window COM Object.  From this object we can obtain the Excel::Application and Excel::Workbook objects, allowing us full interaction with the active document.  So with just a few lines of code, we now have access to automate an Excel 2007 document.</p>
<p>Full source code:</p>
<pre class="brush: cpp; title: ; notranslate">
#include &lt;windows.h&gt;
#include &lt;oleacc.h&gt;
#include &quot;msexcel.h&quot;

static BOOL EnumChildProc(HWND hwnd, LPARAM)
{
     WCHAR szClassName[64];
     if(GetClassNameW(hwnd, szClassName, 64))
     {
          if(_wcsicmp(szClassName, L&quot;EXCEL7&quot;) == 0)
          {
               //Get AccessibleObject
               Excel::Window* pWindow = NULL;
               HRESULT hr = AccessibleObjectFromWindow(hwnd, OBJID_NATIVEOM, __uuidof(Excel::Window), (void**)&amp;pWindow);
               if(hr == S_OK)
               {
                    //Excel object is now in pWindow pointer, from this you can obtain the document or application
                    Excel::_Application* pApp = NULL;
                    pWindow-&gt;get_Application(&amp;pApp);
                    pWindow-&gt;Release();
               }
               return false;     // Stops enumerating through children
          }
     }
	 return true;
}
int main( int argc, CHAR* argv[])
{
     //The main window in Microsoft Excel has a class name of XLMAIN
     HWND excelWindow = FindWindow(L&quot;XLMAIN&quot;, NULL);

     //Use the EnumChildWindows function to iterate through all child windows until we find _WwG
     EnumChildWindows(excelWindow, (WNDENUMPROC) EnumChildProc, (LPARAM)1);

     return 0;
}
</pre>
<p>Useful Links for this post:</p>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/dd317978%28VS.85%29.aspx">AccessibleObjectFromWindow Documentation</a></li>
<li><a title="Using Visual C++ to Automate Office" href="http://support.microsoft.com/kb/238972">Using Visual C++ to Automate Office</a></li>
<li><a title="EnumChildWindows Documentation" href="http://msdn.microsoft.com/en-us/library/ms633494%28VS.85%29.aspx">EnumChildWindows Documentation</a></li>
</ul>
<p>Key phrases: Accessing Excel 2007 COM object using AccessibleObjectFromWindow, Automating Excel 2007 with Microsoft Active Accessibility MSAA<br />
<em><strong>Update:</strong> I&#8217;ve updated the full source to utilize get_Application.  get_Document was in place previously, which was leftover from my Word source code.</em></p>
]]></content:encoded>
			<wfw:commentRss>https://www.northatlantawebdesign.com/index.php/2009/07/15/access-microsoft-excel-2007-com-api-through-microsoft-active-accessibility/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
	</channel>
</rss>
