Accueil
Rechercher:
sur developpez.com sur les forums
Forums | Tutoriels | F.A.Q's | Participez | Hébergement | Contacts
Club Emploi Blogs   TV   Dév. Web PHP XML Python Autres 2D-3D-Jeux Sécurité Windows Linux PC Mac
Accueil Conception Java DotNET Visual Basic  C  C++ Delphi Eclipse MS-Office SQL & SGBD Oracle  4D  Business Intelligence
FORUMS C FAQs C TUTORIELS C LIVRES C COMPILATEURS C SOURCES GTK+

Réaliser un plugin pour la télécommande ATI Remote Wonder

Par gRRosminet

Sommaire

Introduction
Contenu du SDK AMMO
Flux de messages
Description détaillée de l'API
  WhatKeysDoYouWant
  EnumerateProgramableFunction
  Configure
  AreYouInFocus
  HandleKey
Description de la DLL
Définition des ressources de la DLL
Conclusion

Introduction

Si comme moi, vous avez acquis cette superbe télécommande, vous trouverez certainement que les fonctionnalités proposées par celle-ci sont assez limitées quand on ne dispose pas des plugins adaptés aux applications qu'on utilise. Vous vous êtes donc peut-être senti une âme de développeur en herbe et avez décidé d'écrire vos propres plugins. Vous avez donc téléchargé le SDK ATI AMMO (Application Manipulation Modular Object), mais vous n'y avez rien compris. Soyons honnêtes : si les mots compilateur, langage C, file de messages, processus, etc ne vous disent rien, il vaut mieux que vous ne continuiez pas vôtre lecture et que vous vous contentiez de télécharger les plugins dont vous avez besoin auprès des sites spécialisés. Si vous avez les premières notions nécessaires, vous pouvez continuer vôtre lecture sans attendre.


Le contenu du SDK AMMO

Le SDK AMMO contient la licence qui encadre le développement et la diffusion des plugins pour la télécommande, un document explicatif sur ce que doit contenir un plugin, le fichier d'en-tête "ammo.h" et les fichiers de l'exemple de plugin pour Winamp 2.x. Voyons ce que raconte le fichier d'aide à l'écriture de plugins. Tout d'abord, certaines fonctionnalités sont déjà implantées, il n'est donc pas nécessaire de les redévelopper. Il y également certaines touches qu'on ne peut pas reprogrammer : les touches Power, TV, DVD, et Media Library.


Le flux de messages

La télécommande, comme tout périphérique de contrôle, génère un flux de messages à l'attention des plugins. Lorsque le logiciel de gestion de la télécommande reçoit une pression de touche, il détermine le groupe (Custom Raw, Custom Mapped, Mouse Group, Channel Group ...) de touche auquel il appartient. Chaque plugin est alors interrogé pour savoir si il est interressé par ce groupe de touches. Si un plugin est intéressé par le groupe de touches en question, la fonction AreYouInFocus() est appelée pour déterminer si le plugin devrait recevoir l'événement. Si la fonction renvoie FALSE, le plugin suivant est interrogé à son tour et ainsi de suite. Si aucun plugin ne récupère l'événement, il est alors envoyé au Multimedia Center ou à Windows en fonction de l'application qui a le focus à ce moment là. Si la fonction renvoie TRUE, l'événement est passé à la fonction HandleKey(). Si cette dernière renvoie TRUE, plus aucun traitement n'est effectué ; si elle renvoie FALSE, l'événement poursuit son chemin comme décrit précédemment.

Pour la plupart des touches, deux évènements seront générés : "touche enfoncée" et "touche relâchée". Cependant, il se peut que pour certaines touches, un ou plusieurs évènements "touche répétée" soit généré entre les deux précédents. La fonction AreYouInFocus() n'est appellée qu'une seule fois pour chaque groupe d'évènements (de "touche enfoncée" à "touche relâchée").


Description détaillée de chacune des fonctions de l'API AMMO

1)WhatKeysDoYouWant

DWORD WhatKeysDoYouWant(void)

