Help - Search - Members - Calendar
Full Version: adding a gui to the c++ api example. help?
Skype Community > English > Development, Betas and Skype Garage > Skype Public API
vinnyc_
hi there,

i'm quite new to skype and windows gui programming in general, so i am trying to write a small program which basically mimics the c++ console example given on this site.

basically, what i'm trying to do is create a window with a menu. the menu will contain skype commands (in the example below, i have implemented code for the FOCUS command).

at the moment, the program will attach itself to skype and display the received messages, but i cannot send custom data to the api. i have tried using a handle to the skype api window, but this returns false when using the sendmessage function. HWND_BROADCAST does not seem to produce any result either.

if someone could point me in the right direction, i'd really appreciate it.

here's the code:

CODE
#include <windows.h>

#include <string>

#include <process.h>



using namespace std;





#define ID_FILE_EXIT 9001

#define ID_TOOLS_CONNECT 9002

#define ID_TOOLS_DISCONNECT 9003

#define ID_TOOLS_FOCUS 9004





enum {

SKYPECONTROLAPI_ATTACH_SUCCESS=0,        // Client is successfully attached and API window handle can be found in wParam parameter

SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION=1, // Skype has acknowledged connection request and is waiting for confirmation from the user.

                        // The client is not yet attached and should wait for SKYPECONTROLAPI_ATTACH_SUCCESS message

SKYPECONTROLAPI_ATTACH_REFUSED=2,        // User has explicitly denied access to client

SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE=3,     // API is not available at the moment. For example, this happens when no user is currently logged in.

                        // Client should wait for SKYPECONTROLAPI_ATTACH_API_AVAILABLE broadcast before making any further

                        // connection attempts.

SKYPECONTROLAPI_ATTACH_API_AVAILABLE=0x8001

};





const char g_szClassName[] = "skype api test";



HWND hInit_MainWindowHandle;



HWND hGlobal_SkypeAPIWindowHandle=NULL; // Variable to hold handle to Skype API window



HANDLE hGlobal_ThreadShutdownEvent;



UINT uiGlobal_MsgID_SkypeControlAPIAttach;

UINT uiGlobal_MsgID_SkypeControlAPIDiscover;



bool volatile fGlobal_ThreadRunning=true;



bool ipFlag = false;

string acInputRow = "#null";





// Step 4: the Window Procedure

LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)

{



bool defaultEnd = false;





 



   switch(Message)

   {

       case WM_CREATE:

       {



  // Create the menu



           HMENU hMenu, hSubMenu;



           hMenu = CreateMenu();



           hSubMenu = CreatePopupMenu();

           AppendMenu(hSubMenu, MF_STRING, ID_FILE_EXIT, "E&xit");

           AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&File");



           hSubMenu = CreatePopupMenu();

           AppendMenu(hSubMenu, MF_STRING, ID_TOOLS_CONNECT, "&Connect");

  AppendMenu(hSubMenu, MF_STRING, ID_TOOLS_DISCONNECT, "&Disconnect");

  AppendMenu(hSubMenu, MF_STRING, ID_TOOLS_FOCUS, "Focus &Skype");

           AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&Tools");



           SetMenu(hwnd, hMenu);



       }

       break;

       

 case WM_COMMAND:

 {

       

  switch(LOWORD(wParam))

  {



   // Code to handle menu selections



   case ID_FILE_EXIT:

    hGlobal_SkypeAPIWindowHandle=NULL;

    PostMessage(hwnd, WM_CLOSE, 0, 0);

   break;

           

   case ID_TOOLS_CONNECT:

   {





   }

   break;



   case ID_TOOLS_DISCONNECT:



   

   break;



   case ID_TOOLS_FOCUS:

   {

    acInputRow = "FOCUS";

   

   }

   break;

  }

       }

 break;





       case WM_CLOSE:

           DestroyWindow(hwnd);

       break;





 case WM_COPYDATA:

 {



  // Print response received from Skype

  if( hGlobal_SkypeAPIWindowHandle==(HWND)wParam )

  {

   PCOPYDATASTRUCT poCopyData=(PCOPYDATASTRUCT)lParam;





   MessageBox(hwnd, (char *)poCopyData->lpData, "Skype response:", MB_OK | MB_ICONINFORMATION);



  }





 }

 break;





       case WM_DESTROY:

           PostQuitMessage(0);

       break;





       default:

 {

 

  // If attempting to attach to the Skype API

  if( Message==uiGlobal_MsgID_SkypeControlAPIAttach )

  {



   // Check the status code received from the Skype API

   switch(lParam)

   {

    // Connection established

    case SKYPECONTROLAPI_ATTACH_SUCCESS:



     MessageBox(hwnd, "Connected!", "Alert!", MB_OK | MB_ICONINFORMATION);

     hGlobal_SkypeAPIWindowHandle=(HWND)wParam;

     break;



    // Requires authorization from user

    case SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION:



     MessageBox(hwnd, "Pending authorization", "Alert!", MB_OK | MB_ICONINFORMATION);

     break;



    // Connection refused

    case SKYPECONTROLAPI_ATTACH_REFUSED:



     MessageBox(hwnd, "Connection refused!", "Alert!", MB_OK | MB_ICONINFORMATION);

     break;



    // Skype not running / logged in

    case SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE:



     MessageBox(hwnd, "Skype API not available!", "Alert!", MB_OK | MB_ICONINFORMATION);

     break;



    // API is available for connection

    case SKYPECONTROLAPI_ATTACH_API_AVAILABLE:



     MessageBox(hwnd, "Try connect now (API available)", "Alert!", MB_OK | MB_ICONINFORMATION);

     break;

   }



   break;



  }





  return DefWindowProc( hwnd, Message, wParam, lParam);

 }

 break;



   }

   return 0;

}







