Recording Skype
Written by Harry Fairhead   
Sunday, 12 July 2009
Article Index
Recording Skype
Getting started
Message in a queue
Talking to Skype
Make the call

Message in a queue

If you are following the explanation you might be wondering how the skypedata struct ever gets any data in it. At the moment this second half of the interchange hasn’t been touched on. So far our application sends a message to Skype but ignores any response. How do we pick up a message that another application has sent?

The answer is that we have to tap into the message loop, or “pump”, that every application has. In many cases the details of message processing are hidden deep within the language or framework but .NET provides easy access. Every form has a virtual WndProc method that implements the message loop and to process additional messages all you have to do is override it. In this case we simply add:

protected override void WndProc(
ref Message m)
{

WndProc is called each time there is a message to process. The parameter m is a struct that contains the different portions of the message. Notice that the internal workings of Windows don’t use a struct or any sort of data structure to represent a message - this is just .NET wrapping the lower level functioning of the system for us.

The type of message is determined by the Msg property and we know from the documentation that Skype will return the custom APIAttach message that we retrieved the code for earlier. To process this we simply use an if statement to detect the message:

if ((UInt32)m.Msg==APIAttach)
{

Skype uses the LParm parameter in the message to send a status code along with the message. The easiest way to decode this is to declare an enumeration:

public enum SkypeAttachStatus : uint
{
Success = 0,
PendingAuthorizaion = 1,
Refused = 2,
NotAvailable = 3,
Available = 0x8001
}

If you want to see the status place a Textbox on the form and add:

SkypeAttachStatus Status =
(SkypeAttachStatus)m.LParam;
textBox1.Text += "Status=" +
Status.ToString() +
Environment.NewLine;

If you run the completed program you will see that Skype responds with a stream of messages in response to the APIDiscover message that you sent, each one with a different status. You can write code to react to each of the different status conditions but the only one that really matters is "success" which means you have permission to use Skype further. In this case WParam is returned containing a handle to Skype’s main window which you use to send further messages to it.

We clearly need to store Skype’s window handle for further use so we need an additional global variable:

private IntPtr HSkype = IntPtr.Zero;

Now we can test the status and store the window handle for later use:

if (Status == SkypeAttachStatus.Success)
{
HSkype = m.WParam;
}

However this isn’t quite the end of the story. Skype sends a final message after the “success” message to say that it is available for use and this is the one that, in a simple-minded blocking transaction, we should wait for:

if (Status == SkypeAttachStatus.Available)
{
skypedata.valid = true;
}

Notice that by setting the data buffer’s valid property to true we free up WaitForSkype to move on to the next operation. Finally we have to set a non-zero result to signify that the message has been processed – without this Skype closes the connection:

 m.Result = new IntPtr(1);
return;
}

Finally we have to call the parent WndProc method if we haven’t handled the message so that it can deal with all of the messages relating to button clicks and general user interaction. The rule is that when you override WndProc you handle the messages you want to handle but always call the parent WndProc to process any messages you don’t handle:

 base.WndProc(ref m);
}

<ASIN:159257551X>

<ASIN:B001PLWTLG@COM@CA>

<ASIN:B000B8Y5PC@COM@CA>

<ASIN:B000ET1ZM4@UK@DE@FR>

<ASIN:B000JOZWXC@UK@DE@FR>



Last Updated ( Monday, 27 July 2009 )