Cette fonction est la première à être appellée. Elle sert à indiqué quels sont les groupes de touches qui intéressent le plugin. Une constante à été définie par groupe de touches dans le fichier d'en-tête "ammo.h" :

CUSTOM_RAW Boutons A à F, envoyés tels quels
CUSTOM_MAPPED Boutons A à F, remplacés par la fonction à laquelle ils ont été affectés
MOUSE_GROUP 8 directions de la souris, bouton gauche, droit et la main
CHANNEL_GROUP chaine précédente / suivante
VOLUME_GROUP Volume + / -, muet
NUMBER_GROUP Touches de 0 à 9
CURSOR_GROUP Flèches haut, bas, gauche, droite
PLAY_GROUP Lecture, pause, stop, avance / retour rapide
MENU Touche menu
SETUP Touche configuration
ENTER Touche OK
RECORD Touche enregistrement
STOPWATCH Touche de pause / reprise de l'émission TV
RESIZE Touche agrandir / restaurer la fenêtre
WEB_LAUNCH Touche WEB


Pour indiquer qu'on veut utiliser un groupe de touche, il suffit d'utiliser les constantes comme des drapeaux :

DWORD WhatKeysDoYouWant (void)
{
    return (CUSTOM_MAPPED | VOLUME_GROUP | RESIZE | PLAY_GROUP);
}

2) EnumerateProgramableFunction

char *EnumerateProgrammableFunction(WORD wIndex)

Cette fonction sert a fournir au programme de gestion de la télécommande l'intitulé des fonctions programmables proposées par le plugin. Il est recommandé d'utiliser un tableau static et global pour stocker ces chaines :

//nombre de fonctions programmables (optionnel, mais plus clair)
#define kNumFunctions 5
//tableau de chaines descriptives
static char *functions[kNumFunctions] =
{
    "fonction 1",
    "groupe 1|fonction 1",
    "groupe 1|fonction 2",
    "groupe 2|fonction 1",
    "groupe 2|fonction 2"
};
// Fonction d'interfaçage avec l'application ATI
char * EnumerateProgrammableFunction (WORD wIndex)
{
	if (wIndex >= kNumFunctions)
		return NULL;

	return functions[wIndex];
}

Comme vous avez pu le remarquer, il suffit de renvoyer NULL quand l'application d'ATI demande l'intitulé d'une fonction en dehors de la portée du tableau.

3) Configure

void Configure(HWND hWnd)

Cette fonction permet à l'utilisateur de configurer le plugin si cela est nécessaire. Si ce n'est pas le cas, elle peut toujours servir à afficher une petite boite de dialogue avec le nom du plugin et du concepteur.

void Configure (HANDLE hWnd)
{
	MessageBox(hWnd, "Un petit plugin :)\r\npar moi même", "About", MB_OK);
}

4) AreYouInFocus

BOOL AreYouInFocus(void)

Cette fonction sert, comme je l'ai expliqué précédemment, à indiquer à l'application d'ATI si oui ou non notre plugin est celui qui doit recevoir le message :

int AreYouInFocus (void)
{
    // Si l'appli au premier plan est celle qu'on gère, on renvoie vrai
	if (FindWindow("class name de mon appli",NULL) == GetForegroundWindow())
	{
        return TRUE;
	}
	return FALSE;
}

5) HandleKey

BOOL HandleKey(BOOL bCustom, WORD wKeyEvent, WORD wKeyState)

Cette fonction est l'endroit où tout va réellement se passer. C'est dans cette fonction qu'on va réagir en fonction de la touche de la télécommande. Voyons une brève description des trois paramètres :

- bCustom : si il est à TRUE, cela signifie que l'évènement concerne une fonction programmable du plugin.
- wKeyEvent : contient le code de la touche qui a généré l'évènement ou le numéro de la fonction.
- wKeyState : permet de savoir l'état de la touche : enfoncée (RMCTRL_KEY_ON), répétée (RMCTRL_KEY_REPEAT), relâchée (RMCTRL_KEY_OFF).

Pour les codes des touches, reportez vous au contenu du fichier "ammo.h".

