c# SendMessage and Skype woes

Posted by Xcelled194 on Stack Overflow See other posts from Stack Overflow or by Xcelled194
Published on 2012-06-04T04:22:52Z Indexed on 2012/06/04 4:40 UTC
Read the original article Hit count: 506

Filed under:
|
|
|

I'm trying to create an add-on to Skype with C#. I don't want to use Skype4COM, as I'd like the experience with messages and such. Unfortunately, the messages are tripping me up. I've got the pumps and such set up. They all work, and my app successfully sends the "APIDiscover" message to Skype, gets a "PendingAuth" response and then the "AttachSuccess" message. However, when I try to send "ping" to Skype (to which it should reply "pong") nothing happens.

The return code from SendMessage is 0 but Marshall.GetLastWin32Error is 1400 (Invalid handle). The handle was returned with the AttachSuccess method. The equivalent C++ code does work, so I'm at a loss.

First is the C++ code I'm using as a guide: Here's the (cut down) message pump. You can ignore everything but where I put the //<----

static LRESULT APIENTRY SkypeAPITest_Windows_WindowProc(
HWND hWindow, UINT uiMessage, WPARAM uiParam, LPARAM ulParam)
{
LRESULT lReturnCode;
bool fIssueDefProc;

lReturnCode=0;
fIssueDefProc=false;
switch(uiMessage)
    {
    case WM_COPYDATA:
        if( hGlobal_SkypeAPIWindowHandle==(HWND)uiParam )
            {
            PCOPYDATASTRUCT poCopyData=(PCOPYDATASTRUCT)ulParam;
            printf( "Message from Skype(%u): %.*s\n", poCopyData->dwData, poCopyData->cbData, poCopyData->lpData);
            lReturnCode=1;
            }
        break;
    default:
        if( uiMessage==uiGlobal_MsgID_SkypeControlAPIAttach )
            {
            switch(ulParam)
                {
                case SKYPECONTROLAPI_ATTACH_SUCCESS:
                    printf("!!! Connected; to terminate issue #disconnect\n");
                    hGlobal_SkypeAPIWindowHandle=(HWND)uiParam;//<---- Right here is where we receive  the handle from Skype.
                    break;
    }
if( fIssueDefProc )
    lReturnCode=DefWindowProc( hWindow, uiMessage, uiParam, ulParam);
return(lReturnCode);
}

and this is the (again dumbed down) "sending message" code

void __cdecl Global_InputProcessingThread(void *)
{
static char acInputRow[1024];
bool fProcessed;

if( SendMessageTimeout( HWND_BROADCAST, uiGlobal_MsgID_SkypeControlAPIDiscover, (WPARAM)hInit_MainWindowHandle, 0, SMTO_ABORTIFHUNG, 1000, NULL)!=0 )
    {
    while(Global_Console_ReadRow( acInputRow, sizeof(acInputRow)-1))
        {
        if( fProcessed==false && hGlobal_SkypeAPIWindowHandle!=NULL )
            {
            COPYDATASTRUCT oCopyData;

            // send command to skype
            oCopyData.dwData=0;
            oCopyData.lpData=acInputRow;
            oCopyData.cbData=strlen(acInputRow)+1;
            if( oCopyData.cbData!=1 )
                {
                if( SendMessage( hGlobal_SkypeAPIWindowHandle, WM_COPYDATA, (WPARAM)hInit_MainWindowHandle, (LPARAM)&oCopyData)==FALSE )
                    {
                    hGlobal_SkypeAPIWindowHandle=NULL;
                    printf("!!! Disconnected\n");
                    }
                }
            }
        }
    }
SendMessage( hInit_MainWindowHandle, WM_CLOSE, 0, 0);
SetEvent(hGlobal_ThreadShutdownEvent);
fGlobal_ThreadRunning=false;
}

And now here's my C#

    public bool PreFilterMessage(ref Message m)
    {
        Console.WriteLine(m.ToString());
        if (m.Msg == WM_COPYDATA && SkypeAPIWindowHandle == m.WParam)
        {
            SkypeMessage(m);
            return true;
        }
        if (m.Msg == MsgApiAttach)
        {
            switch (m.LParam.ToInt32())
            {
                case (int)SkypeControlAPIAttach.SUCCESS:
                    SkypeAPIWindowHandle = m.WParam; //Here's where we set the Skype Handle
                    AttachSuccess(m);
                    return true;
            }
        }
        return false; //Defer all other messages
    }

And here is my DLL import and Sending code

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
    static extern IntPtr SendMessageA(IntPtr hWnd, UInt32 Msg, IntPtr wParam, ref MsgHelper.COPYDATASTRUCT lParam);

    public static void Command(string c)
    {
        if (c.Last() != '\0')
            c += "\0"; //Make string null terminated
        Console.WriteLine();
        MsgHelper.COPYDATASTRUCT cda = new MsgHelper.COPYDATASTRUCT();
        cda.dwData = new IntPtr(0);
        cda.lpData = c;
        cda.cbData = c.Length + 1;
        Marshal.GetLastWin32Error(); //Clear last error
        Console.WriteLine(SendMessageA(mHelper.SkypeAPIWindowHandle, MsgHelper.WM_COPYDATA, IntPtr.Zero, ref cda));
        Console.WriteLine(Marshal.GetLastWin32Error());
    }

COPYDATASTRUCT is:

    public struct COPYDATASTRUCT
    {
        public IntPtr dwData;
        public int cbData;
        [MarshalAs(UnmanagedType.LPStr)]
        public string lpData;
    }

I think that's everything. Let me know if I forgot something.

Any ideas why I'm getting the 1400?

© Stack Overflow or respective owner

Related posts about c#

Related posts about .NET