<?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>richard hyland &#187; Windows Development</title>
	<atom:link href="http://www.richardhyland.com/diary/category/computers-internet/windows-development/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.richardhyland.com/diary</link>
	<description>random ramblings of a web, windows and iphone developer, oh and amateur photographer</description>
	<lastBuildDate>Fri, 16 Jul 2010 13:32:52 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=abc</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain='www.richardhyland.com' port='80' path='/diary/?rsscloud=notify' registerProcedure='' protocol='http-post' />
		<item>
		<title>.NET installers</title>
		<link>http://www.richardhyland.com/diary/2009/05/26/net-installers/</link>
		<comments>http://www.richardhyland.com/diary/2009/05/26/net-installers/#comments</comments>
		<pubDate>Tue, 26 May 2009 08:00:12 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[Windows Development]]></category>

		<guid isPermaLink="false">http://www.richardhyland.com/diary/?p=482</guid>
		<description><![CDATA[It&#8217;s always been one of the most important, yet often overlooked part of a Windows application, the installation process.
I started off in Visual Studio using the default setup process project and for the most part it worked absolutely fine.  In VS2005 I&#8217;d build my project, I&#8217;d create a setup.exe wrapper around my MSI, then [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignright size-thumbnail wp-image-483" title="Setup Screen" src="http://www.richardhyland.com/diary/wp-content/uploads/2009/05/setupo-150x150.jpg" alt="Setup Screen" width="150" height="150" />It&#8217;s always been one of the most important, yet often overlooked part of a Windows application, the installation process.</p>
<p>I started off in Visual Studio using the default setup process project and for the most part it worked absolutely fine.  In VS2005 I&#8217;d build my project, I&#8217;d create a setup.exe wrapper around my MSI, then bundle it in a self extracting zip file to launch setup.exe.  That worked for me and I liked the setup.</p>
<p>Then came Visual Studio 2008 and that all changed.  Microsoft didn&#8217;t seem to change too much in the setup process yet I was finding my setup projects were crashing constantly and consistently.  I discovered that with the 2008 setup system the .exe wrapper was calling the msi and immediately exiting allowing the .msi to carry on.  Yet the WinZip self extracting .exe tool was waiting for the .exe to finish before cleaning up the files. Effectively as soon as setup.exe finished, WinZip deleted the .msi even if it was still being used.</p>
<p>After hours of research I couldn&#8217;t find a way to change this so I decided to look for decent applications out there that not only would replicate what the Visual Studio setup project would do, but actually enhance it.</p>
<p>My requirements were pretty straight forward.</p>
<ol>
<li>It must detect pre-requisites such as .NET Framework, screen resolutions, etc</li>
<li>Allow me to put custom settings in the registry or shortcut folders</li>
<li>Allow me to create custom components and features that the user can toggle those features on or off</li>
<li>I wanted to be able to associate file extensions with my applications</li>
<li>I wanted to be able to perform actions after an installation or in uninstall (such as add a component to the Visual Studio toolbox)</li>
</ol>
<p>Nice to haves would be to allow me to have licensing integrated at the installer level rather than the application level, customising the interface, etc</p>
<p>My research led me to a number of applications, but the only one that grabbed me was an application called <a href="http://www.advancedinstaller.com" target="_blank">Advanced Installer</a> by Caphyon.</p>
<p><img class="aligncenter size-medium wp-image-484" title="Advanced Installer" src="http://www.richardhyland.com/diary/wp-content/uploads/2009/05/advinstaller-300x177.jpg" alt="Advanced Installer" width="300" height="177" /></p>
<p>This software comes in a number of different versions, most notably a free version too.  I elected for the professional version though but the <a href="http://www.advancedinstaller.com/feats-list.html#free" target="_blank">comparisons</a> are available from their website.</p>
<p>What amazed me about this software was it was so simple to use and build my installer yet the interface to do so was very straight forward, including a number of built in wizards for creating shortcuts, file extension associations, etc.</p>
<p>So much so that I migrated all of my Windows apps to Advanced Installer as soon as I could.</p>
<p>The current version, just released, is version 7.0, which includes an installer for the Windows Mobile Platform.  For me this release is going to solve a problem I hadn&#8217;t even researched.  Basically I am currently developing a lightweight app for Windows that I have thought in passing would be perfect for Windows Mobile too, yet I hadn&#8217;t actually thought how to deploy for Windows Mobile as I&#8217;ve never written a Windows Mobile app before.</p>
<p>So into my Inbox this morning, pops an email from Caphyon telling me about version 7.0 and it&#8217;s new features.  I haven&#8217;t tested this feature yet, but if it works as well as the rest of the application does, this is going to solve hours or even days in working out how to deploy my applications on the Windows Mobile Platform.</p>
<p>I&#8217;m looking forward to their new GUI interface enhancements to the end-user installation screens as well as the MSIE 8 detection. The one other feature that I&#8217;m looking forward to is, in version 7.0 they have added a feature to allow detection of free ports on the PC on installation.  This will solve many issues with connectivity that user&#8217;s face in their own apps all the time!</p>
<p>Basically guys, if you want a decent installer for Windows applications, and you don&#8217;t want to spend a fortune, there is only one way to go&#8230; <a href="http://www.advancedinstaller.com" target="_blank">Advanced Installer</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.richardhyland.com/diary/2009/05/26/net-installers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to truely make a PictureBox background transparent</title>
		<link>http://www.richardhyland.com/diary/2009/05/26/how-to-truely-make-a-picturebox-background-transparent/</link>
		<comments>http://www.richardhyland.com/diary/2009/05/26/how-to-truely-make-a-picturebox-background-transparent/#comments</comments>
		<pubDate>Tue, 26 May 2009 07:35:23 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[Windows Development]]></category>

		<guid isPermaLink="false">http://www.richardhyland.com/diary/?p=476</guid>
		<description><![CDATA[Recently I wanted to overlay a PictureBox over the top of a WebBrowser control in C# for Windows Forms.  I added a transparent PNG to a PictureBox and set the Background to transparent.
However the problem with this approach is the Background of the PictureBox isn&#8217;t truely transparent, it simply inherits the background colour or [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I wanted to overlay a PictureBox over the top of a WebBrowser control in C# for Windows Forms.  I added a transparent PNG to a PictureBox and set the Background to transparent.</p>
<p>However the problem with this approach is the Background of the PictureBox isn&#8217;t truely transparent, it simply inherits the background colour or background image of the control in the layer beneath it.</p>
<p>So in Visual Studio I have the following (note the scroll bar at the bottom right hand corner which can&#8217;t be seen or accessed due to the image overlaying it)</p>
<p><img src="http://www.richardhyland.com/diary/wp-content/uploads/2009/05/untitled-1.jpg" alt="untitled-1" title="untitled-1" width="298" height="39" class="aligncenter size-full wp-image-477" /></p>
<p>However I found a small function that will take the colour of the PictureBox at pixel position x=0, y=0 (which in my image happens to be transparent and apply that to all other transparent elements.</p>
<pre class="csharp" name="code">
public static System.Drawing.Drawing2D.GraphicsPath Transparent(Image im)
        {
            int x;
            int y;
            Bitmap bmp = new Bitmap(im);
            System.Drawing.Drawing2D.GraphicsPath gp = new System.Drawing.Drawing2D.GraphicsPath();
            Color mask = bmp.GetPixel(0, 0);

            for (x = 0; x <= bmp.Width - 1; x++)
            {
                for (y = 0; y <= bmp.Height - 1; y++)
                {
                    if (!bmp.GetPixel(x, y).Equals(mask))
                    {
                        gp.AddRectangle(new Rectangle(x, y, 1, 1));
                    }
                }
            }
            bmp.Dispose();
            return gp;

        }
</pre>
<p>Then in your form load event handler</p>
<pre name="code" class="csharp">
System.Drawing.Drawing2D.GraphicsPath gp = Resources.Images.Transparent(pictureBox1.Image);
pictureBox1.Region = new System.Drawing.Region(gp);
</pre>
<p>And voila, when you compile your application you'll get</p>
<p><img src="http://www.richardhyland.com/diary/wp-content/uploads/2009/05/untitled-2.jpg" alt="untitled-2" title="untitled-2" width="298" height="39" class="aligncenter size-full wp-image-478" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.richardhyland.com/diary/2009/05/26/how-to-truely-make-a-picturebox-background-transparent/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to send a message to an already running .NET application</title>
		<link>http://www.richardhyland.com/diary/2009/05/07/how-to-send-a-message-to-an-already-running-net-application/</link>
		<comments>http://www.richardhyland.com/diary/2009/05/07/how-to-send-a-message-to-an-already-running-net-application/#comments</comments>
		<pubDate>Thu, 07 May 2009 20:38:01 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[Windows Development]]></category>

		<guid isPermaLink="false">http://www.richardhyland.com/diary/?p=449</guid>
		<description><![CDATA[Here is a problem I came across over a year ago now and never got around to detailing.  Here is the scenario
Scenario
I want to create a URL handler in Windows and send that message to my already running .NET application.  For example I create a url handler called myapp: and I create a link in [...]]]></description>
			<content:encoded><![CDATA[<p>Here is a problem I came across over a year ago now and never got around to detailing.  Here is the scenario</p>
<p><strong>Scenario</strong></p>
<p>I want to create a URL handler in Windows and send that message to my already running .NET application.  For example I create a url handler called myapp: and I create a link in HTML to myapp://www.richardhyland.com/, I want to send that URL to my application, let&#8217;s call it MyApp.exe and do something with it.</p>
<p>Now I can quite easily create a URL handler in the Windows registry and call MyApp.exe, but that will create a new instance of the application, what I want  to do is detect to see if MyApp.exe is already running.  If it is then send the URL to that process and if it isn&#8217;t, load MyApp.exe.</p>
<p><strong>My Solution</strong></p>
<p>After many hours with Google, I discovered this cannot be done using managed code, so I had to delve into the scary arena of unmanaged code in .NET.</p>
<p>I first set up MyApp.exe to recieve the message.</p>
<pre name="code" class="csharp">protected override void WndProc(ref System.Windows.Forms.Message m)
{
  if (m.Msg == 0x400)
  {
    // We've recieved a message from handler.exe (we must now decode the IntPtr and deal with it)
    try
    {
      BS.BuildString(m.LParam);
    }
    catch
    {
    }
  }
  base.WndProc(ref m);
}

void BS_StringOK(string Result)
{
  if (Result.StartsWith("myapp://"))
  {
    Result = Result.Substring(8);
  }
  string strUrl = "http://" + Result.ToString();

  this.funcDoSomething(strUrl);
}</pre>
<p>What we&#8217;ve done here is override the WndProc function in the application, examined it for a string and passed it to a function called funcDoSomething()</p>
<p>Next we can create a simple, small .exe for the URL handler to open.</p>
<p>Inside the main class of the handler.exe we need to declare</p>
<pre name="code" class="csharp">
[DllImport("user32.dll")]
private static extern
bool SetForegroundWindow(IntPtr hWnd);

[DllImport("user32.dll")]
private static extern
bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);

[DllImport("user32.dll")]
private static extern
bool IsIconic(IntPtr hWnd);

private const int SW_HIDE = 0;
private const int SW_SHOWNORMAL = 1;
private const int SW_SHOWMINIMIZED = 2;
private const int SW_SHOWMAXIMIZED = 3;
private const int SW_SHOWNOACTIVATE = 4;
private const int SW_RESTORE = 9;
private const int SW_SHOWDEFAULT = 10;

[StructLayout(LayoutKind.Sequential)]
public struct COPYDATASTRUCT
{
   public int dwData;
   public int cbData;
   public int lpData;
}
</pre>
<p>Now you can get the string as an arguement in your form loader and process store it to a string</p>
<p>Now let&#8217;s detect to see if MyApp is running</p>
<pre name="code" class="csharp">
Process[] myProcesses = Process.GetProcessesByName("MyApp");

if (myProcesses.Length >= 1) {
 int n = 0;        // assume the other process is at index 0
 // get the window handle
 IntPtr hWnd = myProcesses[n].MainWindowHandle;

 // if iconic, we need to restore the window
 if (IsIconic(hWnd))
 {
   ShowWindowAsync(hWnd, SW_RESTORE);
 }

 // bring it to the foreground
 SetForegroundWindow(hWnd);

 // Process the message through my builder DLL, see later
 RH.SendMessage.BuildString BS = new RH.SendMessage.BuildString();
 BS.PostString(hWnd, 0x400, 0, strUrl);

 // Message sent to exit
 Application.Exit();
}
else
{
 // Application not running so, start it
 string exeDir = System.Reflection.Assembly.GetExecutingAssembly().Location.Replace("\\handler.exe", "");
 System.Diagnostics.Process.Start(exeDir + "\\MyApp.exe", strURL);
 Application.Exit();
}
</pre>
<p>Finally we need to detail the String Parser DLL that is mentioned in the above code.  This I found online, and it is in Visual Basic</p>
<pre name="code" class="vb">
Imports System.Text

Public Class BuildString

    Private Declare Function PostMessage Lib "user32.dll" _
Alias "PostMessageA" (ByVal HWnd As IntPtr, ByVal WMsg As _
Integer, ByVal WParam As Integer, ByVal LParam As Integer) _
As Integer
    Public Event StringOK(ByVal Result As String)
    Private HWnd As IntPtr
    Private WMsg As Integer = 0
    Private WParam As Integer = 0
    Private LParam As String = ""
    Private tempA(-1) As Byte
    Private enc As Encoding = Encoding.UTF8

    Public Property Encode() As Encoding
        Get
            Return enc
        End Get
        Set(ByVal value As Encoding)
            enc = value
        End Set
    End Property

    Public Sub BuildString(ByVal b As IntPtr)
        If b <> 0 Then
            'build temp array
            Dim tempB(tempA.Length) As Byte
            tempA.CopyTo(tempB, 0)
            tempB(tempA.Length) = b
            ReDim tempA(tempB.Length - 1)
            tempB.CopyTo(tempA, 0)
        Else
            'decode byte array to string
            Dim s As String
            If enc Is Encoding.UTF8 Then
                s = Encoding.UTF8.GetString(tempA)
            ElseIf enc Is Encoding.Unicode Then
                s = Encoding.Unicode.GetString(tempA)
            ElseIf enc Is Encoding.ASCII Then
                s = Encoding.ASCII.GetString(tempA)
            Else
                s = Encoding.Default.GetString(tempA)
            End If
            'send out result string via event
            RaiseEvent StringOK(s)
            ReDim tempA(-1)
        End If
    End Sub

    Public Sub PostString(ByVal HWnd As IntPtr, ByVal WMsg _
As Integer, ByVal WParam As Integer, ByVal LParam As String)
        Me.HWnd = HWnd
        Me.WMsg = WMsg
        Me.WParam = WParam
        Me.LParam = LParam
        'create a new thread to post window message
        Dim t As Threading.Thread
        t = New Threading.Thread(AddressOf SendString)
        t.Start()
    End Sub

    Private Sub SendString()
        'create byte array
        Dim ba() As Byte
        'encode string to byte array
        If enc Is Encoding.UTF8 Then
            ba = Encoding.UTF8.GetBytes(lParam)
        ElseIf enc Is Encoding.Unicode Then
            ba = Encoding.Unicode.GetBytes(lParam)
        ElseIf enc Is Encoding.ASCII Then
            ba = Encoding.ASCII.GetBytes(lParam)
        Else
            ba = Encoding.Default.GetBytes(lParam)
        End If
        Dim i As Integer
        For i = 0 To ba.Length - 1
            'start post message
            PostMessage(hwnd, wMsg, wParam, ba(i))
        Next
        'post a terminator message to destination window
        PostMessage(hwnd, wMsg, wParam, 0)
    End Sub
End Class
</pre>
<p>And voila, that is now I sent a message from one running .NET application to another without starting a new process of the recieving .NET application.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.richardhyland.com/diary/2009/05/07/how-to-send-a-message-to-an-already-running-net-application/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