void __cdecl Global_InputProcessingThread(void *)

{



bool fProcessed; // Processed? flag

 



// Send discover message to find Skype API...

if(SendMessage( HWND_BROADCAST, uiGlobal_MsgID_SkypeControlAPIDiscover, (WPARAM)hInit_MainWindowHandle, 0)!=0)

{ //

 

 // Structure to hold data to be sent to Skype API

 COPYDATASTRUCT oCopyData;

 



 while(true)

 {



  if (!ipFlag)

  {

 

   // Compare user input from console



   // Quit

   if( acInputRow.compare("#quit")==0 ||

    acInputRow.compare("#exit")==0 )

   {

    break;

   }





   fProcessed=false;





   if( acInputRow.compare("#null")==0 )

    fProcessed=true;



   // Connect to Skype API

   if( acInputRow.compare("#connect")==0 )

   {

    SendMessage( HWND_BROADCAST, uiGlobal_MsgID_SkypeControlAPIDiscover, (WPARAM)hInit_MainWindowHandle, 0);

    fProcessed=true;

    acInputRow = "#null";

   }





   // Disconnect from Skype API

   if( acInputRow.compare("#disconnect")==0 )

   {

    hGlobal_SkypeAPIWindowHandle=NULL;

    fProcessed=true;

    acInputRow = "#null";

   }



   // Connect to Skype API

   if( acInputRow.compare("FOCUS")==0 )

   {



    // Convert from CString to char array (this is done because a char array must be sent)

    char* str = strdup(acInputRow.c_str());



    oCopyData.dwData=(WPARAM)0; // Data to be passed (default 0)

    oCopyData.lpData=str;  // Pointer to data to be passed (Skype command char array)

    oCopyData.cbData=(acInputRow.length() + 1); // Store length of Skype command string



   

    if(!SendMessage( hGlobal_SkypeAPIWindowHandle, WM_COPYDATA, (WPARAM)hInit_MainWindowHandle, (LPARAM)&oCopyData))

    {

     MessageBox(hInit_MainWindowHandle, "Sendmessage failed!", "Focus...", MB_OK | MB_ICONINFORMATION);

    }

    fProcessed=true;

    acInputRow = "#null";

   }



   

   // If string is a Skype command...

   if( fProcessed==false && hGlobal_SkypeAPIWindowHandle!=NULL )

   {

   

    //



    if( oCopyData.cbData!=1 )

    {



     // The following line sends the command to the Skype API

     // usage: SendMessage( skype window handle, message to be sent, main window handle,

     //       address of oCopyData variable)

     

     if(SendMessage( hGlobal_SkypeAPIWindowHandle, WM_COPYDATA, (WPARAM)hInit_MainWindowHandle, (LPARAM)&oCopyData) == FALSE )

      // Display "disconnected" message if SendMessage function returns FALSE

     {

      //hGlobal_SkypeAPIWindowHandle=NULL;

      MessageBox(hInit_MainWindowHandle, "SendMessage returned FALSE!", "Error!", MB_OK | MB_ICONINFORMATION);

     

     }



     ipFlag = false;

     

    }

   

   }

  }

 }

 

}



PostMessage( hInit_MainWindowHandle, WM_CLOSE, 0, 0);





// Set the event that will end the thread - this is being waited on by main() using WaitForSingleObject

SetEvent(hGlobal_ThreadShutdownEvent);

fGlobal_ThreadRunning=false;



}







