Tuesday, November 07, 2006

Scott Leonard asks: I am trying to transfer some binary data (byte array) through the clipboard in VS2005 C# without any success. Essentially what I want to do is take a binary file (e.g. dll, exe, jpg, etc.) as a byte array and put it on the clipboard. Then I want to go into a programmer's editor (VSlick, Ultra, VC6, HexEdit etc.), paste the clipboard into an empty doc and save it. I have tried
SetText and SetData and scoured MSDN and the web to no avail. I am not trying to create a custom clipboard type to pass into another app I am writing, I just want to pass binary data and paste it into a standard editor. I found a little tool called CFList from www.ciansoft.com which will show you what format the data in your clipboard is in, and I was trying to see how VSlick and VC6 did it, but it doesn't give very detailed info. MSDN mentions using a memorystream if you want to pass data around unaltered, but I had no success with that either. Here is a simple example of a couple things I tried:

//byte[] byTag = new byte[5] { 0x05, 0x03, 0x09, 0x00, 0x01 }; //doesn't
matter where we get this...
// MemoryStream ms = new MemoryStream(byTag);
// Clipboard.SetData(/*DataFormats.GetFormat(*/"BinaryData"/*)*/,
byTag/*ms*/);




William Answers:

There are two rules for moving data onto the clipboard.
  1. It must be done from the primary thread of a windows form (the thread that created the form), and
  2. You typically need to Clear the clipboard before sending data to it.
Obviously when getting data from the clipboard you don't need to clear it first, but it still needs to occur on a form thread.

To get the function to invoke on the thread which created the form, you'll need to encapsulate your code in a function which checks to see if an Invoke is needed, and if it is, to invoke itself.

Here's a form that I tested out that demonstrates the technique:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
Thread T = new Thread(new ThreadStart(SetTest));
T.Start();
}

public void SetTest()
{
byte[] byTag = new byte[5] { 0x05, 0x03, 0x09, 0x00, 0x01 };
SetClipboard(this, byTag);
}

public delegate void d_SetClipboard(Form Parent, byte[] Data);
public void SetClipboard(Form Target, byte[] Data)
{
if (Target.InvokeRequired)
Target.Invoke(new d_SetClipboard(SetClipboard), new object[] { Target, Data });
else
{
Clipboard.Clear();
Clipboard.SetDataObject(System.Text.ASCIIEncoding.ASCII.GetString(Data), true);
}
}

public delegate byte[] d_GetClipboard(Form Parent);
public byte[] GetClipboard(Form Target)
{
if (Target.InvokeRequired)
return (byte[])Target.Invoke(new d_GetClipboard(GetClipboard), new object[] { Target });
else
{
IDataObject ido = Clipboard.GetDataObject();
string data = (string) ido.GetData(typeof(string));
return ASCIIEncoding.ASCII.GetBytes(data);
}
}

private void button2_Click(object sender, EventArgs e)
{
Thread T = new Thread(new ThreadStart(GetTest));
T.Start();
}

public void GetTest()
{
if (this.InvokeRequired)
Invoke(new MethodInvoker(GetTest));
else
{
byte[] x = GetClipboard(this);
textBox1.Text = x.Length.ToString();
}
}
}
}



Click button1 to set the clipboard to the contents of the array, then click button 2. The text box will be set to 5, which is the length of the byte array on the clipboard. Notice I translated the byte array into/from a string to make it easy to paste into other applications. It may not be necessary to do this if you want the content as an actual byte array instead of as an ASCII string.

Friday, November 03, 2006

What are some cool, new things for Visual Studio 2005 ?

Recently I gave a (lukewarm) presentation on some new and cool things for Visual Studio 2005. I presented a number of free and/or open source tools that have made the last few months of coding somewhat easier.

They include:
The Microsoft Consolas Font Family is a set of highly legible fonts designed for ClearType. It is intended for use in programming environments and other circumstances where a monospaced font is specified. This installation package will set the default font for Visual Studio to Consolas.
A utility to make building XML Comments and keeping them up to date very easy. Load your project and C#CommDog will automatically walk through your project and insert XML comment placeholders with a "C#CD: " in each area you haven't already written a comment. Then you go through, file by file, and find each "C#CD: " string and replace it with actual documentation. C#CommDog keeps track of how many items there are left to write with an easy to follow red/yellow/green system for each file. So if there are 5 strings left to write in a file, it will show a yellow light. When you've written those 5 lines and save the file, C#CommDog updates the entry with a green arrow. This simple appoach to XML Comments makes going from no comments to completely commented code a snap.
This one is shareware for 30 days, but is fully functional. A brief pause on start up after 30 days until you register is the only downsite. $69 to register, and worth every penny.
Enabling managed class library developers throughout the world to easily create accurate, informative documentation with a common look and feel.
A GUI for creating projects to build help files with Sandcastle and a console mode tool to build them as well. Between this NDoc-like program, C#CommDog and Sandcastle (above), you can create MSDN quality documentation from even a very large DLL in only a few days. Building a compiled help file from XML comments for free !
Connects to SQL Server or MySql (or Enterprise data block) and generates ActiveRecord pattern style objects for each table and stored procedure found. No code to write. Just add some XML and your connection string to your Web.config, add a .abp file (a new file) with just a * in it and a reference to SubSonic and each time you build custom objects are made available that directly model your database. This one is not only free but open source, allowing developers to take the code generator and do with it as they see fit.
Allows you to quickly script a SQL Server 2005 database to a series of DROP CREATE and INSERT statements that recreate not only the structure but the actual data in a database. This is a free command line utility from Microsoft.
Editing code snippet XML files can be cumbersome. Shipp Doggy Dogg makes the process much (MUCH) easier with a gui that allows you to forget about the details of the XML and just write the snippets you're looking for. This one is a free utility. You may also want to check out the Code Snippet Editor for Visual Basic 2005 from Microsoft (which works with C# snippets as well, but you have to add the folders to its GUI yourself).

XML Notepad 2006 provides a simple intuitive user interface for browsing and editing XML documents. This one is a new utility from Microsoft and allows you to not only edit XML and XSL documents, but also validate and test xsl render as well. This is no XMLSpy, but it's not bad for being free.
This add-in for Visual Studio further extends the class designer with some very useful features including the ability to export the image to a web page (with hover over areas for methods and properties), simplified zoom and pan, additional interface and class connection options, and more (see the read me). This is a free utility from Microsoft.


In my presentation, I failed to mention a web site I found called DotNetSlackers: ASP.NET News For Lazy Developers which I thought was interesting.