<?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>AB-WebLog.com&#187; .NET</title>
	<atom:link href="http://www.ab-weblog.com/en/category/development/dotnet/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.ab-weblog.com/en</link>
	<description>Andreas Breitschopp</description>
	<lastBuildDate>Wed, 18 Mar 2015 09:47:48 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>DevExpress XPO: Expensive SQL Query Upon XPCollection.EndInit() Call</title>
		<link>http://www.ab-weblog.com/en/devexpress-xpo-expensive-sql-query-upon-xpcollection-endinit-call/</link>
		<comments>http://www.ab-weblog.com/en/devexpress-xpo-expensive-sql-query-upon-xpcollection-endinit-call/#comments</comments>
		<pubDate>Sat, 10 Nov 2012 11:03:50 +0000</pubDate>
		<dc:creator>Andreas Breitschopp</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[DevExpress]]></category>
		<category><![CDATA[XPO]]></category>

		<guid isPermaLink="false">http://www.ab-weblog.com/en/?p=672</guid>
		<description><![CDATA[For .NET projects I do like to use the controls by DevExpress. Additionally DevExpress XPO is very useful as database abstraction layer. But in a current project I came across a very strange issue: for a few forms (curiously not for &#8230; <a href="http://www.ab-weblog.com/en/devexpress-xpo-expensive-sql-query-upon-xpcollection-endinit-call/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>For .NET projects I do like to use the controls by <a title="DevExpress Website" href="http://www.devexpress.com" target="_blank">DevExpress</a>. Additionally DevExpress XPO is very useful as database abstraction layer.</p>
<p>But in a current project I came across a very strange issue:</p>
<p>for a few forms (curiously not for all) a very expensive SQL query is sent to the database backend while the form is loading. It was basically a SQL query that loads all (and I mean really all) data rows from the database which is obviously not a very good idea. But as I wrote that was not the case for all forms: when loading the other forms only the current data object (the current row in the table) was loaded as expected.</p>
<p>Of course, I&#8217;ve first contacted the always very fast and helpful DevExpress support. They researched what causes the data request and determined that the XPCollection.Count property is requested by the CurrencyManager after the Control.UpdateBindings method call. Because that&#8217;s something inside the .NET Framework they can&#8217;t do anything about it unfortunately.</p>
<p>They suggested to not set the XPCollection at design time, but this would result in losing the possibility to build the forms in the Windows Forms Designer. That would have been very bad, because I do have a lot of big forms in this project and I really don&#8217;t like to build them all in code.</p>
<p>But I found another way &#8211; I will not call that solution, just a work-around &#8211; to be still able to use the designer:</p>
<p>Therefore I simple wrote two batch files (using a command line replacement tool called <a title="FART Website" href="http://fart-it.sourceforge.net" target="_blank">FART</a>), one that runs before the build starts and makes sure no XPCollection is initialized in the InitializeComponent method (by just commenting the lines of code) and a second one that runs after the build finished and reverts these changes.</p>
<p>Here is the content of the pre-build batch file:</p>
<pre class="brush: text; gutter: true">%1Tools\fart.exe -r -C &quot;%1*.designer.cs&quot; &quot;this.xpKern = new DevExpress.Xpo.XPCollection(this.components);&quot; &quot;\x2f\x2fthis.xpKern = new DevExpress.Xpo.XPCollection(this.components);&quot;
%1Tools\fart.exe -r -C &quot;%1*.designer.cs&quot; &quot;((System.ComponentModel.ISupportInitialize)(this.xpKern)).BeginInit();&quot; &quot;\x2f\x2f((System.ComponentModel.ISupportInitialize)(this.xpKern)).BeginInit();&quot;
%1Tools\fart.exe -r -C &quot;%1*.designer.cs&quot; &quot;this.xpKern.ObjectType = typeof(Administration.Daten.Kern);&quot; &quot;\x2f\x2fthis.xpKern.ObjectType = typeof(Administration.Daten.Kern);&quot;
%1Tools\fart.exe -r -C &quot;%1*.designer.cs&quot; &quot;this.xpKern.Session = this.unitOfWork;&quot; &quot;\x2f\x2fthis.xpKern.Session = this.unitOfWork;&quot;
%1Tools\fart.exe -r -C &quot;%1*.designer.cs&quot; &quot;((System.ComponentModel.ISupportInitialize)(this.xpKern)).EndInit();&quot; &quot;\x2f\x2f((System.ComponentModel.ISupportInitialize)(this.xpKern)).EndInit();&quot;

@exit 0</pre>
<p>And the post-build one that reverts the changes:</p>
<pre class="brush: text; gutter: true">%1Tools\fart.exe -r -C &quot;%1*.designer.cs&quot; &quot;\x2f\x2fthis.xpKern = new DevExpress.Xpo.XPCollection(this.components);&quot; &quot;this.xpKern = new DevExpress.Xpo.XPCollection(this.components);&quot;
%1Tools\fart.exe -r -C &quot;%1*.designer.cs&quot; &quot;\x2f\x2f((System.ComponentModel.ISupportInitialize)(this.xpKern)).BeginInit();&quot; &quot;((System.ComponentModel.ISupportInitialize)(this.xpKern)).BeginInit();&quot;
%1Tools\fart.exe -r -C &quot;%1*.designer.cs&quot; &quot;\x2f\x2fthis.xpKern.ObjectType = typeof(Administration.Daten.Kern);&quot; &quot;this.xpKern.ObjectType = typeof(Administration.Daten.Kern);&quot;
%1Tools\fart.exe -r -C &quot;%1*.designer.cs&quot; &quot;\x2f\x2fthis.xpKern.Session = this.unitOfWork;&quot; &quot;this.xpKern.Session = this.unitOfWork;&quot;
%1Tools\fart.exe -r -C &quot;%1*.designer.cs&quot; &quot;\x2f\x2f((System.ComponentModel.ISupportInitialize)(this.xpKern)).EndInit();&quot; &quot;((System.ComponentModel.ISupportInitialize)(this.xpKern)).EndInit();&quot;

@exit 0</pre>
<p>The <code class="brush: text; gutter: false">@exit 0</code> at the end of them is important as otherwise code 2 is returned (for whatever reason) and the Visual Studio build system will complain about it every build.</p>
<p>Now you just need to call these batch files in the Visual Studio build events with</p>
<pre class="brush: text; gutter: false">$(ProjectDir)Tools\PreBuild.bat $(ProjectDir)</pre>
<p>respectively:</p>
<pre class="brush: text; gutter: false">$(ProjectDir)Tools\PostBuild.bat $(ProjectDir)</pre>
<p>I know that this is not a very good &#8220;solution&#8221;, but the only idea I had that I can still use the form designer while avoiding these expensive SQL queries.</p>
<p><em>Did you ever have the same issue and maybe even a better solution for it? I&#8217;m looking forward to any other suggestion on this topic!</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ab-weblog.com/en/devexpress-xpo-expensive-sql-query-upon-xpcollection-endinit-call/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Spartakiade Conference in Berlin</title>
		<link>http://www.ab-weblog.com/en/spartakiade-conference-in-berlin/</link>
		<comments>http://www.ab-weblog.com/en/spartakiade-conference-in-berlin/#comments</comments>
		<pubDate>Wed, 09 May 2012 09:23:22 +0000</pubDate>
		<dc:creator>Andreas Breitschopp</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Events]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[Intel AppUp]]></category>
		<category><![CDATA[AppUp]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[event]]></category>
		<category><![CDATA[Intel]]></category>
		<category><![CDATA[speech]]></category>

		<guid isPermaLink="false">http://www.ab-weblog.com/en/?p=491</guid>
		<description><![CDATA[I was invited to be a trainer on the Spartakiade Conference (German) in Berlin (Germany) on June 16, 2012. There I will provide a session about &#8220;Intel AppUp &#8211; Your HTML5/.NET App in the App Store&#8221;:  If you want to sell a product &#8230; <a href="http://www.ab-weblog.com/en/spartakiade-conference-in-berlin/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I was invited to be a trainer on the <a title="Spartakiade Conference Website" href="http://spartakiade.org/2012/MainPage.ashx" target="_blank">Spartakiade Conference</a> (German) in Berlin (Germany) on June 16, 2012.</p>
<p>There I will provide a session about &#8220;Intel AppUp &#8211; Your HTML5/.NET App in the App Store&#8221;:</p>
<blockquote><p> If you want to sell a product as an developer every new distribution channel is welcome. One of them is the app store AppUp operated by Intel that is already pre-installed on many newly sold notebooks (e. g. Dixon&#8217;s Retail). In this session Andreas Breitschopp will show how an existing HTML5 or .NET app is prepared for AppUp. The participants are welcome to bring their own products. These will then be prepared for AppUp together.</p></blockquote>
<p>Of course, there will be also other interesting topics at the conference and the attendance is free.</p>
<p><em>Therefore I&#8217;m looking forward to see you there!</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ab-weblog.com/en/spartakiade-conference-in-berlin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RemotingException Using IPC With .NET</title>
		<link>http://www.ab-weblog.com/en/remotingexception-using-ipc-with-net/</link>
		<comments>http://www.ab-weblog.com/en/remotingexception-using-ipc-with-net/#comments</comments>
		<pubDate>Sat, 12 Nov 2011 23:13:49 +0000</pubDate>
		<dc:creator>Andreas Breitschopp</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[IPC]]></category>
		<category><![CDATA[remoting]]></category>
		<category><![CDATA[service]]></category>

		<guid isPermaLink="false">http://www.ab-weblog.com/en/?p=363</guid>
		<description><![CDATA[In a project I&#8217;m using IPC (Inter Process Communication) for sharing objects of a Windows service with a client application. This always worked correctly when the client application started the first time and used the objects of the Windows service. &#8230; <a href="http://www.ab-weblog.com/en/remotingexception-using-ipc-with-net/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In a project I&#8217;m using IPC (Inter Process Communication) for sharing objects of a Windows service with a client application.</p>
<p>This always worked correctly when the client application started the first time and used the objects of the Windows service. But starting the client application (without restarting the service) some minutes later again, resulted in a <em>RemotingException</em> with this strange error message:</p>
<pre class="brush: text; gutter: false">Failed to write to an IPC Port: The pipe is being closed.</pre>
<p>It took me quite long to figure out what the problem was:<br />
as it is important for my service to really have only one instance of the remote object for the whole lifetime of the service, I used <em>RemotingServices.Marshal</em> to register a previously instantiated object. But I did not know that objects registered with this method are only valid for a very short time period (one minute) by default.</p>
<p>To fix that you need to override the <em>MarshalByRefObject.InitializeLifetimeService</em> method within your remote server object like this:</p>
<pre class="brush: csharp; gutter: true">public override Object InitializeLifetimeService()
{
	ILease lease = (ILease)base.InitializeLifetimeService();
	if (lease.CurrentState == LeaseState.Initial)
	{
		lease.InitialLeaseTime = TimeSpan.FromDays(365);
		lease.SponsorshipTimeout = TimeSpan.FromDays(365);
		lease.RenewOnCallTime = TimeSpan.FromDays(365);
	}
	return lease;
}</pre>
<p>And here the same for VB .NET developers:</p>
<pre class="brush: vbnet; gutter: true">Public Overrides Function InitializeLifetimeService() As Object
	Dim lease As ILease = CType(MyBase.InitializeLifetimeService(), ILease)
	If lease.CurrentState = LeaseState.Initial Then
		lease.InitialLeaseTime = TimeSpan.FromDays(365)
		lease.SponsorshipTimeout = TimeSpan.FromDays(365)
		lease.RenewOnCallTime = TimeSpan.FromDays(365)
	End If
	Return lease
End Function</pre>
<p>OK, 365 days are probably a little bit exaggerated, but this way you can be really sure your remote objects won&#8217;t expire very fast. <img src='http://www.ab-weblog.com/en/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>Did you come across this problem yourself already, too?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ab-weblog.com/en/remotingexception-using-ipc-with-net/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Visual Studio Form Designer With Forms Extending Abstract Classes</title>
		<link>http://www.ab-weblog.com/en/using-visual-studio-form-designer-with-forms-extending-abstract-classes/</link>
		<comments>http://www.ab-weblog.com/en/using-visual-studio-form-designer-with-forms-extending-abstract-classes/#comments</comments>
		<pubDate>Wed, 26 Oct 2011 13:31:18 +0000</pubDate>
		<dc:creator>Andreas Breitschopp</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[form designer]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[Visual Studio]]></category>

		<guid isPermaLink="false">http://www.ab-weblog.com/en/?p=315</guid>
		<description><![CDATA[For a recent project I wanted to create an abstract form base class. This way some global functionality can be inherited by all of my forms and interface methods can be defined. But the result was this error message as &#8230; <a href="http://www.ab-weblog.com/en/using-visual-studio-form-designer-with-forms-extending-abstract-classes/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>For a recent project I wanted to create an abstract form base class. This way some global functionality can be inherited by all of my forms and interface methods can be defined.</p>
<p>But the result was this error message as soon as I tried to open one of my derived from classes in the Visual Studio form designer:</p>
<pre class="brush: text; gutter: false">The designer must create an instance of type &lt;type name&gt;, but it can't because the type is declared as abstract.</pre>
<p>Hereupon I&#8217;ve searched for a solution in the web and it seems that I was not the only one that had the idea to derive some form classes from an abstract base class. To solve the problem I&#8217;ve created a dummy implementation of my abstract base class and derived the form classes from this dummy implementation. This way the form classes can be displayed in the Visual Studio form designer again.</p>
<p>In C# the classes look like this then:</p>
<pre class="brush: csharp; gutter: true">public abstract partial class BaseForm : Form
{
  // Methods of your abstract class...
}

#if DEBUG
public class BaseFormImpl : BaseForm
{
  // The dummy implementation of the abstract BaseForm class.
}
#endif

#if DEBUG
public partial class RealForm : BaseFormImpl
#else
public partial class RealForm : BaseForm
#endif
{
  // One of the forms extending the base form.
}</pre>
<p>And for VB .NET developers it looks like this:</p>
<pre class="brush: vbnet; gutter: true">Public MustInherit Partial Class BaseForm
  Inherits Form
  ' Methods of the abstract base class...
End Class

#if DEBUG
Public Class BaseFormImpl
  Inherits BaseForm
  ' The dummy implementation of the abstract BaseForm class.
End Class
#endif

Public Partial Class RealForm
#if DEBUG
  Inherits BaseFormImpl
#else
  Inherits BaseForm
#endif
  ' One of the forms extending the base form.
End Class</pre>
<p>Probably you have noticed the compiler directives: obviously that&#8217;s not necessary that the forms work correctly inside the form designer again. But I don&#8217;t like to have unnecessary code inside the released product (and the dummy implementation of the abstract <em>BaseForm</em> class is really useless). Therefore I used these conditional compiler directives to make sure that this dummy class is only used in debug mode.</p>
<p><em>Did you come across this issue yourself already, too?</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ab-weblog.com/en/using-visual-studio-form-designer-with-forms-extending-abstract-classes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Math Parser for .NET</title>
		<link>http://www.ab-weblog.com/en/math-parser-for-net/</link>
		<comments>http://www.ab-weblog.com/en/math-parser-for-net/#comments</comments>
		<pubDate>Thu, 28 Jul 2011 16:49:40 +0000</pubDate>
		<dc:creator>Andreas Breitschopp</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://www.ab-weblog.com/en/?p=1</guid>
		<description><![CDATA[For a new software project I&#8217;ve searched for a good math parser for .NET. Beside parsing and evaluating a formula with all common mathematical functions (like sine, cosine, logarithm, &#8230;), I additionally needed to be able to use variables inside &#8230; <a href="http://www.ab-weblog.com/en/math-parser-for-net/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>For a new software project I&#8217;ve searched for a good math parser for .NET.</p>
<p>Beside parsing and evaluating a formula with all common mathematical functions (like sine, cosine, logarithm, &#8230;), I additionally needed to be able to use variables inside the formulas.</p>
<p>The best solution that I found is this one here:<br />
<a href="http://www.lundin.info/mathparser.asp" target="_blank">http://www.lundin.info/mathparser.asp</a></p>
<p>The usage is very easy; here you can see a C# example code:</p>
<pre class="brush: csharp; gutter: true">// Instantiate the parser
ExpressionParser parser = new ExpressionParser();

// Create a hashtable to hold values
Hashtable h = new Hashtable();

// Add variables and values to hashtable
h.Add("x", 1.ToString());
h.Add("y", 2.ToString());

// Parse and get the result
double result = parser.Parse("xcos(y)", h);</pre>
<p>And for those of you that prefer Visual Basic .NET:</p>
<pre class="brush: vbnet; gutter: true">' Instantiate the parser
Dim parser As New ExpressionParser()

' Create a hashtable to hold values
Dim h As New Hashtable()

' Add variables and values to hashtable
h.Add("x", 1.ToString())
h.Add("y", 2.ToString())

' Parse and get the result
Dim result As Double
result = parser.Parse("xcos(y)", h)</pre>
<p>It is important that the values are always added as String to the hashtable of variables. The reason is that internally it just injects them into the formula before parsing it &#8211; this way they have to be of type String, obviously.</p>
<p>The free assembly is open source and under the LGPL license. Therefore it can also be use in commercial projects as long as it is only linked dynamically as external library.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ab-weblog.com/en/math-parser-for-net/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simple Sine Generator for .NET</title>
		<link>http://www.ab-weblog.com/en/simple-sine-generator-for-net/</link>
		<comments>http://www.ab-weblog.com/en/simple-sine-generator-for-net/#comments</comments>
		<pubDate>Mon, 18 Jul 2011 12:08:54 +0000</pubDate>
		<dc:creator>Andreas Breitschopp</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Audio]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[sine]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://www.ab-weblog.com/en/?p=133</guid>
		<description><![CDATA[In this post I want to show how to create an easy sine generator in .NET. Let&#8217;s start with a code listing and then I&#8217;ll explain what I&#8217;m doing here: const double frequency = 1000; const double amplitude = 20000; &#8230; <a href="http://www.ab-weblog.com/en/simple-sine-generator-for-net/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In this post I want to show how to create an easy sine generator in .NET.</p>
<p>Let&#8217;s start with a code listing and then I&#8217;ll explain what I&#8217;m doing here:</p>
<pre class="brush: csharp; gutter: true">const double frequency	= 1000;
const double amplitude	= 20000;
const long sampleRate	= 44100;
const int durationSec	= 5;

long sampleCount = sampleRate * durationSec;

double timeStep = 1.0 / (double)sampleRate;

double time = 0;
int[] values = new int[sampleCount];
for (long i = 0; i &lt; sampleCount; i++) {
	values[i] = (int)(amplitude * Math.Sin(2 * Math.PI * frequency * time));
	time = time + timeStep;
}</pre>
<p>OK, here are some explanations:</p>
<ul>
<li>lines 1-4: some constants you can change to e. g. adjust the frequency.<br />
<em>Note:</em> the frequency cannot be more than half the sampling rate.</li>
<li>line 6: calculating the number of sampling points.</li>
<li>line 8: calculating the time between two sampling points.</li>
<li>lines 10-11: some variable initializations.</li>
<li>lines 12-15: here finally the value of each sampling point is calculated.</li>
</ul>
<p>And here is the corresponding code for Visual Basic .NET:</p>
<pre class="brush: vbnet; gutter: true">const frequency as double		= 1000
const amplitude as double		= 20000
const sampleRate As Long		= 44100
const durationSec As Integer	= 5

Dim sampleCount As Long
sampleCount = sampleRate * durationSec

Dim timeStep As Double
timeStep = 1.0 / sampleRate

Dim time As Double = 0
Dim values(0 To sampleCount - 1) As Integer
For i As Long = 0 To sampleCount - 1
	values(i) = amplitude * Math.Sin(2 * Math.PI * frequency * time)
	time = time + timeStep
Next i</pre>
<p>For sound playback you can now use either an API call like <em>PlaySound</em> (of <em>winmm.dll</em>) or the solution of <a title="Article about .NET sound class" href="http://www.codeproject.com/KB/audio-video/CPIAudio.aspx" target="_blank">this great article</a>.</p>
<p>Did you also need to generate a sine in .NET yourself already?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ab-weblog.com/en/simple-sine-generator-for-net/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Developing a Browser Toolbar: Microsoft Internet Explorer (3/5)</title>
		<link>http://www.ab-weblog.com/en/developing-a-browser-toolbar-microsoft-internet-explorer/</link>
		<comments>http://www.ab-weblog.com/en/developing-a-browser-toolbar-microsoft-internet-explorer/#comments</comments>
		<pubDate>Mon, 01 Mar 2010 15:00:15 +0000</pubDate>
		<dc:creator>Andreas Breitschopp</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASPects]]></category>
		<category><![CDATA[browser]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[publication]]></category>
		<category><![CDATA[toolbar]]></category>

		<guid isPermaLink="false">http://www.ab-weblog.com/en/?p=291</guid>
		<description><![CDATA[This post series reflects my article &#8220;Developing a Browser Toolbar&#8221; published in the ASPects in January 2010 (Volume 23, Issue 1), a magazine of the Association of Shareware Professionals (ASP). The first decision to make is which programming language you &#8230; <a href="http://www.ab-weblog.com/en/developing-a-browser-toolbar-microsoft-internet-explorer/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><em>This post series reflects my article &#8220;Developing a Browser Toolbar&#8221; published in the <a title="ASPects Website" href="http://www.asp-shareware.org/about/aspects.asp" target="_blank">ASPects</a> in January 2010 (Volume 23, Issue 1), a magazine of the <a title="Association of Shareware Professionals Website" href="http://www.asp-shareware.org" target="_blank">Association of Shareware Professionals</a> (ASP).</em></p>
<p>The first decision to make is which programming language you want to use for developing the Internet Explorer toolbar. I did some research in the web and found examples for C++, Visual Basic 6 and .NET. There seem to be some visual styles issues; it obviously does not look so good on Windows Vista and Windows 7 systems by using the C++ version. And as I really don&#8217;t like to develop in Visual Basic 6 anymore, I decided to go the .NET way. The only disadvantage of this decision is that the user needs to have the .NET Framework 2.0 (or higher) installed on the system. But I can live with that, because it is very common already.</p>
<p>Since almost all of my products are developed in .NET, I already had the Visual Studio 2008 installed on my computer. If not, you&#8217;ll need at least the <a title="Microsoft Visual Studio Express Edition Website" href="http://www.microsoft.com/express" target="_blank">Express Edition</a> (version 2005 should be enough, too) for the next steps. I decided to develop the toolbar in C#, but Visual Basic .NET could do the same thing, of course.</p>
<p>As a good starting point I found <a title="Extending Explorer With Band Objects Using .NET and Windows Forms" href="http://www.codeproject.com/KB/shell/dotnetbandobjects.aspx" target="_blank">this</a> and <a title="Internet Explorer Toolbar Creation" href="http://www.codeproject.com/KB/shell/IEToolbar.aspx" target="_blank">this</a> article at the Code Project webpage. If you want to read more about the COM component, you can also read the <a title="Internet Explorer Toolbar (Deskband) Tutorial" href="http://www.codeproject.com/KB/shell/ietoolbartutorial.aspx" target="_blank">C++ tutorial</a>, but that&#8217;s not necessarily needed. By using the demo source code of those articles you should get a working toolbar – at least on a Windows XP system. But there were some issues I came across that needed to be fixed and therefore I will describe them in more detail here:</p>
<h2>Making Toolbar Show up Correctly on All Operating Systems</h2>
<p>By using the demo code of the articles mentioned above, I got the toolbar to work quite fast on my Windows XP testing machine. I was naively thinking that if the toolbar works on Windows XP with Internet Explorer 8, it will also work on Windows Vista and Windows 7 with the same Internet Explorer version. But indeed, I had to learn that this is absolutely not the case! It either just does not show up at all or so far on the right side, that you can only see the toolbar if you have a horizontal resolution of at least 2,000 pixels. So I had to search for a solution, but most changes to the code resulted in the toolbar working either on the one or on the other operating system or browser version combination. After some hours of frustrated testing, I changed the <em>GetBandInfo</em> procedure of the <em>BandObjectsLib</em> class in the following way. Although I&#8217;m still not absolutely sure why, it works fine now on all operating system:</p>
<pre class="brush: csharp; gutter: true">public virtual void GetBandInfo(UInt32 dwBandID, UInt32 dwViewMode, ref DESKBANDINFO dbi)
{
    if ((dbi.dwMask &amp; DBIM.MINSIZE) != 0)
    {
        dbi.ptMinSize.X = this.MinimumSize.Width;
        dbi.ptMinSize.Y = this.MinimumSize.Height;
    }

    if ((dbi.dwMask &amp; DBIM.MAXSIZE) != 0)
    {
        dbi.ptMaxSize.X = this.MaximumSize.Width;
        dbi.ptMaxSize.Y = this.MaximumSize.Height;
    }

    if ((dbi.dwMask &amp; DBIM.ACTUAL) != 0)
    {
        dbi.ptActual.X = this.Size.Width;
        dbi.ptActual.Y = this.Size.Height;
    }

    if ((dbi.dwMask &amp; DBIM.BKCOLOR) != 0)
    {
        dbi.dwMask &amp;= ~DBIM.BKCOLOR;
    }

    dbi.dwModeFlags = DBIMF.BREAK;
}</pre>
<h2>Nicer Appearance on Windows XP and above</h2>
<p>If you don&#8217;t add the following event handler to the <em>BandObjectsLib</em> class, your toolbar will still work, but will just not look very good on Windows XP and above. The <em>if</em>-statement in the event function additionally makes sure that the toolbar still works on older operating systems like Windows 98, 2000 and ME. Otherwise it would throw an exception on these operating systems. Here is the code I&#8217;ve used to get it to work correctly on all operating systems:</p>
<pre class="brush: csharp; gutter: true">[DllImport("uxtheme", ExactSpelling = true)]
public extern static Int32 DrawThemeParentBackground(IntPtr hWnd, IntPtr hdc,
                                                     ref Rectangle pRect);

protected override void OnPaintBackground(PaintEventArgs e)
{
    if (System.Environment.OSVersion.Platform &gt;= PlatformID.Win32NT &amp;&amp;
           (Environment.OSVersion.Version.Major == 5 &amp;&amp;
            Environment.OSVersion.Version.Minor &gt;= 1 ||
            Environment.OSVersion.Version.Major &gt;= 6) &amp;&amp;
           this.BackColor == Color.Transparent)
    {
        // Only if operating system is Windows XP or higher
        IntPtr hdc = e.Graphics.GetHdc();
        Rectangle rec = new Rectangle(e.ClipRectangle.Left,
            e.ClipRectangle.Top, e.ClipRectangle.Width, e.ClipRectangle.Height);
        DrawThemeParentBackground(this.Handle, hdc, ref rec);
        e.Graphics.ReleaseHdc(hdc);
    }
    else
    {
        base.OnPaintBackground(e);
    }
}</pre>
<h2>No Serialization Allowed</h2>
<p>When developing a Firefox toolbar you can use the Mozilla preferences service to store and load user-defined values inside Firefox itself. Because there is no equivalent in Internet Explorer and I&#8217;m using XML serialization in many of my other .NET products, I wanted to use it in the toolbar project, too. This worked fine at first sight, but if the <em>Protected Mode</em> is enabled in Internet Explorer 8 (and it is by default, at least since Windows Vista), it shows an ugly warning dialog to the user whenever the toolbar is initialized. I won&#8217;t explain the reason in detail here, but just don&#8217;t use serialization in Internet Explorer toolbars. You can save user-defined values either without serialization in the file system below the local application data directory or simply by using the registry.</p>
<h2>Automatic Online Update</h2>
<p>As I did in the Firefox version, I also wanted the Internet Explorer toolbar to come with an automatic update feature. Because there is no update system for toolbars in Firefox, you have to implement it yourself. But this is quite easy, because you can use, as in any other .NET application, the <em>WebClient</em> class for doing a HTTP request to first ask if there is a new update available and then to receive the update file if needed. On the server side I have a small PHP script handling the update requests. The update file which is downloaded is the normal setup executable that just overrides all files with the new ones. The only thing you have to care about is the way you call the executable setup file after downloading, because otherwise a User Account Control (UAC) prompt will be shown. I&#8217;ve written this procedure that you can use for executing a file from within the toolbar code without any warning displayed to the user:</p>
<pre class="brush: csharp; gutter: true">private void startProcess(string fileName, string arguments)
{
    System.Diagnostics.ProcessStartInfo startInfo =
        new System.Diagnostics.ProcessStartInfo();
    startInfo.UseShellExecute = true;
    startInfo.WorkingDirectory = Environment.CurrentDirectory;
    startInfo.FileName = fileName;
    if (Environment.OSVersion.Platform &gt;= PlatformID.Win32NT &amp;&amp;
            Environment.OSVersion.Version.Major &gt;= 6)
        // Only if operating system is Windows Vista or higher
        startInfo.Verb = "runas";
    else
        startInfo.Verb = "open";
    startInfo.Arguments = arguments;
    startInfo.ErrorDialog = true;
    try
    {
        System.Diagnostics.Process process = System.Diagnostics.Process.Start(startInfo);
        process.WaitForExit();

        MessageBox.Show(objToolbarData["msg.restartBrowserText"],
                        objToolbarData["msg.restartBrowserTitle"],
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
    catch (Exception ex)
    {
        if (debugMode) MessageBox.Show(ex.ToString());
    }
}</pre>
<h2>Uninstall Button Inside the Toolbar</h2>
<p>That&#8217;s the only thing which is easier to implement in Internet Explorer than in Firefox; it is enough to call the uninstall executable (again with the <em>startProcess</em> procedure above) of the installation system (see next post###) to uninstall the toolbar again. It will disappear then after browser has been restarted (just as on Firefox).</p>
<p>It&#8217;s done; the Internet Explorer version of our toolbar is ready, too! It will work on Internet Explorer 6 or higher running on Windows 98 or higher with an installed .NET Framework 2.0.</p>
<p>In the <a title="Developing a Browser Toolbar: Installation System (4/5)" href="http://www.ab-weblog.com/en/developing-a-browser-toolbar-installation-system/">next post</a> I&#8217;ll explain how we get the toolbars installed.</p>
<h2>Contents of Post Series &#8220;Developing a Browser Toolbar&#8221;:</h2>
<ul>
<li><a title="Developing a Browser Toolbar: Introduction (1/5)" href="http://www.ab-weblog.com/en/developing-a-browser-toolbar-introduction/">Introduction</a></li>
<li><a title="Developing a Browser Toolbar: Mozilla Firefox (2/5)" href="http://www.ab-weblog.com/en/developing-a-browser-toolbar-mozilla-firefox-25/">Mozilla Firefox</a></li>
<li>Microsoft Internet Explorer</li>
<li><a title="Developing a Browser Toolbar: Installation System (4/5)" href="http://www.ab-weblog.com/en/developing-a-browser-toolbar-installation-system/">Installation System</a></li>
<li><a title="Developing a Browser Toolbar: Summary (5/5)" href="http://www.ab-weblog.com/en/developing-a-browser-toolbar-summary/">Summary</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.ab-weblog.com/en/developing-a-browser-toolbar-microsoft-internet-explorer/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->