int MessageLoop(void)

{

MSG Msg;



// Step 3: The Message Loop

while(GetMessage(&Msg, NULL, 0, 0) > 0)

{

 TranslateMessage(&Msg);

 DispatchMessage(&Msg);

}



return Msg.wParam;

}









int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

   LPSTR lpCmdLine, int nCmdShow)

{

   WNDCLASSEX wc;

   int iMsg;



   //Step 1: Registering the Window Class

   wc.cbSize        = sizeof(WNDCLASSEX);

   wc.style         = 0;

   wc.lpfnWndProc   = (WNDPROC)&WndProc;

   wc.cbClsExtra    = 0;

   wc.cbWndExtra    = 0;

   wc.hInstance     = hInstance;

   wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);

   wc.hCursor       = LoadCursor(NULL, IDC_ARROW);

   wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);

   wc.lpszMenuName  = NULL;

   wc.lpszClassName = g_szClassName;

   wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);





uiGlobal_MsgID_SkypeControlAPIAttach=RegisterWindowMessage("SkypeControlAPIAttach");

uiGlobal_MsgID_SkypeControlAPIDiscover=RegisterWindowMessage("SkypeControlAPIDiscover");







   if(!RegisterClassEx(&wc))

   {

       MessageBox(NULL, "Window Registration Failed!", "Error!",

           MB_ICONEXCLAMATION | MB_OK);

       return 0;

   }



   // Step 2: Creating the Window

   hInit_MainWindowHandle = CreateWindowEx(

       WS_EX_CLIENTEDGE,

       g_szClassName,

       "skype API connect",

       WS_OVERLAPPEDWINDOW,

       CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,

       NULL, NULL, hInstance, NULL);



   if(hInit_MainWindowHandle == NULL)

   {

       MessageBox(NULL, "Window Creation Failed!", "Error!",

           MB_ICONEXCLAMATION | MB_OK);

       return 0;

   }



   ShowWindow(hInit_MainWindowHandle, nCmdShow);

   UpdateWindow(hInit_MainWindowHandle);







////////////////////////////////////////////////////////////

// Begin thread to process incoming messages from Skype

////////////////////////////////////////////////////////////

//

// Create an event to handle the quit and exit commands

hGlobal_ThreadShutdownEvent=CreateEvent( NULL, TRUE, FALSE, NULL);





if( hGlobal_ThreadShutdownEvent!=NULL )

{



 if( _beginthread( &Global_InputProcessingThread, 64*1024, NULL)!=(unsigned long)-1 )

 {



  iMsg = MessageLoop();



  //WaitForSingleObject( hGlobal_ThreadShutdownEvent, INFINITE);

 }



 CloseHandle(hGlobal_ThreadShutdownEvent);



}

 

//

////////////////////////////////////////////////////////////





   

   //return Msg.wParam;

return iMsg;

}


thanks in advance,

vinny
TheUberOverlord
Please see this post, does it help? You can't really interface by window handle in the API in C++, just follow the same interface as this does:

http://forum.skype.com/viewtopic.php?t=54549
vinnyc_
Hi ZOverLord, thanks for the response. I did take a look at that interface, but it's not quite what I'm looking for (although the code was quite useful in understanding the basics of windows handles and messages). I actually downloaded the SkypeTracer source code, which is an excellent reference for what I'm doing.

Thanks again,

Vinny
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.