BOOL HandleKey (BOOL bCustom, WORD wKeyEvent, WORD wState)
{
    // recherche du handle de notre application
    HWND h = FindWindow("class name de mon appli",NULL);

	// Si l'application n'a pas été trouvée => on quitte
	if (h == NULL)
	{
		return FALSE;
	}

	// Gestion des fonctions programmables
	if (bCustom)
	{
        if (wState != RMCTRL_KEY_ON)
            switch (wKeyEvent)
            {
                case fonction1 :
                    ...
            }	
	}
	else
    {
	// Gestion des touches non programmables
        if (wState == RMCTRL_KEY_ON)
        {
            switch (wKeyEvent)
            {
                case RMCTRL_MENU:
                    // Traitement
                    return TRUE;

                    ...
            }
        }
        else if (wState == RMCTRL_KEY_REPEAT)
	    {
            switch (wKeyEvent)
            {
                case RMCTRL_VOLUMEUP:
                    // Traitement
                    return TRUE;

                    ...
            }
        }
        else if (wState == RMCTRL_KEY_OFF)
	    {
            switch (wKeyEvent)
            {
                case RMCTRL_VOLUMEUP:
                    // Traitement
                    return TRUE;

                    ...
            }
        }
    }
	return FALSE;
}

Pour ce qui est de la simulation du clavier et de la souris, je vous renvoie à ce tutoriel qui y est consacré.


Description de la DLL

Pour indiquer au compilateur les informations concernant la DLL qu'on vient de réaliser et les fonctions à publier, on va utiliser un fichier de déginition (*.def) dont voici un exemple.

LIBRARY    "nom de la librairie"
DESCRIPTION    'description de la librairie'

EXPORTS
	WhatKeysDoYouWant PRIVATE 
	EnumerateProgrammableFunction PRIVATE
	Configure PRIVATE
	AreYouInFocus PRIVATE
	HandleKey PRIVATE

Définition des ressources de la DLL

Le fichier de ressources doit contenir les informations de langue de la DLL :

#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif

Les informations de version de la DLL , de débogage et de type d'OS/fichier:

VS_VERSION_INFO VERSIONINFO
	FILEVERSION 	1,0,0,0
	PRODUCTVERSION	1,0,0,0
	FILEFLAGSMASK 	0x3fL

#ifdef _DEBUG
	FILEFLAGS 0x1L
#else
	FILEFLAGS 0x0L
#endif

	FILEOS		0x40004L
	FILETYPE	0x2L
	FILESUBTYPE	0x0L

Et enfin, les informations utiles à l'application ATI :

BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904b0"
        BEGIN

		VALUE "CompanyName", "gRRosminet\0"
		VALUE "FileDescription", "Mon plugin pour mon application\0"
		VALUE "LegalCopyright", "Copyright 2002 gRRosminet\0"
		VALUE "FileVersion", "1.0.0.0\0"
		VALUE "OriginalFilename", "monplugin.dll\0"
		VALUE "ProductName", "Mon application\0"
		VALUE "ProductVersion", "1.0.0.0\0"
        END
    END

    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x409, 1200
    END
END

Conclusion

Et voilà, vous n'avez plus qu'à compiler tout ça. Un petit avertissement pour ceux qui utilisent un compilateur tel que Borland C++ Builder : certains compilateurs préfixent le nom des fonctions par un _ (underscore), ce qui ne convient pas : il faut absolument désactiver cette option. Comme vous avez pu le voir tout au long de cet exposé, la création d'un plugin pour la télécommande est un simple remplissage de formulaire. Pour ceux qui ne savent pas comment simuler le clavier et/ou la souris, un petit tour sur le tutoriel que je vous ai indiqué répondra à toutes les question qu'il peut vous rester en suspend.

Responsable bénévole de la rubrique C : Arnaud Feltz (buchs) - Contacter par EMail :
Vos questions techniques : forum d'entraide C - Publiez vos articles, tutoriels et cours
et rejoignez-nous dans l'équipe de rédaction du club d'entraide des développeurs francophones
Nous contacter - Copyright © 2000-2008 www.developpez.com - Legal informations.